Pārlūkot izejas kodu

make addnodes_begin and _finish part of the public API

Julius Pfrommer 7 gadi atpakaļ
vecāks
revīzija
bacb53b1d1

+ 35 - 0
include/ua_server.h

@@ -935,6 +935,41 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                         size_t outputArgumentsSize, const UA_Argument* outputArguments,
                         void *nodeContext, UA_NodeId *outNewNodeId);
 
+
+/**
+ * The method pair UA_Server_addNode_begin and _finish splits the AddNodes
+ * service in two parts. This is useful if the node shall be modified before
+ * finish the instantiation. For example to add children with specific NodeIds.
+ * Otherwise, mandatory children (e.g. of an ObjectType) are added with
+ * pseudo-random unique NodeIds. Existing children are detected during the
+ * _finish part via their matching BrowseName.
+ *
+ * The _begin method prepares the node and adds it to the nodestore. It may copy
+ * some unassigned attributes from the TypeDefinition node internally. The
+ * _finish method adds the references to the parent (and the TypeDefinition if
+ * applicable), copies mandatory children, performs type-checking of variables
+ * and calls the node constructor(s) at the end. The _finish method may remove
+ * the node if it encounters an error. */
+
+/* The ``attr`` argument must have a type according to the NodeClass.
+ * ``VariableAttributes`` for variables, ``ObjectAttributes`` for objects, and
+ * so on. Missing attributes are taken from the TypeDefinition node if
+ * applicable. */
+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_NodeId typeDefinition,
+                        const void *attr, const UA_DataType *attributeType,
+                        void *nodeContext, UA_NodeId *outNewNodeId);
+
+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 typeDefinitionId);
+
+/* Deletes a node and optionally all references leading to the node. */
 UA_StatusCode UA_EXPORT
 UA_Server_deleteNode(UA_Server *server, const UA_NodeId nodeId,
                      UA_Boolean deleteReferences);

+ 0 - 10
src/server/ua_server_internal.h

@@ -337,16 +337,6 @@ Operation_addNode_finish(UA_Server *server, UA_Session *session,
                          const UA_NodeId *referenceTypeId, const UA_NodeId *typeDefinitionId,
                          UA_Boolean overrideChecks);
 
-/* UA_StatusCode */
-/* UA_Server_addNode_begin(UA_Server *server, const UA_AddNodesItem *item, */
-/*                         void *nodeContext, UA_NodeId *outnewNodeId); */
-
-/* UA_StatusCode */
-/* UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId, */
-/*                          const UA_NodeId parentNodeId, */
-/*                          const UA_NodeId referenceTypeId, */
-/*                          const UA_NodeId typeDefinitionId); */
-
 UA_StatusCode
 UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
                                const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,

+ 32 - 2
src/server/ua_services_nodemanagement.c

@@ -608,6 +608,7 @@ removeDeconstructedNode(UA_Server *server, UA_Session *session,
 
 static const UA_NodeId hasSubtype = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}};
 
+/* Children, references, type-checking, constructors. */
 UA_StatusCode
 Operation_addNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
                          const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
@@ -810,14 +811,14 @@ __UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass,
     /* Create the AddNodesItem */
     UA_AddNodesItem item;
     UA_AddNodesItem_init(&item);
+    item.nodeClass = nodeClass;
     item.requestedNewNodeId.nodeId = *requestedNewNodeId;
     item.browseName = browseName;
-    item.nodeClass = nodeClass;
     item.parentNodeId.nodeId = *parentNodeId;
     item.referenceTypeId = *referenceTypeId;
     item.typeDefinition.nodeId = *typeDefinition;
     item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
-    item.nodeAttributes.content.decoded.type =attributeType;
+    item.nodeAttributes.content.decoded.type = attributeType;
     item.nodeAttributes.content.decoded.data = (void*)(uintptr_t)attr;
 
     /* Call the normal addnodes service */
@@ -831,6 +832,35 @@ __UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass,
     return result.statusCode;
 }
 
+UA_StatusCode
+UA_Server_addNode_begin(UA_Server *server, const UA_NodeClass nodeClass,
+                        const UA_NodeId requestedNewNodeId,
+                        const UA_QualifiedName browseName,
+                        const UA_NodeId typeDefinition,
+                        const void *attr, const UA_DataType *attributeType,
+                        void *nodeContext, UA_NodeId *outNewNodeId) {
+    UA_AddNodesItem item;
+    UA_AddNodesItem_init(&item);
+    item.nodeClass = nodeClass;
+    item.requestedNewNodeId.nodeId = requestedNewNodeId;
+    item.browseName = browseName;
+    item.typeDefinition.nodeId = typeDefinition;
+    item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
+    item.nodeAttributes.content.decoded.type = attributeType;
+    item.nodeAttributes.content.decoded.data = (void*)(uintptr_t)attr;
+    return Operation_addNode_begin(server, &adminSession, &item,
+                                   nodeContext, outNewNodeId, false);
+}
+
+UA_StatusCode
+UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId,
+                         const UA_NodeId parentNodeId,
+                         const UA_NodeId referenceTypeId,
+                         const UA_NodeId typeDefinitionId) {
+    return Operation_addNode_finish(server, &adminSession, &nodeId, &parentNodeId,
+                                    &referenceTypeId, &typeDefinitionId, false);
+}
+
 /****************/
 /* Delete Nodes */
 /****************/