Parcourir la source

PubSub: Simplify UA_Server_addPubSubConnection

Julius Pfrommer il y a 6 ans
Parent
commit
cea6caea99
1 fichiers modifiés avec 83 ajouts et 71 suppressions
  1. 83 71
      src/pubsub/ua_pubsub_manager.c

+ 83 - 71
src/pubsub/ua_pubsub_manager.c

@@ -3,6 +3,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner)
+ * Copyright (c) 2018 Fraunhofer IOSB (Author: Julius Pfrommer)
  */
 
 #include "server/ua_server_internal.h"
@@ -13,81 +14,92 @@
 #define UA_DATETIMESTAMP_2000 125911584000000000
 
 UA_StatusCode
-UA_Server_addPubSubConnection(UA_Server *server, const UA_PubSubConnectionConfig *connectionConfig,
+UA_Server_addPubSubConnection(UA_Server *server,
+                              const UA_PubSubConnectionConfig *connectionConfig,
                               UA_NodeId *connectionIdentifier) {
-    //iterate over the available UA_PubSubTransportLayers
+    /* Find the matching UA_PubSubTransportLayers */
+    UA_PubSubTransportLayer *tl = NULL;
     for(size_t i = 0; i < server->config.pubsubTransportLayersSize; i++) {
-        if(connectionConfig && UA_String_equal(&server->config.pubsubTransportLayers[i].transportProfileUri,
-                                               &connectionConfig->transportProfileUri)){
-            //create new connection config
-            UA_PubSubConnectionConfig *tmpConnectionConfig = (UA_PubSubConnectionConfig *)
-                    UA_calloc(1, sizeof(UA_PubSubConnectionConfig));
-            if(!tmpConnectionConfig){
-                UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
-                             "PubSub Connection creation failed. Out of Memory.");
-                return UA_STATUSCODE_BADOUTOFMEMORY;
-            }
-            //deep copy the given connection config
-            if(UA_PubSubConnectionConfig_copy(connectionConfig, tmpConnectionConfig) != UA_STATUSCODE_GOOD){
-                UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
-                             "PubSub Connection creation failed. Config copy problem.");
-                return UA_STATUSCODE_BADOUTOFMEMORY;
-            }
-            //create new connection and add to UA_PubSubManager
-            UA_PubSubConnection *newConnectionsField = (UA_PubSubConnection *)
-                    UA_realloc(server->pubSubManager.connections,
-                               sizeof(UA_PubSubConnection) * (server->pubSubManager.connectionsSize + 1));
-            if(!newConnectionsField) {
-                UA_PubSubConnectionConfig_deleteMembers(tmpConnectionConfig);
-                UA_free(tmpConnectionConfig);
-                UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
-                             "PubSub Connection creation failed. Out of Memory.");
-                return UA_STATUSCODE_BADOUTOFMEMORY;
-            }
-            server->pubSubManager.connections = newConnectionsField;
-            UA_PubSubConnection *newConnection = &server->pubSubManager.connections[server->pubSubManager.connectionsSize];
-            memset(newConnection, 0, sizeof(UA_PubSubConnection));
-            LIST_INIT(&newConnection->writerGroups);
-            //workaround - fixing issue with queue.h and realloc.
-            for(size_t n = 0; n < server->pubSubManager.connectionsSize; n++){
-                if(server->pubSubManager.connections[n].writerGroups.lh_first){
-                    server->pubSubManager.connections[n].writerGroups.lh_first->listEntry.le_prev = &server->pubSubManager.connections[n].writerGroups.lh_first;
-                }
-            }
-            newConnection->config = tmpConnectionConfig;
-            newConnection->channel = server->config.pubsubTransportLayers[i].createPubSubChannel(newConnection->config);
-            if(!newConnection->channel){
-                UA_PubSubConnection_deleteMembers(server, newConnection);
-                if(server->pubSubManager.connectionsSize > 0){
-                    newConnectionsField = (UA_PubSubConnection *)
-                            UA_realloc(server->pubSubManager.connections,
-                                       sizeof(UA_PubSubConnection) * (server->pubSubManager.connectionsSize));
-                    if(!newConnectionsField) {
-                        return UA_STATUSCODE_BADINTERNALERROR;
-                    }
-                    server->pubSubManager.connections = newConnectionsField;
-                } else  {
-                    UA_free(newConnectionsField);
-                    server->pubSubManager.connections = NULL;
-                }
-                UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
-                             "PubSub Connection creation failed. Transport layer creation problem.");
-                return UA_STATUSCODE_BADINTERNALERROR;
-            }
-            UA_PubSubManager_generateUniqueNodeId(server, &newConnection->identifier);
-            if(connectionIdentifier != NULL){
-                UA_NodeId_copy(&newConnection->identifier, connectionIdentifier);
-            }
-            server->pubSubManager.connectionsSize++;
-#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
-        addPubSubConnectionRepresentation(server, newConnection);
-#endif
-            return UA_STATUSCODE_GOOD;
+        if(connectionConfig &&
+           UA_String_equal(&server->config.pubsubTransportLayers[i].transportProfileUri,
+                           &connectionConfig->transportProfileUri)) {
+            tl = &server->config.pubsubTransportLayers[i];
         }
     }
