Browse Source

split server_discovery into a separate compilation unit

Julius Pfrommer 8 years ago
parent
commit
de72bcba23
4 changed files with 175 additions and 176 deletions
  1. 1 0
      CMakeLists.txt
  2. 29 27
      include/ua_server.h
  3. 0 149
      src/server/ua_server.c
  4. 145 0
      src/server/ua_server_discovery.c

+ 1 - 0
CMakeLists.txt

@@ -256,6 +256,7 @@ set(lib_sources ${PROJECT_SOURCE_DIR}/src/ua_types.c
                 ${PROJECT_SOURCE_DIR}/src/ua_session.c
                 ${PROJECT_SOURCE_DIR}/src/ua_timer.c
                 ${PROJECT_SOURCE_DIR}/src/server/ua_server.c
+                ${PROJECT_SOURCE_DIR}/src/server/ua_server_discovery.c
                 ${PROJECT_SOURCE_DIR}/src/server/ua_server_ns0.c
                 ${PROJECT_SOURCE_DIR}/src/server/ua_server_binary.c
                 ${PROJECT_SOURCE_DIR}/src/server/ua_server_utils.c

+ 29 - 27
include/ua_server.h

@@ -192,13 +192,14 @@ typedef struct {
     UA_DoubleRange samplingIntervalLimits;
     UA_UInt32Range queueSizeLimits; /* Negotiated with the client */
 
-#ifdef UA_ENABLE_DISCOVERY
     /* Discovery */
-    // timeout in seconds when to automatically remove a registered server from the list,
-    // if it doesn't re-register within the given time frame. A value of 0 disables automatic removal.
-    // Default is 60 Minutes (60*60). Must be bigger than 10 seconds, because cleanup is only triggered approximately
-    // ervery 10 seconds.
-    // The server will still be removed depending on the state of the semaphore file.
+#ifdef UA_ENABLE_DISCOVERY
+    /* Timeout in seconds when to automatically remove a registered server from
+     * the list, if it doesn't re-register within the given time frame. A value
+     * of 0 disables automatic removal. Default is 60 Minutes (60*60). Must be
+     * bigger than 10 seconds, because cleanup is only triggered approximately
+     * ervery 10 seconds. The server will still be removed depending on the
+     * state of the semaphore file. */
     UA_UInt32 discoveryCleanupTimeout;
 #endif
 } UA_ServerConfig;
@@ -605,9 +606,7 @@ UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
  /**
  * Discovery
  * --------- */
-
- /**
-  * Register the given server instance at the discovery server.
+ /* Register the given server instance at the discovery server.
   * This should be called periodically.
   * The semaphoreFilePath is optional. If the given file is deleted,
   * the server will automatically be unregistered. This could be
@@ -616,23 +615,24 @@ UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
   * When the server shuts down you need to call unregister.
   *
   * @param server
-  * @param discoveryServerUrl if set to NULL, the default value 'opc.tcp://localhost:4840' will be used
+  * @param discoveryServerUrl if set to NULL, the default value
+  *        'opc.tcp://localhost:4840' will be used
   * @param semaphoreFilePath optional parameter pointing to semaphore file.
   */
  UA_StatusCode UA_EXPORT
- UA_Server_register_discovery(UA_Server *server, const char* discoveryServerUrl, const char* semaphoreFilePath);
+ UA_Server_register_discovery(UA_Server *server, const char* discoveryServerUrl,
+                              const char* semaphoreFilePath);
 
- /**
-  * Unregister the given server instance from the discovery server.
+ /* Unregister the given server instance from the discovery server.
   * This should only be called when the server is shutting down.
   * @param server
-  * @param discoveryServerUrl if set to NULL, the default value 'opc.tcp://localhost:4840' will be used
+  * @param discoveryServerUrl if set to NULL, the default value
+  *        'opc.tcp://localhost:4840' will be used
   */
  UA_StatusCode UA_EXPORT
  UA_Server_unregister_discovery(UA_Server *server, const char* discoveryServerUrl);
 
- /**
-  * Adds a periodic job to register the server with the LDS (local discovery server)
+ /* Adds a periodic job to register the server with the LDS (local discovery server)
   * periodically. The interval between each register call is given as second parameter.
   * It should be 10 minutes by default (= 10*60*1000).
   *
@@ -647,26 +647,28 @@ UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
   * @param discoveryServerUrl if set to NULL, the default value 'opc.tcp://localhost:4840' will be used
   * @param intervalMs
   * @param delayFirstRegisterMs
-  * @param periodicJobId
-  */
+  * @param periodicJobId */
  UA_StatusCode UA_EXPORT
-         UA_Server_addPeriodicServerRegisterJob(UA_Server *server, const char* discoveryServerUrl, const UA_UInt32 intervalMs, const UA_UInt32 delayFirstRegisterMs, UA_Guid* periodicJobId);
+UA_Server_addPeriodicServerRegisterJob(UA_Server *server, const char* discoveryServerUrl,
+                                       const UA_UInt32 intervalMs, const UA_UInt32 delayFirstRegisterMs,
+                                       UA_Guid* periodicJobId);
 
- /* Callback for RegisterServer. Data is passed from the register call */
- typedef void (*UA_Server_registerServerCallback)(const UA_RegisteredServer *registeredServer, void* data);
+/* Callback for RegisterServer. Data is passed from the register call */
+typedef void (*UA_Server_registerServerCallback)(const UA_RegisteredServer *registeredServer, void* data);
 
-/**
- * Set the callback which is called if another server registeres or unregisteres with this instance.
- * If called multiple times, previous data will be overwritten.
+/* Set the callback which is called if another server registeres or unregisteres
+ * with this instance. If called multiple times, previous data will be
+ * overwritten.
+ *
  * @param server
  * @param cb the callback
  * @param data data passed to the callback
  * @return UA_STATUSCODE_SUCCESS on success
  */
 void UA_EXPORT
-         UA_Server_setRegisterServerCallback(UA_Server *server,
-                                             UA_Server_registerServerCallback cb,
-                                             void* data);
+ UA_Server_setRegisterServerCallback(UA_Server *server,
+                                     UA_Server_registerServerCallback cb,
+                                     void* data);
 
 #ifdef UA_ENABLE_DISCOVERY_MULTICAST
 

+ 0 - 149
src/server/ua_server.c

@@ -10,19 +10,10 @@
 #include "ua_services.h"
 #include "ua_nodeids.h"
 
-#ifdef UA_ENABLE_DISCOVERY
-#include "ua_client.h"
-#include "ua_config_standard.h"
-#endif
-
 #ifdef UA_ENABLE_GENERATE_NAMESPACE0
 #include "ua_namespaceinit_generated.h"
 #endif
 
-#ifdef UA_ENABLE_SUBSCRIPTIONS
-#include "ua_subscription.h"
-#endif
-
 #if defined(UA_ENABLE_MULTITHREADING) && !defined(NDEBUG)
 UA_THREAD_LOCAL bool rcu_locked = false;
 #endif
@@ -363,146 +354,6 @@ UA_Server_new(const UA_ServerConfig config) {
     return server;
 }
 
-/*************/
-/* Discovery */
-/*************/
-
-#ifdef UA_ENABLE_DISCOVERY
-
-static UA_StatusCode
-register_server_with_discovery_server(UA_Server *server, const char* discoveryServerUrl,
-                                      const UA_Boolean isUnregister,
-                                      const char* semaphoreFilePath) {
-    /* Use a fallback URL */
-    const char *url = "opc.tcp://localhost:4840";
-    if(discoveryServerUrl)
-        url = discoveryServerUrl;
-
-    /* Create the client */
-    UA_Client *client = UA_Client_new(UA_ClientConfig_standard);
-    if(!client)
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-
-    /* Connect the client */
-    UA_StatusCode retval = UA_Client_connect(client, url);
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_CLIENT,
-                     "Connecting to client failed with statuscode %s", UA_StatusCode_name(retval));
-        UA_Client_delete(client);
-        return retval;
-    }
-
-    /* Prepare the request. Do not cleanup the request after the service call,
-     * as the members are stack-allocated or point into the server config. */
-    UA_RegisterServer2Request request;
-    UA_RegisterServer2Request_init(&request);
-    request.requestHeader.timestamp = UA_DateTime_now();
-    request.requestHeader.timeoutHint = 10000;
-
-    request.server.isOnline = !isUnregister;
-    request.server.serverUri = server->config.applicationDescription.applicationUri;
-    request.server.productUri = server->config.applicationDescription.productUri;
-    request.server.serverType = server->config.applicationDescription.applicationType;
-    request.server.gatewayServerUri = server->config.applicationDescription.gatewayServerUri;
-
-    if(semaphoreFilePath) {
-#ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
-        request.server.semaphoreFilePath =
-            UA_STRING((char*)(uintptr_t)semaphoreFilePath); /* dirty cast */
-#else
-        UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_CLIENT,
-                       "Ignoring semaphore file path. open62541 not compiled "
-                       "with UA_ENABLE_DISCOVERY_SEMAPHORE=ON");
-#endif
-    }
-
-    request.server.serverNames = &server->config.applicationDescription.applicationName;
-    request.server.serverNamesSize = 1;
-
-    /* Copy the discovery urls from the server config and the network layers*/
-    size_t config_discurls = server->config.applicationDescription.discoveryUrlsSize;
-    size_t nl_discurls = server->config.networkLayersSize;
-    size_t total_discurls = config_discurls * nl_discurls;
-    request.server.discoveryUrls = (UA_String*)UA_alloca(sizeof(UA_String) * total_discurls);
-    request.server.discoveryUrlsSize = config_discurls + nl_discurls;
-
-    for(size_t i = 0; i < config_discurls; ++i)
-        request.server.discoveryUrls[i] = server->config.applicationDescription.discoveryUrls[i];
-
-    /* TODO: Add nl only if discoveryUrl not already present */
-    for(size_t i = 0; i < nl_discurls; ++i) {
-        UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
-        request.server.discoveryUrls[config_discurls + i] = nl->discoveryUrl;
-    }
-
-    UA_MdnsDiscoveryConfiguration mdnsConfig;
-    UA_MdnsDiscoveryConfiguration_init(&mdnsConfig);
-
-    request.discoveryConfigurationSize = 0;
-    request.discoveryConfigurationSize = 1;
-    request.discoveryConfiguration = UA_ExtensionObject_new();
-    UA_ExtensionObject_init(&request.discoveryConfiguration[0]);
-    request.discoveryConfiguration[0].encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
-    request.discoveryConfiguration[0].content.decoded.type = &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION];
-    request.discoveryConfiguration[0].content.decoded.data = &mdnsConfig;
-
-    mdnsConfig.mdnsServerName = server->config.mdnsServerName;
-    mdnsConfig.serverCapabilities = server->config.serverCapabilities;
-    mdnsConfig.serverCapabilitiesSize = server->config.serverCapabilitiesSize;
-
-    // First try with RegisterServer2, if that isn't implemented, use RegisterServer
-    UA_RegisterServer2Response response;
-    UA_RegisterServer2Response_init(&response);
-    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST],
-                        &response, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]);
-
-    UA_StatusCode serviceResult = response.responseHeader.serviceResult;
-    UA_RegisterServer2Response_deleteMembers(&response);
-    UA_ExtensionObject_delete(request.discoveryConfiguration);
-
-    if(serviceResult == UA_STATUSCODE_BADNOTIMPLEMENTED ||
-       serviceResult == UA_STATUSCODE_BADSERVICEUNSUPPORTED) {
-        /* Try RegisterServer */
-        UA_RegisterServerRequest request_fallback;
-        UA_RegisterServerRequest_init(&request_fallback);
-        /* Copy from RegisterServer2 request */
-        request_fallback.requestHeader = request.requestHeader;
-        request_fallback.server = request.server;
-
-        UA_RegisterServerResponse response_fallback;
-        UA_RegisterServerResponse_init(&response_fallback);
-
-        __UA_Client_Service(client, &request_fallback, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST],
-                            &response_fallback, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]);
-
-        serviceResult = response_fallback.responseHeader.serviceResult;
-        UA_RegisterServerResponse_deleteMembers(&response_fallback);
-    }
-
-    if(serviceResult != UA_STATUSCODE_GOOD) {
-        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_CLIENT,
-                     "RegisterServer/RegisterServer2 failed with statuscode %s",
-                     UA_StatusCode_name(serviceResult));
-    }
-
-    UA_Client_disconnect(client);
-    UA_Client_delete(client);
-    return serviceResult;
-}
-
-UA_StatusCode
-UA_Server_register_discovery(UA_Server *server, const char* discoveryServerUrl,
-                             const char* semaphoreFilePath) {
-    return register_server_with_discovery_server(server, discoveryServerUrl, UA_FALSE, semaphoreFilePath);
-}
-
-UA_StatusCode
-UA_Server_unregister_discovery(UA_Server *server, const char* discoveryServerUrl) {
-    return register_server_with_discovery_server(server, discoveryServerUrl, UA_TRUE, NULL);
-}
-
-#endif
-
 /*****************/
 /* Repeated Jobs */
 /*****************/

