Browse Source

improve instantiation of variables and objects

Julius Pfrommer 8 years ago
parent
commit
384b7b3a31
1 changed files with 211 additions and 206 deletions
  1. 211 206
      src/server/ua_services_nodemanagement.c

+ 211 - 206
src/server/ua_services_nodemanagement.c

@@ -10,173 +10,8 @@ Service_AddNodes_single(UA_Server *server, UA_Session *session,
                         const UA_AddNodesItem *item, UA_AddNodesResult *result,
                         UA_InstantiationCallback *instantiationCallback);
 
-static UA_StatusCode
-instantiateVariableNode(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
-                        const UA_NodeId *typeId, UA_InstantiationCallback *instantiationCallback);
-static UA_StatusCode
-instantiateObjectNode(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
-                      const UA_NodeId *typeId, UA_InstantiationCallback *instantiationCallback);
-
-static UA_StatusCode
-checkNewNodeReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeClass,
-                      const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
-                      const UA_NodeId *typeDefinition) {
-    /* See if the parent exists */
-    const UA_Node *parent = UA_NodeStore_get(server->nodestore, parentNodeId);
-    if(!parent) {
-        UA_LOG_DEBUG_SESSION(server->config.logger, session, "AddNodes: Parent node not found");
-        return UA_STATUSCODE_BADPARENTNODEIDINVALID;
-    }
-
-    /* Check the referencetype exists */
-    const UA_ReferenceTypeNode *referenceType =
-        (const UA_ReferenceTypeNode *)UA_NodeStore_get(server->nodestore, referenceTypeId);
-    if(!referenceType) {
-        UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                             "AddNodes: Reference type to the parent not found");
-        return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
-    }
-
-    /* Check if the referencetype is a reference type node */
-    if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) {
-        UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                             "AddNodes: Reference type to the parent invalid");
-        return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
-    }
-
-    /* Check that the reference type is not abstract */
-    if(referenceType->isAbstract == true) {
-        UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                             "AddNodes: Abstract reference type to the parent invalid");
-        return UA_STATUSCODE_BADREFERENCENOTALLOWED;
-    }
-
-    /* Checks that apply only for type nodeids */
-    const UA_NodeId subtypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
-    if(nodeClass == UA_NODECLASS_DATATYPE ||
-       nodeClass == UA_NODECLASS_VARIABLETYPE ||
-       nodeClass == UA_NODECLASS_OBJECTTYPE ||
-       nodeClass == UA_NODECLASS_REFERENCETYPE) {
-        /* type needs hassubtype reference to the supertype */
-        if(!UA_NodeId_equal(referenceTypeId, &subtypeId)) {
-            UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                                 "AddNodes: New type node need to have a hassubtype reference");
-            return UA_STATUSCODE_BADREFERENCENOTALLOWED;
-        }
-        /* supertype needs to be of the same node type  */
-        if(parent->nodeClass != nodeClass) {
-            UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                                 "AddNodes: New type node needs to be of the same node type as the parent");
-            return UA_STATUSCODE_BADPARENTNODEIDINVALID;
-        }
-    } else {
-        /* Test if the referencetype is hierarchical */
-        const UA_NodeId hierarchicalReference = UA_NODEID_NUMERIC(0, UA_NS0ID_HIERARCHICALREFERENCES);
-        UA_Boolean found = false;
-        UA_StatusCode retval = isNodeInTree(server->nodestore, referenceTypeId,
-                                            &hierarchicalReference, &subtypeId, 1, &found);
-        if(retval != UA_STATUSCODE_GOOD || !found) {
-            UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                                 "AddNodes: Reference type is not hierarchical");
-            return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
-        }
-    }
-
-    return UA_STATUSCODE_GOOD;
-}
-
-UA_StatusCode
-Service_AddNodes_existing(UA_Server *server, UA_Session *session, UA_Node *node,
-                          const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
-                          const UA_NodeId *typeDefinition,
-                          UA_InstantiationCallback *instantiationCallback,
-                          UA_NodeId *addedNodeId) {
-
-    /* Fall back to a default typedefinition for variables and objects */
-    const UA_NodeId basedatavariabletype = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
-    const UA_NodeId baseobjecttype = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE);
-    if(node->nodeClass == UA_NODECLASS_VARIABLE ||
-       node->nodeClass == UA_NODECLASS_OBJECT) {
-        if(UA_NodeId_isNull(typeDefinition)) {
-            if(node->nodeClass == UA_NODECLASS_VARIABLE)
-                typeDefinition = &basedatavariabletype;
-            else
-                typeDefinition = &baseobjecttype;
-        }
-    }
-    
-    /* Check the namespaceindex */
-    if(node->nodeId.namespaceIndex >= server->namespacesSize) {
-        UA_LOG_DEBUG_SESSION(server->config.logger, session, "AddNodes: Namespace invalid");
-        UA_NodeStore_deleteNode(node);
-        return UA_STATUSCODE_BADNODEIDINVALID;
-    }
-
-    /* Check the reference to the parent */
-    UA_StatusCode retval = checkNewNodeReference(server, session, node->nodeClass,
-                                                 parentNodeId, referenceTypeId, typeDefinition);
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_NodeStore_deleteNode(node);
-        return retval;
-    }
-
-    /* Add the node to the nodestore */
-    retval = UA_NodeStore_insert(server->nodestore, node);
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                             "AddNodes: Node could not be added to the nodestore "
-                             "with error code 0x%08x", retval);
-        return retval;
-    }
-
-    /* Copy the nodeid if needed */
-    if(addedNodeId) {
-        retval = UA_NodeId_copy(&node->nodeId, addedNodeId);
-        if(retval != UA_STATUSCODE_GOOD)
-            goto remove_node;
-    }
-
-    /* Hierarchical reference back to the parent */
-    UA_AddReferencesItem item;
-    UA_AddReferencesItem_init(&item);
-    item.sourceNodeId = node->nodeId;
-    item.referenceTypeId = *referenceTypeId;
-    item.isForward = false;
-    item.targetNodeId.nodeId = *parentNodeId;
-    retval = Service_AddReferences_single(server, session, &item);
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_LOG_DEBUG_SESSION(server->config.logger, session,
-                             "AddNodes: Could not add the reference to the parent");
-        goto remove_node;
-    }
-
-    /* Instantiate variables and objects */
-    if(node->nodeClass == UA_NODECLASS_OBJECT)
-        retval = instantiateObjectNode(server, session, &node->nodeId,
-                                       typeDefinition, instantiationCallback);
-    else if(node->nodeClass == UA_NODECLASS_VARIABLE)
-        retval = instantiateVariableNode(server, session, &node->nodeId,
-                                         typeDefinition, instantiationCallback);
-    if(retval != UA_STATUSCODE_GOOD)
-        goto remove_node;
-
-    /* Custom callback */
-    if(instantiationCallback)
-        instantiationCallback->method(node->nodeId, *typeDefinition,
-                                      instantiationCallback->handle);
-    return UA_STATUSCODE_GOOD;
-
- remove_node:
-    Service_DeleteNodes_single(server, &adminSession, &node->nodeId, true);
-    return retval;
-}
-
-/********************************************/
-/* Copy / Instantiate Variables and Objects */
-/********************************************/
-
 /* copy an existing variable under the given parent. then instantiate the
-   variable for all hastypedefinitions of the original version. */
+ * variable for its type */
 static UA_StatusCode
 copyExistingVariable(UA_Server *server, UA_Session *session, const UA_NodeId *variable,
                      const UA_NodeId *referenceType, const UA_NodeId *parent,
@@ -278,10 +113,12 @@ copyExistingObject(UA_Server *server, UA_Session *session, const UA_NodeId *obje
 }
 
 static UA_StatusCode
-setObjectInstanceHandle(UA_Server *server, UA_Session *session, UA_ObjectNode* node, void *handle) {
+setObjectInstanceHandle(UA_Server *server, UA_Session *session,
+                        UA_ObjectNode* node, void * (*constructor)(const UA_NodeId instance)) {
     if(node->nodeClass != UA_NODECLASS_OBJECT)
         return UA_STATUSCODE_BADNODECLASSINVALID;
-    node->instanceHandle = handle;
+    if(!node->instanceHandle)
+        node->instanceHandle = constructor(node->nodeId);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -345,9 +182,9 @@ instantiateObjectNode(UA_Server *server, UA_Session *session,
           copyExistingObject(server, session, &rd->nodeId.nodeId,
                              &rd->referenceTypeId, nodeId, instantiationCallback);
     }
-    
-    // Instantiate supertype attributes if a supertype is available
     UA_BrowseResult_deleteMembers(&browseResult);
+    
+    /* Instantiate supertype attributes if a supertype is available */
     UA_BrowseResult_init(&browseResult);
     browseChildren.nodeId = *typeId;
     browseChildren.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
@@ -357,14 +194,10 @@ instantiateObjectNode(UA_Server *server, UA_Session *session,
     browseChildren.resultMask = UA_BROWSERESULTMASK_REFERENCETYPEID | UA_BROWSERESULTMASK_NODECLASS;
     // todo: continuation points if there are too many results
     Service_Browse_single(server, session, NULL, &browseChildren, 100, &browseResult);
-    
-    for(size_t i = 0; i < browseResult.referencesSize; i++) { // UA Spec forbids multiple inheritance, but we can easily support it...
-      UA_ReferenceDescription *rd = &browseResult.references[i];
-      if(rd->nodeClass != UA_NODECLASS_OBJECTTYPE)
-        break;
-      instantiateObjectNode(server, session, nodeId, &rd->nodeId.nodeId, instantiationCallback);
+    for(size_t i = 0; i < browseResult.referencesSize; i++) {
+        UA_ReferenceDescription *rd = &browseResult.references[i];
+        instantiateObjectNode(server, session, nodeId, &rd->nodeId.nodeId, instantiationCallback);
     }
-    
     UA_BrowseResult_deleteMembers(&browseResult);
     
     /* add a hastypedefinition reference */
@@ -382,7 +215,7 @@ instantiateObjectNode(UA_Server *server, UA_Session *session,
     if(olm->constructor)
         UA_Server_editNode(server, session, nodeId,
                            (UA_EditNodeCallback)setObjectInstanceHandle,
-                           olm->constructor(*nodeId));
+                           olm->constructor);
     return UA_STATUSCODE_GOOD;
 }
 
@@ -390,10 +223,6 @@ static UA_StatusCode
 instantiateVariableNode(UA_Server *server, UA_Session *session,
                         const UA_NodeId *nodeId, const UA_NodeId *typeId,
                         UA_InstantiationCallback *instantiationCallback) {
-    /* we must have a type */
-    if(!typeId)
-        return UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
-
     /* see if the type is derived from basevariabletype */
     UA_Boolean found = false;
     const UA_NodeId hassubtype = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
@@ -420,12 +249,14 @@ instantiateVariableNode(UA_Server *server, UA_Session *session,
     browseChildren.includeSubtypes = true;
     browseChildren.browseDirection = UA_BROWSEDIRECTION_FORWARD;
     browseChildren.nodeClassMask = UA_NODECLASS_VARIABLE;
-    browseChildren.resultMask = UA_BROWSERESULTMASK_REFERENCETYPEID | UA_BROWSERESULTMASK_NODECLASS;
+    browseChildren.resultMask =
+        UA_BROWSERESULTMASK_REFERENCETYPEID | UA_BROWSERESULTMASK_NODECLASS;
 
     UA_BrowseResult browseResult;
     UA_BrowseResult_init(&browseResult);
     // todo: continuation points if there are too many results
-    Service_Browse_single(server, session, NULL, &browseChildren, 100, &browseResult);
+    Service_Browse_single(server, session, NULL, &browseChildren,
+                          100, &browseResult);
 
     /* add the child properties */
     for(size_t i = 0; i < browseResult.referencesSize; i++) {
@@ -433,6 +264,23 @@ instantiateVariableNode(UA_Server *server, UA_Session *session,
         copyExistingVariable(server, session, &rd->nodeId.nodeId,
                              &rd->referenceTypeId, nodeId, instantiationCallback);
     }
+    UA_BrowseResult_deleteMembers(&browseResult);
+
+    /* Instantiate supertypes */
+    UA_BrowseResult_init(&browseResult);
+    browseChildren.nodeId = *typeId;
+    browseChildren.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
+    browseChildren.includeSubtypes = false;
+    browseChildren.browseDirection = UA_BROWSEDIRECTION_INVERSE; // isSubtypeOf
+    browseChildren.nodeClassMask = UA_NODECLASS_VARIABLETYPE;
+    browseChildren.resultMask = UA_BROWSERESULTMASK_REFERENCETYPEID | UA_BROWSERESULTMASK_NODECLASS;
+    // todo: continuation points if there are too many results
+    Service_Browse_single(server, session, NULL, &browseChildren, 100, &browseResult);
+    for(size_t i = 0; i < browseResult.referencesSize; i++) {
+        UA_ReferenceDescription *rd = &browseResult.references[i];
+        instantiateVariableNode(server, session, nodeId, &rd->nodeId.nodeId, instantiationCallback);
+    }
+    UA_BrowseResult_deleteMembers(&browseResult);
 
     /* add a hastypedefinition reference */
     UA_AddReferencesItem addref;
@@ -442,10 +290,170 @@ instantiateVariableNode(UA_Server *server, UA_Session *session,
     addref.isForward = true;
     addref.targetNodeId.nodeId = *typeId;
     addref.targetNodeClass = UA_NODECLASS_OBJECTTYPE;
+    /* TODO: Check result */
     Service_AddReferences_single(server, session, &addref);
     return UA_STATUSCODE_GOOD;
+} 
+
+static UA_StatusCode
+checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeClass,
+                     const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
+                     const UA_NodeId *typeDefinition) {
+    /* See if the parent exists */
+    const UA_Node *parent = UA_NodeStore_get(server->nodestore, parentNodeId);
+    if(!parent) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                             "AddNodes: Parent node not found");
+        return UA_STATUSCODE_BADPARENTNODEIDINVALID;
+    }
+
+    /* Check the referencetype exists */
+    const UA_ReferenceTypeNode *referenceType =
+        (const UA_ReferenceTypeNode*)UA_NodeStore_get(server->nodestore, referenceTypeId);
+    if(!referenceType) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                             "AddNodes: Reference type to the parent not found");
+        return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
+    }
+
+    /* Check if the referencetype is a reference type node */
+    if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                             "AddNodes: Reference type to the parent invalid");
+        return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
+    }
+
+    /* Check that the reference type is not abstract */
+    if(referenceType->isAbstract == true) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                             "AddNodes: Abstract reference type to the parent invalid");
+        return UA_STATUSCODE_BADREFERENCENOTALLOWED;
+    }
+
+    /* Check hassubtype relation for type nodes */
+    const UA_NodeId subtypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE);
+    if(nodeClass == UA_NODECLASS_DATATYPE ||
+       nodeClass == UA_NODECLASS_VARIABLETYPE ||
+       nodeClass == UA_NODECLASS_OBJECTTYPE ||
+       nodeClass == UA_NODECLASS_REFERENCETYPE) {
+        /* type needs hassubtype reference to the supertype */
+        if(!UA_NodeId_equal(referenceTypeId, &subtypeId)) {
+            UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                                 "AddNodes: New type node need to have a "
+                                 "hassubtype reference");
+            return UA_STATUSCODE_BADREFERENCENOTALLOWED;
+        }
+        /* supertype needs to be of the same node type  */
+        if(parent->nodeClass != nodeClass) {
+            UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                                 "AddNodes: New type node needs to be of the same "
+                                 "node type as the parent");
+            return UA_STATUSCODE_BADPARENTNODEIDINVALID;
+        }
+        return UA_STATUSCODE_GOOD;
+    }
+
+    /* Test if the referencetype is hierarchical */
+    const UA_NodeId hierarchicalReference =
+        UA_NODEID_NUMERIC(0, UA_NS0ID_HIERARCHICALREFERENCES);
+    UA_Boolean found = false;
+    UA_StatusCode retval = isNodeInTree(server->nodestore, referenceTypeId,
+                                        &hierarchicalReference, &subtypeId, 1, &found);
+    if(retval != UA_STATUSCODE_GOOD || !found) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                             "AddNodes: Reference type is not hierarchical");
+        return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
+    }
+
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_StatusCode
+Service_AddNodes_existing(UA_Server *server, UA_Session *session, UA_Node *node,
+                          const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
+                          const UA_NodeId *typeDefinition,
+                          UA_InstantiationCallback *instantiationCallback,
+                          UA_NodeId *addedNodeId) {
+    /* Check the namespaceindex */
+    if(node->nodeId.namespaceIndex >= server->namespacesSize) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session, "AddNodes: Namespace invalid");
+        UA_NodeStore_deleteNode(node);
+        return UA_STATUSCODE_BADNODEIDINVALID;
+    }
+
+    /* Fall back to a default typedefinition for variables and objects */
+    const UA_NodeId basedatavariabletype = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
+    const UA_NodeId baseobjecttype = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE);
+    if(node->nodeClass == UA_NODECLASS_VARIABLE ||
+       node->nodeClass == UA_NODECLASS_OBJECT) {
+        if(!typeDefinition || UA_NodeId_isNull(typeDefinition)) {
+            if(node->nodeClass == UA_NODECLASS_VARIABLE)
+                typeDefinition = &basedatavariabletype;
+            else
+                typeDefinition = &baseobjecttype;
+        }
+    }
+
+    /* Check the reference to the parent and the type definition */
+    UA_StatusCode retval = checkParentReference(server, session, node->nodeClass,
+                                                parentNodeId, referenceTypeId, typeDefinition);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_NodeStore_deleteNode(node);
+        return retval;
+    }
+
+    /* Add the node to the nodestore */
+    retval = UA_NodeStore_insert(server->nodestore, node);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                             "AddNodes: Node could not be added to the nodestore "
+                             "with error code 0x%08x", retval);
+        return retval;
+    }
+
+    /* Copy the nodeid if needed */
+    if(addedNodeId) {
+        retval = UA_NodeId_copy(&node->nodeId, addedNodeId);
+        if(retval != UA_STATUSCODE_GOOD)
+            goto remove_node;
+    }
+
+    /* Hierarchical reference back to the parent */
+    UA_AddReferencesItem item;
+    UA_AddReferencesItem_init(&item);
+    item.sourceNodeId = node->nodeId;
+    item.referenceTypeId = *referenceTypeId;
+    item.isForward = false;
+    item.targetNodeId.nodeId = *parentNodeId;
+    retval = Service_AddReferences_single(server, session, &item);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                             "AddNodes: Could not add the reference to the parent");
+        goto remove_node;
+    }
+
+    /* Instantiate variables and objects */
+    if(node->nodeClass == UA_NODECLASS_OBJECT)
+        retval = instantiateObjectNode(server, session, &node->nodeId,
+                                       typeDefinition, instantiationCallback);
+    else if(node->nodeClass == UA_NODECLASS_VARIABLE)
+        retval = instantiateVariableNode(server, session, &node->nodeId,
+                                         typeDefinition, instantiationCallback);
+    if(retval != UA_STATUSCODE_GOOD)
+        goto remove_node;
+
+    /* Custom callback */
+    if(instantiationCallback)
+        instantiationCallback->method(node->nodeId, *typeDefinition,
+                                      instantiationCallback->handle);
+    return UA_STATUSCODE_GOOD;
+
+ remove_node:
+    Service_DeleteNodes_single(server, &adminSession, &node->nodeId, true);
+    return retval;
 }
 