-    UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
-                 "PubSub Connection creation failed. Requested transport layer not found.");
-    return UA_STATUSCODE_BADNOTFOUND;
+    if(!tl) {
+        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
+                     "PubSub Connection creation failed. Requested transport layer not found.");
+        return UA_STATUSCODE_BADNOTFOUND;
+    }
+
+    /* Create a copy of the connection config */
+    UA_PubSubConnectionConfig *tmpConnectionConfig = (UA_PubSubConnectionConfig *)
+        UA_calloc(1, sizeof(UA_PubSubConnectionConfig));
+    if(!tmpConnectionConfig){
+        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
+                     "PubSub Connection creation failed. Out of Memory.");
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    }
+
+    UA_StatusCode retval = UA_PubSubConnectionConfig_copy(connectionConfig, tmpConnectionConfig);
+    if(retval != UA_STATUSCODE_GOOD){
+        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
+                     "PubSub Connection creation failed. Could not copy the config.");
+        return retval;
+    }
+
+    /* Create new connection and add to UA_PubSubManager */
+    UA_PubSubConnection *newConnectionsField = (UA_PubSubConnection *)
+        UA_realloc(server->pubSubManager.connections,
+                   sizeof(UA_PubSubConnection) * (server->pubSubManager.connectionsSize + 1));
+    if(!newConnectionsField) {
+        UA_PubSubConnectionConfig_deleteMembers(tmpConnectionConfig);
+        UA_free(tmpConnectionConfig);
+        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
+                     "PubSub Connection creation failed. Out of Memory.");
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    }
+    server->pubSubManager.connections = newConnectionsField;
+    server->pubSubManager.connectionsSize++;
+
+    UA_PubSubConnection *newConnection =
+        &server->pubSubManager.connections[server->pubSubManager.connectionsSize-1];
+
+    /* Initialize the new connection */
+    memset(newConnection, 0, sizeof(UA_PubSubConnection));
+    LIST_INIT(&newConnection->writerGroups);
+    //workaround - fixing issue with queue.h and realloc.
+    for(size_t n = 0; n < server->pubSubManager.connectionsSize; n++){
+        if(server->pubSubManager.connections[n].writerGroups.lh_first){
+            server->pubSubManager.connections[n].writerGroups.lh_first->listEntry.le_prev = &server->pubSubManager.connections[n].writerGroups.lh_first;
+        }
+    }
+    newConnection->config = tmpConnectionConfig;
+
+    /* Open the channel */
+    newConnection->channel = tl->createPubSubChannel(newConnection->config);
+    if(!newConnection->channel) {
+        UA_PubSubConnection_deleteMembers(server, newConnection);
+        server->pubSubManager.connectionsSize--;
+        /* Keep the realloced (longer) array if entries remain */
+        if(server->pubSubManager.connectionsSize == 0) {
+            UA_free(server->pubSubManager.connections);
+            server->pubSubManager.connections = NULL;
+        }
+        UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER,
+                     "PubSub Connection creation failed. Transport layer creation problem.");
+        return UA_STATUSCODE_BADINTERNALERROR;
+    }
+
+    UA_PubSubManager_generateUniqueNodeId(server, &newConnection->identifier);
+
+    if(connectionIdentifier)
+        UA_NodeId_copy(&newConnection->identifier, connectionIdentifier);
+
+#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
+    addPubSubConnectionRepresentation(server, newConnection);
+#endif
+    return UA_STATUSCODE_GOOD;
 }
 
 UA_StatusCode