.. Copyright (c) 2019 CERN (home.cern)
   SPDX-License-Identifier: CC-BY-SA-4.0+

.. _basic_concepts:

--------------
Basic Concepts
--------------

This section introduces the various basic concepts of WRTD. These concepts are used throughout this
document and are fundamental to understanding how WRTD works (and, by extension, how to use it).

.. _node:

Node
====

WRTD is made of Nodes, connected to each other over a WR network. Nodes receive input :ref:`Events
<event>` and send output :ref:`Events <event>`. See also :numref:`fig-wrtd-overview`.

Every Node has :ref:`local_channel` inputs and/or outputs allowing it to interact with its
environment. It also has a connection to a WR network, allowing it to send and/or receive
:ref:`Messages <message>` to other Nodes.

.. _event:

Event
=====

Events represent inputs and outputs of a WRTD :ref:`node`. Input Events received on a :ref:`node`
will result in an output Event to be generated (assuming that the relevant :ref:`rule` exists to
associate an input to an output). In that sense, inputs Events are the causes, while output Events
are the effects.

Input Events can be either a :ref:`local_channel`, an inbound network :ref:`message`, or an
:ref:`alarm`.

Output Events can be either a :ref:`local_channel`, or an outbound network :ref:`message`.

An Event is essentially a combination of an :ref:`event_id` (the "what") and an :ref:`timestamp` (the
"when").

.. _event_id:

Event ID
--------

Every :ref:`event` is represented by an ID.

Event IDs are 15-character, null-terminated (for a total length of 16) strings that uniquely
identify an input or output Event.

:ref:`local_channel` inputs always use an Event ID in the form of ``LC-I<x>``, where x is a number
starting from 1 (e.g. ``LC-I1``).

:ref:`local_channel` outputs always use an Event ID in the form of ``LC-O<x>``, where x is a number
starting from 1 (e.g. ``LC-O1``).

An :ref:`alarm` Event ID will always have a prefix of ``alarm`` or ``ALARM``, followed by any other
characters (always limited to 16 characters, including null-termination).

All other Event IDs are considered to refer to network :ref:`messages <message>`.

.. attention:: An Event ID that is longer than 16 characters (including null-termination) or that is
   filled with null characters is invalid.

.. note:: Rule 6.4.4 of the `LXI Core Specification`_ also defines some reserved Event IDs. These
   are:

   * ``LXI<x>`` with x being an integer between 0 and 7 (e.g. ``LXI5``)
   * ``LAN<x>`` with x being an integer between 0 and 7 (e.g. ``LAN3``)
   * ``LXIERROR``

   Users are advised to not use these identifiers in their own applications.

.. _timestamp:

Event Timestamp
---------------

Every :ref:`event` has an associated Timestamp.

For an input :ref:`event`, the Timestamp typically represents the moment in time when the
:ref:`event` happened.

For an output :ref:`event`, the Timestamp typically represents the moment in time when the
:ref:`event` should happen.

Timestamps are expressed using a 48-bit counter for seconds, a 32-bit counter for nanoseconds (which
is reset every time the counter reaches 10\ :sup:`9`\ ) and a 16-bit counter for fractional
nanoseconds (where every "tick" represents 2\ :sup:`-16`\ ns).

.. hint:: All Timestamps represent `TAI time`_ since ``00:00:00 Thursday, 1 January 1970`` (`Unix
   Epoch time`_).

.. hint:: For most applications, the upper 16 bits of the seconds counter can be ignored/assumed to
   be zero. A 32-bit seconds counter that was started on ``00:00:00 Thursday, 1 January 1970`` will
   overflow on ``06:26:16 Sunday, 7 February 2106``.

.. _event_log:

Event Log
=========

The Event Log records information about all received and transmitted :ref:`Events <event>`, as well
as information regarding any discarded :ref:`event`, along with the reason for discarding it.

The Event Log has a limited storage buffer. Newer entries will overwrite older, unread ones.

For an explanation of the fields of an Event Log entry, please refer to the documentation of the
:cpp:func:`wrtd_get_next_event_log_entry` function.

.. _local_channel:

Local Channel
=============

Local Channels represent the connections of a :ref:`node` to its environment. They can be either
inputs or outputs.

A Local Channel input delivers input Events to the :ref:`node`. Typical examples include the
external trigger input of a digitiser, a Time to Digital Converter (TDC) or a TTL input channel on
a digital I/O board.

