Przeglądaj źródła

UA_Server_add<Type>Node now takes an additional argument to return the nodeId of the actually created node, allowing userspace functions to create hierarchic instances of objects. Fixed an error in addMethodNode that prevented dynamic methods having arguments when using NODEID_NUMERIC(x,0).

ichrispa 9 lat temu
rodzic
commit
0fb4fd0f12
4 zmienionych plików z 46 dodań i 29 usunięć
  1. 0 4
      CMakeLists.txt
  2. 13 12
      examples/server.c
  3. 9 4
      include/ua_server.h
  4. 24 9
      src/server/ua_server_addressspace.c

+ 0 - 4
CMakeLists.txt

@@ -5,10 +5,6 @@ project(open62541 C)
 
 FIND_PACKAGE(PythonInterp REQUIRED)
 
-set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -march=armv7-r")
-set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -march=armv7-r")
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-r")
-
 # Find Python-lxml
 execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
 if(NOT EXISTS "${PYTHON_SITE_PACKAGES}/lxml")

+ 13 - 12
examples/server.c

@@ -208,7 +208,7 @@ int main(int argc, char** argv) {
 	UA_DataSource dateDataSource = (UA_DataSource) {.handle = NULL, .read = readTimeData, .write = NULL};
 	const UA_QualifiedName dateName = UA_QUALIFIEDNAME(1, "current time");
 	UA_Server_addDataSourceVariableNode(server, dateDataSource, dateName, UA_NODEID_NULL,
-                                        UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES));
+                                        UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), NULL);
 
 #ifndef _WIN32
 	//cpu temperature monitoring for linux machines
@@ -217,7 +217,7 @@ int main(int argc, char** argv) {
 		UA_DataSource temperatureDataSource = (UA_DataSource) {.handle = NULL, .read = readTemperature, .write = NULL};
 		const UA_QualifiedName tempName = UA_QUALIFIEDNAME(1, "cpu temperature");
 		UA_Server_addDataSourceVariableNode(server, temperatureDataSource, tempName, UA_NODEID_NULL,
-                                            UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES));
+                                                    UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), NULL);
 	}
 
 	//LED control for rpi
@@ -236,7 +236,7 @@ int main(int argc, char** argv) {
             const UA_QualifiedName statusName = UA_QUALIFIEDNAME(0, "status LED");
             UA_Server_addDataSourceVariableNode(server, ledStatusDataSource, statusName, UA_NODEID_NULL,
                                                 UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
-                                                UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES));
+                                                UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), NULL);
         } else {
             UA_LOG_WARNING(logger, UA_LOGCATEGORY_USERLAND, "[Raspberry Pi] LED file exist, but I have no access (try to run server with sudo)");
         }
@@ -252,7 +252,7 @@ int main(int argc, char** argv) {
     UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
     UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
     UA_Server_addVariableNode(server, myIntegerVariant, myIntegerName,
-                              myIntegerNodeId, parentNodeId, parentReferenceNodeId);
+                              myIntegerNodeId, parentNodeId, parentReferenceNodeId, NULL);
 
    /**************/
    /* Demo Nodes */
@@ -260,19 +260,19 @@ int main(int argc, char** argv) {
 
 #define DEMOID 50000
    UA_Server_addObjectNode(server,UA_QUALIFIEDNAME(1, "Demo"), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
-                           UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE));
+                           UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), NULL);
 
 #define SCALARID 50001
    UA_Server_addObjectNode(server,UA_QUALIFIEDNAME(1, "Scalar"), UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(1, DEMOID),
-                           UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE));
+                           UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), NULL);
 
 #define ARRAYID 50002
    UA_Server_addObjectNode(server,UA_QUALIFIEDNAME(1, "Array"), UA_NODEID_NUMERIC(1, ARRAYID), UA_NODEID_NUMERIC(1, DEMOID),
-                           UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE));
+                           UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), NULL);
 
 #define MATRIXID 50003
    UA_Server_addObjectNode(server,UA_QUALIFIEDNAME(1, "Matrix"), UA_NODEID_NUMERIC(1, MATRIXID), UA_NODEID_NUMERIC(1, DEMOID),
-                           UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE));
+                           UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), NULL);
 
    UA_UInt32 id = 51000; //running id in namespace 0
    for(UA_UInt32 type = 0; UA_IS_BUILTIN(type); type++) {
@@ -286,13 +286,13 @@ int main(int argc, char** argv) {
         sprintf(name, "%02d", type);
         UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME(1, name);
         UA_Server_addVariableNode(server, variant, qualifiedName, UA_NODEID_NUMERIC(1, ++id),
-                                  UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES));
+                                  UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), NULL);
 
         //add an array node for every built-in type
         UA_Variant *arrayvar = UA_Variant_new();
         UA_Variant_setArray(arrayvar, UA_Array_new(&UA_TYPES[type], 10), 10, &UA_TYPES[type]);
         UA_Server_addVariableNode(server, arrayvar, qualifiedName, UA_NODEID_NUMERIC(1, ++id),
-                                  UA_NODEID_NUMERIC(1, ARRAYID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES));
+                                  UA_NODEID_NUMERIC(1, ARRAYID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), NULL);
 
         //add an matrix node for every built-in type
         arrayvar = UA_Variant_new();
