Browse Source

added "UA_Server_addMethodNodeEx" to public API:
- allows direct specification of requested node IDs for method nodes so that there is no requirement of public "UA_Server_addMethodNode_finish" any more
- old API and kept untouched (backward compatability)
- redirected "UA_Server_addMethodNode(_finish)" to use new "UA_Server_addMethodNodeEx(_finish)" (with UA_NODEID_NULL as requested node IDs which keeps old behaviour)

Thomas Bender 7 years ago
parent
commit
5268f1b134
2 changed files with 97 additions and 39 deletions
  1. 17 0
      include/ua_server.h
  2. 80 39
      src/server/ua_services_nodemanagement.c

+ 17 - 0
include/ua_server.h

@@ -958,6 +958,23 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                         void *nodeContext, UA_NodeId *outNewNodeId);
 
 
+UA_StatusCode UA_EXPORT
+UA_Server_addMethodNodeEx(UA_Server *server, const UA_NodeId requestedNewNodeId,
+                          const UA_NodeId parentNodeId,
+                          const UA_NodeId referenceTypeId,
+                          const UA_QualifiedName browseName,
+                          const UA_MethodAttributes attr, UA_MethodCallback method,
+                          size_t inputArgumentsSize,
+                          const UA_Argument *inputArguments,
+                          const UA_NodeId inputArgumentsRequestedNewNodeId,
+                          UA_NodeId *inputArgumentsOutNewNodeId,
+                          size_t outputArgumentsSize,
+                          const UA_Argument *outputArguments,
+                          const UA_NodeId outputArgumentsRequestedNewNodeId,
+                          UA_NodeId *outputArgumentsOutNewNodeId,
+                          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

+ 80 - 39
src/server/ua_services_nodemanagement.c

@@ -1479,12 +1479,16 @@ UA_Server_setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId,
 static const UA_NodeId hasproperty = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASPROPERTY}};
 static const UA_NodeId propertytype = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_PROPERTYTYPE}};
 