A Local Channel output transmits output Events from the :ref:`node`. Typical examples include a Fine
Delay generator or a TTL output channel on a digital I/O board.

All Local Channels use specific IDs as described in :ref:`Event IDs <event_id>`.

.. _message:

Message
=======

WRTD Event Messages (or, simply, Messages) follow the LXI Event Messaging format, as defined in Rule
4.3 of the `LXI Event Messaging Extended Function specification`_.

To ensure compatibility and interoperability with LXI devices, WRTD Event Messages are transmitted
using multicast UDP on address ``224.0.23.159``, port ``5044`` (Rule 3.3.1 of the specification).

Each Message is transmitted as a single Ethernet frame, with a UDP header and a payload as shown in
:numref:`fig-wrtd-message`.


.. figure:: graphics/wrtd_message.png
   :name: fig-wrtd-message
   :align: center
   :alt: alternate text
   :figclass: align-center

   Contents of a WRTD Event Message

The contents of a WRTD Event Message are again based on LXI Event Messages, with the "Domain" and
"Flag" fields (octets 3 and 36 respectively) fixed to zero.

Each Message contains an :ref:`event_id`, an :ref:`timestamp` and a sequence number. The latter is a
counter that gets increased by one every time a new Event is generated.

.. hint:: The sequence counter can be used to detect lost or duplicate Messages.

.. hint:: Although there are currently no "Data Fields" defined (octets 37 and beyond), it should be
   highlighted that the LXI Event message format supports an arbitrary number of data fields, in the
   form of Type/Length/Value (TLV) triplets, which could be used to provide additional functionality
   to WRTD in the future.

Please refer to Section 4.3 of the `LXI Event Messaging Extended Function specification`_ for more
details.

.. _rep_cap:

Repeated Capability
===================

IVI uses the term Repeated Capability to express functionality that is duplicated in an instrument,
with each instance potentially having different settings. A typical example of a Repeated Capability
is a channel of an oscilloscope; the instrument has many channels, each one offering the exact same
functionality, but each one with its own settings (:ref:`Attributes <attribute>`).

Furthermore, IVI defines the API for accessing Repeated Capabilities in Section 12 of `IVI-3.4: API
Style Guide`_.

WRTD defines the following Repeated Capabilities for each :ref:`node`:

* :ref:`rule`        (see also :ref:`api_rule`)
* :ref:`alarm`       (see also :ref:`api_alarm`)
* :ref:`application` (see also :ref:`api_app`)

.. _rep_cap_id:

Repeated Capability ID
----------------------

An instance of a :ref:`rep_cap` is designated by a unique Repeated Capability ID.

WRTD uses the *Parameter Style* API, defined in Section 12.1 of `IVI-3.4: API Style Guide`_, where
each function related to a Repeated Capability expects the ID of the Repeated Capability instance as
a parameter. This parameter is also called a Repeated Capability *Selector* in IVI terminology.

.. note:: Similar to an :ref:`event_id`, a Repeated Capability ID is limited to 16 characters,
          including null termination.

.. hint:: Section 4.4 of `IVI-3.1: Driver Architecture Specification`_ shows that a Selector can
   include groups of IDs, ranges, nested IDs and much more. For now, WRTD only supports *simple
   selectors*, allowing a single ID to be selected at a time, but this could change in future
   releases.

.. _attribute:

Attribute
=========

WRTD uses Attributes to represent the various settings of the :ref:`node` and defines get/set
functions to access them. This behaviour is identical to IVI.

Attributes can be of one of the following types:

* Boolean
* 32-bit Integer
* String
* Timestamp (new type, does not exist in IVI)

Attributes can be attached to a :ref:`rep_cap`, or they can be "global" (apply to the whole
:ref:`node`).

.. note:: Since global Attributes are not attached to any :ref:`rep_cap`, when using one of the
   functions to get/set a global Attribute, a special :ref:`rep_cap_id`
   (:c:macro:`WRTD_GLOBAL_REP_CAP_ID`) must be passed to the function as the Selector.

Please refer to the :ref:`api_attr` for more details.

.. _rule:

Rule
====

A Rule is a :ref:`rep_cap` instance inside a :ref:`node` that links input to output :ref:`Events
<event>`.

Rules are declared (and deleted) using the :ref:`api_rule`. Their configuration is controlled via
:ref:`Attributes <attribute>` that can be manipulated using the :ref:`api_attr`.