+ 145 - 0
src/server/ua_server_discovery.c

@@ -0,0 +1,145 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef UA_ENABLE_DISCOVERY
+
+#include "ua_server_internal.h"
+#include "ua_client.h"
+#include "ua_config_standard.h"
+
+static UA_StatusCode
+register_server_with_discovery_server(UA_Server *server, const char* discoveryServerUrl,
+                                      const UA_Boolean isUnregister,
+                                      const char* semaphoreFilePath) {
+    /* Use a fallback URL */
+    const char *url = "opc.tcp://localhost:4840";
+    if(discoveryServerUrl)
+        url = discoveryServerUrl;
+
+    /* Create the client */
+    UA_Client *client = UA_Client_new(UA_ClientConfig_standard);
+    if(!client)
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+
+    /* Connect the client */
+    UA_StatusCode retval = UA_Client_connect(client, url);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_CLIENT,
+                     "Connecting to client failed with statuscode %s", UA_StatusCode_name(retval));
+        UA_Client_delete(client);
+        return retval;
+    }
+
+    /* Prepare the request. Do not cleanup the request after the service call,
+     * as the members are stack-allocated or point into the server config. */
+    UA_RegisterServer2Request request;
+    UA_RegisterServer2Request_init(&request);
+    request.requestHeader.timestamp = UA_DateTime_now();
+    request.requestHeader.timeoutHint = 10000;
+
+    request.server.isOnline = !isUnregister;
+    request.server.serverUri = server->config.applicationDescription.applicationUri;
+    request.server.productUri = server->config.applicationDescription.productUri;
+    request.server.serverType = server->config.applicationDescription.applicationType;
+    request.server.gatewayServerUri = server->config.applicationDescription.gatewayServerUri;
+
+    if(semaphoreFilePath) {
+#ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
+        request.server.semaphoreFilePath =
+            UA_STRING((char*)(uintptr_t)semaphoreFilePath); /* dirty cast */
+#else
+        UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_CLIENT,
+                       "Ignoring semaphore file path. open62541 not compiled "
+                       "with UA_ENABLE_DISCOVERY_SEMAPHORE=ON");
+#endif
+    }
+
+    request.server.serverNames = &server->config.applicationDescription.applicationName;
+    request.server.serverNamesSize = 1;
+
+    /* Copy the discovery urls from the server config and the network layers*/
+    size_t config_discurls = server->config.applicationDescription.discoveryUrlsSize;
+    size_t nl_discurls = server->config.networkLayersSize;
+    size_t total_discurls = config_discurls * nl_discurls;
+    request.server.discoveryUrls = (UA_String*)UA_alloca(sizeof(UA_String) * total_discurls);
+    request.server.discoveryUrlsSize = config_discurls + nl_discurls;
+
+    for(size_t i = 0; i < config_discurls; ++i)
+        request.server.discoveryUrls[i] = server->config.applicationDescription.discoveryUrls[i];
+
+    /* TODO: Add nl only if discoveryUrl not already present */
+    for(size_t i = 0; i < nl_discurls; ++i) {
+        UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
+        request.server.discoveryUrls[config_discurls + i] = nl->discoveryUrl;
+    }
+
+    UA_MdnsDiscoveryConfiguration mdnsConfig;
+    UA_MdnsDiscoveryConfiguration_init(&mdnsConfig);
+
+    request.discoveryConfigurationSize = 0;
+    request.discoveryConfigurationSize = 1;
+    request.discoveryConfiguration = UA_ExtensionObject_new();
+    UA_ExtensionObject_init(&request.discoveryConfiguration[0]);
+    request.discoveryConfiguration[0].encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
+    request.discoveryConfiguration[0].content.decoded.type = &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION];
+    request.discoveryConfiguration[0].content.decoded.data = &mdnsConfig;
+
+    mdnsConfig.mdnsServerName = server->config.mdnsServerName;
+    mdnsConfig.serverCapabilities = server->config.serverCapabilities;
+    mdnsConfig.serverCapabilitiesSize = server->config.serverCapabilitiesSize;
+
+    // First try with RegisterServer2, if that isn't implemented, use RegisterServer
+    UA_RegisterServer2Response response;
+    UA_RegisterServer2Response_init(&response);
+    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST],
+                        &response, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]);
+
+    UA_StatusCode serviceResult = response.responseHeader.serviceResult;
+    UA_RegisterServer2Response_deleteMembers(&response);
+    UA_ExtensionObject_delete(request.discoveryConfiguration);
+
+    if(serviceResult == UA_STATUSCODE_BADNOTIMPLEMENTED ||
+       serviceResult == UA_STATUSCODE_BADSERVICEUNSUPPORTED) {
+        /* Try RegisterServer */
+        UA_RegisterServerRequest request_fallback;
+        UA_RegisterServerRequest_init(&request_fallback);
+        /* Copy from RegisterServer2 request */
+        request_fallback.requestHeader = request.requestHeader;
+        request_fallback.server = request.server;
+
+        UA_RegisterServerResponse response_fallback;
+        UA_RegisterServerResponse_init(&response_fallback);
+
+        __UA_Client_Service(client, &request_fallback, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST],
+                            &response_fallback, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]);
+
+        serviceResult = response_fallback.responseHeader.serviceResult;
+        UA_RegisterServerResponse_deleteMembers(&response_fallback);
+    }
+
+    if(serviceResult != UA_STATUSCODE_GOOD) {
+        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_CLIENT,
+                     "RegisterServer/RegisterServer2 failed with statuscode %s",
+                     UA_StatusCode_name(serviceResult));
+    }
+
+    UA_Client_disconnect(client);
+    UA_Client_delete(client);
+    return serviceResult;
+}
+
+UA_StatusCode
+UA_Server_register_discovery(UA_Server *server, const char* discoveryServerUrl,
+                             const char* semaphoreFilePath) {
+    return register_server_with_discovery_server(server, discoveryServerUrl,
+                                                 UA_FALSE, semaphoreFilePath);
+}
+
+UA_StatusCode
+UA_Server_unregister_discovery(UA_Server *server, const char* discoveryServerUrl) {
+    return register_server_with_discovery_server(server, discoveryServerUrl,
+                                                 UA_TRUE, NULL);
+}
+
+#endif /* UA_ENABLE_DISCOVERY */