@@ -305,7 +305,7 @@ int main(int argc, char** argv) {
         arrayvar->data = myMultiArray;
         arrayvar->type = &UA_TYPES[type];
         UA_Server_addVariableNode(server, arrayvar, qualifiedName, UA_NODEID_NUMERIC(1, ++id),
-                                  UA_NODEID_NUMERIC(1, MATRIXID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES));
+                                  UA_NODEID_NUMERIC(1, MATRIXID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), NULL);
    }
 
 
@@ -330,9 +330,10 @@ int main(int argc, char** argv) {
    outputArguments.name = UA_STRING("Input an integer");
    outputArguments.valueRank = -1;
 
+   UA_NodeId methodId; // Retrieve the actual ID if this node if a random id as in UA_NODEID_NUMERIC(1,0) is used
    UA_Server_addMethodNode(server, UA_QUALIFIEDNAME(1,"ping"), UA_NODEID_NUMERIC(1,62541),
                            UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
-                           &getMonitoredItems, 1, &inputArguments, 1, &outputArguments);
+                           &getMonitoredItems, 1, &inputArguments, 1, &outputArguments, &methodId);
 #endif
 	//start server
 	UA_StatusCode retval = UA_Server_run(server, 1, &running); //blocks until running=false

+ 9 - 4
include/ua_server.h

@@ -126,17 +126,21 @@ UA_StatusCode UA_EXPORT UA_Server_addReference(UA_Server *server, const UA_NodeI
 
 UA_StatusCode UA_EXPORT
 UA_Server_addVariableNode(UA_Server *server, UA_Variant *value, const UA_QualifiedName browseName, 
-                          UA_NodeId nodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId);
+                          UA_NodeId nodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                          UA_NodeId *createdNodeId
+                         );
 
 UA_StatusCode UA_EXPORT
 UA_Server_addObjectNode(UA_Server *server, const UA_QualifiedName browseName,
                         UA_NodeId nodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                        const UA_NodeId typeDefinition);
+                        const UA_NodeId typeDefinition,
+                        UA_NodeId *createdNodeId);
 
 UA_StatusCode UA_EXPORT
 UA_Server_addDataSourceVariableNode(UA_Server *server, UA_DataSource dataSource,
                                     const UA_QualifiedName browseName, UA_NodeId nodeId,
-                                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId);
+                                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                                    UA_NodeId *createdNodeId);
 
 UA_StatusCode UA_EXPORT
 UA_Server_AddMonodirectionalReference(UA_Server *server, UA_NodeId sourceNodeId,
@@ -153,7 +157,8 @@ UA_Server_addMethodNode(UA_Server *server, const UA_QualifiedName browseName, UA
                         const UA_ExpandedNodeId parentNodeId, const UA_NodeId referenceTypeId,
                         UA_MethodCallback method, UA_Int32 inputArgumentsSize,
                         const UA_Argument *inputArguments, UA_Int32 outputArgumentsSize,
-                        const UA_Argument *outputArguments);
+                        const UA_Argument *outputArguments,
+                        UA_NodeId *createdNodeId);
 #endif
 
 /** Jobs describe work that is executed once or repeatedly. */

+ 24 - 9
src/server/ua_server_addressspace.c

@@ -3,7 +3,8 @@
 
 UA_StatusCode
 UA_Server_addVariableNode(UA_Server *server, UA_Variant *value, const UA_QualifiedName browseName, 
-                          UA_NodeId nodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId) {
+                          UA_NodeId nodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                          UA_NodeId *createdNodeId) {
     UA_VariableNode *node = UA_VariableNode_new();
     node->value.variant = *value; // copy content
     UA_NodeId_copy(&nodeId, &node->nodeId);
@@ -19,8 +20,10 @@ UA_Server_addVariableNode(UA_Server *server, UA_Variant *value, const UA_Qualifi
     if(res.statusCode != UA_STATUSCODE_GOOD) {
         UA_Variant_init(&node->value.variant);
         UA_VariableNode_delete(node);
-    } else
+    } else 
         UA_free(value);
+    if (createdNodeId != UA_NULL)
+      UA_NodeId_copy(&res.addedNodeId, createdNodeId);
     UA_AddNodesResult_deleteMembers(&res);
     return res.statusCode;
 }