When an input :ref:`event` is received by a :ref:`Node`, WRTD tries to match it with any declared
(and enabled) Rule. The process that is followed for each input :ref:`event` is depicted in
:numref:`fig-wrtd-rule-rx`.

.. figure:: graphics/wrtd_rule_rx.png
   :name: fig-wrtd-rule-rx
   :align: center
   :alt: alternate text
   :figclass: align-center

   Rule processing for incoming :ref:`Events <event>`. The red hexagons represent :ref:`Attributes
   <attribute>`.

Once an input :ref:`event` has been matched and all delays have been applied to it, it is forwarded
to the next processing block that generates the preconfigured output :ref:`event`. This is depicted
in :numref:`fig-wrtd-rule-tx`.

.. figure:: graphics/wrtd_rule_tx.png
   :name: fig-wrtd-rule-tx
   :align: center
   :alt: alternate text
   :figclass: align-center

   Rule processing for outgoing :ref:`Events <event>`. The red hexagons represent :ref:`Attributes
   <attribute>`.

.. hint:: There are actually more :ref:`Attributes <attribute>` than the ones shown in
          :numref:`fig-wrtd-rule-rx` and :numref:`fig-wrtd-rule-tx`. Please refer to the
          :ref:`api_attr` for the complete list, as well as an explanation of each
          :ref:`Attribute`.

.. _alarm:

Alarm
=====

An Alarm is simply a user-defined moment to generate internally an input :ref:`event`.

Similar to a :ref:`Rule`, an Alarm is a :ref:`rep_cap` instance inside a :ref:`node`

Alarms are declared (and deleted) using the :ref:`api_alarm`. Their configuration is controlled via
:ref:`Attributes <attribute>` that can be manipulated using the :ref:`api_attr`.

.. note:: The :ref:`rep_cap_id` of an Alarm must always have a prefix of ``alarm`` or ``ALARM``,
          followed by any other characters (always limited to 16 characters, including
          null-termination).

          The :ref:`event_id` of the input :ref:`event` generated by an Alarm will match its
          :ref:`rep_cap_id`.

Every :ref:`node` checks periodically if any of the declared (and enabled) Alarms need to be
triggered, following the process depicted in :numref:`fig-wrtd-alarm`.

.. figure:: graphics/wrtd_alarm.png
   :name: fig-wrtd-alarm
   :align: center
   :alt: alternate text
   :figclass: align-center

   Alarm processing.

.. hint:: There are actually more :ref:`Attributes <attribute>` than the ones shown in
          :numref:`fig-wrtd-alarm`. Please refer to the :ref:`api_attr` for the complete list,
          as well as an explanation of each :ref:`Attribute`.

.. _application:

Application
===========

A :ref:`node` may be running one or more Applications (firmware).

As such, an Application is also a :ref:`rep_cap` instance inside a :ref:`node`.

Unlike :ref:`Rules <rule>` and :ref:`Alarms <alarm>`, users cannot declare or remove
Applications. They can only get their (read-only) :ref:`Attributes <attribute>` which provide
information regarding firmware version, number and direction of :ref:`Local Channels
<local_channel>`, etc.

Please refer to the :ref:`api_attr` for the complete list of Application-related :ref:`Attributes
<attribute>`. The :ref:`rep_cap_id` of each Application can be retrieved using the :ref:`api_app`.

.. _LXI Core Specification: http://www.lxistandard.org/members/Adopted%20Specifications/Latest%20Version%20of%20Standards_/LXI%20Standard%201.5%20Specifications/LXI%20Device%20Specification%20v1_5_01.pdf

.. _LXI Event Messaging Extended Function specification: http://www.lxistandard.org/members/Adopted%20Specifications/Latest%20Version%20of%20Standards_/LXI%20Standard%201.5%20Specifications/LXI%20Event%20Messaging%20Extended%20Function.pdf

.. _IVI-3.1\: Driver Architecture Specification: http://ivifoundation.org/downloads/Architecture%20Specifications/IVIspecstopost10-22-2018/IVI-3.1_Architecture_2018-10-19.pdf

.. _IVI-3.4\: API Style Guide: http://ivifoundation.org/downloads/Architecture%20Specifications/IVIspecstopost10-22-2018/IVI-3.4_APIStyleGuide_2018-10-19.pdf

.. _TAI time: https://en.wikipedia.org/wiki/International_Atomic_Time

.. _Unix Epoch time: https://en.wikipedia.org/wiki/Unix_time
