4.1. C Library

The WRTD C Library is the standard, most flexible way of accessing a WRTD Node. The library itself is modelled after IVI and LXI (see also Relation to IVI and LXI).

The following specifications are relevant to and used by WRTD:

4.1.1. Error Handling API

Every function in the WRTD C library returns an error code of type wrtd_status. The Error Handling API provides functions for retrieving and interpreting errors from the Node.

Error codes can be converted to strings by means of the wrtd_error_message() function. The latest error can be retrieved with the wrtd_get_error() function.

4.1.1.1. Error Codes

enum wrtd_status

White Rabbit Trigger Distribution error codes.

Names and values inspired by IVI-3.2 and IVI-3.15.

Values:

WRTD_SUCCESS = 0

No error.

__WRTD_ERROR_BASE = 0xBFFA0000

Same as IVI_INHERENT_ERROR_BASE.

WRTD_ERROR_INVALID_ATTRIBUTE = __WRTD_ERROR_BASE + 0x0C

Invalid/unknown attribute.

WRTD_ERROR_ATTR_NOT_WRITEABLE = __WRTD_ERROR_BASE + 0x0D

Attempt to write a read-only attribute.

WRTD_ERROR_ATTR_NOT_READABLE = __WRTD_ERROR_BASE + 0x0E

Attempt to read a write-only attribute.

WRTD_ERROR_INVALID_VALUE = __WRTD_ERROR_BASE + 0x10

Invalid value provided.

WRTD_ERROR_NOT_INITIALIZED = __WRTD_ERROR_BASE + 0x1D

Device not initialized.

WRTD_ERROR_UNKNOWN_CHANNEL_NAME = __WRTD_ERROR_BASE + 0x20

Unknown channel name.

WRTD_ERROR_OUT_OF_MEMORY = __WRTD_ERROR_BASE + 0x56

Device out of memory.

WRTD_ERROR_NULL_POINTER = __WRTD_ERROR_BASE + 0x58

Null pointer.

WRTD_ERROR_UNEXPECTED_RESPONSE = __WRTD_ERROR_BASE + 0x59

Unexpected response.

WRTD_ERROR_RESOURCE_UNKNOWN = __WRTD_ERROR_BASE + 0x60

Unknown resource.

WRTD_ERROR_BADLY_FORMED_SELECTOR = __WRTD_ERROR_BASE + 0x66

Incorrect repeated capability selector.

__WRTD_LXISYNC_ERROR_BASE = 0xBFFA3000

Same as IVI_LXISYNC_ERROR_BASE.

WRTD_ERROR_ALARM_EXISTS = __WRTD_LXISYNC_ERROR_BASE + 0x07

The alarm already exists.

WRTD_ERROR_ALARM_DOES_NOT_EXIST = __WRTD_LXISYNC_ERROR_BASE + 0x08

The specified alarm has not been defined.

__WRTD_SPECIFIC_ERROR_BASE = 0xBFFA6000

Same as IVI_VENDOR_SPECIFIC_ERROR_BASE.

WRTD_ERROR_VERSION_MISMATCH = __WRTD_SPECIFIC_ERROR_BASE + 0x00

Version mismatch.

WRTD_ERROR_INTERNAL = __WRTD_SPECIFIC_ERROR_BASE + 0x01

Internal error.

WRTD_ERROR_UNKNOWN_LOG_TYPE = __WRTD_SPECIFIC_ERROR_BASE + 0x02

Unknown event log type/reason.

WRTD_ERROR_RESOURCE_ACTIVE = __WRTD_SPECIFIC_ERROR_BASE + 0x03

Resource is not disabled and cannot be changed.

WRTD_ERROR_ATTR_GLOBAL = __WRTD_SPECIFIC_ERROR_BASE + 0x04

Attempt to access a global attribute without using the global attribute selector.

WRTD_ERROR_OUT_OF_RESOURCES = __WRTD_SPECIFIC_ERROR_BASE + 0x05

The device has no more resources to allocate.

WRTD_ERROR_RULE_EXISTS = __WRTD_SPECIFIC_ERROR_BASE + 0x06

The rule already exists.

WRTD_ERROR_RULE_DOES_NOT_EXIST = __WRTD_SPECIFIC_ERROR_BASE + 0x07

The specified rule has not been defined.

__WRTD_ERROR_MAX_NUMBER

Always last entry in this enum.

4.1.1.2. Functions

wrtd_status wrtd_get_error(wrtd_dev *wrtd, wrtd_status *error_code, int32_t error_description_buffer_size, char *error_description)

Retrieve and clear the last error from the device.

Modelled after the IVI-C GetError function.

This function complies with IVI-3.2, section 3.1.2.1 (Additional Compliance Rules for C Functions with ViChar Array Output Parameters), with the exception of the buffer_size < 0 case, which produces an error instead of allowing a potential buffer overflow.

Return
wrtd_status. However, if the buffer size parameter is 0, then this function returns instead a positive value, indicating the minimum buffer size necessary to fit the full message. See also IVI-3.2, section 3.1.2.1.
Parameters
  • wrtd: Device token.
  • error_code: wrtd_status pointer to return the error code. Ignored if NULL.
  • error_description_buffer_size: Size of pre-allocated error_description buffer.
  • error_description: Buffer to store the detailed error message string.