@@ -28,7 +31,8 @@ UA_Server_addVariableNode(UA_Server *server, UA_Variant *value, const UA_Qualifi
 UA_StatusCode
 UA_Server_addObjectNode(UA_Server *server, const UA_QualifiedName browseName, UA_NodeId nodeId,
                         const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
-                        const UA_NodeId typeDefinition) {
+                        const UA_NodeId typeDefinition,
+                        UA_NodeId *createdNodeId) {
     UA_ObjectNode *node = UA_ObjectNode_new();
     UA_NodeId_copy(&nodeId, &node->nodeId);
     UA_QualifiedName_copy(&browseName, &node->browseName);
@@ -40,6 +44,8 @@ UA_Server_addObjectNode(UA_Server *server, const UA_QualifiedName browseName, UA
                                                          parentId, referenceTypeId);
     if(res.statusCode != UA_STATUSCODE_GOOD)
         UA_ObjectNode_delete(node);
+    if (createdNodeId != UA_NULL)
+      UA_NodeId_copy(&res.addedNodeId, createdNodeId);
     UA_AddNodesResult_deleteMembers(&res);
 
     if(!UA_NodeId_isNull(&typeDefinition)) {
@@ -55,7 +61,8 @@ UA_Server_addObjectNode(UA_Server *server, const UA_QualifiedName browseName, UA
 UA_StatusCode
 UA_Server_addDataSourceVariableNode(UA_Server *server, UA_DataSource dataSource,
                                     const UA_QualifiedName browseName, UA_NodeId nodeId,
-                                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId) {
+                                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                                    UA_NodeId *createdNodeId) {
     UA_VariableNode *node = UA_VariableNode_new();
     node->valueSource = UA_VALUESOURCE_DATASOURCE;
     node->value.dataSource = dataSource;
@@ -71,6 +78,8 @@ UA_Server_addDataSourceVariableNode(UA_Server *server, UA_DataSource dataSource,
                            UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE));
     if(res.statusCode != UA_STATUSCODE_GOOD)
         UA_VariableNode_delete(node);
+    if (createdNodeId != UA_NULL)
+      UA_NodeId_copy(&res.addedNodeId, createdNodeId);
     UA_AddNodesResult_deleteMembers(&res);
     return res.statusCode;
 }
@@ -373,7 +382,8 @@ UA_Server_addMethodNode(UA_Server *server, const UA_QualifiedName browseName, UA
                         const UA_ExpandedNodeId parentNodeId, const UA_NodeId referenceTypeId,
                         UA_MethodCallback method, UA_Int32 inputArgumentsSize,
                         const UA_Argument *inputArguments, UA_Int32 outputArgumentsSize,
-                        const UA_Argument *outputArguments) {
+                        const UA_Argument *outputArguments,
+                        UA_NodeId *createdNodeId) {
     UA_MethodNode *newMethod = UA_MethodNode_new();
     UA_NodeId_copy(&nodeId, &newMethod->nodeId);
     UA_QualifiedName_copy(&browseName, &newMethod->browseName);
@@ -381,10 +391,6 @@ UA_Server_addMethodNode(UA_Server *server, const UA_QualifiedName browseName, UA
     newMethod->attachedMethod = method;
     newMethod->executable = UA_TRUE;
     newMethod->userExecutable = UA_TRUE;
-
-    UA_ExpandedNodeId methodExpandedNodeId;
-    UA_ExpandedNodeId_init(&methodExpandedNodeId);
-    UA_NodeId_copy(&newMethod->nodeId, &methodExpandedNodeId.nodeId);
     
     UA_AddNodesResult addRes = UA_Server_addNode(server, (UA_Node*)newMethod, parentNodeId, referenceTypeId);
     if(addRes.statusCode != UA_STATUSCODE_GOOD) {
@@ -392,6 +398,13 @@ UA_Server_addMethodNode(UA_Server *server, const UA_QualifiedName browseName, UA
         return addRes.statusCode;
     }
     
+    UA_ExpandedNodeId methodExpandedNodeId;
+    UA_ExpandedNodeId_init(&methodExpandedNodeId);
+    UA_NodeId_copy(&addRes.addedNodeId, &methodExpandedNodeId.nodeId);
+    
+    if (createdNodeId != UA_NULL)
+      UA_NodeId_copy(&addRes.addedNodeId, createdNodeId);
+    
     /* create InputArguments */
     UA_NodeId argId = UA_NODEID_NUMERIC(nodeId.namespaceIndex, 0); 
     UA_VariableNode *inputArgumentsVariableNode  = UA_VariableNode_new();
@@ -409,6 +422,8 @@ UA_Server_addMethodNode(UA_Server *server, const UA_QualifiedName browseName, UA
         // TODO Remove node
         return addRes.statusCode;
     }
+    if (createdNodeId != UA_NULL)
+      UA_NodeId_copy(&addRes.addedNodeId, createdNodeId);
     
     /* create OutputArguments */
     argId = UA_NODEID_NUMERIC(nodeId.namespaceIndex, 0);