瀏覽代碼

used already existing code to create nodes and extended it

FlorianPalm 10 年之前
父節點
當前提交
5f2751188c
共有 3 個文件被更改,包括 304 次插入204 次删除
  1. 16 15
      Makefile
  2. 246 162
      src/server/nodestore/open62541_nodestore_nodemanagement.c
  3. 42 27
      src/server/ua_server.c

+ 16 - 15
Makefile

@@ -1,10 +1,14 @@
 # CMAKE generated file: DO NOT EDIT!
 # CMAKE generated file: DO NOT EDIT!
-# Generated by "Unix Makefiles" Generator, CMake Version 2.8
+# Generated by "Unix Makefiles" Generator, CMake Version 3.1
 
 
 # Default target executed when no arguments are given to make.
 # Default target executed when no arguments are given to make.
 default_target: all
 default_target: all
 .PHONY : default_target
 .PHONY : default_target
 
 
+# Allow only one "make -f Makefile2" at a time, but pass parallelism.
+.NOTPARALLEL:
+.PHONY : .NOTPARALLEL
+
 #=============================================================================
 #=============================================================================
 # Special targets provided by cmake.
 # Special targets provided by cmake.
 
 
@@ -30,30 +34,27 @@ cmake_force:
 SHELL = /bin/sh
 SHELL = /bin/sh
 
 
 # The CMake executable.
 # The CMake executable.
-CMAKE_COMMAND = /usr/bin/cmake
+CMAKE_COMMAND = /usr/local/bin/cmake
 
 
 # The command to remove a file.
 # The command to remove a file.
-RM = /usr/bin/cmake -E remove -f
+RM = /usr/local/bin/cmake -E remove -f
 
 
 # Escaping for special characters.
 # Escaping for special characters.
 EQUALS = =
 EQUALS = =
 
 
-# The program to use to edit the cache.
-CMAKE_EDIT_COMMAND = /usr/bin/cmake-gui
-
 # The top-level source directory on which CMake was run.
 # The top-level source directory on which CMake was run.
-CMAKE_SOURCE_DIR = /home/opcua/Downloads/open62541_external_datasource
+CMAKE_SOURCE_DIR = /home/open62541/Downloads/open62541_ext
 
 
 # The top-level build directory on which CMake was run.
 # The top-level build directory on which CMake was run.
-CMAKE_BINARY_DIR = /home/opcua/Downloads/open62541_external_datasource
+CMAKE_BINARY_DIR = /home/open62541/Downloads/open62541_ext
 
 
 #=============================================================================
 #=============================================================================
 # Targets provided globally by CMake.
 # Targets provided globally by CMake.
 
 
 # Special rule for the target edit_cache
 # Special rule for the target edit_cache
 edit_cache:
 edit_cache:
-	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
-	/usr/bin/cmake-gui -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..."
+	/usr/local/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
 .PHONY : edit_cache
 .PHONY : edit_cache
 
 
 # Special rule for the target edit_cache
 # Special rule for the target edit_cache
@@ -63,7 +64,7 @@ edit_cache/fast: edit_cache
 # Special rule for the target rebuild_cache
 # Special rule for the target rebuild_cache
 rebuild_cache:
 rebuild_cache:
 	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
 	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
-	/usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+	/usr/local/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
 .PHONY : rebuild_cache
 .PHONY : rebuild_cache
 
 
 # Special rule for the target rebuild_cache
 # Special rule for the target rebuild_cache
@@ -72,9 +73,9 @@ rebuild_cache/fast: rebuild_cache
 
 
 # The main all target
 # The main all target
 all: cmake_check_build_system
 all: cmake_check_build_system
-	$(CMAKE_COMMAND) -E cmake_progress_start /home/opcua/Downloads/open62541_external_datasource/CMakeFiles /home/opcua/Downloads/open62541_external_datasource/CMakeFiles/progress.marks
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/open62541/Downloads/open62541_ext/CMakeFiles /home/open62541/Downloads/open62541_ext/CMakeFiles/progress.marks
 	$(MAKE) -f CMakeFiles/Makefile2 all
 	$(MAKE) -f CMakeFiles/Makefile2 all
-	$(CMAKE_COMMAND) -E cmake_progress_start /home/opcua/Downloads/open62541_external_datasource/CMakeFiles 0
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/open62541/Downloads/open62541_ext/CMakeFiles 0
 .PHONY : all
 .PHONY : all
 
 
 # The main clean target
 # The main clean target
@@ -915,10 +916,10 @@ help:
 	@echo "... clean"
 	@echo "... clean"
 	@echo "... depend"
 	@echo "... depend"
 	@echo "... edit_cache"
 	@echo "... edit_cache"
-	@echo "... exampleServer"
+	@echo "... rebuild_cache"
 	@echo "... open62541"
 	@echo "... open62541"
+	@echo "... exampleServer"
 	@echo "... open62541-objects"
 	@echo "... open62541-objects"
-	@echo "... rebuild_cache"
 	@echo "... examples/logger_stdout.o"
 	@echo "... examples/logger_stdout.o"
 	@echo "... examples/logger_stdout.i"
 	@echo "... examples/logger_stdout.i"
 	@echo "... examples/logger_stdout.s"
 	@echo "... examples/logger_stdout.s"