wrtd_status wrtd_error_message(wrtd_dev *wrtd, wrtd_status err_code, char *err_message)

Convert a wrtd_status error code to a string.

Modelled after the IVI-C ErrorMessage function.

Return
wrtd_status
Parameters
  • wrtd: Device token. Can be NULL to allow calling this function even when initialisation has failed.
  • err_code: wrtd_status error code to convert.
  • err_message: Buffer of at least 256 bytes to store the resulting string.

Listing 4.1 Error handling
#include <libwrtd.h>

int main(void) {
        wrtd_dev *wrtd;
        wrtd_status status, err_code;
        char status_str[256];
        char *err_msg;
        int buf_size;

        status = wrtd_init(1, false, NULL, &wrtd);
        if (status != WRTD_SUCCESS) {
                /* use wrtd_error_message because wrtd_init failed
                   and the wrtd pointer is not valid. */
                wrtd_error_message(wrtd, status, status_str);
                printf("ERROR: %d, %s\n", status, status_str);
                return status;
        }

        status = wrtd_get_attr_bool(wrtd, WRTD_GLOBAL_REP_CAP_ID,
                                    WRTD_ATTR_EVENT_LOG_EMPTY);
        if (status != WRTD_SUCCESS) {
                /* query the necessary buffer size for
                   the error message */
                buf_size = wrtd_get_error(wrtd, NULL, 0, NULL);
                /* allocate the buffer */
                err_msg = calloc(sizeof(char), buf_size);
                /* retrieve the error code and message */
                wrtd_get_error(wrtd, &err_code, buf_size, err_msg)
                printf("ERROR: %d, %s\n", err_code, err_msg);
                return status;
        }

        wrtd_close(wrtd);

        return 0;
}

Important

In the remaining code examples we omit error checking on purpose, to simplify the examples. However, in a real application, users should always check the status code of every call to a WRTD function, like in Listing 4.1.

4.1.2. Initialisation API

The initialisation API provides the functions to initiate/close a connection to the Node, as well as to reset it.

wrtd_init() is the first function that should be called by any program, in order to obtain the “device token” to be used in all subsequent function calls.

Conversely, wrtd_close() should be called before exiting the program. No further WRTD library functions can be used after that.

In order to identify the Node to connect to, it is necessary to provide the ID of that Node. This ID is simply an integer that uniquely identifies a Node within a given host system. Functions wrtd_get_node_count() and wrtd_get_node_id() can help you figure out the ID of each Node.

Important

The Node ID is not sequential, nor does it start counting from zero (or one). It might well be that you only have one Node in a given host, and that it has an ID different than 1. Always retrieve therefore the Node ID with wrtd_get_node_id().

wrtd_status wrtd_init(uint32_t node_id, bool reset, const char *options_str, wrtd_dev **wrtd)

Initialize the WRTD Node and obtain the WRTD device token.

Return
wrtd_status
Parameters
  • node_id: WRTD Node ID
  • reset: Reserved for future use.
  • options_str: Reserved for future use.
  • wrtd: Pointer to WRTD device token.

wrtd_status wrtd_close(wrtd_dev *wrtd)

Close a WRTD Node and release all resources.

Return
wrtd_status
Parameters
  • wrtd: Device token.

wrtd_status wrtd_reset(wrtd_dev *wrtd)

Reset a WRTD Node. This will remove all defined Alarms and Rules.

Return
wrtd_status
Parameters
  • wrtd: Device token.

wrtd_status wrtd_get_node_count(uint32_t *count)

Retrieve the number of detected WRTD Nodes.

Return
wrtd_status
Parameters
  • count: number of detected WRTD Nodes

wrtd_status wrtd_get_node_id(uint32_t index, uint32_t *node_id)

Retrieve the ID of a WRTD Node.

Before calling this function, you should probably call wrtd_get_node_count to know the number of Nodes.

Return
wrtd_status
Parameters
  • index: The index of the Node (“1” for the first Node, etc.)
  • node_id: The retrieved ID of the Node

Listing 4.2 Opening and closing a connection to a Node.
#include <libwrtd.h>

int main(void) {
        wrtd_dev *wrtd;
        wrtd_status status;
        uint32_t node_count;
        uint32_t node_id;

        /* Not really used in this example */
        status = wrtd_get_node_count(&node_count);

        /* Get the ID of the first Node */
        status= wrtd_get_node_id(1, &node_id);

        /* Access the first Node */
        status = wrtd_init(node_id, false, NULL, &wrtd);

        /* This will erase all defined rules and alarms
           from the Node, so it might not be what you want
           the program to do every time it is executed. */
        wrtd_reset(wrtd);

        /* Do some more work here... */

        wrtd_close(wrtd);
}

4.1.3. Attribute Handling API

The Attribute Handling API defines the available Attributes and the Functions for accessing them.

Attributes can be of type bool, int32, string, or tstamp (wrtd_tstamp).

Access can be RW (read/write), RO (read-only) or WO (write-only).

Furthermore they can be related to a specific alarm, rule, application, or they can be global (they apply to the whole device).

Attributes are accessed by means of the following functions, depending on their type:

When using one of the above functions to access a “global” Attribute, the Repeated Capability ID parameter should be set to WRTD_GLOBAL_REP_CAP_ID.

WRTD_GLOBAL_REP_CAP_ID

