From 2b632bd229edaa9999be5043f9a8ae2ac7d17e41 Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Thu, 19 Feb 2026 06:19:23 +0100 Subject: Add configurable variable node initialization for server_register New optional CLI argument [nodes-config] lets the server populate its address space from a dot-indexed config file (node.N.name/type/value/ accessLevel/description). Supports 10 scalar types plus 1D arrays. --- src/nodes_config.h | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/nodes_config.h (limited to 'src/nodes_config.h') diff --git a/src/nodes_config.h b/src/nodes_config.h new file mode 100644 index 0000000..0207a55 --- /dev/null +++ b/src/nodes_config.h @@ -0,0 +1,126 @@ +#ifndef DISCOVERY_NODES_CONFIG_H +#define DISCOVERY_NODES_CONFIG_H + +/** + * @file nodes_config.h + * @brief Dot-indexed node configuration parser and server-side node creator. + * + * Reads a config file containing node.N.field entries, parses them into + * an array of node descriptors, and creates corresponding OPC UA variable + * nodes in the server address space. Each node gets a string NodeId in + * namespace 1 (ns=1;s=). + * + * Supported types (scalar and 1D array via "type[]" suffix): + * bool, int16, uint16, int32, uint32, int64, uint64, float, double, string + * + * Access levels: read, readwrite. + */ + +#include + +#include + +/* ======================================================================== + * Types + * ======================================================================== */ + +/** + * @brief OPC UA data types supported by the nodes config parser. + */ +typedef enum +{ + NODE_TYPE_BOOL, + NODE_TYPE_INT16, + NODE_TYPE_UINT16, + NODE_TYPE_INT32, + NODE_TYPE_UINT32, + NODE_TYPE_INT64, + NODE_TYPE_UINT64, + NODE_TYPE_FLOAT, + NODE_TYPE_DOUBLE, + NODE_TYPE_STRING +} node_type; + +/** + * @brief Access level flags for a variable node. + */ +typedef enum +{ + NODE_ACCESS_READ, + NODE_ACCESS_READWRITE +} node_access_level; + +/** + * @brief Describes a single variable node to be created on the server. + * + * All string pointers are heap-allocated copies owned by this struct. + * Call nodes_config_free() to release them. + */ +typedef struct +{ + char *name; /**< DisplayName, browseName, and string NodeId. */ + char *description; /**< Optional description text (NULL when absent). */ + node_type type; /**< OPC UA data type. */ + UA_Boolean is_array; /**< true when the type name ended with "[]". */ + char *value_str; /**< Raw value string (comma-separated for arrays). */ + node_access_level access; /**< Read or read-write. */ +} node_config; + +/** + * @brief A parsed set of variable node definitions. + */ +typedef struct +{ + node_config *nodes; + size_t count; +} nodes_config; + +/* ======================================================================== + * Public API + * ======================================================================== */ + +/** + * @brief Parses a nodes configuration file. + * + * Reads dot-indexed keys (node.N.name, node.N.type, etc.) from the + * file at @p path, groups them by index, validates required fields, + * and populates a nodes_config struct. The caller must free the + * result with nodes_config_free(). + * + * When the file contains no node.* keys the function succeeds with + * out->count == 0 and out->nodes == NULL. + * + * @param path Path to the nodes configuration file. + * @param out Output: parsed nodes configuration. + * @return 0 on success, -1 on error (logged via UA_LOG_ERROR/FATAL). + */ +int nodes_config_load (const char *path, nodes_config *out); + +/** + * @brief Adds all configured variable nodes to a server. + * + * For each node_config entry, parses the value string into the + * appropriate UA type, constructs a UA_VariableAttributes, and calls + * UA_Server_addVariableNode with a string NodeId in namespace 1 + * under the Objects folder. + * + * Individual node failures are logged but do not stop processing of + * remaining nodes. + * + * @param server The UA_Server to add nodes to. + * @param nc The parsed nodes configuration. + * @return 0 when all nodes were added, -1 if any node failed. + */ +int nodes_config_add (UA_Server *server, const nodes_config *nc); + +/** + * @brief Frees all memory owned by a nodes_config structure. + * + * After this call the structure is zeroed and must not be used + * unless nodes_config_load() is called again. + * + * @param nc The nodes configuration to free. + */ +void nodes_config_free (nodes_config *nc); + +#endif /* DISCOVERY_NODES_CONFIG_H */ -- cgit v1.2.3