+
 /***********************************************/
 /* Create a node from an attribute description */
 /***********************************************/
@@ -539,11 +547,11 @@ dataTypeNodeFromAttributes(UA_DataTypeNode *dtnode, const UA_DataTypeAttributes
     return UA_STATUSCODE_GOOD;
 }
 
-#define CHECK_ATTRIBUTES(TYPE) do {                                     \
-        if(item->nodeAttributes.content.decoded.type != &UA_TYPES[UA_TYPES_##TYPE]) { \
-            result->statusCode = UA_STATUSCODE_BADNODEATTRIBUTESINVALID; \
-            break;                                                      \
-        } }while(false)
+#define CHECK_ATTRIBUTES(TYPE)                                          \
+    if(item->nodeAttributes.content.decoded.type != &UA_TYPES[UA_TYPES_##TYPE]) { \
+        result->statusCode = UA_STATUSCODE_BADNODEATTRIBUTESINVALID;    \
+        break;                                                          \
+    }
 
 static void
 Service_AddNodes_single(UA_Server *server, UA_Session *session,
@@ -562,42 +570,37 @@ Service_AddNodes_single(UA_Server *server, UA_Session *session,
         result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
         return;
     }
-    result->statusCode = copyStandardAttributes(node, item, item->nodeAttributes.content.decoded.data);
+
+    void *data = item->nodeAttributes.content.decoded.data;
+    result->statusCode = copyStandardAttributes(node, item, data);
     switch(item->nodeClass) {
     case UA_NODECLASS_OBJECT:
         CHECK_ATTRIBUTES(OBJECTATTRIBUTES);
-        result->statusCode |= objectNodeFromAttributes((UA_ObjectNode*)node,
-                                                       item->nodeAttributes.content.decoded.data);
+        result->statusCode |= objectNodeFromAttributes((UA_ObjectNode*)node, data);
         break;
     case UA_NODECLASS_VARIABLE:
         CHECK_ATTRIBUTES(VARIABLEATTRIBUTES);
-        result->statusCode |= variableNodeFromAttributes(server, (UA_VariableNode*)node,
-                                                         item->nodeAttributes.content.decoded.data);
+        result->statusCode |= variableNodeFromAttributes(server, (UA_VariableNode*)node, data);
         break;
     case UA_NODECLASS_OBJECTTYPE:
         CHECK_ATTRIBUTES(OBJECTTYPEATTRIBUTES);
-        result->statusCode |= objectTypeNodeFromAttributes((UA_ObjectTypeNode*)node,
-                                                           item->nodeAttributes.content.decoded.data);
+        result->statusCode |= objectTypeNodeFromAttributes((UA_ObjectTypeNode*)node, data);
         break;
     case UA_NODECLASS_VARIABLETYPE:
         CHECK_ATTRIBUTES(VARIABLETYPEATTRIBUTES);
-        result->statusCode |= variableTypeNodeFromAttributes(server, (UA_VariableTypeNode*)node,
-                                                             item->nodeAttributes.content.decoded.data);
+        result->statusCode |= variableTypeNodeFromAttributes(server, (UA_VariableTypeNode*)node, data);
         break;
     case UA_NODECLASS_REFERENCETYPE:
         CHECK_ATTRIBUTES(REFERENCETYPEATTRIBUTES);
-        result->statusCode |= referenceTypeNodeFromAttributes((UA_ReferenceTypeNode*)node,
-                                                              item->nodeAttributes.content.decoded.data);
+        result->statusCode |= referenceTypeNodeFromAttributes((UA_ReferenceTypeNode*)node, data);
         break;
     case UA_NODECLASS_DATATYPE:
         CHECK_ATTRIBUTES(DATATYPEATTRIBUTES);
-        result->statusCode |= dataTypeNodeFromAttributes((UA_DataTypeNode*)node,
-                                                         item->nodeAttributes.content.decoded.data);
+        result->statusCode |= dataTypeNodeFromAttributes((UA_DataTypeNode*)node, data);
         break;
     case UA_NODECLASS_VIEW:
         CHECK_ATTRIBUTES(VIEWATTRIBUTES);
-        result->statusCode |= viewNodeFromAttributes((UA_ViewNode*)node,
-                                                     item->nodeAttributes.content.decoded.data);
+        result->statusCode |= viewNodeFromAttributes((UA_ViewNode*)node, data);
         break;
     case UA_NODECLASS_METHOD:
     case UA_NODECLASS_UNSPECIFIED:
@@ -1084,7 +1087,8 @@ Service_DeleteNodes_single(UA_Server *server, UA_Session *session,
 void Service_DeleteNodes(UA_Server *server, UA_Session *session,
                          const UA_DeleteNodesRequest *request,
                          UA_DeleteNodesResponse *response) {
-    UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing DeleteNodesRequest");
+    UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                         "Processing DeleteNodesRequest");
     if(request->nodesToDeleteSize == 0) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
         return;
@@ -1169,7 +1173,8 @@ void
 Service_DeleteReferences(UA_Server *server, UA_Session *session,
                          const UA_DeleteReferencesRequest *request,
                          UA_DeleteReferencesResponse *response) {
-    UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing DeleteReferencesRequest");
+    UA_LOG_DEBUG_SESSION(server->config.logger, session,
+                         "Processing DeleteReferencesRequest");
     if(request->referencesToDeleteSize <= 0) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
         return;