A repeated capability identifier for global attributes.

Listing 4.3 Accessing a “global” Attribute.
#include <libwrtd.h>

int main(void) {
        wrtd_dev *wrtd;
        wrtd_status status;
        bool log_empty;

        status = wrtd_init(1, false, NULL, &wrtd);

        status = wrtd_get_attr_bool(wrtd, WRTD_GLOBAL_REP_CAP_ID,
                                    WRTD_ATTR_EVENT_LOG_EMPTY,
                                    &log_empty);

        wrtd_close(wrtd);
}

4.1.3.1. Attributes

enum wrtd_attr

White Rabbit Trigger Distribution attributes.

Names and values inspired by IVI-3.2 and IVI-3.15.

Values:

__WRTD_ATTR_BASE = 1150000

Same as IVI_INSTR_SPECIFIC_ATTR_BASE.

WRTD_ATTR_EVENT_LOG_EMPTY = __WRTD_ATTR_BASE + 0x00

RO bool global True if the Event Log is empty.

WRTD_ATTR_EVENT_LOG_ENABLED = __WRTD_ATTR_BASE + 0x01

RW bool global Enable/disable the Event Log.

WRTD_ATTR_IS_TIME_SYNCHRONIZED = __WRTD_ATTR_BASE + 0x02

RO bool global True if the device is synchronized to White Rabbit time.

WRTD_ATTR_SYS_TIME = __WRTD_ATTR_BASE + 0x03

RO tstamp global Current system time.

WRTD_ATTR_ALARM_COUNT = __WRTD_ATTR_BASE + 0x10

RO int32 global Number of defined Alarms.

WRTD_ATTR_ALARM_ENABLED = __WRTD_ATTR_BASE + 0x11

RW bool alarm Enable/disable an Alarm.

WRTD_ATTR_ALARM_SETUP_TIME = __WRTD_ATTR_BASE + 0x12

RW tstamp alarm Specifies at what time to send an Alarm event. This is typically set to a moment earlier than WRTD_ATTR_ALARM_TIME, to allow for the event to reach its destination(s) before the WRTD_ATTR_ALARM_TIME moment.

WRTD_ATTR_ALARM_TIME = __WRTD_ATTR_BASE + 0x13

RW tstamp alarm Specifies at what time to trigger an Alarm.

WRTD_ATTR_ALARM_PERIOD = __WRTD_ATTR_BASE + 0x14

RW tstamp alarm Specifies the Alarm period. 0 means no repetitions.

WRTD_ATTR_ALARM_REPEAT_COUNT = __WRTD_ATTR_BASE + 0x15

RW int32 alarm Specifies the number of times an Alarm will occur at the period specified by WRTD_ATTR_ALARM_PERIOD, before becoming automatically disabled. 0 means infinite repetitions. 1 means that the alarm will occur only once. When read, it returns the remaining repetitions.

WRTD_ATTR_RULE_COUNT = __WRTD_ATTR_BASE + 0x20

RO int32 global Number of defined Rules.

WRTD_ATTR_RULE_ENABLED = __WRTD_ATTR_BASE + 0x21

RW bool rule Enable/disable a Rule.

WRTD_ATTR_RULE_REPEAT_COUNT = __WRTD_ATTR_BASE + 0x22

RW int32 rule Specifies the number of times a Rule will fire before becoming automatically disabled. 0 means infinite. 1 means that the Rule will fire only once. When read, it returns the remaining repetitions.

WRTD_ATTR_RULE_SOURCE = __WRTD_ATTR_BASE + 0x23

RW string rule Get/set Rule source. Rule sources can be:

  • Local source Event IDs (in the form of LC-I<x>)
  • Alarm IDs (any ID with an alarm prefix)
  • Any other string which will be interpreted as a network message Event ID.

WRTD_ATTR_RULE_DESTINATION = __WRTD_ATTR_BASE + 0x24

RW string rule Get/set Rule destinations. Rule destinations can be:

  • Local destination Event IDs (in the form of LC-O<x>)
  • Any other string which will be interpreted as a network message Event ID.

WRTD_ATTR_RULE_SEND_LATE = __WRTD_ATTR_BASE + 0x25

RW bool rule If true, events that arrive late (with a timestamp in the past) will still be executed; otherwise they are logged and discarded.

WRTD_ATTR_RULE_DELAY = __WRTD_ATTR_BASE + 0x26

RW tstamp rule Specifies the delay to add to the timestamp of the source Event before forwarding it to its destination. The provided value must be less than 1 second.

WRTD_ATTR_RULE_HOLDOFF = __WRTD_ATTR_BASE + 0x27

RW tstamp rule Specifies the “dead time” between two source Events. Any new event that arrives during this time, will be logged and discarded. The provided value must be less than 1 second.

WRTD_ATTR_RULE_RESYNC_PERIOD = __WRTD_ATTR_BASE + 0x28

RW tstamp rule Re-align the source Event timestamp to a multiple of this value. As an example, if the Event timestamp is 00:00:12.000.123.456 and RESYNC_PERIOD is 00:00:00.000.005.000 (5us), the Event timestamp will be re-aligned to 00:00:12.000.125.000. This calculation is done after applying the delay defined by WRTD_ATTR_RULE_DELAY. The provided value must be less than 1 second.

