Prechádzať zdrojové kódy

refactor nodemenagement services; preparation for addnodes_begin and addnodes_finish

Julius Pfrommer 8 rokov pred
rodič
commit
49f763441c

+ 23 - 23
include/ua_server.h

@@ -886,11 +886,11 @@ typedef struct {
 /* Don't use this function. There are typed versions as inline functions. */
 UA_StatusCode UA_EXPORT
 __UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass,
-                    const UA_NodeId requestedNewNodeId,
-                    const UA_NodeId parentNodeId,
-                    const UA_NodeId referenceTypeId,
+                    const UA_NodeId *requestedNewNodeId,
+                    const UA_NodeId *parentNodeId,
+                    const UA_NodeId *referenceTypeId,
                     const UA_QualifiedName browseName,
-                    const UA_NodeId typeDefinition,
+                    const UA_NodeId *typeDefinition,
                     const UA_NodeAttributes *attr,
                     const UA_DataType *attributeType,
                     UA_InstantiationCallback *instantiationCallback,
@@ -905,9 +905,9 @@ UA_Server_addVariableNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                           const UA_VariableAttributes attr,
                           UA_InstantiationCallback *instantiationCallback,
                           UA_NodeId *outNewNodeId) {
-    return __UA_Server_addNode(server, UA_NODECLASS_VARIABLE, requestedNewNodeId,
-                               parentNodeId, referenceTypeId, browseName,
-                               typeDefinition, (const UA_NodeAttributes*)&attr,
+    return __UA_Server_addNode(server, UA_NODECLASS_VARIABLE, &requestedNewNodeId,
+                               &parentNodeId, &referenceTypeId, browseName,
+                               &typeDefinition, (const UA_NodeAttributes*)&attr,
                                &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
                                instantiationCallback, outNewNodeId);
 }
@@ -923,8 +923,8 @@ UA_Server_addVariableTypeNode(UA_Server *server,
                               UA_InstantiationCallback *instantiationCallback,
                               UA_NodeId *outNewNodeId) {
     return __UA_Server_addNode(server, UA_NODECLASS_VARIABLETYPE,
-                               requestedNewNodeId, parentNodeId, referenceTypeId,
-                               browseName, typeDefinition,
+                               &requestedNewNodeId, &parentNodeId, &referenceTypeId,
+                               browseName, &typeDefinition,
                                (const UA_NodeAttributes*)&attr,
                                &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],
                                instantiationCallback, outNewNodeId);
@@ -939,9 +939,9 @@ UA_Server_addObjectNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                         const UA_ObjectAttributes attr,
                         UA_InstantiationCallback *instantiationCallback,
                         UA_NodeId *outNewNodeId) {
-    return __UA_Server_addNode(server, UA_NODECLASS_OBJECT, requestedNewNodeId,
-                               parentNodeId, referenceTypeId, browseName,
-                               typeDefinition, (const UA_NodeAttributes*)&attr,
+    return __UA_Server_addNode(server, UA_NODECLASS_OBJECT, &requestedNewNodeId,
+                               &parentNodeId, &referenceTypeId, browseName,
+                               &typeDefinition, (const UA_NodeAttributes*)&attr,
                                &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
                                instantiationCallback, outNewNodeId);
 }
@@ -954,9 +954,9 @@ UA_Server_addObjectTypeNode(UA_Server *server, const UA_NodeId requestedNewNodeI
                             const UA_ObjectTypeAttributes attr,
                             UA_InstantiationCallback *instantiationCallback,
                             UA_NodeId *outNewNodeId) {
-    return __UA_Server_addNode(server, UA_NODECLASS_OBJECTTYPE, requestedNewNodeId,
-                               parentNodeId, referenceTypeId, browseName,
-                               UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
+    return __UA_Server_addNode(server, UA_NODECLASS_OBJECTTYPE, &requestedNewNodeId,
+                               &parentNodeId, &referenceTypeId, browseName,
+                               &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
                                &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],
                                instantiationCallback, outNewNodeId);
 }
@@ -969,9 +969,9 @@ UA_Server_addViewNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                       const UA_ViewAttributes attr,
                       UA_InstantiationCallback *instantiationCallback,
                       UA_NodeId *outNewNodeId) {
-    return __UA_Server_addNode(server, UA_NODECLASS_VIEW, requestedNewNodeId,
-                               parentNodeId, referenceTypeId, browseName,
-                               UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
+    return __UA_Server_addNode(server, UA_NODECLASS_VIEW, &requestedNewNodeId,
+                               &parentNodeId, &referenceTypeId, browseName,
+                               &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
                                &UA_TYPES[UA_TYPES_VIEWATTRIBUTES],
                                instantiationCallback, outNewNodeId);
 }
@@ -986,8 +986,8 @@ UA_Server_addReferenceTypeNode(UA_Server *server,
                                UA_InstantiationCallback *instantiationCallback,
                                UA_NodeId *outNewNodeId) {
     return __UA_Server_addNode(server, UA_NODECLASS_REFERENCETYPE,
-                               requestedNewNodeId, parentNodeId, referenceTypeId,
-                               browseName, UA_NODEID_NULL,
+                               &requestedNewNodeId, &parentNodeId, &referenceTypeId,
+                               browseName, &UA_NODEID_NULL,
                                (const UA_NodeAttributes*)&attr,
                                &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],
                                instantiationCallback, outNewNodeId);
@@ -1002,9 +1002,9 @@ UA_Server_addDataTypeNode(UA_Server *server,
                           const UA_DataTypeAttributes attr,
                           UA_InstantiationCallback *instantiationCallback,
                           UA_NodeId *outNewNodeId) {
-    return __UA_Server_addNode(server, UA_NODECLASS_DATATYPE, requestedNewNodeId,
-                               parentNodeId, referenceTypeId, browseName,
-                               UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
+    return __UA_Server_addNode(server, UA_NODECLASS_DATATYPE, &requestedNewNodeId,
+                               &parentNodeId, &referenceTypeId, browseName,
+                               &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
                                &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],
                                instantiationCallback, outNewNodeId);
 }

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 503 - 813
src/server/ua_server.c


+ 128 - 23
src/server/ua_server_internal.h

@@ -218,17 +218,6 @@ void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection
 UA_StatusCode UA_Server_delayedCallback(UA_Server *server, UA_ServerCallback callback, void *data);
 UA_StatusCode UA_Server_delayedFree(UA_Server *server, void *data);
 
-/* Add an existing node. The node is assumed to be "finished", i.e. no
- * instantiation from inheritance is necessary. Instantiationcallback and
- * addedNodeId may be NULL. */
-UA_StatusCode
-Service_AddNodes_existing(UA_Server *server, UA_Session *session, UA_Node *node,
-                          const UA_NodeId *parentNodeId,
-                          const UA_NodeId *referenceTypeId,
-                          const UA_NodeId *typeDefinition,
-                          UA_InstantiationCallback *instantiationCallback,
-                          UA_NodeId *addedNodeId);
-
 /*********************/
 /* Utility Functions */
 /*********************/
@@ -261,8 +250,10 @@ isNodeInTree(UA_NodeStore *ns, const UA_NodeId *leafNode,
              const UA_NodeId *nodeToFind, const UA_NodeId *referenceTypeIds,
              size_t referenceTypeIdsSize);
 
-const UA_Node *
-getNodeType(UA_Server *server, const UA_Node *node);
+
+/* Returns the nodeid of the node type, if none defined for the node or the node
+ * class, typeId is set to UA_NODEID_NULL. */
+void getNodeType(UA_Server *server, const UA_Node *node, UA_NodeId *typeId);
 
 /***************************************/
 /* Check Information Model Consistency */
@@ -277,10 +268,6 @@ typeCheckValue(UA_Server *server, const UA_NodeId *targetDataTypeId,
                const UA_UInt32 *targetArrayDimensions, const UA_Variant *value,
                const UA_NumericRange *range, UA_Variant *editableValue);
 
-UA_StatusCode
-writeDataTypeAttribute(UA_Server *server, UA_VariableNode *node,
-                       const UA_NodeId *dataType, const UA_NodeId *constraintDataType);
-
 UA_StatusCode
 compatibleArrayDimensions(size_t constraintArrayDimensionsSize,
                           const UA_UInt32 *constraintArrayDimensions,
@@ -293,13 +280,19 @@ compatibleDataType(UA_Server *server, const UA_NodeId *dataType,
 UA_StatusCode
 compatibleValueRankArrayDimensions(UA_Int32 valueRank, size_t arrayDimensionsSize);
 
+UA_Boolean
+compatibleDataType(UA_Server *server, const UA_NodeId *dataType,
+                   const UA_NodeId *constraintDataType);
+
 UA_StatusCode
-writeValueRankAttribute(UA_Server *server, UA_VariableNode *node, UA_Int32 valueRank,
-                        UA_Int32 constraintValueRank);
+compatibleValueRankArrayDimensions(UA_Int32 valueRank, size_t arrayDimensionsSize);
 
 UA_StatusCode
-writeValueAttribute(UA_Server *server, UA_VariableNode *node,
-                    const UA_DataValue *value, const UA_String *indexRange);
+writeValueRankAttribute(UA_Server *server, UA_VariableNode *node,
+                        UA_Int32 valueRank, UA_Int32 constraintValueRank);
+
+UA_StatusCode
+compatibleValueRanks(UA_Int32 valueRank, UA_Int32 constraintValueRank);
 
 UA_StatusCode
 compatibleValueRanks(UA_Int32 valueRank, UA_Int32 constraintValueRank);
@@ -309,7 +302,7 @@ compatibleValueRanks(UA_Int32 valueRank, UA_Int32 constraintValueRank);
 /*******************/
 
 /* Some services take an array of "independent" requests. The single-services
-   are stored here to keep ua_services.h clean for documentation purposes. */
+ * are stored here to keep ua_services.h clean for documentation purposes. */
 
 UA_StatusCode
 Service_AddReferences_single(UA_Server *server, UA_Session *session,
@@ -371,9 +364,121 @@ UA_StatusCode UA_Discovery_multicastListenStart(UA_Server* server);
 UA_StatusCode UA_Discovery_multicastListenStop(UA_Server* server);
 #  endif
 UA_StatusCode UA_Discovery_multicastIterate(UA_Server* server, UA_DateTime *nextRepeat, UA_Boolean processIn);
-
 # endif
 
+/*****************************/
+/* AddNodes Begin and Finish */
+/*****************************/
+
+/* Don't use this function. There are typed versions as inline functions. */
+UA_StatusCode UA_EXPORT
+__UA_Server_addNode_begin(UA_Server *server, const UA_NodeClass nodeClass,
+                          const UA_NodeId *requestedNewNodeId,
+                          const UA_QualifiedName *browseName,
+                          const UA_NodeAttributes *attr,
+                          const UA_DataType *attributeType,
+                          UA_NodeId *outNewNodeId);
+
+/* The inline function UA_Server_addNode_finish might be more convenient to
+ * pass NodeIds in-situ (e.g. UA_NODEID_NUMERIC(0, 5)) */
+UA_StatusCode UA_EXPORT
+UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId,
+                         const UA_NodeId parentNodeId,
+                         const UA_NodeId referenceTypeId,
+                         const UA_NodeId typeDefinition,
+                         UA_InstantiationCallback *instantiationCallback);
+
+static UA_INLINE UA_StatusCode
+UA_Server_addReferenceTypeNode_begin(UA_Server *server, const UA_NodeId requestedNewNodeId,
+                                     const UA_QualifiedName browseName,
+                                     const UA_ReferenceTypeAttributes attr,
+                                     UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE,
+                                     &requestedNewNodeId,
+                                     &browseName, (const UA_NodeAttributes*)&attr,
+                                     &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],
+                                     outNewNodeId);
+}
+
+static UA_INLINE UA_StatusCode
+UA_Server_addDataTypeNode_begin(UA_Server *server,
+                                const UA_NodeId requestedNewNodeId,
+                                const UA_QualifiedName browseName,
+                                const UA_DataTypeAttributes attr,
+                                UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE,
+                                     &requestedNewNodeId,
+                                     &browseName, (const UA_NodeAttributes*)&attr,
+                                     &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],
+                                     outNewNodeId);
+}
+
+static UA_INLINE UA_StatusCode
+UA_Server_addVariableNode_begin(UA_Server *server, const UA_NodeId requestedNewNodeId,
+                                const UA_QualifiedName browseName,
+                                const UA_VariableAttributes attr,
+                                UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE,
+                                     &requestedNewNodeId, &browseName,
+                                     (const UA_NodeAttributes*)&attr,
+                                     &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
+                                     outNewNodeId);
+}
+
+static UA_INLINE UA_StatusCode
+UA_Server_addVariableTypeNode_begin(UA_Server *server, const UA_NodeId requestedNewNodeId,
+                                    const UA_QualifiedName browseName,
+                                    const UA_VariableTypeAttributes attr,
+                                    UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE,
+                                     &requestedNewNodeId, &browseName,
+                                     (const UA_NodeAttributes*)&attr,
+                                     &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],
+                                     outNewNodeId);
+}
+
+static UA_INLINE UA_StatusCode
+UA_Server_addObjectNode_begin(UA_Server *server, const UA_NodeId requestedNewNodeId,
+                              const UA_QualifiedName browseName,
+                              const UA_ObjectAttributes attr,
+                              UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT,
+                                     &requestedNewNodeId,
+                                     &browseName, (const UA_NodeAttributes*)&attr,
+                                     &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
+                                     outNewNodeId);
+}
+
+static UA_INLINE UA_StatusCode
+UA_Server_addObjectTypeNode_begin(UA_Server *server,
+                                  const UA_NodeId requestedNewNodeId,
+                                  const UA_QualifiedName browseName,
+                                  const UA_ObjectTypeAttributes attr,
+                                  UA_NodeId *outNewNodeId) {
+    return __UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE,
+                                     &requestedNewNodeId,
+                                     &browseName, (const UA_NodeAttributes*)&attr,
+                                     &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],
+                                     outNewNodeId);
+}
+
+#ifdef UA_ENABLE_METHODCALLS
+UA_StatusCode
+UA_Server_addMethodNode_begin(UA_Server *server, const UA_NodeId requestedNewNodeId,
+                              const UA_QualifiedName browseName,
+                              const UA_MethodAttributes attr, UA_MethodCallback method,
+                              void *handle, UA_NodeId *outNewNodeId);
+
+UA_StatusCode
+UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
+                               const UA_NodeId parentNodeId,
+                               const UA_NodeId referenceTypeId,
+                               size_t inputArgumentsSize,
+                               const UA_Argument* inputArguments,
+                               size_t outputArgumentsSize,
+                               const UA_Argument* outputArguments);
+#endif
+
 #ifdef __cplusplus
 } // extern "C"
 #endif

