Browse Source

re-add @FlorianPalm 's work for parsing attributes of new nodes

Julius Pfrommer 10 years ago
parent
commit
9122377a61
1 changed files with 121 additions and 2 deletions
  1. 121 2
      src/server/ua_services_nodemanagement.c

+ 121 - 2
src/server/ua_services_nodemanagement.c

@@ -83,6 +83,112 @@ static UA_StatusCode parseVariableNode(UA_ExtensionObject *attributes, UA_Node *
     return UA_STATUSCODE_GOOD;
 }
 
+static UA_StatusCode parseObjectNode(UA_ExtensionObject *attributes,
+                                     UA_Node **new_node, const UA_TypeVTable **vt) {
+    if(attributes->typeId.identifier.numeric !=
+       UA_NODEIDS[UA_OBJECTATTRIBUTES].identifier.numeric + UA_ENCODINGOFFSET_BINARY)  // VariableAttributes_Encoding_DefaultBinary
+        return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
+    UA_ObjectAttributes attr;
+    UA_UInt32 pos = 0;
+    // todo return more informative error codes from decodeBinary
+    if (UA_ObjectAttributes_decodeBinary(&attributes->body, &pos, &attr) != UA_STATUSCODE_GOOD)
+        return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
+    UA_ObjectNode *vnode = UA_ObjectNode_new();
+    if(!vnode) {
+        UA_ObjectAttributes_deleteMembers(&attr);
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    }
+
+    // now copy all the attributes. This potentially removes them from the decoded attributes.
+    COPY_STANDARDATTRIBUTES;
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_EVENTNOTIFIER)
+        vnode->eventNotifier = attr.eventNotifier;
+    UA_ObjectAttributes_deleteMembers(&attr);
+    *new_node = (UA_Node*) vnode;
+    *vt = &UA_TYPES[UA_OBJECTNODE];
+    return UA_STATUSCODE_GOOD;
+}
+
+static UA_StatusCode parseReferenceTypeNode(UA_ExtensionObject *attributes,
+                                            UA_Node **new_node, const UA_TypeVTable **vt) {
+    UA_ReferenceTypeAttributes attr;
+    UA_UInt32 pos = 0;
+    // todo return more informative error codes from decodeBinary
+    if(UA_ReferenceTypeAttributes_decodeBinary(&attributes->body, &pos, &attr) != UA_STATUSCODE_GOOD)
+        return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
+    UA_ReferenceTypeNode *vnode = UA_ReferenceTypeNode_new();
+    if(!vnode) {
+        UA_ReferenceTypeAttributes_deleteMembers(&attr);
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    }
+
+    // now copy all the attributes. This potentially removes them from the decoded attributes.
+    COPY_STANDARDATTRIBUTES;
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_ISABSTRACT)
+        vnode->isAbstract = attr.isAbstract;
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_SYMMETRIC)
+        vnode->symmetric = attr.symmetric;
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_INVERSENAME) {
+        vnode->inverseName = attr.inverseName;
+        attr.inverseName.text.length = -1;
+        attr.inverseName.text.data = UA_NULL;
+        attr.inverseName.locale.length = -1;
+        attr.inverseName.locale.data = UA_NULL;
+    }
+    UA_ReferenceTypeAttributes_deleteMembers(&attr);
+    *new_node = (UA_Node*) vnode;
+    *vt = &UA_TYPES[UA_REFERENCETYPENODE];
+    return UA_STATUSCODE_GOOD;
+}
+
+static UA_StatusCode parseObjectTypeNode(UA_ExtensionObject *attributes,
+                                         UA_Node **new_node, const UA_TypeVTable **vt) {
+    UA_ObjectTypeAttributes attr;
+    UA_UInt32 pos = 0;
+    // todo return more informative error codes from decodeBinary
+    if(UA_ObjectTypeAttributes_decodeBinary(&attributes->body, &pos, &attr) != UA_STATUSCODE_GOOD)
+        return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
+    UA_ObjectTypeNode *vnode = UA_ObjectTypeNode_new();
+    if(!vnode) {
+        UA_ObjectTypeAttributes_deleteMembers(&attr);
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    }
+    
+    // now copy all the attributes. This potentially removes them from the decoded attributes.
+    COPY_STANDARDATTRIBUTES;
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_ISABSTRACT) {
+        vnode->isAbstract = attr.isAbstract;
+    }
+    UA_ObjectTypeAttributes_deleteMembers(&attr);
+    *new_node = (UA_Node*) vnode;
+    *vt = &UA_TYPES[UA_OBJECTTYPENODE];
+    return UA_STATUSCODE_GOOD;
+}
+
+static UA_StatusCode parseViewNode(UA_ExtensionObject *attributes, UA_Node **new_node,
+                                   const UA_TypeVTable **vt) {
+    UA_ViewAttributes attr;
+    UA_UInt32 pos = 0;
+    // todo return more informative error codes from decodeBinary
+    if(UA_ViewAttributes_decodeBinary(&attributes->body, &pos, &attr) != UA_STATUSCODE_GOOD)
+        return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
+    UA_ViewNode *vnode = UA_ViewNode_new();
+    if(!vnode) {
+        UA_ViewAttributes_deleteMembers(&attr);
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    }
+    // now copy all the attributes. This potentially removes them from the decoded attributes.
+    COPY_STANDARDATTRIBUTES;
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_CONTAINSNOLOOPS)
+        vnode->containsNoLoops = attr.containsNoLoops;
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_EVENTNOTIFIER)
+        vnode->eventNotifier = attr.eventNotifier;
+    UA_ViewAttributes_deleteMembers(&attr);
+    *new_node = (UA_Node*) vnode;
+    *vt = &UA_TYPES[UA_VIEWNODE];
+    return UA_STATUSCODE_GOOD;
+}
+
 static void addNodeFromAttributes(UA_Server *server, UA_Session *session, UA_AddNodesItem *item,
                                   UA_AddNodesResult *result) {
     // adding nodes to ns0 is not allowed over the wire
@@ -94,10 +200,23 @@ static void addNodeFromAttributes(UA_Server *server, UA_Session *session, UA_Add
     // parse the node
     UA_Node *node;
     const UA_TypeVTable *nodeVT = UA_NULL;
-    if(item->nodeClass == UA_NODECLASS_VARIABLE)
+
+    switch (item->nodeClass) {
+    case UA_NODECLASS_OBJECT:
+        result->statusCode = parseObjectNode(&item->nodeAttributes, &node, &nodeVT);
+        break;
+    case UA_NODECLASS_OBJECTTYPE:
+        result->statusCode = parseObjectTypeNode(&item->nodeAttributes, &node, &nodeVT);
+        break;
+    case UA_NODECLASS_REFERENCETYPE:
+        result->statusCode = parseReferenceTypeNode(&item->nodeAttributes, &node, &nodeVT);
+        break;
+    case UA_NODECLASS_VARIABLE:
         result->statusCode = parseVariableNode(&item->nodeAttributes, &node, &nodeVT);
-    else // add more node types here..
+        break;
+    default:
         result->statusCode = UA_STATUSCODE_BADNOTIMPLEMENTED;
+    }
 
     if(result->statusCode != UA_STATUSCODE_GOOD)
         return;