WRTD_ATTR_RULE_RESYNC_FACTOR = __WRTD_ATTR_BASE + 0x29

RW int32 rule Further re-align the source Event timestamp to a multiple of WRTD_ATTR_RULE_RESYNC_PERIOD. As an example, if RESYNC_PERIOD is 5us and the provided value is 10, 50us will be added to the Event timestamp, after applying WRTD_ATTR_RULE_DELAY and re-aligning it to the RESYNC_PERIOD.

WRTD_ATTR_STAT_RULE_RX_EVENTS = __WRTD_ATTR_BASE + 0x30

RO int32 rule Number of received Events for a Rule.

WRTD_ATTR_STAT_RULE_RX_LAST = __WRTD_ATTR_BASE + 0x31

RO tstamp rule Timestamp of most recently received Event for a Rule.

WRTD_ATTR_STAT_RULE_TX_EVENTS = __WRTD_ATTR_BASE + 0x32

RO int32 rule Number of transmitted Events for a Rule.

WRTD_ATTR_STAT_RULE_TX_LAST = __WRTD_ATTR_BASE + 0x33

RO tstamp rule Timestamp of most recently transmitted Event for a Rule.

WRTD_ATTR_STAT_RULE_MISSED_LATE = __WRTD_ATTR_BASE + 0x34

RO int32 rule Number of received Events that arrived too late. See also WRTD_ATTR_RULE_SEND_LATE.

WRTD_ATTR_STAT_RULE_MISSED_HOLDOFF = __WRTD_ATTR_BASE + 0x35

RO int32 rule Number of received Events that arrived during hold-off. See also WRTD_ATTR_RULE_HOLDOFF.

WRTD_ATTR_STAT_RULE_MISSED_NOSYNC = __WRTD_ATTR_BASE + 0x36

RO int32 rule Number of received Events that were discarded because the device was not synchronized to White Rabbit. See also WRTD_ATTR_IS_TIME_SYNCHRONIZED.

WRTD_ATTR_STAT_RULE_MISSED_OVERFLOW = __WRTD_ATTR_BASE + 0x37

RO int32 rule Number of received Events that were discarded because of internal buffer overflows. This may happen if the Event rate is too high.

WRTD_ATTR_STAT_RULE_MISSED_LAST = __WRTD_ATTR_BASE + 0x38

RO tstamp rule Timestamp of most recently missed Event.

WRTD_ATTR_STAT_RULE_RX_LATENCY_MIN = __WRTD_ATTR_BASE + 0x39

RO tstamp rule Minimum latency between the Event timestamp and its reception by WRTD.

WRTD_ATTR_STAT_RULE_RX_LATENCY_MAX = __WRTD_ATTR_BASE + 0x3A

RO tstamp rule Maximum latency between the Event timestamp and its reception by WRTD.

WRTD_ATTR_STAT_RULE_RX_LATENCY_AVG = __WRTD_ATTR_BASE + 0x3B

RO tstamp rule Average latency between the Event timestamp and its reception by WRTD.

WRTD_ATTR_FW_COUNT = __WRTD_ATTR_BASE + 0x80

RO int32 global Number of separate WRTD firmware applications running on the device.

WRTD_ATTR_FW_MAJOR_VERSION = __WRTD_ATTR_BASE + 0x81

RO int32 application Major part of the firmware’s version.

WRTD_ATTR_FW_MINOR_VERSION = __WRTD_ATTR_BASE + 0x82

RO int32 application Major part of the firmware’s version.

WRTD_ATTR_FW_MAJOR_VERSION_REQUIRED = __WRTD_ATTR_BASE + 0x83

RO int32 application Major part of WRTD version supported by the firmware. It must be equal to the major version of the WRTD library in use.

WRTD_ATTR_FW_MINOR_VERSION_REQUIRED = __WRTD_ATTR_BASE + 0x84

RO int32 application Minor part of WRTD version supported by the firmware. It must be less than or equal to the minor version of the WRTD library in use.

WRTD_ATTR_FW_MAX_RULES = __WRTD_ATTR_BASE + 0x85

RO int32 application Max number of rules allowed by this firmware.

WRTD_ATTR_FW_MAX_ALARMS = __WRTD_ATTR_BASE + 0x86

RO int32 application Max number of alarms allowed by this firmware.

WRTD_ATTR_FW_CAPABILITIES = __WRTD_ATTR_BASE + 0x88

RO int32 application Event TX/RX capabilities of this firmware. This is a bit-field with the following meaning per bit:

  • bit 0: if set, the firmware can receive network events.
  • bit 1: if set, the firmware can create network events.
  • bit 2: if set, the firmware can receive local events.
  • bit 3: if set, the firmware can create local events.

WRTD_ATTR_FW_LOCAL_INPUTS = __WRTD_ATTR_BASE + 0x8A

RO int32 application Number of available local input channels.

WRTD_ATTR_FW_LOCAL_OUTPUTS = __WRTD_ATTR_BASE + 0x8B

RO int32 application Number of available local output channels.

__WRTD_ATTR_MAX_NUMBER

Always last entry in this enum

4.1.3.2. Functions

wrtd_status wrtd_set_attr_bool(wrtd_dev *wrtd, const char *rep_cap_id, wrtd_attr id, bool value)

Set an attribute of type bool.

