summaryrefslogtreecommitdiff
path: root/lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_cfg.c')
-rw-r--r--lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_cfg.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_cfg.c b/lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_cfg.c
new file mode 100644
index 00000000..cdf70181
--- /dev/null
+++ b/lib/avtp_pipeline/platform/Linux/avdecc/openavb_avdecc_cfg.c
@@ -0,0 +1,279 @@
+/*************************************************************************************************************
+Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
+Copyright (c) 2016-2017, Harman International Industries, Incorporated
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Attributions: The inih library portion of the source code is licensed from
+Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt.
+Complete license and copyright information can be found at
+https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
+*************************************************************************************************************/
+
+/*
+* MODULE SUMMARY : Reads the AVDECC .ini file for an endpoint
+*/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include "openavb_avdecc_cfg.h"
+#include "openavb_trace.h"
+#include "openavb_rawsock.h"
+#include "ini.h"
+
+#define AVB_LOG_COMPONENT "AVDECC Cfg"
+#include "openavb_log.h"
+
+// macro to make matching names easier
+#define MATCH(A, B)(strcasecmp((A), (B)) == 0)
+#define MATCH_FIRST(A, B)(strncasecmp((A), (B), strlen(B)) == 0)
+
+static void cfgValErr(const char *section, const char *name, const char *value)
+{
+ AVB_LOGF_ERROR("Invalid value: section=%s, name=%s, value=%s",
+ section, name, value);
+}
+
+static int cfgCallback(void *user, const char *section, const char *name, const char *value)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);
+
+ if (!user || !section || !name || !value) {
+ AVB_LOG_ERROR("Config: invalid arguments passed to callback");
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+
+ openavb_avdecc_cfg_t *pCfg = (openavb_avdecc_cfg_t*)user;
+
+ AVB_LOGF_DEBUG("name=[%s] value=[%s]", name, value);
+
+ bool valOK = FALSE;
+ char *pEnd;
+
+ if (MATCH(section, "network"))
+ {
+ if (MATCH(name, "ifname"))
+ {
+ if_info_t ifinfo;
+ if (openavbCheckInterface(value, &ifinfo)) {
+ strncpy(pCfg->ifname, value, IFNAMSIZ - 1);
+ memcpy(pCfg->ifmac, &ifinfo.mac, ETH_ALEN);
+ valOK = TRUE;
+ }
+ }
+ }
+ else if (MATCH(section, "vlan"))
+ {
+ if (MATCH(name, "vlanID")) {
+ errno = 0;
+ pCfg->vlanID = strtoul(value, &pEnd, 10);
+ if (*pEnd == '\0' && errno == 0)
+ valOK = TRUE;
+ }
+ else if (MATCH(name, "vlanPCP")) {
+ errno = 0;
+ pCfg->vlanPCP = strtoul(value, &pEnd, 10);
+ if (*pEnd == '\0' && errno == 0)
+ valOK = TRUE;
+ }
+ else {
+ // unmatched item, fail
+ AVB_LOGF_ERROR("Unrecognized configuration item: section=%s, name=%s", section, name);
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+ }
+ else if (MATCH(section, "fast_connect"))
+ {
+ if (MATCH(name, "fast_connect")) {
+ errno = 0;
+ pCfg->bFastConnectSupported = (strtoul(value, &pEnd, 10) != 0);
+ if (*pEnd == '\0' && errno == 0)
+ valOK = TRUE;
+ }
+ else {
+ // unmatched item, fail
+ AVB_LOGF_ERROR("Unrecognized configuration item: section=%s, name=%s", section, name);
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+ }
+ else if (MATCH(section, "discovery"))
+ {
+ if (MATCH(name, "valid_time")) {
+ errno = 0;
+ pCfg->valid_time = strtoul(value, &pEnd, 10);
+ if (*pEnd == '\0' && errno == 0) {
+ if (pCfg->valid_time < 2 || pCfg->valid_time > 62) {
+ AVB_LOG_ERROR("valid_time must be between 2 and 62 (inclusive)");
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+ if ((pCfg->valid_time & 1) != 0) {
+ AVB_LOGF_WARNING("valid_time converted to an even number (%d to %d)", pCfg->valid_time, pCfg->valid_time - 1);
+ }
+ pCfg->valid_time /= 2; // Convert from seconds to 2-second units.
+ valOK = TRUE;
+ }
+ }
+ else {
+ // unmatched item, fail
+ AVB_LOGF_ERROR("Unrecognized configuration item: section=%s, name=%s", section, name);
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+ }
+ else if (MATCH(section, "descriptor_entity"))
+ {
+ if (MATCH(name, "avdeccId")) {
+ errno = 0;
+ pCfg->avdeccId = strtoul(value, &pEnd, 0);
+ if (*pEnd == '\0' && errno == 0)
+ valOK = TRUE;
+ }
+ else if (MATCH(name, "entity_model_id")) {
+ errno = 0;
+ U64 nTemp = strtoull(value, &pEnd, 0);
+ if (*pEnd == '\0' && errno == 0) {
+ valOK = TRUE;
+ int i;
+ for (i = 7; i >= 0; --i) {
+ pCfg->entity_model_id[i] = (U8) (nTemp & 0xFF);
+ nTemp = (nTemp >> 8);
+ }
+ AVB_LOGF_DEBUG("entity_model_id = " ENTITYID_FORMAT, ENTITYID_ARGS(pCfg->entity_model_id));
+ }
+ }
+ else if (MATCH(name, "entity_name"))
+ {
+ strncpy(pCfg->entity_name, value, sizeof(pCfg->entity_name));
+ // String does not need to be 0-terminated.
+ valOK = TRUE;
+ }
+ else if (MATCH(name, "firmware_version"))
+ {
+ strncpy(pCfg->firmware_version, value, sizeof(pCfg->firmware_version));
+ // String does not need to be 0-terminated.
+ valOK = TRUE;
+ }
+ else if (MATCH(name, "group_name"))
+ {
+ strncpy(pCfg->group_name, value, sizeof(pCfg->group_name));
+ // String does not need to be 0-terminated.
+ valOK = TRUE;
+ }
+ else if (MATCH(name, "serial_number"))
+ {
+ strncpy(pCfg->serial_number, value, sizeof(pCfg->serial_number));
+ // String does not need to be 0-terminated.
+ valOK = TRUE;
+ }
+ else {
+ // unmatched item, fail
+ AVB_LOGF_ERROR("Unrecognized configuration item: section=%s, name=%s", section, name);
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+ }
+ else if (MATCH(section, "localization"))
+ {
+ if (MATCH(name, "locale_identifier"))
+ {
+ strncpy(pCfg->locale_identifier, value, sizeof(pCfg->locale_identifier));
+ // String does not need to be 0-terminated.
+ valOK = TRUE;
+ }
+ else if (MATCH(name, "vendor_name"))
+ {
+ strncpy(pCfg->vendor_name, value, sizeof(pCfg->vendor_name));
+ // String does not need to be 0-terminated.
+ valOK = TRUE;
+ }
+ else if (MATCH(name, "model_name"))
+ {
+ strncpy(pCfg->model_name, value, sizeof(pCfg->model_name));
+ // String does not need to be 0-terminated.
+ valOK = TRUE;
+ }
+ else {
+ // unmatched item, fail
+ AVB_LOGF_ERROR("Unrecognized configuration item: section=%s, name=%s", section, name);
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+ }
+ else {
+ // unmatched item, fail
+ AVB_LOGF_ERROR("Unrecognized configuration item: section=%s, name=%s", section, name);
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+
+ if (!valOK) {
+ cfgValErr(section, name, value);
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 0;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+ return 1; // OK
+}
+
+// Parse ini file, and create config data
+//
+int openavbReadAvdeccConfig(const char *ini_file, openavb_avdecc_cfg_t *pCfg)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);
+
+ // defaults - most are handled by setting everything to 0
+ memset(pCfg, 0, sizeof(openavb_avdecc_cfg_t));
+ pCfg->valid_time = 31; // See IEEE Std 1722.1-2013 clause 6.2.1.6
+ pCfg->avdeccId = 0xfffe;
+
+ int result = ini_parse(ini_file, cfgCallback, pCfg);
+ if (result < 0) {
+ AVB_LOGF_ERROR("Couldn't parse INI file: %s", ini_file);
+ return -1;
+ }
+ if (result > 0) {
+ AVB_LOGF_ERROR("Error in INI file: %s, line %d", ini_file, result);
+ return -1;
+ }
+
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+
+ // Yay, we did it.
+ return 0;
+}
+
+// Clean up any configuration-related stuff
+//
+void openavbAvdeccUnconfigure(openavb_avdecc_cfg_t *pCfg)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_ENDPOINT);
+
+ AVB_TRACE_EXIT(AVB_TRACE_ENDPOINT);
+}