+ 246 - 162
src/server/nodestore/open62541_nodestore_nodemanagement.c

@@ -9,39 +9,160 @@
 #include "open62541_nodestore.h"
 #include "open62541_nodestore.h"
 #include "ua_namespace_0.h"
 #include "ua_namespace_0.h"
 #include "ua_util.h"
 #include "ua_util.h"
-/*
 
 
-    // ReferenceType Ids
-    UA_ExpandedNodeId RefTypeId_References; NS0EXPANDEDNODEID(RefTypeId_References, 31);
-    UA_ExpandedNodeId RefTypeId_NonHierarchicalReferences; NS0EXPANDEDNODEID(RefTypeId_NonHierarchicalReferences, 32);
-    UA_ExpandedNodeId RefTypeId_HierarchicalReferences; NS0EXPANDEDNODEID(RefTypeId_HierarchicalReferences, 33);
-    UA_ExpandedNodeId RefTypeId_HasChild; NS0EXPANDEDNODEID(RefTypeId_HasChild, 34);
-    UA_ExpandedNodeId RefTypeId_Organizes; NS0EXPANDEDNODEID(RefTypeId_Organizes, 35);
-    UA_ExpandedNodeId RefTypeId_HasEventSource; NS0EXPANDEDNODEID(RefTypeId_HasEventSource, 36);
-    UA_ExpandedNodeId RefTypeId_HasModellingRule; NS0EXPANDEDNODEID(RefTypeId_HasModellingRule, 37);
-    UA_ExpandedNodeId RefTypeId_HasEncoding; NS0EXPANDEDNODEID(RefTypeId_HasEncoding, 38);
-    UA_ExpandedNodeId RefTypeId_HasDescription; NS0EXPANDEDNODEID(RefTypeId_HasDescription, 39);
-    UA_ExpandedNodeId RefTypeId_HasTypeDefinition; NS0EXPANDEDNODEID(RefTypeId_HasTypeDefinition, 40);
-    UA_ExpandedNodeId RefTypeId_GeneratesEvent; NS0EXPANDEDNODEID(RefTypeId_GeneratesEvent, 41);
-    UA_ExpandedNodeId RefTypeId_Aggregates; NS0EXPANDEDNODEID(RefTypeId_Aggregates, 44);
-    UA_ExpandedNodeId RefTypeId_HasSubtype; NS0EXPANDEDNODEID(RefTypeId_HasSubtype, 45);
-    UA_ExpandedNodeId RefTypeId_HasProperty; NS0EXPANDEDNODEID(RefTypeId_HasProperty, 46);
-    UA_ExpandedNodeId RefTypeId_HasComponent; NS0EXPANDEDNODEID(RefTypeId_HasComponent, 47);
-    UA_ExpandedNodeId RefTypeId_HasNotifier; NS0EXPANDEDNODEID(RefTypeId_HasNotifier, 48);
-    UA_ExpandedNodeId RefTypeId_HasOrderedComponent; NS0EXPANDEDNODEID(RefTypeId_HasOrderedComponent, 49);
-    UA_ExpandedNodeId RefTypeId_HasModelParent; NS0EXPANDEDNODEID(RefTypeId_HasModelParent, 50);
-    UA_ExpandedNodeId RefTypeId_FromState; NS0EXPANDEDNODEID(RefTypeId_FromState, 51);
-    UA_ExpandedNodeId RefTypeId_ToState; NS0EXPANDEDNODEID(RefTypeId_ToState, 52);
-    UA_ExpandedNodeId RefTypeId_HasCause; NS0EXPANDEDNODEID(RefTypeId_HasCause, 53);
-    UA_ExpandedNodeId RefTypeId_HasEffect; NS0EXPANDEDNODEID(RefTypeId_HasEffect, 54);
-    UA_ExpandedNodeId RefTypeId_HasHistoricalConfiguration; NS0EXPANDEDNODEID(RefTypeId_HasHistoricalConfiguration, 56);
-
-*/
+
+static UA_Int32 AddSingleReference(UA_Node *node, UA_ReferenceNode *reference) {
+	// TODO: Check if reference already exists
+	UA_Int32 count = node->referencesSize;
+	UA_ReferenceNode *old_refs = node->references;
+	UA_ReferenceNode *new_refs;
+
+	if (count < 0)
+		count = 0;
+
+	if (!(new_refs = UA_alloc(sizeof(UA_ReferenceNode) * (count + 1))))
+		return UA_STATUSCODE_BADOUTOFMEMORY;
+
+	UA_memcpy(new_refs, old_refs, sizeof(UA_ReferenceNode) * count);
+	if (UA_ReferenceNode_copy(reference, &new_refs[count])
+			!= UA_STATUSCODE_GOOD) {
+		UA_free(new_refs);
+		return UA_STATUSCODE_BADOUTOFMEMORY;
+	}
+
+	node->references = new_refs;
+	node->referencesSize = count + 1;
+	UA_free(old_refs);
+	return UA_STATUSCODE_GOOD;
+}
+
+static UA_Int32 AddReference(UA_NodeStoreExample *nodestore, UA_Node *node,
+		UA_ReferenceNode *reference) {
+	UA_Int32 retval = AddSingleReference(node, reference);
+	UA_Node *targetnode;
+	UA_ReferenceNode inversereference;
+	if (retval != UA_STATUSCODE_GOOD || nodestore == UA_NULL)
+		return retval;
+
+	// Do a copy every time?
+	if (UA_NodeStoreExample_get(nodestore, &reference->targetId.nodeId,
+			(const UA_Node **) &targetnode) != UA_STATUSCODE_GOOD)
+		return UA_STATUSCODE_BADINTERNALERROR;
+
+	inversereference.referenceTypeId = reference->referenceTypeId;
+	inversereference.isInverse = !reference->isInverse;
+	inversereference.targetId.nodeId = node->nodeId;
+	inversereference.targetId.namespaceUri = UA_STRING_NULL;
+	inversereference.targetId.serverIndex = 0;
+	retval = AddSingleReference(targetnode, &inversereference);
+	UA_NodeStoreExample_releaseManagedNode(targetnode);
+
+	return retval;
+}
+
+//TODO export to types, maybe?
+void UA_String_setToNULL(UA_String* string){
+	string->data = NULL;
+	string->length = -1;
+}
+
+void UA_Node_setAttributes(UA_NodeAttributes *nodeAttributes, UA_Node *node){
+
+	if(nodeAttributes->specifiedAttributes & UA_ATTRIBUTEID_DISPLAYNAME){
+		node->displayName =  nodeAttributes->displayName;
+		UA_String_setToNULL(&nodeAttributes->displayName.locale);
+		UA_String_setToNULL(&nodeAttributes->displayName.text);
+	}
+	if(nodeAttributes->specifiedAttributes & UA_ATTRIBUTEID_DESCRIPTION){
+		node->description =  nodeAttributes->description;
+		UA_String_setToNULL(&nodeAttributes->description.locale);
+		UA_String_setToNULL(&nodeAttributes->description.text);
+	}
+	if(nodeAttributes->specifiedAttributes & UA_ATTRIBUTEID_WRITEMASK){
+			node->writeMask = nodeAttributes->writeMask;
+	}
+	if(nodeAttributes->specifiedAttributes & UA_ATTRIBUTEID_USERWRITEMASK){
+		node->userWriteMask = nodeAttributes->userWriteMask;
+	}
+}
+void UA_ObjectNode_setAttributes(UA_ObjectAttributes *objectAttributes, UA_ObjectNode *node){
+	UA_Node_setAttributes((UA_NodeAttributes*)objectAttributes,(UA_Node*)node);
+
+	if(objectAttributes->specifiedAttributes & UA_ATTRIBUTEID_EVENTNOTIFIER){
+			node->eventNotifier = objectAttributes->eventNotifier;
+	}
+}
+
+void UA_ReferenceTypeNode_setAttributes(UA_ReferenceTypeAttributes *referenceTypeAttributes, UA_ReferenceTypeNode *node){
+	UA_Node_setAttributes((UA_NodeAttributes*)referenceTypeAttributes,(UA_Node*)node);
+
+	if(referenceTypeAttributes->specifiedAttributes & UA_ATTRIBUTEID_ISABSTRACT){
+			node->isAbstract = referenceTypeAttributes->isAbstract;
+	}
+	if(referenceTypeAttributes->specifiedAttributes & UA_ATTRIBUTEID_SYMMETRIC){
+				node->symmetric = referenceTypeAttributes->symmetric;
+	}
+	if(referenceTypeAttributes->specifiedAttributes & UA_ATTRIBUTEID_INVERSENAME){
+		node->inverseName = referenceTypeAttributes->inverseName;
+		UA_String_setToNULL(&referenceTypeAttributes->inverseName.locale);
+		UA_String_setToNULL(&referenceTypeAttributes->inverseName.text);
+	}
+}
+void UA_ObjectTypeNode_setAttributes(UA_ObjectTypeAttributes *objectTypeAttributes, UA_ObjectTypeNode *node){
+	UA_Node_setAttributes((UA_NodeAttributes*)objectTypeAttributes,(UA_Node*)node);
+
+	if(objectTypeAttributes->specifiedAttributes & UA_ATTRIBUTEID_ISABSTRACT){
+			node->isAbstract = objectTypeAttributes->isAbstract;
+	}
+}
+
+void UA_VariableNode_setAttributes(UA_VariableAttributes *variableAttributes, UA_VariableNode *node){
+	UA_Node_setAttributes((UA_NodeAttributes*)variableAttributes,(UA_Node*)node);
+
+	if(variableAttributes->specifiedAttributes & UA_ATTRIBUTEID_VALUE){
+			UA_Variant_copy(&variableAttributes->value,&node->value);
+	}
+	if(variableAttributes->specifiedAttributes & UA_ATTRIBUTEID_DATATYPE){
+				UA_NodeId_copy(&variableAttributes->dataType,&node->dataType);
+	}
+	if(variableAttributes->specifiedAttributes & UA_ATTRIBUTEID_VALUERANK){
+		node->valueRank = variableAttributes->valueRank;
+	}
+	if(variableAttributes->specifiedAttributes & UA_ATTRIBUTEID_ARRAYDIMENSIONS){
+		node->arrayDimensions = variableAttributes->arrayDimensions;
+		variableAttributes->arrayDimensions = NULL;
+	}
+	if(variableAttributes->specifiedAttributes & UA_ATTRIBUTEID_ACCESSLEVEL){
+		node->accessLevel = variableAttributes->accessLevel;
+	}
+	if(variableAttributes->specifiedAttributes & UA_ATTRIBUTEID_USERACCESSLEVEL){
+		node->userAccessLevel = variableAttributes->userAccessLevel;
+	}
+	if(variableAttributes->specifiedAttributes & UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL){
+		node->minimumSamplingInterval = variableAttributes->minimumSamplingInterval;
+	}
+	if(variableAttributes->specifiedAttributes & UA_ATTRIBUTEID_HISTORIZING){
+		node->historizing = variableAttributes->historizing;
+	}
+}
+void UA_ViewNode_setAttributes(UA_ViewAttributes *viewAttributes, UA_ViewNode *node){
+	UA_Node_setAttributes((UA_NodeAttributes*)viewAttributes,(UA_Node*)node);
+	if(viewAttributes->specifiedAttributes & UA_ATTRIBUTEID_CONTAINSNOLOOPS){
+			node->containsNoLoops = viewAttributes->containsNoLoops;
+	}
+	if(viewAttributes->specifiedAttributes & UA_ATTRIBUTEID_EVENTNOTIFIER){
+				node->eventNotifier = viewAttributes->eventNotifier;
+	}
+}
+void open62541Nodestore_getNewNodeId(UA_ExpandedNodeId *requestedNodeId){
+	//check nodeId here
+	return;
+}
+
 UA_Int32 open62541NodeStore_addReferences(UA_AddReferencesItem* referencesToAdd,
 UA_Int32 open62541NodeStore_addReferences(UA_AddReferencesItem* referencesToAdd,
 		UA_UInt32 *indices,UA_UInt32 indicesSize, UA_StatusCode *addReferencesResults,
 		UA_UInt32 *indices,UA_UInt32 indicesSize, UA_StatusCode *addReferencesResults,
 		UA_DiagnosticInfo *diagnosticInfos)
 		UA_DiagnosticInfo *diagnosticInfos)
 {
 {
-
 	for(UA_UInt32 i = 0;i<indicesSize;i++){
 	for(UA_UInt32 i = 0;i<indicesSize;i++){
 		UA_Node *node = UA_NULL;
 		UA_Node *node = UA_NULL;
 		UA_NodeStoreExample *ns = Nodestore_get();
 		UA_NodeStoreExample *ns = Nodestore_get();
@@ -68,156 +189,119 @@ UA_Int32 open62541NodeStore_addReferences(UA_AddReferencesItem* referencesToAdd,
 	    UA_NodeId_copy(&referencesToAdd[indices[i]].referenceTypeId,&reference->referenceTypeId);
 	    UA_NodeId_copy(&referencesToAdd[indices[i]].referenceTypeId,&reference->referenceTypeId);
 	    UA_ExpandedNodeId_copy(&referencesToAdd[indices[i]].targetNodeId,&reference->targetId);
 	    UA_ExpandedNodeId_copy(&referencesToAdd[indices[i]].targetNodeId,&reference->targetId);
 
 
-	    if(UA_ReferenceNode_copy(reference, &new_refs[count]) != UA_STATUSCODE_GOOD) {
-	        UA_free(new_refs);
-	        addReferencesResults[indices[i]] = UA_STATUSCODE_BADOUTOFMEMORY;
-	    }
-	    node->references     = new_refs;
-	    node->referencesSize = count+1;
-	    UA_free(old_refs);
-	    addReferencesResults[indices[i]] =  UA_STATUSCODE_GOOD;
+	    addReferencesResults[indices[i]] =  AddReference(ns,node,reference);
 	    UA_ReferenceNode_delete(reference); //FIXME to be removed
 	    UA_ReferenceNode_delete(reference); //FIXME to be removed
 	    //TODO fill diagnostic info if needed
 	    //TODO fill diagnostic info if needed
 	}
 	}
 
 
 	return UA_STATUSCODE_GOOD;
 	return UA_STATUSCODE_GOOD;
 }
 }
-
+UA_Boolean isRootNode(UA_NodeId *nodeId){
+	return nodeId->identifierType == UA_NODEIDTYPE_NUMERIC && nodeId->namespaceIndex == 0 && nodeId->identifier.numeric == 84;
+}
 UA_Int32 open62541Nodestore_addNodes(UA_AddNodesItem *nodesToAdd,UA_UInt32 *indices,
 UA_Int32 open62541Nodestore_addNodes(UA_AddNodesItem *nodesToAdd,UA_UInt32 *indices,
 		UA_UInt32 indicesSize, UA_AddNodesResult* addNodesResults,
 		UA_UInt32 indicesSize, UA_AddNodesResult* addNodesResults,
 		UA_DiagnosticInfo *diagnosticInfos){
 		UA_DiagnosticInfo *diagnosticInfos){
 
 
 	UA_Node *node = UA_NULL;
 	UA_Node *node = UA_NULL;
 	for(UA_UInt32 i=0;i<indicesSize;i++){
 	for(UA_UInt32 i=0;i<indicesSize;i++){
+
+		const UA_Node *parent;
+		//todo what if node is in another namespace, readrequest to test, if it exists?
 		UA_NodeStoreExample *ns = Nodestore_get();
 		UA_NodeStoreExample *ns = Nodestore_get();
+		if (UA_NodeStoreExample_get(ns, &nodesToAdd->parentNodeId.nodeId,
+				&parent) != UA_STATUSCODE_GOOD && !isRootNode(&nodesToAdd->parentNodeId.nodeId)) {
+			addNodesResults[indices[i]].statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID;
+			continue;
+		}
+
+
 		UA_NodeStoreExample_get((const UA_NodeStoreExample*)ns, (const UA_NodeId*)&nodesToAdd[indices[i]].requestedNewNodeId.nodeId , (const UA_Node**)&node);
 		UA_NodeStoreExample_get((const UA_NodeStoreExample*)ns, (const UA_NodeId*)&nodesToAdd[indices[i]].requestedNewNodeId.nodeId , (const UA_Node**)&node);
-		if(node==UA_NULL){
-			switch(nodesToAdd[indices[i]].nodeClass){
-				case UA_NODECLASS_DATATYPE:
-				{
-					break;
-				}
-				case UA_NODECLASS_METHOD:
-				{
-
-					break;
-				}
-				case UA_NODECLASS_OBJECT:
-				{
-					UA_ObjectNode *newNode;
-					UA_ObjectNode_new(&newNode);
-					newNode->nodeId    = nodesToAdd[indices[i]].requestedNewNodeId.nodeId;
-					newNode->nodeClass = nodesToAdd[indices[i]].nodeClass;
-					UA_QualifiedName_copy(&nodesToAdd[indices[i]].browseName, &newNode->browseName);
-
-					UA_UInt32 offset = 0;
-					UA_ObjectAttributes objType;
-
-					UA_ObjectAttributes_decodeBinary(&nodesToAdd[indices[i]].nodeAttributes.body,&offset,&objType);
-					if(objType.specifiedAttributes & UA_ATTRIBUTEID_DISPLAYNAME){
-						UA_LocalizedText_copy(&objType.displayName, &newNode->displayName);
-					}
-
-					if(objType.specifiedAttributes & UA_ATTRIBUTEID_DESCRIPTION){
-						UA_LocalizedText_copy(&objType.description, &newNode->description);
-					}
-					if(objType.specifiedAttributes & UA_ATTRIBUTEID_EVENTNOTIFIER){
-						newNode->eventNotifier =  objType.eventNotifier;
-					}
-					if(objType.specifiedAttributes & UA_ATTRIBUTEID_WRITEMASK){
-						newNode->writeMask = objType.writeMask;
-					}
-
-					UA_AddReferencesItem addRefItem;
-					addRefItem.isForward = UA_TRUE;
-
-					addRefItem.referenceTypeId = nodesToAdd[indices[i]].referenceTypeId;
-					addRefItem.sourceNodeId =  nodesToAdd[indices[i]].parentNodeId.nodeId;
-					addRefItem.targetNodeId.nodeId = newNode->nodeId;
-					addRefItem.targetNodeId.namespaceUri.length = 0;
-					addRefItem.targetServerUri.length = 0;
-					addRefItem.targetNodeClass = newNode->nodeClass;
-
-					UA_UInt32 ind = 0;
-					UA_UInt32 indSize = 1;
-					UA_StatusCode result;
-					UA_DiagnosticInfo diagnosticInfo;
-					UA_NodeStoreExample_insert(ns, (UA_Node**)&newNode, UA_NODESTORE_INSERT_UNIQUE);
-					if(!(
-							nodesToAdd[indices[i]].requestedNewNodeId.nodeId.identifier.numeric == 84 &&
-							nodesToAdd[indices[i]].requestedNewNodeId.nodeId.namespaceIndex ==  0)){
-						open62541NodeStore_addReferences(&addRefItem, &ind, indSize, &result, &diagnosticInfo);
-					}
-					break;
-				}
-				case UA_NODECLASS_OBJECTTYPE:
-				{
-
-					break;
-				}
-				case UA_NODECLASS_REFERENCETYPE:
-				{
-					UA_ReferenceTypeNode *newNode;
-					UA_ReferenceTypeNode_new(&newNode);
-					newNode->nodeId    = nodesToAdd[indices[i]].requestedNewNodeId.nodeId;
-					newNode->nodeClass = nodesToAdd[indices[i]].nodeClass;
-					UA_QualifiedName_copy(&nodesToAdd[indices[i]].browseName, &newNode->browseName);
-					UA_UInt32 offset = 0;
-					UA_ReferenceTypeAttributes refType;
-					UA_ReferenceTypeAttributes_decodeBinary(&nodesToAdd[indices[i]].nodeAttributes.body,&offset,&refType);
-					if(refType.specifiedAttributes & UA_ATTRIBUTEID_DISPLAYNAME){
-						UA_LocalizedText_copy(&refType.displayName, &newNode->displayName);
-					}
-
-					if(refType.specifiedAttributes & UA_ATTRIBUTEID_DESCRIPTION){
-						UA_LocalizedText_copy(&refType.description, &newNode->description);
-					}
-
-					if(refType.specifiedAttributes & UA_ATTRIBUTEID_ISABSTRACT){
-						newNode->isAbstract = refType.isAbstract;
-					}
-
-					if(refType.specifiedAttributes & UA_ATTRIBUTEID_SYMMETRIC){
-						newNode->symmetric = refType.symmetric;
-					}
-					//ADDREFERENCE(haschild, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HierarchicalReferences);
-
-					UA_AddReferencesItem addRefItem;
-					addRefItem.isForward = UA_TRUE;
-
-					addRefItem.referenceTypeId = nodesToAdd[indices[i]].referenceTypeId;
-					addRefItem.sourceNodeId =  nodesToAdd[indices[i]].parentNodeId.nodeId;
-					addRefItem.targetNodeId.nodeId = newNode->nodeId;
-					addRefItem.targetNodeId.namespaceUri.length = 0;
-					addRefItem.targetServerUri.length = 0;
-					addRefItem.targetNodeClass = newNode->nodeClass;
-
-					UA_UInt32 ind = 0;
-					UA_UInt32 indSize = 1;
-					UA_StatusCode result;
-					UA_DiagnosticInfo diagnosticInfo;
-					UA_NodeStoreExample_insert(ns, (UA_Node**)&newNode, UA_NODESTORE_INSERT_UNIQUE);
-					open62541NodeStore_addReferences(&addRefItem, &ind, indSize, &result, &diagnosticInfo);
-
-
-					break;
-				}
-				case UA_NODECLASS_VARIABLE:
-				{
-
-					break;
-				}
-				case UA_NODECLASS_VARIABLETYPE:
-				{
-
-					break;
-				}
-				default:
-				{
-					break;
-				}
+
+
+		if(node!=UA_NULL){
+			//todo or overwrite existing node?
+			continue;
+		}
+		UA_Node *newNode = UA_NULL;
+		UA_UInt32 offset = 0;
+		switch(nodesToAdd[indices[i]].nodeClass){
+			case UA_NODECLASS_DATATYPE:
+			{
+				continue;
+				break;
+			}
+			case UA_NODECLASS_METHOD:
+			{
+				continue;
+				break;
+			}
+			case UA_NODECLASS_OBJECT:
+			{
+				UA_ObjectAttributes attributes;
+				UA_ObjectNode_new((UA_ObjectNode**)&newNode);
+				UA_ObjectAttributes_decodeBinary(&nodesToAdd[indices[i]].nodeAttributes.body,&offset,&attributes);
+				UA_ObjectNode_setAttributes((UA_ObjectAttributes*)&attributes, (UA_ObjectNode*)newNode);
+				break;
+			}
+			case UA_NODECLASS_OBJECTTYPE:
+			{
+				continue;
+				break;
+			}
+			case UA_NODECLASS_REFERENCETYPE:
+			{
+				UA_ReferenceTypeAttributes attributes;
+				UA_ReferenceTypeNode_new((UA_ReferenceTypeNode**)&newNode);
+				UA_ReferenceTypeAttributes_decodeBinary(&nodesToAdd[indices[i]].nodeAttributes.body,&offset,&attributes);
+				UA_ReferenceTypeNode_setAttributes((UA_ReferenceTypeAttributes*)&attributes,(UA_ReferenceTypeNode*)newNode);
+				break;
 			}
 			}
+			case UA_NODECLASS_VARIABLE:
+			{
+				continue;
+				break;
+			}
+			case UA_NODECLASS_VARIABLETYPE:
+			{
+				continue;
+				break;
+			}
+			default:
+			{
+				continue;
+				break;
+			}
+
 		}
 		}
+		open62541Nodestore_getNewNodeId(&nodesToAdd[indices[i]].requestedNewNodeId);
+					newNode->nodeId    = nodesToAdd[indices[i]].requestedNewNodeId.nodeId;
+		UA_QualifiedName_copy(&nodesToAdd[indices[i]].browseName,
+				&newNode->browseName);
+
+		UA_AddReferencesItem addRefItem;
+		addRefItem.isForward = UA_TRUE;
+		addRefItem.referenceTypeId = nodesToAdd[indices[i]].referenceTypeId;
+		addRefItem.sourceNodeId = nodesToAdd[indices[i]].parentNodeId.nodeId;
+		addRefItem.targetNodeId.nodeId = newNode->nodeId;
+		addRefItem.targetNodeId.namespaceUri.length = 0;
+		addRefItem.targetServerUri.length = 0;
+		addRefItem.targetNodeClass = newNode->nodeClass;
+
+		UA_UInt32 ind = 0;
+		UA_UInt32 indSize = 1;
+		UA_StatusCode result;
+		UA_DiagnosticInfo diagnosticInfo;
+		UA_NodeStoreExample_insert(ns, (UA_Node**) &newNode,
+				UA_NODESTORE_INSERT_UNIQUE);
+		if (!(nodesToAdd[indices[i]].requestedNewNodeId.nodeId.identifier.numeric
+				== 84
+				&& nodesToAdd[indices[i]].requestedNewNodeId.nodeId.namespaceIndex
+						== 0)) {
+			open62541NodeStore_addReferences(&addRefItem, &ind, indSize,
+					&result, &diagnosticInfo);
+		}
+
 	}
 	}
 	return UA_STATUSCODE_GOOD;
 	return UA_STATUSCODE_GOOD;
 }
 }

+ 42 - 27
src/server/ua_server.c

@@ -37,8 +37,6 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_NodeId_init(&server->hasComponentReferenceTypeId);
     UA_NodeId_init(&server->hasComponentReferenceTypeId);
     server->hasComponentReferenceTypeId.identifier.numeric = 47;
     server->hasComponentReferenceTypeId.identifier.numeric = 47;
 
 
-
-
     UA_ApplicationDescription_init(&server->description);
     UA_ApplicationDescription_init(&server->description);
     UA_ByteString_init(&server->serverCertificate);
     UA_ByteString_init(&server->serverCertificate);
 #define MAXCHANNELCOUNT 100
 #define MAXCHANNELCOUNT 100
@@ -88,18 +86,14 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_ExpandedNodeId RefTypeId_HasHistoricalConfiguration; NS0EXPANDEDNODEID(RefTypeId_HasHistoricalConfiguration, 56);
     UA_ExpandedNodeId RefTypeId_HasHistoricalConfiguration; NS0EXPANDEDNODEID(RefTypeId_HasHistoricalConfiguration, 56);
 
 
 
 
-#define ADD_OBJECTNODE_NSO(REFTYPE_NODEID,REQ_NODEID_NUMERIC_IDENTIFIER,PARENTNODEID_NUMERIC_IDENTIFIER,BROWSENAME,DISPLAYNAME,DESCRIPTION) do{ \
+#define ADD_OBJECTNODE_NSO(REFTYPE_NODEID,REQ_NODEID,PARENTNODEID,BROWSENAME,DISPLAYNAME,DESCRIPTION) do{ \
 	    UA_ObjectAttributes objAttr;\
 	    UA_ObjectAttributes objAttr;\
 	    UA_AddNodesItem addNodesItem;\
 	    UA_AddNodesItem addNodesItem;\
 	    UA_Namespace *ns0 = UA_NULL;\
 	    UA_Namespace *ns0 = UA_NULL;\
 	    UA_NamespaceManager_getNamespace(server->namespaceManager,0,&ns0); \
 	    UA_NamespaceManager_getNamespace(server->namespaceManager,0,&ns0); \
-	    addNodesItem.parentNodeId.nodeId.identifier.numeric = PARENTNODEID_NUMERIC_IDENTIFIER;\
-	    addNodesItem.parentNodeId.nodeId.namespaceIndex = 0; \
-    	addNodesItem.parentNodeId.nodeId.identifierType = UA_NODEIDTYPE_NUMERIC; \
-	    addNodesItem.requestedNewNodeId.nodeId.identifier.numeric = REQ_NODEID_NUMERIC_IDENTIFIER;\
-	    addNodesItem.requestedNewNodeId.nodeId.namespaceIndex = 0;\
-	    addNodesItem.requestedNewNodeId.nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;\
-	    addNodesItem.referenceTypeId = RefTypeId_Organizes.nodeId;\
+	    addNodesItem.parentNodeId = PARENTNODEID;;\
+	    addNodesItem.requestedNewNodeId = REQ_NODEID;\
+	    addNodesItem.referenceTypeId = REFTYPE_NODEID;\
 	    addNodesItem.nodeClass = UA_NODECLASS_OBJECT;\
 	    addNodesItem.nodeClass = UA_NODECLASS_OBJECT;\
 	    UA_QualifiedName_copycstring(BROWSENAME, &addNodesItem.browseName);\
 	    UA_QualifiedName_copycstring(BROWSENAME, &addNodesItem.browseName);\
 	    UA_LocalizedText_copycstring(DISPLAYNAME, &objAttr.displayName);\
 	    UA_LocalizedText_copycstring(DISPLAYNAME, &objAttr.displayName);\
@@ -156,12 +150,42 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     } while(0)
     } while(0)
 
 
 
 
