Przeglądaj źródła

Merge remote-tracking branch 'origin/master' into external_datasource

Conflicts:
	CMakeLists.txt
	examples/opcuaClient.c
	examples/opcuaServer.c
	include/ua_server.h
	src/server/ua_nodestore.c
	src/server/ua_nodestore.h
	src/server/ua_server.c
	src/server/ua_services_attribute.c
	src/server/ua_services_internal.h
	src/server/ua_services_nodemanagement.c
	src/server/ua_services_view.c
FlorianPalm 10 lat temu
rodzic
commit
82a92dbb05
42 zmienionych plików z 948 dodań i 1517 usunięć
  1. 12 8
      CMakeLists.txt
  2. 0 27
      Makefile
  3. 22 18
      README.md
  4. 15 16
      examples/networklayer_tcp.c
  5. 1 5
      examples/networklayer_tcp.h
  6. 125 190
      examples/opcuaClient.c
  7. 27 33
      examples/opcuaServer.c
  8. 3 6
      examples/ua_nodestore_concurrent.c
  9. 4 26
      include/ua_server.h
  10. 35 44
      include/ua_types.h
  11. 0 0
      src/ongoing/ua_services_monitoreditems.c
  12. 26 26
      src/server/nodestore/open62541_nodestore_attribute.c
  13. 2 2
      src/server/nodestore/open62541_nodestore_core.c
  14. 5 5
      src/server/nodestore/open62541_nodestore_nodemanagement.c
  15. 179 153
      src/server/nodestore/open62541_nodestore_view.c
  16. 3 2
      src/server/ua_namespace_manager.c
  17. 5 5
      src/server/ua_namespace_manager.h
  18. 21 29
      src/server/ua_securechannel_manager.c
  19. 16 4
      src/server/ua_securechannel_manager.h
  20. 92 598
      src/server/ua_server.c
  21. 7 8
      src/server/ua_server_binary.c
  22. 21 0
      src/server/ua_server_internal.h
  23. 33 33
      src/server/ua_services_attribute.c
  24. 11 31
      src/server/ua_services_discovery.c
  25. 11 11
      src/server/ua_services_nodemanagement.c
  26. 5 4
      src/server/ua_services_securechannel.c
  27. 11 7
      src/server/ua_services_session.c
  28. 6 6
      src/server/ua_services_view.c
  29. 10 22
      src/server/ua_session_manager.c
  30. 12 2
      src/server/ua_session_manager.h
  31. 5 7
      src/ua_session.c
  32. 1 1
      src/ua_session.h
  33. 0 11
      src/ua_transport.h
  34. 43 38
      src/ua_types.c
  35. 16 16
      src/ua_types_encoding_binary.c
  36. 8 0
      src/ua_util.h
  37. 1 1
      tests/CMakeLists.txt
  38. 35 28
      tests/check_builtin.c
  39. 39 44
      tests/check_memory.c
  40. 13 13
      tests/check_nodestore.c
  41. 17 12
      tools/generate_builtin.py
  42. 50 25
      tools/generate_namespace.py

+ 12 - 8
CMakeLists.txt