+ 36 - 29
src/server/ua_server_utils.c

@@ -185,54 +185,62 @@ isNodeInTree(UA_NodeStore *ns, const UA_NodeId *leafNode, const UA_NodeId *nodeT
     return false;
 }
 
-const UA_Node *
-getNodeType(UA_Server *server, const UA_Node *node) {
-    /* The reference to the parent is different for variable and variabletype */ 
+void getNodeType(UA_Server *server, const UA_Node *node, UA_NodeId *typeId) {
+    UA_NodeId_init(typeId);
     UA_NodeId parentRef;
     UA_Boolean inverse;
+
+    /* The reference to the parent is different for variable and variabletype */
     if(node->nodeClass == UA_NODECLASS_VARIABLE ||
        node->nodeClass == UA_NODECLASS_OBJECT) {
         parentRef = UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION);
         inverse = false;
     } else if(node->nodeClass == UA_NODECLASS_VARIABLETYPE ||
-              /* node->nodeClass == UA_NODECLASS_OBJECTTYPE || // objecttype may have multiple parents */
+              node->nodeClass == UA_NODECLASS_OBJECTTYPE ||
               node->nodeClass == UA_NODECLASS_REFERENCETYPE ||
               node->nodeClass == UA_NODECLASS_DATATYPE) {
         parentRef = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
         inverse = true;
     } else {
-        return NULL;
+        return;
     }
 
-    /* stop at the first matching candidate */
-    UA_NodeId *parentId = NULL;
+    /* Stop at the first matching candidate */
     for(size_t i = 0; i < node->referencesSize; ++i) {
         if(node->references[i].isInverse == inverse &&
            UA_NodeId_equal(&node->references[i].referenceTypeId, &parentRef)) {
-            parentId = &node->references[i].targetId.nodeId;
+            UA_NodeId_copy(&node->references[i].targetId.nodeId, typeId);
             break;
         }
     }
-
-    if(!parentId)
-        return NULL;
-    return UA_NodeStore_get(server->nodestore, parentId);
 }
 
 const UA_VariableTypeNode *
 getVariableNodeType(UA_Server *server, const UA_VariableNode *node) {
-    const UA_Node *type = getNodeType(server, (const UA_Node*)node);
-    if(!type || type->nodeClass != UA_NODECLASS_VARIABLETYPE)
-        return NULL;
-    return (const UA_VariableTypeNode*)type;
+    UA_NodeId vtId;
+    getNodeType(server, (const UA_Node*)node, &vtId);
+
+    const UA_Node *vt = UA_NodeStore_get(server->nodestore, &vtId);
+    if(!vt || vt->nodeClass != UA_NODECLASS_VARIABLETYPE) {
+        vt = NULL;
+        UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER,
+                     "No VariableType for the node found");
+    }
+    return (const UA_VariableTypeNode*)vt;
 }
 
 const UA_ObjectTypeNode *
 getObjectNodeType(UA_Server *server, const UA_ObjectNode *node) {
-    const UA_Node *type = getNodeType(server, (const UA_Node*)node);
-    if(type->nodeClass != UA_NODECLASS_OBJECTTYPE)
-        return NULL;
-    return (const UA_ObjectTypeNode*)type;
+    UA_NodeId otId;
+    getNodeType(server, (const UA_Node*)node, &otId);
+
+    const UA_Node *ot = UA_NodeStore_get(server->nodestore, &otId);
+    if(!ot || ot->nodeClass != UA_NODECLASS_OBJECTTYPE) {
+        ot = NULL;
+        UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER,
+                     "No ObjectType for the node found");
+    }
+    return (const UA_ObjectTypeNode*)ot;
 }
 
 UA_Boolean
