Browse Source

move client discovery functions to a separate compilation unit

Julius Pfrommer 7 years ago
parent
commit
84c797b976
5 changed files with 182 additions and 161 deletions
  1. 1 0
      CMakeLists.txt
  2. 39 31
      include/ua_client.h
  3. 8 130
      src/client/ua_client.c
  4. 126 0
      src/client/ua_client_discovery.c
  5. 8 0
      src/client/ua_client_internal.h

+ 1 - 0
CMakeLists.txt

@@ -283,6 +283,7 @@ set(lib_sources ${PROJECT_SOURCE_DIR}/src/ua_types.c
                 ${PROJECT_SOURCE_DIR}/src/server/ua_services_subscription.c
                 # client
                 ${PROJECT_SOURCE_DIR}/src/client/ua_client.c
+                ${PROJECT_SOURCE_DIR}/src/client/ua_client_discovery.c
                 ${PROJECT_SOURCE_DIR}/src/client/ua_client_highlevel.c
                 ${PROJECT_SOURCE_DIR}/src/client/ua_client_highlevel_subscriptions.c
                 # plugins and dependencies

+ 39 - 31
include/ua_client.h

@@ -52,7 +52,7 @@ typedef struct UA_ClientConfig {
     const UA_DataType *customDataTypes;
 } UA_ClientConfig;
 
-/*
+/**
  * Client Lifecycle
  * ---------------- */
 typedef enum {
@@ -72,7 +72,7 @@ typedef enum {
 struct UA_Client;
 typedef struct UA_Client UA_Client;
 
-/** Create a new client
+/* Create a new client
  *
  * @param config for the new client. You can use UA_ClientConfig_standard
  *        which has sane defaults
@@ -81,31 +81,34 @@ typedef struct UA_Client UA_Client;
  * @return return the new Client object */
 UA_Client UA_EXPORT * UA_Client_new(UA_ClientConfig config);
 
-/** Get the client connection status */
+/* Get the client connection status */
 UA_ClientState UA_EXPORT UA_Client_getState(UA_Client *client);
 
-/** Reset a client */
+/* Reset a client */
 void UA_EXPORT UA_Client_reset(UA_Client *client);
 
-/** Delete a client */
+/* Delete a client */
 void UA_EXPORT UA_Client_delete(UA_Client *client);
 
-/** Gets a list of endpoints of a server
+/**
+ * Discovery
+ * --------- */
+
+/* Gets a list of endpoints of a server
  *
- * @param client to use. Must be connected to the same endpoint given in serverUrl or otherwise in disconnected state.
+ * @param client to use. Must be connected to the same endpoint given in
+ *        serverUrl or otherwise in disconnected state.
  * @param serverUrl url to connect (for example "opc.tcp://localhost:16664")
  * @param endpointDescriptionsSize size of the array of endpoint descriptions
  * @param endpointDescriptions array of endpoint descriptions that is allocated
  *        by the function (you need to free manually)
- * @return Indicates whether the operation succeeded or returns an error code
- */
+ * @return Indicates whether the operation succeeded or returns an error code */
 UA_StatusCode UA_EXPORT
 UA_Client_getEndpoints(UA_Client *client, const char *serverUrl,
                        size_t* endpointDescriptionsSize,
                        UA_EndpointDescription** endpointDescriptions);
 
-/**
- * Gets a list of all registered servers at the given server.
+/* Gets a list of all registered servers at the given server.
  *
  * You can pass an optional filter for serverUris. If the given server is not registered,
  * an empty array will be returned. If the server is registered, only that application
@@ -115,47 +118,52 @@ UA_Client_getEndpoints(UA_Client *client, const char *serverUrl,
  * in the returned application description. The array indicates the order of preference.
  * A server may have localized names.
  *
- * @param client to use. Must be connected to the same endpoint given in serverUrl or otherwise in disconnected state.
+ * @param client to use. Must be connected to the same endpoint given in
+ *        serverUrl or otherwise in disconnected state.
  * @param serverUrl url to connect (for example "opc.tcp://localhost:16664")
  * @param serverUrisSize Optional filter for specific server uris
  * @param serverUris Optional filter for specific server uris
  * @param localeIdsSize Optional indication which locale you prefer
  * @param localeIds Optional indication which locale you prefer
- * @param registeredServerSize size of returned array, i.e., number of found/registered servers
+ * @param registeredServersSize size of returned array, i.e., number of found/registered servers
  * @param registeredServers array containing found/registered servers
- * @return Indicates whether the operation succeeded or returns an error code
- */
+ * @return Indicates whether the operation succeeded or returns an error code */
 UA_StatusCode UA_EXPORT
 UA_Client_findServers(UA_Client *client, const char *serverUrl,
                       size_t serverUrisSize, UA_String *serverUris,
                       size_t localeIdsSize, UA_String *localeIds,
-                      size_t *registeredServerSize, UA_ApplicationDescription **registeredServers);
+                      size_t *registeredServersSize,
+                      UA_ApplicationDescription **registeredServers);
 
-/**
- * Get a list of all known server in the network. Only supported by LDS servers.
- *
+/* Get a list of all known server in the network. Only supported by LDS servers.
  *
- * @param client to use. Must be connected to the same endpoint given in serverUrl or otherwise in disconnected state.
+ * @param client to use. Must be connected to the same endpoint given in
+ * serverUrl or otherwise in disconnected state.
  * @param serverUrl url to connect (for example "opc.tcp://localhost:16664")
- * @param startingRecordId optional. Only return the records with an ID higher or equal the given. Can be used for pagination to only get a subset of the full list
+ * @param startingRecordId optional. Only return the records with an ID higher
+ *        or equal the given. Can be used for pagination to only get a subset of
+ *        the full list
  * @param maxRecordsToReturn optional. Only return this number of records
- * @param serverCapabilityFilterSize optional. Filter the returned list to only get servers with given capabilities, e.g. "LDS"
- * @param serverCapabilityFilter optional. Filter the returned list to only get servers with given capabilities, e.g. "LDS"
- * @param serverOnNetworkSize size of returned array, i.e., number of known/registered servers
+
+ * @param serverCapabilityFilterSize optional. Filter the returned list to only
+ *        get servers with given capabilities, e.g. "LDS"
+ * @param serverCapabilityFilter optional. Filter the returned list to only get
+ *        servers with given capabilities, e.g. "LDS"
+ * @param serverOnNetworkSize size of returned array, i.e., number of
+ *        known/registered servers
  * @param serverOnNetwork array containing known/registered servers
- * @return Indicates whether the operation succeeded or returns an error code
- */
+ * @return Indicates whether the operation succeeded or returns an error code */
 UA_StatusCode UA_EXPORT
 UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl,
                      UA_UInt32 startingRecordId, UA_UInt32 maxRecordsToReturn,
                      size_t serverCapabilityFilterSize, UA_String *serverCapabilityFilter,
                      size_t *serverOnNetworkSize, UA_ServerOnNetwork **serverOnNetwork);
 
-/*
+/**
  * Manage the Connection
  * --------------------- */
 
-/** Connect to the selected server
+/* Connect to the selected server
  *
  * @param client to use
  * @param endpointURL to connect (for example "opc.tcp://localhost:16664")
@@ -163,7 +171,7 @@ UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl,
 UA_StatusCode UA_EXPORT
 UA_Client_connect(UA_Client *client, const char *endpointUrl);
 
-/** Connect to the selected server with the given username and password
+/* Connect to the selected server with the given username and password
  *
  * @param client to use
  * @param endpointURL to connect (for example "opc.tcp://localhost:16664")
@@ -174,10 +182,10 @@ UA_StatusCode UA_EXPORT
 UA_Client_connect_username(UA_Client *client, const char *endpointUrl,
                            const char *username, const char *password);
 
-/** Close a connection to the selected server */
+/* Close a connection to the selected server */
 UA_StatusCode UA_EXPORT UA_Client_disconnect(UA_Client *client);
 
-/** Renew the underlying secure channel */
+/* Renew the underlying secure channel */
 UA_StatusCode UA_EXPORT UA_Client_manuallyRenewSecureChannel(UA_Client *client);
 
 /**

+ 8 - 130
src/client/ua_client.c

@@ -366,9 +366,9 @@ static UA_StatusCode ActivateSession(UA_Client *client) {
 }
 
 /* Gets a list of endpoints. Memory is allocated for endpointDescription array */
-static UA_StatusCode
-GetEndpoints(UA_Client *client, size_t* endpointDescriptionsSize,
-             UA_EndpointDescription** endpointDescriptions) {
+UA_StatusCode
+__UA_Client_getEndpoints(UA_Client *client, size_t* endpointDescriptionsSize,
+                         UA_EndpointDescription** endpointDescriptions) {
     UA_GetEndpointsRequest request;
     UA_GetEndpointsRequest_init(&request);
     request.requestHeader.timestamp = UA_DateTime_now();
@@ -399,7 +399,7 @@ GetEndpoints(UA_Client *client, size_t* endpointDescriptionsSize,
 static UA_StatusCode EndpointsHandshake(UA_Client *client) {
     UA_EndpointDescription* endpointArray = NULL;
     size_t endpointArraySize = 0;
-    UA_StatusCode retval = GetEndpoints(client, &endpointArraySize, &endpointArray);
+    UA_StatusCode retval = __UA_Client_getEndpoints(client, &endpointArraySize, &endpointArray);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
 
@@ -565,8 +565,9 @@ UA_Client_connect_username(UA_Client *client, const char *endpointUrl,
     return UA_Client_connect(client, endpointUrl);
 }
 
-static UA_StatusCode
-_UA_Client_connect(UA_Client *client, const char *endpointUrl, UA_Boolean endpointsHandshake, UA_Boolean createSession) {
+UA_StatusCode
+__UA_Client_connect(UA_Client *client, const char *endpointUrl,
+                    UA_Boolean endpointsHandshake, UA_Boolean createSession) {
     if(client->state == UA_CLIENTSTATE_CONNECTED)
         return UA_STATUSCODE_GOOD;
     if(client->state == UA_CLIENTSTATE_ERRORED) {
@@ -613,7 +614,7 @@ _UA_Client_connect(UA_Client *client, const char *endpointUrl, UA_Boolean endpoi
 
 UA_StatusCode
 UA_Client_connect(UA_Client *client, const char *endpointUrl) {
-    return _UA_Client_connect(client, endpointUrl, UA_TRUE, UA_TRUE);
+    return __UA_Client_connect(client, endpointUrl, UA_TRUE, UA_TRUE);
 }
 
 UA_StatusCode UA_Client_disconnect(UA_Client *client) {
@@ -637,129 +638,6 @@ UA_StatusCode UA_Client_manuallyRenewSecureChannel(UA_Client *client) {
     return retval;
 }
 
-UA_StatusCode
-UA_Client_getEndpoints(UA_Client *client, const char *serverUrl,
-                       size_t* endpointDescriptionsSize,
-                       UA_EndpointDescription** endpointDescriptions) {
-    if (client->state == UA_CLIENTSTATE_CONNECTED &&
-        strncmp((const char*)client->endpointUrl.data, serverUrl, client->endpointUrl.length) != 0) {
-        // client is already connected but to a different endpoint url.
-        return UA_STATUSCODE_BADINVALIDARGUMENT;
-    }
-
-    UA_StatusCode retval = _UA_Client_connect(client, serverUrl, UA_FALSE, UA_FALSE);
-    if(retval == UA_STATUSCODE_GOOD)
-        retval = GetEndpoints(client, endpointDescriptionsSize, endpointDescriptions);
-
-    UA_Client_disconnect(client);
-    UA_Client_reset(client);
-    return retval;
-}
-
-UA_StatusCode
-UA_Client_findServers(UA_Client *client, const char *serverUrl,
-                      size_t serverUrisSize, UA_String *serverUris,
-                      size_t localeIdsSize, UA_String *localeIds,
-                      size_t *registeredServerSize, UA_ApplicationDescription **registeredServers) {
-
-    if (client->state == UA_CLIENTSTATE_CONNECTED &&
-       strncmp((const char*)client->endpointUrl.data, serverUrl, client->endpointUrl.length) != 0) {
-        // client is already connected but to a different endpoint url.
-        return UA_STATUSCODE_BADINVALIDARGUMENT;
-    }
-
-    UA_StatusCode retval = _UA_Client_connect(client, serverUrl, UA_TRUE, UA_FALSE);
-    if (retval != UA_STATUSCODE_GOOD) {
-        UA_Client_disconnect(client);
-        UA_Client_reset(client);
-        return retval;
-    }
-
-    UA_FindServersRequest request;
-    UA_FindServersRequest_init(&request);
-
-    request.serverUrisSize = serverUrisSize;
-    request.serverUris = serverUris;
-
-    request.localeIdsSize = localeIdsSize;
-    request.localeIds = localeIds;
-
-    // now send the request
-    UA_FindServersResponse response;
-    UA_FindServersResponse_init(&response);
-    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST],
-                        &response, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]);
-    retval = response.responseHeader.serviceResult;
-    if (retval != UA_STATUSCODE_GOOD) {
-        *registeredServerSize = 0;
-        goto cleanup;
-    }
-
-    *registeredServerSize = response.serversSize;
-    *registeredServers = (UA_ApplicationDescription *) UA_Array_new(response.serversSize,
-                                                                    &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
-    for (size_t i = 0; i < response.serversSize; i++)
-        UA_ApplicationDescription_copy(&response.servers[i], &(*registeredServers)[i]);
-
-    /* always cleanup */
-    cleanup:
-    UA_FindServersResponse_deleteMembers(&response);
-    UA_Client_disconnect(client);
-    UA_Client_reset(client);
-    return retval;
-}
-
-UA_StatusCode
-UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl,
-                               UA_UInt32 startingRecordId, UA_UInt32 maxRecordsToReturn,
-                               size_t serverCapabilityFilterSize, UA_String *serverCapabilityFilter,
-                               size_t *serverOnNetworkSize, UA_ServerOnNetwork **serverOnNetwork) {
-
-    if (client->state == UA_CLIENTSTATE_CONNECTED &&
-        strncmp((const char*)client->endpointUrl.data, serverUrl, client->endpointUrl.length) != 0) {
-        // client is already connected but to a different endpoint url.
-        return UA_STATUSCODE_BADINVALIDARGUMENT;
-    }
-
-    UA_StatusCode retval = _UA_Client_connect(client, serverUrl, UA_TRUE, UA_FALSE);
-    if (retval != UA_STATUSCODE_GOOD) {
-        UA_Client_disconnect(client);
-        UA_Client_reset(client);
-        return retval;
-    }
-
-    UA_FindServersOnNetworkRequest request;
-    UA_FindServersOnNetworkRequest_init(&request);
-
-    request.startingRecordId = startingRecordId;
-    request.maxRecordsToReturn = maxRecordsToReturn;
-
-    request.serverCapabilityFilterSize = serverCapabilityFilterSize;
-    request.serverCapabilityFilter = serverCapabilityFilter;
-
-    // now send the request
-    UA_FindServersOnNetworkResponse response;
-    UA_FindServersOnNetworkResponse_init(&response);
-    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST],
-                        &response, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]);
-    retval = response.responseHeader.serviceResult;
-    if (retval != UA_STATUSCODE_GOOD) {
-        *serverOnNetworkSize = 0;
-        goto cleanup;
-    }
-
-    *serverOnNetworkSize = response.serversSize;
-    *serverOnNetwork = (UA_ServerOnNetwork *) UA_Array_new(response.serversSize, &UA_TYPES[UA_TYPES_SERVERONNETWORK]);
-    for (size_t i = 0; i < response.serversSize; i++)
-        UA_ServerOnNetwork_copy(&response.servers[i], &(*serverOnNetwork)[i]);
-
-    cleanup:
-    UA_FindServersOnNetworkResponse_deleteMembers(&response);
-    UA_Client_disconnect(client);
-    UA_Client_reset(client);
-    return retval;
-}
-
 /****************/
 /* Raw Services */
 /****************/

+ 126 - 0
src/client/ua_client_discovery.c

@@ -0,0 +1,126 @@
+/* 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/. */
+
+#include "ua_client.h"
+#include "ua_client_internal.h"
+
+UA_StatusCode
+UA_Client_getEndpoints(UA_Client *client, const char *serverUrl,
+                       size_t* endpointDescriptionsSize,
+                       UA_EndpointDescription** endpointDescriptions) {
+    if(client->state == UA_CLIENTSTATE_CONNECTED &&
+        strncmp((const char*)client->endpointUrl.data, serverUrl, client->endpointUrl.length) != 0) {
+        // client is already connected but to a different endpoint url.
+        return UA_STATUSCODE_BADINVALIDARGUMENT;
+    }
+
+    UA_StatusCode retval = __UA_Client_connect(client, serverUrl, UA_FALSE, UA_FALSE);
+    if(retval == UA_STATUSCODE_GOOD)
+        retval = __UA_Client_getEndpoints(client, endpointDescriptionsSize, endpointDescriptions);
+
+    UA_Client_disconnect(client);
+    UA_Client_reset(client);
+    return retval;
+}
+
+UA_StatusCode
+UA_Client_findServers(UA_Client *client, const char *serverUrl,
+                      size_t serverUrisSize, UA_String *serverUris,
+                      size_t localeIdsSize, UA_String *localeIds,
+                      size_t *registeredServersSize,
+                      UA_ApplicationDescription **registeredServers) {
+    /* Client is already connected but to a different endpoint url */
+    if(client->state == UA_CLIENTSTATE_CONNECTED &&
+       strncmp((const char*)client->endpointUrl.data, serverUrl, client->endpointUrl.length) != 0)
+        return UA_STATUSCODE_BADINVALIDARGUMENT;
+
+    UA_StatusCode retval = __UA_Client_connect(client, serverUrl, UA_TRUE, UA_FALSE);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_Client_disconnect(client);
+        UA_Client_reset(client);
+        return retval;
+    }
+
+    /* Prepare the request */
+    UA_FindServersRequest request;
+    UA_FindServersRequest_init(&request);
+    request.serverUrisSize = serverUrisSize;
+    request.serverUris = serverUris;
+    request.localeIdsSize = localeIdsSize;
+    request.localeIds = localeIds;
+
+    /* Send the request */
+    UA_FindServersResponse response;
+    UA_FindServersResponse_init(&response);
+    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST],
+                        &response, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]);
+
+    /* Process the response */
+    retval = response.responseHeader.serviceResult;
+    if(retval == UA_STATUSCODE_GOOD) {
+        *registeredServersSize = response.serversSize;
+        *registeredServers = response.servers;
+        response.serversSize = 0;
+        response.servers = NULL;
+    } else {
+        *registeredServersSize = 0;
+        *registeredServers = NULL;
+    }
+
+    /* Clean up */
+    UA_FindServersResponse_deleteMembers(&response);
+    UA_Client_disconnect(client);
+    UA_Client_reset(client);
+    return retval;
+}
+
+UA_StatusCode
+UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl,
+                               UA_UInt32 startingRecordId, UA_UInt32 maxRecordsToReturn,
+                               size_t serverCapabilityFilterSize, UA_String *serverCapabilityFilter,
+                               size_t *serverOnNetworkSize, UA_ServerOnNetwork **serverOnNetwork) {
+    /* Client is already connected but to a different endpoint url */
+    if(client->state == UA_CLIENTSTATE_CONNECTED &&
+        strncmp((const char*)client->endpointUrl.data, serverUrl, client->endpointUrl.length) != 0)
+        return UA_STATUSCODE_BADINVALIDARGUMENT;
+
+    UA_StatusCode retval = __UA_Client_connect(client, serverUrl, UA_TRUE, UA_FALSE);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_Client_disconnect(client);
+        UA_Client_reset(client);
+        return retval;
+    }
+
+    /* Prepare the request */
+    UA_FindServersOnNetworkRequest request;
+    UA_FindServersOnNetworkRequest_init(&request);
+    request.startingRecordId = startingRecordId;
+    request.maxRecordsToReturn = maxRecordsToReturn;
+    request.serverCapabilityFilterSize = serverCapabilityFilterSize;
+    request.serverCapabilityFilter = serverCapabilityFilter;
+
+    /* Send the request */
+    UA_FindServersOnNetworkResponse response;
+    UA_FindServersOnNetworkResponse_init(&response);
+    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST],
+                        &response, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]);
+
+    /* Process the response */
+    retval = response.responseHeader.serviceResult;
+    if(retval == UA_STATUSCODE_GOOD) {
+        *serverOnNetworkSize = response.serversSize;
+        *serverOnNetwork = response.servers;
+        response.serversSize = 0;
+        response.servers = NULL;
+    } else {
+        *serverOnNetworkSize = 0;
+        *serverOnNetwork = NULL;
+    }
+
+    /* Clean up */
+    UA_FindServersOnNetworkResponse_deleteMembers(&response);
+    UA_Client_disconnect(client);
+    UA_Client_reset(client);
+    return retval;
+}

+ 8 - 0
src/client/ua_client_internal.h

@@ -98,4 +98,12 @@ struct UA_Client {
 UA_StatusCode UA_EXPORT
 UA_Client_connect_no_session(UA_Client *client, const char *endpointUrl);
 
+UA_StatusCode
+__UA_Client_connect(UA_Client *client, const char *endpointUrl,
+                    UA_Boolean endpointsHandshake, UA_Boolean createSession);
+
+UA_StatusCode
+__UA_Client_getEndpoints(UA_Client *client, size_t* endpointDescriptionsSize,
+                         UA_EndpointDescription** endpointDescriptions);
+
 #endif /* UA_CLIENT_INTERNAL_H_ */