-UA_StatusCode
-UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
-                               const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                               UA_MethodCallback method,
-                               size_t inputArgumentsSize, const UA_Argument* inputArguments,
-                               size_t outputArgumentsSize, const UA_Argument* outputArguments) {
+static UA_StatusCode
+UA_Server_addMethodNodeEx_finish(UA_Server *server, const UA_NodeId nodeId,
+                                 const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                                 UA_MethodCallback method,
+                                 const size_t inputArgumentsSize, const UA_Argument *inputArguments,
+                                 const UA_NodeId inputArgumentsRequestedNewNodeId,
+                                 UA_NodeId *inputArgumentsOutNewNodeId,
+                                 const size_t outputArgumentsSize, const UA_Argument *outputArguments,
+                                 const UA_NodeId outputArgumentsRequestedNewNodeId,
+                                 UA_NodeId *outputArgumentsOutNewNodeId) {
     /* Browse to see which argument nodes exist */
     UA_BrowseDescription bd;
     UA_BrowseDescription_init(&bd);
@@ -1510,7 +1514,6 @@ UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
     /* Filter out the argument nodes */
     UA_NodeId inputArgsId = UA_NODEID_NULL;
     UA_NodeId outputArgsId = UA_NODEID_NULL;
-    const UA_NodeId newArgsId = UA_NODEID_NUMERIC(nodeId.namespaceIndex, 0);
     const UA_QualifiedName inputArgsName = UA_QUALIFIEDNAME(0, "InputArguments");
     const UA_QualifiedName outputArgsName = UA_QUALIFIEDNAME(0, "OutputArguments");
     for(size_t i = 0; i < br.referencesSize; i++) {
@@ -1525,34 +1528,30 @@ UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
 
     /* Add the Input Arguments VariableNode */
     if(inputArgumentsSize > 0 && UA_NodeId_isNull(&inputArgsId)) {
-        UA_VariableAttributes inputargs = UA_VariableAttributes_default;
-        inputargs.displayName = UA_LOCALIZEDTEXT("", "InputArguments");
-        /* UAExpert creates a monitoreditem on inputarguments ... */
-        inputargs.minimumSamplingInterval = 100000.0f;
-        inputargs.valueRank = 1;
-        inputargs.dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
-        /* dirty-cast, but is treated as const ... */
-        UA_Variant_setArray(&inputargs.value, (void*)(uintptr_t)inputArguments,
+        UA_VariableAttributes attr = UA_VariableAttributes_default;
+        char *name = "InputArguments";
+        attr.displayName = UA_LOCALIZEDTEXT("", name);
+        attr.dataType = UA_TYPES[UA_TYPES_ARGUMENT].typeId;
+        attr.valueRank = 1;
+        UA_Variant_setArray(&attr.value, (void*)(uintptr_t) inputArguments,
                             inputArgumentsSize, &UA_TYPES[UA_TYPES_ARGUMENT]);
-        retval = UA_Server_addVariableNode(server, newArgsId, nodeId, hasproperty,
-                                           inputArgsName, propertytype, inputargs,
-                                           NULL, &inputArgsId);
+        retval |= UA_Server_addVariableNode(server, inputArgumentsRequestedNewNodeId, nodeId,
+                                            hasproperty, UA_QUALIFIEDNAME(0, name),
+                                            propertytype, attr, NULL, &inputArgsId);
     }
 
     /* Add the Output Arguments VariableNode */
     if(outputArgumentsSize > 0 && UA_NodeId_isNull(&outputArgsId)) {
-        UA_VariableAttributes outputargs = UA_VariableAttributes_default;
-        outputargs.displayName = UA_LOCALIZEDTEXT("", "OutputArguments");
-        /* UAExpert creates a monitoreditem on outputarguments ... */
-        outputargs.minimumSamplingInterval = 100000.0f;
-        outputargs.valueRank = 1;
-        outputargs.dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
-        /* dirty-cast, but is treated as const ... */
-        UA_Variant_setArray(&outputargs.value, (void*)(uintptr_t)outputArguments,
+        UA_VariableAttributes attr = UA_VariableAttributes_default;
+        char *name = "OutputArguments";
+        attr.displayName = UA_LOCALIZEDTEXT("", name);
+        attr.dataType = UA_TYPES[UA_TYPES_ARGUMENT].typeId;
+        attr.valueRank = 1;
+        UA_Variant_setArray(&attr.value, (void*)(uintptr_t) outputArguments,
                             outputArgumentsSize, &UA_TYPES[UA_TYPES_ARGUMENT]);
-        retval |= UA_Server_addVariableNode(server, newArgsId, nodeId, hasproperty,
-                                            outputArgsName, propertytype, outputargs,
-                                            NULL, &outputArgsId);
+        retval |= UA_Server_addVariableNode(server, outputArgumentsRequestedNewNodeId, nodeId,
+                                            hasproperty, UA_QUALIFIEDNAME(0, name),
+                                            propertytype, attr, NULL, &outputArgsId);
     }
 
     retval |= UA_Server_setMethodNode_callback(server, nodeId, method);
@@ -1565,18 +1564,41 @@ UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
         UA_Server_deleteNode(server, nodeId, true);
         UA_Server_deleteNode(server, inputArgsId, true);
         UA_Server_deleteNode(server, outputArgsId, true);
+    } else {
+        if(inputArgumentsOutNewNodeId != NULL) {
+            UA_NodeId_copy(&inputArgsId, inputArgumentsOutNewNodeId);
+    }
+        if(outputArgumentsOutNewNodeId != NULL) {
+            UA_NodeId_copy(&outputArgsId, outputArgumentsOutNewNodeId);
+        }
     }
     UA_BrowseResult_deleteMembers(&br);
     return retval;
 }
 
 UA_StatusCode
-UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
-                        const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                        const UA_QualifiedName browseName, const UA_MethodAttributes attr,
-                        UA_MethodCallback method,
-                        size_t inputArgumentsSize, const UA_Argument* inputArguments,
-                        size_t outputArgumentsSize, const UA_Argument* outputArguments,
+UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
+                               const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                               UA_MethodCallback method,
+                               size_t inputArgumentsSize, const UA_Argument* inputArguments,
+                               size_t outputArgumentsSize, const UA_Argument* outputArguments) {
+    return UA_Server_addMethodNodeEx_finish(server, nodeId, parentNodeId,
+                                            referenceTypeId, method,
+                                            inputArgumentsSize, inputArguments, UA_NODEID_NULL, NULL,
+                                            outputArgumentsSize, outputArguments, UA_NODEID_NULL, NULL);
+}
+
+UA_StatusCode
+UA_Server_addMethodNodeEx(UA_Server *server, const UA_NodeId requestedNewNodeId,
+                          const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                          const UA_QualifiedName browseName, const UA_MethodAttributes attr,
+                          UA_MethodCallback method,
+                          const size_t inputArgumentsSize, const UA_Argument *inputArguments,
+                          const UA_NodeId inputArgumentsRequestedNewNodeId,
+                          UA_NodeId *inputArgumentsOutNewNodeId,
+                          const size_t outputArgumentsSize, const UA_Argument *outputArguments,
+                          const UA_NodeId outputArgumentsRequestedNewNodeId,
+                          UA_NodeId *outputArgumentsOutNewNodeId,
                         void *nodeContext, UA_NodeId *outNewNodeId) {
     UA_AddNodesItem item;
     UA_AddNodesItem_init(&item);
@@ -1598,16 +1620,35 @@ UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
 
-    retval = UA_Server_addMethodNode_finish(server, *outNewNodeId,
-                                            parentNodeId, referenceTypeId, method,
-                                            inputArgumentsSize, inputArguments,
-                                            outputArgumentsSize, outputArguments);
+    retval = UA_Server_addMethodNodeEx_finish(server, *outNewNodeId,
+                                              parentNodeId, referenceTypeId, method,
+                                              inputArgumentsSize, inputArguments,
+                                              inputArgumentsRequestedNewNodeId,
+                                              inputArgumentsOutNewNodeId,
+                                              outputArgumentsSize, outputArguments,
+                                              outputArgumentsRequestedNewNodeId,
+                                              outputArgumentsOutNewNodeId);
 
     if(outNewNodeId == &newId)
         UA_NodeId_deleteMembers(&newId);
     return retval;
 }
 
+UA_StatusCode
+UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
+                        const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                        const UA_QualifiedName browseName, const UA_MethodAttributes attr,
+                        UA_MethodCallback method,
+                        const size_t inputArgumentsSize, const UA_Argument *inputArguments,
+                        const size_t outputArgumentsSize, const UA_Argument *outputArguments,
+                        void *nodeContext, UA_NodeId *outNewNodeId) {
+    return UA_Server_addMethodNodeEx(server, requestedNewNodeId,  parentNodeId,
+                                     referenceTypeId, browseName, attr, method,
+                                     inputArgumentsSize, inputArguments, UA_NODEID_NULL, NULL,
+                                     outputArgumentsSize, outputArguments, UA_NODEID_NULL, NULL,
+                                     nodeContext, outNewNodeId);
+}
+
 static UA_StatusCode
 editMethodCallback(UA_Server *server, UA_Session* session,
                    UA_Node* node, void* handle) {