-    UA_ExpandedNodeId rootNode;
-    NS0EXPANDEDNODEID(rootNode, 84);
 
 
-    ADD_OBJECTNODE_NSO(RefTypeId_Organizes.nodeId,84,0,"Root","Root","Root");
-	ADD_REFTYPENODE_NS0(RefTypeId_Organizes.nodeId,RefTypeId_References,rootNode,
-		"References","References","References",UA_TRUE,UA_TRUE);
+
+    // ObjectTypes (Ids only)
+    UA_ExpandedNodeId ObjTypeId_FolderType; NS0EXPANDEDNODEID(ObjTypeId_FolderType, 61);
+
+    // Objects (Ids only)
+    UA_ExpandedNodeId ObjId_Null; NS0EXPANDEDNODEID(ObjId_Null, 0);
+    UA_ExpandedNodeId ObjId_Root; NS0EXPANDEDNODEID(ObjId_Root, 84);
+    UA_ExpandedNodeId ObjId_ObjectsFolder; NS0EXPANDEDNODEID(ObjId_ObjectsFolder, 85);
+    UA_ExpandedNodeId ObjId_TypesFolder; NS0EXPANDEDNODEID(ObjId_TypesFolder, 86);
+    UA_ExpandedNodeId ObjId_ViewsFolder; NS0EXPANDEDNODEID(ObjId_ViewsFolder, 87);
+    UA_ExpandedNodeId ObjId_ReferenceTypesFolder; NS0EXPANDEDNODEID(ObjId_ReferenceTypesFolder, 91);
+    UA_ExpandedNodeId ObjId_Server; NS0EXPANDEDNODEID(ObjId_Server, 2253);
+    UA_ExpandedNodeId ObjId_ServerArray; NS0EXPANDEDNODEID(ObjId_ServerArray, 2254);
+    UA_ExpandedNodeId ObjId_NamespaceArray; NS0EXPANDEDNODEID(ObjId_NamespaceArray, 2255);
+    UA_ExpandedNodeId ObjId_ServerStatus; NS0EXPANDEDNODEID(ObjId_ServerStatus, 2256);
+    UA_ExpandedNodeId ObjId_ServerCapabilities; NS0EXPANDEDNODEID(ObjId_ServerCapabilities, 2268);
+    UA_ExpandedNodeId ObjId_State; NS0EXPANDEDNODEID(ObjId_State, 2259);
+
+
+
+
+    ADD_OBJECTNODE_NSO(RefTypeId_Organizes.nodeId,ObjId_Root,ObjId_Null,"Root","Root","Root");
+
+    ADD_OBJECTNODE_NSO(RefTypeId_Organizes.nodeId,ObjId_ObjectsFolder,ObjId_Root,"Objects","Objects","Objects");
+
+    ADD_OBJECTNODE_NSO(RefTypeId_Organizes.nodeId,ObjId_TypesFolder,ObjId_Root,"Types","Types","Types");
+
+    	ADD_OBJECTNODE_NSO(RefTypeId_Organizes.nodeId,ObjId_TypesFolder,ObjId_Root,"Types","Types","Types");
+    		ADD_OBJECTNODE_NSO(RefTypeId_Organizes.nodeId,ObjId_ReferenceTypesFolder,ObjId_TypesFolder,"ReferenceTypes","ReferenceTypes","ReferenceTypes");
+    			ADD_REFTYPENODE_NS0(RefTypeId_Organizes.nodeId,RefTypeId_References,ObjId_ReferenceTypesFolder,
+    				"References","References","References",UA_TRUE,UA_TRUE);
+
+    	ADD_OBJECTNODE_NSO(RefTypeId_Organizes.nodeId,ObjId_ViewsFolder,ObjId_Root,"Views","Views","Views");
+
+
     	ADD_REFTYPENODE_NS0(RefTypeId_HasSubtype.nodeId,RefTypeId_NonHierarchicalReferences,RefTypeId_References,
     	ADD_REFTYPENODE_NS0(RefTypeId_HasSubtype.nodeId,RefTypeId_NonHierarchicalReferences,RefTypeId_References,
     		"NonHierarchicalReferences","NonHierarchicalReferences","NonHierarchicalReferences",UA_TRUE,UA_TRUE);
     		"NonHierarchicalReferences","NonHierarchicalReferences","NonHierarchicalReferences",UA_TRUE,UA_TRUE);
 
 