Modelled after the IVI-C SetAttribute family of functions.

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: ID (string) of concerned repeated capability. If it is a global attribute, use WRTD_GLOBAL_REP_CAP_ID
  • id: ID (wrtd_attr) of concerned attribute.
  • value: Value to write to the attribute.

wrtd_status wrtd_get_attr_bool(wrtd_dev *wrtd, const char *rep_cap_id, wrtd_attr id, bool *value)

Get an attribute of type bool.

Modelled after the IVI-C GetAttribute family of functions.

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: ID (string) of concerned repeated capability. If it is a global attribute, use WRTD_GLOBAL_REP_CAP_ID
  • id: ID (wrtd_attr) of concerned attribute.
  • value: Retrieved attribute value.

wrtd_status wrtd_set_attr_int32(wrtd_dev *wrtd, const char *rep_cap_id, wrtd_attr id, int32_t value)

Set an attribute of type int32.

Modelled after the IVI-C SetAttribute family of functions.

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: ID (string) of concerned repeated capability. If it is a global attribute, use WRTD_GLOBAL_REP_CAP_ID
  • id: ID (wrtd_attr) of concerned attribute.
  • value: Value to write to the attribute.

wrtd_status wrtd_get_attr_int32(wrtd_dev *wrtd, const char *rep_cap_id, wrtd_attr id, int32_t *value)

Get an attribute of type int32.

Modelled after the IVI-C GetAttribute family of functions.

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: ID (string) of concerned repeated capability. If it is a global attribute, use WRTD_GLOBAL_REP_CAP_ID
  • id: ID (wrtd_attr) of concerned attribute.
  • value: Retrieved attribute value.

wrtd_status wrtd_set_attr_string(wrtd_dev *wrtd, const char *rep_cap_id, wrtd_attr id, const char *value)

Set an attribute of type string.

Modelled after the IVI-C SetAttribute family of functions.

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: ID (string) of concerned repeated capability. If it is a global attribute, use WRTD_GLOBAL_REP_CAP_ID
  • id: ID (wrtd_attr) of concerned attribute.
  • value: Value to write to the attribute.

wrtd_status wrtd_get_attr_string(wrtd_dev *wrtd, const char *rep_cap_id, wrtd_attr id, int32_t value_buf_size, char *value)

Get an attribute of type string.

Modelled after the IVI-C GetAttribute family of functions.

This function complies with IVI-3.2 section, 3.1.2.1 (Additional Compliance Rules for C Functions with ViChar Array Output Parameters), with the exception of the buffer_size < 0 case, which produces an error instead of allowing a potential buffer overflow.

Return
wrtd_status. However, if the buffer size parameter is 0, then this function returns instead a positive value, indicating the minimum buffer size necessary to fit the full message. See also IVI-3.2, section 3.1.2.1.
Parameters
  • wrtd: Device token.
  • rep_cap_id: ID (string) of concerned repeated capability. If it is a global attribute, use WRTD_GLOBAL_REP_CAP_ID
  • id: ID (wrtd_attr) of concerned attribute.
  • value_buffer_size: Size of pre-allocated value buffer.
  • value: Retrieved attribute value.

wrtd_status wrtd_set_attr_tstamp(wrtd_dev *wrtd, const char *rep_cap_id, wrtd_attr id, const wrtd_tstamp *value)

Set an attribute of type timestamp.

Modelled after the IVI-C SetAttribute family of functions.

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: ID (string) of concerned repeated capability. If it is a global attribute, use WRTD_GLOBAL_REP_CAP_ID
  • id: ID (wrtd_attr) of concerned attribute.
  • value: Value to write to the attribute.

wrtd_status wrtd_get_attr_tstamp(wrtd_dev *wrtd, const char *rep_cap_id, wrtd_attr id, wrtd_tstamp *value)

Get an attribute of type timestamp.

Modelled after the IVI-C GetAttribute family of functions.

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: ID (string) of concerned repeated capability. If it is a global attribute, use WRTD_GLOBAL_REP_CAP_ID
  • id: ID (wrtd_attr) of concerned attribute.
  • value: Retrieved attribute value.

Listing 4.4 Accessing various types of attributes.
#include <libwrtd.h>

