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:
- IVI-3.1 Driver Architecture Specification
- IVI-3.2 Inherent Capabilities Specification
- IVI-3.4 API Style Guide
- IVI-3.15 IviLxiSync Specification
- LXI Core Specification
- LXI Event Messaging Extended Function
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-allocatederror_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.
#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 IDreset
: 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
#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:
wrtd_set_attr_bool()
wrtd_get_attr_bool()
wrtd_set_attr_int32()
wrtd_get_attr_int32()
wrtd_set_attr_string()
wrtd_get_attr_string()
wrtd_set_attr_tstamp()
wrtd_get_attr_tstamp()
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.
#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_IDid
: 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_IDid
: 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_IDid
: 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_IDid
: 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_IDid
: 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_IDid
: ID (wrtd_attr) of concerned attribute.value_buffer_size
: Size of pre-allocatedvalue
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_IDid
: 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_IDid
: ID (wrtd_attr) of concerned attribute.value
: Retrieved attribute value.
#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
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-allocatedlog_entry
buffer.log_entry
: Buffer to store the log message string.
#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.
#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-allocatedname
buffer.name
: Buffer to store the retrieved Alarm name.
#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-allocatedname
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.
#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;
}
#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-allocatedname
buffer.name
: Buffer to store the retrieved application name.
#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;
}