Kaynağa Gözat

improve the node adding API

Julius Pfrommer 9 yıl önce
ebeveyn
işleme
5821236990

+ 9 - 10
examples/opcuaServer.c

@@ -20,8 +20,6 @@
 #include "networklayer_udp.h"
 #endif
 
-#include "ua_types.h"
-#include "ua_nodeids.h"
 
 UA_Boolean running = 1;
 
@@ -77,12 +75,13 @@ int main(int argc, char** argv) {
 	//add a node to the adresspace
     UA_Int32 *myInteger = UA_Int32_new();
     *myInteger = 42;
+    UA_Variant *myIntegerVariant = UA_Variant_new();
+    UA_Variant_setValue(myIntegerVariant, myInteger, UA_TYPES_INT32);
     UA_QualifiedName myIntegerName;
     UA_QUALIFIEDNAME_ASSIGN(myIntegerName, "the answer");
-    UA_Server_addScalarVariableNode(server, &myIntegerName,
-                                    myInteger, UA_NODEID_STATIC(UA_TYPES_IDS[UA_TYPES_INT32],0),
-                                    &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_OBJECTSFOLDER,0),
-                                    &UA_NODEID_STATIC(UA_NS0ID_ORGANIZES,0));
+    UA_Server_addVariableNode(server, myIntegerVariant, &myIntegerName,
+                              &UA_NODEID_STATIC(UA_NS0ID_OBJECTSFOLDER,0),
+                              &UA_NODEID_STATIC(UA_NS0ID_ORGANIZES,0));
     
 #ifdef BENCHMARK
     UA_UInt32 nodeCount = 500;
@@ -93,10 +92,10 @@ int main(int argc, char** argv) {
         *data = 42;
         sprintf(str,"%d",i);
         UA_QualifiedName_copycstring(str, nodeName);
-        UA_Server_addScalarVariableNode(server, nodeName,
-                                        data, UA_NODEID_STATIC(UA_TYPES_IDS[UA_TYPES_INT32],0),
-                                        &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_OBJECTSFOLDER,0),
-                                        &UA_NODEID_STATIC(UA_NS0ID_ORGANIZES,0));
+        UA_Server_addVariableNode(server, nodeName,
+                                  data, UA_NODEID_STATIC(UA_TYPES_IDS[UA_TYPES_INT32],0),
+                                  &UA_EXPANDEDNODEID_STATIC(UA_NS0ID_OBJECTSFOLDER,0),
+                                  &UA_NODEID_STATIC(UA_NS0ID_ORGANIZES,0));
     }
 #endif
 

+ 4 - 11
include/ua_server.h