@@ -256,16 +264,15 @@ UA_StatusCode
 UA_Server_editNode(UA_Server *server, UA_Session *session,
                    const UA_NodeId *nodeId, UA_EditNodeCallback callback,
                    const void *data) {
-    UA_StatusCode retval;
-    do {
 #ifndef UA_ENABLE_MULTITHREADING
-        const UA_Node *node = UA_NodeStore_get(server->nodestore, nodeId);
-        if(!node)
-            return UA_STATUSCODE_BADNODEIDUNKNOWN;
-        UA_Node *editNode = (UA_Node*)(uintptr_t)node; // dirty cast
-        retval = callback(server, session, editNode, data);
-        return retval;
+    const UA_Node *node = UA_NodeStore_get(server->nodestore, nodeId);
+    if(!node)
+        return UA_STATUSCODE_BADNODEIDUNKNOWN;
+    UA_Node *editNode = (UA_Node*)(uintptr_t)node; // dirty cast
+    return callback(server, session, editNode, data);
 #else
+    UA_StatusCode retval;
+    do {
         UA_Node *copy = UA_NodeStore_getCopy(server->nodestore, nodeId);
         if(!copy)
             return UA_STATUSCODE_BADOUTOFMEMORY;
@@ -275,7 +282,7 @@ UA_Server_editNode(UA_Server *server, UA_Session *session,
             return retval;
         }
         retval = UA_NodeStore_replace(server->nodestore, copy);
-#endif
     } while(retval != UA_STATUSCODE_GOOD);
     return UA_STATUSCODE_GOOD;
+#endif
 }

+ 2 - 2
src/server/ua_services_attribute.c

@@ -403,7 +403,7 @@ writeValueRankAttribute(UA_Server *server, UA_VariableNode *node, UA_Int32 value
 /* DataType Attribute */
 /**********************/
 
-UA_StatusCode
+static UA_StatusCode
 writeDataTypeAttribute(UA_Server *server, UA_VariableNode *node,
                        const UA_NodeId *dataType, const UA_NodeId *constraintDataType) {
     /* If this is a variabletype, there must be no instances or subtypes of it
@@ -570,7 +570,7 @@ writeValueAttributeWithRange(UA_VariableNode *node, const UA_DataValue *value,
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode
+static UA_StatusCode
 writeValueAttribute(UA_Server *server, UA_VariableNode *node,
                     const UA_DataValue *value, const UA_String *indexRange) {
     /* Parse the range */

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 679 - 606
src/server/ua_services_nodemanagement.c