@@ -11,6 +11,7 @@ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG")
 # main sources of libopen62541
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src")
+file(GLOB_RECURSE exported_headers "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
 file(GLOB_RECURSE headers "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
 file(GLOB generated_headers "${PROJECT_BINARY_DIR}/src_generated/*.h")
 set(lib_sources src/ua_types.c
@@ -34,14 +35,14 @@ set(lib_sources src/ua_types.c
                 src/server/ua_services_securechannel.c
                 src/server/ua_services_nodemanagement.c
                 src/server/ua_services_view.c
-                src/server/ua_services_monitoreditems.c
 				src/server/nodestore/open62541_nodestore_view.c
 				src/server/nodestore/open62541_nodestore_attribute.c
 				src/server/nodestore/open62541_nodestore_nodemanagement.c
 				src/server/nodestore/open62541_nodestore_core.c
 				src/server/ua_nodestore_interface.c
-                ${headers}
-                ${generated_headers})
+				${exported_headers}
+				${generated_headers}
+                ${headers})
 
 # compiler flags
 if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
@@ -49,13 +50,14 @@ add_definitions(-std=c99 -pedantic -pipe -Wall -Wextra -Werror -Wformat
                 -Wno-unused-parameter -Wno-unused-function -Wno-unused-label -Wpointer-arith -Wreturn-type -Wsign-compare -Wmultichar
                 -Winit-self -Wuninitialized -Wno-deprecated -Wformat-security -ffunction-sections -fdata-sections)
     if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
-        add_definitions(-Wformat-nonliteral -Wl,--gc-sections)
+        add_definitions(-Wformat-nonliteral)
+        set (CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--gc-sections")
+        set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
     endif()
 	if(NOT WIN32)
 	    add_definitions(-fstack-protector -fPIC -fvisibility=hidden)
 	endif()
 endif()
-add_definitions(-Dopen62541_EXPORTS) # dllexport/dllimport differentiation in ua_config.h when building the lib on windows
 
 # build settings
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules")
@@ -119,6 +121,9 @@ endif()
 
 add_library(open62541-objects OBJECT ${lib_sources}) # static version that exports all symbols
 add_library(open62541 SHARED $<TARGET_OBJECTS:open62541-objects>)
+target_compile_definitions(open62541 INTERFACE
+  $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:open62541_EXPORTS> # the UA_EXPORT macro is different when building the lib or using the lib
+)
 
 ## logging
 set(UA_LOGLEVEL 400 CACHE STRING "Level at which logs shall be reported")
@@ -140,7 +145,7 @@ file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/src_generated")
 include_directories("${PROJECT_BINARY_DIR}/src_generated") 
 add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.c
                           ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated.h
-                   COMMAND python ${PROJECT_SOURCE_DIR}/tools/generate_builtin.py ${generate_src_options} ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.Types.bsd ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated
+                   COMMAND python ${PROJECT_SOURCE_DIR}/tools/generate_builtin.py --export-prototypes ${generate_src_options} ${PROJECT_SOURCE_DIR}/tools/schema/Opc.Ua.Types.bsd ${PROJECT_BINARY_DIR}/src_generated/ua_types_generated
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tools/generate_builtin.py
                            ${CMAKE_CURRENT_SOURCE_DIR}/tools/schema/Opc.Ua.Types.bsd)
 
@@ -176,7 +181,7 @@ if(NOT ENABLE_MULTITHREADING)
 else()
     list(APPEND server_sources examples/networklayer_tcp_concurrent.c)
 endif()
-add_executable(exampleServer ${server_sources})
+add_executable(exampleServer ${server_sources} ${exported_headers} ${generated_headers})
 target_link_libraries(exampleServer open62541)
 if(WIN32)
     target_link_libraries(exampleServer ws2_32)
@@ -187,7 +192,6 @@ if(ENABLE_MULTITHREADING)
 endif()
 endif()
 
-
 # build unit tests
 option(ENABLE_UNIT_TESTS "Run unit tests after building" OFF)
 if(ENABLE_UNIT_TESTS)

+ 0 - 27
Makefile

@@ -476,30 +476,6 @@ src/server/ua_services_discovery.c.s:
 	$(MAKE) -f CMakeFiles/open62541-objects.dir/build.make CMakeFiles/open62541-objects.dir/src/server/ua_services_discovery.c.s
 .PHONY : src/server/ua_services_discovery.c.s
 
-src/server/ua_services_monitoreditems.o: src/server/ua_services_monitoreditems.c.o
-.PHONY : src/server/ua_services_monitoreditems.o
-
-# target to build an object file
-src/server/ua_services_monitoreditems.c.o:
-	$(MAKE) -f CMakeFiles/open62541-objects.dir/build.make CMakeFiles/open62541-objects.dir/src/server/ua_services_monitoreditems.c.o
-.PHONY : src/server/ua_services_monitoreditems.c.o
-
-src/server/ua_services_monitoreditems.i: src/server/ua_services_monitoreditems.c.i
-.PHONY : src/server/ua_services_monitoreditems.i
-
-# target to preprocess a source file
-src/server/ua_services_monitoreditems.c.i:
-	$(MAKE) -f CMakeFiles/open62541-objects.dir/build.make CMakeFiles/open62541-objects.dir/src/server/ua_services_monitoreditems.c.i
-.PHONY : src/server/ua_services_monitoreditems.c.i
-
-src/server/ua_services_monitoreditems.s: src/server/ua_services_monitoreditems.c.s
-.PHONY : src/server/ua_services_monitoreditems.s
-
-# target to generate assembly for a file
-src/server/ua_services_monitoreditems.c.s:
-	$(MAKE) -f CMakeFiles/open62541-objects.dir/build.make CMakeFiles/open62541-objects.dir/src/server/ua_services_monitoreditems.c.s
-.PHONY : src/server/ua_services_monitoreditems.c.s
-
 src/server/ua_services_nodemanagement.o: src/server/ua_services_nodemanagement.c.o
 .PHONY : src/server/ua_services_nodemanagement.o
 
@@ -913,9 +889,6 @@ help:
 	@echo "... src/server/ua_services_discovery.o"
 	@echo "... src/server/ua_services_discovery.i"
 	@echo "... src/server/ua_services_discovery.s"
-	@echo "... src/server/ua_services_monitoreditems.o"
-	@echo "... src/server/ua_services_monitoreditems.i"
-	@echo "... src/server/ua_services_monitoreditems.s"
 	@echo "... src/server/ua_services_nodemanagement.o"
 	@echo "... src/server/ua_services_nodemanagement.i"
 	@echo "... src/server/ua_services_nodemanagement.s"

+ 22 - 18
README.md

@@ -45,33 +45,37 @@ void serverCallback(UA_Server *server) {
 int main(int argc, char** argv) {
 	signal(SIGINT, stopHandler); /* catches ctrl-c */
 
+    /* init the server */
 	#define PORT 16664
 	UA_String endpointUrl;
-	UA_String_copyprintf("opc.tpc://127.0.0.1:%i", endpointUrl, PORT);
-    
-	UA_Server server;
-	UA_Server_init(&server, &endpointUrl);
-	Logger_Stdout_init(&server.logger);
+	UA_String_copyprintf("opc.tcp://127.0.0.1:%i", &endpointUrl, PORT);
+	UA_Server *server = UA_Server_new(&endpointUrl, NULL);
 
+    /* add a variable node */
     UA_Int32 myInteger = 42;
     UA_String myIntegerName;
     UA_STRING_STATIC(myIntegerName, "The Answer");
-    // Adds the integer variable as a child (HasComponent) to the "Objects" node.
-    UA_Server_addScalarVariableNode(&server, &myIntegerName, (void*)&myInteger,
-                                    &UA_[UA_INT32], &server.objectsNodeId,
-                                    &server.hasComponentReferenceTypeId);
-
-	NetworklayerTCP* nl;
-	NetworklayerTCP_new(&nl, UA_ConnectionConfig_standard, PORT);
+    UA_Server_addScalarVariableNode(server,
+                 /* browse name, the value and the datatype's vtable */
+                 &myIntegerName, (void*)&myInteger, &UA_TYPES[UA_INT32],
+                 /* the parent node where the variable shall be attached */
+                 &UA_NODEIDS[UA_OBJECTSFOLDER],
+                 /* the (hierarchical) referencetype from the parent */
+                 &UA_NODEIDS[UA_HASCOMPONENT]);
+
+    /* attach a network layer */
+	NetworklayerTCP* nl = NetworklayerTCP_new(UA_ConnectionConfig_standard, PORT);
 	printf("Server started, connect to to opc.tcp://127.0.0.1:%i\n", PORT);
-	struct timeval callback_interval = {5, 0}; // run serverCallback every 5 seconds
-	UA_Int32 retval = NetworkLayerTCP_run(nl, &server, callback_interval,
-										  serverCallback, &running);
-                                          
-	UA_Server_deleteMembers(&server);
+
+    /* run the server loop */
+	struct timeval callback_interval = {1, 0}; // 1 second
+	NetworkLayerTCP_run(nl, server, callback_interval, serverCallback, &running);
+    
+    /* clean up */
 	NetworklayerTCP_delete(nl);
+	UA_Server_delete(server);
     UA_String_deleteMembers(&endpointUrl);
-	return retval == UA_SUCCESS ? 0 : retval;
+	return 0;
 }
 ```
 

+ 15 - 16
examples/networklayer_tcp.c

@@ -51,16 +51,15 @@ typedef struct TCPConnectionHandle {
 	NetworklayerTCP *layer;
 } TCPConnectionHandle;
 
-UA_StatusCode NetworklayerTCP_new(NetworklayerTCP **newlayer, UA_ConnectionConfig localConf,
-                                  UA_UInt32 port) {
-    *newlayer = malloc(sizeof(NetworklayerTCP));
-    if(*newlayer == UA_NULL)
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-	(*newlayer)->localConf = localConf;
-	(*newlayer)->port = port;
-	(*newlayer)->connectionsSize = 0;
-	(*newlayer)->connections = UA_NULL;
-	return UA_STATUSCODE_GOOD;
+NetworklayerTCP *NetworklayerTCP_new(UA_ConnectionConfig localConf, UA_UInt32 port) {
+    NetworklayerTCP *newlayer = malloc(sizeof(NetworklayerTCP));
+    if(newlayer == NULL)
+        return NULL;
+	newlayer->localConf = localConf;
+	newlayer->port = port;
+	newlayer->connectionsSize = 0;
+	newlayer->connections = NULL;
+	return newlayer;
 }
 
 // copy the array of connections, but _loose_ one. This does not close the
@@ -76,14 +75,14 @@ static UA_StatusCode NetworklayerTCP_remove(NetworklayerTCP *layer, UA_Int32 soc
         return UA_STATUSCODE_BADINTERNALERROR;
 
     if(layer->connections[index].connection.channel)
-        layer->connections[index].connection.channel->connection = UA_NULL;
+        layer->connections[index].connection.channel->connection = NULL;
 
 	UA_Connection_deleteMembers(&layer->connections[index].connection);
 
     layer->connectionsSize--;
 	TCPConnection *newconnections;
     newconnections = malloc(sizeof(TCPConnection) * layer->connectionsSize);
-	memcpy(newconnections, &layer->connections, sizeof(TCPConnection) * index);
+	memcpy(newconnections, layer->connections, sizeof(TCPConnection) * index);
 	memcpy(&newconnections[index], &layer->connections[index+1],
            sizeof(TCPConnection) * (layer->connectionsSize - index));
     free(layer->connections);
@@ -95,7 +94,7 @@ void NetworklayerTCP_delete(NetworklayerTCP *layer) {
 	for(UA_UInt32 index = 0;index < layer->connectionsSize;index++) {
 		shutdown(layer->connections[index].sockfd, 2);
         if(layer->connections[index].connection.channel)
-            layer->connections[index].connection.channel->connection = UA_NULL;
+            layer->connections[index].connection.channel->connection = NULL;
         UA_Connection_deleteMembers(&layer->connections[index].connection);
 		CLOSESOCKET(layer->connections[index].sockfd);
 	}
@@ -139,8 +138,8 @@ void writeCallback(TCPConnectionHandle *handle, UA_ByteStringArray gather_buf) {
 		iov[i].iov_len = gather_buf.strings[i].length;
 		total_len += gather_buf.strings[i].length;
 	}
-	struct msghdr message = {.msg_name = UA_NULL, .msg_namelen = 0, .msg_iov = iov,
-							 .msg_iovlen = gather_buf.stringsSize, .msg_control = UA_NULL,
+	struct msghdr message = {.msg_name = NULL, .msg_namelen = 0, .msg_iov = iov,
+							 .msg_iovlen = gather_buf.stringsSize, .msg_control = NULL,
 							 .msg_controllen = 0, .msg_flags = 0};
 	while (nWritten < total_len) {
 		UA_Int32 n = 0;
@@ -303,7 +302,7 @@ UA_StatusCode NetworkLayerTCP_run(NetworklayerTCP *layer, UA_Server *server, str
 	while (*running) {
 		setFDSet(layer);
 		struct timeval tmptv = tv;
-		UA_Int32 resultsize = select(layer->highestfd, &layer->fdset, UA_NULL, UA_NULL, &tmptv);
+		UA_Int32 resultsize = select(layer->highestfd, &layer->fdset, NULL, NULL, &tmptv);
 		if (resultsize <= 0) {
 #ifdef WIN32
 			UA_Int32 err = (resultsize == SOCKET_ERROR) ? WSAGetLastError() : 0;

+ 1 - 5
examples/networklayer_tcp.h

@@ -20,11 +20,7 @@
 struct NetworklayerTCP;
 typedef struct NetworklayerTCP NetworklayerTCP;
 
-#define BINARYCONNECTION_PROTOCOL_VERSION  0
-#define BINARYCONNECTION_MAX_CHUNK_COUNT 1
-#define BINARYCONNECTION_MAX_MESSAGE_SIZE 8192
-
-UA_StatusCode NetworklayerTCP_new(NetworklayerTCP **newlayer, UA_ConnectionConfig localConf, UA_UInt32 port);
+NetworklayerTCP * NetworklayerTCP_new(UA_ConnectionConfig localConf, UA_UInt32 port);
 void NetworklayerTCP_delete(NetworklayerTCP *layer);
 UA_StatusCode NetworkLayerTCP_run(NetworklayerTCP *layer, UA_Server *server, struct timeval tv,
                                   void(*worker)(UA_Server*), UA_Boolean *running);

+ 125 - 190
examples/opcuaClient.c

@@ -1,5 +1,8 @@
 /*
  C ECHO client example using sockets
+
+ This is an example client for internal benchmarks. It works, but is not ready
+ for serious use. We do not really check any of the returns from the server.
  */
 #include <stdio.h> //printf
 #include <string.h> //strlen
@@ -12,113 +15,96 @@
 #include "ua_util.h"
 
 UA_Int32 sendHello(UA_Int32 sock, UA_String *endpointURL) {
-	UA_ByteString *message;
-	UA_ByteString_new(&message);
-	UA_ByteString_newMembers(message, 1000);
-
-	UA_UInt32 offset = 0;
-
-
 
 	UA_TcpMessageHeader messageHeader;
-	UA_TcpHelloMessage hello;
 	messageHeader.isFinal = 'F';
 	messageHeader.messageType = UA_MESSAGETYPE_HEL;
 
+	UA_TcpHelloMessage hello;
 	UA_String_copy(endpointURL, &hello.endpointUrl);
-
 	hello.maxChunkCount = 1;
 	hello.maxMessageSize = 16777216;
 	hello.protocolVersion = 0;
 	hello.receiveBufferSize = 65536;
 	hello.sendBufferSize = 65536;
 
-	messageHeader.messageSize = UA_TcpHelloMessage_calcSizeBinary(
-			(UA_TcpHelloMessage const*) &hello)
-			+ UA_TcpMessageHeader_calcSizeBinary(
-					(UA_TcpMessageHeader const*) &messageHeader);
-
-	UA_TcpMessageHeader_encodeBinary(
-			(UA_TcpMessageHeader const*) &messageHeader, message, &offset);
-	UA_TcpHelloMessage_encodeBinary((UA_TcpHelloMessage const*) &hello, message,
-			&offset);
+	messageHeader.messageSize = UA_TcpHelloMessage_calcSizeBinary((UA_TcpHelloMessage const*) &hello) +
+                                UA_TcpMessageHeader_calcSizeBinary((UA_TcpMessageHeader const*) &messageHeader);
+	UA_ByteString message;
+	UA_ByteString_newMembers(&message, messageHeader.messageSize);
 
-	UA_Int32 sendret = send(sock, message->data, offset, 0);
+	UA_UInt32 offset = 0;
+	UA_TcpMessageHeader_encodeBinary((UA_TcpMessageHeader const*) &messageHeader, &message, &offset);
+	UA_TcpHelloMessage_encodeBinary((UA_TcpHelloMessage const*) &hello, &message, &offset);
 
-	UA_ByteString_delete(message);
+	UA_Int32 sendret = send(sock, message.data, offset, 0);
 
+	UA_ByteString_deleteMembers(&message);
 	free(hello.endpointUrl.data);
-	if (sendret < 0) {
+	if (sendret < 0)
 		return 1;
-	}
 	return 0;
-
 }
-int sendOpenSecureChannel(UA_Int32 sock) {
-	UA_ByteString *message;
-	UA_ByteString_new(&message);
-	UA_ByteString_newMembers(message, 1000);
-
-	UA_UInt32 offset = 0;
 
+int sendOpenSecureChannel(UA_Int32 sock) {
 	UA_TcpMessageHeader msghdr;
 	msghdr.isFinal = 'F';
 	msghdr.messageType = UA_MESSAGETYPE_OPN;
-	msghdr.messageSize = 135;
 
-	UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
 	UA_UInt32 secureChannelId = 0;
-	UA_UInt32_encodeBinary(&secureChannelId, message, &offset);
 	UA_String securityPolicy;
-
-	UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None",
-			&securityPolicy);
-	UA_String_encodeBinary(&securityPolicy, message, &offset);
+	UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None", &securityPolicy);
 
 	UA_String senderCert;
 	senderCert.data = UA_NULL;
 	senderCert.length = -1;
-	UA_String_encodeBinary(&senderCert, message, &offset);
 
 	UA_String receiverCertThumb;
 	receiverCertThumb.data = UA_NULL;
 	receiverCertThumb.length = -1;
-	UA_String_encodeBinary(&receiverCertThumb, message, &offset);
 
 	UA_UInt32 sequenceNumber = 51;
-	UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
 
 	UA_UInt32 requestId = 1;
-	UA_UInt32_encodeBinary(&requestId, message, &offset);
 
 	UA_NodeId type;
-	type.identifier.numeric = 446;
+	type.identifier.numeric = 446; // id of opensecurechannelrequest
 	type.identifierType = UA_NODEIDTYPE_NUMERIC;
 	type.namespaceIndex = 0;
-	UA_NodeId_encodeBinary(&type, message, &offset);
 
 	UA_OpenSecureChannelRequest opnSecRq;
 	UA_OpenSecureChannelRequest_init(&opnSecRq);
-
 	opnSecRq.requestHeader.timestamp = UA_DateTime_now();
-
 	UA_ByteString_newMembers(&opnSecRq.clientNonce, 1);
 	opnSecRq.clientNonce.data[0] = 0;
-
 	opnSecRq.clientProtocolVersion = 0;
 	opnSecRq.requestedLifetime = 30000;
-	opnSecRq.securityMode = UA_SECURITYMODE_NONE;
+	opnSecRq.securityMode = UA_MESSAGESECURITYMODE_NONE;
 	opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE;
-
 	opnSecRq.requestHeader.authenticationToken.identifier.numeric = 10;
-	opnSecRq.requestHeader.authenticationToken.identifierType =
-			UA_NODEIDTYPE_NUMERIC;
+	opnSecRq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
 	opnSecRq.requestHeader.authenticationToken.namespaceIndex = 10;
 
-	UA_OpenSecureChannelRequest_encodeBinary(&opnSecRq, message, &offset);
-	UA_Int32 sendret = send(sock, message->data, offset, 0);
-	UA_ByteString_delete(message);
-	free(securityPolicy.data);
+	msghdr.messageSize = 135; // todo: compute the message size from the actual content
+
+	UA_ByteString message;
+	UA_ByteString_newMembers(&message, 1000);
+	UA_UInt32 offset = 0;
+	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
+	UA_UInt32_encodeBinary(&secureChannelId, &message, &offset);
+	UA_String_encodeBinary(&securityPolicy, &message, &offset);
+	UA_String_encodeBinary(&senderCert, &message, &offset);
+	UA_String_encodeBinary(&receiverCertThumb, &message, &offset);
+	UA_UInt32_encodeBinary(&sequenceNumber, &message, &offset);
+	UA_UInt32_encodeBinary(&requestId, &message, &offset);
+	UA_NodeId_encodeBinary(&type, &message, &offset);
+	UA_OpenSecureChannelRequest_encodeBinary(&opnSecRq, &message, &offset);
+
+    UA_OpenSecureChannelRequest_deleteMembers(&opnSecRq);
+	UA_String_deleteMembers(&securityPolicy);
+
+	UA_Int32 sendret = send(sock, message.data, offset, 0);
+	UA_ByteString_deleteMembers(&message);
 	if (sendret < 0) {
 		printf("send opensecurechannel failed");
 		return 1;
@@ -126,12 +112,10 @@ int sendOpenSecureChannel(UA_Int32 sock) {
 	return 0;
 }
 
-UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId,
-		UA_UInt32 tokenId, UA_UInt32 sequenceNumber, UA_UInt32 requestId,
-		UA_String *endpointUrl) {
-	UA_ByteString *message;
-	UA_ByteString_new(&message);
-	UA_ByteString_newMembers(message, 65536);
+UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
+                           UA_UInt32 requestId, UA_String *endpointUrl) {
+    UA_ByteString message;
+	UA_ByteString_newMembers(&message, 65536);
 	UA_UInt32 tmpChannelId = channelId;
 	UA_UInt32 offset = 0;
 
@@ -139,73 +123,50 @@ UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId,
 	msghdr.isFinal = 'F';
 	msghdr.messageType = UA_MESSAGETYPE_MSG;
 
-
-
-
 	UA_NodeId type;
 	type.identifier.numeric = 461;
 	type.identifierType = UA_NODEIDTYPE_NUMERIC;
 	type.namespaceIndex = 0;
 
-
 	UA_CreateSessionRequest rq;
-	UA_RequestHeader_init(&rq.requestHeader);
-
+    UA_CreateSessionRequest_init(&rq);
 	rq.requestHeader.requestHandle = 1;
 	rq.requestHeader.timestamp = UA_DateTime_now();
 	rq.requestHeader.timeoutHint = 10000;
-	rq.requestHeader.auditEntryId.length = -1;
 	rq.requestHeader.authenticationToken.identifier.numeric = 10;
 	rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
 	rq.requestHeader.authenticationToken.namespaceIndex = 10;
 	UA_String_copy(endpointUrl, &rq.endpointUrl);
-	rq.clientDescription.applicationName.locale.length = 0;
-	rq.clientDescription.applicationName.text.length = 0;
-	rq.serverUri.length = 0;
-	rq.serverUri.data = UA_NULL;
-	rq.clientDescription.applicationUri.length = 0;
-	rq.clientDescription.discoveryProfileUri.length = 0;
-	rq.clientDescription.discoveryUrls = UA_NULL;
-	rq.clientDescription.discoveryUrlsSize = 0;
-	rq.clientDescription.gatewayServerUri.length = 0;
-	rq.clientDescription.productUri.length = 0;
-
 	UA_String_copycstring("mysession", &rq.sessionName);
-
 	UA_String_copycstring("abcd", &rq.clientCertificate);
-
 	UA_ByteString_newMembers(&rq.clientNonce, 1);
 	rq.clientNonce.data[0] = 0;
-
 	rq.requestedSessionTimeout = 1200000;
 	rq.maxResponseMessageSize = UA_INT32_MAX;
 
+	msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
+                         UA_CreateSessionRequest_calcSizeBinary(&rq);
 
+	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
+	UA_UInt32_encodeBinary(&tmpChannelId, &message, &offset);
+	UA_UInt32_encodeBinary(&tokenId, &message, &offset);
+	UA_UInt32_encodeBinary(&sequenceNumber, &message, &offset);
+	UA_UInt32_encodeBinary(&requestId, &message, &offset);
+	UA_NodeId_encodeBinary(&type, &message, &offset);
+	UA_CreateSessionRequest_encodeBinary(&rq, &message, &offset);
 
-	msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) + UA_CreateSessionRequest_calcSizeBinary(&rq);
-	UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
-
-	UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
-	UA_UInt32_encodeBinary(&tokenId, message, &offset);
-	UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
-	UA_UInt32_encodeBinary(&requestId, message, &offset);
-	UA_NodeId_encodeBinary(&type, message, &offset);
-	UA_CreateSessionRequest_encodeBinary(&rq, message, &offset);
-
-	UA_Int32 sendret = send(sock, message->data, offset, 0);
-	UA_ByteString_delete(message);
-	free(rq.sessionName.data);
-	free(rq.clientCertificate.data);
+	UA_Int32 sendret = send(sock, message.data, offset, 0);
+	UA_ByteString_deleteMembers(&message);
+	UA_CreateSessionRequest_deleteMembers(&rq);
 	if (sendret < 0) {
 		printf("send opensecurechannel failed");
 		return 1;
 	}
 	return 0;
 }
-UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId,
-		UA_UInt32 tokenId, UA_UInt32 sequenceNumber, UA_UInt32 requestId, UA_NodeId authenticationToken) {
-	UA_ByteString *message;
-	UA_ByteString_new(&message);
+UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
+                             UA_UInt32 requestId, UA_NodeId authenticationToken) {
+	UA_ByteString *message = UA_ByteString_new();
 	UA_ByteString_newMembers(message, 65536);
 	UA_UInt32 tmpChannelId = channelId;
 	UA_UInt32 offset = 0;
@@ -215,24 +176,22 @@ UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId,
 	msghdr.messageType = UA_MESSAGETYPE_MSG;
 	msghdr.messageSize = 86;
 
-
-
 	UA_NodeId type;
 	type.identifier.numeric = 467;
 	type.identifierType = UA_NODEIDTYPE_NUMERIC;
 	type.namespaceIndex = 0;
 
-
 	UA_ActivateSessionRequest rq;
 	UA_ActivateSessionRequest_init(&rq);
 	rq.requestHeader.requestHandle = 2;
 	rq.requestHeader.authenticationToken = authenticationToken;
 	rq.requestHeader.timestamp = UA_DateTime_now();
 	rq.requestHeader.timeoutHint = 10000;
-	msghdr.messageSize  = 16 +UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) + UA_ActivateSessionRequest_calcSizeBinary(&rq);
+    
+	msghdr.messageSize  = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
+                          UA_ActivateSessionRequest_calcSizeBinary(&rq);
 
 	UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
-
 	UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
 	UA_UInt32_encodeBinary(&tokenId, message, &offset);
 	UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
@@ -251,10 +210,9 @@ UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId,
 
 }
 
-UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
-		UA_UInt32 sequenceNumber, UA_UInt32 requestId,UA_NodeId authenticationToken, UA_Int32 nodeIds_size,UA_NodeId* nodeIds) {
-	UA_ByteString *message;
-	UA_ByteString_new(&message);
+UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber, UA_UInt32 requestId,
+                         UA_NodeId authenticationToken, UA_Int32 nodeIds_size,UA_NodeId* nodeIds) {
+	UA_ByteString *message = UA_ByteString_new();
 	UA_ByteString_newMembers(message, 65536);
 	UA_UInt32 tmpChannelId = channelId;
 	UA_UInt32 offset = 0;
@@ -263,22 +221,17 @@ UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
 	msghdr.isFinal = 'F';
 	msghdr.messageType = UA_MESSAGETYPE_MSG;
 
-
 	UA_NodeId type;
 	type.identifier.numeric = 631;
 	type.identifierType = UA_NODEIDTYPE_NUMERIC;
 	type.namespaceIndex = 0;
 
-
 	UA_ReadRequest rq;
 	UA_ReadRequest_init(&rq);
-
 	rq.maxAge = 0;
-
-	UA_Array_new((void **) &rq.nodesToRead, nodeIds_size, &UA_[UA_READVALUEID]);
+	UA_Array_new((void **)&rq.nodesToRead, nodeIds_size, &UA_TYPES[UA_READVALUEID]);
 	rq.nodesToReadSize = nodeIds_size;
-	for(UA_Int32 i=0;i<nodeIds_size;i++)
-	{
+	for(UA_Int32 i=0;i<nodeIds_size;i++) {
 		UA_ReadValueId_init(&(rq.nodesToRead[i]));
 		rq.nodesToRead[i].attributeId = 6; //WriteMask
 		UA_NodeId_init(&(rq.nodesToRead[i].nodeId));
@@ -290,7 +243,10 @@ UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
 	rq.requestHeader.authenticationToken = authenticationToken;
 	rq.timestampsToReturn = 0x03;
 	rq.requestHeader.requestHandle = 1 + requestId;
-	msghdr.messageSize = 16 +UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) + UA_ReadRequest_calcSizeBinary(&rq);
+
+	msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
+                         UA_ReadRequest_calcSizeBinary(&rq);
+
 	UA_TcpMessageHeader_encodeBinary(&msghdr,message,&offset);
 	UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
 	UA_UInt32_encodeBinary(&tokenId, message, &offset);
@@ -301,29 +257,25 @@ UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
 
 	UA_DateTime tic = UA_DateTime_now();
 	UA_Int32 sendret = send(sock, message->data, offset, 0);
-	UA_Array_delete(rq.nodesToRead,nodeIds_size,&UA_[UA_READVALUEID]);
+	UA_Array_delete(rq.nodesToRead,nodeIds_size,&UA_TYPES[UA_READVALUEID]);
 	UA_ByteString_delete(message);
 
-
-
-
 	if (sendret < 0) {
 		printf("send readrequest failed");
 		return 1;
 	}
 	return tic;
 }
+
 int main(int argc, char *argv[]) {
 	int sock;
 	struct sockaddr_in server;
 
-	UA_ByteString *reply;
-	UA_ByteString_new(&reply);
-	UA_ByteString_newMembers(reply, 65536);
+	UA_ByteString reply;
+	UA_ByteString_newMembers(&reply, 65536);
 
 	//start parameters
-	if(argc < 7)
-	{
+	if(argc < 7) {
 		printf("1st parameter: number of nodes to read \n");
 		printf("2nd parameter: number of read-tries \n");
 		printf("3rd parameter: name of the file to save measurement data \n");
@@ -333,147 +285,130 @@ int main(int argc, char *argv[]) {
 		return 0;
 	}
 
-
 	UA_UInt32 nodesToReadSize;
 	UA_UInt32 tries;
 	UA_Boolean alwaysSameNode;
-	if(argv[1] == UA_NULL){
+	if(argv[1] == UA_NULL)
 		nodesToReadSize = 1;
-	}else{
+	else
 		nodesToReadSize = atoi(argv[1]);
-	}
 
-	if(argv[2] == UA_NULL){
+	if(argv[2] == UA_NULL)
 		tries= 2;
-	}else{
+	else
 		tries = (UA_UInt32) atoi(argv[2]);
-	}
+
 	if(atoi(argv[4]) != 0)
-	{
 		alwaysSameNode = UA_TRUE;
-	}
 	else
-	{
 		alwaysSameNode = UA_FALSE;
-	}
-
 
 	//Create socket
 	sock = socket(AF_INET, SOCK_STREAM, 0);
-	if (sock == -1) {
+	if(sock == -1) {
 		printf("Could not create socket");
-	}
+        return 1;
+    }
 	server.sin_addr.s_addr = inet_addr(argv[5]);
 	server.sin_family = AF_INET;
 	server.sin_port = htons(atoi(argv[6]));
-//Connect to remote server
-	if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
+
+    //Connect to remote server
+	if(connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
 		perror("connect failed. Error");
 		return 1;
 	}
-	UA_String *endpointUrl;
-	UA_String_new(&endpointUrl);
 
+	UA_String *endpointUrl = UA_String_new();
 	UA_String_copycstring("opc.tcp://blabla.com:1234", endpointUrl);
 	sendHello(sock, endpointUrl);
-	int received = recv(sock, reply->data, reply->length, 0);
+	int received = recv(sock, reply.data, reply.length, 0);
 	sendOpenSecureChannel(sock);
-	received = recv(sock, reply->data, reply->length, 0);
-
+	received = recv(sock, reply.data, reply.length, 0);
 
 	UA_UInt32 recvOffset = 0;
 	UA_TcpMessageHeader msghdr;
-	UA_TcpMessageHeader_decodeBinary(reply, &recvOffset, &msghdr);
+	UA_TcpMessageHeader_decodeBinary(&reply, &recvOffset, &msghdr);
 	UA_UInt32 secureChannelId;
 	UA_AsymmetricAlgorithmSecurityHeader asymHeader;
 	UA_SequenceHeader seqHeader;
 	UA_NodeId rspType;
 	UA_OpenSecureChannelResponse openSecChannelRsp;
-	UA_UInt32_decodeBinary(reply, &recvOffset, &secureChannelId);
-	UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(reply,&recvOffset,&asymHeader);
-	UA_SequenceHeader_decodeBinary(reply,&recvOffset,&seqHeader);
-	UA_NodeId_decodeBinary(reply,&recvOffset,&rspType);
-	UA_OpenSecureChannelResponse_decodeBinary(reply,&recvOffset,&openSecChannelRsp);
+	UA_UInt32_decodeBinary(&reply, &recvOffset, &secureChannelId);
+	UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(&reply,&recvOffset,&asymHeader);
+	UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&asymHeader);
+	UA_SequenceHeader_decodeBinary(&reply,&recvOffset,&seqHeader);
+	UA_NodeId_decodeBinary(&reply,&recvOffset,&rspType);
+	UA_OpenSecureChannelResponse_decodeBinary(&reply,&recvOffset,&openSecChannelRsp);
 
 	sendCreateSession(sock, secureChannelId, openSecChannelRsp.securityToken.tokenId, 52, 2, endpointUrl);
-	received = recv(sock, reply->data, reply->length, 0);
-
+	received = recv(sock, reply.data, reply.length, 0);
 
 	UA_NodeId messageType;
 	recvOffset = 24;
-	UA_NodeId_decodeBinary(reply,&recvOffset,&messageType);
+	UA_NodeId_decodeBinary(&reply,&recvOffset,&messageType);
 	UA_CreateSessionResponse createSessionResponse;
-	//createSessionResponse = (UA_CreateSessionResponse*)&(reply->data[recvOffset]);
-	UA_CreateSessionResponse_decodeBinary(reply,&recvOffset,&createSessionResponse);
+	UA_CreateSessionResponse_decodeBinary(&reply,&recvOffset,&createSessionResponse);
 
-	sendActivateSession(sock, secureChannelId, openSecChannelRsp.securityToken.tokenId, 53, 3,createSessionResponse.authenticationToken);
-	received = recv(sock, reply->data, reply->length, 0);
+	sendActivateSession(sock, secureChannelId, openSecChannelRsp.securityToken.tokenId, 53, 3,
+                        createSessionResponse.authenticationToken);
+	received = recv(sock, reply.data, reply.length, 0);
 
     UA_NodeId *nodesToRead;
+    UA_Array_new((void**)&nodesToRead,nodesToReadSize,&UA_TYPES[UA_NODEID]);
 
-    UA_Array_new((void**)&nodesToRead,nodesToReadSize,&UA_[UA_NODEID]);
-
-	for(UA_UInt32 i = 0; i<nodesToReadSize; i++){
-		UA_NodeId_new((UA_NodeId**)&nodesToRead[i]);
-		if(alwaysSameNode){
+	for(UA_UInt32 i = 0; i<nodesToReadSize; i++) {
+		if(alwaysSameNode)
 			nodesToRead[i].identifier.numeric = 2253; //ask always the same node
-		}
-		else{
+		else
 			nodesToRead[i].identifier.numeric = 19000 +i;
-			nodesToRead[i].namespaceIndex = i;
-		}
 		nodesToRead[i].identifierType = UA_NODEIDTYPE_NUMERIC;
-
+		nodesToRead[i].namespaceIndex = 0;
 	}
 
 	UA_DateTime tic, toc;
 	UA_Double *timeDiffs;
 
-
-
-	UA_Array_new((void**)&timeDiffs,tries,&UA_[UA_DOUBLE]);
+	UA_Array_new((void**)&timeDiffs,tries,&UA_TYPES[UA_DOUBLE]);
 	UA_Double sum = 0;
 
-	for (UA_UInt32 i = 0; i < tries; i++) {
-
-		tic = sendReadRequest(sock, secureChannelId, openSecChannelRsp.securityToken.tokenId, 54+i, 4+i,createSessionResponse.authenticationToken,nodesToReadSize,nodesToRead);
-
-		received = recv(sock, reply->data, 2000, 0);
+	for(UA_UInt32 i = 0; i < tries; i++) {
+		tic = sendReadRequest(sock, secureChannelId, openSecChannelRsp.securityToken.tokenId, 54+i, 4+i,
+                              createSessionResponse.authenticationToken,nodesToReadSize,nodesToRead);
+		received = recv(sock, reply.data, 2000, 0);
 		toc = UA_DateTime_now() - tic;
-
 		timeDiffs[i] = (UA_Double)toc/(UA_Double)1e4;
 		sum = sum + timeDiffs[i];
-		//printf("read request took: %16.10f ms \n",timeDiffs[i]);
 	}
 
 	UA_Double mean = sum / tries;
 	printf("mean time for handling request: %16.10f ms \n",mean);
 
-	if(received>0)//dummy
-	{
-		printf("%i",received);
-	}
+	if(received>0)
+		printf("%i",received); // dummy
 
 	//save to file
 	char data[100];
 	const char flag = 'a';
-	FILE* fHandle =  fopen(argv[3],&flag);
+	FILE* fHandle =  fopen(argv[3], &flag);
 	//header
 
-	UA_Int32 bytesToWrite = sprintf(data,"measurement %s in ms, nodesToRead %d \n",argv[3],nodesToReadSize);
-
+	UA_Int32 bytesToWrite = sprintf(data, "measurement %s in ms, nodesToRead %d \n", argv[3], nodesToReadSize);
 	fwrite(data,1,bytesToWrite,fHandle);
-
-	for(UA_UInt32 i=0;i<tries;i++){
+	for(UA_UInt32 i=0;i<tries;i++) {
 		bytesToWrite = sprintf(data,"%16.10f \n",timeDiffs[i]);
 		fwrite(data,1,bytesToWrite,fHandle);
 	}
 	fclose(fHandle);
 
+    UA_OpenSecureChannelResponse_deleteMembers(&openSecChannelRsp);
 	UA_String_delete(endpointUrl);
-	UA_Array_delete(nodesToRead,nodesToReadSize,&UA_[UA_NODEID]);
-	close(sock);
-	return 0;
+	UA_String_deleteMembers(&reply);
+	UA_Array_delete(nodesToRead,nodesToReadSize,&UA_TYPES[UA_NODEID]);
+    UA_free(timeDiffs);
+	UA_CreateSessionResponse_deleteMembers(&createSessionResponse);
 
+	close(sock);
 
+	return 0;
 }

+ 27 - 33
examples/opcuaServer.c

@@ -21,8 +21,7 @@
 #include "../src/server/ua_namespace_manager.h"
 #include "../src/server/nodestore/open62541_nodestore.h"
 
-UA_Boolean running = UA_TRUE;
-
+UA_Boolean running = 1;
 
 void stopHandler(int sign) {
 	running = 0;
@@ -55,48 +54,46 @@ UA_ByteString loadCertificate() {
     return certificate;
 }
 
-
 int main(int argc, char** argv) {
 	signal(SIGINT, stopHandler); /* catches ctrl-c */
 
-	UA_Server server;
+	UA_Server *server;
 	UA_String endpointUrl;
 	UA_String_copycstring("no endpoint url",&endpointUrl);
-	UA_NodeStore newNodeStore;
-	open62541NodeStore_new(&server.nodestore);
-
-	open62541NodeStore_setNodeStore(server.nodestore);
-	UA_NamespaceManager_new(&server.namespaceManager);
-	UA_NamespaceManager_addNamespace(server.namespaceManager,0, &newNodeStore);
-	UA_NodeStore_registerReadNodesOperation(&newNodeStore,open62541NodeStore_ReadNodes);
-	UA_NodeStore_registerBrowseNodesOperation(&newNodeStore,open62541NodeStore_BrowseNodes);
-	UA_NodeStore_registerAddNodesOperation(&newNodeStore,open62541NodeStore_AddNodes);
-	UA_NodeStore_registerWriteNodesOperation(&newNodeStore,open62541NodeStore_WriteNodes);
-	//register more operations/ services here
+	UA_NodeStore  nodeStore;
 
-	UA_Server_init(&server, &endpointUrl);
+	open62541NodeStore *myNodeStore;
+	open62541NodeStore_new(&myNodeStore);
 
-	//initMyNode();
+	open62541NodeStore_setNodeStore(myNodeStore);
+
+	UA_NodeStore_registerReadNodesOperation(&nodeStore,open62541NodeStore_ReadNodes);
+	UA_NodeStore_registerBrowseNodesOperation(&nodeStore,open62541NodeStore_BrowseNodes);
+	UA_NodeStore_registerAddNodesOperation(&nodeStore,open62541NodeStore_AddNodes);
+	UA_NodeStore_registerWriteNodesOperation(&nodeStore,open62541NodeStore_WriteNodes);
+	//register more operations/ services here
+	UA_ByteString certificate = loadCertificate();
+
+	server = UA_Server_new(&endpointUrl, &certificate, &nodeStore);
 
-	Logger_Stdout_init(&server.logger);
-    server.serverCertificate = loadCertificate();
 
     UA_Int32 myInteger = 42;
     UA_QualifiedName *myIntegerName;
-    UA_QualifiedName_new(&myIntegerName);
+    myIntegerName = UA_QualifiedName_new();
     UA_QualifiedName_copycstring("the answer is",myIntegerName);
 
-    UA_Server_addScalarVariableNode(&server, myIntegerName, (void*)&myInteger, &UA_[UA_INT32],
-                                   &server.objectsNodeId, &server.hasComponentReferenceTypeId);
+    UA_ExpandedNodeId parentNodeId;
+    parentNodeId.namespaceUri.length = 0;
+    parentNodeId.nodeId = UA_NODEIDS[UA_OBJECTSFOLDER];
+    UA_Server_addScalarVariableNode(server, myIntegerName, (void*)&myInteger, &UA_TYPES[UA_INT32],
+    		&parentNodeId, (UA_NodeId*)&UA_NODEIDS[UA_HASCOMPONENT]);
 
 #ifdef BENCHMARK
     UA_UInt32 nodeCount = 500;
-    UA_VariableNode *tmpNode;
-
     UA_Int32 data = 42;
     char str[15];
     for(UA_UInt32 i = 0;i<nodeCount;i++) {
-        UA_VariableNode_new(&tmpNode);
+        UA_VariableNode *tmpNode = UA_VariableNode_new();
         sprintf(str,"%d",i);
         UA_QualifiedName_copycstring(str,&tmpNode->browseName);
         UA_LocalizedText_copycstring(str,&tmpNode->displayName);
@@ -104,23 +101,20 @@ int main(int argc, char** argv) {
         tmpNode->nodeId.identifier.numeric = 19000+i;
         tmpNode->nodeClass = UA_NODECLASS_VARIABLE;
         //tmpNode->valueRank = -1;
-        tmpNode->value.vt = &UA_[UA_INT32];
+        tmpNode->value.vt = &UA_TYPES[UA_INT32];
         tmpNode->value.storage.data.dataPtr = &data;
         tmpNode->value.storageType = UA_VARIANT_DATA_NODELETE;
         tmpNode->value.storage.data.arrayLength = 1;
-        UA_Server_addNode(&server, (UA_Node**)&tmpNode, &server.objectsNodeId,
-                          &server.hasComponentReferenceTypeId);
+        UA_Server_addNode(server, (UA_Node**)&tmpNode, &UA_NODEIDS[UA_OBJECTSFOLDER], &UA_NODEIDS[UA_HASCOMPONENT]);
     }
 #endif
 	
 	#define PORT 16664
-	NetworklayerTCP* nl;
-	NetworklayerTCP_new(&nl, UA_ConnectionConfig_standard, PORT);
+	NetworklayerTCP* nl = NetworklayerTCP_new(UA_ConnectionConfig_standard, PORT);
 	printf("Server started, connect to to opc.tcp://127.0.0.1:%i\n", PORT);
 	struct timeval callback_interval = {1, 0}; // 1 second
-	UA_Int32 retval = NetworkLayerTCP_run(nl, &server, callback_interval,
-										  serverCallback, &running);
-	UA_Server_deleteMembers(&server);
+	UA_Int32 retval = NetworkLayerTCP_run(nl, server, callback_interval, serverCallback, &running);
+	UA_Server_delete(server);
 	NetworklayerTCP_delete(nl);
     UA_String_deleteMembers(&endpointUrl);
 	return retval == UA_STATUSCODE_GOOD ? 0 : retval;

+ 3 - 6
examples/ua_nodestore_concurrent.c

@@ -146,7 +146,7 @@ static int compare(struct cds_lfht_node *htn, const void *orig) {
     UA_NodeId *origid = (UA_NodeId *)orig;
     UA_NodeId *newid  = &((UA_NodeStore_Entry *)htn)->node.nodeId;   /* The htn is first in the entry structure. */
 
-    return UA_NodeId_equal(newid, origid) == UA_EQUAL;
+    return UA_NodeId_equal(newid, origid);
 }
 
 /* The entry was removed from the hashtable. No more readers can get it. Since
@@ -164,10 +164,7 @@ static void markDead(struct rcu_head *head) {
 }
 
 /* Free the entry if it is dead and nobody uses it anymore */
-void UA_NodeStore_releaseManagedNode(const UA_Node *managed) {
-    if(managed == UA_NULL)
-        return;
-
+void UA_NodeStore_release(const UA_Node *managed) {
     UA_NodeStore_Entry *entry = caa_container_of(managed, UA_NodeStore_Entry, node); // pointer to the first entry
     if(uatomic_sub_return(&entry->readcount, 1) > 0)
         return;
@@ -350,7 +347,7 @@ void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visit
         const UA_Node      *node = &found_entry->node;
         rcu_read_unlock();
         visitor(node);
-        UA_NodeStore_releaseManagedNode((UA_Node *)node);
+        UA_NodeStore_release((UA_Node *)node);
         rcu_read_lock();
         cds_lfht_next(ht, &iter);
     }

+ 4 - 26
include/ua_server.h

@@ -27,19 +27,11 @@ extern "C" {
 
 /** @defgroup server Server */
 
-//identifier numbers are different for XML and binary, so we have to substract an offset for comparison
-#define UA_ENCODINGOFFSET_XML 1
-#define UA_ENCODINGOFFSET_BINARY 2
-
-struct UA_SecureChannelManager;
-typedef struct UA_SecureChannelManager UA_SecureChannelManager;
-
-struct UA_SessionManager;
-typedef struct UA_SessionManager UA_SessionManager;
-
 struct UA_NodeStore;
 typedef struct UA_NodeStore UA_NodeStore;
 
+struct UA_Server;
+typedef struct UA_Server UA_Server;
 struct open62541NodeStore;
 typedef struct open62541NodeStore open62541NodeStore;
 
@@ -76,23 +68,9 @@ struct UA_NodeStore {
 	UA_NodeStore_deleteReferences deleteReferences;
 };
 
-typedef struct UA_Server {
-	UA_ApplicationDescription description;
-	UA_SecureChannelManager *secureChannelManager;
-	UA_SessionManager *sessionManager;
-	UA_NamespaceManager* namespaceManager;
-	open62541NodeStore *nodestore;
-	UA_Logger logger;
-	UA_ByteString serverCertificate;
-
-	// todo: move these somewhere sane
-	UA_ExpandedNodeId objectsNodeId;
-	UA_NodeId hasComponentReferenceTypeId;
-
-}UA_Server;
 
-void UA_EXPORT UA_Server_init(UA_Server *server, UA_String *endpointUrl);
-UA_StatusCode UA_EXPORT UA_Server_deleteMembers(UA_Server *server);
+UA_Server UA_EXPORT * UA_Server_new(UA_String *endpointUrl, UA_ByteString *serverCertificate, UA_NodeStore *ns0Nodestore);
+void UA_EXPORT UA_Server_delete(UA_Server *server);
 void UA_EXPORT UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);
 
 /* Services for local use */

+ 35 - 44
include/ua_types.h

@@ -21,21 +21,11 @@ extern "C" {
 #endif
 
 #include <stdint.h>
-#include "ua_config.h"
-
 #ifdef DEBUG
 #include <stdio.h>
 #endif
 
-/* For internal use */
-#define UA_NULL ((void *)0)
-#define UA_TRUE (42 == 42)
-#define UA_FALSE (!UA_TRUE)
-
-typedef enum UA_EQUALITY {
-    UA_EQUAL,
-    UA_NOT_EQUAL
-} UA_EQUALITY;
+#include "ua_config.h"
     
 /**
  * @defgroup types Datatypes
@@ -51,7 +41,7 @@ typedef enum UA_EQUALITY {
  * PERMITTED.
  *
  * - <type>_new: Allocates the memory for the type and runs <type>_init on the
- *     returned variable.
+ *     returned variable. Returns null if no memory could be allocated.
  *
  * - <type>_init: Sets all members to a "safe" standard, usually zero. Arrays
  *   (e.g. for strings) are set to a length of -1.
@@ -303,21 +293,28 @@ typedef void UA_InvalidType;
 /*************/
 
 #ifdef DEBUG
+#define PRINTTYPE(TYPE) void UA_EXPORT TYPE##_print(const TYPE *p, FILE *stream);
+#define PRINTTYPE_NOEXPORT(TYPE) void TYPE##_print(const TYPE *p, FILE *stream);
+#else
+#define PRINTTYPE(TYPE)
+#define PRINTTYPE_NOEXPORT(TYPE)
+#endif
+    
 #define UA_TYPE_PROTOTYPES(TYPE)                                     \
-    UA_StatusCode UA_EXPORT TYPE##_new(TYPE **p);                    \
+    TYPE UA_EXPORT * TYPE##_new();                                   \
     void UA_EXPORT TYPE##_init(TYPE * p);                            \
     void UA_EXPORT TYPE##_delete(TYPE * p);                          \
     void UA_EXPORT TYPE##_deleteMembers(TYPE * p);                   \
     UA_StatusCode UA_EXPORT TYPE##_copy(const TYPE *src, TYPE *dst); \
-    void UA_EXPORT TYPE##_print(const TYPE *p, FILE *stream);
-#else
-#define UA_TYPE_PROTOTYPES(TYPE)                                        \
-    UA_StatusCode UA_EXPORT TYPE##_new(TYPE **p);                       \
-    void UA_EXPORT TYPE##_init(TYPE * p);                               \
-    void UA_EXPORT TYPE##_delete(TYPE * p);                             \
-    void UA_EXPORT TYPE##_deleteMembers(TYPE * p);                      \
-    UA_StatusCode UA_EXPORT TYPE##_copy(const TYPE *src, TYPE *dst);
-#endif
+    PRINTTYPE(TYPE)
+
+#define UA_TYPE_PROTOTYPES_NOEXPORT(TYPE)                            \
+    TYPE * TYPE##_new();                                             \
+    void TYPE##_init(TYPE * p);                                      \
+    void TYPE##_delete(TYPE * p);                                    \
+    void TYPE##_deleteMembers(TYPE * p);                             \
+    UA_StatusCode TYPE##_copy(const TYPE *src, TYPE *dst);           \
+    PRINTTYPE_NOEXPORT(TYPE)
 
 /* Functions for all types */
 UA_TYPE_PROTOTYPES(UA_Boolean)
@@ -348,14 +345,14 @@ UA_TYPE_PROTOTYPES(UA_DiagnosticInfo)
 UA_TYPE_PROTOTYPES(UA_InvalidType)
 
 /* String */
-#define UA_STRING_NULL (UA_String) {-1, UA_NULL }
+#define UA_STRING_NULL (UA_String) {-1, (UA_Byte*)0 }
 #define UA_STRING_STATIC(VARIABLE, STRING) do { \
         VARIABLE.length = sizeof(STRING)-1;     \
         VARIABLE.data   = (UA_Byte *)STRING; } while(0)
 
 UA_StatusCode UA_EXPORT UA_String_copycstring(char const *src, UA_String *dst);
 UA_StatusCode UA_EXPORT UA_String_copyprintf(char const *fmt, UA_String *dst, ...);
-UA_EQUALITY UA_EXPORT UA_String_equal(const UA_String *string1, const UA_String *string2);
+UA_Boolean UA_EXPORT UA_String_equal(const UA_String *string1, const UA_String *string2);
 #ifdef DEBUG
 void UA_EXPORT UA_String_printf(char const *label, const UA_String *string);
 void UA_EXPORT UA_String_printx(char const *label, const UA_String *string);
@@ -379,10 +376,10 @@ UA_DateTimeStruct UA_EXPORT UA_DateTime_toStruct(UA_DateTime time);
 UA_StatusCode UA_EXPORT UA_DateTime_toString(UA_DateTime time, UA_String *timeString);
 
 /* Guid */
-UA_EQUALITY UA_EXPORT UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2);
+UA_Boolean UA_EXPORT UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2);
 
 /* ByteString */
-UA_EQUALITY UA_EXPORT UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2);
+UA_Boolean UA_EXPORT UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2);
 UA_StatusCode UA_EXPORT UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length);
 #ifdef DEBUG
 void UA_EXPORT UA_ByteString_printf(char *label, const UA_ByteString *string);
@@ -391,7 +388,7 @@ void UA_EXPORT UA_ByteString_printx_hex(char *label, const UA_ByteString *string
 #endif
 
 /* NodeId */
-UA_EQUALITY UA_EXPORT UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2);
+UA_Boolean UA_EXPORT UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2);
 UA_Boolean UA_EXPORT UA_NodeId_isNull(const UA_NodeId *p);
 UA_Boolean UA_EXPORT UA_NodeId_isBasicType(UA_NodeId const *id);
 
@@ -456,7 +453,7 @@ typedef struct UA_Encoding {
 struct UA_VTable_Entry {
     UA_NodeId     typeId;
     UA_Byte       *name;
-    UA_StatusCode (*new)(void **p);
+    void *        (*new)();
     void          (*init)(void *p);
     UA_StatusCode (*copy)(void const *src, void *dst);
     void          (*delete)(void *p);
@@ -483,11 +480,10 @@ struct UA_VTable_Entry {
     UA_TYPE_COPY_DEFAULT(TYPE)           \
     
 #define UA_TYPE_NEW_DEFAULT(TYPE)                             \
-    UA_StatusCode TYPE##_new(TYPE **p) {                      \
-        if(!(*p = UA_alloc(sizeof(TYPE))))                    \
-            return UA_STATUSCODE_BADOUTOFMEMORY;              \
-        TYPE##_init(*p);                                      \
-        return UA_STATUSCODE_GOOD;                            \
+    TYPE * TYPE##_new() {                                     \
+        TYPE *p = UA_alloc(sizeof(TYPE));                     \
+        if(p) TYPE##_init(p);                                 \
+        return p;                                             \
     }
 
 #define UA_TYPE_INIT_DEFAULT(TYPE) \
@@ -525,16 +521,19 @@ struct UA_VTable_Entry {
     }
 
 #define UA_TYPE_COPY_AS(TYPE, TYPE_AS)                         \
-    UA_StatusCode TYPE##_copy(TYPE const *src, TYPE *dst) {         \
+    UA_StatusCode TYPE##_copy(TYPE const *src, TYPE *dst) {    \
         return TYPE_AS##_copy((TYPE_AS *)src, (TYPE_AS *)dst); \
     }
 
+#ifdef DEBUG //print functions only in debug mode
 #define UA_TYPE_PRINT_AS(TYPE, TYPE_AS)              \
     void TYPE##_print(TYPE const *p, FILE *stream) { \
         TYPE_AS##_print((TYPE_AS *)p, stream);       \
-    }                                                \
+    }
+#else
+#define UA_TYPE_PRINT_AS(TYPE, TYPE_AS)
+#endif
 
-#ifdef DEBUG //print functions only in debug mode
 #define UA_TYPE_AS(TYPE, TYPE_AS)           \
     UA_TYPE_NEW_DEFAULT(TYPE)               \
     UA_TYPE_INIT_AS(TYPE, TYPE_AS)          \
@@ -542,14 +541,6 @@ struct UA_VTable_Entry {
     UA_TYPE_DELETEMEMBERS_AS(TYPE, TYPE_AS) \
     UA_TYPE_COPY_AS(TYPE, TYPE_AS)          \
     UA_TYPE_PRINT_AS(TYPE, TYPE_AS)
-#else
-#define UA_TYPE_AS(TYPE, TYPE_AS)           \
-    UA_TYPE_NEW_DEFAULT(TYPE)               \
-    UA_TYPE_INIT_AS(TYPE, TYPE_AS)          \
-    UA_TYPE_DELETE_AS(TYPE, TYPE_AS)        \
-    UA_TYPE_DELETEMEMBERS_AS(TYPE, TYPE_AS) \
-    UA_TYPE_COPY_AS(TYPE, TYPE_AS)
-#endif
 
 /// @} /* end of group */
 

src/server/ua_services_monitoreditems.c → src/ongoing/ua_services_monitoreditems.c


+ 26 - 26
src/server/nodestore/open62541_nodestore_attribute.c

@@ -21,10 +21,10 @@ static UA_DataValue service_read_node(UA_Server *server,
 	UA_DataValue v;
 	UA_DataValue_init(&v);
 
-	UA_Node const *node = UA_NULL;
+	UA_Node const *node = NULL;
 	open62541NodeStore *ns = open62541NodeStore_getNodeStore();
 	UA_Int32 result = open62541NodeStore_get(ns, &(id->nodeId), &node);
-	if (result != UA_STATUSCODE_GOOD || node == UA_NULL) {
+	if (result != UA_STATUSCODE_GOOD || node == NULL) {
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
 		v.status = UA_STATUSCODE_BADNODEIDUNKNOWN;
 		return v;
@@ -34,44 +34,44 @@ static UA_DataValue service_read_node(UA_Server *server,
 	switch (id->attributeId) {
 	case UA_ATTRIBUTEID_NODEID:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_NODEID],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_NODEID],
 				&node->nodeId);
 		break;
 
 	case UA_ATTRIBUTEID_NODECLASS:
 
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_INT32],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_INT32],
 				&node->nodeClass);
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 		break;
 
 	case UA_ATTRIBUTEID_BROWSENAME:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_QUALIFIEDNAME],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_QUALIFIEDNAME],
 				&node->browseName);
 		break;
 
 	case UA_ATTRIBUTEID_DISPLAYNAME:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT],
 				&node->displayName);
 		break;
 
 	case UA_ATTRIBUTEID_DESCRIPTION:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT],
 				&node->description);
 		break;
 
 	case UA_ATTRIBUTEID_WRITEMASK:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_UINT32],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_UINT32],
 				&node->writeMask);
 		break;
 
 	case UA_ATTRIBUTEID_USERWRITEMASK:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_UINT32],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_UINT32],
 				&node->userWriteMask);
 		break;
 
@@ -81,7 +81,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 						| UA_NODECLASS_VARIABLETYPE | UA_NODECLASS_DATATYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_ReferenceTypeNode *) node)->isAbstract);
 		break;
 
@@ -89,7 +89,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_ReferenceTypeNode *) node)->symmetric);
 		break;
 
@@ -97,7 +97,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT],
 				&((UA_ReferenceTypeNode *) node)->inverseName);
 		break;
 
@@ -105,7 +105,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VIEW)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_ViewNode *) node)->containsNoLoops);
 		break;
 
@@ -113,7 +113,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
 				&((UA_ViewNode *) node)->eventNotifier);
 		break;
 
@@ -128,7 +128,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_NODEID],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_NODEID],
 				&((UA_VariableTypeNode *) node)->dataType);
 		break;
 
@@ -136,7 +136,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_INT32],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_INT32],
 				&((UA_VariableTypeNode *) node)->valueRank);
 		break;
 
@@ -144,7 +144,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		UA_Variant_copySetArray(&v.value, &UA_[UA_UINT32],
+		UA_Variant_copySetArray(&v.value, &UA_TYPES[UA_UINT32],
 				((UA_VariableTypeNode *) node)->arrayDimensionsSize,
 				&((UA_VariableTypeNode *) node)->arrayDimensions);
 		break;
@@ -153,7 +153,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
 				&((UA_VariableNode *) node)->accessLevel);
 		break;
 
@@ -161,7 +161,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
 				&((UA_VariableNode *) node)->userAccessLevel);
 		break;
 
@@ -169,7 +169,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_DOUBLE],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_DOUBLE],
 				&((UA_VariableNode *) node)->minimumSamplingInterval);
 		break;
 
@@ -177,7 +177,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_VariableNode *) node)->historizing);
 		break;
 
@@ -185,7 +185,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_METHOD)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_MethodNode *) node)->executable);
 		break;
 
@@ -193,7 +193,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_METHOD)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_MethodNode *) node)->userExecutable);
 		break;
 
@@ -219,7 +219,7 @@ UA_Int32 open62541NodeStore_ReadNodes(const UA_RequestHeader *requestHeader,
 		UA_DataValue *readNodesResults, UA_Boolean timeStampToReturn,
 		UA_DiagnosticInfo *diagnosticInfos) {
 	for (UA_UInt32 i = 0; i < indicesSize; i++) {
-		readNodesResults[indices[i]] = service_read_node(UA_NULL,
+		readNodesResults[indices[i]] = service_read_node(NULL,
 				&readValueIds[indices[i]]);
 	}
 	return UA_STATUSCODE_GOOD;
@@ -361,9 +361,9 @@ UA_Int32 UA_EXPORT open62541NodeStore_WriteNodes(
 		const UA_RequestHeader *requestHeader, UA_WriteValue *writeValues,
 		UA_UInt32 *indices, UA_UInt32 indicesSize,
 		UA_StatusCode *writeNodesResults, UA_DiagnosticInfo *diagnosticInfo) {
-	open62541NodeStore *nodestore = UA_NULL;
+	open62541NodeStore *nodestore = NULL;
 	nodestore = open62541NodeStore_getNodeStore();
-	if (nodestore == UA_NULL) {
+	if (nodestore == NULL) {
 		return UA_STATUSCODE_BADINTERNALERROR;
 	}
 

+ 2 - 2
src/server/nodestore/open62541_nodestore_core.c

@@ -191,7 +191,7 @@ static INLINE UA_StatusCode find_entry(const open62541NodeStore *ns,
 		return UA_STATUSCODE_BADINTERNALERROR;
 	}
 
-	if (UA_NodeId_equal(&(*e)->nodeId, nodeid) == UA_EQUAL) {
+	if (UA_NodeId_equal(&(*e)->nodeId, nodeid)) {
 		*entry = e;
 		return UA_STATUSCODE_GOOD;
 	}
@@ -209,7 +209,7 @@ static INLINE UA_StatusCode find_entry(const open62541NodeStore *ns,
 			return UA_STATUSCODE_BADINTERNALERROR;
 		}
 
-		if (UA_NodeId_equal(&(*e)->nodeId, nodeid) == UA_EQUAL) {
+		if (UA_NodeId_equal(&(*e)->nodeId, nodeid)) {
 			*entry = e;
 			return UA_STATUSCODE_GOOD;
 		}

+ 5 - 5
src/server/nodestore/open62541_nodestore_nodemanagement.c

@@ -182,8 +182,7 @@ UA_Int32 open62541NodeStore_AddReferences(const UA_RequestHeader *requestHeader,
 
 	    UA_memcpy(new_refs, old_refs, sizeof(UA_ReferenceNode)*count);
 
-	    UA_ReferenceNode *reference;
-	    UA_ReferenceNode_new(&reference);
+	    UA_ReferenceNode *reference = UA_ReferenceNode_new();
 
 	    reference->isInverse = !referencesToAdd[indices[i]].isForward;
 	    UA_NodeId_copy(&referencesToAdd[indices[i]].referenceTypeId,&reference->referenceTypeId);
@@ -241,7 +240,8 @@ UA_Int32 open62541NodeStore_AddNodes(const UA_RequestHeader *requestHeader,UA_Ad
 			case UA_NODECLASS_OBJECT:
 			{
 				UA_ObjectAttributes attributes;
-				UA_ObjectNode_new((UA_ObjectNode**)&newNode);
+
+				newNode = (UA_Node*)UA_ObjectNode_new();
 				newNode->nodeClass = UA_NODECLASS_OBJECT;
 				UA_ObjectAttributes_decodeBinary(&nodesToAdd[indices[i]].nodeAttributes.body,&offset,&attributes);
 				UA_ObjectNode_setAttributes((UA_ObjectAttributes*)&attributes, (UA_ObjectNode*)newNode);
@@ -256,7 +256,7 @@ UA_Int32 open62541NodeStore_AddNodes(const UA_RequestHeader *requestHeader,UA_Ad
 			case UA_NODECLASS_REFERENCETYPE:
 			{
 				UA_ReferenceTypeAttributes attributes;
-				UA_ReferenceTypeNode_new((UA_ReferenceTypeNode**)&newNode);
+				newNode = (UA_Node*)UA_ReferenceTypeNode_new();
 				newNode->nodeClass = UA_NODECLASS_REFERENCETYPE;
 				UA_ReferenceTypeAttributes_decodeBinary(&nodesToAdd[indices[i]].nodeAttributes.body,&offset,&attributes);
 				UA_ReferenceTypeNode_setAttributes((UA_ReferenceTypeAttributes*)&attributes,(UA_ReferenceTypeNode*)newNode);
@@ -265,7 +265,7 @@ UA_Int32 open62541NodeStore_AddNodes(const UA_RequestHeader *requestHeader,UA_Ad
 			case UA_NODECLASS_VARIABLE:
 			{
 				UA_VariableAttributes attributes;
-				UA_VariableNode_new((UA_VariableNode**)&newNode);
+				newNode = (UA_Node*)UA_VariableNode_new();
 				newNode->nodeClass = UA_NODECLASS_VARIABLE;
 				UA_VariableAttributes_decodeBinary(&nodesToAdd[indices[i]].nodeAttributes.body,&offset,&attributes);
 				UA_VariableNode_setAttributes((UA_VariableAttributes*)&attributes,(UA_VariableNode*)newNode);

+ 179 - 153
src/server/nodestore/open62541_nodestore_view.c

@@ -9,194 +9,220 @@
 #include "ua_namespace_0.h"
 #include "ua_util.h"
 
-UA_Int32 Service_Browse_getReferenceDescription(open62541NodeStore *ns, UA_ReferenceNode *reference,
-                                                UA_UInt32 nodeClassMask, UA_UInt32 resultMask,
-                                                UA_ReferenceDescription *referenceDescription) {
-    const UA_Node *foundNode;
-    if(open62541NodeStore_get(ns, &reference->targetId.nodeId, &foundNode) != UA_STATUSCODE_GOOD)
-    	return UA_STATUSCODE_BADINTERNALERROR;
-
-    UA_NodeId_copy(&foundNode->nodeId, &referenceDescription->nodeId.nodeId);
-    //TODO ExpandedNodeId is a mockup
+
+
+/* Releases the current node, even if it was supplied as an argument. */
+static UA_StatusCode fillReferenceDescription(open62541NodeStore *ns, const UA_Node *currentNode, UA_ReferenceNode *reference,
+                                              UA_UInt32 resultMask, UA_ReferenceDescription *referenceDescription) {
+    UA_ReferenceDescription_init(referenceDescription);
+    if(!currentNode && resultMask != 0) {
+        if(open62541NodeStore_get(ns, &reference->targetId.nodeId, &currentNode) != UA_STATUSCODE_GOOD)
+            return UA_STATUSCODE_BADINTERNALERROR;
+    }
+
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
+    retval |= UA_NodeId_copy(&currentNode->nodeId, &referenceDescription->nodeId.nodeId);
+    //TODO: ExpandedNodeId is mocked up
     referenceDescription->nodeId.serverIndex = 0;
     referenceDescription->nodeId.namespaceUri.length = -1;
 
-    /* UA_UInt32 mask = 0; */
-    /* for(mask = 0x01;mask <= 0x40;mask *= 2) { */
-    /*     switch(mask & (resultMask)) { */
     if(resultMask & UA_BROWSERESULTMASK_REFERENCETYPEID)
-        UA_NodeId_copy(&reference->referenceTypeId, &referenceDescription->referenceTypeId);
+        retval |= UA_NodeId_copy(&reference->referenceTypeId, &referenceDescription->referenceTypeId);
     if(resultMask & UA_BROWSERESULTMASK_ISFORWARD)
         referenceDescription->isForward = !reference->isInverse;
     if(resultMask & UA_BROWSERESULTMASK_NODECLASS)
-        UA_NodeClass_copy(&foundNode->nodeClass, &referenceDescription->nodeClass);
+        retval |= UA_NodeClass_copy(&currentNode->nodeClass, &referenceDescription->nodeClass);
     if(resultMask & UA_BROWSERESULTMASK_BROWSENAME)
-        UA_QualifiedName_copy(&foundNode->browseName, &referenceDescription->browseName);
+        retval |= UA_QualifiedName_copy(&currentNode->browseName, &referenceDescription->browseName);
     if(resultMask & UA_BROWSERESULTMASK_DISPLAYNAME)
-        UA_LocalizedText_copy(&foundNode->displayName, &referenceDescription->displayName);
-    if(resultMask & UA_BROWSERESULTMASK_TYPEDEFINITION) {
-        if(foundNode->nodeClass != UA_NODECLASS_OBJECT &&
-           foundNode->nodeClass != UA_NODECLASS_VARIABLE)
-            goto end;
-
-        for(UA_Int32 i = 0;i < foundNode->referencesSize;i++) {
-            UA_ReferenceNode *ref = &foundNode->references[i];
+        retval |= UA_LocalizedText_copy(&currentNode->displayName, &referenceDescription->displayName);
+    if(resultMask & UA_BROWSERESULTMASK_TYPEDEFINITION && currentNode->nodeClass != UA_NODECLASS_OBJECT &&
+       currentNode->nodeClass != UA_NODECLASS_VARIABLE) {
+        for(UA_Int32 i = 0;i < currentNode->referencesSize;i++) {
+            UA_ReferenceNode *ref = &currentNode->references[i];
             if(ref->referenceTypeId.identifier.numeric == 40 /* hastypedefinition */) {
-                UA_ExpandedNodeId_copy(&ref->targetId, &referenceDescription->typeDefinition);
-                goto end;
+                retval |= UA_ExpandedNodeId_copy(&ref->targetId, &referenceDescription->typeDefinition);
+                break;
             }
         }
     }
- end:
-    open62541NodeStore_releaseManagedNode(foundNode);
-    return UA_STATUSCODE_GOOD;
-}
 
-/* singly-linked list */
-struct SubRefTypeId {
-    UA_NodeId id;
-    SLIST_ENTRY(SubRefTypeId) next;
-};
-SLIST_HEAD(SubRefTypeIdList, SubRefTypeId);
-
-static UA_UInt32 walkReferenceTree(open62541NodeStore *ns, const UA_ReferenceTypeNode *current,
-                                   struct SubRefTypeIdList *list) {
-    // insert the current referencetype
-    struct SubRefTypeId *element = UA_alloc(sizeof(struct SubRefTypeId));
-    element->id = current->nodeId;
-    SLIST_INSERT_HEAD(list, element, next);
-
-    UA_UInt32 count = 1; // the current element
-
-    // walk the tree
-    for(UA_Int32 i = 0;i < current->referencesSize;i++) {
-        if(current->references[i].referenceTypeId.identifier.numeric == 45 /* HasSubtype */ &&
-           current->references[i].isInverse == UA_FALSE) {
-            const UA_Node *node;
-            if(open62541NodeStore_get(ns, &current->references[i].targetId.nodeId, &node) == UA_STATUSCODE_GOOD
-               && node->nodeClass == UA_NODECLASS_REFERENCETYPE) {
-                count += walkReferenceTree(ns, (UA_ReferenceTypeNode *)node, list);
-                open62541NodeStore_releaseManagedNode(node);
-            }
-        }
-    }
-    return count;
+    if(currentNode)
+    	open62541NodeStore_releaseManagedNode(currentNode);
+    if(retval)
+        UA_ReferenceDescription_deleteMembers(referenceDescription);
+    return retval;
 }
 
-/* We do not search across namespaces so far. The id of the father-referencetype is returned in the array also. */
-static UA_Int32 findSubReferenceTypes(open62541NodeStore *ns, UA_NodeId *rootReferenceType,
-                                      UA_NodeId **ids, UA_UInt32 *idcount) {
-    struct SubRefTypeIdList list;
-    UA_UInt32 count;
-    SLIST_INIT(&list);
-
-    // walk the tree
-    const UA_ReferenceTypeNode *root;
-
-    if(open62541NodeStore_get(ns, rootReferenceType, (const UA_Node **)&root) != UA_STATUSCODE_GOOD ||
-       root->nodeClass != UA_NODECLASS_REFERENCETYPE)
-        return UA_STATUSCODE_BADINTERNALERROR;
-    count = walkReferenceTree(ns, root, &list);
-    open62541NodeStore_releaseManagedNode((const UA_Node *)root);
-
-    // copy results into an array
-    *ids = UA_alloc(sizeof(UA_NodeId)*count);
-    for(UA_UInt32 i = 0;i < count;i++) {
-        struct SubRefTypeId *element = SLIST_FIRST(&list);
-        UA_NodeId_copy(&element->id, &(*ids)[i]);
-        SLIST_REMOVE_HEAD(&list, next);
-        UA_free(element);
+/* Tests if the node is relevant an shall be returned. If the targetNode needs
+   to be retrieved from the nodestore to determine this, the targetNode is
+   returned if the node is relevant. */
+static UA_Boolean isRelevantTargetNode(open62541NodeStore *ns, const UA_BrowseDescription *browseDescription, UA_Boolean returnAll,
+                                       UA_ReferenceNode *reference, const UA_Node **currentNode,
+                                       UA_NodeId *relevantRefTypes, UA_UInt32 relevantRefTypesCount) {
+    // 1) Test Browse direction
+    if(reference->isInverse == UA_TRUE && browseDescription->browseDirection == UA_BROWSEDIRECTION_FORWARD)
+        return UA_FALSE;
+
+    else if(reference->isInverse == UA_FALSE && browseDescription->browseDirection == UA_BROWSEDIRECTION_INVERSE)
+        return UA_FALSE;
+
+    // 2) Test if the reference type is relevant
+    UA_Boolean isRelevant = returnAll;
+    if(!isRelevant) {
+        for(UA_UInt32 i = 0;i < relevantRefTypesCount;i++) {
+            if(UA_NodeId_equal(&reference->referenceTypeId, &relevantRefTypes[i]))
+                isRelevant = UA_TRUE;
+        }
+        if(!isRelevant)
+            return UA_FALSE;
     }
-    *idcount = count;
 
-    return UA_STATUSCODE_GOOD;
-}
+    // 3) Test if the target nodeClass is relevant
+    if(browseDescription->nodeClassMask == 0)
+        return UA_TRUE; // the node is relevant, but we didn't need to get it from the nodestore yet.
 
-/* is this a relevant reference? */
-static INLINE UA_Boolean Service_Browse_returnReference(UA_BrowseDescription *browseDescription,
-                                                        UA_ReferenceNode     *reference,
-                                                        UA_NodeId            *relevantRefTypes,
-                                                        UA_UInt32             relevantRefTypesCount) {
-    if(reference->isInverse == UA_TRUE &&
-       browseDescription->browseDirection == UA_BROWSEDIRECTION_FORWARD)
+    if(open62541NodeStore_get(ns, &reference->targetId.nodeId, currentNode) != UA_STATUSCODE_GOOD)
         return UA_FALSE;
-    else if(reference->isInverse == UA_FALSE &&
-            browseDescription->browseDirection == UA_BROWSEDIRECTION_INVERSE)
+
+    if(((*currentNode)->nodeClass & browseDescription->nodeClassMask) == 0) {
+    	open62541NodeStore_releaseManagedNode(*currentNode);
         return UA_FALSE;
-    for(UA_UInt32 i = 0;i < relevantRefTypesCount;i++) {
-        if(UA_NodeId_equal(&browseDescription->referenceTypeId, &relevantRefTypes[i]) == UA_EQUAL)
-            return UA_TRUE;
     }
-    return UA_FALSE;
+
+    // the node is relevant and was retrieved from the nodestore, do not release it.
+    return UA_TRUE;
 }
 
-/* Return results to a single browsedescription. */
-static void NodeStore_Browse_getBrowseResult(open62541NodeStore         *ns,
-                                           UA_BrowseDescription *browseDescription,
-                                           UA_UInt32             maxReferences,
-                                           UA_BrowseResult      *browseResult) {
-    const UA_Node *node;
-    UA_NodeId     *relevantReferenceTypes = UA_NULL;
-    UA_UInt32      relevantReferenceTypesCount = 0;
-    if(open62541NodeStore_get(ns, &browseDescription->nodeId, &node) != UA_STATUSCODE_GOOD) {
-        browseResult->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
-        return;
+/* We do not search across namespaces so far. The id of the root-referencetype
+   is returned in the array also. */
+static UA_StatusCode findRelevantReferenceTypes(open62541NodeStore *ns, const UA_NodeId *rootReferenceType,
+                                                UA_NodeId **referenceTypes, UA_UInt32 *referenceTypesSize) {
+    /* The references form a tree. We walk the tree by adding new nodes to the end of the array. */
+    UA_UInt32 currentIndex = 0;
+    UA_UInt32 currentLastIndex = 0;
+    UA_UInt32 currentArraySize = 20; // should be more than enough. if not, increase the array size.
+    UA_NodeId *typeArray = UA_alloc(sizeof(UA_NodeId) * currentArraySize);
+    if(!typeArray)
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
+    retval |= UA_NodeId_copy(rootReferenceType, &typeArray[0]);
+    if(retval) {
+        UA_free(typeArray);
+        return UA_STATUSCODE_BADOUTOFMEMORY;
     }
 
-    // 0 => unlimited references
-    if(maxReferences == 0)
-        maxReferences = node->referencesSize;
-
-    // discover the relevant subtypes
-    if(!browseDescription->includeSubtypes ||
-       findSubReferenceTypes(ns, &browseDescription->referenceTypeId, &relevantReferenceTypes,
-                             &relevantReferenceTypesCount) != UA_STATUSCODE_GOOD) {
-        if(!(relevantReferenceTypes = UA_alloc(sizeof(UA_NodeId)))) {
-            return;
-        }
-        UA_NodeId_copy(&browseDescription->referenceTypeId, relevantReferenceTypes);
-        relevantReferenceTypesCount = 1;
-    }
+    const UA_ReferenceTypeNode *node;
+    do {
+        retval |= open62541NodeStore_get(ns, &typeArray[currentIndex], (const UA_Node **)&node);
+        if(retval)
+            break;
+        if(node->nodeClass != UA_NODECLASS_REFERENCETYPE) // subtypes of referencestypes are always referencestypes?
+            continue;
 
-    /* We do not use a linked list but traverse the nodes references list twice
-     * (once for counting, once for generating the referencedescriptions). That
-     * is much faster than using a linked list, since the references are
-     * allocated in a continuous blob and RAM access is predictible/does not
-     * miss cache lines so often. TODO: measure with some huge objects! */
-    UA_UInt32 refs = 0;
-    for(UA_Int32 i = 0;i < node->referencesSize && refs <= maxReferences;i++) {
-        if(Service_Browse_returnReference(browseDescription, &node->references[i], relevantReferenceTypes,
-                                          relevantReferenceTypesCount))
-            refs++;
-    }
+        // Find subtypes of the current referencetype
+        for(UA_Int32 i = 0; i < node->referencesSize && retval == UA_STATUSCODE_GOOD; i++) {
+            if(node->references[i].referenceTypeId.identifier.numeric != 45 /* HasSubtype */ ||
+               node->references[i].isInverse == UA_TRUE)
+                continue;
+
+            if(currentLastIndex + 1 >= currentArraySize) {
+                // we need to resize the array
+                UA_NodeId *newArray = UA_alloc(sizeof(UA_NodeId) * currentArraySize * 2);
+                if(newArray) {
+                    memcpy(newArray, typeArray, sizeof(UA_NodeId) * currentArraySize);
+                    currentArraySize *= 2;
+                    UA_free(typeArray);
+                    typeArray = newArray;
+                } else {
+                    retval = UA_STATUSCODE_BADOUTOFMEMORY;
+                    break;
+                }
+            }
 
-    // can we return all relevant references at once?
-    UA_Boolean finished = UA_TRUE;
-    if(refs > maxReferences) {
-        refs--;
-        finished = UA_FALSE;
+            // ok, we have space to add the new referencetype.
+            retval |= UA_NodeId_copy(&node->references[i].targetId.nodeId, &typeArray[++currentLastIndex]);
+            if(retval)
+                currentLastIndex--; // undo if we need to delete the typeArray
+        }
+        open62541NodeStore_releaseManagedNode((UA_Node*)node);
+    } while(++currentIndex <= currentLastIndex && retval == UA_STATUSCODE_GOOD);
+
+    if(retval)
+        UA_Array_delete(typeArray, currentLastIndex, &UA_TYPES[UA_NODEID]);
+    else {
+        *referenceTypes = typeArray;
+        *referenceTypesSize = currentLastIndex + 1;
     }
 
-    browseResult->referencesSize = refs;
-    UA_Array_new((void **)&browseResult->references, refs, &UA_[UA_REFERENCEDESCRIPTION]);
+    return retval;
+}
 
-    for(UA_UInt32 i = 0, j = 0;j < refs;i++) {
-        if(!Service_Browse_returnReference(browseDescription, &node->references[i], relevantReferenceTypes,
-                                           relevantReferenceTypesCount))
-            continue;
+/* Results for a single browsedescription. */
+static void getBrowseResult(open62541NodeStore *ns, const UA_BrowseDescription *browseDescription,
+                            UA_UInt32 maxReferences, UA_BrowseResult *browseResult) {
+    UA_UInt32  relevantReferenceTypesSize = 0;
+    UA_NodeId *relevantReferenceTypes = UA_NULL;
+
+    // if the referencetype is null, all referencetypes are returned
+    UA_Boolean returnAll = UA_NodeId_isNull(&browseDescription->referenceTypeId);
+    if(!returnAll) {
+        if(browseDescription->includeSubtypes) {
+            browseResult->statusCode = findRelevantReferenceTypes(ns, &browseDescription->referenceTypeId,
+                                                                  &relevantReferenceTypes, &relevantReferenceTypesSize);
+            if(browseResult->statusCode != UA_STATUSCODE_GOOD)
+                return;
+        } else {
+            relevantReferenceTypes = (UA_NodeId*)&browseDescription->referenceTypeId; // is const
+            relevantReferenceTypesSize = 1;
+        }
+    }
 
-        if(Service_Browse_getReferenceDescription(ns, &node->references[i], browseDescription->nodeClassMask,
-                                                  browseDescription->resultMask, &browseResult->references[j]) != UA_STATUSCODE_GOOD)
-            browseResult->statusCode = UA_STATUSCODE_UNCERTAINNOTALLNODESAVAILABLE;
-        j++;
+    const UA_Node *parentNode;
+    if(open62541NodeStore_get(ns, &browseDescription->nodeId, &parentNode) != UA_STATUSCODE_GOOD) {
+        browseResult->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
+        if(!returnAll && browseDescription->includeSubtypes)
+            UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesSize, &UA_TYPES[UA_NODEID]);
+        return;
     }
 
-    if(!finished) {
-        // Todo. Set the Statuscode and the continuation point.
+    // 0 => unlimited references
+    if(maxReferences == 0 || maxReferences > UA_INT32_MAX || (UA_Int32)maxReferences > parentNode->referencesSize)
+        maxReferences = parentNode->referencesSize;
+
+    /* We allocate an array that is probably too big. But since most systems
+       have more than enough memory, this has zero impact on speed and
+       performance. Call Array_delete with the actual content size! */
+    browseResult->references = UA_alloc(sizeof(UA_ReferenceDescription) * maxReferences);
+    if(!browseResult->references) {
+        browseResult->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
+    } else {
+        UA_UInt32 currentRefs = 0;
+        for(UA_Int32 i = 0;i < parentNode->referencesSize && currentRefs < maxReferences;i++) {
+            // 1) Is the node relevant? This might retrieve the node from the nodestore
+            const UA_Node *currentNode = UA_NULL;
+            if(!isRelevantTargetNode(ns, browseDescription, returnAll, &parentNode->references[i], &currentNode,
+                                     relevantReferenceTypes, relevantReferenceTypesSize))
+                continue;
+
+            // 2) Fill the reference description. This also releases the current node.
+            if(fillReferenceDescription(ns, currentNode, &parentNode->references[i], browseDescription->resultMask,
+                                        &browseResult->references[currentRefs]) != UA_STATUSCODE_GOOD) {
+                UA_Array_delete(browseResult->references, currentRefs, &UA_TYPES[UA_REFERENCEDESCRIPTION]);
+                currentRefs = 0;
+                browseResult->references = UA_NULL;
+                browseResult->statusCode = UA_STATUSCODE_UNCERTAINNOTALLNODESAVAILABLE;
+                break;
+            }
+            currentRefs++;
+        }
+        browseResult->referencesSize = currentRefs;
     }
 
-    open62541NodeStore_releaseManagedNode(node);
-    UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesCount, &UA_[UA_NODEID]);
+    open62541NodeStore_releaseManagedNode(parentNode);
+    if(!returnAll && browseDescription->includeSubtypes)
+        UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesSize, &UA_TYPES[UA_NODEID]);
 }
 
 UA_Int32 open62541NodeStore_BrowseNodes(const UA_RequestHeader *requestHeader,UA_BrowseDescription *browseDescriptions,UA_UInt32 *indices,UA_UInt32 indicesSize, UA_UInt32 requestedMaxReferencesPerNode,
@@ -205,7 +231,7 @@ UA_Int32 open62541NodeStore_BrowseNodes(const UA_RequestHeader *requestHeader,UA
 
 
 	for(UA_UInt32 i = 0; i < indicesSize; i++){
-		NodeStore_Browse_getBrowseResult(open62541NodeStore_getNodeStore(),&browseDescriptions[indices[i]],requestedMaxReferencesPerNode, &browseResults[indices[i]]);
+		getBrowseResult(open62541NodeStore_getNodeStore(),&browseDescriptions[indices[i]],requestedMaxReferencesPerNode, &browseResults[indices[i]]);
 	}
 	return UA_STATUSCODE_GOOD;
 }

+ 3 - 2
src/server/ua_namespace_manager.c

@@ -4,8 +4,9 @@
  *  Created on: Oct 14, 2014
  *      Author: opcua
  */
-#include "ua_util.h"
 #include "ua_namespace_manager.h"
+#include "ua_util.h"
+
 
 
 
@@ -26,7 +27,7 @@ void UA_NamespaceManager_new(UA_NamespaceManager** namespaceManager)
 
 }
 
-UA_StatusCode UA_NamespaceManager_addNamespace(UA_NamespaceManager *namespaceManager, UA_UInt16 index, UA_NodeStore *nodeStore)
+UA_StatusCode UA_NamespaceManager_addNamespace(UA_NamespaceManager *namespaceManager,UA_UInt16 index, UA_NodeStore *nodeStore)
 {
 	if(namespaceManager->currentNamespaceCount<UA_UINT16_MAX){
 		namespaceManager->currentNamespaceCount++;

+ 5 - 5
src/server/ua_namespace_manager.h

@@ -11,15 +11,15 @@
 #include "ua_nodestore_interface.h"
 
 
-void UA_EXPORT UA_NamespaceManager_new(UA_NamespaceManager** namespaceManager);
+void  UA_NamespaceManager_new(UA_NamespaceManager** namespaceManager);
 
-UA_Int32 UA_EXPORT UA_NamespaceManager_addNamespace(UA_NamespaceManager *namespaceManager, UA_UInt16 index, UA_NodeStore *nodeStore);
+UA_Int32  UA_NamespaceManager_addNamespace(UA_NamespaceManager *namespaceManager, UA_UInt16 index, UA_NodeStore *nodeStore);
 
-UA_Int32 UA_EXPORT UA_NamespaceManager_removeNamespace(UA_NamespaceManager *namespaceManager,UA_UInt16 index);
+UA_Int32  UA_NamespaceManager_removeNamespace(UA_NamespaceManager *namespaceManager,UA_UInt16 index);
 
-UA_Int32 UA_EXPORT UA_NamespaceManager_getNamespace(UA_NamespaceManager *namespaceManager, UA_UInt16 index, UA_Namespace **ns);
+UA_Int32  UA_NamespaceManager_getNamespace(UA_NamespaceManager *namespaceManager, UA_UInt16 index, UA_Namespace **ns);
 
-UA_Int32 UA_EXPORT UA_NamespaceManager_setNodeStore(UA_NamespaceManager *namespaceManager,UA_UInt16 index, UA_NodeStore *nodeStore);
+UA_Int32  UA_NamespaceManager_setNodeStore(UA_NamespaceManager *namespaceManager,UA_UInt16 index, UA_NodeStore *nodeStore);
 
 
 

+ 21 - 29
src/server/ua_securechannel_manager.c

@@ -1,6 +1,5 @@
 #include "ua_securechannel_manager.h"
 #include "ua_session.h"
-#include "ua_util.h"
 #include "ua_statuscodes.h"
 
 struct channel_list_entry {
@@ -8,33 +7,19 @@ struct channel_list_entry {
     LIST_ENTRY(channel_list_entry) pointers;
 };
 
-struct UA_SecureChannelManager {
-    UA_Int32    maxChannelCount;
-    UA_DateTime maxChannelLifetime;
-    LIST_HEAD(channel_list, channel_list_entry) channels;
-    UA_MessageSecurityMode securityMode;
-    UA_String   endpointUrl;
-    UA_DateTime channelLifeTime;
-    UA_Int32    lastChannelId;
-    UA_UInt32   lastTokenId;
-};
-
-UA_StatusCode UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 maxChannelCount,
-                                          UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
-                                          UA_UInt32 startTokenId, UA_String *endpointUrl) {
-    if(!(*cm = UA_alloc(sizeof(UA_SecureChannelManager))))
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-    UA_SecureChannelManager *channelManager = *cm;
-    LIST_INIT(&channelManager->channels);
-    channelManager->lastChannelId      = startChannelId;
-    channelManager->lastTokenId        = startTokenId;
-    UA_String_copy(endpointUrl, &channelManager->endpointUrl);
-    channelManager->maxChannelLifetime = tokenLifetime;
-    channelManager->maxChannelCount    = maxChannelCount;
+UA_StatusCode UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
+                                           UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
+                                           UA_UInt32 startTokenId, UA_String *endpointUrl) {
+    LIST_INIT(&cm->channels);
+    cm->lastChannelId      = startChannelId;
+    cm->lastTokenId        = startTokenId;
+    UA_String_copy(endpointUrl, &cm->endpointUrl);
+    cm->maxChannelLifetime = tokenLifetime;
+    cm->maxChannelCount    = maxChannelCount;
     return UA_STATUSCODE_GOOD;
 }
 
-void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
+void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm) {
     struct channel_list_entry *entry = LIST_FIRST(&cm->channels);
     while(entry) {
         LIST_REMOVE(entry, pointers);
@@ -47,7 +32,6 @@ void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
         entry = LIST_FIRST(&cm->channels);
     }
     UA_String_deleteMembers(&cm->endpointUrl);
-    UA_free(cm);
 }
 
 UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager           *cm,
@@ -55,6 +39,9 @@ UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager           *cm
                                            const UA_OpenSecureChannelRequest *request,
                                            UA_OpenSecureChannelResponse      *response) {
     struct channel_list_entry *entry = UA_alloc(sizeof(struct channel_list_entry));
+    if(!entry)
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+
     UA_SecureChannel_init(&entry->channel);
 
     entry->channel.connection = conn;
@@ -66,15 +53,16 @@ UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager           *cm
         cm->maxChannelLifetime : request->requestedLifetime;
 
     switch(request->securityMode) {
-    case UA_SECURITYMODE_INVALID:
+    case UA_MESSAGESECURITYMODE_INVALID:
         printf("UA_SecureChannel_processOpenRequest - client demands invalid \n");
         break;
 
-    case UA_SECURITYMODE_NONE:
+    case UA_MESSAGESECURITYMODE_NONE:
         UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce);
         break;
 
-    case UA_SECURITYMODE_SIGNANDENCRYPT:
+    case UA_MESSAGESECURITYMODE_SIGN:
+    case UA_MESSAGESECURITYMODE_SIGNANDENCRYPT:
         printf("UA_SecureChannel_processOpenRequest - client demands signed & encrypted \n");
         //TODO check if senderCertificate and ReceiverCertificateThumbprint are present
         break;
@@ -134,6 +122,10 @@ UA_StatusCode UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt
     struct channel_list_entry *entry;
     LIST_FOREACH(entry, &cm->channels, pointers) {
         if(entry->channel.securityToken.channelId == channelId) {
+            if(entry->channel.connection)
+                entry->channel.connection->channel = UA_NULL; // remove pointer back to the channel
+            if(entry->channel.session)
+                entry->channel.session->channel = UA_NULL; // remove ponter back to the channel
             UA_SecureChannel_deleteMembers(&entry->channel);
             LIST_REMOVE(entry, pointers);
             UA_free(entry);

+ 16 - 4
src/server/ua_securechannel_manager.h

@@ -3,11 +3,23 @@
 
 #include "ua_server.h"
 #include "ua_securechannel.h"
+#include "ua_util.h"
 
-UA_StatusCode UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 maxChannelCount,
-                                          UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
-                                          UA_UInt32 startTokenId, UA_String *endpointUrl);
-void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm);
+typedef struct UA_SecureChannelManager {
+    LIST_HEAD(channel_list, channel_list_entry) channels; // doubly-linked list of channels
+    UA_Int32    maxChannelCount;
+    UA_DateTime maxChannelLifetime;
+    UA_MessageSecurityMode securityMode;
+    UA_String   endpointUrl;
+    UA_DateTime channelLifeTime;
+    UA_Int32    lastChannelId;
+    UA_UInt32   lastTokenId;
+} UA_SecureChannelManager;
+
+UA_StatusCode UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
+                                           UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
+                                           UA_UInt32 startTokenId, UA_String *endpointUrl);
+void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm);
 UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
                                            const UA_OpenSecureChannelRequest *request,
                                            UA_OpenSecureChannelResponse *response);

+ 92 - 598
src/server/ua_server.c

@@ -1,5 +1,4 @@
-#include "ua_server.h"
-
+#include "ua_server_internal.h"
 #include "ua_services_internal.h" // AddReferences
 #include "ua_namespace_0.h"
 #include "ua_securechannel_manager.h"
@@ -8,13 +7,14 @@
 #include "ua_util.h"
 #include "ua_services.h"
 
-UA_StatusCode UA_Server_deleteMembers(UA_Server *server) {
-	UA_ApplicationDescription_deleteMembers(&server->description);
-	UA_SecureChannelManager_delete(server->secureChannelManager);
-	UA_SessionManager_delete(server->sessionManager);
-	//   UA_NodeStoreExample_delete(server->nodestore);
-	UA_ByteString_deleteMembers(&server->serverCertificate);
-	return UA_STATUSCODE_GOOD;
+void UA_Server_delete(UA_Server *server) {
+    UA_ApplicationDescription_deleteMembers(&server->description);
+    UA_SecureChannelManager_deleteMembers(&server->secureChannelManager);
+    UA_SessionManager_deleteMembers(&server->sessionManager);
+    //UA_NodeStore_delete(server->nodestore);
+    UA_ByteString_deleteMembers(&server->serverCertificate);
+    UA_Array_delete(server->endpointDescriptions, server->endpointDescriptionsSize, &UA_TYPES[UA_ENDPOINTDESCRIPTION]);
+    UA_free(server);
 }
 void addSingleReference(UA_Namespace *namespace,
 		UA_AddReferencesItem *addReferencesItem) {
@@ -63,17 +63,17 @@ void ns0_addObjectNode(UA_Server *server, UA_NodeId REFTYPE_NODEID,
 			&addNodesItem.nodeAttributes.body, &offset);
 	addSingleNode(ns0, &addNodesItem);
 }
-void ns0_addVariableNode(UA_Server *server, UA_NodeId REFTYPE_NODEID,
-		UA_ExpandedNodeId REQ_NODEID, UA_ExpandedNodeId PARENTNODEID,
+void ns0_addVariableNode(UA_Server *server, UA_NodeId refTypeNodeId,
+		UA_ExpandedNodeId requestedNodeId, UA_ExpandedNodeId parentNodeId,
 		UA_QualifiedName browseName, UA_LocalizedText displayName, UA_LocalizedText description,
 		UA_DataValue *dataValue, UA_Int32 valueRank) {
 	UA_VariableAttributes varAttr;
 	UA_AddNodesItem addNodesItem;
 	UA_Namespace *ns0 = UA_NULL;
 	UA_NamespaceManager_getNamespace(server->namespaceManager, 0, &ns0);
-	addNodesItem.parentNodeId = PARENTNODEID;
-	addNodesItem.requestedNewNodeId = REQ_NODEID;
-	addNodesItem.referenceTypeId = REFTYPE_NODEID;
+	addNodesItem.parentNodeId = parentNodeId;
+	addNodesItem.requestedNewNodeId = requestedNodeId;
+	addNodesItem.referenceTypeId = refTypeNodeId;
 	addNodesItem.nodeClass = UA_NODECLASS_VARIABLE;
 	addNodesItem.browseName = browseName;
 	varAttr.displayName = displayName ;
@@ -108,28 +108,60 @@ void ns0_addVariableNode(UA_Server *server, UA_NodeId REFTYPE_NODEID,
 	addSingleNode(ns0, &addNodesItem);
 }
 
-void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
-	UA_ExpandedNodeId_init(&server->objectsNodeId);
-	server->objectsNodeId.nodeId.identifier.numeric = 85;
-
-	UA_NodeId_init(&server->hasComponentReferenceTypeId);
-	server->hasComponentReferenceTypeId.identifier.numeric = 47;
+UA_Server * UA_Server_new(UA_String *endpointUrl, UA_ByteString *serverCertificate, UA_NodeStore *ns0Nodestore) {
+    UA_Server *server = UA_alloc(sizeof(UA_Server));
+    if(!server)
+        return server;
+    //add namespace zero
+    UA_NamespaceManager_new(&server->namespaceManager);
+    UA_NamespaceManager_addNamespace(server->namespaceManager,0,ns0Nodestore);
+    
+
+    // mockup application description
+    UA_ApplicationDescription_init(&server->description);
+    UA_String_copycstring("urn:servername:open62541:application", &server->description.productUri);
+    UA_String_copycstring("http://open62541.info/applications/4711", &server->description.applicationUri);
+    UA_LocalizedText_copycstring("The open62541 application", &server->description.applicationName);
+    server->description.applicationType = UA_APPLICATIONTYPE_SERVER;
+
+    UA_ByteString_init(&server->serverCertificate);
+    if(serverCertificate)
+        UA_ByteString_copy(serverCertificate, &server->serverCertificate);
+
+    // mockup endpoint description
+    server->endpointDescriptionsSize = 1;
+    UA_EndpointDescription *endpoint = UA_alloc(sizeof(UA_EndpointDescription)); // todo: check return code
+
+    endpoint->securityMode = UA_MESSAGESECURITYMODE_NONE;
+    UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None", &endpoint->securityPolicyUri);
+    UA_String_copycstring("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary", &endpoint->transportProfileUri);
+
+    endpoint->userIdentityTokensSize = 1;
+    endpoint->userIdentityTokens = UA_alloc(sizeof(UA_UserTokenPolicy));
+    UA_UserTokenPolicy_init(endpoint->userIdentityTokens);
+    UA_String_copycstring("my-anonymous-policy", &endpoint->userIdentityTokens->policyId); // defined per server
+    endpoint->userIdentityTokens->tokenType = UA_USERTOKENTYPE_ANONYMOUS;
+
+    UA_String_copy(endpointUrl, &endpoint->endpointUrl);
+    /* The standard says "the HostName specified in the Server Certificate is the
+       same as the HostName contained in the endpointUrl provided in the
+       EndpointDescription */
+    UA_String_copy(&server->serverCertificate, &endpoint->serverCertificate);
+    UA_ApplicationDescription_copy(&server->description, &endpoint->server);
+    server->endpointDescriptions = endpoint;
 
-	UA_ApplicationDescription_init(&server->description);
-	UA_ByteString_init(&server->serverCertificate);
 #define MAXCHANNELCOUNT 100
 #define STARTCHANNELID 1
 #define TOKENLIFETIME 10000
 #define STARTTOKENID 1
-	UA_SecureChannelManager_new(&server->secureChannelManager, MAXCHANNELCOUNT,
-	TOKENLIFETIME, STARTCHANNELID, STARTTOKENID, endpointUrl);
+    UA_SecureChannelManager_init(&server->secureChannelManager, MAXCHANNELCOUNT,
+                                 TOKENLIFETIME, STARTCHANNELID, STARTTOKENID, endpointUrl);
+
 
 #define MAXSESSIONCOUNT 1000
 #define SESSIONLIFETIME 10000
 #define STARTSESSIONID 1
-	UA_SessionManager_new(&server->sessionManager, MAXSESSIONCOUNT,
-			SESSIONLIFETIME,
-			STARTSESSIONID);
+    UA_SessionManager_init(&server->sessionManager, MAXSESSIONCOUNT, SESSIONLIFETIME, STARTSESSIONID);
 
 	//ns0: C2UA_STRING("http://opcfoundation.org/UA/"));
 	//ns1: C2UA_STRING("http://localhost:16664/open62541/"));
@@ -261,43 +293,49 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
 
 
 	UA_DataValue *serverArrayValue;
-	UA_DataValue_new(&serverArrayValue);
+	serverArrayValue = UA_DataValue_new();
 	UA_UInt32 namespaceArraySize = 2;
 
-	UA_Array_new((void**)&serverArrayValue->value.storage.data.dataPtr, namespaceArraySize, &UA_[UA_STRING]);
+	UA_Array_new((void**)&serverArrayValue->value.storage.data.dataPtr, namespaceArraySize, &UA_TYPES[UA_STRING]);
 	UA_String_copycstring("http://opcfoundation.org/UA/", &((UA_String *)(serverArrayValue->value.storage.data.dataPtr))[0]);
 	UA_Int32 *arrayDim;
 	UA_UInt32 arrayDimSize = 1;
-	UA_Array_new((void**)&arrayDim, arrayDimSize, &UA_[UA_INT32]);
+	UA_Array_new((void**)&arrayDim, arrayDimSize, &UA_TYPES[UA_INT32]);
 
-	serverArrayValue->value.vt = &UA_[UA_STRING];
+	serverArrayValue->value.vt = &UA_TYPES[UA_STRING];
 	serverArrayValue->value.storage.data.arrayDimensions = arrayDim;
 	serverArrayValue->value.storage.data.arrayDimensionsLength = 1; // added to ensure encoding in readreponse
 	serverArrayValue->value.storage.data.arrayLength = 1;
 	serverArrayValue->value.storageType = UA_VARIANT_DATA;
 	 {
 		 UA_QualifiedName *browseName;
-		 UA_QualifiedName_new(&browseName);
+		 browseName=UA_QualifiedName_new();
 		 UA_LocalizedText *description;
-		 UA_LocalizedText_new(&description);
+		 description = UA_LocalizedText_new();
 		 UA_LocalizedText *displayName;
-		 UA_LocalizedText_new(&displayName);
+		 displayName = UA_LocalizedText_new();
 
 		 UA_QualifiedName_copycstring("NamespaceArray",browseName);
 		 UA_LocalizedText_copycstring("NamespaceArray",description);
 		 UA_LocalizedText_copycstring("NamespaceArray",displayName);
 
-		 ns0_addVariableNode(server,RefTypeId_HasComponent.nodeId,VarId_NamespaceArray,ObjId_Server, *browseName,*description, *displayName,serverArrayValue,1);
+		 ns0_addVariableNode(server, RefTypeId_HasComponent.nodeId,
+				 VarId_NamespaceArray,
+				 ObjId_Server,
+				 *browseName,
+				 *description,
+				 *displayName,
+				 serverArrayValue,1);
 	 }
 
 
 
 	 // ServerStatus
 	 UA_DataValue *serverStatusValue;
-	 UA_DataValue_new(&serverStatusValue);
+	 serverStatusValue = UA_DataValue_new();
 
 	 UA_ServerStatusDataType *status;
-	 UA_ServerStatusDataType_new(&status);
+	 status = UA_ServerStatusDataType_new();
 	 status->startTime   = UA_DateTime_now();
 	 status->currentTime = UA_DateTime_now();
 	 status->state       = UA_SERVERSTATE_RUNNING;
@@ -309,17 +347,14 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
 	 status->buildInfo.buildDate     = UA_DateTime_now();
 	 status->secondsTillShutdown     = 99999999;
 	 UA_LocalizedText_copycstring("because", &status->shutdownReason);
-	 serverStatusValue->value.vt          = &UA_[UA_SERVERSTATUSDATATYPE]; // gets encoded as an extensionobject
+	 serverStatusValue->value.vt          = &UA_TYPES[UA_SERVERSTATUSDATATYPE]; // gets encoded as an extensionobject
 	 serverStatusValue->value.storage.data.arrayLength = 0;
 	 serverStatusValue->value.storage.data.dataPtr        = status;
 	 serverStatusValue->value.storage.data.arrayDimensionsLength = 0;
 	 {
-		 UA_QualifiedName *browseName;
-		 UA_QualifiedName_new(&browseName);
-		 UA_LocalizedText *description;
-		 UA_LocalizedText_new(&description);
-		 UA_LocalizedText *displayName;
-		 UA_LocalizedText_new(&displayName);
+		 UA_QualifiedName *browseName = UA_QualifiedName_new();
+		 UA_LocalizedText *description = UA_LocalizedText_new();
+		 UA_LocalizedText *displayName = UA_LocalizedText_new();
 
 		 UA_QualifiedName_copycstring("ServerStatus",browseName);
 		 UA_LocalizedText_copycstring("ServerStatus",description);
@@ -330,22 +365,19 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
 
 	 // State (Component of ServerStatus)
 
-	 UA_DataValue *sateValue;
-	 UA_DataValue_new(&sateValue);
+	 UA_DataValue *sateValue = UA_DataValue_new();
+
 
-	 sateValue->value.vt = &UA_[UA_SERVERSTATE];
+	 sateValue->value.vt = &UA_TYPES[UA_SERVERSTATE];
 	 sateValue->value.storage.data.arrayDimensionsLength = 0; // added to ensure encoding in readreponse
 	 sateValue->value.storage.data.arrayLength = 0;
 	 sateValue->value.storage.data.dataPtr = &status->state; // points into the other object.
 	 sateValue->value.storageType = UA_VARIANT_DATA;
 
 	 {
-		 UA_QualifiedName *browseName;
-		 UA_QualifiedName_new(&browseName);
-		 UA_LocalizedText *description;
-		 UA_LocalizedText_new(&description);
-		 UA_LocalizedText *displayName;
-		 UA_LocalizedText_new(&displayName);
+		 UA_QualifiedName *browseName = UA_QualifiedName_new();
+		 UA_LocalizedText *description = UA_LocalizedText_new();
+		 UA_LocalizedText *displayName = UA_LocalizedText_new();
 
 		 UA_QualifiedName_copycstring("State",browseName);
 		 UA_LocalizedText_copycstring("State",description);
@@ -443,558 +475,19 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
 	ADD_REFTYPENODE_NS0(RefTypeId_HasSubtype.nodeId, RefTypeId_Organizes,
 			RefTypeId_HierarchicalReferences, "Organizes", "Organizes",
 			"Organizes", UA_TRUE, UA_FALSE);
-
-	/*UA_ReferenceTypeNode *references;
-	 UA_ReferenceTypeNode_new(&references);
-	 references->nodeId    = RefTypeId_References.nodeId;
-	 references->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("References", &references->browseName);
-	 UA_LocalizedText_copycstring("References", &references->displayName);
-	 UA_LocalizedText_copycstring("References", &references->description);
-	 references->isAbstract = UA_TRUE;
-	 references->symmetric  = UA_TRUE;
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&references, UA_NODESTORE_INSERT_UNIQUE);
-
-
-
-	 //addSingleNode()
-
-	 UA_ReferenceTypeNode *hierarchicalreferences;
-	 UA_ReferenceTypeNode_new(&hierarchicalreferences);
-	 hierarchicalreferences->nodeId    = RefTypeId_HierarchicalReferences.nodeId;
-	 hierarchicalreferences->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HierarchicalReferences", &hierarchicalreferences->browseName);
-	 UA_LocalizedText_copycstring("HierarchicalReferences", &hierarchicalreferences->displayName);
-	 UA_LocalizedText_copycstring("HierarchicalReferences", &hierarchicalreferences->description);
-	 hierarchicalreferences->isAbstract = UA_TRUE;
-	 hierarchicalreferences->symmetric  = UA_FALSE;
-
-	 ADDREFERENCE(hierarchicalreferences, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_References);
-
-
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hierarchicalreferences, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *nonhierarchicalreferences;
-	 UA_ReferenceTypeNode_new(&nonhierarchicalreferences);
-	 nonhierarchicalreferences->nodeId    = RefTypeId_NonHierarchicalReferences.nodeId;
-	 nonhierarchicalreferences->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("NonHierarchicalReferences", &nonhierarchicalreferences->browseName);
-	 UA_LocalizedText_copycstring("NonHierarchicalReferences", &nonhierarchicalreferences->displayName);
-	 UA_LocalizedText_copycstring("NonHierarchicalReferences", &nonhierarchicalreferences->description);
-	 nonhierarchicalreferences->isAbstract = UA_TRUE;
-	 nonhierarchicalreferences->symmetric  = UA_FALSE;
-	 ADDREFERENCE(nonhierarchicalreferences, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_References);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&nonhierarchicalreferences, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *haschild;
-	 UA_ReferenceTypeNode_new(&haschild);
-	 haschild->nodeId    = RefTypeId_HasChild.nodeId;
-	 haschild->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasChild", &haschild->browseName);
-	 UA_LocalizedText_copycstring("HasChild", &haschild->displayName);
-	 UA_LocalizedText_copycstring("HasChild", &haschild->description);
-	 haschild->isAbstract = UA_TRUE;
-	 haschild->symmetric  = UA_FALSE;
-	 ADDREFERENCE(haschild, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&haschild, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *organizes;
-	 UA_ReferenceTypeNode_new(&organizes);
-	 organizes->nodeId    = RefTypeId_Organizes.nodeId;
-	 organizes->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("Organizes", &organizes->browseName);
-	 UA_LocalizedText_copycstring("Organizes", &organizes->displayName);
-	 UA_LocalizedText_copycstring("Organizes", &organizes->description);
-	 organizes->isAbstract = UA_FALSE;
-	 organizes->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("OrganizedBy", &organizes->inverseName);
-	 ADDREFERENCE(organizes, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&organizes, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *haseventsource;
-	 UA_ReferenceTypeNode_new(&haseventsource);
-	 haseventsource->nodeId    = RefTypeId_HasEventSource.nodeId;
-	 haseventsource->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasEventSource", &haseventsource->browseName);
-	 UA_LocalizedText_copycstring("HasEventSource", &haseventsource->displayName);
-	 UA_LocalizedText_copycstring("HasEventSource", &haseventsource->description);
-	 haseventsource->isAbstract = UA_FALSE;
-	 haseventsource->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("EventSourceOf", &haseventsource->inverseName);
-	 ADDREFERENCE(haseventsource, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&haseventsource, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hasmodellingrule;
-	 UA_ReferenceTypeNode_new(&hasmodellingrule);
-	 hasmodellingrule->nodeId    = RefTypeId_HasModellingRule.nodeId;
-	 hasmodellingrule->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasModellingRule", &hasmodellingrule->browseName);
-	 UA_LocalizedText_copycstring("HasModellingRule", &hasmodellingrule->displayName);
-	 UA_LocalizedText_copycstring("HasModellingRule", &hasmodellingrule->description);
-	 hasmodellingrule->isAbstract = UA_FALSE;
-	 hasmodellingrule->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("ModellingRuleOf", &hasmodellingrule->inverseName);
-	 ADDREFERENCE(hasmodellingrule, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasmodellingrule, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hasencoding;
-	 UA_ReferenceTypeNode_new(&hasencoding);
-	 hasencoding->nodeId    = RefTypeId_HasEncoding.nodeId;
-	 hasencoding->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasEncoding", &hasencoding->browseName);
-	 UA_LocalizedText_copycstring("HasEncoding", &hasencoding->displayName);
-	 UA_LocalizedText_copycstring("HasEncoding", &hasencoding->description);
-	 hasencoding->isAbstract = UA_FALSE;
-	 hasencoding->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("EncodingOf", &hasencoding->inverseName);
-	 ADDREFERENCE(hasencoding, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasencoding, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hasdescription;
-	 UA_ReferenceTypeNode_new(&hasdescription);
-	 hasdescription->nodeId    = RefTypeId_HasDescription.nodeId;
-	 hasdescription->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasDescription", &hasdescription->browseName);
-	 UA_LocalizedText_copycstring("HasDescription", &hasdescription->displayName);
-	 UA_LocalizedText_copycstring("HasDescription", &hasdescription->description);
-	 hasdescription->isAbstract = UA_FALSE;
-	 hasdescription->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("DescriptionOf", &hasdescription->inverseName);
-	 ADDREFERENCE(hasdescription, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasdescription, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hastypedefinition;
-	 UA_ReferenceTypeNode_new(&hastypedefinition);
-	 hastypedefinition->nodeId    = RefTypeId_HasTypeDefinition.nodeId;
-	 hastypedefinition->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasTypeDefinition", &hastypedefinition->browseName);
-	 UA_LocalizedText_copycstring("HasTypeDefinition", &hastypedefinition->displayName);
-	 UA_LocalizedText_copycstring("HasTypeDefinition", &hastypedefinition->description);
-	 hastypedefinition->isAbstract = UA_FALSE;
-	 hastypedefinition->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("TypeDefinitionOf", &hastypedefinition->inverseName);
-	 ADDREFERENCE(hastypedefinition, RefTypeId_HasSubtype, UA_TRUE,  RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hastypedefinition, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *generatesevent;
-	 UA_ReferenceTypeNode_new(&generatesevent);
-	 generatesevent->nodeId    = RefTypeId_GeneratesEvent.nodeId;
-	 generatesevent->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("GeneratesEvent", &generatesevent->browseName);
-	 UA_LocalizedText_copycstring("GeneratesEvent", &generatesevent->displayName);
-	 UA_LocalizedText_copycstring("GeneratesEvent", &generatesevent->description);
-	 generatesevent->isAbstract = UA_FALSE;
-	 generatesevent->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("GeneratedBy", &generatesevent->inverseName);
-	 ADDREFERENCE(generatesevent, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&generatesevent, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *aggregates;
-	 UA_ReferenceTypeNode_new(&aggregates);
-	 aggregates->nodeId    = RefTypeId_Aggregates.nodeId;
-	 aggregates->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("Aggregates", &aggregates->browseName);
-	 UA_LocalizedText_copycstring("Aggregates", &aggregates->displayName);
-	 UA_LocalizedText_copycstring("Aggregates", &aggregates->description);
-	 aggregates->isAbstract = UA_TRUE;
-	 aggregates->symmetric  = UA_FALSE;
-	 ADDREFERENCE(aggregates, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HasChild);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&aggregates, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hassubtype;
-	 UA_ReferenceTypeNode_new(&hassubtype);
-	 hassubtype->nodeId    = RefTypeId_HasSubtype.nodeId;
-	 hassubtype->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasSubtype", &hassubtype->browseName);
-	 UA_LocalizedText_copycstring("HasSubtype", &hassubtype->displayName);
-	 UA_LocalizedText_copycstring("HasSubtype", &hassubtype->description);
-	 hassubtype->isAbstract = UA_FALSE;
-	 hassubtype->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("SubtypeOf", &hassubtype->inverseName);
-	 ADDREFERENCE(hassubtype, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HasChild);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hassubtype, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hasproperty;
-	 UA_ReferenceTypeNode_new(&hasproperty);
-	 hasproperty->nodeId    = RefTypeId_HasProperty.nodeId;
-	 hasproperty->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasProperty", &hasproperty->browseName);
-	 UA_LocalizedText_copycstring("HasProperty", &hasproperty->displayName);
-	 UA_LocalizedText_copycstring("HasProperty", &hasproperty->description);
-	 hasproperty->isAbstract = UA_FALSE;
-	 hasproperty->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("PropertyOf", &hasproperty->inverseName);
-	 ADDREFERENCE(hasproperty, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_Aggregates);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasproperty, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hascomponent;
-	 UA_ReferenceTypeNode_new(&hascomponent);
-	 hascomponent->nodeId    = RefTypeId_HasComponent.nodeId;
-	 hascomponent->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasComponent", &hascomponent->browseName);
-	 UA_LocalizedText_copycstring("HasComponent", &hascomponent->displayName);
-	 UA_LocalizedText_copycstring("HasComponent", &hascomponent->description);
-	 hascomponent->isAbstract = UA_FALSE;
-	 hascomponent->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("ComponentOf", &hascomponent->inverseName);
-	 ADDREFERENCE(hascomponent, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_Aggregates);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hascomponent, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hasnotifier;
-	 UA_ReferenceTypeNode_new(&hasnotifier);
-	 hasnotifier->nodeId    = RefTypeId_HasNotifier.nodeId;
-	 hasnotifier->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasNotifier", &hasnotifier->browseName);
-	 UA_LocalizedText_copycstring("HasNotifier", &hasnotifier->displayName);
-	 UA_LocalizedText_copycstring("HasNotifier", &hasnotifier->description);
-	 hasnotifier->isAbstract = UA_FALSE;
-	 hasnotifier->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("NotifierOf", &hasnotifier->inverseName);
-	 ADDREFERENCE(hasnotifier, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HasEventSource);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasnotifier, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hasorderedcomponent;
-	 UA_ReferenceTypeNode_new(&hasorderedcomponent);
-	 hasorderedcomponent->nodeId    = RefTypeId_HasOrderedComponent.nodeId;
-	 hasorderedcomponent->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasOrderedComponent", &hasorderedcomponent->browseName);
-	 UA_LocalizedText_copycstring("HasOrderedComponent", &hasorderedcomponent->displayName);
-	 UA_LocalizedText_copycstring("HasOrderedComponent", &hasorderedcomponent->description);
-	 hasorderedcomponent->isAbstract = UA_FALSE;
-	 hasorderedcomponent->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("OrderedComponentOf", &hasorderedcomponent->inverseName);
-	 ADDREFERENCE(hasorderedcomponent, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HasComponent);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasorderedcomponent, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hasmodelparent;
-	 UA_ReferenceTypeNode_new(&hasmodelparent);
-	 hasmodelparent->nodeId    = RefTypeId_HasModelParent.nodeId;
-	 hasmodelparent->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasModelParent", &hasmodelparent->browseName);
-	 UA_LocalizedText_copycstring("HasModelParent", &hasmodelparent->displayName);
-	 UA_LocalizedText_copycstring("HasModelParent", &hasmodelparent->description);
-	 hasmodelparent->isAbstract = UA_FALSE;
-	 hasmodelparent->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("ModelParentOf", &hasmodelparent->inverseName);
-	 ADDREFERENCE(hasmodelparent, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasmodelparent, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *fromstate;
-	 UA_ReferenceTypeNode_new(&fromstate);
-	 fromstate->nodeId    = RefTypeId_FromState.nodeId;
-	 fromstate->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("FromState", &fromstate->browseName);
-	 UA_LocalizedText_copycstring("FromState", &fromstate->displayName);
-	 UA_LocalizedText_copycstring("FromState", &fromstate->description);
-	 fromstate->isAbstract = UA_FALSE;
-	 fromstate->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("ToTransition", &fromstate->inverseName);
-	 ADDREFERENCE(fromstate, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&fromstate, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *tostate;
-	 UA_ReferenceTypeNode_new(&tostate);
-	 tostate->nodeId    = RefTypeId_ToState.nodeId;
-	 tostate->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("ToState", &tostate->browseName);
-	 UA_LocalizedText_copycstring("ToState", &tostate->displayName);
-	 UA_LocalizedText_copycstring("ToState", &tostate->description);
-	 tostate->isAbstract = UA_FALSE;
-	 tostate->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("FromTransition", &tostate->inverseName);
-	 ADDREFERENCE(tostate, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&tostate, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hascause;
-	 UA_ReferenceTypeNode_new(&hascause);
-	 hascause->nodeId    = RefTypeId_HasCause.nodeId;
-	 hascause->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasCause", &hascause->browseName);
-	 UA_LocalizedText_copycstring("HasCause", &hascause->displayName);
-	 UA_LocalizedText_copycstring("HasCause", &hascause->description);
-	 hascause->isAbstract = UA_FALSE;
-	 hascause->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("MayBeCausedBy", &hascause->inverseName);
-	 ADDREFERENCE(hascause, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hascause, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *haseffect;
-	 UA_ReferenceTypeNode_new(&haseffect);
-	 haseffect->nodeId    = RefTypeId_HasEffect.nodeId;
-	 haseffect->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasEffect", &haseffect->browseName);
-	 UA_LocalizedText_copycstring("HasEffect", &haseffect->displayName);
-	 UA_LocalizedText_copycstring("HasEffect", &haseffect->description);
-	 haseffect->isAbstract = UA_FALSE;
-	 haseffect->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("MayBeEffectedBy", &haseffect->inverseName);
-	 ADDREFERENCE(haseffect, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&haseffect, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_ReferenceTypeNode *hashistoricalconfiguration;
-	 UA_ReferenceTypeNode_new(&hashistoricalconfiguration);
-	 hashistoricalconfiguration->nodeId    = RefTypeId_HasHistoricalConfiguration.nodeId;
-	 hashistoricalconfiguration->nodeClass = UA_NODECLASS_REFERENCETYPE;
-	 UA_QualifiedName_copycstring("HasHistoricalConfiguration", &hashistoricalconfiguration->browseName);
-	 UA_LocalizedText_copycstring("HasHistoricalConfiguration", &hashistoricalconfiguration->displayName);
-	 UA_LocalizedText_copycstring("HasHistoricalConfiguration", &hashistoricalconfiguration->description);
-	 hashistoricalconfiguration->isAbstract = UA_FALSE;
-	 hashistoricalconfiguration->symmetric  = UA_FALSE;
-	 UA_LocalizedText_copycstring("HistoricalConfigurationOf", &hashistoricalconfiguration->inverseName);
-	 ADDREFERENCE(hashistoricalconfiguration, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_Aggregates);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hashistoricalconfiguration, UA_NODESTORE_INSERT_UNIQUE);
-
-	 */
-	/*
-
-	 // FolderType
-	 UA_ObjectNode *folderType;
-	 UA_ObjectNode_new(&folderType);
-	 folderType->nodeId    = NS0NODEID(61);
-	 folderType->nodeClass = UA_NODECLASS_OBJECTTYPE; // I should not have to set this manually
-	 UA_QualifiedName_copycstring("FolderType", &folderType->browseName);
-	 UA_LocalizedText_copycstring("FolderType", &folderType->displayName);
-	 UA_LocalizedText_copycstring("FolderType", &folderType->description);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&folderType, UA_NODESTORE_INSERT_UNIQUE);
-
-	 // Root
-	 UA_ObjectNode *root;
-	 UA_ObjectNode_new(&root);
-	 root->nodeId    = NS0NODEID(84);
-	 root->nodeClass = UA_NODECLASS_OBJECT; // I should not have to set this manually
-	 UA_QualifiedName_copycstring("Root", &root->browseName);
-	 UA_LocalizedText_copycstring("Root", &root->displayName);
-	 UA_LocalizedText_copycstring("Root", &root->description);
-	 ADDREFERENCE(root, RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType);
-	 ADDREFERENCE(root, RefTypeId_Organizes, UA_FALSE, ObjId_ObjectsFolder);
-	 ADDREFERENCE(root, RefTypeId_Organizes, UA_FALSE, ObjId_TypesFolder);
-	 ADDREFERENCE(root, RefTypeId_Organizes, UA_FALSE, ObjId_ViewsFolder);
-	 */
-	/* root becomes a managed node. we need to release it at the end.*/
-	/*
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&root, UA_NODESTORE_INSERT_UNIQUE | UA_NODESTORE_INSERT_GETMANAGED);
-
-
-
-	 // Objects
-	 UA_ObjectNode *objects;
-	 UA_ObjectNode_new(&objects);
-	 objects->nodeId    = ObjId_ObjectsFolder.nodeId;
-	 objects->nodeClass = UA_NODECLASS_OBJECT;
-	 UA_QualifiedName_copycstring("Objects", &objects->browseName);
-	 UA_LocalizedText_copycstring("Objects", &objects->displayName);
-	 UA_LocalizedText_copycstring("Objects", &objects->description);
-	 ADDREFERENCE(objects, RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType);
-	 ADDREFERENCE(objects, RefTypeId_Organizes, UA_FALSE, ObjId_Server);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&objects, UA_NODESTORE_INSERT_UNIQUE);
-
-	 // Types
-	 UA_ObjectNode *types;
-	 UA_ObjectNode_new(&types);
-	 types->nodeId    = ObjId_TypesFolder.nodeId;
-	 types->nodeClass = UA_NODECLASS_OBJECT;
-	 UA_QualifiedName_copycstring("Types", &types->browseName);
-	 UA_LocalizedText_copycstring("Types", &types->displayName);
-	 UA_LocalizedText_copycstring("Types", &types->description);
-	 ADDREFERENCE(types, RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&types, UA_NODESTORE_INSERT_UNIQUE);
-
-	 // Views
-	 UA_ObjectNode *views;
-	 UA_ObjectNode_new(&views);
-	 views->nodeId    = ObjId_ViewsFolder.nodeId;
-	 views->nodeClass = UA_NODECLASS_OBJECT;
-	 UA_QualifiedName_copycstring("Views", &views->browseName);
-	 UA_LocalizedText_copycstring("Views", &views->displayName);
-	 UA_LocalizedText_copycstring("Views", &views->description);
-	 ADDREFERENCE(views, RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&views, UA_NODESTORE_INSERT_UNIQUE);
-
-	 // Server
-	 UA_ObjectNode *servernode;
-	 UA_ObjectNode_new(&servernode);
-	 servernode->nodeId    = ObjId_Server.nodeId;
-	 servernode->nodeClass = UA_NODECLASS_OBJECT;
-	 UA_QualifiedName_copycstring("Server", &servernode->browseName);
-	 UA_LocalizedText_copycstring("Server", &servernode->displayName);
-	 UA_LocalizedText_copycstring("Server", &servernode->description);
-	 ADDREFERENCE(servernode, RefTypeId_HasComponent, UA_FALSE, ObjId_ServerCapabilities);
-	 ADDREFERENCE(servernode, RefTypeId_HasComponent, UA_FALSE, ObjId_NamespaceArray);
-	 ADDREFERENCE(servernode, RefTypeId_HasProperty, UA_FALSE, ObjId_ServerStatus);
-	 ADDREFERENCE(servernode, RefTypeId_HasProperty, UA_FALSE, ObjId_ServerArray);
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&servernode, UA_NODESTORE_INSERT_UNIQUE);
-
-	 // NamespaceArray
-	 UA_VariableNode *namespaceArray;
-	 UA_VariableNode_new(&namespaceArray);
-	 namespaceArray->nodeId    = ObjId_NamespaceArray.nodeId;
-	 namespaceArray->nodeClass = UA_NODECLASS_VARIABLE; //FIXME: this should go into _new?
-	 UA_QualifiedName_copycstring("NodeStoreArray", &namespaceArray->browseName);
-	 UA_LocalizedText_copycstring("NodeStoreArray", &namespaceArray->displayName);
-	 UA_LocalizedText_copycstring("NodeStoreArray", &namespaceArray->description);
-	 UA_Array_new((void **)&namespaceArray->value.storage.data.dataPtr, 2, &UA_[UA_STRING]);
-	 namespaceArray->value.vt = &UA_[UA_STRING];
-	 namespaceArray->value.storage.data.arrayLength = 2;
-	 UA_String_copycstring("http://opcfoundation.org/UA/", &((UA_String *)(namespaceArray->value.storage.data.dataPtr))[0]);
-	 UA_String_copycstring("http://localhost:16664/open62541/", &((UA_String *)(namespaceArray->value.storage.data.dataPtr))[1]);
-	 namespaceArray->arrayDimensionsSize = 1;
-	 UA_UInt32 *dimensions = UA_NULL;
-	 dimensions = UA_alloc(sizeof(UA_UInt32));
-	 *dimensions = 2;
-	 namespaceArray->arrayDimensions = dimensions;
-	 namespaceArray->dataType = NS0NODEID(UA_STRING_NS0);
-	 namespaceArray->valueRank       = 1;
-	 namespaceArray->minimumSamplingInterval = 1.0;
-	 namespaceArray->historizing     = UA_FALSE;
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&namespaceArray, UA_NODESTORE_INSERT_UNIQUE);
-
-	 // ServerStatus
-	 UA_VariableNode *serverstatus;
-	 UA_VariableNode_new(&serverstatus);
-	 serverstatus->nodeId    = ObjId_ServerStatus.nodeId;
-	 serverstatus->nodeClass = UA_NODECLASS_VARIABLE;
-	 UA_QualifiedName_copycstring("ServerStatus", &serverstatus->browseName);
-	 UA_LocalizedText_copycstring("ServerStatus", &serverstatus->displayName);
-	 UA_LocalizedText_copycstring("ServerStatus", &serverstatus->description);
-	 UA_ServerStatusDataType *status;
-	 UA_ServerStatusDataType_new(&status);
-	 status->startTime   = UA_DateTime_now();
-	 status->currentTime = UA_DateTime_now();
-	 status->state       = UA_SERVERSTATE_RUNNING;
-	 UA_String_copycstring("open62541.org", &status->buildInfo.productUri);
-	 UA_String_copycstring("open62541", &status->buildInfo.manufacturerName);
-	 UA_String_copycstring("open62541", &status->buildInfo.productName);
-	 UA_String_copycstring("0.0", &status->buildInfo.softwareVersion);
-	 UA_String_copycstring("0.0", &status->buildInfo.buildNumber);
-	 status->buildInfo.buildDate     = UA_DateTime_now();
-	 status->secondsTillShutdown     = 99999999;
-	 UA_LocalizedText_copycstring("because", &status->shutdownReason);
-	 serverstatus->value.vt          = &UA_[UA_SERVERSTATUSDATATYPE]; // gets encoded as an extensionobject
-	 serverstatus->value.storage.data.arrayLength = 1;
-	 serverstatus->value.storage.data.dataPtr        = status;
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&serverstatus, UA_NODESTORE_INSERT_UNIQUE);
-
-	 // State (Component of ServerStatus)
-	 UA_VariableNode *state;
-	 UA_VariableNode_new(&state);
-	 state->nodeId    = ObjId_State.nodeId;
-	 state->nodeClass = UA_NODECLASS_VARIABLE;
-	 UA_QualifiedName_copycstring("State", &state->browseName);
-	 UA_LocalizedText_copycstring("State", &state->displayName);
-	 UA_LocalizedText_copycstring("State", &state->description);
-	 state->value.vt = &UA_[UA_SERVERSTATE];
-	 state->value.storage.data.arrayDimensionsLength = 1; // added to ensure encoding in readreponse
-	 state->value.storage.data.arrayLength = 1;
-	 state->value.storage.data.dataPtr = &status->state; // points into the other object.
-	 state->value.storageType = UA_VARIANT_DATA_NODELETE;
-	 UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&state, UA_NODESTORE_INSERT_UNIQUE);
-
-	 UA_NodeStoreExample_releaseManagedNode((const UA_Node *)root);
-
-
-
-	 UA_Namespace *namespace;
-	 UA_NamespaceManager_getNamespace(server->namespaceManager,0,&namespace);
-	 */
-
-	/*****
-	 UA_Namespace *namespace;
-	 UA_NamespaceManager_getNamespace(server->namespaceManager,0,&namespace);
-
-	 UA_AddNodesItem addNodesItem;
-	 UA_ReferenceTypeAttributes refTypeAttr;
-
-
-	 addNodesItem.parentNodeId.nodeId = root->nodeId;
-
-	 addNodesItem.requestedNewNodeId.nodeId.identifier.numeric = 999;
-	 addNodesItem.requestedNewNodeId.nodeId.namespaceIndex = 0;
-	 addNodesItem.requestedNewNodeId.nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
-	 addNodesItem.referenceTypeId = RefTypeId_Organizes.nodeId;
-	 addNodesItem.nodeClass = UA_NODECLASS_REFERENCETYPE;
-
-	 UA_QualifiedName_copycstring("myNewNode", &addNodesItem.browseName);
-	 UA_LocalizedText_copycstring("myNewNode", &refTypeAttr.displayName);
-	 UA_LocalizedText_copycstring("myNewNode", &refTypeAttr.description);
-	 refTypeAttr.isAbstract = UA_TRUE;
-	 refTypeAttr.symmetric  = UA_TRUE;
-	 refTypeAttr.userWriteMask = 0;
-	 refTypeAttr.writeMask = 0;
-
-	 refTypeAttr.inverseName.locale.length = 0;
-	 refTypeAttr.inverseName.text.length = 0;
-
-	 refTypeAttr.specifiedAttributes |= UA_ATTRIBUTEID_BROWSENAME;
-	 refTypeAttr.specifiedAttributes |= UA_ATTRIBUTEID_DISPLAYNAME;
-	 refTypeAttr.specifiedAttributes |= UA_ATTRIBUTEID_DESCRIPTION;
-	 refTypeAttr.specifiedAttributes |= UA_ATTRIBUTEID_ISABSTRACT;
-	 refTypeAttr.specifiedAttributes |= UA_ATTRIBUTEID_SYMMETRIC;
-	 refTypeAttr.specifiedAttributes |= UA_ATTRIBUTEID_INVERSENAME;
-
-	 UA_UInt32 offset = 0;
-
-	 UA_ByteString_newMembers(&addNodesItem.nodeAttributes.body,UA_ReferenceTypeAttributes_calcSizeBinary(&refTypeAttr));
-
-	 UA_ReferenceTypeAttributes_encodeBinary(&refTypeAttr,&addNodesItem.nodeAttributes.body,&offset);
-
-	 addSingleNode(namespace,&addNodesItem);
-	 */
-	/*   UA_ObjectAttributes objAttr;
-	 UA_AddNodesItem addNodesItem;
-	 addNodesItem.parentNodeId.nodeId = root->nodeId;
-	 addNodesItem.requestedNewNodeId.nodeId.identifier.numeric = 222;
-	 addNodesItem.requestedNewNodeId.nodeId.namespaceIndex = 0;
-	 addNodesItem.requestedNewNodeId.nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
-	 addNodesItem.referenceTypeId = RefTypeId_Organizes.nodeId;
-	 addNodesItem.nodeClass = UA_NODECLASS_OBJECT;
-
-	 UA_QualifiedName_copycstring("myNewNodeObject", &addNodesItem.browseName);
-	 UA_LocalizedText_copycstring("myNewNodeObject", &objAttr.displayName);
-	 UA_LocalizedText_copycstring("myNewNodeObject", &objAttr.description);
-
-	 objAttr.userWriteMask = 0;
-	 objAttr.writeMask = 0;
-
-	 objAttr.specifiedAttributes |= UA_ATTRIBUTEID_BROWSENAME;
-	 objAttr.specifiedAttributes |= UA_ATTRIBUTEID_DISPLAYNAME;
-	 objAttr.specifiedAttributes |= UA_ATTRIBUTEID_DESCRIPTION;
-	 UA_UInt32 offset = 0;
-
-	 UA_ByteString_newMembers(&addNodesItem.nodeAttributes.body,UA_ObjectAttributes_calcSizeBinary(&objAttr));
-
-	 UA_ObjectAttributes_encodeBinary(&objAttr, &addNodesItem.nodeAttributes.body,&offset);
-
-	 UA_Namespace *ns0;
-	 UA_NamespaceManager_getNamespace(server->namespaceManager,0,&ns0);
-	 addSingleNode(ns0,&addNodesItem);
-	 */
-
+    return server;
 }
 
-//UA_AddNodesResult UA_Server_addNode(UA_Server *server, UA_Node **node, UA_ExpandedNodeId *parentNodeId,
-//                                    UA_NodeId *referenceTypeId) {
-//    return AddNode(server, &adminSession, node, parentNodeId, referenceTypeId);
-//}
-
-//void UA_Server_addReference(UA_Server *server, const UA_AddReferencesRequest *request,
-//                            UA_AddReferencesResponse *response) {
-//    Service_AddReferences(server, &adminSession, request, response);
-//}
 
 void UA_Server_addScalarVariableNode(UA_Server *server, UA_QualifiedName *browseName, void *value,
                                                   const UA_VTable_Entry *vt, UA_ExpandedNodeId *parentNodeId,
                                                   UA_NodeId *referenceTypeId ) {
-    UA_VariableNode *tmpNode;
-    UA_VariableNode_new(&tmpNode);
-    UA_DataValue *dataValue;
-    UA_DataValue_new(&dataValue);
+    UA_DataValue *dataValue = UA_DataValue_new();
 
     /*UA_LocalizedText_copycstring("integer value", &tmpNode->description); */
-    UA_LocalizedText *displayName;
-    UA_LocalizedText *description;
+    UA_LocalizedText *displayName = UA_LocalizedText_new();
+    UA_LocalizedText *description = UA_LocalizedText_new();
 
-    UA_LocalizedText_new(&displayName);
-    UA_LocalizedText_new(&description);
     displayName->locale.length = 0;
     description->locale.length = 0;
 
@@ -1011,11 +504,12 @@ void UA_Server_addScalarVariableNode(UA_Server *server, UA_QualifiedName *browse
     UA_String_copy(&browseName->name,&reqNodeId.nodeId.identifier.string);
     reqNodeId.nodeId.identifierType = UA_NODEIDTYPE_STRING;
     ns0_addVariableNode(server,*referenceTypeId,reqNodeId, *parentNodeId,*browseName,*displayName,*description,dataValue,-1);
-   // return UA_Server_addNode(server, (UA_Node**)&tmpNode, parentNodeId, referenceTypeId);
+
 }
 
 UA_Int32 UA_Server_addNamespace(UA_Server *server, UA_UInt16 namespaceIndex,
 		UA_NodeStore *nodeStore) {
-	return UA_NamespaceManager_addNamespace(server->namespaceManager,
+
+	return (UA_Int32)UA_NamespaceManager_addNamespace(server->namespaceManager,
 			namespaceIndex, nodeStore);
 }

+ 7 - 8
src/server/ua_server_binary.c

@@ -1,4 +1,4 @@
-#include "ua_server.h"
+#include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 #include "ua_namespace_0.h"
@@ -53,8 +53,7 @@ static void processHello(UA_Connection *connection, const UA_ByteString *msg,
     UA_TcpHelloMessage_deleteMembers(&helloMessage);
 }
 
-static void processOpen(UA_Connection *connection, UA_Server *server,
-                        const UA_ByteString *msg, UA_UInt32 *pos) {
+static void processOpen(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
     if(connection->state != UA_CONNECTION_ESTABLISHED) {
         // was hello exchanged before?
         if(connection->state == UA_CONNECTION_OPENING)
@@ -140,8 +139,8 @@ static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r
         DBG_VERBOSE(printf("Invoke Service: %s\n", # TYPE));                                              \
         Service_##TYPE(server, channel->session, &p, &r);                                                 \
         DBG_VERBOSE(printf("Finished Service: %s\n", # TYPE));                                            \
-        UA_ByteString_newMembers(message, UA_##TYPE##Response_calcSizeBinary(&r)); \
-        UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset);     \
+        UA_ByteString_newMembers(message, UA_##TYPE##Response_calcSizeBinary(&r));                        \
+        UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset);                                       \
         UA_##TYPE##Request_deleteMembers(&p);                                                             \
         UA_##TYPE##Response_deleteMembers(&r);                                                            \
         responseType = requestType.nodeId.identifier.numeric + 3;                                         \
@@ -153,7 +152,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
     UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
 
     UA_SecureChannel *channel;
-    UA_SecureChannelManager_get(server->secureChannelManager, secureChannelId, &channel);
+    UA_SecureChannelManager_get(&server->secureChannelManager, secureChannelId, &channel);
 
     // 2) Read the security header
     UA_UInt32 tokenId;
@@ -227,8 +226,8 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         UA_ActivateSessionRequest_deleteMembers(&p);
         UA_ActivateSessionResponse_deleteMembers(&r);
         responseType = requestType.nodeId.identifier.numeric + 3;
-    }
         break;
+    }
 
     case UA_CLOSESESSIONREQUEST_NS0: {
         UA_CloseSessionRequest  p;
@@ -243,8 +242,8 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         UA_CloseSessionRequest_deleteMembers(&p);
         UA_CloseSessionResponse_deleteMembers(&r);
         responseType = requestType.nodeId.identifier.numeric + 3;
+        break;
     }
-    break;
 
     case UA_READREQUEST_NS0:
         INVOKE_SERVICE(Read);

+ 21 - 0
src/server/ua_server_internal.h

@@ -0,0 +1,21 @@
+#ifndef UA_SERVER_INTERNAL_H_
+#define UA_SERVER_INTERNAL_H_
+
+#include "ua_server.h"
+#include "ua_session_manager.h"
+#include "ua_namespace_manager.h"
+#include "ua_securechannel_manager.h"
+
+struct UA_Server {
+    UA_ApplicationDescription description;
+    UA_Int32 endpointDescriptionsSize;
+    UA_EndpointDescription *endpointDescriptions;
+    UA_ByteString serverCertificate;
+    UA_NamespaceManager *namespaceManager;
+    UA_SecureChannelManager secureChannelManager;
+    UA_SessionManager sessionManager;
+    UA_NodeStore *nodestore;
+    UA_Logger logger;
+};
+
+#endif /* UA_SERVER_INTERNAL_H_ */

+ 33 - 33
src/server/ua_services_attribute.c

@@ -1,7 +1,7 @@
 #include "ua_services.h"
 
 #include "ua_statuscodes.h"
-
+#include "ua_server_internal.h"
 #include "ua_namespace_manager.h"
 #include "ua_namespace_0.h"
 #include "ua_util.h"
@@ -31,43 +31,43 @@ static UA_DataValue service_read_node(UA_Server *server,
 	switch (id->attributeId) {
 	case UA_ATTRIBUTEID_NODEID:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_NODEID],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_NODEID],
 				&node->nodeId);
 		break;
 
 	case UA_ATTRIBUTEID_NODECLASS:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_INT32],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_INT32],
 				&node->nodeClass);
 		break;
 
 	case UA_ATTRIBUTEID_BROWSENAME:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_QUALIFIEDNAME],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_QUALIFIEDNAME],
 				&node->browseName);
 		break;
 
 	case UA_ATTRIBUTEID_DISPLAYNAME:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT],
 				&node->displayName);
 		break;
 
 	case UA_ATTRIBUTEID_DESCRIPTION:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT],
 				&node->description);
 		break;
 
 	case UA_ATTRIBUTEID_WRITEMASK:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_UINT32],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_UINT32],
 				&node->writeMask);
 		break;
 
 	case UA_ATTRIBUTEID_USERWRITEMASK:
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_UINT32],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_UINT32],
 				&node->userWriteMask);
 		break;
 
@@ -77,7 +77,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 						| UA_NODECLASS_VARIABLETYPE | UA_NODECLASS_DATATYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_ReferenceTypeNode *) node)->isAbstract);
 		break;
 
@@ -85,7 +85,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_ReferenceTypeNode *) node)->symmetric);
 		break;
 
@@ -93,7 +93,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT],
 				&((UA_ReferenceTypeNode *) node)->inverseName);
 		break;
 
@@ -101,7 +101,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VIEW)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_ViewNode *) node)->containsNoLoops);
 		break;
 
@@ -109,7 +109,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
 				&((UA_ViewNode *) node)->eventNotifier);
 		break;
 
@@ -124,7 +124,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_NODEID],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_NODEID],
 				&((UA_VariableTypeNode *) node)->dataType);
 		break;
 
@@ -132,7 +132,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_INT32],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_INT32],
 				&((UA_VariableTypeNode *) node)->valueRank);
 		break;
 
@@ -140,7 +140,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		UA_Variant_copySetArray(&v.value, &UA_[UA_UINT32],
+		UA_Variant_copySetArray(&v.value, &UA_TYPES[UA_UINT32],
 				((UA_VariableTypeNode *) node)->arrayDimensionsSize,
 				&((UA_VariableTypeNode *) node)->arrayDimensions);
 		break;
@@ -149,7 +149,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
 				&((UA_VariableNode *) node)->accessLevel);
 		break;
 
@@ -157,7 +157,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
 				&((UA_VariableNode *) node)->userAccessLevel);
 		break;
 
@@ -165,7 +165,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_DOUBLE],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_DOUBLE],
 				&((UA_VariableNode *) node)->minimumSamplingInterval);
 		break;
 
@@ -173,7 +173,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_VARIABLE)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_VariableNode *) node)->historizing);
 		break;
 
@@ -181,7 +181,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_METHOD)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_MethodNode *) node)->executable);
 		break;
 
@@ -189,7 +189,7 @@ static UA_DataValue service_read_node(UA_Server *server,
 		CHECK_NODECLASS(UA_NODECLASS_METHOD)
 		;
 		v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-		retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+		retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
 				&((UA_MethodNode *) node)->userExecutable);
 		break;
 
@@ -218,13 +218,13 @@ void Service_Read(UA_Server *server, UA_Session *session,
 		return;
 	}
 	if (UA_Array_new((void **) &response->results, request->nodesToReadSize,
-			&UA_[UA_DATAVALUE]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_DATAVALUE]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
 
 	if (UA_Array_new((void **) &response->diagnosticInfos,
-			request->nodesToReadSize, &UA_[UA_DIAGNOSTICINFO])
+			request->nodesToReadSize, &UA_TYPES[UA_DIAGNOSTICINFO])
 			!= UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
@@ -235,13 +235,13 @@ void Service_Read(UA_Server *server, UA_Session *session,
 	UA_UInt16 *associatedIndices;
 	UA_UInt32 differentNamespaceIndexCount = 0;
 	if (UA_Array_new((void **) &numberOfFoundIndices, request->nodesToReadSize,
-			&UA_[UA_UINT32]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_UINT32]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
 
 	if (UA_Array_new((void **) &associatedIndices, request->nodesToReadSize,
-			&UA_[UA_UINT16]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_UINT16]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
@@ -251,7 +251,7 @@ void Service_Read(UA_Server *server, UA_Session *session,
 
 	UA_UInt32 *readValueIdIndices;
 	if (UA_Array_new((void **) &readValueIdIndices, request->nodesToReadSize,
-			&UA_[UA_UINT32]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_UINT32]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
@@ -296,7 +296,7 @@ void Service_Write(UA_Server *server, UA_Session *session,
 	response->resultsSize = request->nodesToWriteSize;
 
 	if (UA_Array_new((void **) &response->results, request->nodesToWriteSize,
-			&UA_[UA_STATUSCODE])) {
+			&UA_TYPES[UA_STATUSCODE])) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
@@ -307,13 +307,13 @@ void Service_Write(UA_Server *server, UA_Session *session,
 	}
 
 	if (UA_Array_new((void **) &response->results, request->nodesToWriteSize,
-			&UA_[UA_DATAVALUE]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_DATAVALUE]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
 
 	if (UA_Array_new((void **) &response->diagnosticInfos,
-			request->nodesToWriteSize, &UA_[UA_DIAGNOSTICINFO])
+			request->nodesToWriteSize, &UA_TYPES[UA_DIAGNOSTICINFO])
 			!= UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
@@ -324,13 +324,13 @@ void Service_Write(UA_Server *server, UA_Session *session,
 	UA_UInt16 *associatedIndices;
 	UA_UInt32 differentNamespaceIndexCount = 0;
 	if (UA_Array_new((void **) &numberOfFoundIndices, request->nodesToWriteSize,
-			&UA_[UA_UINT32]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_UINT32]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
 
 	if (UA_Array_new((void **) &associatedIndices, request->nodesToWriteSize,
-			&UA_[UA_UINT16]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_UINT16]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
@@ -340,7 +340,7 @@ void Service_Write(UA_Server *server, UA_Session *session,
 
 	UA_UInt32 *writeValues;
 	if (UA_Array_new((void **) &writeValues, request->nodesToWriteSize,
-			&UA_[UA_UINT32]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_UINT32]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}

+ 11 - 31
src/server/ua_services_discovery.c

@@ -1,40 +1,20 @@
+#include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_namespace_0.h"
+#include "ua_util.h"
 
 void Service_GetEndpoints(UA_Server                    *server,
                           const UA_GetEndpointsRequest *request,
                           UA_GetEndpointsResponse      *response) {
     UA_GetEndpointsResponse_init(response);
     response->endpointsSize = 1;
-    UA_Array_new((void **)&response->endpoints, response->endpointsSize, &UA_[UA_ENDPOINTDESCRIPTION]);
-
-    // security policy
-    response->endpoints[0].securityMode = UA_MESSAGESECURITYMODE_NONE;
-    UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None",
-                          &response->endpoints[0].securityPolicyUri);
-    UA_String_copycstring("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary",
-                          &response->endpoints[0].transportProfileUri);
-
-    // usertoken policy
-    response->endpoints[0].userIdentityTokensSize = 1;
-    UA_Array_new((void **)&response->endpoints[0].userIdentityTokens,
-                 response->endpoints[0].userIdentityTokensSize, &UA_[UA_USERTOKENPOLICY]);
-    UA_UserTokenPolicy *token = &response->endpoints[0].userIdentityTokens[0];
-    UA_UserTokenPolicy_init(token);
-    UA_String_copycstring("my-anonymous-policy", &token->policyId); // defined per server
-    token->tokenType         = UA_USERTOKENTYPE_ANONYMOUS;
-
-    // server description
-    UA_String_copy(&request->endpointUrl, &response->endpoints[0].endpointUrl);
-    /* The standard says "the HostName specified in the Server Certificate is the
-       same as the HostName contained in the endpointUrl provided in the
-       EndpointDescription */
-    UA_String_copy(&server->serverCertificate, &response->endpoints[0].serverCertificate);
-    UA_String_copycstring("http://open62541.info/product/release", &(response->endpoints[0].server.productUri));
-    // FIXME: This information should be provided by the application, preferably in the address space
-    UA_String_copycstring("http://open62541.info/applications/4711",
-                          &(response->endpoints[0].server.applicationUri));
-    UA_LocalizedText_copycstring("The open62541 application", &(response->endpoints[0].server.applicationName));
-    // FIXME: This should be a feature of the application and an enum
-    response->endpoints[0].server.applicationType = UA_APPLICATIONTYPE_SERVER;
+    response->endpoints = UA_alloc(sizeof(UA_EndpointDescription));
+    if(!response->endpoints) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
+    }
+    if(UA_EndpointDescription_copy(server->endpointDescriptions, response->endpoints) != UA_STATUSCODE_GOOD) {
+        UA_free(response->endpoints);
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+    }
 }

+ 11 - 11
src/server/ua_services_nodemanagement.c

@@ -1,7 +1,7 @@
 #include "ua_services.h"
 #include "ua_namespace_0.h"
 #include "ua_statuscodes.h"
-
+#include "ua_server_internal.h"
 #include "ua_services_internal.h"
 #include "ua_namespace_manager.h"
 #include "ua_session.h"
@@ -17,13 +17,13 @@ void Service_AddNodes(UA_Server *server, UA_Session *session,
 	}
 
 	if (UA_Array_new((void **) &response->results, request->nodesToAddSize,
-			&UA_[UA_ADDNODESRESULT]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_ADDNODESRESULT]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
 
 	if (UA_Array_new((void **) &response->diagnosticInfos,
-			request->nodesToAddSize, &UA_[UA_DIAGNOSTICINFO])
+			request->nodesToAddSize, &UA_TYPES[UA_DIAGNOSTICINFO])
 			!= UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
@@ -34,14 +34,14 @@ void Service_AddNodes(UA_Server *server, UA_Session *session,
 	UA_UInt16 *associatedIndices;
 	UA_UInt32 differentNamespaceIndexCount = 0;
 	if (UA_Array_new((void **) &numberOfFoundIndices,
-			request->nodesToAddSize, &UA_[UA_UINT32])
+			request->nodesToAddSize, &UA_TYPES[UA_UINT32])
 			!= UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
 
 	if (UA_Array_new((void **) &associatedIndices, request->nodesToAddSize,
-			&UA_[UA_UINT16]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_UINT16]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
@@ -50,7 +50,7 @@ void Service_AddNodes(UA_Server *server, UA_Session *session,
 
 	UA_UInt32 *addNodesIndices;
 	if (UA_Array_new((void **) &addNodesIndices,
-			request->nodesToAddSize, &UA_[UA_UINT32])
+			request->nodesToAddSize, &UA_TYPES[UA_UINT32])
 			!= UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
@@ -93,13 +93,13 @@ void Service_AddReferences(UA_Server *server, UA_Session *session,
 	}
 
 	if (UA_Array_new((void **) &response->results, request->referencesToAddSize,
-			&UA_[UA_STATUSCODE]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_STATUSCODE]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
 
 	if (UA_Array_new((void **) &response->diagnosticInfos,
-			request->referencesToAddSize, &UA_[UA_DIAGNOSTICINFO])
+			request->referencesToAddSize, &UA_TYPES[UA_DIAGNOSTICINFO])
 			!= UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
@@ -110,14 +110,14 @@ void Service_AddReferences(UA_Server *server, UA_Session *session,
 	UA_UInt16 *associatedIndices;
 	UA_UInt32 differentNamespaceIndexCount = 0;
 	if (UA_Array_new((void **) &numberOfFoundIndices,
-			request->referencesToAddSize, &UA_[UA_UINT32])
+			request->referencesToAddSize, &UA_TYPES[UA_UINT32])
 			!= UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
 
 	if (UA_Array_new((void **) &associatedIndices, request->referencesToAddSize,
-			&UA_[UA_UINT16]) != UA_STATUSCODE_GOOD) {
+			&UA_TYPES[UA_UINT16]) != UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;
 	}
@@ -128,7 +128,7 @@ void Service_AddReferences(UA_Server *server, UA_Session *session,
 
 	UA_UInt32 *readValueIdIndices;
 	if (UA_Array_new((void **) &readValueIdIndices,
-			request->referencesToAddSize, &UA_[UA_UINT32])
+			request->referencesToAddSize, &UA_TYPES[UA_UINT32])
 			!= UA_STATUSCODE_GOOD) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
 		return;

+ 5 - 4
src/server/ua_services_securechannel.c

@@ -1,3 +1,4 @@
+#include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_securechannel_manager.h"
 
@@ -5,14 +6,14 @@ void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
                                const UA_OpenSecureChannelRequest *request,
                                UA_OpenSecureChannelResponse *response) {
     // todo: if(request->clientProtocolVersion != protocolVersion)
-    if(request->requestType == UA_SECURITYTOKEN_ISSUE)
-        UA_SecureChannelManager_open(server->secureChannelManager, connection, request, response);
+    if(request->requestType == UA_SECURITYTOKENREQUESTTYPE_ISSUE)
+        UA_SecureChannelManager_open(&server->secureChannelManager, connection, request, response);
     else
-        UA_SecureChannelManager_renew(server->secureChannelManager, connection, request, response);
+        UA_SecureChannelManager_renew(&server->secureChannelManager, connection, request, response);
 }
 
 void Service_CloseSecureChannel(UA_Server *server, UA_Int32 channelId) {
 	//Sten: this service is a bit assymmetric to OpenSecureChannel since CloseSecureChannelRequest does not contain any indormation
-    UA_SecureChannelManager_close(server->secureChannelManager, channelId);
+    UA_SecureChannelManager_close(&server->secureChannelManager, channelId);
     // 62451 Part 6 Chapter 7.1.4 - The server does not send a CloseSecureChannel response
 }

+ 11 - 7
src/server/ua_services_session.c

@@ -1,5 +1,5 @@
 #include "ua_services.h"
-#include "ua_server.h"
+#include "ua_server_internal.h"
 #include "ua_session_manager.h"
 #include "ua_statuscodes.h"
 #include "ua_util.h"
@@ -10,8 +10,7 @@ void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
     // creates a session and adds a pointer to the channel. Only when the
     // session is activated will the channel point to the session as well
 	UA_Session *newSession;
-    response->responseHeader.serviceResult = UA_SessionManager_createSession(server->sessionManager,
-                                                                             channel, &newSession);
+    response->responseHeader.serviceResult = UA_SessionManager_createSession(&server->sessionManager, channel, &newSession);
 	if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
 		return;
 
@@ -22,7 +21,12 @@ void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
     response->sessionId = newSession->sessionId;
     response->revisedSessionTimeout = newSession->timeout;
     response->authenticationToken = newSession->authenticationToken;
-    //channel->session = newSession;
+    UA_ByteString_copy(&server->serverCertificate, &response->serverCertificate);
+
+    response->serverEndpointsSize = 1;
+    response->serverEndpoints = UA_alloc(sizeof(UA_EndpointDescription));
+    UA_EndpointDescription_copy(server->endpointDescriptions, response->serverEndpoints);
+    
 }
 
 void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
@@ -30,7 +34,7 @@ void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
                              UA_ActivateSessionResponse *response) {
     // make the channel know about the session
 	UA_Session *foundSession;
-	UA_SessionManager_getSessionByToken(server->sessionManager,
+	UA_SessionManager_getSessionByToken(&server->sessionManager,
                                         (UA_NodeId*)&request->requestHeader.authenticationToken,
                                         &foundSession);
 
@@ -43,7 +47,7 @@ void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
 void Service_CloseSession(UA_Server *server, const UA_CloseSessionRequest *request,
                               UA_CloseSessionResponse *response) {
 	UA_Session *foundSession;
-	UA_SessionManager_getSessionByToken(server->sessionManager,
+	UA_SessionManager_getSessionByToken(&server->sessionManager,
 			(UA_NodeId*)&request->requestHeader.authenticationToken,
 			&foundSession);
 
@@ -53,7 +57,7 @@ void Service_CloseSession(UA_Server *server, const UA_CloseSessionRequest *reque
 	}
 
 
-	if(UA_SessionManager_removeSession(server->sessionManager, &foundSession->sessionId) == UA_STATUSCODE_GOOD){
+	if(UA_SessionManager_removeSession(&server->sessionManager, &foundSession->sessionId) == UA_STATUSCODE_GOOD){
 		response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
 	}else{
 		//still not 100% sure about the return code

+ 6 - 6
src/server/ua_services_view.c

@@ -1,6 +1,6 @@
 #include "ua_services.h"
 #include "ua_statuscodes.h"
-
+#include "ua_server_internal.h"
 #include "ua_namespace_0.h"
 #include "ua_util.h"
 #include "ua_namespace_manager.h"
@@ -17,19 +17,19 @@ void Service_Browse(UA_Server *server, UA_Session *session,
         return;
     }
 
-    if(UA_Array_new((void **)&(response->results), request->nodesToBrowseSize, &UA_[UA_BROWSERESULT])
+    if(UA_Array_new((void **)&(response->results), request->nodesToBrowseSize, &UA_TYPES[UA_BROWSERESULT])
        != UA_STATUSCODE_GOOD) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
         return;
     }
 
     response->resultsSize = request->nodesToBrowseSize;
-    if(UA_Array_new((void **)&numberOfFoundIndices,request->nodesToBrowseSize,&UA_[UA_UINT32]) != UA_STATUSCODE_GOOD){
+    if(UA_Array_new((void **)&numberOfFoundIndices,request->nodesToBrowseSize,&UA_TYPES[UA_UINT32]) != UA_STATUSCODE_GOOD){
     	response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
     	return ;
     }
 
-    if(UA_Array_new((void **)&associatedIndices,request->nodesToBrowseSize,&UA_[UA_UINT16]) != UA_STATUSCODE_GOOD){
+    if(UA_Array_new((void **)&associatedIndices,request->nodesToBrowseSize,&UA_TYPES[UA_UINT16]) != UA_STATUSCODE_GOOD){
     	response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
     	return ;
     }
@@ -37,7 +37,7 @@ void Service_Browse(UA_Server *server, UA_Session *session,
     BUILD_INDEX_ARRAYS(request->nodesToBrowseSize,request->nodesToBrowse,nodeId,differentNamespaceIndexCount,associatedIndices,numberOfFoundIndices);
 
 	UA_UInt32 *browseDescriptionIndices;
-    if(UA_Array_new((void **)&browseDescriptionIndices,request->nodesToBrowseSize,&UA_[UA_UINT32]) != UA_STATUSCODE_GOOD){
+    if(UA_Array_new((void **)&browseDescriptionIndices,request->nodesToBrowseSize,&UA_TYPES[UA_UINT32]) != UA_STATUSCODE_GOOD){
     	response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
     	return ;
     }
@@ -84,7 +84,7 @@ void Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *sessio
     // Allocate space for a correct answer
     response->resultsSize = request->browsePathsSize;
     // _init of the elements is done in Array_new
-    if(UA_Array_new((void **)&response->results, request->browsePathsSize, &UA_[UA_BROWSEPATHRESULT])
+    if(UA_Array_new((void **)&response->results, request->browsePathsSize, &UA_TYPES[UA_BROWSEPATHRESULT])
        != UA_STATUSCODE_GOOD) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
         return;

+ 10 - 22
src/server/ua_session_manager.c

@@ -13,28 +13,17 @@ struct session_list_entry {
     LIST_ENTRY(session_list_entry) pointers;
 };
 
-struct UA_SessionManager {
-    LIST_HEAD(session_list, session_list_entry) sessions;
-    UA_UInt32    maxSessionCount;
-    UA_Int32     lastSessionId;
-    UA_UInt32    currentSessionCount;
-    UA_DateTime  maxSessionLifeTime;
-    UA_DateTime  sessionTimeout;
-};
-
-UA_StatusCode UA_SessionManager_new(UA_SessionManager **sessionManager, UA_UInt32 maxSessionCount,
+UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
                                     UA_UInt32 sessionTimeout, UA_UInt32 startSessionId) {
-    if(!(*sessionManager = UA_alloc(sizeof(UA_SessionManager))))
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-    LIST_INIT(&(*sessionManager)->sessions);
-    (*sessionManager)->maxSessionCount = maxSessionCount;
-    (*sessionManager)->lastSessionId   = startSessionId;
-    (*sessionManager)->sessionTimeout  = sessionTimeout;
-    (*sessionManager)->currentSessionCount = 0;
+    LIST_INIT(&sessionManager->sessions);
+    sessionManager->maxSessionCount = maxSessionCount;
+    sessionManager->lastSessionId   = startSessionId;
+    sessionManager->sessionTimeout  = sessionTimeout;
+    sessionManager->currentSessionCount = 0;
     return UA_STATUSCODE_GOOD;
 }
 
-void UA_SessionManager_delete(UA_SessionManager *sessionManager) {
+void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager) {
     struct session_list_entry *current = LIST_FIRST(&sessionManager->sessions);
     while(current) {
         LIST_REMOVE(current, pointers);
@@ -44,7 +33,6 @@ void UA_SessionManager_delete(UA_SessionManager *sessionManager) {
         UA_free(current);
         current = LIST_FIRST(&sessionManager->sessions);
     }
-    UA_free(sessionManager);
 }
 
 UA_StatusCode UA_SessionManager_getSessionById(UA_SessionManager *sessionManager, UA_NodeId *sessionId, UA_Session **session) {
@@ -55,7 +43,7 @@ UA_StatusCode UA_SessionManager_getSessionById(UA_SessionManager *sessionManager
 
     struct session_list_entry *current = UA_NULL;
     LIST_FOREACH(current, &sessionManager->sessions, pointers) {
-        if(UA_NodeId_equal(&current->session.sessionId, sessionId) == UA_EQUAL)
+        if(UA_NodeId_equal(&current->session.sessionId, sessionId))
             break;
     }
 
@@ -78,7 +66,7 @@ UA_StatusCode UA_SessionManager_getSessionByToken(UA_SessionManager *sessionMana
 
     struct session_list_entry *current = UA_NULL;
     LIST_FOREACH(current, &sessionManager->sessions, pointers) {
-        if(UA_NodeId_equal(&current->session.authenticationToken, token) == UA_EQUAL)
+        if(UA_NodeId_equal(&current->session.authenticationToken, token))
             break;
     }
 
@@ -122,7 +110,7 @@ UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
 UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, UA_NodeId  *sessionId) {
     struct session_list_entry *current = UA_NULL;
     LIST_FOREACH(current, &sessionManager->sessions, pointers) {
-        if(UA_NodeId_equal(&current->session.sessionId, sessionId) == UA_EQUAL)
+        if(UA_NodeId_equal(&current->session.sessionId, sessionId))
             break;
     }
 

+ 12 - 2
src/server/ua_session_manager.h

@@ -2,12 +2,22 @@
 #define UA_SESSION_MANAGER_H_
 
 #include "ua_server.h"
+#include "ua_util.h"
 #include "ua_session.h"
 
-UA_StatusCode UA_SessionManager_new(UA_SessionManager **sessionManager, UA_UInt32 maxSessionCount,
+typedef struct UA_SessionManager {
+    LIST_HEAD(session_list, session_list_entry) sessions; // doubly-linked list of sessions
+    UA_UInt32    maxSessionCount;
+    UA_Int32     lastSessionId;
+    UA_UInt32    currentSessionCount;
+    UA_DateTime  maxSessionLifeTime;
+    UA_DateTime  sessionTimeout;
+} UA_SessionManager;
+
+UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
                                     UA_UInt32 sessionLifetime, UA_UInt32 startSessionId);
 
-void UA_SessionManager_delete(UA_SessionManager *sessionManager);
+void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager);
 
 UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
                                               UA_SecureChannel *channel, UA_Session **session);

+ 5 - 7
src/ua_session.c

@@ -41,11 +41,10 @@ UA_Session adminSession = {
     .validTill = UA_INT64_MAX,
     .channel = UA_NULL};
 
-UA_StatusCode UA_Session_new(UA_Session **session) {
-    if(!(*session = UA_alloc(sizeof(UA_Session))))
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-    UA_Session_init(*session);
-    return UA_STATUSCODE_GOOD;
+UA_Session * UA_Session_new() {
+    UA_Session *s = UA_alloc(sizeof(UA_Session));
+    if(s) UA_Session_init(s);
+    return s;
 }
 
 /* mock up function to generate tokens for authentication */
@@ -99,8 +98,7 @@ void UA_Session_delete(UA_Session *session) {
 }
 
 UA_Boolean UA_Session_compare(UA_Session *session1, UA_Session *session2) {
-    if(session1 && session2 &&
-       UA_NodeId_equal(&session1->sessionId, &session2->sessionId) == UA_EQUAL)
+    if(session1 && session2 && UA_NodeId_equal(&session1->sessionId, &session2->sessionId))
         return UA_TRUE;
     return UA_FALSE;
 }

+ 1 - 1
src/ua_session.h

@@ -25,7 +25,7 @@ struct UA_Session {
 extern UA_Session anonymousSession; ///< If anonymous access is allowed, this session is used internally (Session ID: 0)
 extern UA_Session adminSession; ///< Local access to the services (for startup and maintenance) uses this Session with all possible access rights (Session ID: 1)
 
-UA_StatusCode UA_Session_new(UA_Session **session);
+UA_Session * UA_Session_new();
 void UA_Session_init(UA_Session *session);
 void UA_Session_delete(UA_Session *session);
 void UA_Session_deleteMembers(UA_Session *session);

+ 0 - 11
src/ua_transport.h

@@ -4,17 +4,6 @@
 #include "ua_types.h"
 #include "ua_types_encoding_binary.h"
 
-typedef enum SecurityTokenRequestType {
-    UA_SECURITYTOKEN_ISSUE = 0,
-    UA_SECURITYTOKEN_RENEW = 1
-} SecurityTokenRequestType;
-
-typedef enum {
-    UA_SECURITYMODE_INVALID        = 0,
-    UA_SECURITYMODE_NONE           = 1,
-    UA_SECURITYMODE_SIGNANDENCRYPT = 2
-} SecurityMode;
-
 /* MessageType */
 typedef UA_Int32 UA_MessageType;
 enum UA_MessageType {

+ 43 - 38
src/ua_types.c

@@ -159,13 +159,18 @@ void UA_String_print(const UA_String *p, FILE *stream) {
 }
 #endif
 
+/* The c-string needs to be null-terminated. the string cannot be smaller than zero. */
 UA_Int32 UA_String_copycstring(char const *src, UA_String *dst) {
-    dst->data   = UA_NULL;
-    dst->length = strlen(src);
-    if(dst->length > 0) {
-        if(!(dst->data = UA_alloc(dst->length)))
-            return UA_STATUSCODE_BADOUTOFMEMORY;
-        UA_memcpy((void *)dst->data, src, dst->length);
+    UA_Int32 length = strlen(src);
+    if(length == 0) {
+        dst->length = 0;
+        dst->data = UA_NULL;
+    } else if((dst->data = UA_alloc(length)) != UA_NULL) {
+        memcpy(dst->data, src, length);
+        dst->length = length;
+    } else {
+        dst->length = -1;
+        return UA_STATUSCODE_BADOUTOFMEMORY;
     }
     return UA_STATUSCODE_GOOD;
 }
@@ -196,15 +201,15 @@ UA_StatusCode UA_String_copyprintf(char const *fmt, UA_String *dst, ...) {
     return UA_STATUSCODE_GOOD;
 }
 
-UA_EQUALITY UA_String_equal(const UA_String *string1, const UA_String *string2) {
+UA_Boolean UA_String_equal(const UA_String *string1, const UA_String *string2) {
     if(string1->length <= 0 && string2->length <= 0)
-        return UA_EQUAL;
+        return UA_TRUE;
     if(string1->length != string2->length)
-        return UA_NOT_EQUAL;
+        return UA_FALSE;
 
     // casts are needed to overcome signed warnings
     UA_Int32 is = strncmp((char const *)string1->data, (char const *)string2->data, string1->length);
-    return (is == 0) ? UA_EQUAL : UA_NOT_EQUAL;
+    return (is == 0) ? UA_TRUE : UA_FALSE;
 }
 
 #ifdef DEBUG
@@ -303,9 +308,9 @@ UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime time) {
 
 UA_StatusCode UA_DateTime_toString(UA_DateTime time, UA_String *timeString) {
     // length of the string is 31 (incl. \0 at the end)
-    if(!(timeString->data = UA_alloc(31)))
+    if(!(timeString->data = UA_alloc(32)))
         return UA_STATUSCODE_BADOUTOFMEMORY;
-    timeString->length = 30;
+    timeString->length = 31;
 
     UA_DateTimeStruct tSt = UA_DateTime_toStruct(time);
     sprintf((char*)timeString->data, "%2d/%2d/%4d %2d:%2d:%2d.%3d.%3d.%3d", tSt.mounth, tSt.day, tSt.year,
@@ -317,10 +322,10 @@ UA_StatusCode UA_DateTime_toString(UA_DateTime time, UA_String *timeString) {
 UA_TYPE_DELETE_DEFAULT(UA_Guid)
 UA_TYPE_DELETEMEMBERS_NOACTION(UA_Guid)
 
-UA_EQUALITY UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2) {
+UA_Boolean UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2) {
     if(memcmp(g1, g2, sizeof(UA_Guid)) == 0)
-        return UA_EQUAL;
-    return UA_NOT_EQUAL;
+        return UA_TRUE;
+    return UA_FALSE;
 }
 
 void UA_Guid_init(UA_Guid *p) {
@@ -345,7 +350,7 @@ void UA_Guid_print(const UA_Guid *p, FILE *stream) {
 
 /* ByteString */
 UA_TYPE_AS(UA_ByteString, UA_String)
-UA_EQUALITY UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2) {
+UA_Boolean UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2) {
     return UA_String_equal((const UA_String *)string1, (const UA_String *)string2);
 }
 
@@ -508,16 +513,16 @@ void UA_NodeId_print(const UA_NodeId *p, FILE *stream) {
 }
 #endif
 
-UA_EQUALITY UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
+UA_Boolean UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
     if(n1->namespaceIndex != n2->namespaceIndex)
-        return UA_NOT_EQUAL;
+        return UA_FALSE;
 
     switch(n1->identifierType) {
     case UA_NODEIDTYPE_NUMERIC:
         if(n1->identifier.numeric == n2->identifier.numeric)
-            return UA_EQUAL;
+            return UA_TRUE;
         else
-            return UA_NOT_EQUAL;
+            return UA_FALSE;
 
     case UA_NODEIDTYPE_STRING:
         return UA_String_equal(&n1->identifier.string, &n2->identifier.string);
@@ -528,7 +533,7 @@ UA_EQUALITY UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
     case UA_NODEIDTYPE_BYTESTRING:
         return UA_ByteString_equal(&n1->identifier.byteString, &n2->identifier.byteString);
     }
-    return UA_NOT_EQUAL;
+    return UA_FALSE;
 }
 
 UA_Boolean UA_NodeId_isNull(const UA_NodeId *p) {
@@ -806,7 +811,7 @@ void UA_Variant_init(UA_Variant *p) {
     p->storage.data.dataPtr        = UA_NULL;
     p->storage.data.arrayDimensions       = UA_NULL;
     p->storage.data.arrayDimensionsLength = -1;
-    p->vt = &UA_[UA_INVALIDTYPE];
+    p->vt = &UA_TYPES[UA_INVALIDTYPE];
 }
 
 /** This function performs a deep copy. The resulting StorageType is UA_VARIANT_DATA. */
@@ -831,7 +836,7 @@ UA_StatusCode UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
         dst->vt = src->vt;
         dstdata->arrayLength = srcdata->arrayLength;
         if(srcdata->arrayDimensions) {
-            retval |= UA_Array_copy(srcdata->arrayDimensions, srcdata->arrayDimensionsLength, &UA_[UA_INT32],
+            retval |= UA_Array_copy(srcdata->arrayDimensions, srcdata->arrayDimensionsLength, &UA_TYPES[UA_INT32],
                                     (void **)&dstdata->arrayDimensions);
             if(retval == UA_STATUSCODE_GOOD)
                 dstdata->arrayDimensionsLength = srcdata->arrayDimensionsLength;
@@ -854,9 +859,11 @@ UA_StatusCode UA_Variant_copySetValue(UA_Variant *v, const UA_VTable_Entry *vt,
     UA_Variant_init(v);
     v->vt = vt;
     v->storage.data.arrayLength = 1; // no array but a single entry
-    UA_StatusCode retval = vt->new(&v->storage.data.dataPtr);
-    if(retval == UA_STATUSCODE_GOOD)
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
+    if((v->storage.data.dataPtr = vt->new()))
         retval |= vt->copy(value, v->storage.data.dataPtr);
+    else
+        retval = UA_STATUSCODE_BADOUTOFMEMORY;
     if(retval) {
         UA_Variant_deleteMembers(v);
         UA_Variant_init(v);
@@ -884,8 +891,8 @@ void UA_Variant_print(const UA_Variant *p, FILE *stream) {
         return;
     }
     fprintf(stream, "(UA_Variant){/*%s*/", p->vt->name);
-    if(p->vt == &UA_[ns0id])
-        fprintf(stream, "UA_[%d]", ns0id);
+    if(p->vt == &UA_TYPES[ns0id])
+        fprintf(stream, "UA_TYPES[%d]", ns0id);
     else
         fprintf(stream, "ERROR (not a builtin type)");
     UA_Int32_print(&p->storage.data.arrayLength, stream);
@@ -895,7 +902,7 @@ void UA_Variant_print(const UA_Variant *p, FILE *stream) {
     UA_Int32_print(&p->storage.data.arrayDimensionsLength, stream);
     fprintf(stream, ",");
     UA_Array_print(p->storage.data.arrayDimensions, p->storage.data.arrayDimensionsLength,
-                   &UA_[UA_INT32], stream);
+                   &UA_TYPES[UA_INT32], stream);
     fprintf(stream, "}");
 }
 #endif
@@ -987,8 +994,8 @@ UA_StatusCode UA_InvalidType_copy(UA_InvalidType const *src, UA_InvalidType *dst
     return UA_STATUSCODE_BADINTERNALERROR;
 }
 
-UA_StatusCode UA_InvalidType_new(UA_InvalidType **p) {
-    return UA_STATUSCODE_BADINTERNALERROR;
+UA_InvalidType * UA_InvalidType_new() {
+    return UA_NULL;
 }
 
 #ifdef DEBUG
@@ -1006,12 +1013,12 @@ UA_StatusCode UA_Array_new(void **p, UA_Int32 noElements, const UA_VTable_Entry
         *p = UA_NULL;
         return UA_STATUSCODE_GOOD;
     }
-
-    // FIXME! Arrays cannot be larger than 100MB.
-    // This was randomly chosen so that the development VM does not blow up.
-    if(noElements > (2^16)) {
+    
+    // Arrays cannot be larger than 2^16 elements. This was randomly chosen so
+    // that the development VM does not blow up during fuzzing tests.
+    if(noElements > (1<<15)) {
         *p = UA_NULL;
-        return UA_STATUSCODE_BADINTERNALERROR;
+        return UA_STATUSCODE_BADOUTOFMEMORY;
     }
 
     if(!(*p = UA_alloc(vt->memSize * noElements)))
@@ -1043,10 +1050,8 @@ void UA_Array_delete(void *p, UA_Int32 noElements, const UA_VTable_Entry *vt) {
 
 UA_StatusCode UA_Array_copy(const void *src, UA_Int32 noElements, const UA_VTable_Entry *vt, void **dst) {
     UA_StatusCode retval = UA_Array_new(dst, noElements, vt);
-    if(retval) {
-        *dst = UA_NULL;
+    if(retval)
         return retval;
-    }
 
     UA_Byte *csrc = (UA_Byte *)src; // so compilers allow pointer arithmetic
     UA_Byte *cdst = (UA_Byte *)*dst;

+ 16 - 16
src/ua_types_encoding_binary.c

@@ -84,13 +84,13 @@ UA_StatusCode UA_Array_decodeBinary(const UA_ByteString *src, UA_UInt32 *offset,
         return UA_STATUSCODE_GOOD;
     }
 
-    UA_StatusCode retval  = UA_Array_new(dst, length, vt);
+    UA_StatusCode retval = UA_Array_new(dst, length, vt);
     if(retval)
         return retval;
-        
-    UA_Byte      *arr     = (UA_Byte *)*dst;
-    UA_Int32      i       = 0;
-    UA_UInt32     memSize = vt->memSize;
+    
+    UA_Byte  *arr     = (UA_Byte *)*dst;
+    UA_Int32  i       = 0;
+    UA_UInt32 memSize = vt->memSize;
     for(;i < length && !retval;i++) {
         retval |= vt->encodings[UA_ENCODING_BINARY].decode(src, offset, arr);
         arr    += memSize;
@@ -473,9 +473,9 @@ UA_TYPE_ENCODEBINARY(UA_NodeId,
 
 UA_StatusCode UA_NodeId_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_NodeId *dst) {
     // temporary variables to overcome decoder's non-endian-saveness for datatypes with different length
-    UA_Byte   dstByte;
-    UA_UInt16 dstUInt16;
-    UA_Byte   encodingByte;
+    UA_Byte   dstByte = 0;
+    UA_UInt16 dstUInt16 = 0;
+    UA_Byte   encodingByte = 0;
 
     UA_StatusCode retval = UA_Byte_decodeBinary(src, offset, &encodingByte); // will be cleaned up in the end if sth goes wrong
     if(retval) {
@@ -674,7 +674,7 @@ UA_TYPE_ENCODEBINARY(UA_ExtensionObject,
 
                      case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING:
                          // FIXME: This code is valid for numeric nodeIds in ns0 only!
-                         retval |= UA_[UA_ns0ToVTableIndex(&src->typeId)].encodings[UA_ENCODING_BINARY].encode(src-> body. data, dst, offset);
+                         retval |= UA_TYPES[UA_ns0ToVTableIndex(&src->typeId)].encodings[UA_ENCODING_BINARY].encode(src-> body. data, dst, offset);
                          break;
 
                      case UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML:
@@ -688,7 +688,7 @@ UA_TYPE_ENCODEBINARY(UA_ExtensionObject,
 
 UA_StatusCode UA_ExtensionObject_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_ExtensionObject *dst) {
     UA_ExtensionObject_init(dst);
-    UA_Byte encoding;
+    UA_Byte encoding = 0;
     UA_StatusCode retval = UA_NodeId_decodeBinary(src, offset, &dst->typeId);
     retval |= UA_Byte_decodeBinary(src, offset, &encoding);
     dst->encoding = encoding;
@@ -817,9 +817,9 @@ UA_UInt32 UA_Variant_calcSizeBinary(UA_Variant const *p) {
 
     if(arrayLength != 1 && data->arrayDimensions != UA_NULL) {
         if(is_builtin(&p->vt->typeId))
-            length += UA_Array_calcSizeBinary(data->arrayDimensionsLength, &UA_[UA_INT32], data->arrayDimensions);
+            length += UA_Array_calcSizeBinary(data->arrayDimensionsLength, &UA_TYPES[UA_INT32], data->arrayDimensions);
         else
-            length += UA_Array_calcSizeBinary_asExtensionObject(data->arrayDimensionsLength, &UA_[UA_INT32], data->arrayDimensions);
+            length += UA_Array_calcSizeBinary_asExtensionObject(data->arrayDimensionsLength, &UA_TYPES[UA_INT32], data->arrayDimensions);
     }
     
     if(p->storageType == UA_VARIANT_DATASOURCE)
@@ -878,9 +878,9 @@ UA_TYPE_ENCODEBINARY(UA_Variant,
 
                      if(hasDimensions) {
                          if(isBuiltin)
-                             retval |= UA_Array_encodeBinary(data->arrayDimensions, data->arrayDimensionsLength, &UA_[UA_INT32], dst, offset);
+                             retval |= UA_Array_encodeBinary(data->arrayDimensions, data->arrayDimensionsLength, &UA_TYPES[UA_INT32], dst, offset);
                          else
-                             retval |= UA_Array_encodeBinary_asExtensionObject(data->arrayDimensions, data->arrayDimensionsLength, &UA_[UA_INT32], dst, offset);
+                             retval |= UA_Array_encodeBinary_asExtensionObject(data->arrayDimensions, data->arrayDimensionsLength, &UA_TYPES[UA_INT32], dst, offset);
                      }
 
                      if(src->storageType == UA_VARIANT_DATASOURCE)
@@ -902,7 +902,7 @@ UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, UA_UInt32 *offse
     UA_NodeId typeid = { .namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC,
                          .identifier.numeric = encodingByte & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK };
     UA_Int32 typeNs0Id = UA_ns0ToVTableIndex(&typeid );
-    const UA_VTable_Entry *vt = &UA_[typeNs0Id];
+    const UA_VTable_Entry *vt = &UA_TYPES[typeNs0Id];
 
     if(!isArray) {
         if(!(data->dataPtr = UA_alloc(vt->memSize)))
@@ -924,7 +924,7 @@ UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, UA_UInt32 *offse
     if(hasDimensions && retval == UA_STATUSCODE_GOOD) {
         retval |= UA_Int32_decodeBinary(src, offset, &data->arrayDimensionsLength);
         if(retval == UA_STATUSCODE_GOOD)
-            retval |= UA_Array_decodeBinary(src, offset, data->arrayDimensionsLength, &UA_[UA_INT32], &data->dataPtr);
+            retval |= UA_Array_decodeBinary(src, offset, data->arrayDimensionsLength, &UA_TYPES[UA_INT32], &data->dataPtr);
         if(retval)
             data->arrayLength = -1; // for deleteMembers
     }

+ 8 - 0
src/ua_util.h

@@ -17,6 +17,14 @@
 
 #include "ua_types.h"
 
+#define UA_NULL ((void *)0)
+#define UA_TRUE (42 == 42)
+#define UA_FALSE (!UA_TRUE)
+
+//identifier numbers are different for XML and binary, so we have to substract an offset for comparison
+#define UA_ENCODINGOFFSET_XML 1
+#define UA_ENCODINGOFFSET_BINARY 2
+
 /* Debug macros */
 #define DBG_VERBOSE(expression) // omit debug code
 #define DBG_ERR(expression)     // omit debug code

+ 1 - 1
tests/CMakeLists.txt

@@ -34,7 +34,7 @@ add_test(services_view ${CMAKE_CURRENT_BINARY_DIR}/check_services_view)
 
 add_executable(check_nodestore $<TARGET_OBJECTS:open62541-objects> check_nodestore.c)
 target_link_libraries(check_nodestore ${LIBS})
-add_test(namespace ${CMAKE_CURRENT_BINARY_DIR}/check_nodestore)
+add_test(nodestore ${CMAKE_CURRENT_BINARY_DIR}/check_nodestore)
 
 # add_executable(check_startup check_startup.c)
 # target_link_libraries(check_startup ${LIBS})

+ 35 - 28
tests/check_builtin.c

@@ -253,7 +253,7 @@ START_TEST(UA_Variant_calcSizeFixedSizeArrayShallReturnEncodingSize) {
 	// given
 	UA_Variant arg;
 	UA_Variant_init(&arg);
-	arg.vt = &UA_[UA_INT32];
+	arg.vt = &UA_TYPES[UA_INT32];
 #define ARRAY_LEN 8
 	arg.storage.data.arrayLength = ARRAY_LEN;
 	UA_Int32 *data[ARRAY_LEN];
@@ -271,7 +271,7 @@ START_TEST(UA_Variant_calcSizeVariableSizeArrayShallReturnEncodingSize) {
 	// given
 	UA_Variant arg;
 	UA_Variant_init(&arg);
-	arg.vt = &UA_[UA_STRING];
+	arg.vt = &UA_TYPES[UA_STRING];
 #define ARRAY_LEN 3
 	arg.storage.data.arrayLength = ARRAY_LEN;
 	UA_String strings[3];
@@ -642,7 +642,7 @@ START_TEST(UA_Variant_decodeWithOutArrayFlagSetShallSetVTAndAllocateMemoryForArr
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_int_eq(pos, 5);
-	ck_assert_ptr_eq(dst.vt, &UA_[UA_INT32]);
+	ck_assert_ptr_eq((void *)dst.vt, (void *)&UA_TYPES[UA_INT32]);
 	ck_assert_int_eq(dst.storage.data.arrayLength, 1);
 	ck_assert_int_eq(*(UA_Int32 *)dst.storage.data.dataPtr, 255);
 	// finally
@@ -664,7 +664,7 @@ START_TEST(UA_Variant_decodeWithArrayFlagSetShallSetVTAndAllocateMemoryForArray)
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_int_eq(pos, 1+4+2*4);
-	ck_assert_ptr_eq(dst.vt, &UA_[UA_INT32]);
+	ck_assert_ptr_eq((void*)dst.vt, (void*)&UA_TYPES[UA_INT32]);
 	ck_assert_int_eq(dst.storage.data.arrayLength, 2);
 	ck_assert_int_eq(((UA_Int32 *)dst.storage.data.dataPtr)[0], 255);
 	ck_assert_int_eq(((UA_Int32 *)dst.storage.data.dataPtr)[1], -1);
@@ -1087,7 +1087,7 @@ START_TEST(UA_DataValue_encodeShallWorkOnExampleWithVariant) {
 	src.serverTimestamp    = 80;
 	src.encodingMask       = UA_DATAVALUE_ENCODINGMASK_VARIANT | UA_DATAVALUE_ENCODINGMASK_SERVERTIMESTAMP; //Variant & SourvePicoseconds
 	UA_Variant_init(&src.value);
-	src.value.vt           = &UA_[UA_INT32];
+	src.value.vt           = &UA_TYPES[UA_INT32];
 	src.value.storage.data.arrayLength  = 1; // one element (encoded as not an array)
 	UA_Int32  vdata  = 45;
 	src.value.storage.data.dataPtr = (void *)&vdata;
@@ -1154,6 +1154,7 @@ START_TEST(UA_DateTime_toStringShallWorkOnExample) {
 	ck_assert_int_eq(dst.data[2], '/');
 	ck_assert_int_eq(dst.data[3], '1');
 	ck_assert_int_eq(dst.data[4], '4');
+    UA_String_deleteMembers(&dst);
 }
 END_TEST
 START_TEST(UA_ExtensionObject_copyShallWorkOnExample) {
@@ -1203,7 +1204,7 @@ START_TEST(UA_Array_copyByteArrayShallWorkOnExample) {
 	testString.length  = 5;
 
 	//when
-	UA_Array_copy((const void *)testString.data, 5, &UA_[UA_BYTE], (void **)&dstArray);
+	UA_Array_copy((const void *)testString.data, 5, &UA_TYPES[UA_BYTE], (void **)&dstArray);
 	//then
 	for(i = 0;i < size;i++)
 		ck_assert_int_eq(testString.data[i], dstArray[i]);
@@ -1219,14 +1220,14 @@ START_TEST(UA_Array_copyUA_StringShallWorkOnExample) {
 	// given
 	UA_Int32   i, j;
 	UA_String *srcArray;
-	UA_Array_new((void **)&srcArray, 3, &UA_[UA_STRING]);
+    UA_Array_new((void**)&srcArray, 3, &UA_TYPES[UA_STRING]);
 	UA_String *dstArray;
 
 	UA_String_copycstring("open", &srcArray[0]);
 	UA_String_copycstring("62541", &srcArray[1]);
 	UA_String_copycstring("opc ua", &srcArray[2]);
 	//when
-	UA_Array_copy((const void *)srcArray, 3, &UA_[UA_STRING], (void **)&dstArray);
+	UA_Array_copy((const void *)srcArray, 3, &UA_TYPES[UA_STRING], (void **)&dstArray);
 	//then
 	for(i = 0;i < 3;i++) {
 		for(j = 0;j < 3;j++)
@@ -1234,8 +1235,8 @@ START_TEST(UA_Array_copyUA_StringShallWorkOnExample) {
 		ck_assert_int_eq(srcArray[i].length, dstArray[i].length);
 	}
 	//finally
-	UA_Array_delete(srcArray, 3, &UA_[UA_STRING]);
-	UA_Array_delete(dstArray, 3, &UA_[UA_STRING]);
+	UA_Array_delete(srcArray, 3, &UA_TYPES[UA_STRING]);
+	UA_Array_delete(dstArray, 3, &UA_TYPES[UA_STRING]);
 }
 END_TEST
 
@@ -1343,6 +1344,8 @@ START_TEST(UA_QualifiedName_copyShallWorkOnInputExample) {
 	ck_assert_int_eq('!', dst.name.data[7]);
 	ck_assert_int_eq(8, dst.name.length);
 	ck_assert_int_eq(5, dst.namespaceIndex);
+    // finally
+    UA_QualifiedName_deleteMembers(&dst);
 }
 END_TEST
 START_TEST(UA_Guid_copyShallWorkOnInputExample) {
@@ -1363,7 +1366,7 @@ START_TEST(UA_Guid_copyShallWorkOnInputExample) {
 END_TEST
 START_TEST(UA_LocalizedText_copycstringShallWorkOnInputExample) {
 	// given
-	const char src[7] = {'t', 'e', 'X', 't', '1', '2', '3'};
+	const char src[8] = {'t', 'e', 'X', 't', '1', '2', '3', (char)0};
 	UA_LocalizedText dst;
 
 	// when
@@ -1375,6 +1378,8 @@ START_TEST(UA_LocalizedText_copycstringShallWorkOnInputExample) {
 	ck_assert_int_eq('1', dst.text.data[4]);
 	ck_assert_int_eq(2, dst.locale.length);
 	ck_assert_int_eq(7, dst.text.length);
+    // finally
+    UA_LocalizedText_deleteMembers(&dst);
 }
 END_TEST
 START_TEST(UA_DataValue_copyShallWorkOnInputExample) {
@@ -1402,7 +1407,7 @@ START_TEST(UA_Variant_copyShallWorkOnSingleValueExample) {
 	UA_Variant_init(&copiedValue);
 	value.storage.data.dataPtr = UA_alloc(sizeof(UA_String));
 	*((UA_String*)value.storage.data.dataPtr) = testString;
-	value.vt = &UA_[UA_STRING];
+	value.vt = &UA_TYPES[UA_STRING];
 	value.storage.data.arrayLength = 1;
 
 	//when
@@ -1426,7 +1431,7 @@ END_TEST
 START_TEST(UA_Variant_copyShallWorkOn1DArrayExample) {
 	// given
 	UA_String *srcArray;
-	UA_Array_new((void **)&srcArray, 3, &UA_[UA_STRING]);
+    UA_Array_new((void**)&srcArray, 3, &UA_TYPES[UA_STRING]);
 	UA_String_copycstring("__open", &srcArray[0]);
 	UA_String_copycstring("_62541", &srcArray[1]);
 	UA_String_copycstring("opc ua", &srcArray[2]);
@@ -1440,10 +1445,10 @@ START_TEST(UA_Variant_copyShallWorkOn1DArrayExample) {
 	UA_Variant_init(&copiedValue);
 
 	value.storage.data.arrayLength = 3;
-	value.storage.data.dataPtr        = (void **)srcArray;
+	value.storage.data.dataPtr = (void *)srcArray;
 	value.storage.data.arrayDimensionsLength = 1;
-	value.storage.data.arrayDimensions       = dimensions;
-	value.vt = &UA_[UA_STRING];
+	value.storage.data.arrayDimensions = dimensions;
+	value.vt = &UA_TYPES[UA_STRING];
 
 	//when
 	UA_Variant_copy(&value, &copiedValue);
@@ -1452,15 +1457,17 @@ START_TEST(UA_Variant_copyShallWorkOn1DArrayExample) {
 	UA_Int32 i1 = value.storage.data.arrayDimensions[0];
 	UA_Int32 i2 = copiedValue.storage.data.arrayDimensions[0];
 	ck_assert_int_eq(i1, i2);
-
+    
 	for(UA_Int32 i = 0;i < 3;i++) {
-		for(UA_Int32 j = 0;j < 6;j++)
-			ck_assert_int_eq(((UA_String *)value.storage.data.dataPtr)[i].data[j], ((UA_String *)copiedValue.storage.data.dataPtr)[i].data[j]);
-		ck_assert_int_eq(((UA_String *)value.storage.data.dataPtr)[i].length, ((UA_String *)copiedValue.storage.data.dataPtr)[i].length);
+		for(UA_Int32 j = 0;j < 6;j++) {
+			ck_assert_int_eq(((UA_String *)value.storage.data.dataPtr)[i].data[j],
+                             ((UA_String *)copiedValue.storage.data.dataPtr)[i].data[j]);
+        }
+		ck_assert_int_eq(((UA_String *)value.storage.data.dataPtr)[i].length,
+                         ((UA_String *)copiedValue.storage.data.dataPtr)[i].length);
 	}
 	ck_assert_int_eq(((UA_String *)copiedValue.storage.data.dataPtr)[0].data[2], 'o');
 	ck_assert_int_eq(((UA_String *)copiedValue.storage.data.dataPtr)[0].data[3], 'p');
-
 	ck_assert_int_eq(value.storage.data.arrayDimensionsLength, copiedValue.storage.data.arrayDimensionsLength);
 	ck_assert_int_eq(value.storage.data.arrayLength, copiedValue.storage.data.arrayLength);
 
@@ -1472,7 +1479,7 @@ END_TEST
 START_TEST(UA_Variant_copyShallWorkOn2DArrayExample) {
 	// given
 	UA_Int32 *srcArray;
-	UA_Array_new((void **)&srcArray, 6, &UA_[UA_INT32]);
+    UA_Array_new((void**)&srcArray, 6, &UA_TYPES[UA_INT32]);
 	srcArray[0] = 0;
 	srcArray[1] = 1;
 	srcArray[2] = 2;
@@ -1481,9 +1488,9 @@ START_TEST(UA_Variant_copyShallWorkOn2DArrayExample) {
 	srcArray[5] = 5;
 
 	UA_Int32 *dimensions;
-	UA_Array_new((void **)&dimensions, 2, &UA_[UA_INT32]);
-	UA_Int32  dim1 = 3;
-	UA_Int32  dim2 = 2;
+    UA_Array_new((void**)&dimensions, 2, &UA_TYPES[UA_INT32]);
+	UA_Int32 dim1 = 3;
+	UA_Int32 dim2 = 2;
 	dimensions[0] = dim1;
 	dimensions[1] = dim2;
 
@@ -1492,10 +1499,10 @@ START_TEST(UA_Variant_copyShallWorkOn2DArrayExample) {
 	UA_Variant_init(&copiedValue);
 
 	value.storage.data.arrayLength = 6;
-	value.storage.data.dataPtr        = (void **)srcArray;
+	value.storage.data.dataPtr     = (void **)srcArray;
 	value.storage.data.arrayDimensionsLength = 2;
 	value.storage.data.arrayDimensions       = dimensions;
-	value.vt = &UA_[UA_INT32];
+	value.vt = &UA_TYPES[UA_INT32];
 
 	//when
 	UA_Variant_copy(&value, &copiedValue);
@@ -1637,7 +1644,7 @@ int main(void) {
 
 	s  = testSuite_builtin();
 	sr = srunner_create(s);
-	// srunner_set_fork_status(sr, CK_NOFORK);
+	//srunner_set_fork_status(sr, CK_NOFORK);
 	srunner_run_all(sr, CK_NORMAL);
 	number_failed += srunner_ntests_failed(sr);
 	srunner_free(sr);

+ 39 - 44
tests/check_memory.c

@@ -9,16 +9,15 @@
 
 START_TEST(newAndEmptyObjectShallBeDeleted) {
 	// given
-	UA_Int32 retval;
-	void    *obj;
+	void *obj = UA_TYPES[_i].new();
 	// when
-	retval  = UA_[_i].new(&obj);
 #ifdef DEBUG //no print functions if not in debug mode
-	UA_[_i].print(obj, stdout);
+	UA_TYPES[_i].print(obj, stdout);
 #endif
-	UA_[_i].delete(obj);
 	// then
-	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
+	ck_assert_ptr_ne(obj, UA_NULL);
+    // finally
+	UA_TYPES[_i].delete(obj);
 }
 END_TEST
 
@@ -30,7 +29,7 @@ START_TEST(arrayCopyShallMakeADeepCopy) {
 	a1[2] = (UA_String){3, (UA_Byte*)"ccc"};
 	// when
 	UA_String *a2;
-	UA_Int32   retval = UA_Array_copy((const void *)a1, 3, &UA_[UA_STRING], (void **)&a2);
+	UA_Int32   retval = UA_Array_copy((const void *)a1, 3, &UA_TYPES[UA_STRING], (void **)&a2);
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_int_eq(a1[0].length, 1);
@@ -46,41 +45,39 @@ START_TEST(arrayCopyShallMakeADeepCopy) {
 	ck_assert_int_eq(a1[1].data[0], a2[1].data[0]);
 	ck_assert_int_eq(a1[2].data[0], a2[2].data[0]);
 	// finally
-	UA_Array_delete((void *)a2, 3, &UA_[UA_STRING]);
+	UA_Array_delete((void *)a2, 3, &UA_TYPES[UA_STRING]);
 }
 END_TEST
 
 START_TEST(encodeShallYieldDecode) {
 	// given
-	void         *obj1 = UA_NULL, *obj2 = UA_NULL;
 	UA_ByteString msg1, msg2;
-	UA_Int32      retval;
 	UA_UInt32     pos = 0;
-	retval = UA_[_i].new(&obj1);
-	UA_ByteString_newMembers(&msg1, UA_[_i].encodings[UA_ENCODING_BINARY].calcSize(obj1));
-	retval |= UA_[_i].encodings[UA_ENCODING_BINARY].encode(obj1, &msg1, &pos);
+	void *obj1 = UA_TYPES[_i].new();
+	UA_ByteString_newMembers(&msg1, UA_TYPES[_i].encodings[UA_ENCODING_BINARY].calcSize(obj1));
+	UA_StatusCode retval = UA_TYPES[_i].encodings[UA_ENCODING_BINARY].encode(obj1, &msg1, &pos);
 	if(retval != UA_STATUSCODE_GOOD) {
-		// this happens, e.g. when we encode a variant (with UA_[UA_INVALIDTYPE] in the vtable)
-		UA_[_i].delete(obj1);
+		// this happens, e.g. when we encode a variant (with UA_TYPES[UA_INVALIDTYPE] in the vtable)
+		UA_TYPES[_i].delete(obj1);
 		UA_ByteString_deleteMembers(&msg1);
 		return;	
 	}
 
 	// when
-	UA_[_i].new(&obj2);
-	pos = 0; retval = UA_[_i].encodings[UA_ENCODING_BINARY].decode(&msg1, &pos, obj2);
-	ck_assert_msg(retval == UA_STATUSCODE_GOOD, "messages differ idx=%d,name=%s", _i, UA_[_i].name);
-	retval = UA_ByteString_newMembers(&msg2, UA_[_i].encodings[UA_ENCODING_BINARY].calcSize(obj2));
+	void *obj2 = UA_TYPES[_i].new();
+	pos = 0; retval = UA_TYPES[_i].encodings[UA_ENCODING_BINARY].decode(&msg1, &pos, obj2);
+	ck_assert_msg(retval == UA_STATUSCODE_GOOD, "messages differ idx=%d,name=%s", _i, UA_TYPES[_i].name);
+	retval = UA_ByteString_newMembers(&msg2, UA_TYPES[_i].encodings[UA_ENCODING_BINARY].calcSize(obj2));
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
-	pos = 0; retval = UA_[_i].encodings[UA_ENCODING_BINARY].encode(obj2, &msg2, &pos);
+	pos = 0; retval = UA_TYPES[_i].encodings[UA_ENCODING_BINARY].encode(obj2, &msg2, &pos);
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 
 	// then
-	ck_assert_msg(UA_ByteString_equal(&msg1, &msg2) == 0, "messages differ idx=%d,name=%s", _i, UA_[_i].name);
+	ck_assert_msg(UA_ByteString_equal(&msg1, &msg2) == UA_TRUE, "messages differ idx=%d,name=%s", _i, UA_TYPES[_i].name);
 
 	// finally
-	UA_[_i].delete(obj1);
-	UA_[_i].delete(obj2);
+	UA_TYPES[_i].delete(obj1);
+	UA_TYPES[_i].delete(obj2);
 	UA_ByteString_deleteMembers(&msg1);
 	UA_ByteString_deleteMembers(&msg2);
 }
@@ -88,23 +85,22 @@ END_TEST
 
 START_TEST(decodeShallFailWithTruncatedBufferButSurvive) {
 	// given
-	void *obj1 = UA_NULL, *obj2 = UA_NULL;
 	UA_ByteString msg1;
 	UA_UInt32 pos;
-	UA_[_i].new(&obj1);
-	UA_ByteString_newMembers(&msg1, UA_[_i].encodings[0].calcSize(obj1));
-	pos = 0; UA_[_i].encodings[0].encode(obj1, &msg1, &pos);
-	UA_[_i].delete(obj1);
+	void *obj1 = UA_TYPES[_i].new();
+	UA_ByteString_newMembers(&msg1, UA_TYPES[_i].encodings[0].calcSize(obj1));
+	pos = 0; UA_TYPES[_i].encodings[0].encode(obj1, &msg1, &pos);
+	UA_TYPES[_i].delete(obj1);
 	// when
-	UA_[_i].new(&obj2);
+	void *obj2 = UA_TYPES[_i].new();
 	pos = 0;
 	msg1.length = msg1.length / 2;
-	//fprintf(stderr,"testing %s with half buffer\n",UA_[_i].name);
-	UA_[_i].encodings[0].decode(&msg1, &pos, obj2);
+	//fprintf(stderr,"testing %s with half buffer\n",UA_TYPES[_i].name);
+	UA_TYPES[_i].encodings[0].decode(&msg1, &pos, obj2);
 	//then
 	// finally
-	//fprintf(stderr,"delete %s with half buffer\n",UA_[_i].name);
-	UA_[_i].delete(obj2);
+	//fprintf(stderr,"delete %s with half buffer\n",UA_TYPES[_i].name);
+	UA_TYPES[_i].delete(obj2);
 	UA_ByteString_deleteMembers(&msg1);
 }
 END_TEST
@@ -134,12 +130,12 @@ START_TEST(decodeScalarBasicTypeFromRandomBufferShallSucceed) {
 #endif
 		}
 		UA_UInt32 pos = 0;
-		retval |= UA_[_i].new(&obj1);
-		retval |= UA_[_i].encodings[0].decode(&msg1, &pos, obj1);
+		obj1 = UA_TYPES[_i].new();
+		retval |= UA_TYPES[_i].encodings[0].decode(&msg1, &pos, obj1);
 		//then
-		ck_assert_msg(retval == UA_STATUSCODE_GOOD, "Decoding %s from random buffer", UA_[_i].name);
+		ck_assert_msg(retval == UA_STATUSCODE_GOOD, "Decoding %s from random buffer", UA_TYPES[_i].name);
 		// finally
-		UA_[_i].delete(obj1);
+		UA_TYPES[_i].delete(obj1);
 	}
 	UA_ByteString_deleteMembers(&msg1);
 }
@@ -147,7 +143,6 @@ END_TEST
 
 START_TEST(decodeComplexTypeFromRandomBufferShallSurvive) {
 	// given
-	void    *obj1 = UA_NULL;
 	UA_ByteString msg1;
 	UA_Int32 retval = UA_STATUSCODE_GOOD;
 	UA_Int32 buflen = 256;
@@ -159,7 +154,7 @@ START_TEST(decodeComplexTypeFromRandomBufferShallSurvive) {
 #endif
 	// when
 	for(int n = 0;n < RANDOM_TESTS;n++) {
-		for(UA_Int32 i = 0;i < buflen;i++){
+		for(UA_Int32 i = 0;i < buflen;i++) {
 #ifdef WIN32
 			UA_UInt32 rnd;
 			rnd = rand();
@@ -169,9 +164,9 @@ START_TEST(decodeComplexTypeFromRandomBufferShallSurvive) {
 #endif
 		}
 		UA_UInt32 pos = 0;
-		retval |= UA_[_i].new(&obj1);
-		retval |= UA_[_i].encodings[0].decode(&msg1, &pos, obj1);
-		UA_[_i].delete(obj1);
+		void *obj1 = UA_TYPES[_i].new();
+		retval |= UA_TYPES[_i].encodings[0].decode(&msg1, &pos, obj1);
+		UA_TYPES[_i].delete(obj1);
 	}
 
 	// finally
@@ -183,8 +178,8 @@ int main() {
 	int number_failed = 0;
 	SRunner *sr;
 
-	Suite   *s  = suite_create("testMemoryHandling");
-	TCase   *tc = tcase_create("Empty Objects");
+	Suite *s  = suite_create("testMemoryHandling");
+	TCase *tc = tcase_create("Empty Objects");
 	tcase_add_loop_test(tc, newAndEmptyObjectShallBeDeleted, UA_BOOLEAN, UA_INVALIDTYPE-1);
 	tcase_add_test(tc, arrayCopyShallMakeADeepCopy);
 	tcase_add_loop_test(tc, encodeShallYieldDecode, UA_BOOLEAN, UA_INVALIDTYPE-1);

+ 13 - 13
tests/check_nodestore.c

@@ -30,8 +30,8 @@ START_TEST(test_UA_NodeStore) {
 }
 END_TEST
 
-UA_Int32 createNode(UA_Node** p, UA_Int16 nsid, UA_Int32 id) {
-	UA_VariableNode_new((UA_VariableNode **)p);
+UA_StatusCode createNode(UA_Node** p, UA_Int16 nsid, UA_Int32 id) {
+	*p = (UA_Node *)UA_VariableNode_new();
 	(*p)->nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
 	(*p)->nodeId.namespaceIndex = nsid;
 	(*p)->nodeId.identifier.numeric = id;
@@ -54,10 +54,10 @@ START_TEST(findNodeInUA_NodeStoreWithSingleEntry) {
 	retval = UA_NodeStore_get(ns,&n1->nodeId,&nr);
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
-	ck_assert_ptr_eq(nr,n1);
+	ck_assert_ptr_eq((void*)nr, (void*)n1);
 	// finally
-	UA_NodeStore_releaseManagedNode(n1);
-	UA_NodeStore_releaseManagedNode(nr);
+	UA_NodeStore_release(n1);
+	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef MULTITHREADING
 	rcu_unregister_thread();
@@ -84,7 +84,7 @@ START_TEST(failToFindNodeInOtherUA_NodeStore) {
 	ck_assert_int_ne(retval, UA_STATUSCODE_GOOD);
 	// finally
 	UA_Node_delete(n);
-	UA_NodeStore_releaseManagedNode(nr);
+	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef MULTITHREADING
 	rcu_unregister_thread();
@@ -112,10 +112,10 @@ START_TEST(findNodeInUA_NodeStoreWithSeveralEntries) {
 	retval = UA_NodeStore_get(ns,&(n3->nodeId),&nr);
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
-	ck_assert_ptr_eq(nr,n3);
+	ck_assert_ptr_eq((void*)nr, (void*)n3);
 	// finally
-	UA_NodeStore_releaseManagedNode(n3);
-	UA_NodeStore_releaseManagedNode(nr);
+	UA_NodeStore_release(n3);
+	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef MULTITHREADING
 	rcu_unregister_thread();
@@ -174,7 +174,7 @@ START_TEST(findNodeInExpandedNamespace) {
 	ck_assert_int_eq(nr->nodeId.identifier.numeric,n->nodeId.identifier.numeric);
 	// finally
 	UA_free((void*)n);
-	UA_NodeStore_releaseManagedNode(nr);
+	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef MULTITHREADING
 	rcu_unregister_thread();
@@ -261,7 +261,7 @@ void *profileGetThread(void *arg) {
 		for (UA_Int32 i=test->min_val; i<max_val; i++) {
 			id.identifier.numeric = i;
 			UA_NodeStore_get(ns,&id, &cn);
-			UA_NodeStore_releaseManagedNode(cn);
+			UA_NodeStore_release(cn);
 		}
 	}
 	rcu_unregister_thread();
@@ -304,7 +304,7 @@ START_TEST(profileGetDelete) {
 	    for(i=0; i<N; i++) {
 	        id.identifier.numeric = i;
 			UA_NodeStore_get(ns,&id, &cn);
-			UA_NodeStore_releaseManagedNode(cn);
+			UA_NodeStore_release(cn);
         }
     }
 	end = clock();
@@ -351,7 +351,7 @@ int main (void) {
 	int number_failed =0;
 	Suite *s = namespace_suite ();
 	SRunner *sr = srunner_create (s);
-	//srunner_set_fork_status(sr,CK_NOFORK);
+	srunner_set_fork_status(sr,CK_NOFORK);
 	srunner_run_all (sr, CK_NORMAL);
 	number_failed += srunner_ntests_failed (sr);
 	srunner_free (sr);

+ 17 - 12
tools/generate_builtin.py

@@ -10,6 +10,7 @@ import inspect
 import argparse
 
 parser = argparse.ArgumentParser()
+parser.add_argument('--export-prototypes', action='store_true', help='make the prototypes (init, delete, copy, ..) of generated types visible for users of the library')
 parser.add_argument('--with-xml', action='store_true', help='generate xml encoding')
 parser.add_argument('--with-json', action='store_true', help='generate json encoding')
 parser.add_argument('--only-nano', action='store_true', help='generate only the types for the nano profile')
@@ -81,17 +82,21 @@ def createEnumerated(element):
     valuemap = OrderedDict()
     name = "UA_" + element.get("Name")
     fixed_size.add(name)
+    printh("") # newline
     for child in element:
         if child.tag == "{http://opcfoundation.org/BinarySchema/}Documentation":
             printh("/** @brief " + child.text + " */")
         if child.tag == "{http://opcfoundation.org/BinarySchema/}EnumeratedValue":
             valuemap[name + "_" + child.get("Name")] = child.get("Value")
     valuemap = OrderedDict(sorted(valuemap.iteritems(), key=lambda (k,v): int(v)))
-    printh("typedef UA_Int32 " + name + ";")
-    printh("enum " + name + "_enum { \n\t" +
+    # printh("typedef UA_Int32 " + name + ";")
+    printh("typedef enum " + name + " { \n\t" +
            ",\n\t".join(map(lambda (key, value) : key.upper() + " = " + value, valuemap.iteritems())) +
-           "\n};")
-    printh("UA_TYPE_PROTOTYPES (" + name + ")")
+           "\n} " + name + ";")
+    if args.export_prototypes:
+        printh("UA_TYPE_PROTOTYPES(" + name + ")")
+    else:
+        printh("UA_TYPE_PROTOTYPES_NOEXPORT(" + name + ")")
     printh("UA_TYPE_BINARY_ENCODING(" + name + ")")
     printc("UA_TYPE_AS(" + name + ", UA_Int32)")
     printc("UA_TYPE_BINARY_ENCODING_AS(" + name + ", UA_Int32)")
@@ -103,6 +108,7 @@ UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s\n)''')
 
 def createOpaque(element):
     name = "UA_" + element.get("Name")
+    printh("") # newline
     for child in element:
         if child.tag == "{http://opcfoundation.org/BinarySchema/}Documentation":
             printh("/** @brief " + child.text + " */")
@@ -128,6 +134,7 @@ def createStructured(element):
 
     # 2) Store members in membermap (name->type).
     membermap = OrderedDict()
+    printh("") # newline
     for child in element:
         if child.tag == "{http://opcfoundation.org/BinarySchema/}Documentation":
             printh("/** @brief " + child.text + " */")
@@ -152,7 +159,6 @@ def createStructured(element):
     else:
         printh("typedef void* %(name)s;")
         
-
     # 3) function prototypes
     printh("UA_TYPE_PROTOTYPES(" + name + ")")
     printh("UA_TYPE_BINARY_ENCODING(" + name + ")")
@@ -167,7 +173,7 @@ def createStructured(element):
         if t in fixed_size:
             printc('\t + sizeof(%(t)s) // %(n)s')
         elif t.find("*") != -1:
-            printc('\t + UA_Array_calcSizeBinary(ptr->%(n)sSize,&UA_['+ t[0:t.find("*")].upper() +
+            printc('\t + UA_Array_calcSizeBinary(ptr->%(n)sSize,&UA_TYPES['+ t[0:t.find("*")].upper() +
                    "],ptr->%(n)s)")
             has_fixed_size = False
         else:
@@ -182,7 +188,7 @@ def createStructured(element):
     UA_StatusCode retval = UA_STATUSCODE_GOOD;''')
     for n,t in membermap.iteritems():
         if t.find("*") != -1:
-            printc("\tretval |= UA_Array_encodeBinary(src->%(n)s,src->%(n)sSize,&UA_[" + t[0:t.find("*")].upper() + "],dst,offset);")
+            printc("\tretval |= UA_Array_encodeBinary(src->%(n)s,src->%(n)sSize,&UA_TYPES[" + t[0:t.find("*")].upper() + "],dst,offset);")
         else:
             printc('\tretval |= %(t)s_encodeBinary(&src->%(n)s,dst,offset);')
     printc("\treturn retval;\n}\n")
@@ -195,7 +201,7 @@ def createStructured(element):
     for n,t in membermap.iteritems():
         if t.find("*") != -1:
             printc('\tretval |= UA_Int32_decodeBinary(src,offset,&dst->%(n)sSize);')
-            printc('\tif(!retval) { retval |= UA_Array_decodeBinary(src,offset,dst->%(n)sSize,&UA_[' + t[0:t.find("*")].upper() + '],(void**)&dst->%(n)s); }')
+            printc('\tif(!retval) { retval |= UA_Array_decodeBinary(src,offset,dst->%(n)sSize,&UA_TYPES[' + t[0:t.find("*")].upper() + '],(void**)&dst->%(n)s); }')
             printc('\tif(retval) { dst->%(n)sSize = -1; }') # arrays clean up internally. But the size needs to be set here for the eventual deleteMembers.
         else:
             printc('\tretval |= %(t)s_decodeBinary(src,offset,&dst->%(n)s);')
@@ -218,7 +224,7 @@ UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     for n,t in membermap.iteritems():
         if not t in fixed_size: # dynamic size on the wire
             if t.find("*") != -1:
-		printc("\tUA_Array_delete((void*)p->%(n)s,p->%(n)sSize,&UA_["+t[0:t.find("*")].upper()+"]);")
+		printc("\tUA_Array_delete((void*)p->%(n)s,p->%(n)sSize,&UA_TYPES["+t[0:t.find("*")].upper()+"]);")
             else:
 		printc('\t%(t)s_deleteMembers(&p->%(n)s);')
     printc("}\n")
@@ -244,7 +250,7 @@ UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     for n,t in membermap.iteritems():
         if t.find("*") != -1:
             printc('\tdst->%(n)sSize = src->%(n)sSize;')
-            printc("\tretval |= UA_Array_copy(src->%(n)s, src->%(n)sSize,&UA_[" + t[0:t.find("*")].upper() + "],(void**)&dst->%(n)s);")
+            printc("\tretval |= UA_Array_copy(src->%(n)s, src->%(n)sSize,&UA_TYPES[" + t[0:t.find("*")].upper() + "],(void**)&dst->%(n)s);")
             continue
         if not t in fixed_size: # there are members of variable size    
             printc('\tretval |= %(t)s_copy(&src->%(n)s,&dst->%(n)s);')
@@ -261,7 +267,7 @@ UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     for i,(n,t) in enumerate(membermap.iteritems()):
         if t.find("*") != -1:
             printc('\tUA_Int32_print(&p->%(n)sSize, stream);')
-            printc("\tUA_Array_print(p->%(n)s, p->%(n)sSize, &UA_[" + t[0:t.find("*")].upper()+"], stream);")
+            printc("\tUA_Array_print(p->%(n)s, p->%(n)sSize, &UA_TYPES[" + t[0:t.find("*")].upper()+"], stream);")
         else:
             printc('\t%(t)s_print(&p->%(n)s,stream);')
         if i == len(membermap)-1:
@@ -301,7 +307,6 @@ if args.with_xml:
 if args.additional_includes:
     for incl in args.additional_includes.split(","):
         printh("#include \"" + incl + "\"")
-printh("") # newline
 
 printc('''/**
  * @file '''+sys.argv[2]+'''.c

+ 50 - 25
tools/generate_namespace.py

@@ -104,14 +104,10 @@ printh('''/**********************************************************
  */
 
 UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id);\n
-extern const UA_VTable_Entry UA_EXPORT *UA_;
+extern const UA_VTable_Entry UA_EXPORT *UA_TYPES;
+extern const UA_NodeId UA_EXPORT *UA_NODEIDS;
 
-/**
- * @brief the set of possible indices into UA_VTable
- *
- * Enumerated type to define the types that the open62541 stack can handle
- */
-enum UA_VTableIndex_enum {''')
+/** The entries of UA_TYPES can be accessed with the following indices */ ''')
 
 printc('''/**********************************************************
  * '''+args.outfile.split("/")[-1]+'''.cgen -- do not modify
@@ -138,15 +134,27 @@ for row in rows:
     else:
         name = "UA_" + row[0]
 	
-    printh("\t"+name.upper()+" = "+str(i)+",")
+    printh("#define "+name.upper()+" "+str(i))
     printc('\tcase '+row[1]+': retval='+name.upper()+'; break; //'+row[2])
     i = i+1
 
-printh("};\n")
+printh('\n#define SIZE_UA_VTABLE '+str(i));
+printh("") # newline
+printh("/** In UA_NODEIDS are the nodeids of the types, referencetypes and objects */")
+# assign indices to the reference types afterwards
+for row in rows:
+    if row[0] == "" or (row[2] != "ReferenceType" and (row[2] != "Object" or "_Encoding_Default" in row[0])):
+        continue
+    name = "UA_" + row[0]
+    printh("#define "+name.upper()+" "+str(i))
+    i=i+1
+
 printc('''\n}\nreturn retval;\n}\n''');
 
-printc('''const UA_VTable_Entry *UA_ = (UA_VTable_Entry[]){''')
-i = 0
+printh("") # newline
+printh("/** These are the actual (numeric) nodeids of the types, not the indices to the vtable */")
+
+printc('''const UA_VTable_Entry *UA_TYPES = (UA_VTable_Entry[]){''')
 for row in rows:
     if skipType(row):
         continue
@@ -156,32 +164,49 @@ for row in rows:
         name = "UA_ExtensionObject"
     else:
 	name = "UA_" + row[0]
-	i=i+1
     printh('#define '+name.upper()+'_NS0 '+row[1])
 
     printc("\t{.typeId={.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric=" + row[1] + "}" + 
-          ",\n.name=(UA_Byte*)&\"%(name)s\"" +
-          ",\n.new=(UA_Int32(*)(void **))%(name)s_new" +
-          ",\n.init=(void(*)(void *))%(name)s_init"+
-          ",\n.copy=(UA_Int32(*)(void const * ,void*))%(name)s_copy" +
-          ",\n.delete=(void(*)(void *))%(name)s_delete" +
-          ",\n.deleteMembers=(void(*)(void *))%(name)s_deleteMembers" +
-          ",\n#ifdef DEBUG //FIXME: seems to be okay atm, however a pointer to a noop function would be more safe" + 
-          "\n.print=(void(*)(const void *, FILE *))%(name)s_print," +
-          "\n#endif" + 
-          "\n.memSize=" + ("sizeof(%(name)s)" if (name != "UA_InvalidType") else "0") +
-          ",\n.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
+           ",\n.name=(UA_Byte*)&\"%(name)s\"" +
+           ",\n.new=(void *(*)())%(name)s_new" +
+           ",\n.init=(void(*)(void *))%(name)s_init"+
+           ",\n.copy=(UA_Int32(*)(void const * ,void*))%(name)s_copy" +
+           ",\n.delete=(void(*)(void *))%(name)s_delete" +
+           ",\n.deleteMembers=(void(*)(void *))%(name)s_deleteMembers" +
+           ",\n#ifdef DEBUG //FIXME: seems to be okay atm, however a pointer to a noop function would be more safe" + 
+           "\n.print=(void(*)(const void *, FILE *))%(name)s_print," +
+           "\n#endif" + 
+           "\n.memSize=" + ("sizeof(%(name)s)" if (name != "UA_InvalidType") else "0") +
+           ",\n.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
            ",\n.encodings={{.calcSize=(UA_Int32(*)(const void*))%(name)s_calcSizeBinary" +
            ",\n.encode=(UA_Int32(*)(const void*,UA_ByteString*,UA_UInt32*))%(name)s_encodeBinary" +
            ",\n.decode=(UA_Int32(*)(const UA_ByteString*,UA_UInt32*,void*))%(name)s_decodeBinary}" +
            (",\n{.calcSize=(UA_Int32(*)(const void*))%(name)s_calcSizeXml" +
             ",\n.encode=(UA_Int32(*)(const void*,UA_ByteString*,UA_UInt32*))%(name)s_encodeXml" +
             ",\n.decode=(UA_Int32(*)(const UA_ByteString*,UA_UInt32*,void*))%(name)s_decodeXml}" if (args.with_xml) else "") +
-          "}},")
+           "}},")
 
 printc('};')
 
-printh('\n#define SIZE_UA_VTABLE '+str(i));
+# make the nodeids available as well
+printc('''const UA_NodeId *UA_NODEIDS = (UA_NodeId[]){''')
+for row in rows:
+    if skipType(row):
+        continue
+    if row[0] == "BaseDataType":
+        name = "UA_Variant"
+    elif row[0] == "Structure":
+        name = "UA_ExtensionObject"
+    else:
+	name = "UA_" + row[0]
+    printc("\t{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = " + row[1] + "},")
+
+for row in rows:
+    if row[0] == "" or (row[2] != "ReferenceType" and (row[2] != "Object" or "_Encoding_Default" in row[0])):
+        continue
+    printc("\t{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = " + row[1] + "},")
+
+printc('};')
 
 printh('\n#endif /* OPCUA_NAMESPACE_0_H_ */')