@@ -20,11 +20,11 @@
 extern "C" {
 #endif
 
-#include "ua_types.h"
 #include "ua_util.h"
+#include "ua_types.h"
 #include "ua_types_generated.h"
+#include "ua_nodeids.h"
 #include "ua_connection.h"
-    //#include "ua_nodes.h"
 #include "ua_log.h"
 
 /**
@@ -59,15 +59,8 @@ UA_StatusCode UA_EXPORT UA_Server_run(UA_Server *server, UA_UInt16 nThreads, UA_
 /** Add a reference to the server's address space */
 UA_StatusCode UA_EXPORT UA_Server_addReference(UA_Server *server, const UA_AddReferencesItem *item);
 
-/**
- * Add a scalar variable (node) to the server's address space
- *
- * The value must lie on the heap and must not be reused after adding it, as it
- * becomes attached to the lifecycle of the VariableNode. */
-UA_StatusCode UA_EXPORT UA_Server_addScalarVariableNode(UA_Server *server, UA_QualifiedName *browseName,
-                                                        void *value, const UA_NodeId typeId,
-                                                        const UA_ExpandedNodeId *parentNodeId,
-                                                        const UA_NodeId *referenceTypeId );
+UA_StatusCode UA_EXPORT UA_Server_addVariableNode(UA_Server *server, UA_Variant *value, UA_QualifiedName *browseName,
+                                                  const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId );
 
 /** Work that is run in the main loop (singlethreaded) or dispatched to a worker
     thread. */

+ 2 - 0
include/ua_types.h

@@ -389,7 +389,9 @@ void UA_EXPORT UA_QualifiedName_printf(char const *label, const UA_QualifiedName
 UA_StatusCode UA_EXPORT UA_LocalizedText_copycstring(char const *src, UA_LocalizedText *dst);
 
 /* Variant */
+UA_StatusCode UA_EXPORT UA_Variant_setValue(UA_Variant *v, void *p, UA_UInt16 typeIndex);
 UA_StatusCode UA_EXPORT UA_Variant_copySetValue(UA_Variant *v, const void *p, UA_UInt16 typeIndex);
+UA_StatusCode UA_EXPORT UA_Variant_setArray(UA_Variant *v, void *array, UA_Int32 noElements, UA_UInt16 typeIndex);
 UA_StatusCode UA_EXPORT UA_Variant_copySetArray(UA_Variant *v, const void *array, UA_Int32 noElements, UA_UInt16 typeIndex);
 
 /****************************/

+ 8 - 0
src/server/ua_nodes.c

@@ -43,6 +43,7 @@ static UA_StatusCode UA_Node_copy(const UA_Node *src, UA_Node *dst) {
 /* UA_ObjectNode */
 void UA_ObjectNode_init(UA_ObjectNode *p) {
 	UA_Node_init((UA_Node*)p);
+    p->nodeClass = UA_NODECLASS_OBJECT;
     p->eventNotifier = 0;
 }
 
@@ -70,6 +71,7 @@ UA_StatusCode UA_ObjectNode_copy(const UA_ObjectNode *src, UA_ObjectNode *dst) {
 /* UA_ObjectTypeNode */
 void UA_ObjectTypeNode_init(UA_ObjectTypeNode *p) {
 	UA_Node_init((UA_Node*)p);
+    p->nodeClass = UA_NODECLASS_OBJECTTYPE;
     p->isAbstract = UA_FALSE;
 }
 
@@ -97,6 +99,7 @@ UA_StatusCode UA_ObjectTypeNode_copy(const UA_ObjectTypeNode *src, UA_ObjectType
 /* UA_VariableNode */
 void UA_VariableNode_init(UA_VariableNode *p) {
 	UA_Node_init((UA_Node*)p);
+    p->nodeClass = UA_NODECLASS_VARIABLE;
     UA_Variant_init(&p->value);
     UA_NodeId_init(&p->dataType);
     p->valueRank = 0;
@@ -155,6 +158,7 @@ UA_StatusCode UA_VariableNode_copy(const UA_VariableNode *src, UA_VariableNode *
 /* UA_VariableTypeNode */
 void UA_VariableTypeNode_init(UA_VariableTypeNode *p) {
 	UA_Node_init((UA_Node*)p);
+    p->nodeClass = UA_NODECLASS_VARIABLETYPE;
     UA_Variant_init(&p->value);
     UA_NodeId_init(&p->dataType);
     p->valueRank = 0;
@@ -207,6 +211,7 @@ UA_StatusCode UA_VariableTypeNode_copy(const UA_VariableTypeNode *src, UA_Variab
 /* UA_ReferenceTypeNode */
 void UA_ReferenceTypeNode_init(UA_ReferenceTypeNode *p) {
 	UA_Node_init((UA_Node*)p);
+    p->nodeClass = UA_NODECLASS_REFERENCETYPE;
     p->isAbstract = UA_FALSE;
     p->symmetric = UA_FALSE;
     UA_LocalizedText_init(&p->inverseName);
@@ -246,6 +251,7 @@ UA_StatusCode UA_ReferenceTypeNode_copy(const UA_ReferenceTypeNode *src, UA_Refe
 /* UA_MethodNode */
 void UA_MethodNode_init(UA_MethodNode *p) {
 	UA_Node_init((UA_Node*)p);
+    p->nodeClass = UA_NODECLASS_METHOD;
     p->executable = UA_FALSE;
     p->userExecutable = UA_FALSE;
 }
@@ -275,6 +281,7 @@ UA_StatusCode UA_MethodNode_copy(const UA_MethodNode *src, UA_MethodNode *dst) {
 /* UA_ViewNode */
 void UA_ViewNode_init(UA_ViewNode *p) {
 	UA_Node_init((UA_Node*)p);
+    p->nodeClass = UA_NODECLASS_VIEW;
     p->containsNoLoops = UA_FALSE;
     p->eventNotifier = 0;
 }
@@ -304,6 +311,7 @@ UA_StatusCode UA_ViewNode_copy(const UA_ViewNode *src, UA_ViewNode *dst) {
 /* UA_DataTypeNode */
 void UA_DataTypeNode_init(UA_DataTypeNode *p) {
 	UA_Node_init((UA_Node*)p);
+    p->nodeClass = UA_NODECLASS_DATATYPE;
     p->isAbstract = UA_FALSE;
 }
 

+ 28 - 29
src/server/ua_server_addressspace.c

@@ -1,36 +1,35 @@
 #include "ua_server.h"
 #include "ua_server_internal.h"
 
-UA_StatusCode UA_Server_addScalarVariableNode(UA_Server *server, UA_QualifiedName *browseName,
-                                              void *value, const UA_NodeId typeId,
-                                              const UA_ExpandedNodeId *parentNodeId,
-                                              const UA_NodeId *referenceTypeId ) {
-    if(typeId.namespaceIndex != 0)
-        return UA_STATUSCODE_BADINTERNALERROR;
-    UA_VariableNode *tmpNode = UA_VariableNode_new();
-    UA_QualifiedName_copy(browseName, &tmpNode->browseName);
-    UA_String_copy(&browseName->name, &tmpNode->displayName.text);
-    /* UA_LocalizedText_copycstring("integer value", &tmpNode->description); */
-    tmpNode->nodeClass = UA_NODECLASS_VARIABLE;
-    tmpNode->valueRank = -1;
-    UA_NodeId_copy(&typeId, &tmpNode->dataType);
-    UA_NodeId_copy(&typeId, &tmpNode->value.typeId);
-    tmpNode->value.storage.data.dataPtr = value;
-    tmpNode->value.storageType = UA_VARIANT_DATA;
-    tmpNode->value.storage.data.arrayLength = 1;
-    size_t i;
-    for(i = 0;i<UA_TYPES_COUNT;i++) {
-        if(UA_TYPES_IDS[i] == typeId.identifier.numeric)
-            break;
-    }
-    if(i >= UA_TYPES_COUNT) {
-        UA_VariableNode_delete(tmpNode);
-        return UA_STATUSCODE_BADINTERNALERROR;
+    /* size_t i; */
+    /* for(i = 0;i<UA_TYPES_COUNT;i++) { */
+    /*     if(UA_TYPES_IDS[i] == typeId.identifier.numeric) */
+    /*         break; */
+    /* } */
+    /* if(i >= UA_TYPES_COUNT) { */
+    /*     UA_VariableNode_delete(tmpNode); */
+    /*     return UA_STATUSCODE_BADINTERNALERROR; */
+    /* } */
+    /* tmpNode->value.type = &UA_TYPES[i]; */
+
+UA_StatusCode UA_Server_addVariableNode(UA_Server *server, UA_Variant *value, UA_QualifiedName *browseName,
+                                        const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId ) {
+    UA_VariableNode *node = UA_VariableNode_new();
+    node->value = *value; // copy content
+    UA_QualifiedName_copy(browseName, &node->browseName);
+    UA_String_copy(&browseName->name, &node->displayName.text);
+    UA_ExpandedNodeId parentId; // we need an expandednodeid
+    UA_ExpandedNodeId_init(&parentId);
+    parentId.nodeId = *parentNodeId;
+    UA_AddNodesResult res = UA_Server_addNodeWithSession(server, &adminSession, (UA_Node*)node,
+                                                         &parentId, referenceTypeId);
+    if(res.statusCode != UA_STATUSCODE_GOOD) {
+        UA_Variant_init(&node->value);
+        UA_VariableNode_delete(node);
+    } else {
+        UA_free(value);
     }
-    tmpNode->value.type = &UA_TYPES[i];
-    UA_Server_addNodeWithSession(server, &adminSession, (UA_Node*)tmpNode,
-                                 parentNodeId, referenceTypeId);
-    return UA_STATUSCODE_GOOD;
+    return res.statusCode;
 }
 
 /* Adds a one-way reference to the local nodestore */

+ 31 - 28
src/ua_types.c

@@ -643,39 +643,42 @@ UA_StatusCode UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
     return retval;
 }
 
-/** Copies data into a variant. The target variant has always a storagetype UA_VARIANT_DATA */
+UA_StatusCode UA_Variant_setValue(UA_Variant *v, void *p, UA_UInt16 typeIndex) {
+    return UA_Variant_setArray(v, p, 1, typeIndex);
+}
+
 UA_StatusCode UA_Variant_copySetValue(UA_Variant *v, const void *p, UA_UInt16 typeIndex) {
-    UA_Variant_init(v);
-    v->type = &UA_TYPES[typeIndex];
-    v->typeId = (UA_NodeId){.namespaceIndex = 0,
-                                .identifierType = UA_NODEIDTYPE_NUMERIC,
-                                .identifier.numeric = UA_TYPES_IDS[typeIndex]};
-    v->storage.data.arrayLength = 1; // no array but a single entry
-    UA_StatusCode retval = UA_STATUSCODE_GOOD;
-    if((v->storage.data.dataPtr = UA_new(&UA_TYPES[typeIndex])))
-       retval = UA_copy(p, v->storage.data.dataPtr, &UA_TYPES[typeIndex]);
-    else
-        retval = UA_STATUSCODE_BADOUTOFMEMORY;
-    if(retval) {
-        UA_Variant_deleteMembers(v);
-        UA_Variant_init(v);
-    }
-    return retval;
+    if(typeIndex >= UA_TYPES_COUNT)
+        return UA_STATUSCODE_BADINTERNALERROR;
+    void *new;
+    UA_StatusCode retval = UA_copy(p, &new, &UA_TYPES[typeIndex]);
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
+    return UA_Variant_setArray(v, new, 1, typeIndex);
 }
 
-UA_StatusCode UA_Variant_copySetArray(UA_Variant *v, const void *array, UA_Int32 noElements, UA_UInt16 typeIndex) {
-    UA_Variant_init(v);
+UA_StatusCode UA_Variant_setArray(UA_Variant *v, void *array, UA_Int32 noElements,
+                                  UA_UInt16 typeIndex) {
+    if(typeIndex >= UA_TYPES_COUNT)
+        return UA_STATUSCODE_BADINTERNALERROR;
+
+    UA_Variant_deleteMembers(v);
     v->type = &UA_TYPES[typeIndex];
-    v->typeId = (UA_NodeId){.namespaceIndex = 0,
-                            .identifierType = UA_NODEIDTYPE_NUMERIC,
-                            .identifier.numeric = UA_TYPES_IDS[typeIndex]};
+    v->typeId = UA_NODEID_STATIC(UA_TYPES_IDS[typeIndex], 0);
     v->storage.data.arrayLength = noElements;
-    UA_StatusCode retval = UA_Array_copy(array, noElements, &v->storage.data.dataPtr, &UA_TYPES[typeIndex]);
-    if(retval) {
-        UA_Variant_deleteMembers(v);
-        UA_Variant_init(v);
-    }
-    return retval;
+    v->storage.data.dataPtr = array;
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_StatusCode UA_Variant_copySetArray(UA_Variant *v, const void *array, UA_Int32 noElements,
+                                      UA_UInt16 typeIndex) {
+    if(typeIndex >= UA_TYPES_COUNT)
+        return UA_STATUSCODE_BADINTERNALERROR;
+    void *new;
+    UA_StatusCode retval = UA_Array_copy(array, noElements, &new, &UA_TYPES[typeIndex]);
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
+    return UA_Variant_setArray(v, new, noElements, typeIndex);
 }
 
 /* DiagnosticInfo */