@@ -212,6 +236,9 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     	    				"Organizes","Organizes","Organizes",UA_TRUE,UA_TRUE);
     	    				"Organizes","Organizes","Organizes",UA_TRUE,UA_TRUE);
 
 
 
 
+
+
+
     		/*UA_ReferenceTypeNode *references;
     		/*UA_ReferenceTypeNode *references;
     UA_ReferenceTypeNode_new(&references);
     UA_ReferenceTypeNode_new(&references);
     references->nodeId    = RefTypeId_References.nodeId;
     references->nodeId    = RefTypeId_References.nodeId;
@@ -513,19 +540,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hashistoricalconfiguration, UA_NODESTORE_INSERT_UNIQUE);
     UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hashistoricalconfiguration, UA_NODESTORE_INSERT_UNIQUE);
 
 
 */
 */
-    // ObjectTypes (Ids only)
-    UA_ExpandedNodeId ObjTypeId_FolderType; NS0EXPANDEDNODEID(ObjTypeId_FolderType, 61);
 
 
-    // Objects (Ids only)
-    UA_ExpandedNodeId ObjId_ObjectsFolder; NS0EXPANDEDNODEID(ObjId_ObjectsFolder, 85);
-    UA_ExpandedNodeId ObjId_TypesFolder; NS0EXPANDEDNODEID(ObjId_TypesFolder, 86);
-    UA_ExpandedNodeId ObjId_ViewsFolder; NS0EXPANDEDNODEID(ObjId_ViewsFolder, 87);
-    UA_ExpandedNodeId ObjId_Server; NS0EXPANDEDNODEID(ObjId_Server, 2253);
-    UA_ExpandedNodeId ObjId_ServerArray; NS0EXPANDEDNODEID(ObjId_ServerArray, 2254);
-    UA_ExpandedNodeId ObjId_NamespaceArray; NS0EXPANDEDNODEID(ObjId_NamespaceArray, 2255);
-    UA_ExpandedNodeId ObjId_ServerStatus; NS0EXPANDEDNODEID(ObjId_ServerStatus, 2256);
-    UA_ExpandedNodeId ObjId_ServerCapabilities; NS0EXPANDEDNODEID(ObjId_ServerCapabilities, 2268);
-    UA_ExpandedNodeId ObjId_State; NS0EXPANDEDNODEID(ObjId_State, 2259);
 
 
     // FolderType
     // FolderType
     UA_ObjectNode *folderType;
     UA_ObjectNode *folderType;