int main(void) {
        wrtd_dev *wrtd;
        wrtd_status status;
        wrtd_tstamp ts;
        bool log_empty;

        status = wrtd_init(1, false, NULL, &wrtd);

        /* check if the event log is empty (global attribute) */
        status = wrtd_get_attr_bool(wrtd, WRTD_GLOBAL_REP_CAP_ID,
                                    WRTD_ATTR_EVENT_LOG_EMPTY,
                                    &log_empty);

        /* add a rule with name "rule1" */
        status = wrtd_add_rule(wrtd, "rule1");

        /* set the repeat count for "rule1 */
        status = wrtd_set_attr_int32(wrtd, "rule1",
                                     WRTD_ATTR_RULE_REPEAT_COUNT, 5);

        /* set the source for "rule1" to local channel input 1 */
        status = wrtd_set_attr_string(wrtd, "rule1",
                                      WRTD_ATTR_RULE_SOURCE, "LC-I1");

        /* get the delay configured for "rule1" */
        status = wrtd_get_attr_tstamp(wrtd, "rule1",
                                      WRTD_ATTR_RULE_DELAY, &ts");

        wrtd_close(wrtd);
}

Important

wrtd_get_attr_tstamp() and wrtd_set_attr_tstamp() allow getting and setting of timestamp attributes. Within the C library, a timestamp is represented as a C struct:

struct wrtd_tstamp

WRTD timestamp format

Public Members

uint32_t seconds

TAI seconds since 1/Jan/1970 (Unix Epoch Time). This will overflow in 7/Feb/2106…

uint32_t ns

Number of nanoseconds. Wraps at 1e9.

uint32_t frac

Number of fractional nanoseconds. Unit is 2^(-32) ns.

Note that the above internal representation is slightly different than the official definition of a timestamp. In particular, the seconds counter is 16-bits shorter and the fractional nanosecond counter is 16 bits longer (and every “tick” represents 2-32ns). Both of these changes help the underlying firmware to operate faster. When WRTD sends (or receives) a message, it will always use the official definition of a timestamp and convert it automatically to the above internal representation when necessary.

4.1.4. Event Logging API

The Event Logging API provides functions for accessing the Event Log.

wrtd_status wrtd_clear_event_log_entries(wrtd_dev *wrtd)

Clear all entries from the Event Log.

Modelled after the IVI-C ClearEventLog function (from IVI-3.15).

Return
wrtd_status.
Parameters
  • wrtd: Device token.

wrtd_status wrtd_get_next_event_log_entry(wrtd_dev *wrtd, int32_t log_entry_buffer_size, char *log_entry)

Retrieve and clear the last entry from the Event Log.

Modelled after the IVI-C GetNextEventLogEntry function (from IVI-3.15).

This function complies with IVI-3.2, section 3.1.2.1 (Additional Compliance Rules for C Functions with ViChar Array Output Parameters), with the exception of the buffer_size < 0 case, which produces an error instead of allowing a potential buffer overflow.

Event log entries use the format id|seq|log tstamp|event tstamp|log type|log reason, where:

  • id is the Event ID.
  • seq is a sequence number for the rule that generated this Event. Each Event generated by the Rule causes the sequence number to increase by one. Limited to 4 digits.
  • log tstamp is the timestamp of when the event was logged.
  • event tstamp is the timestamp of when the event happened.
  • log type is the type of the event.
  • log reason is the specific reason for this type of event.

All event log entries have a fixed length of WRTD_LOG_ENTRY_SIZE.

Timestamps are represented using the format YYYY-MM-DD,hh:mm:ss.mmm.uuu.nnn+fff, where:

  • YYYY-MM-DD is the year, month and day.
  • hh:mm:ss is hours, minutes and seconds.
  • mmm.uuu.nnn is milliseconds, microseconds and nanoseconds.
  • fff is fractional nanoseconds. The unit is 2e-9 nanoseconds.

Log types and reasons can be one of the following (in the form type|reason):

  • GENERATED|ALARM : An Event was generated because of an Alarm.
  • GENERATED|DEVICE_x: An Event was generated from device x.
  • CONSUMED|START : An Event with a local channel output as destination has been forwarded and scheduled to execute. The exact meaning of this log type is application-specific.
  • CONSUMED|DONE : An Event with a local channel output as destination has finished executing. The exact meaning of this log type is application-specific.
  • DISCARDED|NO SYNC : An Event was discarded because the device was not syncrhonized to White Rabbit. See also WRTD_ATTR_STAT_RULE_MISSED_NOSYNC.
  • DISCARDED|HOLD OFF: An Event was discarded because it violated the programmed hold-off value. See also WRTD_ATTR_STAT_RULE_MISSED_HOLDOFF.
  • DISCARDED|TIME OUT: An Event was discarded because it arrived too late. See also WRTD_ATTR_STAT_RULE_MISSED_LATE.
  • DISCARDED|OVERFLOW: An Event was discarded because of internal buffer overflows. This may happen if the Event rate is too high. See also WRTD_ATTR_STAT_RULE_MISSED_OVERFLOW.
  • NETWORK|TX : An Event was sent over the White Rabbit network.
  • NETWORK|RX : An Event was received over the White Rabbit network.

Return
wrtd_status. However, if the buffer size parameter is 0, then this function returns instead a positive value, indicating the minimum buffer size necessary to fit the full message. See also IVI-3.2, section 3.1.2.1.
Parameters
  • wrtd: Device token.
  • log_entry_buffer_size: Size of pre-allocated log_entry buffer.
  • log_entry: Buffer to store the log message string.

Listing 4.5 Accessing the Event Log.
#include <libwrtd.h>

int main(void) {
        wrtd_dev *wrtd;
        char *log_msg;
        int buf_size;

        status = wrtd_init(1, false, NULL, &wrtd);

        /* clear the event log */
        status = wrtd_clean_event_log_entries(wrtd);

        /* query the size of the next event log message */
        buf_size = wrtd_get_next_event_log_entry(wrtd, 0, NULL);

        /* allocate the buffer for the log message */
        log_msg = calloc(sizeof(char), buf_size);

        /* retrieve the next event log message */
        status = wrtd_get_next_event_log_entry(wrtd, buf_size, log_msg);

        wrtd_close(wrtd);

        return 0;
}

Hint

If you want to be sure that the buffer that you pass to wrtd_get_next_event_log_entry() is large enough, without having to resort to querying like in Listing 4.5, you can always allocate a buffer of WRTD_LOG_ENTRY_SIZE. WRTD guarantees that all event log entries shall not exceed this size.

WRTD_LOG_ENTRY_SIZE

Size (in characters, including null termination) of an event log enty.

Listing 4.6 Accessing the Event Log with a pre-defined buffer size
#include <libwrtd.h>

int main(void) {
        wrtd_dev *wrtd;
        char log_msg[WRTD_LOG_ENTRY_SIZE];

        status = wrtd_init(1, false, NULL, &wrtd);

        /* retrieve the next event log message */
        status = wrtd_get_next_event_log_entry(wrtd, WRTD_LOG_ENTRY_SIZE, log_msg);

        wrtd_close(wrtd);

        return 0;
}

4.1.5. Alarms API

The Alarms API provides functions for adding, removing and indexing Alarms.

Configuration of an Alarm happens by setting the relevant Attributes via the Attribute Handling API.

wrtd_status wrtd_add_alarm(wrtd_dev *wrtd, const char *rep_cap_id)

Create a new Alarm.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: Name for the new Alarm. Must begin with ‘alarm’ or ‘ALARM’.

wrtd_status wrtd_disable_all_alarms(wrtd_dev *wrtd)

Disable all defined Alarms.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

See also, WRTD_ATTR_ALARM_ENABLED and wrtd_set_attr_bool for disabling a single Alarm.

Return
wrtd_status
Parameters
  • wrtd: Device token.

wrtd_status wrtd_remove_alarm(wrtd_dev *wrtd, const char *rep_cap_id)

Remove an Alarm. The Alarm must not be enabled.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: Name of the Alarm to remove.

wrtd_status wrtd_remove_all_alarms(wrtd_dev *wrtd)

Remove all defined Alarms. The Alarms must not be enabled.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

Return
wrtd_status
Parameters
  • wrtd: Device token.

wrtd_status wrtd_get_alarm_name(wrtd_dev *wrtd, int32_t index, int32_t name_buffer_size, char *name)

Retrieve the name of an Alarm, based on the provided index.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

This function complies with IVI-3.2, section 3.1.2.1 (Additional Compliance Rules for C Functions with ViChar Array Output Parameters), with the exception of the buffer_size < 0 case, which produces an error instead of allowing a potential buffer overflow.

Return
wrtd_status. See also IVI-3.2, section 3.1.2.1.
Parameters
  • wrtd: Device token.
  • index: index of the Alarm.
  • name_buffer_size: Size of pre-allocated name buffer.
  • name: Buffer to store the retrieved Alarm name.

Listing 4.7 Adding, removing and indexing Alarms.
#include <libwrtd.h>

int main(void) {
        int i, count;
        char rep_cap_id[16];
        wrtd_dev *wrtd;

        status = wrtd_init(1, false, NULL, &wrtd);

        /* disable and then remove any declared alarms */
        status = wrtd_disable_all_alarms(wrtd);
        status = wrtd_remove_all_alarms(wrtd);

        /* Add three alarms */
        status = wrtd_add_alarm(wrtd, "alarm1");
        status = wrtd_add_alarm(wrtd, "alarm2");
        status = wrtd_add_alarm(wrtd, "alarm3");

        /* Remove the 2nd alarm */
        status = wrtd_remove_alarm(wrtd, "alarm2");

        /* Get number of defined alarms */
        status = wrtd_get_attr_int32(wrtd, WRTD_GLOBAL_REP_CAP_ID,
                                     WRTD_ATTR_ALARM_COUNT, &count);

        /* Iterate through alarms and print their names.
           This should output:
           1: alarm1
           2: alarm3
         */
        for (i = 0; i < count; i++) {
                status = wrtd_get_alarm_name(wrtd, i, 16, rep_cap_id);
                printf ("%d: %s\n", i, rep_cap_id);
        }

        wrtd_close(wrtd);

        return 0;
}

4.1.6. Rules API

The Rules API provides functions for adding, removing and indexing Rules.

Configuration of a Rule happens by setting the relevant Attributes via the Attribute Handling API.

wrtd_status wrtd_add_rule(wrtd_dev *wrtd, const char *rep_cap_id)

Create a new Rule.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: Name for the new Rule.

wrtd_status wrtd_disable_all_rules(wrtd_dev *wrtd)

Disable all defined Rules.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

See also, WRTD_ATTR_RULE_ENABLED and wrtd_set_attr_bool for disabling a single Rule.

Return
wrtd_status
Parameters
  • wrtd: Device token.

wrtd_status wrtd_remove_rule(wrtd_dev *wrtd, const char *rep_cap_id)

Remove a Rule. The Rule must not be enabled.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: Name of the Rule to remove.

wrtd_status wrtd_remove_all_rules(wrtd_dev *wrtd)

Remove all defined Rules. The Rules must not be enabled.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

Return
wrtd_status
Parameters
  • wrtd: Device token.

wrtd_status wrtd_get_rule_name(wrtd_dev *wrtd, int32_t index, int32_t name_buffer_size, char *name)

Retrieve the name of a Rule, based on the provided index.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

This function complies with IVI-3.2, section 3.1.2.1 (Additional Compliance Rules for C Functions with ViChar Array Output Parameters), with the exception of the buffer_size < 0 case, which produces an error instead of allowing a potential buffer overflow.

Return
wrtd_status. See also IVI-3.2, section 3.1.2.1.
Parameters
  • wrtd: Device token.
  • index: index of the Rule.
  • name_buffer_size: Size of pre-allocated name buffer.
  • name: Buffer to store the retrieved Rule name.

wrtd_status wrtd_reset_rule_stats(wrtd_dev *wrtd, const char *rep_cap_id)

Reset all statistics for the given rule. The Rule must not be enabled.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

Return
wrtd_status
Parameters
  • wrtd: Device token.
  • rep_cap_id: Name of the Rule to reset its statistics.

Listing 4.8 Adding, removing and indexing Rules.
#include <libwrtd.h>

int main(void) {
        int i, count;
        char rep_cap_id[16];
        wrtd_dev *wrtd;

        status = wrtd_init(1, false, NULL, &wrtd);

        /* disable and then remove any declared rules */
        status = wrtd_disable_all_rules(wrtd);
        status = wrtd_remove_all_rules(wrtd);

        /* Add three rules */
        status = wrtd_add_rule(wrtd, "rule1");
        status = wrtd_add_rule(wrtd, "rule2");
        status = wrtd_add_rule(wrtd, "rule3");

        /* Remove the 2nd rule */
        status = wrtd_remove_rule(wrtd, "rule2");

        /* Get number of defined rules */
        status = wrtd_get_attr_int32(wrtd, WRTD_GLOBAL_REP_CAP_ID,
                                     WRTD_ATTR_RULE_COUNT, &count);

        /* Iterate through rules and print their names.
           This should output:
           1: rule1
           2: rule3
         */
        for (i = 0; i < count; i++) {
                status = wrtd_get_rule_name(wrtd, i, 16, rep_cap_id);
                printf ("%d: %s\n", i, rep_cap_id);
        }

        wrtd_close(wrtd);

        return 0;
}
Listing 4.9 Basic Rule configuration.
#include <libwrtd.h>

int main(void) {
        wrtd_dev *wrtd;

        status = wrtd_init(1, false, NULL, &wrtd);

        /* Add a rule */
        status = wrtd_add_rule(wrtd, "rule1");

        /* Set rule to listen for events coming on local channel
           input 1 and generate a message on the network with
           event ID "NET0", after adding 500ns to the event timestamp. */
        status = wrtd_set_attr_string(wrtd, "rule1",
                                      WRTD_ATTR_RULE_SOURCE, "LC-I1");
        status = wrtd_set_attr_string(wrtd, "rule1",
                                      WRTD_ATTR_RULE_DESTINATION, "NET0");
        wrtd_tstamp ts = {.seconds = 0, .ns = 500, .frac = 0};
        status = wrtd_set_attr_tstamp(wrtd, "rule1",
                                      WRTD_ATTR_RULE_DELAY, &ts);

        /* Enable rule */
        status = wrtd_set_attr_bool(wrtd, "rule1",
                                    WRTD_ATTR_RULE_ENABLED, True);

        wrtd_close(wrtd);

        return 0;
}

4.1.7. Applications API

Similar to Rules and Alarms, Applications are also Repeated Capabilities. However, they are read-only and, as such, do not possess any functions to add or remove them. The only provided functionality is that of indexing.

Information retrieval regarding a particular Application is performed by by getting the relevant Attributes via the Attribute Handling API.

wrtd_status wrtd_get_fw_name(wrtd_dev *wrtd, int32_t index, int32_t name_buffer_size, char *name)

Retrieve the name of a firmware application, based on the provided index.

Complies with the IVI “Parameter style” for repeated capabilities (see IVI-3.4, section 12).

This function complies with IVI-3.2, section 3.1.2.1 (Additional Compliance Rules for C Functions with ViChar Array Output Parameters), with the exception of the buffer_size < 0 case, which produces an error instead of allowing a potential buffer overflow.

Return
wrtd_status. See also IVI-3.2, section 3.1.2.1.
Parameters
  • wrtd: Device token.
  • index: index of the firmware application.
  • name_buffer_size: Size of pre-allocated name buffer.
  • name: Buffer to store the retrieved application name.

Listing 4.10 Indexing Applications and version retrieval.
#include <libwrtd.h>

int main(void) {
        int i, count, major, minor;
        char rep_cap_id[16];
        wrtd_dev *wrtd;

        status = wrtd_init(1, false, NULL, &wrtd);

        /* Get number of defined applications */
        status = wrtd_get_attr_int32(wrtd, WRTD_GLOBAL_REP_CAP_ID,
                                     WRTD_ATTR_FW_COUNT, &count);

        /* Iterate through applications and print their
           names and versions. */
        for (i = 0; i < count; i++) {
                status = wrtd_get_fw_name(wrtd, i, 16, rep_cap_id);
                status = wrtd_get_attr_int32(wrtd, rep_cap_id,
                                             WRTD_ATTR_FW_MAJOR_VERSION,
                                             &major);
                status = wrtd_get_attr_int32(wrtd, rep_cap_id,
                                             WRTD_ATTR_FW_MINOR_VERSION,
                                             &minor);
                printf ("%d: %s, v%d.%d\n", i, rep_cap_id, major, minor);
        }

        wrtd_close(wrtd);

        return 0;
}