Newer
Older
/**
* @file libwrtd.c
*
* Copyright (c) 2018-2019 CERN (home.cern)
*
* SPDX-License-Identifier: LGPL-2.1-or-later
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include "mockturtle/libmockturtle.h"
#include "libwrtd.h"
#include "libwrtd-private.h"
* Functions to manage the basic Node and library configuration.
/**
* Retrieve the number of detected WRTD Nodes.
*
* @param[out] count number of detected WRTD Nodes
* @return #wrtd_status
*/
wrtd_status wrtd_get_node_count(uint32_t *count)
{
int i;
uint32_t dev_count = 0;
struct trtl_dev *trtl;
const struct trtl_config_rom *cfgrom;
char **dev_list = trtl_list();
if (!dev_list)
return WRTD_ERROR_INTERNAL;
for (i = 0; dev_list[i]; i++) {
trtl = trtl_open(dev_list[i]);
if (trtl == NULL) {
trtl_list_free(dev_list);
return WRTD_ERROR_RESOURCE_UNKNOWN;
}
cfgrom = trtl_config_get(trtl);
if (wrtd_node_id_match(cfgrom->app_id))
dev_count++;
trtl_close(trtl);
}
trtl_list_free(dev_list);
*count = dev_count;
return WRTD_SUCCESS;
}
/**
* 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.
*
* @param[in] index The index of the Node ("1" for the first Node, etc.)
* @param[out] node_id The retrieved ID of the Node
* @return #wrtd_status
*/
wrtd_status wrtd_get_node_id(uint32_t index, uint32_t *node_id)
{
int i;
uint32_t dev_count = 0;
struct trtl_dev *trtl;
const struct trtl_config_rom *cfgrom;
char **dev_list = trtl_list();
if (!dev_list)
return WRTD_ERROR_INTERNAL;
*node_id = 0;
for (i = 0; dev_list[i]; i++) {
trtl = trtl_open(dev_list[i]);
if (trtl == NULL) {
trtl_list_free(dev_list);
return WRTD_ERROR_RESOURCE_UNKNOWN;
}
cfgrom = trtl_config_get(trtl);
if (wrtd_node_id_match(cfgrom->app_id))
dev_count++;
if (dev_count == index) {
char *eptr;
/* expecting string in the form of "trtl-xxxx, where
xxxx is a hex integer */
*node_id = strtoul(dev_list[i]+5, &eptr, 16);
if (*eptr != 0) {
trtl_list_free(dev_list);
trtl_close(trtl);
return WRTD_ERROR_INTERNAL;
}
}
trtl_close(trtl);
}
trtl_list_free(dev_list);
if (*node_id == 0)
return WRTD_ERROR_RESOURCE_UNKNOWN;
return WRTD_SUCCESS;
}
* Initialize the WRTD Node and obtain the WRTD device token.
* @param[in] node_id WRTD Node ID
* @param[in] options_str Reserved for future use.
* @param[out] wrtd Pointer to WRTD device token.
* @return #wrtd_status
*/
wrtd_status wrtd_init(uint32_t node_id,
bool reset,
const char *options_str,
wrtd_dev **wrtd)
int i;
struct trtl_dev *trtl;
const struct trtl_config_rom *cfgrom;
struct wrtd_config_msg msg;
/* In case of error... */
trtl = trtl_open_by_id(node_id);
return WRTD_ERROR_RESOURCE_UNKNOWN;
if (res == NULL)
return WRTD_ERROR_OUT_OF_MEMORY;
memset(res, 0, sizeof(*res));
res->trtl = trtl;
cfgrom = trtl_config_get(res->trtl);
if (cfgrom->n_cpu > WRTD_MAX_CPUS)
return wrtd_return_error(res, WRTD_ERROR_INTERNAL,
"%s: Too many CPUs detected.", __func__);
/* Set HMQ words. */
for (i = 0; i < cfgrom->n_cpu; i++) {
if (cfgrom->n_hmq[i] > 0)
res->hmq_words[i] = TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD
(cfgrom->hmq[i][0].sizes);
for (i = 0; i < cfgrom->n_cpu; i++) {
status = wrtd_msg_get_config(res, i, &msg, __func__);
WRTD_RETURN_IF_ERROR(status);
res->root_addr[i] = msg.root_addr;
}
for (i = 0; i < cfgrom->n_cpu; i++) {
if (trtl_fw_version(res->trtl, i, WRTD_HMQ, &res->fw_version[i]) < 0)
return wrtd_return_error(
res, WRTD_ERROR_INTERNAL,
"%s: Could not retrieve firmware vesion info (%s)",
__func__, trtl_strerror(errno));
}
res->nbr_cpus = cfgrom->n_cpu;
if (reset) {
status = wrtd_reset(res);
if (status != WRTD_SUCCESS)
return status;
}
*
* @param[in] wrtd Device token.
* @return #wrtd_status
*/
wrtd_status wrtd_close(wrtd_dev *wrtd)
return WRTD_ERROR_NOT_INITIALIZED;
free(wrtd->alarms);
free(wrtd->rules);
free(wrtd);
return WRTD_SUCCESS;
}
* Reset a WRTD Node. This will remove all defined Alarms and Rules.
*
* @param[in] wrtd Device token.
* @return #wrtd_status
*/
wrtd_status wrtd_reset(wrtd_dev *wrtd)
return WRTD_ERROR_NOT_INITIALIZED;
status = wrtd_disable_all_alarms(wrtd);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_disable_all_rules(wrtd);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_remove_all_alarms(wrtd);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_remove_all_rules(wrtd);
WRTD_RETURN_IF_ERROR(status);
* 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.
*
* @param[in] wrtd Device token.
* @param[out] error_code #wrtd_status pointer to return the error code. Ignored if NULL.
* @param[in] error_description_buffer_size Size of pre-allocated `error_description` buffer.
* @param[out] error_description Buffer to store the detailed error message string.
* @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.
wrtd_status wrtd_get_error(wrtd_dev *wrtd,
wrtd_status *error_code,
int32_t error_description_buffer_size,
char *error_description)
int ret;
return WRTD_ERROR_NOT_INITIALIZED;
char error_message[WRTD_ERR_MSG_BUF_SIZE];
memset(error_message, 0, WRTD_ERR_MSG_BUF_SIZE);
status = wrtd_error_message(wrtd, wrtd->err, error_message);
WRTD_RETURN_IF_ERROR(status);
int required_buffer_size =
strlen(error_message) + strlen(wrtd->error_msg) + 2;
/* If buffer_size is zero, just report on necessary
buffer size. According to IVI-3.2, section 3.1.2.1. */
if (error_description_buffer_size == 0)
return required_buffer_size;
return wrtd_return_error
(wrtd, WRTD_ERROR_NULL_POINTER,
"Null pointer passed for function %s, "
"parameter error_description", __func__);
/* This violates IVI-3.2, section 3.1.2.1 which dictates to
ignore overflow if buffer_size is negative. Still, it is
the safer thing to do.*/
if (error_description_buffer_size < 0)
return wrtd_return_error(wrtd, WRTD_ERROR_INVALID_VALUE,
"Invalid value (%d) for function %s, "
"parameter error_description_buffer_size",
error_description_buffer_size, __func__);
*error_code = wrtd->err;
ret = snprintf(error_description, error_description_buffer_size,
"%s %s", error_message, wrtd->error_msg);
if (ret < error_description_buffer_size)
status = WRTD_SUCCESS;
else
status = ret + 1;
wrtd->err = 0;
memset(wrtd->error_msg, 0, sizeof(wrtd->error_msg));
return status;
}
* Convert a #wrtd_status error code to a string.
*
* Modelled after the IVI-C ErrorMessage function.
* @param[in] wrtd Device token. Can be NULL to allow calling this function
* even when initialisation has failed.
* @param[in] err_code #wrtd_status error code to convert.
* @param[out] err_message Buffer of at least #WRTD_ERR_MSG_BUF_SIZE bytes
* to store the resulting string.
* @return #wrtd_status
*/
wrtd_status wrtd_error_message(wrtd_dev *wrtd,
wrtd_status err_code,
char *err_message)
{
if (err_message == NULL) {
if (wrtd != NULL)
return wrtd_return_error
(wrtd, WRTD_ERROR_NULL_POINTER,
"Null pointer passed for function %s, "
"parameter err_message", __func__);
}
switch(err_code){
case WRTD_SUCCESS:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE, "WRTD_SUCCESS");
break;
case WRTD_ERROR_INVALID_ATTRIBUTE:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_INVALID_ATTRIBUTE");
break;
case WRTD_ERROR_ATTR_NOT_WRITEABLE:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_ATTR_NOT_WRITEABLE");
break;
case WRTD_ERROR_ATTR_NOT_READABLE:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_ATTR_NOT_READABLE");
break;
case WRTD_ERROR_INVALID_VALUE:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_INVALID_VALUE");
break;
case WRTD_ERROR_NOT_INITIALIZED:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_NOT_INITIALIZED");
break;
case WRTD_ERROR_UNKNOWN_CHANNEL_NAME:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_UNKNOWN_CHANNEL_NAME");
break;
case WRTD_ERROR_OUT_OF_MEMORY:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_OUT_OF_MEMORY");
break;
case WRTD_ERROR_NULL_POINTER:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_NULL_POINTER");
break;
case WRTD_ERROR_UNEXPECTED_RESPONSE:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_UNEXPECTED_RESPONSE");
break;
case WRTD_ERROR_RESOURCE_UNKNOWN:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_RESOURCE_UNKNOWN");
break;
case WRTD_ERROR_BADLY_FORMED_SELECTOR:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_BADLY_FORMED_SELECTOR");
break;
case WRTD_ERROR_ALARM_EXISTS:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_ALARM_EXISTS");
break;
case WRTD_ERROR_ALARM_DOES_NOT_EXIST:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_ALARM_DOES_NOT_EXIST");
break;
case WRTD_ERROR_VERSION_MISMATCH:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_VERSION_MISMATCH");
break;
case WRTD_ERROR_INTERNAL:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_INTERNAL");
break;
case WRTD_ERROR_UNKNOWN_LOG_TYPE:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_UNKNOWN_LOG_TYPE");
break;
case WRTD_ERROR_RESOURCE_ACTIVE:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_RESOURCE_ACTIVE");
break;
case WRTD_ERROR_ATTR_GLOBAL:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_ATTR_GLOBAL");
break;
case WRTD_ERROR_OUT_OF_RESOURCES:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_OUT_OF_RESOURCES");
break;
case WRTD_ERROR_RULE_EXISTS:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_RULE_EXISTS");
break;
case WRTD_ERROR_RULE_DOES_NOT_EXIST:
snprintf(err_message, WRTD_ERR_MSG_BUF_SIZE,
"WRTD_ERROR_RULE_DOES_NOT_EXIST");
break;
default:
if (wrtd != NULL)
return wrtd_return_error(wrtd, WRTD_ERROR_INVALID_VALUE,
"Invalid value (%d) for function %s, "
"parameter err_code",
err_code, __func__);
return WRTD_ERROR_INVALID_VALUE;
}
return WRTD_SUCCESS;
}
/**
*@} End group Base
*/
/**
* @defgroup Attributes
* Functions to get/set WRTD attributes.
* @{
*/
/**
* Set an attribute of type `bool`.
*
* Modelled after the IVI-C SetAttribute family of functions.
*
* @param[in] wrtd Device token.
* @param[in] rep_cap_id ID (string) of concerned repeated capability.
* If it is a global attribute, use #WRTD_GLOBAL_REP_CAP_ID
* @param[in] id ID (#wrtd_attr) of concerned attribute.
* @param[in] value Value to write to the attribute.
* @return #wrtd_status
*/
wrtd_status wrtd_set_attr_bool(wrtd_dev *wrtd,
const char *rep_cap_id,
wrtd_attr id,
bool value)
status = wrtd_validate_id(wrtd, rep_cap_id, __func__);
WRTD_RETURN_IF_ERROR(status);
switch(id) {
case WRTD_ATTR_EVENT_LOG_ENABLED:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
return wrtd_attr_set_log_enable
(wrtd, value);
case WRTD_ATTR_ALARM_ENABLED:
return wrtd_attr_set_alarm_enable
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_ENABLED:
return wrtd_attr_set_rule_enable
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_SEND_LATE:
return wrtd_attr_set_rule_send_late
(wrtd, rep_cap_id, value);
case WRTD_ATTR_EVENT_LOG_EMPTY:
case WRTD_ATTR_IS_TIME_SYNCHRONIZED:
return wrtd_return_error
(wrtd, WRTD_ERROR_ATTR_NOT_WRITEABLE,
"Attribute %u is read only.", id);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"Attribute ID %u is not recognized.", id);
* Get an attribute of type `bool`.
*
* Modelled after the IVI-C GetAttribute family of functions.
*
* @param[in] wrtd Device token.
* @param[in] rep_cap_id ID (string) of concerned repeated capability.
* If it is a global attribute, use #WRTD_GLOBAL_REP_CAP_ID
* @param[in] id ID (#wrtd_attr) of concerned attribute.
* @param[out] value Retrieved attribute value.
* @return #wrtd_status
*/
wrtd_status wrtd_get_attr_bool(wrtd_dev *wrtd,
const char *rep_cap_id,
wrtd_attr id,
bool *value)
status = wrtd_validate_id(wrtd, rep_cap_id, __func__);
WRTD_RETURN_IF_ERROR(status);
return wrtd_return_error
(wrtd, WRTD_ERROR_NULL_POINTER,
"Null pointer passed for function %s, "
"parameter value", __func__);
switch(id) {
case WRTD_ATTR_EVENT_LOG_ENABLED:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
return wrtd_attr_get_log_enable
(wrtd, value);
case WRTD_ATTR_EVENT_LOG_EMPTY:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
return wrtd_attr_get_log_empty
(wrtd, value);
case WRTD_ATTR_IS_TIME_SYNCHRONIZED:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
return wrtd_attr_get_time_sync
(wrtd, value);
case WRTD_ATTR_ALARM_ENABLED:
return wrtd_attr_get_alarm_enable
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_ENABLED:
return wrtd_attr_get_rule_enable
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_SEND_LATE:
return wrtd_attr_get_rule_send_late
(wrtd, rep_cap_id, value);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"Attribute ID %u is not recognized.", id);
* Set an attribute of type `int32`.
*
* Modelled after the IVI-C SetAttribute family of functions.
*
* @param[in] wrtd Device token.
* @param[in] rep_cap_id ID (string) of concerned repeated capability.
* If it is a global attribute, use #WRTD_GLOBAL_REP_CAP_ID
* @param[in] id ID (#wrtd_attr) of concerned attribute.
* @param[in] value Value to write to the attribute.
* @return #wrtd_status
*/
wrtd_status wrtd_set_attr_int32(wrtd_dev *wrtd,
const char *rep_cap_id,
wrtd_attr id,
int32_t value)
status = wrtd_validate_id(wrtd, rep_cap_id, __func__);
WRTD_RETURN_IF_ERROR(status);
switch(id) {
case WRTD_ATTR_ALARM_REPEAT_COUNT:
return wrtd_attr_set_alarm_repeat_count
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_REPEAT_COUNT:
return wrtd_attr_set_rule_repeat_count
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_RESYNC_FACTOR:
return wrtd_attr_set_rule_resync_factor
(wrtd, rep_cap_id, value);
case WRTD_ATTR_FW_COUNT:
case WRTD_ATTR_FW_MAJOR_VERSION:
case WRTD_ATTR_FW_MINOR_VERSION:
case WRTD_ATTR_FW_MAJOR_VERSION_REQUIRED:
case WRTD_ATTR_FW_MINOR_VERSION_REQUIRED:
case WRTD_ATTR_FW_MAX_RULES:
case WRTD_ATTR_FW_MAX_ALARMS:
case WRTD_ATTR_FW_CAPABILITIES:
case WRTD_ATTR_FW_LOCAL_INPUTS:
case WRTD_ATTR_FW_LOCAL_OUTPUTS:
case WRTD_ATTR_ALARM_COUNT:
case WRTD_ATTR_RULE_COUNT:
case WRTD_ATTR_STAT_RULE_RX_EVENTS:
case WRTD_ATTR_STAT_RULE_TX_EVENTS:
case WRTD_ATTR_STAT_RULE_MISSED_LATE:
case WRTD_ATTR_STAT_RULE_MISSED_HOLDOFF:
case WRTD_ATTR_STAT_RULE_MISSED_NOSYNC:
case WRTD_ATTR_STAT_RULE_MISSED_OVERFLOW:
return wrtd_return_error
(wrtd, WRTD_ERROR_ATTR_NOT_WRITEABLE,
"Attribute %u is read only.", id);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"Attribute ID %u is not recognized.", id);
}
* Get an attribute of type `int32`.
*
* Modelled after the IVI-C GetAttribute family of functions.
*
* @param[in] wrtd Device token.
* @param[in] rep_cap_id ID (string) of concerned repeated capability.
* If it is a global attribute, use #WRTD_GLOBAL_REP_CAP_ID
* @param[in] id ID (#wrtd_attr) of concerned attribute.
* @param[out] value Retrieved attribute value.
* @return #wrtd_status
*/
wrtd_status wrtd_get_attr_int32(wrtd_dev *wrtd,
const char *rep_cap_id,
wrtd_attr id,
int32_t *value)
status = wrtd_validate_id(wrtd, rep_cap_id, __func__);
WRTD_RETURN_IF_ERROR(status);
return wrtd_return_error
(wrtd, WRTD_ERROR_NULL_POINTER,
"Null pointer passed for function %s, "
"parameter value", __func__);
case WRTD_ATTR_FW_COUNT:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
*value = wrtd->nbr_cpus;
return WRTD_SUCCESS;
case WRTD_ATTR_FW_MAJOR_VERSION:
status = wrtd_attr_get_fw_major_version
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
case WRTD_ATTR_FW_MINOR_VERSION:
status = wrtd_attr_get_fw_minor_version
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_FW_MAJOR_VERSION_REQUIRED:
status = wrtd_attr_get_fw_major_version_required
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_FW_MINOR_VERSION_REQUIRED:
status = wrtd_attr_get_fw_minor_version_required
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
case WRTD_ATTR_FW_MAX_RULES:
status = wrtd_attr_get_fw_max_rules
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_FW_MAX_ALARMS:
status = wrtd_attr_get_fw_max_alarms
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_FW_CAPABILITIES:
status = wrtd_attr_get_fw_capabilities
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_FW_LOCAL_INPUTS:
status = wrtd_attr_get_fw_local_inputs
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_FW_LOCAL_OUTPUTS:
status = wrtd_attr_get_fw_local_outputs
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
case WRTD_ATTR_ALARM_COUNT:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_attr_get_alarm_count
(wrtd, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_ALARM_REPEAT_COUNT:
return wrtd_attr_get_alarm_repeat_count
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_COUNT:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_attr_get_rule_count
(wrtd, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_RULE_REPEAT_COUNT:
return wrtd_attr_get_rule_repeat_count
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_RESYNC_FACTOR:
return wrtd_attr_get_rule_resync_factor
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_RX_EVENTS:
return wrtd_attr_get_stat_rule_rx_events
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_TX_EVENTS:
return wrtd_attr_get_stat_rule_tx_events
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_MISSED_LATE:
return wrtd_attr_get_stat_rule_missed_late
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_MISSED_HOLDOFF:
return wrtd_attr_get_stat_rule_missed_holdoff
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_MISSED_NOSYNC:
Dimitris Lampridis
committed
return wrtd_attr_get_stat_rule_missed_nosync
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_MISSED_OVERFLOW:
return wrtd_attr_get_stat_rule_missed_overflow
(wrtd, rep_cap_id, value);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"Attribute ID %u is not recognized.", id);
}
* Set an attribute of type `string`.
*
* Modelled after the IVI-C SetAttribute family of functions.
*
* @param[in] wrtd Device token.
* @param[in] rep_cap_id ID (string) of concerned repeated capability.
* If it is a global attribute, use #WRTD_GLOBAL_REP_CAP_ID
* @param[in] id ID (#wrtd_attr) of concerned attribute.
* @param[in] value Value to write to the attribute.
* @return #wrtd_status
*/
wrtd_status wrtd_set_attr_string(wrtd_dev *wrtd,
const char *rep_cap_id,
wrtd_attr id,
const char *value)
status = wrtd_validate_id(wrtd, rep_cap_id, __func__);
WRTD_RETURN_IF_ERROR(status);
switch(id) {
case WRTD_ATTR_RULE_SOURCE:
return wrtd_attr_set_rule_source
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_DESTINATION:
return wrtd_attr_set_rule_destination
(wrtd, rep_cap_id, value);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"Attribute ID %u is not recognized.", id);
}
}
* 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.
*
* @param[in] wrtd Device token.
* @param[in] rep_cap_id ID (string) of concerned repeated capability.
* If it is a global attribute, use #WRTD_GLOBAL_REP_CAP_ID
* @param[in] id ID (#wrtd_attr) of concerned attribute.
* @param[in] value_buffer_size Size of pre-allocated `value` buffer.
* @param[out] value Retrieved attribute value.
* @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.
wrtd_status wrtd_get_attr_string(wrtd_dev *wrtd,
const char *rep_cap_id,
wrtd_attr id,
int32_t value_buffer_size,
char *value)
status = wrtd_validate_id(wrtd, rep_cap_id, __func__);
WRTD_RETURN_IF_ERROR(status);
Dimitris Lampridis
committed
if ((value_buffer_size != 0) && (value == NULL)) {
return wrtd_return_error
(wrtd, WRTD_ERROR_NULL_POINTER,
"Null pointer passed for function %s, "
"parameter value", __func__);
switch(id) {
case WRTD_ATTR_RULE_SOURCE:
return wrtd_attr_get_rule_source
(wrtd, rep_cap_id, value_buffer_size, value);
case WRTD_ATTR_RULE_DESTINATION:
return wrtd_attr_get_rule_destination
(wrtd, rep_cap_id, value_buffer_size, value);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"Attribute ID %u is not recognized.", id);
* Set an attribute of type `timestamp` (#wrtd_tstamp).
*
* Modelled after the IVI-C SetAttribute family of functions.
*
* @param[in] wrtd Device token.
* @param[in] rep_cap_id ID (string) of concerned repeated capability.
* If it is a global attribute, use #WRTD_GLOBAL_REP_CAP_ID
* @param[in] id ID (#wrtd_attr) of concerned attribute.
* @param[in] value Value (#wrtd_tstamp) to write to the attribute.
* If the `ns` part is greater or equal to 1e9, the `seconds` part will be
* automatically increased and the `ns` part will be reduced accordingly.
* @return #wrtd_status
*/
wrtd_status wrtd_set_attr_tstamp(wrtd_dev *wrtd,
const char *rep_cap_id,
wrtd_attr id,
wrtd_tstamp *value)
status = wrtd_validate_id(wrtd, rep_cap_id, __func__);
WRTD_RETURN_IF_ERROR(status);
return wrtd_return_error
(wrtd, WRTD_ERROR_NULL_POINTER,
"Null pointer passed for function %s, "
"parameter value", __func__);
while (value->ns >= 1e9) {
value->seconds++;
value->ns -= 1e9;
}
switch(id) {
case WRTD_ATTR_ALARM_TIME:
return wrtd_attr_set_alarm_time
(wrtd, rep_cap_id, value);
case WRTD_ATTR_ALARM_SETUP_TIME:
return wrtd_attr_set_alarm_setup_time
(wrtd, rep_cap_id, value);
case WRTD_ATTR_ALARM_PERIOD:
return wrtd_attr_set_alarm_period
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_DELAY:
return wrtd_attr_set_rule_delay
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_HOLDOFF:
return wrtd_attr_set_rule_holdoff
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_RESYNC_PERIOD:
return wrtd_attr_set_rule_resync_period
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_RX_LAST:
case WRTD_ATTR_STAT_RULE_TX_LAST:
case WRTD_ATTR_STAT_RULE_MISSED_LAST:
case WRTD_ATTR_STAT_RULE_RX_LATENCY_MIN:
case WRTD_ATTR_STAT_RULE_RX_LATENCY_MAX:
case WRTD_ATTR_STAT_RULE_RX_LATENCY_AVG:
return wrtd_return_error
(wrtd, WRTD_ERROR_ATTR_NOT_WRITEABLE,
"Attribute %u is read only.", id);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"Attribute ID %u is not recognized.", id);
}
}
* Get an attribute of type `timestamp` (#wrtd_tstamp).
*
* Modelled after the IVI-C GetAttribute family of functions.
*
* @param[in] wrtd Device token.
* @param[in] rep_cap_id ID (string) of concerned repeated capability.
* If it is a global attribute, use #WRTD_GLOBAL_REP_CAP_ID
* @param[in] id ID (#wrtd_attr) of concerned attribute.
* @param[out] value Retrieved attribute value (#wrtd_tstamp).
* @return #wrtd_status
*/
wrtd_status wrtd_get_attr_tstamp(wrtd_dev *wrtd,
const char *rep_cap_id,
wrtd_attr id,
wrtd_tstamp *value)
status = wrtd_validate_id(wrtd, rep_cap_id, __func__);
WRTD_RETURN_IF_ERROR(status);
return wrtd_return_error
(wrtd, WRTD_ERROR_NULL_POINTER,
"Null pointer passed for function %s, "
"parameter value", __func__);
case WRTD_ATTR_SYS_TIME:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
return wrtd_attr_get_sys_time
(wrtd, value);
case WRTD_ATTR_ALARM_TIME:
return wrtd_attr_get_alarm_time
(wrtd, rep_cap_id, value);
case WRTD_ATTR_ALARM_SETUP_TIME:
return wrtd_attr_get_alarm_setup_time
(wrtd, rep_cap_id, value);
case WRTD_ATTR_ALARM_PERIOD:
return wrtd_attr_get_alarm_period
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_DELAY:
return wrtd_attr_get_rule_delay
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_HOLDOFF:
return wrtd_attr_get_rule_holdoff
(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_RESYNC_PERIOD:
return wrtd_attr_get_rule_resync_period
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_RX_LAST:
return wrtd_attr_get_stat_rule_rx_last
(wrtd, rep_cap_id, value);
case WRTD_ATTR_STAT_RULE_TX_LAST: