aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.c328
-rw-r--r--src/client_find_servers.c438
-rw-r--r--src/common.c114
-rw-r--r--src/common.h25
-rw-r--r--src/config.c40
-rw-r--r--src/config.h21
-rw-r--r--src/server_lds.c19
-rw-r--r--src/server_register.c227
8 files changed, 621 insertions, 591 deletions
diff --git a/src/client.c b/src/client.c
new file mode 100644
index 0000000..8234963
--- /dev/null
+++ b/src/client.c
@@ -0,0 +1,328 @@
+/**
+ * @file client.c
+ * @brief Unified OPC UA client for discovery and server interaction.
+ *
+ * Supports three operations selected via CLI:
+ * find-servers — queries a server's FindServers service
+ * get-endpoints — queries a server's GetEndpoints service
+ * read-time — connects to a server and reads the current time
+ */
+
+#include "common.h"
+#include "config.h"
+
+#include <open62541/client_highlevel.h>
+#include <open62541/plugin/log_stdout.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+/* ========================================================================
+ * Operation Dispatch
+ * ======================================================================== */
+
+typedef enum
+{
+ OP_FIND_SERVERS,
+ OP_GET_ENDPOINTS,
+ OP_READ_TIME,
+ OP_INVALID
+} Operation;
+
+static Operation
+parseOperation (const char *name)
+{
+ if (strcmp (name, "find-servers") == 0)
+ return OP_FIND_SERVERS;
+ if (strcmp (name, "get-endpoints") == 0)
+ return OP_GET_ENDPOINTS;
+ if (strcmp (name, "read-time") == 0)
+ return OP_READ_TIME;
+ return OP_INVALID;
+}
+
+/* ========================================================================
+ * Operations
+ * ======================================================================== */
+
+/**
+ * Calls the FindServers service and prints all discovered servers.
+ *
+ * @return EXIT_SUCCESS on success, EXIT_FAILURE otherwise.
+ */
+static int
+opFindServers (UA_Client *client, const char *url)
+{
+ size_t arraySize = 0;
+ UA_ApplicationDescription *array = NULL;
+
+ UA_StatusCode retval = UA_Client_findServers (client, url, 0, NULL, 0, NULL,
+ &arraySize, &array);
+ if (retval != UA_STATUSCODE_GOOD)
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
+ "FindServers failed: %s", UA_StatusCode_name (retval));
+ return EXIT_FAILURE;
+ }
+
+ for (size_t i = 0; i < arraySize; i++)
+ printApplicationDescription (&array[i], i);
+
+ UA_Array_delete (array, arraySize,
+ &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
+ return EXIT_SUCCESS;
+}
+
+/**
+ * Calls the GetEndpoints service and prints all endpoints.
+ *
+ * @return EXIT_SUCCESS on success, EXIT_FAILURE otherwise.
+ */
+static int
+opGetEndpoints (UA_Client *client, const char *url)
+{
+ size_t arraySize = 0;
+ UA_EndpointDescription *array = NULL;
+
+ UA_StatusCode retval
+ = UA_Client_getEndpoints (client, url, &arraySize, &array);
+ if (retval != UA_STATUSCODE_GOOD)
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
+ "GetEndpoints failed: %s", UA_StatusCode_name (retval));
+ return EXIT_FAILURE;
+ }
+
+ for (size_t i = 0; i < arraySize; i++)
+ printEndpoint (&array[i], i);
+
+ UA_Array_delete (array, arraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
+ return EXIT_SUCCESS;
+}
+
+/**
+ * Connects to a server and reads the current time node.
+ *
+ * @param username Username for session auth, or NULL for anonymous.
+ * @param password Password for session auth (ignored when username is NULL).
+ * @return EXIT_SUCCESS on success, EXIT_FAILURE otherwise.
+ */
+static int
+opReadTime (UA_Client *client, const char *url, const char *username,
+ const char *password)
+{
+ UA_StatusCode retval;
+ if (username)
+ retval = UA_Client_connectUsername (client, url, username, password);
+ else
+ retval = UA_Client_connect (client, url);
+
+ if (retval != UA_STATUSCODE_GOOD)
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
+ "Could not connect: %s", UA_StatusCode_name (retval));
+ return EXIT_FAILURE;
+ }
+
+ UA_Variant value;
+ UA_Variant_init (&value);
+
+ const UA_NodeId nodeId = UA_NS0ID (SERVER_SERVERSTATUS_CURRENTTIME);
+ retval = UA_Client_readValueAttribute (client, nodeId, &value);
+
+ int rc = EXIT_SUCCESS;
+ if (retval == UA_STATUSCODE_GOOD
+ && UA_Variant_hasScalarType (&value, &UA_TYPES[UA_TYPES_DATETIME]))
+ {
+ UA_DateTime raw_date = *(UA_DateTime *)value.data;
+ UA_DateTimeStruct dts = UA_DateTime_toStruct (raw_date);
+ UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_APPLICATION,
+ "date is: %u-%u-%u %u:%u:%u.%03u", dts.day, dts.month,
+ dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
+ }
+ else
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
+ "Could not read current time: %s",
+ UA_StatusCode_name (retval));
+ rc = EXIT_FAILURE;
+ }
+
+ UA_Variant_clear (&value);
+ UA_Client_disconnect (client);
+ return rc;
+}
+
+/* ========================================================================
+ * Main
+ * ======================================================================== */
+
+int
+main (int argc, char **argv)
+{
+ if (argc < 4 || argc > 5)
+ {
+ UA_LOG_FATAL (
+ UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Usage: %s <config-file> <operation> <endpoint-url> [log-level]",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ Operation op = parseOperation (argv[2]);
+ if (op == OP_INVALID)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown operation: %s "
+ "(expected find-servers, get-endpoints, read-time)",
+ argv[2]);
+ return EXIT_FAILURE;
+ }
+
+ const char *endpointUrl = argv[3];
+
+ const char *logLevelStr = (argc == 5) ? argv[4] : "info";
+ int logLevel = parseLogLevel (logLevelStr);
+ if (logLevel < 0)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown log level: %s "
+ "(expected trace, debug, info, warning, error, fatal)",
+ logLevelStr);
+ return EXIT_FAILURE;
+ }
+
+ Config cfg;
+ if (configLoad (argv[1], &cfg) != 0)
+ return EXIT_FAILURE;
+
+ /* ---- Common config keys ---- */
+
+ const char *applicationUri
+ = configRequire (&cfg, "applicationUri", "Client");
+ const char *certPath = configRequire (&cfg, "certificate", "Client");
+ const char *keyPath = configRequire (&cfg, "privateKey", "Client");
+ const char *secModeStr = configRequire (&cfg, "securityMode", "Client");
+ const char *secPolStr = configRequire (&cfg, "securityPolicy", "Client");
+
+ if (!applicationUri || !certPath || !keyPath || !secModeStr || !secPolStr)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ UA_MessageSecurityMode secMode = parseSecurityMode (secModeStr);
+ if (secMode == UA_MESSAGESECURITYMODE_INVALID)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown security mode: %s", secModeStr);
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ const char *secPolUri = resolveSecurityPolicyUri (secPolStr);
+ if (!secPolUri)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown security policy: %s", secPolStr);
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ /* ---- Auth config (read-time only) ---- */
+
+ const char *username = NULL, *password = NULL;
+
+ if (op == OP_READ_TIME)
+ {
+ const char *authMode = configRequire (&cfg, "authMode", "Client");
+ if (!authMode)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ if (strcmp (authMode, "anonymous") == 0)
+ {
+ /* No credentials needed. */
+ }
+ else if (strcmp (authMode, "user") == 0)
+ {
+ username = configRequire (&cfg, "username", "Client");
+ password = configRequire (&cfg, "password", "Client");
+ if (!username || !password)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown auth mode: %s "
+ "(expected 'anonymous' or 'user')",
+ authMode);
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* ---- Trust store ---- */
+
+ const char *trustStore = configRequire (&cfg, "trustStore", "Client");
+ if (!trustStore)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ char **trustPaths = NULL;
+ size_t trustSize = 0;
+ if (loadTrustStore (trustStore, &trustPaths, &trustSize) != 0)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
+ /* ---- Create client ---- */
+
+ UA_Client *client = UA_Client_new ();
+ UA_StatusCode retval = createSecureClientConfig (
+ UA_Client_getConfig (client), applicationUri, certPath, keyPath,
+ trustPaths, trustSize, secMode, secPolUri);
+ if (retval != UA_STATUSCODE_GOOD)
+ {
+ UA_Client_delete (client);
+ freeTrustStore (trustPaths, trustSize);
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+ UA_Client_getConfig (client)->logging->context = (void *)(uintptr_t)logLevel;
+
+ /* ---- Dispatch operation ---- */
+
+ int rc;
+ switch (op)
+ {
+ case OP_FIND_SERVERS:
+ rc = opFindServers (client, endpointUrl);
+ break;
+ case OP_GET_ENDPOINTS:
+ rc = opGetEndpoints (client, endpointUrl);
+ break;
+ case OP_READ_TIME:
+ rc = opReadTime (client, endpointUrl, username, password);
+ break;
+ default:
+ rc = EXIT_FAILURE;
+ break;
+ }
+
+ /* ---- Cleanup ---- */
+
+ UA_Client_delete (client);
+ freeTrustStore (trustPaths, trustSize);
+ configFree (&cfg);
+
+ return rc;
+}
diff --git a/src/client_find_servers.c b/src/client_find_servers.c
deleted file mode 100644
index 2212026..0000000
--- a/src/client_find_servers.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/**
- * @file client_find_servers.c
- * @brief OPC UA client that queries a Local Discovery Server for registered
- * servers.
- *
- * This program connects to an LDS and calls the FindServers service to
- * retrieve all registered servers. It then queries each server's endpoints
- * using the GetEndpoints service and displays the results in a human-readable
- * format.
- */
-
-#include "common.h"
-#include "config.h"
-
-#include <open62541/client_highlevel.h>
-#include <open62541/plugin/log_stdout.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-/* ========================================================================
- * Discovery Service Calls
- * ======================================================================== */
-
-/**
- * Calls the FindServers service on the LDS and prints all discovered servers.
- *
- * @param client The OPC UA client instance.
- * @param discoveryServerEndpoint The LDS endpoint URL.
- * @param applicationDescriptionArraySize Output: number of servers found.
- * @param applicationDescriptionArray Output: array of server descriptions.
- * @return UA_STATUSCODE_GOOD on success, error code otherwise.
- */
-static UA_StatusCode
-findServers (UA_Client *client, const char *discoveryServerEndpoint,
- size_t *applicationDescriptionArraySize,
- UA_ApplicationDescription **applicationDescriptionArray)
-{
- UA_StatusCode retval = UA_Client_findServers (
- client, discoveryServerEndpoint, 0, NULL, 0, NULL,
- applicationDescriptionArraySize, applicationDescriptionArray);
-
- if (retval != UA_STATUSCODE_GOOD)
- {
- UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
- "Could not call FindServers service. "
- "Is the discovery server started? StatusCode %s",
- UA_StatusCode_name (retval));
- return retval;
- }
-
- for (size_t i = 0; i < *applicationDescriptionArraySize; i++)
- printApplicationDescription (&(*applicationDescriptionArray)[i], i);
-
- return UA_STATUSCODE_GOOD;
-}
-
-/**
- * Queries endpoints for each discovered server using the GetEndpoints service.
- *
- * For each server in the applicationDescriptionArray, this function extracts
- * the first discovery URL and calls GetEndpoints to retrieve all available
- * endpoints. Results are logged via UA_LOG_INFO.
- *
- * @param client The OPC UA client instance.
- * @param applicationDescriptionArray Array of server descriptions from
- * FindServers.
- * @param applicationDescriptionArraySize Number of servers in the array.
- */
-static void
-getServersEndpoints (UA_Client *client,
- UA_ApplicationDescription *applicationDescriptionArray,
- size_t applicationDescriptionArraySize)
-{
- for (size_t i = 0; i < applicationDescriptionArraySize; i++)
- {
- UA_ApplicationDescription *description = &applicationDescriptionArray[i];
- if (description->discoveryUrlsSize == 0)
- {
- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
- "[GetEndpoints] Server %.*s did not provide any "
- "discovery urls. Skipping.",
- (int)description->applicationUri.length,
- description->applicationUri.data);
- continue;
- }
-
- /* UA_String is not null-terminated; build a C string for the API. */
- char *discoveryUrl = (char *)UA_malloc (
- sizeof (char) * description->discoveryUrls[0].length + 1);
- memcpy (discoveryUrl, description->discoveryUrls[0].data,
- description->discoveryUrls[0].length);
- discoveryUrl[description->discoveryUrls[0].length] = '\0';
-
- UA_EndpointDescription *endpointArray = NULL;
- size_t endpointArraySize = 0;
- UA_StatusCode retval = UA_Client_getEndpoints (
- client, discoveryUrl, &endpointArraySize, &endpointArray);
- UA_free (discoveryUrl);
- if (retval != UA_STATUSCODE_GOOD)
- {
- UA_Client_disconnect (client);
- break;
- }
-
- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_APPLICATION,
- "Endpoints for Server[%lu]: %.*s", (unsigned long)i,
- (int)description->applicationUri.length,
- description->applicationUri.data);
- for (size_t j = 0; j < endpointArraySize; j++)
- printEndpoint (&endpointArray[j], j);
-
- UA_Array_delete (endpointArray, endpointArraySize,
- &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
- }
-}
-
-/* ========================================================================
- * Node Reading
- * ======================================================================== */
-
-/**
- * Connects to each non-discovery server and reads the current time node.
- *
- * For each server that is not a DiscoveryServer, this function establishes a
- * secure session, reads the Server_ServerStatus_CurrentTime variable, prints
- * the result, and disconnects.
- *
- * @param client The OPC UA client instance.
- * @param applicationDescriptionArray Array of server descriptions from
- * FindServers.
- * @param applicationDescriptionArraySize Number of servers in the array.
- * @param username Username for session auth, or NULL for anonymous.
- * @param password Password for session auth (ignored when username is NULL).
- */
-static void
-readServerTime (UA_Client *client,
- UA_ApplicationDescription *applicationDescriptionArray,
- size_t applicationDescriptionArraySize, const char *username,
- const char *password)
-{
- for (size_t i = 0; i < applicationDescriptionArraySize; i++)
- {
- UA_ApplicationDescription *desc = &applicationDescriptionArray[i];
-
- if (desc->applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER)
- continue;
-
- if (desc->discoveryUrlsSize == 0)
- {
- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
- "[ReadTime] Server %.*s has no discovery URLs. "
- "Skipping.",
- (int)desc->applicationUri.length,
- desc->applicationUri.data);
- continue;
- }
-
- /* UA_String is not null-terminated; build a C string for the API. */
- char *url = (char *)UA_malloc (desc->discoveryUrls[0].length + 1);
- memcpy (url, desc->discoveryUrls[0].data, desc->discoveryUrls[0].length);
- url[desc->discoveryUrls[0].length] = '\0';
-
- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
- "Connecting to %s to read current time...", url);
-
- UA_StatusCode retval;
- if (username)
- retval = UA_Client_connectUsername (client, url, username, password);
- else
- retval = UA_Client_connect (client, url);
- UA_free (url);
- if (retval != UA_STATUSCODE_GOOD)
- {
- UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
- "Could not connect: %s", UA_StatusCode_name (retval));
- continue;
- }
-
- UA_Variant value;
- UA_Variant_init (&value);
-
- const UA_NodeId nodeId = UA_NS0ID (SERVER_SERVERSTATUS_CURRENTTIME);
- retval = UA_Client_readValueAttribute (client, nodeId, &value);
-
- if (retval == UA_STATUSCODE_GOOD
- && UA_Variant_hasScalarType (&value, &UA_TYPES[UA_TYPES_DATETIME]))
- {
- UA_DateTime raw_date = *(UA_DateTime *)value.data;
- UA_DateTimeStruct dts = UA_DateTime_toStruct (raw_date);
- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_APPLICATION,
- "date is: %u-%u-%u %u:%u:%u.%03u", dts.day, dts.month,
- dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
- }
- else
- {
- UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
- "Could not read current time: %s",
- UA_StatusCode_name (retval));
- }
-
- UA_Variant_clear (&value);
- UA_Client_disconnect (client);
- }
-}
-
-/* ========================================================================
- * Main
- * ======================================================================== */
-
-int
-main (int argc, char **argv)
-{
- if (argc < 2 || argc > 3)
- {
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Usage: %s <config-file> [log-level]", argv[0]);
- return EXIT_FAILURE;
- }
-
- const char *logLevelStr = (argc == 3) ? argv[2] : "info";
- int logLevel = parseLogLevel (logLevelStr);
- if (logLevel < 0)
- {
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown log level: %s "
- "(expected trace, debug, info, warning, error, fatal)",
- logLevelStr);
- return EXIT_FAILURE;
- }
-
- Config cfg;
- if (configLoad (argv[1], &cfg) != 0)
- return EXIT_FAILURE;
-
- /* ---- Shared keys ---- */
-
- const char *discoveryServerEndpoint
- = configRequire (&cfg, "discoveryEndpoint", "ClientFindServers");
- const char *applicationUri
- = configRequire (&cfg, "applicationUri", "ClientFindServers");
-
- if (!discoveryServerEndpoint || !applicationUri)
- {
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- /* ---- Discovery-side config (LDS connection) ---- */
-
- const char *discCertPath
- = configRequire (&cfg, "discoveryCertificate", "ClientFindServers");
- const char *discKeyPath
- = configRequire (&cfg, "discoveryPrivateKey", "ClientFindServers");
- const char *discSecModeStr
- = configRequire (&cfg, "discoverySecurityMode", "ClientFindServers");
- const char *discSecPolStr
- = configRequire (&cfg, "discoverySecurityPolicy", "ClientFindServers");
- const char *discAuthMode
- = configRequire (&cfg, "discoveryAuthMode", "ClientFindServers");
-
- if (!discCertPath || !discKeyPath || !discSecModeStr || !discSecPolStr
- || !discAuthMode)
- {
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- UA_MessageSecurityMode discSecMode = parseSecurityMode (discSecModeStr);
- if (discSecMode == UA_MESSAGESECURITYMODE_INVALID)
- {
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown discovery security mode: %s", discSecModeStr);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- const char *discSecPolUri = resolveSecurityPolicyUri (discSecPolStr);
- if (!discSecPolUri)
- {
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown discovery security policy: %s", discSecPolStr);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- /* ---- Server-side config (connections to discovered servers) ---- */
-
- const char *srvCertPath
- = configRequire (&cfg, "serverCertificate", "ClientFindServers");
- const char *srvKeyPath
- = configRequire (&cfg, "serverPrivateKey", "ClientFindServers");
- const char *srvSecModeStr
- = configRequire (&cfg, "serverSecurityMode", "ClientFindServers");
- const char *srvSecPolStr
- = configRequire (&cfg, "serverSecurityPolicy", "ClientFindServers");
- const char *srvAuthMode
- = configRequire (&cfg, "serverAuthMode", "ClientFindServers");
-
- if (!srvCertPath || !srvKeyPath || !srvSecModeStr || !srvSecPolStr
- || !srvAuthMode)
- {
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- UA_MessageSecurityMode srvSecMode = parseSecurityMode (srvSecModeStr);
- if (srvSecMode == UA_MESSAGESECURITYMODE_INVALID)
- {
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown server security mode: %s", srvSecModeStr);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- const char *srvSecPolUri = resolveSecurityPolicyUri (srvSecPolStr);
- if (!srvSecPolUri)
- {
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown server security policy: %s", srvSecPolStr);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- /* ---- Server-side auth ---- */
-
- const char *srvUsername = NULL, *srvPassword = NULL;
-
- if (strcmp (srvAuthMode, "anonymous") == 0)
- {
- /* No credentials needed */
- }
- else if (strcmp (srvAuthMode, "user") == 0)
- {
- srvUsername
- = configRequire (&cfg, "serverUsername", "ClientFindServers");
- srvPassword
- = configRequire (&cfg, "serverPassword", "ClientFindServers");
- if (!srvUsername || !srvPassword)
- {
- configFree (&cfg);
- return EXIT_FAILURE;
- }
- }
- else
- {
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown server auth mode: %s "
- "(expected 'anonymous' or 'user')",
- srvAuthMode);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- /* ---- Trust lists ---- */
-
- char **discTrustPaths = NULL;
- size_t discTrustSize = 0;
- configGetAll (&cfg, "discoveryTrustList", &discTrustPaths, &discTrustSize);
-
- char **srvTrustPaths = NULL;
- size_t srvTrustSize = 0;
- configGetAll (&cfg, "serverTrustList", &srvTrustPaths, &srvTrustSize);
-
- /* ---- Create discovery client (LDS) ---- */
-
- UA_Client *discoveryClient = UA_Client_new ();
- UA_StatusCode retval = createSecureClientConfig (
- UA_Client_getConfig (discoveryClient), applicationUri, discCertPath,
- discKeyPath, discTrustPaths, discTrustSize, discSecMode, discSecPolUri);
- if (retval != UA_STATUSCODE_GOOD)
- {
- UA_Client_delete (discoveryClient);
- free (discTrustPaths);
- free (srvTrustPaths);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
- UA_Client_getConfig (discoveryClient)->logging->context
- = (void *)(uintptr_t)logLevel;
-
- /* ---- Create server client (discovered servers) ---- */
-
- UA_Client *serverClient = UA_Client_new ();
- retval = createSecureClientConfig (
- UA_Client_getConfig (serverClient), applicationUri, srvCertPath,
- srvKeyPath, srvTrustPaths, srvTrustSize, srvSecMode, srvSecPolUri);
- if (retval != UA_STATUSCODE_GOOD)
- {
- UA_Client_delete (discoveryClient);
- UA_Client_delete (serverClient);
- free (discTrustPaths);
- free (srvTrustPaths);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
- UA_Client_getConfig (serverClient)->logging->context
- = (void *)(uintptr_t)logLevel;
-
- /* ---- Discovery calls (use discoveryClient) ---- */
-
- UA_ApplicationDescription *applicationDescriptionArray = NULL;
- size_t applicationDescriptionArraySize = 0;
-
- retval = findServers (discoveryClient, discoveryServerEndpoint,
- &applicationDescriptionArraySize,
- &applicationDescriptionArray);
- if (retval != UA_STATUSCODE_GOOD)
- {
- UA_Client_delete (discoveryClient);
- UA_Client_delete (serverClient);
- free (discTrustPaths);
- free (srvTrustPaths);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- getServersEndpoints (discoveryClient, applicationDescriptionArray,
- applicationDescriptionArraySize);
-
- /* ---- Server calls (use serverClient) ---- */
-
- readServerTime (serverClient, applicationDescriptionArray,
- applicationDescriptionArraySize, srvUsername, srvPassword);
-
- /* ---- Cleanup ---- */
-
- UA_Client_delete (discoveryClient);
- UA_Client_delete (serverClient);
- UA_Array_delete (applicationDescriptionArray,
- applicationDescriptionArraySize,
- &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
- free (discTrustPaths);
- free (srvTrustPaths);
- configFree (&cfg);
-
- return EXIT_SUCCESS;
-}
diff --git a/src/common.c b/src/common.c
index 7d378f1..568e4d0 100644
--- a/src/common.c
+++ b/src/common.c
@@ -9,6 +9,7 @@
#include <open62541/plugin/log_stdout.h>
#include <open62541/server_config_default.h>
+#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -56,6 +57,102 @@ loadFile (const char *const path)
}
/* ========================================================================
+ * Trust Store
+ * ======================================================================== */
+
+int
+loadTrustStore (const char *dirPath, char ***outPaths, size_t *outSize)
+{
+ *outPaths = NULL;
+ *outSize = 0;
+
+ DIR *dir = opendir (dirPath);
+ if (!dir)
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Cannot open trust store directory '%s'", dirPath);
+ return -1;
+ }
+
+ size_t capacity = 8;
+ size_t count = 0;
+ char **paths = malloc (capacity * sizeof (char *));
+ if (!paths)
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "loadTrustStore: out of memory");
+ closedir (dir);
+ return -1;
+ }
+
+ struct dirent *entry;
+ while ((entry = readdir (dir)) != NULL)
+ {
+ const char *name = entry->d_name;
+ size_t nameLen = strlen (name);
+ /* Skip entries that are not *.der files. 5 = strlen("x.der"). */
+ if (nameLen < 5 || strcmp (name + nameLen - 4, ".der") != 0)
+ continue;
+
+ /* Build full path: dirPath/name */
+ size_t dirLen = strlen (dirPath);
+ size_t fullLen = dirLen + 1 + nameLen + 1;
+ char *full = malloc (fullLen);
+ if (!full)
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "loadTrustStore: out of memory");
+ for (size_t i = 0; i < count; i++)
+ free (paths[i]);
+ free (paths);
+ closedir (dir);
+ return -1;
+ }
+ snprintf (full, fullLen, "%s/%s", dirPath, name);
+
+ if (count == capacity)
+ {
+ capacity *= 2;
+ char **tmp = realloc (paths, capacity * sizeof (char *));
+ if (!tmp)
+ {
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "loadTrustStore: out of memory");
+ free (full);
+ for (size_t i = 0; i < count; i++)
+ free (paths[i]);
+ free (paths);
+ closedir (dir);
+ return -1;
+ }
+ paths = tmp;
+ }
+
+ paths[count++] = full;
+ }
+
+ closedir (dir);
+
+ if (count == 0)
+ {
+ free (paths);
+ return 0;
+ }
+
+ *outPaths = paths;
+ *outSize = count;
+ return 0;
+}
+
+void
+freeTrustStore (char **paths, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ free (paths[i]);
+ free (paths);
+}
+
+/* ========================================================================
* Security Helpers
* ======================================================================== */
@@ -223,18 +320,12 @@ createSecureServer (UA_UInt16 port, const char *applicationUri,
for (size_t i = 0; i < trustSize; i++)
trustList[i] = loadFile (trustPaths[i]);
- /* Issuer and revocation lists are unused in this demo. */
- size_t issuerListSize = 0;
- UA_ByteString *issuerList = NULL;
- UA_ByteString *revocationList = NULL;
- size_t revocationListSize = 0;
-
UA_Server *server = UA_Server_new ();
UA_ServerConfig *config = UA_Server_getConfig (server);
*retval = UA_ServerConfig_setDefaultWithSecurityPolicies (
- config, port, &certificate, &privateKey, trustList, trustSize,
- issuerList, issuerListSize, revocationList, revocationListSize);
+ config, port, &certificate, &privateKey, trustList, trustSize, NULL, 0,
+ NULL, 0);
UA_ByteString_clear (&certificate);
UA_ByteString_clear (&privateKey);
@@ -269,13 +360,8 @@ createSecureClientConfig (UA_ClientConfig *cc, const char *applicationUri,
for (size_t i = 0; i < trustSize; i++)
trustList[i] = loadFile (trustPaths[i]);
- /* Revocation list is unused in this demo. */
- UA_ByteString *revocationList = NULL;
- size_t revocationListSize = 0;
-
UA_StatusCode retval = UA_ClientConfig_setDefaultEncryption (
- cc, certificate, privateKey, trustList, trustSize, revocationList,
- revocationListSize);
+ cc, certificate, privateKey, trustList, trustSize, NULL, 0);
UA_ByteString_clear (&certificate);
UA_ByteString_clear (&privateKey);
diff --git a/src/common.h b/src/common.h
index e8c0c78..7290181 100644
--- a/src/common.h
+++ b/src/common.h
@@ -13,6 +13,8 @@
#include <open62541/server.h>
#include <open62541/types.h>
+#include <stddef.h>
+
/**
* @brief Loads a DER-encoded certificate or key file into a UA_ByteString.
*
@@ -22,6 +24,29 @@
UA_ByteString loadFile (const char *const path);
/**
+ * @brief Collects all *.der file paths from a trust store directory.
+ *
+ * Opens the directory, finds every file ending in ".der", and builds
+ * heap-allocated full paths (dirPath/filename). The caller must free
+ * the result with freeTrustStore().
+ *
+ * @param dirPath Path to the trust store directory.
+ * @param outPaths Output: heap-allocated array of heap-allocated strings.
+ * Set to NULL when the directory is empty.
+ * @param outSize Output: number of entries in outPaths.
+ * @return 0 on success, -1 on error (logged via UA_LOG_ERROR).
+ */
+int loadTrustStore (const char *dirPath, char ***outPaths, size_t *outSize);
+
+/**
+ * @brief Frees the array returned by loadTrustStore().
+ *
+ * @param paths The array of strings (may be NULL).
+ * @param size Number of entries.
+ */
+void freeTrustStore (char **paths, size_t size);
+
+/**
* @brief Creates a UA_Server configured with security policies and encryption.
*
* The server is initialized with the specified port, certificate, private key,
diff --git a/src/config.c b/src/config.c
index 163f601..2165821 100644
--- a/src/config.c
+++ b/src/config.c
@@ -200,46 +200,6 @@ configRequireInt (const Config *cfg, const char *key, const char *program)
}
void
-configGetAll (const Config *cfg, const char *key, char ***out, size_t *size)
-{
- /* First pass: count matches. */
- size_t count = 0;
- for (size_t i = 0; i < cfg->count; i++)
- {
- if (strcmp (cfg->entries[i].key, key) == 0)
- count++;
- }
-
- if (count == 0)
- {
- *out = NULL;
- *size = 0;
- return;
- }
-
- /* Second pass: collect pointers. */
- char **arr = malloc (count * sizeof (char *));
- if (!arr)
- {
- UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Config: out of memory");
- *out = NULL;
- *size = 0;
- return;
- }
-
- size_t idx = 0;
- for (size_t i = 0; i < cfg->count; i++)
- {
- if (strcmp (cfg->entries[i].key, key) == 0)
- arr[idx++] = cfg->entries[i].value;
- }
-
- *out = arr;
- *size = count;
-}
-
-void
configFree (Config *cfg)
{
for (size_t i = 0; i < cfg->count; i++)
diff --git a/src/config.h b/src/config.h
index 649278d..2c5e364 100644
--- a/src/config.h
+++ b/src/config.h
@@ -7,8 +7,6 @@
*
* Parses configuration files with one key=value pair per line.
* Lines starting with '#' are comments. Blank lines are ignored.
- * Repeated keys are allowed (used for list-valued settings like
- * trustList).
*/
#include <stddef.h>
@@ -28,8 +26,7 @@ typedef struct
/**
* @brief A parsed configuration file.
*
- * Holds a dynamic array of ConfigEntry items. Duplicate keys are
- * allowed (used for list-valued settings like trustList).
+ * Holds a dynamic array of ConfigEntry items.
*/
typedef struct
{
@@ -92,22 +89,6 @@ const char *configRequire (const Config *cfg, const char *key,
int configRequireInt (const Config *cfg, const char *key, const char *program);
/**
- * @brief Collects all values for a repeated key.
- *
- * Allocates an array of char* pointers to the values stored
- * in @p cfg. The caller must free the array itself (but not
- * the strings, which are owned by cfg).
- *
- * @param cfg The parsed configuration.
- * @param key The key to collect (e.g. "trustList").
- * @param out Output: heap-allocated array of string pointers.
- * Set to NULL if the key is not present.
- * @param size Output: number of entries in @p out.
- */
-void configGetAll (const Config *cfg, const char *key, char ***out,
- size_t *size);
-
-/**
* @brief Frees all memory owned by a Config structure.
*
* After this call the Config is zeroed and must not be used
diff --git a/src/server_lds.c b/src/server_lds.c
index 2fe508f..a9a68bc 100644
--- a/src/server_lds.c
+++ b/src/server_lds.c
@@ -111,9 +111,20 @@ main (int argc, char *argv[])
return EXIT_FAILURE;
}
+ const char *trustStore = configRequire (&cfg, "trustStore", "ServerLDS");
+ if (!trustStore)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
+
char **trustPaths = NULL;
size_t trustSize = 0;
- configGetAll (&cfg, "trustList", &trustPaths, &trustSize);
+ if (loadTrustStore (trustStore, &trustPaths, &trustSize) != 0)
+ {
+ configFree (&cfg);
+ return EXIT_FAILURE;
+ }
UA_StatusCode retval;
UA_Server *server
@@ -121,7 +132,7 @@ main (int argc, char *argv[])
trustPaths, trustSize, &retval);
if (!server)
{
- free (trustPaths);
+ freeTrustStore (trustPaths, trustSize);
configFree (&cfg);
return EXIT_FAILURE;
}
@@ -147,7 +158,7 @@ main (int argc, char *argv[])
if (retval != UA_STATUSCODE_GOOD)
{
UA_Server_delete (server);
- free (trustPaths);
+ freeTrustStore (trustPaths, trustSize);
configFree (&cfg);
return EXIT_FAILURE;
}
@@ -164,7 +175,7 @@ main (int argc, char *argv[])
retval = UA_Server_run (server, &running);
UA_Server_delete (server);
- free (trustPaths);
+ freeTrustStore (trustPaths, trustSize);
configFree (&cfg);
return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/server_register.c b/src/server_register.c
index d259961..6e1eb6d 100644
--- a/src/server_register.c
+++ b/src/server_register.c
@@ -42,14 +42,18 @@ main (int argc, char **argv)
signal (SIGINT, stopHandler);
signal (SIGTERM, stopHandler);
- if (argc < 2 || argc > 3)
+ if (argc < 4 || argc > 5)
{
UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Usage: %s <config-file> [log-level]", argv[0]);
+ "Usage: %s <server-config> <client-config> "
+ "<discovery-url> [log-level]",
+ argv[0]);
return EXIT_FAILURE;
}
- const char *logLevelStr = (argc == 3) ? argv[2] : "info";
+ const char *discoveryEndpoint = argv[3];
+
+ const char *logLevelStr = (argc == 5) ? argv[4] : "info";
int logLevel = parseLogLevel (logLevelStr);
if (logLevel < 0)
{
@@ -60,58 +64,28 @@ main (int argc, char **argv)
return EXIT_FAILURE;
}
- Config cfg;
- if (configLoad (argv[1], &cfg) != 0)
+ /* ── Load server config ─────────────────────────────────────── */
+
+ Config serverCfg;
+ if (configLoad (argv[1], &serverCfg) != 0)
return EXIT_FAILURE;
- int port = configRequireInt (&cfg, "port", "ServerRegister");
+ int port = configRequireInt (&serverCfg, "port", "ServerRegister");
const char *applicationUri
- = configRequire (&cfg, "applicationUri", "ServerRegister");
+ = configRequire (&serverCfg, "applicationUri", "ServerRegister");
const char *serverCertPath
- = configRequire (&cfg, "serverCertificate", "ServerRegister");
+ = configRequire (&serverCfg, "certificate", "ServerRegister");
const char *serverKeyPath
- = configRequire (&cfg, "serverPrivateKey", "ServerRegister");
- const char *clientCertPath
- = configRequire (&cfg, "clientCertificate", "ServerRegister");
- const char *clientKeyPath
- = configRequire (&cfg, "clientPrivateKey", "ServerRegister");
- const char *discoveryEndpoint
- = configRequire (&cfg, "discoveryEndpoint", "ServerRegister");
+ = configRequire (&serverCfg, "privateKey", "ServerRegister");
int registerInterval
- = configRequireInt (&cfg, "registerInterval", "ServerRegister");
- const char *securityModeStr
- = configRequire (&cfg, "securityMode", "ServerRegister");
- const char *securityPolicyStr
- = configRequire (&cfg, "securityPolicy", "ServerRegister");
+ = configRequireInt (&serverCfg, "registerInterval", "ServerRegister");
const char *serverAuthMode
- = configRequire (&cfg, "serverAuthMode", "ServerRegister");
- const char *clientAuthMode
- = configRequire (&cfg, "clientAuthMode", "ServerRegister");
-
- if (!applicationUri || !serverCertPath || !serverKeyPath || !clientCertPath
- || !clientKeyPath || !discoveryEndpoint || !securityModeStr
- || !securityPolicyStr || !serverAuthMode || !clientAuthMode || port < 0
- || registerInterval < 0)
- {
- configFree (&cfg);
- return EXIT_FAILURE;
- }
+ = configRequire (&serverCfg, "authMode", "ServerRegister");
- UA_MessageSecurityMode securityMode = parseSecurityMode (securityModeStr);
- if (securityMode == UA_MESSAGESECURITYMODE_INVALID)
+ if (!applicationUri || !serverCertPath || !serverKeyPath || !serverAuthMode
+ || port < 0 || registerInterval < 0)
{
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown security mode: %s", securityModeStr);
- configFree (&cfg);
- return EXIT_FAILURE;
- }
-
- const char *securityPolicyUri = resolveSecurityPolicyUri (securityPolicyStr);
- if (!securityPolicyUri)
- {
- UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
- "Unknown security policy: %s", securityPolicyStr);
- configFree (&cfg);
+ configFree (&serverCfg);
return EXIT_FAILURE;
}
@@ -129,12 +103,12 @@ main (int argc, char **argv)
{
serverAllowAnonymous = false;
serverUsername
- = configRequire (&cfg, "serverUsername", "ServerRegister");
+ = configRequire (&serverCfg, "username", "ServerRegister");
serverPassword
- = configRequire (&cfg, "serverPassword", "ServerRegister");
+ = configRequire (&serverCfg, "password", "ServerRegister");
if (!serverUsername || !serverPassword)
{
- configFree (&cfg);
+ configFree (&serverCfg);
return EXIT_FAILURE;
}
}
@@ -144,7 +118,78 @@ main (int argc, char **argv)
"Unknown server auth mode: %s "
"(expected 'anonymous' or 'user')",
serverAuthMode);
- configFree (&cfg);
+ configFree (&serverCfg);
+ return EXIT_FAILURE;
+ }
+
+ const char *serverTrustStore
+ = configRequire (&serverCfg, "trustStore", "ServerRegister");
+ if (!serverTrustStore)
+ {
+ configFree (&serverCfg);
+ return EXIT_FAILURE;
+ }
+
+ char **serverTrustPaths = NULL;
+ size_t serverTrustSize = 0;
+ if (loadTrustStore (serverTrustStore, &serverTrustPaths, &serverTrustSize)
+ != 0)
+ {
+ configFree (&serverCfg);
+ return EXIT_FAILURE;
+ }
+
+ /* ── Load client config ─────────────────────────────────────── */
+
+ Config clientCfg;
+ if (configLoad (argv[2], &clientCfg) != 0)
+ {
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&serverCfg);
+ return EXIT_FAILURE;
+ }
+
+ const char *clientAppUri
+ = configRequire (&clientCfg, "applicationUri", "ServerRegister");
+ const char *clientCertPath
+ = configRequire (&clientCfg, "certificate", "ServerRegister");
+ const char *clientKeyPath
+ = configRequire (&clientCfg, "privateKey", "ServerRegister");
+ const char *securityModeStr
+ = configRequire (&clientCfg, "securityMode", "ServerRegister");
+ const char *securityPolicyStr
+ = configRequire (&clientCfg, "securityPolicy", "ServerRegister");
+ const char *clientAuthMode
+ = configRequire (&clientCfg, "authMode", "ServerRegister");
+
+ if (!clientAppUri || !clientCertPath || !clientKeyPath || !securityModeStr
+ || !securityPolicyStr || !clientAuthMode)
+ {
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
+ return EXIT_FAILURE;
+ }
+
+ UA_MessageSecurityMode securityMode = parseSecurityMode (securityModeStr);
+ if (securityMode == UA_MESSAGESECURITYMODE_INVALID)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown security mode: %s", securityModeStr);
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
+ return EXIT_FAILURE;
+ }
+
+ const char *securityPolicyUri = resolveSecurityPolicyUri (securityPolicyStr);
+ if (!securityPolicyUri)
+ {
+ UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
+ "Unknown security policy: %s", securityPolicyStr);
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
return EXIT_FAILURE;
}
@@ -159,12 +204,14 @@ main (int argc, char **argv)
else if (strcmp (clientAuthMode, "user") == 0)
{
clientUsername
- = configRequire (&cfg, "clientUsername", "ServerRegister");
+ = configRequire (&clientCfg, "username", "ServerRegister");
clientPassword
- = configRequire (&cfg, "clientPassword", "ServerRegister");
+ = configRequire (&clientCfg, "password", "ServerRegister");
if (!clientUsername || !clientPassword)
{
- configFree (&cfg);
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
return EXIT_FAILURE;
}
}
@@ -174,22 +221,45 @@ main (int argc, char **argv)
"Unknown client auth mode: %s "
"(expected 'anonymous' or 'user')",
clientAuthMode);
- configFree (&cfg);
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
+ return EXIT_FAILURE;
+ }
+
+ const char *clientTrustStore
+ = configRequire (&clientCfg, "trustStore", "ServerRegister");
+ if (!clientTrustStore)
+ {
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
+ return EXIT_FAILURE;
+ }
+
+ char **clientTrustPaths = NULL;
+ size_t clientTrustSize = 0;
+ if (loadTrustStore (clientTrustStore, &clientTrustPaths, &clientTrustSize)
+ != 0)
+ {
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
return EXIT_FAILURE;
}
- char **trustPaths = NULL;
- size_t trustSize = 0;
- configGetAll (&cfg, "trustList", &trustPaths, &trustSize);
+ /* ── Create and configure server ────────────────────────────── */
UA_StatusCode retval;
- UA_Server *server
- = createSecureServer ((UA_UInt16)port, applicationUri, serverCertPath,
- serverKeyPath, trustPaths, trustSize, &retval);
+ UA_Server *server = createSecureServer (
+ (UA_UInt16)port, applicationUri, serverCertPath, serverKeyPath,
+ serverTrustPaths, serverTrustSize, &retval);
if (!server)
{
- free (trustPaths);
- configFree (&cfg);
+ freeTrustStore (clientTrustPaths, clientTrustSize);
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
return EXIT_FAILURE;
}
@@ -209,8 +279,10 @@ main (int argc, char **argv)
if (retval != UA_STATUSCODE_GOOD)
{
UA_Server_delete (server);
- free (trustPaths);
- configFree (&cfg);
+ freeTrustStore (clientTrustPaths, clientTrustSize);
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
return EXIT_FAILURE;
}
}
@@ -227,14 +299,16 @@ main (int argc, char **argv)
UA_ClientConfig clientConfig;
memset (&clientConfig, 0, sizeof (UA_ClientConfig));
retval = createSecureClientConfig (
- &clientConfig, applicationUri, clientCertPath, clientKeyPath, trustPaths,
- trustSize, securityMode, securityPolicyUri);
+ &clientConfig, clientAppUri, clientCertPath, clientKeyPath,
+ clientTrustPaths, clientTrustSize, securityMode, securityPolicyUri);
if (retval != UA_STATUSCODE_GOOD)
{
UA_Server_run_shutdown (server);
UA_Server_delete (server);
- free (trustPaths);
- configFree (&cfg);
+ freeTrustStore (clientTrustPaths, clientTrustSize);
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
return EXIT_FAILURE;
}
clientConfig.logging->context = (void *)(uintptr_t)logLevel;
@@ -263,9 +337,10 @@ main (int argc, char **argv)
if (now - lastRegister >= registerInterval)
{
memset (&clientConfig, 0, sizeof (UA_ClientConfig));
- retval = createSecureClientConfig (
- &clientConfig, applicationUri, clientCertPath, clientKeyPath,
- trustPaths, trustSize, securityMode, securityPolicyUri);
+ retval = createSecureClientConfig (&clientConfig, clientAppUri,
+ clientCertPath, clientKeyPath,
+ clientTrustPaths, clientTrustSize,
+ securityMode, securityPolicyUri);
if (retval == UA_STATUSCODE_GOOD)
{
clientConfig.logging->context = (void *)(uintptr_t)logLevel;
@@ -289,8 +364,8 @@ main (int argc, char **argv)
our entry immediately rather than waiting for the cleanup timeout. */
memset (&clientConfig, 0, sizeof (UA_ClientConfig));
retval = createSecureClientConfig (
- &clientConfig, applicationUri, clientCertPath, clientKeyPath, trustPaths,
- trustSize, securityMode, securityPolicyUri);
+ &clientConfig, clientAppUri, clientCertPath, clientKeyPath,
+ clientTrustPaths, clientTrustSize, securityMode, securityPolicyUri);
if (retval == UA_STATUSCODE_GOOD)
{
clientConfig.logging->context = (void *)(uintptr_t)logLevel;
@@ -308,7 +383,9 @@ main (int argc, char **argv)
UA_Server_run_shutdown (server);
UA_Server_delete (server);
- free (trustPaths);
- configFree (&cfg);
+ freeTrustStore (clientTrustPaths, clientTrustSize);
+ freeTrustStore (serverTrustPaths, serverTrustSize);
+ configFree (&clientCfg);
+ configFree (&serverCfg);
return EXIT_SUCCESS;
}