Преглед на файлове

Merge branch 'master' of https://github.com/acplt/open62541

Florian Palm преди 10 години
родител
ревизия
3c2e06aada
променени са 45 файла, в които са добавени 1045 реда и са изтрити 759 реда
  1. 1 0
      .travis.yml
  2. 1 1
      AUTHORS
  3. 8 9
      CMakeLists.txt
  4. 56 0
      README.md
  5. 19 7
      examples/networklayer_tcp.c
  6. 9 0
      examples/networklayer_tcp.h
  7. 15 3
      examples/networklayer_tcp_concurrent.c
  8. 36 11
      examples/opcuaServer.c
  9. 3 3
      include/ua_connection.h
  10. 20 3
      include/ua_server.h
  11. 227 0
      include/ua_statuscodes.h
  12. 47 42
      include/ua_types.h
  13. 0 0
      src/ongoing/ua_services_subscription.c
  14. 7 6
      src/server/ua_nodestore.c
  15. 1 1
      src/server/ua_nodestore_concurrent.c
  16. 7 5
      src/server/ua_securechannel_manager.c
  17. 35 47
      src/server/ua_server.c
  18. 33 11
      src/server/ua_server_binary.c
  19. 36 44
      src/server/ua_services.h
  20. 27 35
      src/server/ua_services_attribute.c
  21. 3 5
      src/server/ua_services_discovery.c
  22. 4 1
      src/server/ua_services_internal.h
  23. 191 74
      src/server/ua_services_nodemanagement.c
  24. 8 11
      src/server/ua_services_securechannel.c
  25. 36 32
      src/server/ua_services_session.c
  26. 39 36
      src/server/ua_services_view.c
  27. 13 10
      src/server/ua_session_manager.c
  28. 2 2
      src/server/ua_session_manager.h
  29. 6 12
      src/ua_config.h.in
  30. 2 2
      src/ua_connection.c
  31. 3 2
      src/ua_securechannel.c
  32. 41 5
      src/ua_session.c
  33. 3 0
      src/ua_session.h
  34. 0 224
      src/ua_statuscodes.h
  35. 2 2
      src/ua_transport.c
  36. 0 3
      src/ua_transport.h
  37. 42 32
      src/ua_types.c
  38. 24 19
      src/ua_types_encoding_binary.c
  39. 6 2
      src/ua_util.c
  40. 14 35
      src/ua_util.h
  41. 8 5
      tests/CMakeLists.txt
  42. 7 10
      tests/check_builtin.c
  43. 1 3
      tools/generate_builtin.py
  44. 1 3
      tools/generate_namespace.py
  45. 1 1
      tools/type_lists.py

+ 1 - 0
.travis.yml

@@ -18,6 +18,7 @@ addons:
     branch_pattern: coverity_scan
 before_install:
    - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
+   - sudo add-apt-repository ppa:kalakris/cmake -y
    - sudo apt-get update -qq
    - sudo apt-get install -qq gcc-4.8
    - sudo apt-get install -qq --no-install-recommends build-essential cmake python-lxml graphviz doxygen wget

+ 1 - 1
AUTHORS

@@ -1,7 +1,7 @@
 The authors of open62541 are (in alphabetical order)
 
 Bauer, Maximilian
-Graube, Markus
+Graube, Markus <markus.graube (at) tu-dresden.de>
 Gruener, Sten <s.gruener (at) plt.rwth-aachen.de>
 Jeromin, Holger
 Palm, Florian <f.palm (at) plt.rwth-aachen.de>

+ 8 - 9
CMakeLists.txt

@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 2.8.8)
 # set(CMAKE_VERBOSE_MAKEFILE on )
 
 project(open62541 C)
@@ -6,6 +6,7 @@ set(open62541_VERSION_MAJOR 0)
 set(open62541_VERSION_MINOR 1)
 
 set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
+set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
 
 # main sources of libopen62541
 include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
@@ -22,7 +23,6 @@ set(lib_sources src/ua_types.c
                 src/ua_securechannel.c
                 src/ua_session.c
                 src/ua_util.c
-                #src/util/ua_base64.c
                 src/server/ua_server.c
                 src/server/ua_securechannel_manager.c
                 src/server/ua_session_manager.c
@@ -33,14 +33,13 @@ 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_subscription.c
                 src/server/ua_services_monitoreditems.c
                 ${headers}
                 ${generated_headers})
 
 # compiler flags
 if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
-add_definitions(-std=c99 -pedantic -pipe -fvisibility=hidden -Wall -Wextra -Werror -Wformat
+add_definitions(-std=c99 -pedantic -pipe -fvisibility=hidden -fPIC -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")
@@ -68,7 +67,6 @@ if(ENABLE_SELFSIGNED)
                            ${CMAKE_CURRENT_SOURCE_DIR}/tools/certs/localhost.cnf)
 endif()
 
-
 ## auto-generate all types or only the relevant subset?
 option(TYPES_ONLY_NEEDED "Include only compile-needed types" OFF)
 if(TYPES_ONLY_NEEDED)
@@ -113,7 +111,8 @@ else()
     list(APPEND lib_sources src/server/ua_nodestore.c)
 endif()
 
-add_library(open62541 ${lib_sources}) # we can add more files to lib_sources later on
+add_library(open62541-objects OBJECT ${lib_sources}) # static version that exports all symbols
+add_library(open62541 SHARED $<TARGET_OBJECTS:open62541-objects>)
 
 ## logging
 set(UA_LOGLEVEL 400 CACHE STRING "Level at which logs shall be reported")
@@ -156,8 +155,9 @@ option(CLIENT "Build a test client" OFF)
 if(CLIENT)
 	message(STATUS "Extensions: enabling client")
 	add_definitions( -DBENCHMARK=1 )
-	add_executable(exampleClient examples/opcuaClient.c)
-	target_link_libraries(exampleClient open62541)
+    # the client is built directly with the .o files as it currently uses
+    # internal functions that are not exported to the shared lib.
+	add_executable(exampleClient $<TARGET_OBJECTS:open62541-objects> examples/opcuaClient.c)
 endif()
 
 # build example server
@@ -220,4 +220,3 @@ endif(WIN32)
 #if(MULTITHREADING)
 #    target_link_libraries(api-design urcu-cds urcu)
 #endif(MULTITHREADING)
-

+ 56 - 0
README.md

@@ -19,6 +19,62 @@ The project is in an early stage. We retain the right to break APIs until a firs
 ### Documentation
 Documentation is generated from Doxygen annotations in the source code. The current version can be accessed at [http://open62541.org/doxygen/](http://open62541.org/doxygen/).
 
+### Example Server Implementation
+```c
+#include <stdio.h>
+#include <signal.h>
+
+// provided by the open62541 lib
+#include "ua_server.h"
+#include "ua_namespace_0.h"
+
+// provided by the user, implementations available in the /examples folder
+#include "logger_stdout.h"
+#include "networklayer_tcp.h"
+
+UA_Boolean running = UA_TRUE;
+void stopHandler(int sign) {
+	running = UA_FALSE;
+}
+
+void serverCallback(UA_Server *server) {
+    // add your maintenance functionality here
+    printf("does whatever servers do\n");
+}
+
+int main(int argc, char** argv) {
+	signal(SIGINT, stopHandler); /* catches ctrl-c */
+
+	#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_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);
+	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);
+	NetworklayerTCP_delete(nl);
+    UA_String_deleteMembers(&endpointUrl);
+	return retval == UA_SUCCESS ? 0 : retval;
+}
+```
+
 ## Build Procedure
 ### Ubuntu
 

+ 19 - 7
examples/networklayer_tcp.c

@@ -26,6 +26,7 @@
 #include <memory.h> // memset
 #include <fcntl.h> // fcntl
 
+#include "ua_securechannel.h"
 #include "networklayer_tcp.h"
 
 typedef struct TCPConnection {
@@ -52,8 +53,9 @@ typedef struct TCPConnectionHandle {
 
 UA_Int32 NetworklayerTCP_new(NetworklayerTCP **newlayer, UA_ConnectionConfig localConf,
 							 UA_UInt32 port) {
+    if(!newlayer) return UA_ERROR;
     *newlayer = malloc(sizeof(NetworklayerTCP));
-    if(newlayer == UA_NULL)
+    if(*newlayer == UA_NULL)
         return UA_ERROR;
 	(*newlayer)->localConf = localConf;
 	(*newlayer)->port = port;
@@ -70,22 +72,31 @@ UA_Int32 NetworklayerTCP_remove(NetworklayerTCP *layer, UA_Int32 sockfd) {
 		if(layer->connections[index].sockfd == sockfd)
 			break;
 	}
+
+    if(index == layer->connectionsSize)
+        return UA_ERROR;
+
+    if(layer->connections[index].connection.channel)
+        layer->connections[index].connection.channel->connection = UA_NULL;
+
 	UA_Connection_deleteMembers(&layer->connections[index].connection);
 
+    layer->connectionsSize--;
 	TCPConnection *newconnections;
-    newconnections = malloc(sizeof(TCPConnection) * (layer->connectionsSize-1));
+    newconnections = malloc(sizeof(TCPConnection) * layer->connectionsSize);
 	memcpy(newconnections, &layer->connections, sizeof(TCPConnection) * index);
 	memcpy(&newconnections[index], &layer->connections[index+1],
-           sizeof(TCPConnection) * (layer->connectionsSize - index - 1));
+           sizeof(TCPConnection) * (layer->connectionsSize - index));
     free(layer->connections);
 	layer->connections = newconnections;
-	layer->connectionsSize--;
 	return UA_SUCCESS;
 }
 
 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;
         UA_Connection_deleteMembers(&layer->connections[index].connection);
 		CLOSESOCKET(layer->connections[index].sockfd);
 	}
@@ -210,6 +221,7 @@ void readConnection(NetworklayerTCP *layer, UA_Server *server, TCPConnection *en
 			UA_Server_processBinaryMessage(server, &entry->connection, &readBuffer);
 		}
 	}
+    readBuffer.length = layer->localConf.recvBufferSize; // because this was malloc'd. Length=0 would lead to errors.
 	UA_ByteString_deleteMembers(&readBuffer);
 }
 
@@ -249,7 +261,7 @@ void setFDSet(NetworklayerTCP *layer) {
 }
 
 UA_Int32 NetworkLayerTCP_run(NetworklayerTCP *layer, UA_Server *server, struct timeval tv,
-							   void(*worker)(UA_Server*), UA_Boolean *running) {
+                             void(*worker)(UA_Server*), UA_Boolean *running) {
 #ifdef WIN32
 	WORD wVersionRequested;
 	WSADATA wsaData;
@@ -274,13 +286,13 @@ UA_Int32 NetworkLayerTCP_run(NetworklayerTCP *layer, UA_Server *server, struct t
 	int optval = 1;
 	if(setsockopt(layer->serversockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(optval)) == -1) {
 		perror("setsockopt");
-		close(layer->serversockfd);
+		CLOSESOCKET(layer->serversockfd);
 		return UA_ERROR;
 	}
 		
 	if(bind(layer->serversockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
 		perror("binding");
-		close(layer->serversockfd);
+		CLOSESOCKET(layer->serversockfd);
 		return UA_ERROR;
 	}
 

+ 9 - 0
examples/networklayer_tcp.h

@@ -6,6 +6,15 @@
 #ifndef NETWORKLAYERTCP_H_
 #define NETWORKLAYERTCP_H_
 
+#ifdef WIN32
+  #include "winsock2.h"
+#else
+  #include <sys/mman.h>
+  #include <sys/wait.h>
+  #include <unistd.h>
+  #include <sys/time.h>
+#endif
+
 #include "ua_server.h"
 
 struct NetworklayerTCP;

+ 15 - 3
examples/networklayer_tcp_concurrent.c

@@ -15,6 +15,7 @@ struct NetworklayerTCP {
     UA_Server *server;
     uv_loop_t *uvloop;
     uv_tcp_t uvserver;
+    UA_Boolean *running;
 	UA_ConnectionConfig localConf;
 	UA_UInt32 port;
 	UA_UInt32 connectionsSize;
@@ -114,8 +115,8 @@ static void handle_message(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
 }
 
 static uv_buf_t read_alloc(uv_handle_t * handle, size_t suggested_size) {
-    //UA_Server *server = (UA_Server*)handle->loop->data;
-    UA_UInt32 receive_bufsize = 2048; // todo: server->layer.localConf.recvBufferSize;
+    NetworklayerTCP *layer = (NetworklayerTCP*)handle->loop->data;
+    UA_UInt32 receive_bufsize = layer->localConf.recvBufferSize;
 	char* buf = malloc(sizeof(char)*receive_bufsize);
     return uv_buf_init(buf, receive_bufsize);
 }
@@ -140,6 +141,12 @@ static void on_connection(uv_stream_t *server, int status) {
     assert(uv_read_start((uv_stream_t*)stream, read_alloc, handle_message) == 0);
 }
 
+void check_running(uv_timer_t* handle, int status) {
+    NetworklayerTCP *layer = (NetworklayerTCP*)handle->loop->data;
+    if(!*layer->running)
+        uv_stop(layer->uvloop);
+}
+
 UA_Int32 NetworkLayerTCP_run(NetworklayerTCP *layer, UA_Server *server, struct timeval tv, void(*worker)(UA_Server*), UA_Boolean *running) {
     layer->uvloop = uv_default_loop();
     layer->server = server;
@@ -160,7 +167,12 @@ UA_Int32 NetworkLayerTCP_run(NetworklayerTCP *layer, UA_Server *server, struct t
         return UA_ERROR;
     }
     layer->uvloop->data = (void*)layer; // so we can get the pointer to the server
+    layer->running = running;
+    
+    uv_timer_t timer_check_running;
+    uv_timer_init(layer->uvloop, &timer_check_running);
+    uv_timer_start(&timer_check_running, check_running, 0, 500);
+    
     uv_run(layer->uvloop, UV_RUN_DEFAULT);
-    uv_loop_delete(layer->uvloop);
     return UA_SUCCESS;
 }

+ 36 - 11
examples/opcuaServer.c

@@ -5,19 +5,14 @@
 
 #include <stdio.h>
 #include <stdlib.h> 
-#ifndef WIN32
-#include <sys/mman.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/time.h>
-#else
-#include "winsock2.h"
-#endif
-#include <sys/types.h>
-#include <fcntl.h>
 #include <signal.h>
 #include <errno.h> // errno, EINTR
+
+// provided by the open62541 lib
 #include "ua_server.h"
+#include "ua_namespace_0.h"
+
+// provided by the user, implementations available in the /examples folder
 #include "logger_stdout.h"
 #include "networklayer_tcp.h"
 
@@ -63,6 +58,36 @@ int main(int argc, char** argv) {
 	UA_Server_init(&server, &endpointUrl);
 	Logger_Stdout_init(&server.logger);
     server.serverCertificate = loadCertificate();
+
+    UA_Int32 myInteger = 42;
+    UA_String myIntegerName;
+    UA_STRING_STATIC(myIntegerName, "The Answer");
+    UA_Server_addScalarVariableNode(&server, &myIntegerName, (void*)&myInteger, &UA_[UA_INT32],
+                                    &server.objectsNodeId, &server.hasComponentReferenceTypeId);
+
+#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);
+        sprintf(str,"%d",i);
+        UA_QualifiedName_copycstring(str,&tmpNode->browseName);
+        UA_LocalizedText_copycstring(str,&tmpNode->displayName);
+        UA_LocalizedText_copycstring("integer value", &tmpNode->description);
+        tmpNode->nodeId.identifier.numeric = 19000+i;
+        tmpNode->nodeClass = UA_NODECLASS_VARIABLE;
+        //tmpNode->valueRank = -1;
+        tmpNode->value.vt = &UA_[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);
+    }
+#endif
 	
 	#define PORT 16664
 	NetworklayerTCP* nl;
@@ -71,8 +96,8 @@ int main(int argc, char** argv) {
 	struct timeval callback_interval = {1, 0}; // 1 second
 	UA_Int32 retval = NetworkLayerTCP_run(nl, &server, callback_interval,
 										  serverCallback, &running);
-	NetworklayerTCP_delete(nl);
 	UA_Server_deleteMembers(&server);
+	NetworklayerTCP_delete(nl);
     UA_String_deleteMembers(&endpointUrl);
 	return retval == UA_SUCCESS ? 0 : retval;
 }

+ 3 - 3
include/ua_connection.h

@@ -45,7 +45,7 @@ typedef struct UA_ConnectionConfig {
     UA_UInt32 maxChunkCount;
 } UA_ConnectionConfig;
 
-extern UA_LIBEXPORT UA_ConnectionConfig UA_ConnectionConfig_standard;
+extern UA_EXPORT UA_ConnectionConfig UA_ConnectionConfig_standard;
 
 /* Forward declaration */
 struct UA_SecureChannel;
@@ -64,9 +64,9 @@ typedef struct UA_Connection {
     UA_Connection_closeCallback close;
 } UA_Connection;
 
-UA_Int32 UA_LIBEXPORT UA_Connection_init(UA_Connection *connection, UA_ConnectionConfig localConf, void *callbackHandle,
+UA_Int32 UA_EXPORT UA_Connection_init(UA_Connection *connection, UA_ConnectionConfig localConf, void *callbackHandle,
                                          UA_Connection_closeCallback close, UA_Connection_writeCallback write);
-UA_Int32 UA_LIBEXPORT UA_Connection_deleteMembers(UA_Connection *connection);
+UA_Int32 UA_EXPORT UA_Connection_deleteMembers(UA_Connection *connection);
 
 // todo: closing a binaryconnection that was closed on the network level
 

+ 20 - 3
include/ua_server.h

@@ -27,6 +27,10 @@ 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;
 
@@ -43,11 +47,24 @@ typedef struct UA_Server {
     UA_NodeStore *nodestore;
     UA_Logger logger;
     UA_ByteString serverCertificate;
+
+    // todo: move these somewhere sane
+    UA_ExpandedNodeId objectsNodeId;
+    UA_NodeId hasComponentReferenceTypeId;
 } UA_Server;
 
-void UA_LIBEXPORT UA_Server_init(UA_Server *server, UA_String *endpointUrl);
-UA_Int32 UA_LIBEXPORT UA_Server_deleteMembers(UA_Server *server);
-UA_Int32 UA_LIBEXPORT UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);
+void UA_EXPORT UA_Server_init(UA_Server *server, UA_String *endpointUrl);
+UA_Int32 UA_EXPORT UA_Server_deleteMembers(UA_Server *server);
+UA_Int32 UA_EXPORT UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);
+
+/* Services for local use */
+UA_AddNodesResult UA_EXPORT UA_Server_addScalarVariableNode(UA_Server *server, UA_String *browseName, void *value,
+                                                            const UA_VTable_Entry *vt, UA_ExpandedNodeId *parentNodeId,
+                                                            UA_NodeId *referenceTypeId );
+UA_AddNodesResult UA_EXPORT UA_Server_addNode(UA_Server *server, UA_Node **node, UA_ExpandedNodeId *parentNodeId,
+                                              UA_NodeId *referenceTypeId);
+void UA_EXPORT UA_Server_addReferences(UA_Server *server, const UA_AddReferencesRequest *request,
+                                       UA_AddReferencesResponse *response);
 
 #ifdef __cplusplus
 } // extern "C"

+ 227 - 0
include/ua_statuscodes.h

@@ -0,0 +1,227 @@
+/* This file shall only be included in ua_types.h */
+#ifdef UA_TYPES_H_
+#ifndef OPCUA_STATUSCODES_H_
+#define OPCUA_STATUSCODES_H_
+
+enum UA_StatusCode {
+	UA_STATUSCODE_GOOD = (UA_Int32) 0x00,
+	UA_STATUSCODE_BADUNEXPECTEDERROR = (UA_Int32) 0x80010000, // An unexpected error occurred.
+	UA_STATUSCODE_BADINTERNALERROR = (UA_Int32) 0x80020000, // An internal error occurred as a result of a programming or configuration error.
+	UA_STATUSCODE_BADOUTOFMEMORY = (UA_Int32) 0x80030000, // Not enough memory to complete the operation.
+	UA_STATUSCODE_BADRESOURCEUNAVAILABLE = (UA_Int32) 0x80040000, // An operating system resource is not available.
+	UA_STATUSCODE_BADCOMMUNICATIONERROR = (UA_Int32) 0x80050000, // A low level communication error occurred.
+	UA_STATUSCODE_BADENCODINGERROR = (UA_Int32) 0x80060000, // Encoding halted because of invalid data in the objects being serialized.
+	UA_STATUSCODE_BADDECODINGERROR = (UA_Int32) 0x80070000, // Decoding halted because of invalid data in the stream.
+	UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED = (UA_Int32) 0x80080000, // The message encoding/decoding limits imposed by the stack have been exceeded.
+	UA_STATUSCODE_BADREQUESTTOOLARGE = (UA_Int32) 0x80b80000, // The request message size exceeds limits set by the server.
+	UA_STATUSCODE_BADRESPONSETOOLARGE = (UA_Int32) 0x80b90000, // The response message size exceeds limits set by the client.
+	UA_STATUSCODE_BADUNKNOWNRESPONSE = (UA_Int32) 0x80090000, // An unrecognized response was received from the server.
+	UA_STATUSCODE_BADTIMEOUT = (UA_Int32) 0x800a0000, // The operation timed out.
+	UA_STATUSCODE_BADSERVICEUNSUPPORTED = (UA_Int32) 0x800b0000, // The server does not support the requested service.
+	UA_STATUSCODE_BADSHUTDOWN = (UA_Int32) 0x800c0000, // The operation was cancelled because the application is shutting down.
+	UA_STATUSCODE_BADSERVERNOTCONNECTED = (UA_Int32) 0x800d0000, // The operation could not complete because the client is not connected to the server.
+	UA_STATUSCODE_BADSERVERHALTED = (UA_Int32) 0x800e0000, // The server has stopped and cannot process any requests.
+	UA_STATUSCODE_BADNOTHINGTODO = (UA_Int32) 0x800f0000, // There was nothing to do because the client passed a list of operations with no elements.
+	UA_STATUSCODE_BADTOOMANYOPERATIONS = (UA_Int32) 0x80100000, // The request could not be processed because it specified too many operations.
+	UA_STATUSCODE_BADTOOMANYMONITOREDITEMS = (UA_Int32) 0x80db0000, // The request could not be processed because there are too many monitored items in the subscription.
+	UA_STATUSCODE_BADDATATYPEIDUNKNOWN = (UA_Int32) 0x80110000, // The extension object cannot be (de)serialized because the data type id is not recognized.
+	UA_STATUSCODE_BADCERTIFICATEINVALID = (UA_Int32) 0x80120000, // The certificate provided as a parameter is not valid.
+	UA_STATUSCODE_BADSECURITYCHECKSFAILED = (UA_Int32) 0x80130000, // An error occurred verifying security.
+	UA_STATUSCODE_BADCERTIFICATETIMEINVALID = (UA_Int32) 0x80140000, // The Certificate has expired or is not yet valid.
+	UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID = (UA_Int32) 0x80150000, // An Issuer Certificate has expired or is not yet valid.
+	UA_STATUSCODE_BADCERTIFICATEHOSTNAMEINVALID = (UA_Int32) 0x80160000, // The HostName used to connect to a Server does not match a HostName in the Certificate.
+	UA_STATUSCODE_BADCERTIFICATEURIINVALID = (UA_Int32) 0x80170000, // The URI specified in the ApplicationDescription does not match the URI in the Certificate.
+	UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED = (UA_Int32) 0x80180000, // The Certificate may not be used for the requested operation.
+	UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED = (UA_Int32) 0x80190000, // The Issuer Certificate may not be used for the requested operation.
+	UA_STATUSCODE_BADCERTIFICATEUNTRUSTED = (UA_Int32) 0x801a0000, // The Certificate is not trusted.
+	UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN = (UA_Int32) 0x801b0000, // It was not possible to determine if the Certificate has been revoked.
+	UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN = (UA_Int32) 0x801c0000, // It was not possible to determine if the Issuer Certificate has been revoked.
+	UA_STATUSCODE_BADCERTIFICATEREVOKED = (UA_Int32) 0x801d0000, // The Certificate has been revoked.
+	UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED = (UA_Int32) 0x801e0000, // The Issuer Certificate has been revoked.
+	UA_STATUSCODE_BADUSERACCESSDENIED = (UA_Int32) 0x801f0000, // User does not have permission to perform the requested operation.
+	UA_STATUSCODE_BADIDENTITYTOKENINVALID = (UA_Int32) 0x80200000, // The user identity token is not valid.
+	UA_STATUSCODE_BADIDENTITYTOKENREJECTED = (UA_Int32) 0x80210000, // The user identity token is valid but the server has rejected it.
+	UA_STATUSCODE_BADSECURECHANNELIDINVALID = (UA_Int32) 0x80220000, // The specified secure channel is no longer valid.
+	UA_STATUSCODE_BADINVALIDTIMESTAMP = (UA_Int32) 0x80230000, // The timestamp is outside the range allowed by the server.
+	UA_STATUSCODE_BADNONCEINVALID = (UA_Int32) 0x80240000, // The nonce does appear to be not a random value or it is not the correct length.
+	UA_STATUSCODE_BADSESSIONIDINVALID = (UA_Int32) 0x80250000, // The session id is not valid.
+	UA_STATUSCODE_BADSESSIONCLOSED = (UA_Int32) 0x80260000, // The session was closed by the client.
+	UA_STATUSCODE_BADSESSIONNOTACTIVATED = (UA_Int32) 0x80270000, // The session cannot be used because ActivateSession has not been called.
+	UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID = (UA_Int32) 0x80280000, // The subscription id is not valid.
+	UA_STATUSCODE_BADREQUESTHEADERINVALID = (UA_Int32) 0x802a0000, // The header for the request is missing or invalid.
+	UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID = (UA_Int32) 0x802b0000, // The timestamps to return parameter is invalid.
+	UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT = (UA_Int32) 0x802c0000, // The request was cancelled by the client.
+	UA_STATUSCODE_GOODSUBSCRIPTIONTRANSFERRED = (UA_Int32) 0x002d0000, // The subscription was transferred to another session.
+	UA_STATUSCODE_GOODCOMPLETESASYNCHRONOUSLY = (UA_Int32) 0x002e0000, // The processing will complete asynchronously.
+	UA_STATUSCODE_GOODOVERLOAD = (UA_Int32) 0x002f0000, // Sampling has slowed down due to resource limitations.
+	UA_STATUSCODE_GOODCLAMPED = (UA_Int32) 0x00300000, // The value written was accepted but was clamped.
+	UA_STATUSCODE_BADNOCOMMUNICATION = (UA_Int32) 0x80310000, // Communication with the data source is defined, but not established, and there is no last known value available.
+	UA_STATUSCODE_BADWAITINGFORINITIALDATA = (UA_Int32) 0x80320000, // Waiting for the server to obtain values from the underlying data source.
+	UA_STATUSCODE_BADNODEIDINVALID = (UA_Int32) 0x80330000, // The syntax of the node id is not valid.
+	UA_STATUSCODE_BADNODEIDUNKNOWN = (UA_Int32) 0x80340000, // The node id refers to a node that does not exist in the server address space.
+	UA_STATUSCODE_BADATTRIBUTEIDINVALID = (UA_Int32) 0x80350000, // The attribute is not supported for the specified Node.
+	UA_STATUSCODE_BADINDEXRANGEINVALID = (UA_Int32) 0x80360000, // The syntax of the index range parameter is invalid.
+	UA_STATUSCODE_BADINDEXRANGENODATA = (UA_Int32) 0x80370000, // No data exists within the range of indexes specified.
+	UA_STATUSCODE_BADDATAENCODINGINVALID = (UA_Int32) 0x80380000, // The data encoding is invalid.
+	UA_STATUSCODE_BADDATAENCODINGUNSUPPORTED = (UA_Int32) 0x80390000, // The server does not support the requested data encoding for the node.
+	UA_STATUSCODE_BADNOTREADABLE = (UA_Int32) 0x803a0000, // The access level does not allow reading or subscribing to the Node.
+	UA_STATUSCODE_BADNOTWRITABLE = (UA_Int32) 0x803b0000, // The access level does not allow writing to the Node.
+	UA_STATUSCODE_BADOUTOFRANGE = (UA_Int32) 0x803c0000, // The value was out of range.
+	UA_STATUSCODE_BADNOTSUPPORTED = (UA_Int32) 0x803d0000, // The requested operation is not supported.
+	UA_STATUSCODE_BADNOTFOUND = (UA_Int32) 0x803e0000, // A requested item was not found or a search operation ended without success.
+	UA_STATUSCODE_BADOBJECTDELETED = (UA_Int32) 0x803f0000, // The object cannot be used because it has been deleted.
+	UA_STATUSCODE_BADNOTIMPLEMENTED = (UA_Int32) 0x80400000, // Requested operation is not implemented.
+	UA_STATUSCODE_BADMONITORINGMODEINVALID = (UA_Int32) 0x80410000, // The monitoring mode is invalid.
+	UA_STATUSCODE_BADMONITOREDITEMIDINVALID = (UA_Int32) 0x80420000, // The monitoring item id does not refer to a valid monitored item.
+	UA_STATUSCODE_BADMONITOREDITEMFILTERINVALID = (UA_Int32) 0x80430000, // The monitored item filter parameter is not valid.
+	UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED = (UA_Int32) 0x80440000, // The server does not support the requested monitored item filter.
+	UA_STATUSCODE_BADFILTERNOTALLOWED = (UA_Int32) 0x80450000, // A monitoring filter cannot be used in combination with the attribute specified.
+	UA_STATUSCODE_BADSTRUCTUREMISSING = (UA_Int32) 0x80460000, // A mandatory structured parameter was missing or null.
+	UA_STATUSCODE_BADEVENTFILTERINVALID = (UA_Int32) 0x80470000, // The event filter is not valid.
+	UA_STATUSCODE_BADCONTENTFILTERINVALID = (UA_Int32) 0x80480000, // The content filter is not valid.
+	UA_STATUSCODE_BADFILTEROPERATORINVALID = (UA_Int32) 0x80c10000, // An unregognized operator was provided in a filter.
+	UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED = (UA_Int32) 0x80c20000, // A valid operator was provided, but the server does not provide support for this filter operator.
+	UA_STATUSCODE_BADFILTEROPERANDCOUNTMISMATCH = (UA_Int32) 0x80c30000, // The number of operands provided for the filter operator was less then expected for the operand provided.
+	UA_STATUSCODE_BADFILTEROPERANDINVALID = (UA_Int32) 0x80490000, // The operand used in a content filter is not valid.
+	UA_STATUSCODE_BADFILTERELEMENTINVALID = (UA_Int32) 0x80c40000, // The referenced element is not a valid element in the content filter.
+	UA_STATUSCODE_BADFILTERLITERALINVALID = (UA_Int32) 0x80c50000, // The referenced literal is not a valid value.
+	UA_STATUSCODE_BADCONTINUATIONPOINTINVALID = (UA_Int32) 0x804a0000, // The continuation point provide is longer valid.
+	UA_STATUSCODE_BADNOCONTINUATIONPOINTS = (UA_Int32) 0x804b0000, // The operation could not be processed because all continuation points have been allocated.
+	UA_STATUSCODE_BADREFERENCETYPEIDINVALID = (UA_Int32) 0x804c0000, // The operation could not be processed because all continuation points have been allocated.
+	UA_STATUSCODE_BADBROWSEDIRECTIONINVALID = (UA_Int32) 0x804d0000, // The browse direction is not valid.
+	UA_STATUSCODE_BADNODENOTINVIEW = (UA_Int32) 0x804e0000, // The node is not part of the view.
+	UA_STATUSCODE_BADSERVERURIINVALID = (UA_Int32) 0x804f0000, // The ServerUri is not a valid URI.
+	UA_STATUSCODE_BADSERVERNAMEMISSING = (UA_Int32) 0x80500000, // No ServerName was specified.
+	UA_STATUSCODE_BADDISCOVERYURLMISSING = (UA_Int32) 0x80510000, // No DiscoveryUrl was specified.
+	UA_STATUSCODE_BADSEMPAHOREFILEMISSING = (UA_Int32) 0x80520000, // The semaphore file specified by the client is not valid.
+	UA_STATUSCODE_BADREQUESTTYPEINVALID = (UA_Int32) 0x80530000, // The security token request type is not valid.
+	UA_STATUSCODE_BADSECURITYMODEREJECTED = (UA_Int32) 0x80540000, // The security mode does not meet the requirements set by the Server.
+	UA_STATUSCODE_BADSECURITYPOLICYREJECTED = (UA_Int32) 0x80550000, // The security policy does not meet the requirements set by the Server.
+	UA_STATUSCODE_BADTOOMANYSESSIONS = (UA_Int32) 0x80560000, // The server has reached its maximum number of sessions.
+	UA_STATUSCODE_BADUSERSIGNATUREINVALID = (UA_Int32) 0x80570000, // The user token signature is missing or invalid.
+	UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID = (UA_Int32) 0x80580000, // The signature generated with the client certificate is missing or invalid.
+	UA_STATUSCODE_BADNOVALIDCERTIFICATES = (UA_Int32) 0x80590000, // The client did not provide at least one software certificate that is valid and meets the profile requirements for the server.
+	UA_STATUSCODE_BADIDENTITYCHANGENOTSUPPORTED = (UA_Int32) 0x80c60000, // The Server does not support changing the user identity assigned to the session.
+	UA_STATUSCODE_BADREQUESTCANCELLEDBYREQUEST = (UA_Int32) 0x805a0000, // The request was cancelled by the client with the Cancel service.
+	UA_STATUSCODE_BADPARENTNODEIDINVALID = (UA_Int32) 0x805b0000, // The parent node id does not to refer to a valid node.
+	UA_STATUSCODE_BADREFERENCENOTALLOWED = (UA_Int32) 0x805c0000, // The reference could not be created because it violates constraints imposed by the data model.
+	UA_STATUSCODE_BADNODEIDREJECTED = (UA_Int32) 0x805d0000, // The requested node id was reject because it was either invalid or server does not allow node ids to be specified by the client.
+	UA_STATUSCODE_BADNODEIDEXISTS = (UA_Int32) 0x805e0000, // The requested node id is already used by another node.
+	UA_STATUSCODE_BADNODECLASSINVALID = (UA_Int32) 0x805f0000, // The node class is not valid.
+	UA_STATUSCODE_BADBROWSENAMEINVALID = (UA_Int32) 0x80600000, // The browse name is invalid.
+	UA_STATUSCODE_BADBROWSENAMEDUPLICATED = (UA_Int32) 0x80610000, // The browse name is not unique among nodes that share the same relationship with the parent.
+	UA_STATUSCODE_BADNODEATTRIBUTESINVALID = (UA_Int32) 0x80620000, // The node attributes are not valid for the node class.
+	UA_STATUSCODE_BADTYPEDEFINITIONINVALID = (UA_Int32) 0x80630000, // The type definition node id does not reference an appropriate type node.
+	UA_STATUSCODE_BADSOURCENODEIDINVALID = (UA_Int32) 0x80640000, // The source node id does not reference a valid node.
+	UA_STATUSCODE_BADTARGETNODEIDINVALID = (UA_Int32) 0x80650000, // The target node id does not reference a valid node.
+	UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED = (UA_Int32) 0x80660000, // The reference type between the nodes is already defined.
+	UA_STATUSCODE_BADINVALIDSELFREFERENCE = (UA_Int32) 0x80670000, // The server does not allow this type of self reference on this node.
+	UA_STATUSCODE_BADREFERENCELOCALONLY = (UA_Int32) 0x80680000, // The reference type is not valid for a reference to a remote server.
+	UA_STATUSCODE_BADNODELETERIGHTS = (UA_Int32) 0x80690000, // The server will not allow the node to be deleted.
+	UA_STATUSCODE_UNCERTAINREFERENCENOTDELETED = (UA_Int32) 0x40bc0000, // The server was not able to delete all target references.
+	UA_STATUSCODE_BADSERVERINDEXINVALID = (UA_Int32) 0x806a0000, // The server index is not valid.
+	UA_STATUSCODE_BADVIEWIDUNKNOWN = (UA_Int32) 0x806b0000, // The view id does not refer to a valid view node.
+	UA_STATUSCODE_BADVIEWTIMESTAMPINVALID = (UA_Int32) 0x80c90000, // The view timestamp is not available or not supported.
+	UA_STATUSCODE_BADVIEWPARAMETERMISMATCH = (UA_Int32) 0x80ca0000, // The view parameters are not consistent with each other.
+	UA_STATUSCODE_BADVIEWVERSIONINVALID = (UA_Int32) 0x80cb0000, // The view version is not available or not supported.
+	UA_STATUSCODE_UNCERTAINNOTALLNODESAVAILABLE = (UA_Int32) 0x40c00000, // The list of references may not be complete because the underlying system is not available.
+	UA_STATUSCODE_GOODRESULTSMAYBEINCOMPLETE = (UA_Int32) 0x00ba0000, // The server should have followed a reference to a node in a remote server but did not. The result set may be incomplete.
+	UA_STATUSCODE_BADNOTTYPEDEFINITION = (UA_Int32) 0x80c80000, // The provided Nodeid was not a type definition nodeid.
+	UA_STATUSCODE_UNCERTAINREFERENCEOUTOFSERVER = (UA_Int32) 0x406c0000, // One of the references to follow in the relative path references to a node in the address space in another server.
+	UA_STATUSCODE_BADTOOMANYMATCHES = (UA_Int32) 0x806d0000, // The requested operation has too many matches to return.
+	UA_STATUSCODE_BADQUERYTOOCOMPLEX = (UA_Int32) 0x806e0000, // The requested operation requires too many resources in the server.
+	UA_STATUSCODE_BADNOMATCH = (UA_Int32) 0x806f0000, // The requested operation has no match to return.
+	UA_STATUSCODE_BADMAXAGEINVALID = (UA_Int32) 0x80700000, // The max age parameter is invalid.
+	UA_STATUSCODE_BADHISTORYOPERATIONINVALID = (UA_Int32) 0x80710000, // The history details parameter is not valid.
+	UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED = (UA_Int32) 0x80720000, // The server does not support the requested operation.
+	UA_STATUSCODE_BADINVALIDTIMESTAMPARGUMENT = (UA_Int32) 0x80bd0000, // The defined timestamp to return was invalid.
+	UA_STATUSCODE_BADWRITENOTSUPPORTED = (UA_Int32) 0x80730000, // The server not does support writing the combination of value, status and timestamps provided.
+	UA_STATUSCODE_BADTYPEMISMATCH = (UA_Int32) 0x80740000, // The value supplied for the attribute is not of the same type as the attribute's value.
+	UA_STATUSCODE_BADMETHODINVALID = (UA_Int32) 0x80750000, // The method id does not refer to a method for the specified object.
+	UA_STATUSCODE_BADARGUMENTSMISSING = (UA_Int32) 0x80760000, // The client did not specify all of the input arguments for the method.
+	UA_STATUSCODE_BADTOOMANYSUBSCRIPTIONS = (UA_Int32) 0x80770000, // The server has reached its  maximum number of subscriptions.
+	UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS = (UA_Int32) 0x80780000, // The server has reached the maximum number of queued publish requests.
+	UA_STATUSCODE_BADNOSUBSCRIPTION = (UA_Int32) 0x80790000, // There is no subscription available for this session.
+	UA_STATUSCODE_BADSEQUENCENUMBERUNKNOWN = (UA_Int32) 0x807a0000, // The sequence number is unknown to the server.
+	UA_STATUSCODE_BADMESSAGENOTAVAILABLE = (UA_Int32) 0x807b0000, // The requested notification message is no longer available.
+	UA_STATUSCODE_BADINSUFFICIENTCLIENTPROFILE = (UA_Int32) 0x807c0000, // The Client of the current Session does not support one or more Profiles that are necessary for the Subscription.
+	UA_STATUSCODE_BADSTATENOTACTIVE = (UA_Int32) 0x80bf0000, // The sub-state machine is not currently active.
+	UA_STATUSCODE_BADTCPSERVERTOOBUSY = (UA_Int32) 0x807d0000, // The server cannot process the request because it is too busy.
+	UA_STATUSCODE_BADTCPMESSAGETYPEINVALID = (UA_Int32) 0x807e0000, // The type of the message specified in the header invalid.
+	UA_STATUSCODE_BADTCPSECURECHANNELUNKNOWN = (UA_Int32) 0x807f0000, // The SecureChannelId and/or TokenId are not currently in use.
+	UA_STATUSCODE_BADTCPMESSAGETOOLARGE = (UA_Int32) 0x80800000, // The size of the message specified in the header is too large.
+	UA_STATUSCODE_BADTCPNOTENOUGHRESOURCES = (UA_Int32) 0x80810000, // There are not enough resources to process the request.
+	UA_STATUSCODE_BADTCPINTERNALERROR = (UA_Int32) 0x80820000, // An internal error occurred.
+	UA_STATUSCODE_BADTCPENDPOINTURLINVALID = (UA_Int32) 0x80830000, // The Server does not recognize the QueryString specified.
+	UA_STATUSCODE_BADREQUESTINTERRUPTED = (UA_Int32) 0x80840000, // The request could not be sent because of a network interruption.
+	UA_STATUSCODE_BADREQUESTTIMEOUT = (UA_Int32) 0x80850000, // Timeout occurred while processing the request.
+	UA_STATUSCODE_BADSECURECHANNELCLOSED = (UA_Int32) 0x80860000, // The secure channel has been closed.
+	UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN = (UA_Int32) 0x80870000, // The token has expired or is not recognized.
+	UA_STATUSCODE_BADSEQUENCENUMBERINVALID = (UA_Int32) 0x80880000, // The sequence number is not valid.
+	UA_STATUSCODE_BADPROTOCOLVERSIONUNSUPPORTED = (UA_Int32) 0x80be0000, // The applications do not have compatible protocol versions.
+	UA_STATUSCODE_BADCONFIGURATIONERROR = (UA_Int32) 0x80890000, // There is a problem with the configuration that affects the usefulness of the value.
+	UA_STATUSCODE_BADNOTCONNECTED = (UA_Int32) 0x808a0000, // The variable should receive its value from another variable, but has never been configured to do so.
+	UA_STATUSCODE_BADDEVICEFAILURE = (UA_Int32) 0x808b0000, // There has been a failure in the device/data source that generates the value that has affected the value.
+	UA_STATUSCODE_BADSENSORFAILURE = (UA_Int32) 0x808c0000, // There has been a failure in the sensor from which the value is derived by the device/data source.
+	UA_STATUSCODE_BADOUTOFSERVICE = (UA_Int32) 0x808d0000, // The source of the data is not operational.
+	UA_STATUSCODE_BADDEADBANDFILTERINVALID = (UA_Int32) 0x808e0000, // The deadband filter is not valid.
+	UA_STATUSCODE_UNCERTAINNOCOMMUNICATIONLASTUSABLEVALUE = (UA_Int32) 0x408f0000, // Communication to the data source has failed. The variable value is the last value that had a good quality.
+	UA_STATUSCODE_UNCERTAINLASTUSABLEVALUE = (UA_Int32) 0x40900000, // Whatever was updating this value has stopped doing so.
+	UA_STATUSCODE_UNCERTAINSUBSTITUTEVALUE = (UA_Int32) 0x40910000, // The value is an operational value that was manually overwritten.
+	UA_STATUSCODE_UNCERTAININITIALVALUE = (UA_Int32) 0x40920000, // The value is an initial value for a variable that normally receives its value from another variable.
+	UA_STATUSCODE_UNCERTAINSENSORNOTACCURATE = (UA_Int32) 0x40930000, // The value is at one of the sensor limits.
+	UA_STATUSCODE_UNCERTAINENGINEERINGUNITSEXCEEDED = (UA_Int32) 0x40940000, // The value is outside of the range of values defined for this parameter.
+	UA_STATUSCODE_UNCERTAINSUBNORMAL = (UA_Int32) 0x40950000, // The value is derived from multiple sources and has less than the required number of Good sources.
+	UA_STATUSCODE_GOODLOCALOVERRIDE = (UA_Int32) 0x00960000, // The value has been overridden.
+	UA_STATUSCODE_BADREFRESHINPROGRESS = (UA_Int32) 0x80970000, // This Condition refresh failed, a Condition refresh operation is already in progress.
+	UA_STATUSCODE_BADCONDITIONALREADYDISABLED = (UA_Int32) 0x80980000, // This condition has already been disabled.
+	UA_STATUSCODE_BADCONDITIONALREADYENABLED = (UA_Int32) 0x80cc0000, // This condition has already been enabled.
+	UA_STATUSCODE_BADCONDITIONDISABLED = (UA_Int32) 0x80990000, // Property not available, this condition is disabled.
+	UA_STATUSCODE_BADEVENTIDUNKNOWN = (UA_Int32) 0x809a0000, // The specified event id is not recognized.
+	UA_STATUSCODE_BADEVENTNOTACKNOWLEDGEABLE = (UA_Int32) 0x80bb0000, // The event cannot be acknowledged.
+	UA_STATUSCODE_BADDIALOGNOTACTIVE = (UA_Int32) 0x80cd0000, // The dialog condition is not active.
+	UA_STATUSCODE_BADDIALOGRESPONSEINVALID = (UA_Int32) 0x80ce0000, // The response is not valid for the dialog.
+	UA_STATUSCODE_BADCONDITIONBRANCHALREADYACKED = (UA_Int32) 0x80cf0000, // The condition branch has already been acknowledged.
+	UA_STATUSCODE_BADCONDITIONBRANCHALREADYCONFIRMED = (UA_Int32) 0x80d00000, // The condition branch has already been confirmed.
+	UA_STATUSCODE_BADCONDITIONALREADYSHELVED = (UA_Int32) 0x80d10000, // The condition has already been shelved.
+	UA_STATUSCODE_BADCONDITIONNOTSHELVED = (UA_Int32) 0x80d20000, // The condition is not currently shelved.
+	UA_STATUSCODE_BADSHELVINGTIMEOUTOFRANGE = (UA_Int32) 0x80d30000, // The shelving time not within an acceptable range.
+	UA_STATUSCODE_BADNODATA = (UA_Int32) 0x809b0000, // No data exists for the requested time range or event filter.
+	UA_STATUSCODE_BADBOUNDNOTFOUND = (UA_Int32) 0x80d70000, // No data found to provide upper or lower bound value.
+	UA_STATUSCODE_BADBOUNDNOTSUPPORTED = (UA_Int32) 0x80d80000, // The server cannot retrieve a bound for the variable.
+	UA_STATUSCODE_BADDATALOST = (UA_Int32) 0x809d0000, // Data is missing due to collection started/stopped/lost.
+	UA_STATUSCODE_BADDATAUNAVAILABLE = (UA_Int32) 0x809e0000, // Expected data is unavailable for the requested time range due to an un-mounted volume, an off-line archive or tape, or similar reason for temporary unavailability.
+	UA_STATUSCODE_BADENTRYEXISTS = (UA_Int32) 0x809f0000, // The data or event was not successfully inserted because a matching entry exists.
+	UA_STATUSCODE_BADNOENTRYEXISTS = (UA_Int32) 0x80a00000, // The data or event was not successfully updated because no matching entry exists.
+	UA_STATUSCODE_BADTIMESTAMPNOTSUPPORTED = (UA_Int32) 0x80a10000, // The client requested history using a timestamp format the server does not support (i.e requested ServerTimestamp when server only supports SourceTimestamp).
+	UA_STATUSCODE_GOODENTRYINSERTED = (UA_Int32) 0x00a20000, // The data or event was successfully inserted into the historical database.
+	UA_STATUSCODE_GOODENTRYREPLACED = (UA_Int32) 0x00a30000, // The data or event field was successfully replaced in the historical database.
+	UA_STATUSCODE_UNCERTAINDATASUBNORMAL = (UA_Int32) 0x40a40000, // The value is derived from multiple values and has less than the required number of Good values.
+	UA_STATUSCODE_GOODNODATA = (UA_Int32) 0x00a50000, // No data exists for the requested time range or event filter.
+	UA_STATUSCODE_GOODMOREDATA = (UA_Int32) 0x00a60000, // The data or event field was successfully replaced in the historical database.
+	UA_STATUSCODE_BADAGGREGATELISTMISMATCH = (UA_Int32) 0x80d40000, // The requested number of Aggregates does not match the requested number of NodeIds.
+	UA_STATUSCODE_BADAGGREGATENOTSUPPORTED = (UA_Int32) 0x80d50000, // The requested Aggregate is not support by the server.
+	UA_STATUSCODE_BADAGGREGATEINVALIDINPUTS = (UA_Int32) 0x80d60000, // The aggregate value could not be derived due to invalid data inputs.
+	UA_STATUSCODE_BADAGGREGATECONFIGURATIONREJECTED = (UA_Int32) 0x80da0000, // The aggregate configuration is not valid for specified node.
+	UA_STATUSCODE_GOODDATAIGNORED = (UA_Int32) 0x00d90000, // The request pecifies fields which are not valid for the EventType or cannot be saved by the historian.
+	UA_STATUSCODE_GOODCOMMUNICATIONEVENT = (UA_Int32) 0x00a70000, // The communication layer has raised an event.
+	UA_STATUSCODE_GOODSHUTDOWNEVENT = (UA_Int32) 0x00a80000, // The system is shutting down.
+	UA_STATUSCODE_GOODCALLAGAIN = (UA_Int32) 0x00a90000, // The operation is not finished and needs to be called again.
+	UA_STATUSCODE_GOODNONCRITICALTIMEOUT = (UA_Int32) 0x00aa0000, // A non-critical timeout occurred.
+	UA_STATUSCODE_BADINVALIDARGUMENT = (UA_Int32) 0x80ab0000, // One or more arguments are invalid.
+	UA_STATUSCODE_BADCONNECTIONREJECTED = (UA_Int32) 0x80ac0000, // Could not establish a network connection to remote server.
+	UA_STATUSCODE_BADDISCONNECT = (UA_Int32) 0x80ad0000, // The server has disconnected from the client.
+	UA_STATUSCODE_BADCONNECTIONCLOSED = (UA_Int32) 0x80ae0000, // The network connection has been closed.
+	UA_STATUSCODE_BADINVALIDSTATE = (UA_Int32) 0x80af0000, // The operation cannot be completed because the object is closed, uninitialized or in some other invalid state.
+	UA_STATUSCODE_BADENDOFSTREAM = (UA_Int32) 0x80b00000, // Cannot move beyond end of the stream.
+	UA_STATUSCODE_BADNODATAAVAILABLE = (UA_Int32) 0x80b10000, // No data is currently available for reading from a non-blocking stream.
+	UA_STATUSCODE_BADWAITINGFORRESPONSE = (UA_Int32) 0x80b20000, // The asynchronous operation is waiting for a response.
+	UA_STATUSCODE_BADOPERATIONABANDONED = (UA_Int32) 0x80b30000, // The asynchronous operation was abandoned by the caller.
+	UA_STATUSCODE_BADEXPECTEDSTREAMTOBLOCK = (UA_Int32) 0x80b40000, // The stream did not return all data requested (possibly because it is a non-blocking stream).
+	UA_STATUSCODE_BADWOULDBLOCK = (UA_Int32) 0x80b50000, // Non blocking behaviour is required and the operation would block.
+	UA_STATUSCODE_BADSYNTAXERROR = (UA_Int32) 0x80b60000, // A value had an invalid syntax.
+	UA_STATUSCODE_BADMAXCONNECTIONSREACHED = (UA_Int32) 0x80b70000 // The operation could not be finished because all available connections are in use.
+};
+
+#endif /* UA_STATUSCODES_H_ */
+#endif /* UA_TYPES_H_ */

+ 47 - 42
include/ua_types.h

@@ -23,6 +23,10 @@ extern "C" {
 #include <stdint.h>
 #include "ua_config.h"
 
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
 /**
  * @defgroup types Datatypes
  *
@@ -172,8 +176,9 @@ typedef struct UA_ExpandedNodeId {
     UA_UInt32 serverIndex;  // not encoded if 0
 } UA_ExpandedNodeId;
 
+#include "ua_statuscodes.h"
 /** @brief A numeric identifier for a error or condition that is associated with a value or an operation. */
-typedef UA_UInt32 UA_StatusCode; // StatusCodes aren't an enum(=int) since 32 unsigned bits are needed. See also ua_statuscodes.h */
+typedef enum UA_StatusCode UA_StatusCode; // StatusCodes aren't an enum(=int) since 32 unsigned bits are needed. See also ua_statuscodes.h */
 
 /** @brief A name qualified by a namespace. */
 typedef struct UA_QualifiedName {
@@ -305,19 +310,19 @@ typedef void UA_InvalidType;
 
 #ifdef DEBUG
 #define UA_TYPE_PROTOTYPES(TYPE)                                   \
-    UA_Int32 UA_LIBEXPORT TYPE##_new(TYPE **p);                    \
-    void UA_LIBEXPORT     TYPE##_init(TYPE * p);                   \
-    void UA_LIBEXPORT     TYPE##_delete(TYPE * p);                 \
-    void UA_LIBEXPORT     TYPE##_deleteMembers(TYPE * p);          \
-    UA_Int32 UA_LIBEXPORT TYPE##_copy(const TYPE *src, TYPE *dst); \
-    void UA_LIBEXPORT     TYPE##_print(const TYPE *p, FILE *stream);
+    UA_Int32 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_Int32 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_Int32 UA_LIBEXPORT TYPE##_new(TYPE **p);           \
-    void UA_LIBEXPORT     TYPE##_init(TYPE * p);          \
-    void UA_LIBEXPORT     TYPE##_delete(TYPE * p);        \
-    void UA_LIBEXPORT     TYPE##_deleteMembers(TYPE * p); \
-    UA_Int32 UA_LIBEXPORT TYPE##_copy(const TYPE *src, TYPE *dst);
+    UA_Int32 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_Int32 UA_EXPORT TYPE##_copy(const TYPE *src, TYPE *dst);
 #endif
 
 /* Functions for all types */
@@ -354,17 +359,17 @@ UA_TYPE_PROTOTYPES(UA_InvalidType)
         VARIABLE.length = sizeof(STRING)-1;     \
         VARIABLE.data   = (UA_Byte *)STRING; } while(0)
 
-UA_Int32 UA_LIBEXPORT UA_String_copycstring(char const *src, UA_String *dst);
-UA_Int32 UA_LIBEXPORT UA_String_copyprintf(char const *fmt, UA_String *dst, ...);
-UA_EQUALITY UA_LIBEXPORT UA_String_equal(const UA_String *string1, const UA_String *string2);
+UA_Int32 UA_EXPORT UA_String_copycstring(char const *src, UA_String *dst);
+UA_Int32 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);
 #ifdef DEBUG
-void UA_LIBEXPORT UA_String_printf(char const *label, const UA_String *string);
-void UA_LIBEXPORT UA_String_printx(char const *label, const UA_String *string);
-void UA_LIBEXPORT UA_String_printx_hex(char const *label, const UA_String *string);
+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);
+void UA_EXPORT UA_String_printx_hex(char const *label, const UA_String *string);
 #endif
 
 /* DateTime */
-UA_DateTime UA_LIBEXPORT UA_DateTime_now();
+UA_DateTime UA_EXPORT UA_DateTime_now();
 typedef struct UA_DateTimeStruct {
     UA_Int16 nanoSec;
     UA_Int16 microSec;
@@ -376,32 +381,32 @@ typedef struct UA_DateTimeStruct {
     UA_Int16 mounth;
     UA_Int16 year;
 } UA_DateTimeStruct;
-UA_DateTimeStruct UA_LIBEXPORT UA_DateTime_toStruct(UA_DateTime time);
-UA_Int32 UA_LIBEXPORT UA_DateTime_toString(UA_DateTime time, UA_String *timeString);
+UA_DateTimeStruct UA_EXPORT UA_DateTime_toStruct(UA_DateTime time);
+UA_Int32 UA_EXPORT UA_DateTime_toString(UA_DateTime time, UA_String *timeString);
 
 /* Guid */
-UA_EQUALITY UA_LIBEXPORT UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2);
+UA_EQUALITY UA_EXPORT UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2);
 
 /* ByteString */
-UA_EQUALITY UA_LIBEXPORT UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2);
-UA_Int32 UA_LIBEXPORT UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length);
+UA_EQUALITY UA_EXPORT UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2);
+UA_Int32 UA_EXPORT UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length);
 #ifdef DEBUG
-void UA_LIBEXPORT UA_ByteString_printf(char *label, const UA_ByteString *string);
-void UA_LIBEXPORT UA_ByteString_printx(char *label, const UA_ByteString *string);
-void UA_LIBEXPORT UA_ByteString_printx_hex(char *label, const UA_ByteString *string);
+void UA_EXPORT UA_ByteString_printf(char *label, const UA_ByteString *string);
+void UA_EXPORT UA_ByteString_printx(char *label, const UA_ByteString *string);
+void UA_EXPORT UA_ByteString_printx_hex(char *label, const UA_ByteString *string);
 #endif
 
 /* NodeId */
-UA_EQUALITY UA_LIBEXPORT UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2);
-UA_Boolean UA_LIBEXPORT UA_NodeId_isNull(const UA_NodeId *p);
-UA_Boolean UA_LIBEXPORT UA_NodeId_isBasicType(UA_NodeId const *id);
+UA_EQUALITY 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);
 
 #define NS0NODEID(NUMERIC_ID)                                                                        \
     (UA_NodeId) {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = \
                      NUMERIC_ID }
 
 /* ExpandedNodeId */
-UA_Boolean UA_LIBEXPORT UA_ExpandedNodeId_isNull(const UA_ExpandedNodeId *p);
+UA_Boolean UA_EXPORT UA_ExpandedNodeId_isNull(const UA_ExpandedNodeId *p);
 
 #define NS0EXPANDEDNODEID(VARIABLE, NUMERIC_ID) do {   \
         VARIABLE.nodeId       = NS0NODEID(NUMERIC_ID); \
@@ -412,9 +417,9 @@ UA_Boolean UA_LIBEXPORT UA_ExpandedNodeId_isNull(const UA_ExpandedNodeId *p);
 #define UA_QUALIFIEDNAME_STATIC(VARIABLE, STRING) do { \
         VARIABLE.namespaceIndex = 0;                   \
         UA_STRING_STATIC(VARIABLE.name, STRING); } while(0)
-UA_Int32 UA_LIBEXPORT UA_QualifiedName_copycstring(char const *src, UA_QualifiedName *dst);
+UA_Int32 UA_EXPORT UA_QualifiedName_copycstring(char const *src, UA_QualifiedName *dst);
 #ifdef DEBUG
-void UA_LIBEXPORT UA_QualifiedName_printf(char const *label, const UA_QualifiedName *qn);
+void UA_EXPORT UA_QualifiedName_printf(char const *label, const UA_QualifiedName *qn);
 #endif
 
 /* LocalizedText */
@@ -422,21 +427,21 @@ void UA_LIBEXPORT UA_QualifiedName_printf(char const *label, const UA_QualifiedN
         UA_STRING_STATIC(VARIABLE.locale, "en");       \
         UA_STRING_STATIC(VARIABLE.text, STRING); } while(0)
 
-UA_Int32 UA_LIBEXPORT UA_LocalizedText_copycstring(char const *src, UA_LocalizedText *dst);
+UA_Int32 UA_EXPORT UA_LocalizedText_copycstring(char const *src, UA_LocalizedText *dst);
 
 /* Variant */
-UA_Int32 UA_LIBEXPORT UA_Variant_copySetValue(UA_Variant *v, const UA_VTable_Entry *vt, const void *value);
-UA_Int32 UA_LIBEXPORT UA_Variant_copySetArray(UA_Variant *v, const UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array);
+UA_Int32 UA_EXPORT UA_Variant_copySetValue(UA_Variant *v, const UA_VTable_Entry *vt, const void *value);
+UA_Int32 UA_EXPORT UA_Variant_copySetArray(UA_Variant *v, const UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array);
 
 /* Array operations */
-UA_Int32 UA_LIBEXPORT UA_Array_new(void **p, UA_Int32 noElements, const UA_VTable_Entry *vt);
-void UA_LIBEXPORT UA_Array_init(void *p, UA_Int32 noElements, const UA_VTable_Entry *vt);
-void UA_LIBEXPORT UA_Array_delete(void *p, UA_Int32 noElements, const UA_VTable_Entry *vt);
+UA_Int32 UA_EXPORT UA_Array_new(void **p, UA_Int32 noElements, const UA_VTable_Entry *vt);
+void UA_EXPORT UA_Array_init(void *p, UA_Int32 noElements, const UA_VTable_Entry *vt);
+void UA_EXPORT UA_Array_delete(void *p, UA_Int32 noElements, const UA_VTable_Entry *vt);
 
 /* @brief The destination array is allocated according to noElements. */
-UA_Int32 UA_LIBEXPORT UA_Array_copy(const void *src, UA_Int32 noElements, const UA_VTable_Entry *vt, void **dst);
+UA_Int32 UA_EXPORT UA_Array_copy(const void *src, UA_Int32 noElements, const UA_VTable_Entry *vt, void **dst);
 #ifdef DEBUG
-void UA_LIBEXPORT UA_Array_print(const void *p, UA_Int32 noElements, const UA_VTable_Entry *vt, FILE *stream);
+void UA_EXPORT UA_Array_print(const void *p, UA_Int32 noElements, const UA_VTable_Entry *vt, FILE *stream);
 #endif
 
 /**********/
@@ -485,7 +490,7 @@ struct UA_VTable_Entry {
 
 #define UA_TYPE_NEW_DEFAULT(TYPE)                            \
     UA_Int32 TYPE##_new(TYPE **p) {                          \
-        if(UA_alloc((void **)p, sizeof(TYPE)) != UA_SUCCESS) \
+        if(!(*p = UA_alloc(sizeof(TYPE))))                    \
             return UA_ERROR;                                 \
         TYPE##_init(*p);                                     \
         return UA_SUCCESS;                                   \

src/server/ua_services_subscription.c → src/ongoing/ua_services_subscription.c


+ 7 - 6
src/server/ua_nodestore.c

@@ -1,5 +1,6 @@
 #include "ua_nodestore.h"
 #include "ua_util.h"
+#include "ua_statuscodes.h"
 
 struct UA_NodeStore {
     const UA_Node **entries;
@@ -223,8 +224,8 @@ static UA_Int32 expand(UA_NodeStore *ns) {
     nindex = higher_prime_index(count * 2);
     nsize  = primes[nindex];
 
-    if(UA_alloc((void **)&nentries, sizeof(UA_Node *) * nsize) != UA_SUCCESS)
-        return UA_ERR_NO_MEMORY;
+    if(!(nentries = UA_alloc(sizeof(UA_Node *) * nsize)))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
 
     memset(nentries, 0, nsize * sizeof(UA_Node *));
     ns->entries = nentries;
@@ -252,14 +253,14 @@ static UA_Int32 expand(UA_NodeStore *ns) {
 UA_Int32 UA_NodeStore_new(UA_NodeStore **result) {
     UA_NodeStore *ns;
     UA_UInt32     sizePrimeIndex, size;
-    if(UA_alloc((void **)&ns, sizeof(UA_NodeStore)) != UA_SUCCESS)
-        return UA_ERR_NO_MEMORY;
+    if(!(ns = UA_alloc(sizeof(UA_NodeStore))))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
 
     sizePrimeIndex = higher_prime_index(32);
     size = primes[sizePrimeIndex];
-    if(UA_alloc((void **)&ns->entries, sizeof(UA_Node *) * size) != UA_SUCCESS) {
+    if(!(ns->entries = UA_alloc(sizeof(UA_Node *) * size))) {
         UA_free(ns);
-        return UA_ERR_NO_MEMORY;
+        return UA_STATUSCODE_BADOUTOFMEMORY;
     }
 
     /* set entries to zero */

+ 1 - 1
src/server/ua_nodestore_concurrent.c

@@ -215,7 +215,7 @@ UA_Int32 UA_NodeStore_delete(UA_NodeStore *ns) {
     if(!cds_lfht_destroy(ht, UA_NULL)) {
         UA_free(ns);
         return UA_SUCCESS;
-    }else
+    } else
         return UA_ERROR;
 }
 

+ 7 - 5
src/server/ua_securechannel_manager.c

@@ -1,6 +1,7 @@
 #include "ua_securechannel_manager.h"
 #include "ua_session.h"
 #include "ua_util.h"
+#include "ua_statuscodes.h"
 
 struct channel_list_entry {
     UA_SecureChannel channel;
@@ -21,7 +22,8 @@ struct UA_SecureChannelManager {
 UA_Int32 UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 maxChannelCount,
                                      UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
                                      UA_UInt32 startTokenId, UA_String *endpointUrl) {
-    UA_alloc((void **)cm, sizeof(UA_SecureChannelManager));
+    if(!(*cm = UA_alloc(sizeof(UA_SecureChannelManager))))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
     UA_SecureChannelManager *channelManager = *cm;
     LIST_INIT(&channelManager->channels);
     channelManager->lastChannelId      = startChannelId;
@@ -33,8 +35,8 @@ UA_Int32 UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 max
 }
 
 UA_Int32 UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
-    struct channel_list_entry *entry;
-    LIST_FOREACH(entry, &cm->channels, pointers) {
+    struct channel_list_entry *entry = LIST_FIRST(&cm->channels);
+    while(entry) {
         LIST_REMOVE(entry, pointers);
         if(entry->channel.session)
             entry->channel.session->channel = UA_NULL;
@@ -42,6 +44,7 @@ UA_Int32 UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
             entry->channel.connection->channel = UA_NULL;
         UA_SecureChannel_deleteMembers(&entry->channel);
         UA_free(entry);
+        entry = LIST_FIRST(&cm->channels);
     }
     UA_String_deleteMembers(&cm->endpointUrl);
     UA_free(cm);
@@ -52,8 +55,7 @@ UA_Int32 UA_SecureChannelManager_open(UA_SecureChannelManager           *cm,
                                       UA_Connection                     *conn,
                                       const UA_OpenSecureChannelRequest *request,
                                       UA_OpenSecureChannelResponse      *response) {
-    struct channel_list_entry *entry;
-    UA_alloc((void **)&entry, sizeof(struct channel_list_entry));
+    struct channel_list_entry *entry = UA_alloc(sizeof(struct channel_list_entry));
     UA_SecureChannel_init(&entry->channel);
 
     entry->channel.connection = conn;

+ 35 - 47
src/server/ua_server.c

@@ -4,6 +4,7 @@
 #include "ua_securechannel_manager.h"
 #include "ua_session_manager.h"
 #include "ua_util.h"
+#include "ua_services.h"
 
 UA_Int32 UA_Server_deleteMembers(UA_Server *server) {
     UA_ApplicationDescription_deleteMembers(&server->description);
@@ -15,6 +16,12 @@ UA_Int32 UA_Server_deleteMembers(UA_Server *server) {
 }
 
 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_ApplicationDescription_init(&server->description);
     UA_ByteString_init(&server->serverCertificate);
 #define MAXCHANNELCOUNT 100
@@ -468,7 +475,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_String_copycstring("http://localhost:16664/open62541/", &((UA_String *)(namespaceArray->value.storage.data.dataPtr))[1]);
     namespaceArray->arrayDimensionsSize = 1;
     UA_UInt32 *dimensions = UA_NULL;
-    UA_alloc((void **)&dimensions, sizeof(UA_UInt32));
+    dimensions = UA_alloc(sizeof(UA_UInt32));
     *dimensions = 2;
     namespaceArray->arrayDimensions = dimensions;
     namespaceArray->dataType = NS0NODEID(UA_STRING_NS0);
@@ -518,51 +525,32 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     state->value.storageType = UA_VARIANT_DATA_NODELETE;
     UA_NodeStore_insert(server->nodestore, (UA_Node**)&state, UA_NODESTORE_INSERT_UNIQUE);
 
-#ifdef BENCHMARK
-    UA_UInt32 nodeCount = 500;
-    UA_VariableNode *tmpNode;
-    /* UA_ExpandedNodeId *tmpNodeIds; */
-    /* UA_Array_new((void**)&tmpNodes,nodeCount,&UA_[UA_VARIABLENODE]); */
-    /* UA_Array_new((void**)&tmpNodeIds,nodeCount,&UA_[UA_EXPANDEDNODEID]); */
-
-    for(UA_UInt32 i = 0;i<nodeCount;i++) {
-        UA_VariableNode_new(&tmpNode);
-        tmpNode->nodeId.identifier.numeric = 19000+i;
-        tmpNode->nodeClass = UA_NODECLASS_VARIABLE;
-
-        UA_Int32 data = 42;
-        char str[15];
-        UA_alloc((void*)str,15);
-        sprintf(str,"%d",i);
-        UA_QualifiedName_copycstring(str,&tmpNode->browseName);
-        UA_LocalizedText_copycstring(str,&tmpNode->displayName);
-
-        UA_LocalizedText_copycstring("integer value", &tmpNode->description);
-        tmpNode->value.vt = &UA_[UA_INT32];
-        tmpNode->value.storage.data.arrayDimensionsLength = 1; // added to ensure encoding in readreponse
-        tmpNode->value.storage.data.arrayLength = 1;
-        tmpNode->value.storage.data.dataPtr = &data;//&status->state; // points into the other object.
-        tmpNode->value.storageType = UA_VARIANT_DATA_NODELETE;
-
-        ADDREFERENCE(tmpNode, RefTypeId_Organizes, UA_TRUE, ObjId_ObjectsFolder);
-        UA_NodeStore_insert(server->nodestore, (UA_Node**)&tmpNode, UA_NODESTORE_INSERT_UNIQUE);
-    }
-#endif
-
-    //TODO: free(namespaceArray->value.data) later or forget it
-
-    /* UA_VariableNode* v = (UA_VariableNode*)np; */
-    /* UA_Array_new((void**)&v->value.data, 2, &UA_.types[UA_STRING]); */
-    /* v->value.vt = &UA_.types[UA_STRING]; */
-    /* v->value.arrayLength = 2; */
-    /* UA_String_copycstring("http://opcfoundation.org/UA/",&((UA_String *)((v->value).data))[0]); */
-    /* UA_String_copycstring("http://localhost:16664/open62541/",&((UA_String *)(((v)->value).data))[1]); */
-    /* v->dataType.identifierType = UA_NODEIDTYPE_FOURBYTE; */
-    /* v->dataType.identifier.numeric = UA_STRING_NS0; */
-    /* v->valueRank = 1; */
-    /* v->minimumSamplingInterval = 1.0; */
-    /* v->historizing = UA_FALSE; */
-    /* UA_NodeStore_insert(server->nodestore,np); */
-
     UA_NodeStore_releaseManagedNode((const UA_Node *)root);
 }
+
+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);
+}
+
+UA_AddNodesResult UA_Server_addScalarVariableNode(UA_Server *server, UA_String *browseName, void *value,
+                                                  const UA_VTable_Entry *vt, UA_ExpandedNodeId *parentNodeId,
+                                                  UA_NodeId *referenceTypeId ) {
+    UA_VariableNode *tmpNode;
+    UA_VariableNode_new(&tmpNode);
+    UA_String_copy(browseName, &tmpNode->browseName.name);
+    UA_String_copy(browseName, &tmpNode->displayName.text);
+    /* UA_LocalizedText_copycstring("integer value", &tmpNode->description); */
+    tmpNode->nodeClass = UA_NODECLASS_VARIABLE;
+    tmpNode->valueRank = -1;
+    tmpNode->value.vt = vt;
+    tmpNode->value.storage.data.dataPtr = value;
+    tmpNode->value.storageType = UA_VARIANT_DATA_NODELETE;
+    tmpNode->value.storage.data.arrayLength = 1;
+    return UA_Server_addNode(server, (UA_Node**)&tmpNode, parentNodeId, referenceTypeId);
+}

+ 33 - 11
src/server/ua_server_binary.c

@@ -181,9 +181,9 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
     UA_ByteString *header = &responseBufs[0];
     UA_ByteString *message = &responseBufs[1];
 
-    //subtract 2 for binary encoding
     UA_UInt32 sendOffset = 0;
-    switch(requestType.nodeId.identifier.numeric - 2) {
+    //subtract UA_ENCODINGOFFSET_BINARY for binary encoding
+    switch(requestType.nodeId.identifier.numeric - UA_ENCODINGOFFSET_BINARY) {
     case UA_GETENDPOINTSREQUEST_NS0: {
         UA_GetEndpointsRequest  p;
         UA_GetEndpointsResponse r;
@@ -230,6 +230,23 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
     }
         break;
 
+    case UA_CLOSESESSIONREQUEST_NS0: {
+        UA_CloseSessionRequest  p;
+        UA_CloseSessionResponse r;
+        CHECK_PROCESS(UA_CloseSessionRequest_decodeBinary(msg, pos, &p),; );
+        UA_CloseSessionResponse_init(&r);
+        init_response_header(&p.requestHeader, &r.responseHeader);
+
+        Service_CloseSession(server, &p, &r);
+        UA_ByteString_newMembers(message, UA_CloseSessionResponse_calcSizeBinary(&r));
+        UA_CloseSessionResponse_encodeBinary(&r, message, &sendOffset);
+        UA_CloseSessionRequest_deleteMembers(&p);
+        UA_CloseSessionResponse_deleteMembers(&r);
+        responseType = requestType.nodeId.identifier.numeric + 3;
+    }
+    break;
+
+
     case UA_READREQUEST_NS0:
         INVOKE_SERVICE(Read);
         break;
@@ -250,17 +267,17 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         INVOKE_SERVICE(TranslateBrowsePathsToNodeIds);
         break;
 
-    case UA_PUBLISHREQUEST_NS0:
-        INVOKE_SERVICE(Publish);
-        break;
+    /* case UA_PUBLISHREQUEST_NS0: */
+    /*     INVOKE_SERVICE(Publish); */
+    /*     break; */
 
-    case UA_CREATEMONITOREDITEMSREQUEST_NS0:
-        INVOKE_SERVICE(CreateMonitoredItems);
-        break;
+    /* case UA_CREATEMONITOREDITEMSREQUEST_NS0: */
+    /*     INVOKE_SERVICE(CreateMonitoredItems); */
+    /*     break; */
 
-    case UA_SETPUBLISHINGMODEREQUEST_NS0:
-        INVOKE_SERVICE(SetPublishingMode);
-        break;
+    /* case UA_SETPUBLISHINGMODEREQUEST_NS0: */
+    /*     INVOKE_SERVICE(SetPublishingMode); */
+    /*     break; */
 
     default: {
         printf("SL_processMessage - unknown request, namespace=%d, request=%d\n",
@@ -318,6 +335,11 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
 static void processClose(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
     // just read in the sequenceheader
 
+    UA_UInt32 secureChannelId;
+    UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
+
+	//the two last parameter is ignored since no answer is needed
+	Service_CloseSecureChannel(server, secureChannelId);
 }
 
 UA_Int32 UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg) {

+ 36 - 44
src/server/ua_services.h

@@ -29,9 +29,8 @@
  * the configuration information required to establish a SecureChannel and a
  * Session.
  */
-UA_Int32 Service_GetEndpoints(UA_Server                    *server,
-                              const UA_GetEndpointsRequest *request,
-                              UA_GetEndpointsResponse      *response);
+void Service_GetEndpoints(UA_Server                    *server,
+                          const UA_GetEndpointsRequest *request, UA_GetEndpointsResponse *response);
 // Service_RegisterServer
 /** @} */
 
@@ -48,14 +47,12 @@ UA_Int32 Service_GetEndpoints(UA_Server                    *server,
 /** @brief This Service is used to open or renew a SecureChannel that can be
    used to ensure Confidentiality and Integrity for Message exchange during a
    Session. */
-UA_Int32 Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
-                                   const UA_OpenSecureChannelRequest *request,
-                                   UA_OpenSecureChannelResponse *response);
+void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
+                               const UA_OpenSecureChannelRequest *request,
+                               UA_OpenSecureChannelResponse *response);
 
 /** @brief This Service is used to terminate a SecureChannel. */
-UA_Int32 Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel,
-                                    const UA_CloseSecureChannelRequest *request,
-                                    UA_CloseSecureChannelResponse *response);
+void Service_CloseSecureChannel(UA_Server *server, UA_Int32 channelId);
 /** @} */
 
 /**
@@ -74,9 +71,8 @@ UA_Int32 Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel
  * logs and in the Server’s address space. The second is the authenticationToken
  * which is used to associate an incoming request with a Session.
  */
-UA_Int32 Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
-                               const UA_CreateSessionRequest *request,
-                               UA_CreateSessionResponse *response);
+void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
+                           const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
 
 /**
  * @brief This Service is used by the Client to submit its SoftwareCertificates
@@ -85,16 +81,13 @@ UA_Int32 Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
  * Client before it issues any other Service request after CreateSession.
  * Failure to do so shall cause the Server to close the Session.
  */
-UA_Int32 Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
-                                 const UA_ActivateSessionRequest *request,
-                                 UA_ActivateSessionResponse *response);
+void Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
+                             const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
 
 /**
  * @brief This Service is used to terminate a Session.
  */
-UA_Int32 Service_CloseSession(UA_Server *server, UA_Session *session,
-                              const UA_CloseSessionRequest *request,
-                              UA_CloseSessionResponse *response);
+void Service_CloseSession(UA_Server *server, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
 // Service_Cancel
 /** @} */
 
@@ -111,15 +104,14 @@ UA_Int32 Service_CloseSession(UA_Server *server, UA_Session *session,
 /**
  * @brief This Service is used to add one or more Nodes into the AddressSpace hierarchy.
  */
-UA_Int32 Service_AddNodes(UA_Server *server, UA_Session *session,
-                          const UA_AddNodesRequest *request, UA_AddNodesResponse *response);
+void Service_AddNodes(UA_Server *server, UA_Session *session,
+                      const UA_AddNodesRequest *request, UA_AddNodesResponse *response);
 
 /**
  * @brief This Service is used to add one or more References to one or more Nodes
  */
-UA_Int32 Service_AddReferences(UA_Server *server, UA_Session *session,
-                               const UA_AddReferencesRequest *request,
-                               UA_AddReferencesResponse *response);
+void Service_AddReferences(UA_Server *server, UA_Session *session,
+                           const UA_AddReferencesRequest *request, UA_AddReferencesResponse *response);
 
 // Service_DeleteNodes
 // Service_DeleteReferences
@@ -139,15 +131,15 @@ UA_Int32 Service_AddReferences(UA_Server *server, UA_Session *session,
  * The browse can be further limited by the use of a View. This Browse Service
  * also supports a primitive filtering capability.
  */
-UA_Int32 Service_Browse(UA_Server *server, UA_Session *session,
-                        const UA_BrowseRequest *request, UA_BrowseResponse *response);
+void Service_Browse(UA_Server *server, UA_Session *session,
+                    const UA_BrowseRequest *request, UA_BrowseResponse *response);
 
 /**
  * @brief This Service is used to translate textual node paths to their respective ids.
  */
-UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
-                                               const UA_TranslateBrowsePathsToNodeIdsRequest *request,
-                                               UA_TranslateBrowsePathsToNodeIdsResponse *response);
+void Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
+                                           const UA_TranslateBrowsePathsToNodeIdsRequest *request,
+                                           UA_TranslateBrowsePathsToNodeIdsResponse *response);
 // Service_BrowseNext
 // Service_TranslateBrowsePathsToNodeIds
 // Service_RegisterNodes
@@ -190,8 +182,8 @@ UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *se
  * values as a composite, to read individual elements or to read ranges of
  * elements of the composite.
  */
-UA_Int32 Service_Read(UA_Server *server, UA_Session *session, const UA_ReadRequest *request,
-                      UA_ReadResponse *response);
+void Service_Read(UA_Server *server, UA_Session *session,
+                  const UA_ReadRequest *request, UA_ReadResponse *response);
 // Service_HistoryRead
 /**
  * @brief This Service is used to write one or more Attributes of one or more
@@ -200,8 +192,8 @@ UA_Int32 Service_Read(UA_Server *server, UA_Session *session, const UA_ReadReque
  *  values as a composite, to write individual elements or to write ranges of
  *  elements of the composite.
  */
-UA_Int32 Service_Write(UA_Server *server, UA_Session *session, const UA_WriteRequest *request,
-                       UA_WriteResponse *response);
+void Service_Write(UA_Server *server, UA_Session *session,
+                   const UA_WriteRequest *request, UA_WriteResponse *response);
 // Service_HistoryUpdate
 /** @} */
 
@@ -233,9 +225,9 @@ UA_Int32 Service_Write(UA_Server *server, UA_Session *session, const UA_WriteReq
  * triggered item links to be deleted, but has no effect on the MonitoredItems
  * referenced by the triggered items.
  */
-UA_Int32 Service_CreateMonitoredItems(UA_Server *server, UA_Session *session,
-                                      const UA_CreateMonitoredItemsRequest *request,
-                                      UA_CreateMonitoredItemsResponse *response);
+/* UA_Int32 Service_CreateMonitoredItems(UA_Server *server, UA_Session *session, */
+/*                                       const UA_CreateMonitoredItemsRequest *request, */
+/*                                       UA_CreateMonitoredItemsResponse *response); */
 // Service_ModifyMonitoredItems
 // Service_SetMonitoringMode
 // Service_SetTriggering
@@ -250,18 +242,18 @@ UA_Int32 Service_CreateMonitoredItems(UA_Server *server, UA_Session *session,
  * @{
  */
 // Service_CreateSubscription
-UA_Int32 Service_CreateSubscription(UA_Server *server, UA_Session *session,
-                                    const UA_CreateSubscriptionRequest *request,
-                                    UA_CreateSubscriptionResponse *response);
+/* UA_Int32 Service_CreateSubscription(UA_Server *server, UA_Session *session, */
+/*                                     const UA_CreateSubscriptionRequest *request, */
+/*                                     UA_CreateSubscriptionResponse *response); */
 // Service_ModifySubscription
 // Service_SetPublishingMode
-UA_Int32 Service_SetPublishingMode(UA_Server *server, UA_Session *session,
-                                   const UA_SetPublishingModeRequest *request,
-                                   UA_SetPublishingModeResponse *response);
+/* UA_Int32 Service_SetPublishingMode(UA_Server *server, UA_Session *session, */
+/*                                    const UA_SetPublishingModeRequest *request, */
+/*                                    UA_SetPublishingModeResponse *response); */
 
-UA_Int32 Service_Publish(UA_Server *server, UA_Session *session,
-                         const UA_PublishRequest *request,
-                         UA_PublishResponse *response);
+/* UA_Int32 Service_Publish(UA_Server *server, UA_Session *session, */
+/*                          const UA_PublishRequest *request, */
+/*                          UA_PublishResponse *response); */
 
 // Service_Republish
 // Service_TransferSubscription

+ 27 - 35
src/server/ua_services_attribute.c

@@ -5,9 +5,9 @@
 #include "ua_util.h"
 
 enum UA_AttributeId {
-    UA_ATTRIBUTEID_NODEID = 1,
-    UA_ATTRIBUTEID_NODECLASS = 2,
-    UA_ATTRIBUTEID_BROWSENAME = 3,
+    UA_ATTRIBUTEID_NODEID                  = 1,
+    UA_ATTRIBUTEID_NODECLASS               = 2,
+    UA_ATTRIBUTEID_BROWSENAME              = 3,
     UA_ATTRIBUTEID_DISPLAYNAME             = 4,
     UA_ATTRIBUTEID_DESCRIPTION             = 5,
     UA_ATTRIBUTEID_WRITEMASK               = 6,
@@ -211,31 +211,23 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
 
     return v;
 }
-UA_Int32 Service_Read(UA_Server *server, UA_Session *session, const UA_ReadRequest *request,
-                      UA_ReadResponse *response) {
-    UA_Int32 readsize;
-    if(session == UA_NULL) {
-        response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
-        return UA_ERROR;
-    }
+void Service_Read(UA_Server *server, UA_Session *session,
+                  const UA_ReadRequest *request, UA_ReadResponse *response) {
+    UA_assert(server != UA_NULL && session != UA_NULL && request != UA_NULL && response != UA_NULL);
 
-    readsize = request->nodesToReadSize;
-    /* NothingTodo */
-    if(readsize <= 0) {
+    if(request->nodesToReadSize <= 0) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
-        return UA_SUCCESS;
+        return;
     }
 
-    response->resultsSize = readsize;
-    UA_alloc((void **)&response->results, sizeof(UA_DataValue) * readsize);
-    for(UA_Int32 i = 0;i < readsize;i++) {
-        DBG_VERBOSE(printf("service_read - attributeId=%d\n", request->nodesToRead[i].attributeId));
-        DBG_VERBOSE(UA_NodeId_printf("service_read - nodeId=", &(request->nodesToRead[i].nodeId)));
-        response->results[i] = service_read_node(server, &request->nodesToRead[i]);
+    if(UA_Array_new((void **)&response->results, request->nodesToReadSize, &UA_[UA_DATAVALUE]) != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
     }
-    response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
-    response->diagnosticInfosSize = 0;
-    return UA_SUCCESS;
+
+    response->resultsSize = request->nodesToReadSize;
+    for(UA_Int32 i = 0;i < response->resultsSize;i++)
+        response->results[i] = service_read_node(server, &request->nodesToRead[i]);
 }
 
 UA_Int32 Service_Write_writeNode(UA_Server *server, UA_WriteValue *writeValue,
@@ -379,17 +371,17 @@ UA_Int32 Service_Write_writeNode(UA_Server *server, UA_WriteValue *writeValue,
 
 }
 
-UA_Int32 Service_Write(UA_Server *server, UA_Session *session, const UA_WriteRequest *request,
-                       UA_WriteResponse *response) {
-    UA_Int32 retval = UA_SUCCESS;
-    UA_Int32 i;
-    if(session == UA_NULL || server == UA_NULL)
-        return UA_ERROR;    // TODO: Return error message
-    response->resultsSize = request->nodesToWriteSize;
-    //TODO evalutate diagnostic info within the request
-    UA_Array_new((void **)&response->results, response->resultsSize, &UA_[UA_STATUSCODE]);
-    for(i = 0;i < request->nodesToWriteSize;i++)
-        retval |= Service_Write_writeNode(server, &request->nodesToWrite[i], &response->results[i]);
+void Service_Write(UA_Server *server, UA_Session *session,
+                   const UA_WriteRequest *request, UA_WriteResponse *response) {
+    UA_assert(server != UA_NULL && session != UA_NULL && request != UA_NULL && response != UA_NULL);
 
-    return retval;
+    if(UA_Array_new((void **)&response->results, request->nodesToWriteSize, &UA_[UA_STATUSCODE])
+       != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
+    }
+    
+    response->resultsSize = request->nodesToWriteSize;
+    for(UA_Int32 i = 0;i < request->nodesToWriteSize;i++)
+        Service_Write_writeNode(server, &request->nodesToWrite[i], &response->results[i]);
 }

+ 3 - 5
src/server/ua_services_discovery.c

@@ -1,9 +1,9 @@
 #include "ua_services.h"
 #include "ua_namespace_0.h"
 
-UA_Int32 Service_GetEndpoints(UA_Server                    *server,
-                              const UA_GetEndpointsRequest *request,
-                              UA_GetEndpointsResponse      *response) {
+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]);
@@ -37,6 +37,4 @@ UA_Int32 Service_GetEndpoints(UA_Server                    *server,
     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;
-
-	return UA_SUCCESS;
 }

+ 4 - 1
src/server/ua_services_internal.h

@@ -3,6 +3,7 @@
  * internally as well (with a simplified API as no access rights are checked).
  */
 
+#include "ua_session.h"
 #include "ua_nodestore.h"
 #include "ua_types_generated.h"
 
@@ -12,4 +13,6 @@
  * @param The reference itself
  * @param The namespace where the target node is looked up for the reverse reference (this is omitted if targetns is UA_NULL)
  */
-UA_Int32 AddReference(UA_NodeStore *targetns, UA_Node *node, UA_ReferenceNode *reference);
+UA_Int32 AddReference(UA_NodeStore *nodestore, UA_Node *node, UA_ReferenceNode *reference);
+UA_AddNodesResult AddNode(UA_Server *server, UA_Session *session, UA_Node **node,
+                          UA_ExpandedNodeId *parentNodeId, UA_NodeId *referenceTypeId);

+ 191 - 74
src/server/ua_services_nodemanagement.c

@@ -1,120 +1,237 @@
 #include "ua_services.h"
+#include "ua_namespace_0.h"
 #include "ua_statuscodes.h"
 #include "ua_nodestore.h"
 #include "ua_services_internal.h"
 #include "ua_session.h"
 #include "ua_util.h"
 
-#define CHECKED_ACTION(ACTION, CLEAN_UP, GOTO) do { \
-        status |= ACTION;                           \
-        if(status != UA_SUCCESS) {                  \
-            CLEAN_UP;                               \
-            goto GOTO;                              \
-        } } while(0)                                \
+#define COPY_STANDARDATTRIBUTES do {                                    \
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_DISPLAYNAME) {  \
+        vnode->displayName = attr.displayName;                          \
+        UA_LocalizedText_init(&attr.displayName);                       \
+    }                                                                   \
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_DESCRIPTION) {  \
+        vnode->description = attr.description;                          \
+        UA_LocalizedText_init(&attr.description);                       \
+    }                                                                   \
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_WRITEMASK)      \
+        vnode->writeMask = attr.writeMask;                              \
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_USERWRITEMASK)  \
+        vnode->userWriteMask = attr.userWriteMask;                      \
+    } while(0)
+
+static UA_StatusCode parseVariableNode(UA_ExtensionObject *attributes, UA_Node **new_node,
+                                       const UA_VTable_Entry **vt) {
+    if(attributes->typeId.identifier.numeric != 357) // VariableAttributes_Encoding_DefaultBinary,357,Object
+        return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
+
+    UA_VariableAttributes attr;
+    UA_UInt32 pos = 0;
+    // todo return more informative error codes from decodeBinary
+    if(UA_VariableAttributes_decodeBinary(&attributes->body, &pos, &attr) != UA_SUCCESS)
+        return UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
+
+    UA_VariableNode *vnode;
+    if(UA_VariableNode_new(&vnode) != UA_SUCCESS) {
+        UA_VariableAttributes_deleteMembers(&attr);
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    }
+
+    // now copy all the attributes. This potentially removes them from the decoded attributes.
+    COPY_STANDARDATTRIBUTES;
+
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_ACCESSLEVEL)
+        vnode->accessLevel = attr.accessLevel;
+
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_USERACCESSLEVEL)
+        vnode->userAccessLevel = attr.userAccessLevel;
+
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_HISTORIZING)
+        vnode->historizing = attr.historizing;
+
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_MINIMUMSAMPLINGINTERVAL)
+        vnode->minimumSamplingInterval = attr.minimumSamplingInterval;
+
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_VALUERANK)
+        vnode->valueRank = attr.valueRank;
+
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_ARRAYDIMENSIONS) {
+        vnode->arrayDimensionsSize = attr.arrayDimensionsSize;
+        vnode->arrayDimensions = attr.arrayDimensions;
+        attr.arrayDimensionsSize = -1;
+        attr.arrayDimensions = UA_NULL;
+    }
+
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_DATATYPE ||
+       attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_OBJECTTYPEORDATATYPE) {
+        vnode->dataType = attr.dataType;
+        UA_NodeId_init(&attr.dataType);
+    }
 
-static UA_AddNodesResult addSingleNode(UA_Server *server, UA_AddNodesItem *item) {
+    if(attr.specifiedAttributes & UA_NODEATTRIBUTESMASK_VALUE) {
+        vnode->value = attr.value;
+        UA_Variant_init(&attr.value);
+    }
+
+    UA_VariableAttributes_deleteMembers(&attr);
+
+    *new_node = (UA_Node*)vnode;
+    *vt = &UA_[UA_VARIABLENODE];
+    return UA_STATUSCODE_GOOD;
+}
+
+UA_Int32 AddReference(UA_NodeStore *nodestore, UA_Node *node, UA_ReferenceNode *reference);
+
+/**
+   If adding the node succeeds, the pointer will be set to zero. If the nodeid
+   of the node is null (ns=0,i=0), a unique new nodeid will be assigned and
+   returned in the AddNodesResult.
+ */
+UA_AddNodesResult AddNode(UA_Server *server, UA_Session *session, UA_Node **node,
+                          UA_ExpandedNodeId *parentNodeId, UA_NodeId *referenceTypeId) {
     UA_AddNodesResult result;
     UA_AddNodesResult_init(&result);
+    
+    const UA_Node *parent;
+    if(UA_NodeStore_get(server->nodestore, &parentNodeId->nodeId, &parent) != UA_SUCCESS) {
+        result.statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID;
+        return result;
+    }
 
-    // TODO: search for namespaceUris and not only ns-ids.
-    /* UA_Boolean    nodeid_isnull = UA_NodeId_isNull(&item->requestedNewNodeId.nodeId); */
+    const UA_ReferenceTypeNode *referenceType;
+    if(UA_NodeStore_get(server->nodestore, referenceTypeId, (const UA_Node**)&referenceType) != UA_SUCCESS) {
+        result.statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
+        goto ret;
+    }
 
-    if(item->requestedNewNodeId.nodeId.namespaceIndex == 0) {
-        result.statusCode = UA_STATUSCODE_BADNODEIDREJECTED;
-        return result;
+    if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) {
+        result.statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
+        goto ret2;
     }
 
-    UA_Int32       status = UA_SUCCESS;
-    const UA_Node *parent;
-    CHECKED_ACTION(UA_NodeStore_get(server->nodestore, &item->parentNodeId.nodeId, &parent),
-                   result.statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID, ret);
-
-    /* if(!nodeid_isnull && NodeStore_contains(ns, &item->requestedNewNodeId.nodeId)) { */
-    /*  result.statusCode = UA_STATUSCODE_BADNODEIDEXISTS; */
-    /*  goto ret; */
-    /* } */
-
-    /**
-       TODO:
-
-       1) Check for the remaining conditions
-       Bad_ReferenceTypeIdInvalid  See Table 166 for the description of this result code.
-       Bad_ReferenceNotAllowed  The reference could not be created because it violates constraints imposed by the data model.
-       Bad_NodeClassInvalid  See Table 166 for the description of this result code.
-       Bad_BrowseNameInvalid  See Table 166 for the description of this result code.
-       Bad_BrowseNameDuplicated  The browse name is not unique among nodes that share the same relationship with the parent.
-       Bad_NodeAttributesInvalid  The node Attributes are not valid for the node class.
-       Bad_TypeDefinitionInvalid  See Table 166 for the description of this result code.
-       Bad_UserAccessDenied  See Table 165 for the description of this result code
-
-       2) Parse the UA_Node from the ExtensionObject
-       3) Create a new entry in the namespace
-       4) Add the reference to the parent.
-     */
-
-ret:
+    if(referenceType->isAbstract == UA_TRUE) {
+        result.statusCode = UA_STATUSCODE_BADREFERENCENOTALLOWED;
+        goto ret2;
+    }
+
+    // todo: test if the referenetype is hierarchical
+
+    if(UA_NodeId_isNull(&(*node)->nodeId)) {
+        if(UA_NodeStore_insert(server->nodestore, node,
+                               UA_NODESTORE_INSERT_UNIQUE | UA_NODESTORE_INSERT_GETMANAGED) != UA_SUCCESS) {
+            result.statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
+            goto ret2;
+        }
+        result.addedNodeId = (*node)->nodeId; // cannot fail as unique nodeids are numeric
+    } else {
+        if(UA_NodeId_copy(&(*node)->nodeId, &result.addedNodeId) != UA_SUCCESS) {
+            result.statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
+            goto ret2;
+        }
+
+        if(UA_NodeStore_insert(server->nodestore, node, UA_NODESTORE_INSERT_GETMANAGED) != UA_SUCCESS) {
+            result.statusCode = UA_STATUSCODE_BADNODEIDEXISTS;  // todo: differentiate out of memory
+            UA_NodeId_deleteMembers(&result.addedNodeId);
+            goto ret2;
+        }
+    }
+    
+    UA_ReferenceNode ref;
+    UA_ReferenceNode_init(&ref);
+    ref.referenceTypeId = referenceType->nodeId; // is numeric
+    ref.isInverse = UA_TRUE; // todo: check if they are all not inverse..
+    ref.targetId.nodeId = parent->nodeId;
+    AddReference(server->nodestore, *node, &ref);
+
+    // todo: error handling. remove new node from nodestore
+
+    UA_NodeStore_releaseManagedNode(*node);
+    *node = UA_NULL;
+    
+ ret2:
+    UA_NodeStore_releaseManagedNode((UA_Node*)referenceType);
+ ret:
     UA_NodeStore_releaseManagedNode(parent);
+
     return result;
 }
 
-UA_Int32 Service_AddNodes(UA_Server *server, UA_Session *session,
-                          const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
-    if(session == UA_NULL)
-        return UA_ERROR;    // TODO: Return error message
+static void addNodeFromAttributes(UA_Server *server, UA_Session *session, UA_AddNodesItem *item,
+                                  UA_AddNodesResult *result) {
+    if(item->requestedNewNodeId.nodeId.namespaceIndex == 0) {
+        // adding nodes to ns0 is not allowed over the wire
+        result->statusCode = UA_STATUSCODE_BADNODEIDREJECTED;
+        return;
+    }
+
+    UA_Node *newNode;
+    const UA_VTable_Entry *newNodeVT = UA_NULL;
+    if(item->nodeClass == UA_NODECLASS_VARIABLE)
+        result->statusCode = parseVariableNode(&item->nodeAttributes, &newNode, &newNodeVT);
+    else // add more node types here..
+        result->statusCode = UA_STATUSCODE_BADNOTIMPLEMENTED;
+
+    if(result->statusCode != UA_STATUSCODE_GOOD)
+        return;
+
+    *result = AddNode(server, session, &newNode, &item->parentNodeId, &item->referenceTypeId);
+    if(result->statusCode != UA_STATUSCODE_GOOD)
+        newNodeVT->delete(newNode);
+}
+
+void Service_AddNodes(UA_Server *server, UA_Session *session,
+                      const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
+    UA_assert(server != UA_NULL && session != UA_NULL);
 
-    UA_Int32 nodestoaddsize = request->nodesToAddSize;
-    if(nodestoaddsize <= 0) {
+    if(request->nodesToAddSize <= 0) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
-        response->resultsSize = 0;
-        return UA_SUCCESS;
+        return;
     }
 
-    response->resultsSize = nodestoaddsize;
-    UA_alloc((void **)&response->results, sizeof(void *) * nodestoaddsize);
-    for(int i = 0;i < nodestoaddsize;i++) {
-        DBG_VERBOSE(UA_QualifiedName_printf("service_addnodes - name=", &(request->nodesToAdd[i].browseName)));
-        response->results[i] = addSingleNode(server, &request->nodesToAdd[i]);
+    if(UA_Array_new((void **)&response->results, request->nodesToAddSize, &UA_[UA_ADDNODESRESULT])
+       != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
     }
-    response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
-    response->diagnosticInfosSize = -1;
-    return UA_SUCCESS;
-
+    
+    response->resultsSize = request->nodesToAddSize;
+    for(int i = 0;i < request->nodesToAddSize;i++)
+        addNodeFromAttributes(server, session, &request->nodesToAdd[i], &response->results[i]);
 }
 
 static UA_Int32 AddSingleReference(UA_Node *node, UA_ReferenceNode *reference) {
     // TODO: Check if reference already exists
-    UA_Int32 retval;
     UA_Int32 count = node->referencesSize;
     UA_ReferenceNode *old_refs = node->references;
     UA_ReferenceNode *new_refs;
+
     if(count < 0) count = 0;
 
-    retval = UA_alloc((void **)&new_refs, sizeof(UA_ReferenceNode)*(count+1));
-    if(retval != UA_SUCCESS)
-        return UA_ERROR;
-    UA_memcpy(new_refs, old_refs, sizeof(UA_ReferenceNode)*count);
-    retval |= UA_ReferenceNode_copy(reference, &new_refs[count]);
+    if(!(new_refs = UA_alloc(sizeof(UA_ReferenceNode)*(count+1))))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
 
-    if(retval != UA_SUCCESS) {
+    UA_memcpy(new_refs, old_refs, sizeof(UA_ReferenceNode)*count);
+    if(UA_ReferenceNode_copy(reference, &new_refs[count]) != UA_SUCCESS) {
         UA_free(new_refs);
-        return retval;
+        return UA_STATUSCODE_BADOUTOFMEMORY;
     }
 
     node->references     = new_refs;
     node->referencesSize = count+1;
     UA_free(old_refs);
-    return retval;
+    return UA_SUCCESS;
 }
 
-UA_Int32 AddReference(UA_NodeStore *targetns, UA_Node *node, UA_ReferenceNode *reference) {
+UA_Int32 AddReference(UA_NodeStore *nodestore, UA_Node *node, UA_ReferenceNode *reference) {
     UA_Int32 retval = AddSingleReference(node, reference);
     UA_Node *targetnode;
     UA_ReferenceNode inversereference;
-    if(retval != UA_SUCCESS || targetns == UA_NULL)
+    if(retval != UA_SUCCESS || nodestore == UA_NULL)
         return retval;
 
     // Do a copy every time?
-    if(UA_NodeStore_get(targetns, &reference->targetId.nodeId, (const UA_Node **)&targetnode) != UA_SUCCESS)
+    if(UA_NodeStore_get(nodestore, &reference->targetId.nodeId, (const UA_Node **)&targetnode) != UA_SUCCESS)
         return UA_ERROR;
 
     inversereference.referenceTypeId       = reference->referenceTypeId;
@@ -128,8 +245,8 @@ UA_Int32 AddReference(UA_NodeStore *targetns, UA_Node *node, UA_ReferenceNode *r
     return retval;
 }
 
-UA_Int32 Service_AddReferences(UA_Server *server, UA_Session *session,
-                               const UA_AddReferencesRequest *request,
-                               UA_AddReferencesResponse *response) {
-    return UA_ERROR;
+void Service_AddReferences(UA_Server *server, UA_Session *session,
+                           const UA_AddReferencesRequest *request,
+                           UA_AddReferencesResponse *response) {
+    response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTIMPLEMENTED;
 }

+ 8 - 11
src/server/ua_services_securechannel.c

@@ -1,21 +1,18 @@
 #include "ua_services.h"
 #include "ua_securechannel_manager.h"
 
-UA_Int32 Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
-                                   const UA_OpenSecureChannelRequest *request,
-                                   UA_OpenSecureChannelResponse *response) {
-    UA_Int32 retval = UA_SUCCESS;
+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)
-        retval |= UA_SecureChannelManager_open(server->secureChannelManager, connection, request, response);
+        UA_SecureChannelManager_open(server->secureChannelManager, connection, request, response);
     else
-        retval |= UA_SecureChannelManager_renew(server->secureChannelManager, connection, request, response);
-    return retval;
+        UA_SecureChannelManager_renew(server->secureChannelManager, connection, request, response);
 }
 
-UA_Int32 Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel,
-                                    const UA_CloseSecureChannelRequest *request,
-                                    UA_CloseSecureChannelResponse *response) {
-    return UA_SecureChannelManager_close(server->secureChannelManager, channel->securityToken.channelId);
+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);
     // 62451 Part 6 Chapter 7.1.4 - The server does not send a CloseSecureChannel response
 }

+ 36 - 32
src/server/ua_services_session.c

@@ -1,19 +1,19 @@
 #include "ua_services.h"
 #include "ua_server.h"
 #include "ua_session_manager.h"
+#include "ua_statuscodes.h"
 
-UA_Int32 Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
-                               const UA_CreateSessionRequest *request,
-                               UA_CreateSessionResponse *response) {
+void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
+                           const UA_CreateSessionRequest *request,
+                           UA_CreateSessionResponse *response) {
     // 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_Int32 retval = UA_SUCCESS;
 	UA_Session *newSession;
-    retval |= UA_SessionManager_createSession(server->sessionManager, channel, &newSession);
-	if(retval != UA_SUCCESS)
-	{
-		return retval;
-	}
+    response->responseHeader.serviceResult = UA_SessionManager_createSession(server->sessionManager,
+                                                                             channel, &newSession);
+	if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
+		return;
+
     //TODO get maxResponseMessageSize
     UA_String_copy(&request->sessionName, &newSession->sessionName);
     newSession->maxResponseMessageSize = request->maxResponseMessageSize;
@@ -22,36 +22,40 @@ UA_Int32 Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
     response->revisedSessionTimeout = newSession->timeout;
     response->authenticationToken = newSession->authenticationToken;
     //channel->session = newSession;
-    return retval;
 }
 
-UA_Int32 Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
-                                 const UA_ActivateSessionRequest *request,
-                                 UA_ActivateSessionResponse *response) {
+void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
+                             const UA_ActivateSessionRequest *request,
+                             UA_ActivateSessionResponse *response) {
     // make the channel know about the session
 	UA_Session *foundSession;
-
-	UA_SessionManager_getSessionByToken(server->sessionManager,(UA_NodeId*)&request->requestHeader.authenticationToken,&foundSession);
+	UA_SessionManager_getSessionByToken(server->sessionManager,
+                                        (UA_NodeId*)&request->requestHeader.authenticationToken,
+                                        &foundSession);
 
 	if(foundSession == UA_NULL)
-	{
-		return UA_ERROR;
-	}
-
-    channel->session = foundSession;
-
-    return UA_SUCCESS;
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
+    else
+        channel->session = foundSession;
 }
 
-UA_Int32 Service_CloseSession(UA_Server *server, UA_Session *session,
-                              const UA_CloseSessionRequest *request,
+void Service_CloseSession(UA_Server *server, const UA_CloseSessionRequest *request,
                               UA_CloseSessionResponse *response) {
-    session->channel->session = UA_NULL;
-    UA_SessionManager_removeSession(server->sessionManager, &session->sessionId);
-    /* UA_NodeId sessionId; */
-    /* UA_Session_getId(session,&sessionId); */
-
-    /* UA_SessionManager_removeSession(&sessionId); */
-    // FIXME: set response
-    return UA_SUCCESS;
+	UA_Session *foundSession;
+	UA_SessionManager_getSessionByToken(server->sessionManager,
+			(UA_NodeId*)&request->requestHeader.authenticationToken,
+			&foundSession);
+
+	if(foundSession == UA_NULL){
+		response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
+		return;
+	}
+
+
+	if(UA_SessionManager_removeSession(server->sessionManager, &foundSession->sessionId) == UA_SUCCESS){
+		response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
+	}else{
+		//still not 100% sure about the return code
+		response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURECHANNELIDINVALID;
+	}
 }

+ 39 - 36
src/server/ua_services_view.c

@@ -66,11 +66,10 @@ struct SubRefTypeId {
 };
 SLIST_HEAD(SubRefTypeIdList, SubRefTypeId);
 
-UA_UInt32 walkReferenceTree(UA_NodeStore *ns, const UA_ReferenceTypeNode *current,
-                            struct SubRefTypeIdList *list) {
+static UA_UInt32 walkReferenceTree(UA_NodeStore *ns, const UA_ReferenceTypeNode *current,
+                                   struct SubRefTypeIdList *list) {
     // insert the current referencetype
-    struct SubRefTypeId *element;
-    UA_alloc((void **)&element, sizeof(struct SubRefTypeId));
+    struct SubRefTypeId *element = UA_alloc(sizeof(struct SubRefTypeId));
     element->id = current->nodeId;
     SLIST_INSERT_HEAD(list, element, next);
 
@@ -107,7 +106,7 @@ static UA_Int32 findSubReferenceTypes(UA_NodeStore *ns, UA_NodeId *rootReference
     UA_NodeStore_releaseManagedNode((const UA_Node *)root);
 
     // copy results into an array
-    UA_alloc((void **)ids, sizeof(UA_NodeId)*count);
+    *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]);
@@ -143,7 +142,7 @@ static void Service_Browse_getBrowseResult(UA_NodeStore         *ns,
                                            UA_UInt32             maxReferences,
                                            UA_BrowseResult      *browseResult) {
     const UA_Node *node;
-    UA_NodeId     *relevantReferenceTypes;
+    UA_NodeId     *relevantReferenceTypes = UA_NULL;
     UA_UInt32      relevantReferenceTypesCount = 0;
     if(UA_NodeStore_get(ns, &browseDescription->nodeId, &node) != UA_SUCCESS) {
         browseResult->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
@@ -158,7 +157,9 @@ static void Service_Browse_getBrowseResult(UA_NodeStore         *ns,
     if(!browseDescription->includeSubtypes ||
        findSubReferenceTypes(ns, &browseDescription->referenceTypeId, &relevantReferenceTypes,
                              &relevantReferenceTypesCount) != UA_SUCCESS) {
-        UA_alloc((void **)&relevantReferenceTypes, sizeof(UA_NodeId));
+        if(!(relevantReferenceTypes = UA_alloc(sizeof(UA_NodeId)))) {
+            return;
+        }
         UA_NodeId_copy(&browseDescription->referenceTypeId, relevantReferenceTypes);
         relevantReferenceTypesCount = 1;
     }
@@ -205,45 +206,47 @@ static void Service_Browse_getBrowseResult(UA_NodeStore         *ns,
     UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesCount, &UA_[UA_NODEID]);
 }
 
-UA_Int32 Service_Browse(UA_Server *server, UA_Session *session,
-                        const UA_BrowseRequest *request, UA_BrowseResponse *response) {
-    UA_Int32 retval = UA_SUCCESS;
-    if(server == UA_NULL || session == UA_NULL)
-        return UA_ERROR;
-
-    //TODO request->view not used atm
-    UA_Array_new((void **)&(response->results), request->nodesToBrowseSize, &UA_[UA_BROWSERESULT]);
-    response->resultsSize = request->nodesToBrowseSize;
+void Service_Browse(UA_Server *server, UA_Session *session,
+                    const UA_BrowseRequest *request, UA_BrowseResponse *response) {
+    UA_assert(server != UA_NULL && session != UA_NULL && request != UA_NULL && response != UA_NULL);
 
-    for(UA_Int32 i = 0;i < request->nodesToBrowseSize;i++) {
-        // Service_Browse_getBrowseResult has no return value. All errors are resolved internally.
-        Service_Browse_getBrowseResult(server->nodestore, &request->nodesToBrowse[i],
-                                       request->requestedMaxReferencesPerNode,
-                                       &response->results[i]);
+    if(request->nodesToBrowseSize <= 0) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
+        return;
     }
 
-    //TODO fill Diagnostic info array
-    response->diagnosticInfosSize = 0;
-    response->diagnosticInfos     = UA_NULL;
-    return retval;
+    if(UA_Array_new((void **)&(response->results), request->nodesToBrowseSize, &UA_[UA_BROWSERESULT])
+       != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
+    }
+        
+    response->resultsSize = request->nodesToBrowseSize;
+    for(UA_Int32 i = 0;i < request->nodesToBrowseSize;i++)
+        Service_Browse_getBrowseResult(server->nodestore, &request->nodesToBrowse[i],
+                                       request->requestedMaxReferencesPerNode, &response->results[i]);
 }
 
 
-UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
-                                               const UA_TranslateBrowsePathsToNodeIdsRequest *request,
-                                               UA_TranslateBrowsePathsToNodeIdsResponse *response) {
-    UA_Int32 retval = UA_SUCCESS;
-    DBG_VERBOSE(printf("TranslateBrowsePathsToNodeIdsService - %i path(s)", request->browsePathsSize));
+void Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
+                                           const UA_TranslateBrowsePathsToNodeIdsRequest *request,
+                                           UA_TranslateBrowsePathsToNodeIdsResponse *response) {
+    UA_assert(server != UA_NULL && session != UA_NULL && request != UA_NULL && response != UA_NULL);
+
+    if(request->browsePathsSize <= 0) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
+        return;
+    }
 
     // Allocate space for a correct answer
     response->resultsSize = request->browsePathsSize;
     // _init of the elements is done in Array_new
-    UA_Array_new((void **)&response->results, request->browsePathsSize, &UA_[UA_BROWSEPATHRESULT]);
-
-    for(UA_Int32 i = 0;i < request->browsePathsSize;i++) {
-        //FIXME: implement
-        response->results[i].statusCode = UA_STATUSCODE_BADNOMATCH;
+    if(UA_Array_new((void **)&response->results, request->browsePathsSize, &UA_[UA_BROWSEPATHRESULT])
+       != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
     }
 
-    return retval;
+    for(UA_Int32 i = 0;i < request->browsePathsSize;i++)
+        response->results[i].statusCode = UA_STATUSCODE_BADNOMATCH; //FIXME: implement
 }

+ 13 - 10
src/server/ua_session_manager.c

@@ -1,4 +1,5 @@
 #include "ua_session_manager.h"
+#include "ua_statuscodes.h"
 #include "ua_util.h"
 
 /**
@@ -24,13 +25,13 @@ struct UA_SessionManager {
 UA_Int32 UA_SessionManager_new(UA_SessionManager **sessionManager, UA_UInt32 maxSessionCount,
                                UA_UInt32 sessionTimeout, UA_UInt32 startSessionId) {
     UA_Int32 retval = UA_SUCCESS;
-    retval |= UA_alloc((void **)sessionManager, sizeof(UA_SessionManager));
-    if(retval != UA_SUCCESS)
-        return UA_ERROR;
+    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;
     return retval;
 }
 
@@ -95,18 +96,20 @@ UA_Int32 UA_SessionManager_getSessionByToken(UA_SessionManager *sessionManager,
 }
 
 /** Creates and adds a session. */
-UA_Int32 UA_SessionManager_createSession(UA_SessionManager *sessionManager, UA_SecureChannel *channel, UA_Session **session) {
+UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager, UA_SecureChannel *channel,
+                                              UA_Session **session) {
     if(sessionManager->currentSessionCount >= sessionManager->maxSessionCount)
-        return UA_ERROR;
+        return UA_STATUSCODE_BADTOOMANYSESSIONS;
 
-    struct session_list_entry *newentry;
-    if(UA_alloc((void **)&newentry, sizeof(struct session_list_entry)) != UA_SUCCESS)
-        return UA_ERROR;
+    struct session_list_entry *newentry = UA_alloc(sizeof(struct session_list_entry));
+    if(!newentry)
+        return UA_STATUSCODE_BADOUTOFMEMORY;
 
     UA_Session_init(&newentry->session);
     newentry->session.sessionId = (UA_NodeId) {.namespaceIndex = 1, .identifierType = UA_NODEIDTYPE_NUMERIC,
                                                .identifier.numeric = sessionManager->lastSessionId++ };
-    newentry->session.authenticationToken = (UA_NodeId) {.namespaceIndex = 1, .identifierType = UA_NODEIDTYPE_NUMERIC,
+    newentry->session.authenticationToken = (UA_NodeId) {.namespaceIndex = 1,
+                                                         .identifierType = UA_NODEIDTYPE_NUMERIC,
                                                          .identifier.numeric = sessionManager->lastSessionId };
     newentry->session.channel = channel;
     newentry->session.timeout = 3600 * 1000; // 1h
@@ -115,7 +118,7 @@ UA_Int32 UA_SessionManager_createSession(UA_SessionManager *sessionManager, UA_S
     sessionManager->currentSessionCount++;
     LIST_INSERT_HEAD(&sessionManager->sessions, newentry, pointers);
     *session = &newentry->session;
-    return UA_SUCCESS;
+    return UA_STATUSCODE_GOOD;
 }
 
 UA_Int32 UA_SessionManager_removeSession(UA_SessionManager *sessionManager, UA_NodeId  *sessionId) {

+ 2 - 2
src/server/ua_session_manager.h

@@ -9,8 +9,8 @@ UA_Int32 UA_SessionManager_new(UA_SessionManager **sessionManager, UA_UInt32 max
 
 UA_Int32 UA_SessionManager_delete(UA_SessionManager *sessionManager);
 
-UA_Int32 UA_SessionManager_createSession(UA_SessionManager *sessionManager,
-                                         UA_SecureChannel *channel, UA_Session **session);
+UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
+                                              UA_SecureChannel *channel, UA_Session **session);
 
 UA_Int32 UA_SessionManager_removeSession(UA_SessionManager *sessionManager,
                                          UA_NodeId         *sessionId);

+ 6 - 12
src/ua_config.h.in

@@ -6,12 +6,6 @@
 #cmakedefine MSVC
 #cmakedefine WIN32
 
-#ifndef MSVC
-#define INLINE inline
-#else
-#define INLINE __inline
-#endif
-
 /* Visibility */
 #ifdef MSVC
 #define INLINE __inline
@@ -22,21 +16,21 @@
 #if defined(_WIN32) || defined(__CYGWIN__)
   #ifdef open62541_EXPORTS
     #ifdef __GNUC__
-      #define UA_LIBEXPORT __attribute__ ((dllexport))
+      #define UA_EXPORT __attribute__ ((dllexport))
     #else
-      #define UA_LIBEXPORT __declspec(dllexport)
+      #define UA_EXPORT __declspec(dllexport)
     #endif
   #else
     #ifdef __GNUC__
-      #define UA_LIBEXPORT __attribute__ ((dllimport))
+      #define UA_EXPORT __attribute__ ((dllimport))
     #else
-      #define UA_LIBEXPORT __declspec(dllimport)
+      #define UA_EXPORT __declspec(dllimport)
     #endif
   #endif
 #else
   #if __GNUC__ >= 4 || __clang__
-    #define UA_LIBEXPORT __attribute__ ((visibility ("default")))
+    #define UA_EXPORT __attribute__ ((visibility ("default")))
   #else
-    #define UA_LIBEXPORT
+    #define UA_EXPORT
   #endif
 #endif

+ 2 - 2
src/ua_connection.c

@@ -1,8 +1,8 @@
 #include "ua_connection.h"
 #include "ua_util.h"
 
-UA_ConnectionConfig UA_ConnectionConfig_standard = { .protocolVersion = 0,    .sendBufferSize = 8192,
-                                                     .recvBufferSize  = 8192, .maxMessageSize = 8192,
+UA_ConnectionConfig UA_ConnectionConfig_standard = { .protocolVersion = 0,    .sendBufferSize = 65536,
+                                                     .recvBufferSize  = 65536, .maxMessageSize = 65536,
                                                      .maxChunkCount   = 1 };
 
 

+ 3 - 2
src/ua_securechannel.c

@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include "ua_securechannel.h"
 #include "ua_util.h"
+#include "ua_statuscodes.h"
 
 void UA_SecureChannel_init(UA_SecureChannel *channel) {
     UA_AsymmetricAlgorithmSecurityHeader_init(&channel->clientAsymAlgSettings);
@@ -31,8 +32,8 @@ UA_Boolean UA_SecureChannel_compare(UA_SecureChannel *sc1, UA_SecureChannel *sc2
 
 //TODO implement real nonce generator - DUMMY function
 UA_Int32 UA_SecureChannel_generateNonce(UA_ByteString *nonce) {
-    //UA_ByteString_new(&nonce);
-    UA_alloc((void ** )&nonce->data, 1);
+    if(!(nonce->data = UA_alloc(1)))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
     nonce->length  = 1;
     nonce->data[0] = 'a';
     return UA_SUCCESS;

+ 41 - 5
src/ua_session.c

@@ -3,13 +3,49 @@
 
 #include "ua_session.h"
 #include "ua_util.h"
+#include "ua_statuscodes.h"
+
+UA_Session anonymousSession = {
+    .clientDescription =  {.applicationUri = {-1, UA_NULL},
+                           .productUri = {-1, UA_NULL},
+                           .applicationName = {.locale = {-1, UA_NULL}, .text = {-1, UA_NULL}},
+                           .applicationType = UA_APPLICATIONTYPE_CLIENT,
+                           .gatewayServerUri = {-1, UA_NULL},
+                           .discoveryProfileUri = {-1, UA_NULL},
+                           .discoveryUrlsSize = -1,
+                           .discoveryUrls = UA_NULL},
+    .sessionName = {sizeof("Anonymous Session")-1, (UA_Byte*)"Anonymous Session"},
+    .authenticationToken = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0}, // is never used, as this session is not stored in the sessionmanager
+    .sessionId = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0},
+    .maxRequestMessageSize = UA_UINT32_MAX,
+    .maxResponseMessageSize = UA_UINT32_MAX,
+    .timeout = UA_INT64_MAX,
+    .validTill = UA_INT64_MAX,
+    .channel = UA_NULL};
+
+UA_Session adminSession = {
+    .clientDescription =  {.applicationUri = {-1, UA_NULL},
+                           .productUri = {-1, UA_NULL},
+                           .applicationName = {.locale = {-1, UA_NULL}, .text = {-1, UA_NULL}},
+                           .applicationType = UA_APPLICATIONTYPE_CLIENT,
+                           .gatewayServerUri = {-1, UA_NULL},
+                           .discoveryProfileUri = {-1, UA_NULL},
+                           .discoveryUrlsSize = -1,
+                           .discoveryUrls = UA_NULL},
+    .sessionName = {sizeof("Administrator Session")-1, (UA_Byte*)"Administrator Session"},
+    .authenticationToken = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 1}, // is never used, as this session is not stored in the sessionmanager
+    .sessionId = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 1},
+    .maxRequestMessageSize = UA_UINT32_MAX,
+    .maxResponseMessageSize = UA_UINT32_MAX,
+    .timeout = UA_INT64_MAX,
+    .validTill = UA_INT64_MAX,
+    .channel = UA_NULL};
 
 UA_Int32 UA_Session_new(UA_Session **session) {
-    UA_Int32 retval = UA_SUCCESS;
-    retval |= UA_alloc((void **)session, sizeof(UA_Session));
-    if(retval == UA_SUCCESS)
-        UA_Session_init(*session);
-    return retval;
+    if(!(*session = UA_alloc(sizeof(UA_Session))))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    UA_Session_init(*session);
+    return UA_SUCCESS;
 }
 
 /* mock up function to generate tokens for authentication */

+ 3 - 0
src/ua_session.h

@@ -22,6 +22,9 @@ struct UA_Session {
     UA_SecureChannel *channel;
 };
 
+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_Int32 UA_Session_new(UA_Session **session);
 void UA_Session_init(UA_Session *session);
 void UA_Session_delete(UA_Session *session);

+ 0 - 224
src/ua_statuscodes.h

@@ -1,224 +0,0 @@
-#ifndef OPCUA_STATUSCODES_H_
-#define OPCUA_STATUSCODES_H_
-
-#include "ua_types.h"
-
-static const UA_StatusCode UA_STATUSCODE_GOOD = 0x00;
-static const UA_StatusCode UA_STATUSCODE_BADUNEXPECTEDERROR = 0x80010000; // An unexpected error occurred.
-static const UA_StatusCode UA_STATUSCODE_BADINTERNALERROR = 0x80020000; // An internal error occurred as a result of a programming or configuration error.
-static const UA_StatusCode UA_STATUSCODE_BADOUTOFMEMORY = 0x80030000; // Not enough memory to complete the operation.
-static const UA_StatusCode UA_STATUSCODE_BADRESOURCEUNAVAILABLE = 0x80040000; // An operating system resource is not available.
-static const UA_StatusCode UA_STATUSCODE_BADCOMMUNICATIONERROR = 0x80050000; // A low level communication error occurred.
-static const UA_StatusCode UA_STATUSCODE_BADENCODINGERROR = 0x80060000; // Encoding halted because of invalid data in the objects being serialized.
-static const UA_StatusCode UA_STATUSCODE_BADDECODINGERROR = 0x80070000; // Decoding halted because of invalid data in the stream.
-static const UA_StatusCode UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED = 0x80080000; // The message encoding/decoding limits imposed by the stack have been exceeded.
-static const UA_StatusCode UA_STATUSCODE_BADREQUESTTOOLARGE = 0x80b80000; // The request message size exceeds limits set by the server.
-static const UA_StatusCode UA_STATUSCODE_BADRESPONSETOOLARGE = 0x80b90000; // The response message size exceeds limits set by the client.
-static const UA_StatusCode UA_STATUSCODE_BADUNKNOWNRESPONSE = 0x80090000; // An unrecognized response was received from the server.
-static const UA_StatusCode UA_STATUSCODE_BADTIMEOUT = 0x800a0000; // The operation timed out.
-static const UA_StatusCode UA_STATUSCODE_BADSERVICEUNSUPPORTED = 0x800b0000; // The server does not support the requested service.
-static const UA_StatusCode UA_STATUSCODE_BADSHUTDOWN = 0x800c0000; // The operation was cancelled because the application is shutting down.
-static const UA_StatusCode UA_STATUSCODE_BADSERVERNOTCONNECTED = 0x800d0000; // The operation could not complete because the client is not connected to the server.
-static const UA_StatusCode UA_STATUSCODE_BADSERVERHALTED = 0x800e0000; // The server has stopped and cannot process any requests.
-static const UA_StatusCode UA_STATUSCODE_BADNOTHINGTODO = 0x800f0000; // There was nothing to do because the client passed a list of operations with no elements.
-static const UA_StatusCode UA_STATUSCODE_BADTOOMANYOPERATIONS = 0x80100000; // The request could not be processed because it specified too many operations.
-static const UA_StatusCode UA_STATUSCODE_BADTOOMANYMONITOREDITEMS = 0x80db0000; // The request could not be processed because there are too many monitored items in the subscription.
-static const UA_StatusCode UA_STATUSCODE_BADDATATYPEIDUNKNOWN = 0x80110000; // The extension object cannot be (de)serialized because the data type id is not recognized.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEINVALID = 0x80120000; // The certificate provided as a parameter is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADSECURITYCHECKSFAILED = 0x80130000; // An error occurred verifying security.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATETIMEINVALID = 0x80140000; // The Certificate has expired or is not yet valid.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID = 0x80150000; // An Issuer Certificate has expired or is not yet valid.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEHOSTNAMEINVALID = 0x80160000; // The HostName used to connect to a Server does not match a HostName in the Certificate.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEURIINVALID = 0x80170000; // The URI specified in the ApplicationDescription does not match the URI in the Certificate.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED = 0x80180000; // The Certificate may not be used for the requested operation.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED = 0x80190000; // The Issuer Certificate may not be used for the requested operation.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEUNTRUSTED = 0x801a0000; // The Certificate is not trusted.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN = 0x801b0000; // It was not possible to determine if the Certificate has been revoked.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN = 0x801c0000; // It was not possible to determine if the Issuer Certificate has been revoked.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEREVOKED = 0x801d0000; // The Certificate has been revoked.
-static const UA_StatusCode UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED = 0x801e0000; // The Issuer Certificate has been revoked.
-static const UA_StatusCode UA_STATUSCODE_BADUSERACCESSDENIED = 0x801f0000; // User does not have permission to perform the requested operation.
-static const UA_StatusCode UA_STATUSCODE_BADIDENTITYTOKENINVALID = 0x80200000; // The user identity token is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADIDENTITYTOKENREJECTED = 0x80210000; // The user identity token is valid but the server has rejected it.
-static const UA_StatusCode UA_STATUSCODE_BADSECURECHANNELIDINVALID = 0x80220000; // The specified secure channel is no longer valid.
-static const UA_StatusCode UA_STATUSCODE_BADINVALIDTIMESTAMP = 0x80230000; // The timestamp is outside the range allowed by the server.
-static const UA_StatusCode UA_STATUSCODE_BADNONCEINVALID = 0x80240000; // The nonce does appear to be not a random value or it is not the correct length.
-static const UA_StatusCode UA_STATUSCODE_BADSESSIONIDINVALID = 0x80250000; // The session id is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADSESSIONCLOSED = 0x80260000; // The session was closed by the client.
-static const UA_StatusCode UA_STATUSCODE_BADSESSIONNOTACTIVATED = 0x80270000; // The session cannot be used because ActivateSession has not been called.
-static const UA_StatusCode UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID = 0x80280000; // The subscription id is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADREQUESTHEADERINVALID = 0x802a0000; // The header for the request is missing or invalid.
-static const UA_StatusCode UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID = 0x802b0000; // The timestamps to return parameter is invalid.
-static const UA_StatusCode UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT = 0x802c0000; // The request was cancelled by the client.
-static const UA_StatusCode UA_STATUSCODE_GOODSUBSCRIPTIONTRANSFERRED = 0x002d0000; // The subscription was transferred to another session.
-static const UA_StatusCode UA_STATUSCODE_GOODCOMPLETESASYNCHRONOUSLY = 0x002e0000; // The processing will complete asynchronously.
-static const UA_StatusCode UA_STATUSCODE_GOODOVERLOAD = 0x002f0000; // Sampling has slowed down due to resource limitations.
-static const UA_StatusCode UA_STATUSCODE_GOODCLAMPED = 0x00300000; // The value written was accepted but was clamped.
-static const UA_StatusCode UA_STATUSCODE_BADNOCOMMUNICATION = 0x80310000; // Communication with the data source is defined, but not established, and there is no last known value available.
-static const UA_StatusCode UA_STATUSCODE_BADWAITINGFORINITIALDATA = 0x80320000; // Waiting for the server to obtain values from the underlying data source.
-static const UA_StatusCode UA_STATUSCODE_BADNODEIDINVALID = 0x80330000; // The syntax of the node id is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADNODEIDUNKNOWN = 0x80340000; // The node id refers to a node that does not exist in the server address space.
-static const UA_StatusCode UA_STATUSCODE_BADATTRIBUTEIDINVALID = 0x80350000; // The attribute is not supported for the specified Node.
-static const UA_StatusCode UA_STATUSCODE_BADINDEXRANGEINVALID = 0x80360000; // The syntax of the index range parameter is invalid.
-static const UA_StatusCode UA_STATUSCODE_BADINDEXRANGENODATA = 0x80370000; // No data exists within the range of indexes specified.
-static const UA_StatusCode UA_STATUSCODE_BADDATAENCODINGINVALID = 0x80380000; // The data encoding is invalid.
-static const UA_StatusCode UA_STATUSCODE_BADDATAENCODINGUNSUPPORTED = 0x80390000; // The server does not support the requested data encoding for the node.
-static const UA_StatusCode UA_STATUSCODE_BADNOTREADABLE = 0x803a0000; // The access level does not allow reading or subscribing to the Node.
-static const UA_StatusCode UA_STATUSCODE_BADNOTWRITABLE = 0x803b0000; // The access level does not allow writing to the Node.
-static const UA_StatusCode UA_STATUSCODE_BADOUTOFRANGE = 0x803c0000; // The value was out of range.
-static const UA_StatusCode UA_STATUSCODE_BADNOTSUPPORTED = 0x803d0000; // The requested operation is not supported.
-static const UA_StatusCode UA_STATUSCODE_BADNOTFOUND = 0x803e0000; // A requested item was not found or a search operation ended without success.
-static const UA_StatusCode UA_STATUSCODE_BADOBJECTDELETED = 0x803f0000; // The object cannot be used because it has been deleted.
-static const UA_StatusCode UA_STATUSCODE_BADNOTIMPLEMENTED = 0x80400000; // Requested operation is not implemented.
-static const UA_StatusCode UA_STATUSCODE_BADMONITORINGMODEINVALID = 0x80410000; // The monitoring mode is invalid.
-static const UA_StatusCode UA_STATUSCODE_BADMONITOREDITEMIDINVALID = 0x80420000; // The monitoring item id does not refer to a valid monitored item.
-static const UA_StatusCode UA_STATUSCODE_BADMONITOREDITEMFILTERINVALID = 0x80430000; // The monitored item filter parameter is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED = 0x80440000; // The server does not support the requested monitored item filter.
-static const UA_StatusCode UA_STATUSCODE_BADFILTERNOTALLOWED = 0x80450000; // A monitoring filter cannot be used in combination with the attribute specified.
-static const UA_StatusCode UA_STATUSCODE_BADSTRUCTUREMISSING = 0x80460000; // A mandatory structured parameter was missing or null.
-static const UA_StatusCode UA_STATUSCODE_BADEVENTFILTERINVALID = 0x80470000; // The event filter is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADCONTENTFILTERINVALID = 0x80480000; // The content filter is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADFILTEROPERATORINVALID = 0x80c10000; // An unregognized operator was provided in a filter.
-static const UA_StatusCode UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED = 0x80c20000; // A valid operator was provided, but the server does not provide support for this filter operator.
-static const UA_StatusCode UA_STATUSCODE_BADFILTEROPERANDCOUNTMISMATCH = 0x80c30000; // The number of operands provided for the filter operator was less then expected for the operand provided.
-static const UA_StatusCode UA_STATUSCODE_BADFILTEROPERANDINVALID = 0x80490000; // The operand used in a content filter is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADFILTERELEMENTINVALID = 0x80c40000; // The referenced element is not a valid element in the content filter.
-static const UA_StatusCode UA_STATUSCODE_BADFILTERLITERALINVALID = 0x80c50000; // The referenced literal is not a valid value.
-static const UA_StatusCode UA_STATUSCODE_BADCONTINUATIONPOINTINVALID = 0x804a0000; // The continuation point provide is longer valid.
-static const UA_StatusCode UA_STATUSCODE_BADNOCONTINUATIONPOINTS = 0x804b0000; // The operation could not be processed because all continuation points have been allocated.
-static const UA_StatusCode UA_STATUSCODE_BADREFERENCETYPEIDINVALID = 0x804c0000; // The operation could not be processed because all continuation points have been allocated.
-static const UA_StatusCode UA_STATUSCODE_BADBROWSEDIRECTIONINVALID = 0x804d0000; // The browse direction is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADNODENOTINVIEW = 0x804e0000; // The node is not part of the view.
-static const UA_StatusCode UA_STATUSCODE_BADSERVERURIINVALID = 0x804f0000; // The ServerUri is not a valid URI.
-static const UA_StatusCode UA_STATUSCODE_BADSERVERNAMEMISSING = 0x80500000; // No ServerName was specified.
-static const UA_StatusCode UA_STATUSCODE_BADDISCOVERYURLMISSING = 0x80510000; // No DiscoveryUrl was specified.
-static const UA_StatusCode UA_STATUSCODE_BADSEMPAHOREFILEMISSING = 0x80520000; // The semaphore file specified by the client is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADREQUESTTYPEINVALID = 0x80530000; // The security token request type is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADSECURITYMODEREJECTED = 0x80540000; // The security mode does not meet the requirements set by the Server.
-static const UA_StatusCode UA_STATUSCODE_BADSECURITYPOLICYREJECTED = 0x80550000; // The security policy does not meet the requirements set by the Server.
-static const UA_StatusCode UA_STATUSCODE_BADTOOMANYSESSIONS = 0x80560000; // The server has reached its maximum number of sessions.
-static const UA_StatusCode UA_STATUSCODE_BADUSERSIGNATUREINVALID = 0x80570000; // The user token signature is missing or invalid.
-static const UA_StatusCode UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID = 0x80580000; // The signature generated with the client certificate is missing or invalid.
-static const UA_StatusCode UA_STATUSCODE_BADNOVALIDCERTIFICATES = 0x80590000; // The client did not provide at least one software certificate that is valid and meets the profile requirements for the server.
-static const UA_StatusCode UA_STATUSCODE_BADIDENTITYCHANGENOTSUPPORTED = 0x80c60000; // The Server does not support changing the user identity assigned to the session.
-static const UA_StatusCode UA_STATUSCODE_BADREQUESTCANCELLEDBYREQUEST = 0x805a0000; // The request was cancelled by the client with the Cancel service.
-static const UA_StatusCode UA_STATUSCODE_BADPARENTNODEIDINVALID = 0x805b0000; // The parent node id does not to refer to a valid node.
-static const UA_StatusCode UA_STATUSCODE_BADREFERENCENOTALLOWED = 0x805c0000; // The reference could not be created because it violates constraints imposed by the data model.
-static const UA_StatusCode UA_STATUSCODE_BADNODEIDREJECTED = 0x805d0000; // The requested node id was reject because it was either invalid or server does not allow node ids to be specified by the client.
-static const UA_StatusCode UA_STATUSCODE_BADNODEIDEXISTS = 0x805e0000; // The requested node id is already used by another node.
-static const UA_StatusCode UA_STATUSCODE_BADNODECLASSINVALID = 0x805f0000; // The node class is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADBROWSENAMEINVALID = 0x80600000; // The browse name is invalid.
-static const UA_StatusCode UA_STATUSCODE_BADBROWSENAMEDUPLICATED = 0x80610000; // The browse name is not unique among nodes that share the same relationship with the parent.
-static const UA_StatusCode UA_STATUSCODE_BADNODEATTRIBUTESINVALID = 0x80620000; // The node attributes are not valid for the node class.
-static const UA_StatusCode UA_STATUSCODE_BADTYPEDEFINITIONINVALID = 0x80630000; // The type definition node id does not reference an appropriate type node.
-static const UA_StatusCode UA_STATUSCODE_BADSOURCENODEIDINVALID = 0x80640000; // The source node id does not reference a valid node.
-static const UA_StatusCode UA_STATUSCODE_BADTARGETNODEIDINVALID = 0x80650000; // The target node id does not reference a valid node.
-static const UA_StatusCode UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED = 0x80660000; // The reference type between the nodes is already defined.
-static const UA_StatusCode UA_STATUSCODE_BADINVALIDSELFREFERENCE = 0x80670000; // The server does not allow this type of self reference on this node.
-static const UA_StatusCode UA_STATUSCODE_BADREFERENCELOCALONLY = 0x80680000; // The reference type is not valid for a reference to a remote server.
-static const UA_StatusCode UA_STATUSCODE_BADNODELETERIGHTS = 0x80690000; // The server will not allow the node to be deleted.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINREFERENCENOTDELETED = 0x40bc0000; // The server was not able to delete all target references.
-static const UA_StatusCode UA_STATUSCODE_BADSERVERINDEXINVALID = 0x806a0000; // The server index is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADVIEWIDUNKNOWN = 0x806b0000; // The view id does not refer to a valid view node.
-static const UA_StatusCode UA_STATUSCODE_BADVIEWTIMESTAMPINVALID = 0x80c90000; // The view timestamp is not available or not supported.
-static const UA_StatusCode UA_STATUSCODE_BADVIEWPARAMETERMISMATCH = 0x80ca0000; // The view parameters are not consistent with each other.
-static const UA_StatusCode UA_STATUSCODE_BADVIEWVERSIONINVALID = 0x80cb0000; // The view version is not available or not supported.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINNOTALLNODESAVAILABLE = 0x40c00000; // The list of references may not be complete because the underlying system is not available.
-static const UA_StatusCode UA_STATUSCODE_GOODRESULTSMAYBEINCOMPLETE = 0x00ba0000; // The server should have followed a reference to a node in a remote server but did not. The result set may be incomplete.
-static const UA_StatusCode UA_STATUSCODE_BADNOTTYPEDEFINITION = 0x80c80000; // The provided Nodeid was not a type definition nodeid.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINREFERENCEOUTOFSERVER = 0x406c0000; // One of the references to follow in the relative path references to a node in the address space in another server.
-static const UA_StatusCode UA_STATUSCODE_BADTOOMANYMATCHES = 0x806d0000; // The requested operation has too many matches to return.
-static const UA_StatusCode UA_STATUSCODE_BADQUERYTOOCOMPLEX = 0x806e0000; // The requested operation requires too many resources in the server.
-static const UA_StatusCode UA_STATUSCODE_BADNOMATCH = 0x806f0000; // The requested operation has no match to return.
-static const UA_StatusCode UA_STATUSCODE_BADMAXAGEINVALID = 0x80700000; // The max age parameter is invalid.
-static const UA_StatusCode UA_STATUSCODE_BADHISTORYOPERATIONINVALID = 0x80710000; // The history details parameter is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED = 0x80720000; // The server does not support the requested operation.
-static const UA_StatusCode UA_STATUSCODE_BADINVALIDTIMESTAMPARGUMENT = 0x80bd0000; // The defined timestamp to return was invalid.
-static const UA_StatusCode UA_STATUSCODE_BADWRITENOTSUPPORTED = 0x80730000; // The server not does support writing the combination of value, status and timestamps provided.
-static const UA_StatusCode UA_STATUSCODE_BADTYPEMISMATCH = 0x80740000; // The value supplied for the attribute is not of the same type as the attribute's value.
-static const UA_StatusCode UA_STATUSCODE_BADMETHODINVALID = 0x80750000; // The method id does not refer to a method for the specified object.
-static const UA_StatusCode UA_STATUSCODE_BADARGUMENTSMISSING = 0x80760000; // The client did not specify all of the input arguments for the method.
-static const UA_StatusCode UA_STATUSCODE_BADTOOMANYSUBSCRIPTIONS = 0x80770000; // The server has reached its  maximum number of subscriptions.
-static const UA_StatusCode UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS = 0x80780000; // The server has reached the maximum number of queued publish requests.
-static const UA_StatusCode UA_STATUSCODE_BADNOSUBSCRIPTION = 0x80790000; // There is no subscription available for this session.
-static const UA_StatusCode UA_STATUSCODE_BADSEQUENCENUMBERUNKNOWN = 0x807a0000; // The sequence number is unknown to the server.
-static const UA_StatusCode UA_STATUSCODE_BADMESSAGENOTAVAILABLE = 0x807b0000; // The requested notification message is no longer available.
-static const UA_StatusCode UA_STATUSCODE_BADINSUFFICIENTCLIENTPROFILE = 0x807c0000; // The Client of the current Session does not support one or more Profiles that are necessary for the Subscription.
-static const UA_StatusCode UA_STATUSCODE_BADSTATENOTACTIVE = 0x80bf0000; // The sub-state machine is not currently active.
-static const UA_StatusCode UA_STATUSCODE_BADTCPSERVERTOOBUSY = 0x807d0000; // The server cannot process the request because it is too busy.
-static const UA_StatusCode UA_STATUSCODE_BADTCPMESSAGETYPEINVALID = 0x807e0000; // The type of the message specified in the header invalid.
-static const UA_StatusCode UA_STATUSCODE_BADTCPSECURECHANNELUNKNOWN = 0x807f0000; // The SecureChannelId and/or TokenId are not currently in use.
-static const UA_StatusCode UA_STATUSCODE_BADTCPMESSAGETOOLARGE = 0x80800000; // The size of the message specified in the header is too large.
-static const UA_StatusCode UA_STATUSCODE_BADTCPNOTENOUGHRESOURCES = 0x80810000; // There are not enough resources to process the request.
-static const UA_StatusCode UA_STATUSCODE_BADTCPINTERNALERROR = 0x80820000; // An internal error occurred.
-static const UA_StatusCode UA_STATUSCODE_BADTCPENDPOINTURLINVALID = 0x80830000; // The Server does not recognize the QueryString specified.
-static const UA_StatusCode UA_STATUSCODE_BADREQUESTINTERRUPTED = 0x80840000; // The request could not be sent because of a network interruption.
-static const UA_StatusCode UA_STATUSCODE_BADREQUESTTIMEOUT = 0x80850000; // Timeout occurred while processing the request.
-static const UA_StatusCode UA_STATUSCODE_BADSECURECHANNELCLOSED = 0x80860000; // The secure channel has been closed.
-static const UA_StatusCode UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN = 0x80870000; // The token has expired or is not recognized.
-static const UA_StatusCode UA_STATUSCODE_BADSEQUENCENUMBERINVALID = 0x80880000; // The sequence number is not valid.
-static const UA_StatusCode UA_STATUSCODE_BADPROTOCOLVERSIONUNSUPPORTED = 0x80be0000; // The applications do not have compatible protocol versions.
-static const UA_StatusCode UA_STATUSCODE_BADCONFIGURATIONERROR = 0x80890000; // There is a problem with the configuration that affects the usefulness of the value.
-static const UA_StatusCode UA_STATUSCODE_BADNOTCONNECTED = 0x808a0000; // The variable should receive its value from another variable, but has never been configured to do so.
-static const UA_StatusCode UA_STATUSCODE_BADDEVICEFAILURE = 0x808b0000; // There has been a failure in the device/data source that generates the value that has affected the value.
-static const UA_StatusCode UA_STATUSCODE_BADSENSORFAILURE = 0x808c0000; // There has been a failure in the sensor from which the value is derived by the device/data source.
-static const UA_StatusCode UA_STATUSCODE_BADOUTOFSERVICE = 0x808d0000; // The source of the data is not operational.
-static const UA_StatusCode UA_STATUSCODE_BADDEADBANDFILTERINVALID = 0x808e0000; // The deadband filter is not valid.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINNOCOMMUNICATIONLASTUSABLEVALUE = 0x408f0000; // Communication to the data source has failed. The variable value is the last value that had a good quality.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINLASTUSABLEVALUE = 0x40900000; // Whatever was updating this value has stopped doing so.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINSUBSTITUTEVALUE = 0x40910000; // The value is an operational value that was manually overwritten.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAININITIALVALUE = 0x40920000; // The value is an initial value for a variable that normally receives its value from another variable.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINSENSORNOTACCURATE = 0x40930000; // The value is at one of the sensor limits.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINENGINEERINGUNITSEXCEEDED = 0x40940000; // The value is outside of the range of values defined for this parameter.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINSUBNORMAL = 0x40950000; // The value is derived from multiple sources and has less than the required number of Good sources.
-static const UA_StatusCode UA_STATUSCODE_GOODLOCALOVERRIDE = 0x00960000; // The value has been overridden.
-static const UA_StatusCode UA_STATUSCODE_BADREFRESHINPROGRESS = 0x80970000; // This Condition refresh failed, a Condition refresh operation is already in progress.
-static const UA_StatusCode UA_STATUSCODE_BADCONDITIONALREADYDISABLED = 0x80980000; // This condition has already been disabled.
-static const UA_StatusCode UA_STATUSCODE_BADCONDITIONALREADYENABLED = 0x80cc0000; // This condition has already been enabled.
-static const UA_StatusCode UA_STATUSCODE_BADCONDITIONDISABLED = 0x80990000; // Property not available, this condition is disabled.
-static const UA_StatusCode UA_STATUSCODE_BADEVENTIDUNKNOWN = 0x809a0000; // The specified event id is not recognized.
-static const UA_StatusCode UA_STATUSCODE_BADEVENTNOTACKNOWLEDGEABLE = 0x80bb0000; // The event cannot be acknowledged.
-static const UA_StatusCode UA_STATUSCODE_BADDIALOGNOTACTIVE = 0x80cd0000; // The dialog condition is not active.
-static const UA_StatusCode UA_STATUSCODE_BADDIALOGRESPONSEINVALID = 0x80ce0000; // The response is not valid for the dialog.
-static const UA_StatusCode UA_STATUSCODE_BADCONDITIONBRANCHALREADYACKED = 0x80cf0000; // The condition branch has already been acknowledged.
-static const UA_StatusCode UA_STATUSCODE_BADCONDITIONBRANCHALREADYCONFIRMED = 0x80d00000; // The condition branch has already been confirmed.
-static const UA_StatusCode UA_STATUSCODE_BADCONDITIONALREADYSHELVED = 0x80d10000; // The condition has already been shelved.
-static const UA_StatusCode UA_STATUSCODE_BADCONDITIONNOTSHELVED = 0x80d20000; // The condition is not currently shelved.
-static const UA_StatusCode UA_STATUSCODE_BADSHELVINGTIMEOUTOFRANGE = 0x80d30000; // The shelving time not within an acceptable range.
-static const UA_StatusCode UA_STATUSCODE_BADNODATA = 0x809b0000; // No data exists for the requested time range or event filter.
-static const UA_StatusCode UA_STATUSCODE_BADBOUNDNOTFOUND = 0x80d70000; // No data found to provide upper or lower bound value.
-static const UA_StatusCode UA_STATUSCODE_BADBOUNDNOTSUPPORTED = 0x80d80000; // The server cannot retrieve a bound for the variable.
-static const UA_StatusCode UA_STATUSCODE_BADDATALOST = 0x809d0000; // Data is missing due to collection started/stopped/lost.
-static const UA_StatusCode UA_STATUSCODE_BADDATAUNAVAILABLE = 0x809e0000; // Expected data is unavailable for the requested time range due to an un-mounted volume, an off-line archive or tape, or similar reason for temporary unavailability.
-static const UA_StatusCode UA_STATUSCODE_BADENTRYEXISTS = 0x809f0000; // The data or event was not successfully inserted because a matching entry exists.
-static const UA_StatusCode UA_STATUSCODE_BADNOENTRYEXISTS = 0x80a00000; // The data or event was not successfully updated because no matching entry exists.
-static const UA_StatusCode UA_STATUSCODE_BADTIMESTAMPNOTSUPPORTED = 0x80a10000; // The client requested history using a timestamp format the server does not support (i.e requested ServerTimestamp when server only supports SourceTimestamp).
-static const UA_StatusCode UA_STATUSCODE_GOODENTRYINSERTED = 0x00a20000; // The data or event was successfully inserted into the historical database.
-static const UA_StatusCode UA_STATUSCODE_GOODENTRYREPLACED = 0x00a30000; // The data or event field was successfully replaced in the historical database.
-static const UA_StatusCode UA_STATUSCODE_UNCERTAINDATASUBNORMAL = 0x40a40000; // The value is derived from multiple values and has less than the required number of Good values.
-static const UA_StatusCode UA_STATUSCODE_GOODNODATA = 0x00a50000; // No data exists for the requested time range or event filter.
-static const UA_StatusCode UA_STATUSCODE_GOODMOREDATA = 0x00a60000; // The data or event field was successfully replaced in the historical database.
-static const UA_StatusCode UA_STATUSCODE_BADAGGREGATELISTMISMATCH = 0x80d40000; // The requested number of Aggregates does not match the requested number of NodeIds.
-static const UA_StatusCode UA_STATUSCODE_BADAGGREGATENOTSUPPORTED = 0x80d50000; // The requested Aggregate is not support by the server.
-static const UA_StatusCode UA_STATUSCODE_BADAGGREGATEINVALIDINPUTS = 0x80d60000; // The aggregate value could not be derived due to invalid data inputs.
-static const UA_StatusCode UA_STATUSCODE_BADAGGREGATECONFIGURATIONREJECTED = 0x80da0000; // The aggregate configuration is not valid for specified node.
-static const UA_StatusCode UA_STATUSCODE_GOODDATAIGNORED = 0x00d90000; // The request pecifies fields which are not valid for the EventType or cannot be saved by the historian.
-static const UA_StatusCode UA_STATUSCODE_GOODCOMMUNICATIONEVENT = 0x00a70000; // The communication layer has raised an event.
-static const UA_StatusCode UA_STATUSCODE_GOODSHUTDOWNEVENT = 0x00a80000; // The system is shutting down.
-static const UA_StatusCode UA_STATUSCODE_GOODCALLAGAIN = 0x00a90000; // The operation is not finished and needs to be called again.
-static const UA_StatusCode UA_STATUSCODE_GOODNONCRITICALTIMEOUT = 0x00aa0000; // A non-critical timeout occurred.
-static const UA_StatusCode UA_STATUSCODE_BADINVALIDARGUMENT = 0x80ab0000; // One or more arguments are invalid.
-static const UA_StatusCode UA_STATUSCODE_BADCONNECTIONREJECTED = 0x80ac0000; // Could not establish a network connection to remote server.
-static const UA_StatusCode UA_STATUSCODE_BADDISCONNECT = 0x80ad0000; // The server has disconnected from the client.
-static const UA_StatusCode UA_STATUSCODE_BADCONNECTIONCLOSED = 0x80ae0000; // The network connection has been closed.
-static const UA_StatusCode UA_STATUSCODE_BADINVALIDSTATE = 0x80af0000; // The operation cannot be completed because the object is closed, uninitialized or in some other invalid state.
-static const UA_StatusCode UA_STATUSCODE_BADENDOFSTREAM = 0x80b00000; // Cannot move beyond end of the stream.
-static const UA_StatusCode UA_STATUSCODE_BADNODATAAVAILABLE = 0x80b10000; // No data is currently available for reading from a non-blocking stream.
-static const UA_StatusCode UA_STATUSCODE_BADWAITINGFORRESPONSE = 0x80b20000; // The asynchronous operation is waiting for a response.
-static const UA_StatusCode UA_STATUSCODE_BADOPERATIONABANDONED = 0x80b30000; // The asynchronous operation was abandoned by the caller.
-static const UA_StatusCode UA_STATUSCODE_BADEXPECTEDSTREAMTOBLOCK = 0x80b40000; // The stream did not return all data requested (possibly because it is a non-blocking stream).
-static const UA_StatusCode UA_STATUSCODE_BADWOULDBLOCK = 0x80b50000; // Non blocking behaviour is required and the operation would block.
-static const UA_StatusCode UA_STATUSCODE_BADSYNTAXERROR = 0x80b60000; // A value had an invalid syntax.
-static const UA_StatusCode UA_STATUSCODE_BADMAXCONNECTIONSREACHED = 0x80b70000; // The operation could not be finished because all available connections are in use.
-
-#endif /* OPCUA_STATUSCODES_H_ */

+ 2 - 2
src/ua_transport.c

@@ -36,8 +36,8 @@ UA_Int32 UA_MessageType_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset
 }
 
 #ifdef DEBUG
-void UA_MessageType_printf(char *label, UA_MessageType *p) {
+void UA_MessageType_print(const UA_MessageType *p, FILE *stream) {
     UA_Byte *b = (UA_Byte *)p;
-    printf("%s{%c%c%c}\n", label, b[2], b[1], b[0]);
+    fprintf(stream, "%c%c%c", b[2], b[1], b[0]);
 }
 #endif

+ 0 - 3
src/ua_transport.h

@@ -27,9 +27,6 @@ enum UA_MessageType {
 };
 UA_TYPE_PROTOTYPES(UA_MessageType)
 UA_TYPE_BINARY_ENCODING(UA_MessageType)
-#ifdef DEBUG
-void UA_MessageType_printf(char *label, UA_MessageType *p);
-#endif
 
 /* All other transport types are auto-generated from a schema definition. */
 

+ 42 - 32
src/ua_types.c

@@ -8,13 +8,14 @@
 #endif
 
 #ifdef DEBUG
-#include <stdio.h>
+#include <inttypes.h>
 #endif
 
 #include "ua_util.h"
 #include "ua_types.h"
 #include "ua_types_encoding_binary.h"
 #include "ua_namespace_0.h"
+#include "ua_statuscodes.h"
 
 /* Boolean */
 void UA_Boolean_init(UA_Boolean *p) {
@@ -143,16 +144,14 @@ void UA_String_deleteMembers(UA_String *p) {
 }
 
 UA_Int32 UA_String_copy(UA_String const *src, UA_String *dst) {
-    UA_Int32 retval = UA_SUCCESS;
     if(!src || !dst) return UA_ERROR;
     if(src->length > 0) {
-        retval |= UA_alloc((void **)&dst->data, src->length);
-        if(retval != UA_SUCCESS)
-            return retval;
+        if(!(dst->data = UA_alloc(src->length)))
+            return UA_STATUSCODE_BADOUTOFMEMORY;
         UA_memcpy((void *)dst->data, src->data, src->length);
     }
     dst->length = src->length;
-    return retval;
+    return UA_SUCCESS;
 }
 
 #ifdef DEBUG
@@ -167,15 +166,14 @@ void UA_String_print(const UA_String *p, FILE *stream) {
 #endif
 
 UA_Int32 UA_String_copycstring(char const *src, UA_String *dst) {
-    UA_Int32 retval = UA_SUCCESS;
-    dst->length = strlen(src);
     dst->data   = UA_NULL;
+    dst->length = strlen(src);
     if(dst->length > 0) {
-        retval |= UA_alloc((void **)&dst->data, dst->length);
-        if(retval == UA_SUCCESS)
-            UA_memcpy((void *)dst->data, src, dst->length);
+        if(!(dst->data = UA_alloc(dst->length)))
+            return UA_STATUSCODE_BADOUTOFMEMORY;
+        UA_memcpy((void *)dst->data, src, dst->length);
     }
-    return retval;
+    return UA_SUCCESS;
 }
 
 #define UA_STRING_COPYPRINTF_BUFSIZE 1024
@@ -198,9 +196,10 @@ UA_Int32 UA_String_copyprintf(char const *fmt, UA_String *dst, ...) {
     } else {
         // since glibc 2.1 vsnprintf returns len that would have resulted if buf were large enough
         dst->length = ( len > UA_STRING_COPYPRINTF_BUFSIZE ? UA_STRING_COPYPRINTF_BUFSIZE : len );
-        retval     |= UA_alloc((void **)&dst->data, dst->length);
-        if(retval == UA_SUCCESS)
+        if((dst->data = UA_alloc(dst->length)))
             UA_memcpy((void *)dst->data, src, dst->length);
+        else
+            retval = UA_STATUSCODE_BADOUTOFMEMORY;
     }
     return retval;
 }
@@ -314,9 +313,13 @@ UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime time) {
 }
 
 UA_Int32 UA_DateTime_toString(UA_DateTime time, UA_String *timeString) {
-    char *charBuf = (char *)(*timeString).data;
+    // length of the string is 31 (incl. \0 at the end)
+    if(!(timeString->data = UA_alloc(31)))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+    timeString->length = 30;
+
     UA_DateTimeStruct tSt = UA_DateTime_toStruct(time);
-    sprintf(charBuf, "%2d/%2d/%4d %2d:%2d:%2d.%3d.%3d.%3d", tSt.mounth, tSt.day, tSt.year,
+    sprintf((char*)timeString->data, "%2d/%2d/%4d %2d:%2d:%2d.%3d.%3d.%3d", tSt.mounth, tSt.day, tSt.year,
             tSt.hour, tSt.min, tSt.sec, tSt.milliSec, tSt.microSec, tSt.nanoSec);
     return UA_SUCCESS;
 }
@@ -386,12 +389,15 @@ UA_ByteString UA_ByteString_securityPoliceNone =
 
 UA_Int32 UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length) {
     UA_Int32 retval = UA_SUCCESS;
-    if(length > 0 && (retval |= UA_alloc((void **)&p->data, length)) == UA_SUCCESS)
-        p->length = length;
-    else {
-        p->length = -1;
-        p->data   = UA_NULL;
+    if(length > 0) {
+        if((p->data = UA_alloc(length))) {
+            p->length = length;
+            return retval;
+        }
+        retval = UA_STATUSCODE_BADOUTOFMEMORY;
     }
+    p->length = -1;
+    p->data   = UA_NULL;
     return retval;
 }
 
@@ -490,7 +496,7 @@ void UA_NodeId_print(const UA_NodeId *p, FILE *stream) {
         break;
     }
     fprintf(stream, ",%u,", p->namespaceIndex);
-    switch(p->identifierType & UA_NODEIDTYPE_MASK) {
+    switch(p->identifierType) {
     case UA_NODEIDTYPE_NUMERIC:
         fprintf(stream, ".identifier.numeric=%u", p->identifier.numeric);
         break;
@@ -905,18 +911,23 @@ UA_Int32 UA_Variant_copySetArray(UA_Variant *v, const UA_VTable_Entry *vt, UA_In
 void UA_Variant_print(const UA_Variant *p, FILE *stream) {
     if(p == UA_NULL || stream == UA_NULL) return;
     UA_UInt32 ns0id = UA_ns0ToVTableIndex(&p->vt->typeId);
+    if(p->storageType == UA_VARIANT_DATASOURCE) {
+        fprintf(stream, "Variant from a Datasource");
+        return;
+    }
     fprintf(stream, "(UA_Variant){/*%s*/", p->vt->name);
     if(p->vt == &UA_[ns0id])
         fprintf(stream, "UA_[%d]", ns0id);
     else
         fprintf(stream, "ERROR (not a builtin type)");
-    UA_Int32_print(&p->arrayLength, stream);
+    UA_Int32_print(&p->storage.data.arrayLength, stream);
     fprintf(stream, ",");
-    UA_Array_print(p->data, p->arrayLength, p->vt, stream);
+    UA_Array_print(p->storage.data.dataPtr, p->storage.data.arrayLength, p->vt, stream);
     fprintf(stream, ",");
-    UA_Int32_print(&p->arrayDimensionsLength, stream);
+    UA_Int32_print(&p->storage.data.arrayDimensionsLength, stream);
     fprintf(stream, ",");
-    UA_Array_print(p->arrayDimensions, p->arrayDimensionsLength, &UA_[UA_INT32], stream);
+    UA_Array_print(p->storage.data.arrayDimensions, p->storage.data.arrayDimensionsLength,
+                   &UA_[UA_INT32], stream);
     fprintf(stream, "}");
 }
 #endif
@@ -952,9 +963,10 @@ UA_Int32 UA_DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo
     retval |= UA_Byte_copy(&src->encodingMask, &dst->encodingMask);
     retval |= UA_StatusCode_copy(&src->innerStatusCode, &dst->innerStatusCode);
     if(src->innerDiagnosticInfo) {
-        retval |= UA_alloc((void **)&dst->innerDiagnosticInfo, sizeof(UA_DiagnosticInfo));
-        if(retval == UA_SUCCESS)
+        if((dst->innerDiagnosticInfo = UA_alloc(sizeof(UA_DiagnosticInfo))))
             retval |= UA_DiagnosticInfo_copy(src->innerDiagnosticInfo, dst->innerDiagnosticInfo);
+        else
+            retval |= UA_STATUSCODE_BADOUTOFMEMORY;
     } else
         dst->innerDiagnosticInfo = UA_NULL;
     retval |= UA_Int32_copy(&src->locale, &dst->locale);
@@ -1040,10 +1052,8 @@ UA_Int32 UA_Array_new(void **p, UA_Int32 noElements, const UA_VTable_Entry *vt)
         return UA_ERROR;
     }
 
-    UA_Int32 retval = UA_SUCCESS;
-    retval = UA_alloc(p, vt->memSize * noElements);
-    if(retval != UA_SUCCESS)
-        return retval;
+    if(!(*p = UA_alloc(vt->memSize * noElements)))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
 
     UA_Array_init(*p, noElements, vt);
     return UA_SUCCESS;

+ 24 - 19
src/ua_types_encoding_binary.c

@@ -1,6 +1,7 @@
 #include "ua_types_encoding_binary.h"
 #include "ua_util.h"
 #include "ua_namespace_0.h"
+#include "ua_statuscodes.h"
 
 static INLINE UA_Boolean is_builtin(const UA_NodeId *typeid ) {
     return typeid ->namespaceIndex == 0 && 1 <= typeid ->identifier.numeric && typeid ->identifier.numeric <=
@@ -341,22 +342,24 @@ UA_Int32 UA_String_encodeBinary(UA_String const *src, UA_ByteString *dst, UA_UIn
     return retval;
 }
 UA_Int32 UA_String_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_String *dst) {
-    UA_Int32 retval = UA_SUCCESS;
     UA_String_init(dst);
-    retval |= UA_Int32_decodeBinary(src, offset, &dst->length);
+    UA_Int32 length;
+    if(UA_Int32_decodeBinary(src, offset, &length) != UA_SUCCESS)
+        return UA_ERROR;
 
-    if(dst->length > (UA_Int32)(src->length - *offset))
-        retval = UA_ERR_INVALID_VALUE;
+    if(length <= 0)
+        return UA_SUCCESS;
+        
+    if(length > (UA_Int32)(src->length - *offset))
+        return UA_ERR_INVALID_VALUE;
+    
+    if(!(dst->data = UA_alloc(length)))
+        return UA_STATUSCODE_BADOUTOFMEMORY;
 
-    if(retval != UA_SUCCESS || dst->length <= 0) {
-        dst->length = -1;
-        dst->data   = UA_NULL;
-    } else {
-        CHECKED_DECODE(UA_alloc((void **)&dst->data, dst->length), dst->length = -1);
-        UA_memcpy(dst->data, &src->data[*offset], dst->length);
-        *offset += dst->length;
-    }
-    return retval;
+    UA_memcpy(dst->data, &src->data[*offset], length);
+    dst->length = length;
+    *offset += length;
+    return UA_SUCCESS;
 }
 
 /* DateTime */
@@ -922,7 +925,7 @@ UA_TYPE_ENCODEBINARY(UA_Variant,
                      
                      )
 
-/* For decoding, we read extensionobects as is. The resulting variant always has the storagetype UA_VARIANT_DATA. */
+/* For decoding, we read extensionobjects as is. The resulting variant always has the storagetype UA_VARIANT_DATA. */
 UA_Int32 UA_Variant_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA_Variant *dst) {
     UA_Int32 retval = UA_SUCCESS;
     UA_Variant_init(dst);
@@ -941,7 +944,8 @@ UA_Int32 UA_Variant_decodeBinary(UA_ByteString const *src, UA_UInt32 *offset, UA
     dst->vt = &UA_[typeNs0Id];
 
     if(!isArray) {
-        if(UA_alloc(&data->dataPtr, dst->vt->memSize) != UA_SUCCESS) return UA_ERROR;
+        if(!(data->dataPtr = UA_alloc(dst->vt->memSize)))
+            return UA_STATUSCODE_BADOUTOFMEMORY;
         retval |= dst->vt->encodings[UA_ENCODING_BINARY].decode(src, offset, data->dataPtr);
         if(retval != UA_SUCCESS) {
             UA_free(data->dataPtr);
@@ -1051,10 +1055,11 @@ UA_Int32 UA_DiagnosticInfo_decodeBinary(UA_ByteString const *src, UA_UInt32 *off
 
         case UA_DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO:
             // innerDiagnosticInfo is a pointer to struct, therefore allocate
-            CHECKED_DECODE(UA_alloc((void **)&dst->innerDiagnosticInfo,
-                                    UA_DiagnosticInfo_calcSizeBinary(UA_NULL)),; );
-            CHECKED_DECODE(UA_DiagnosticInfo_decodeBinary(src, offset,
-                                                          dst->innerDiagnosticInfo),
+            if(!(dst->innerDiagnosticInfo = UA_alloc(sizeof(UA_DiagnosticInfo)))) {
+                retval |= UA_STATUSCODE_BADOUTOFMEMORY;
+                return retval;
+            }
+            CHECKED_DECODE(UA_DiagnosticInfo_decodeBinary(src, offset, dst->innerDiagnosticInfo),
                            UA_DiagnosticInfo_deleteMembers(dst));
             break;
         }

+ 6 - 2
src/ua_util.c

@@ -3,6 +3,10 @@
 /* the extern inline in a *.c-file is required for other compilation units to
    see the inline function. */
 extern INLINE UA_Int32 _UA_free(void *ptr, char *pname, char *f, UA_Int32 l);
-extern INLINE UA_Int32 _UA_alloc(void **ptr, UA_Int32 size, char *pname, char *sname, char *f, UA_Int32 l);
-extern INLINE UA_Int32 _UA_alloca(void **ptr, UA_Int32 size, char *pname, char *sname, char *f, UA_Int32 l);
 extern INLINE void UA_memcpy(void *dst, void const *src, UA_Int32 size);
+
+#ifdef DEBUG
+extern INLINE void * _UA_alloc(UA_Int32 size, char *file, UA_Int32 line);
+#else
+extern INLINE void * _UA_alloc(UA_Int32 size);
+#endif

+ 14 - 35
src/ua_util.h

@@ -7,13 +7,6 @@
 #include <assert.h> // assert
 
 #include "ua_config.h"
-#ifndef MSVC
-#ifndef WIN32
-#include <alloca.h> // alloca
-#else
-#include <malloc.h> // MinGW alloca
-#endif
-#endif
 
 #include <stddef.h> /* Needed for sys/queue.h */
 #ifndef MSVC
@@ -39,50 +32,36 @@
 # endif
 #endif
 
+#ifdef DEBUG
 #define UA_assert(ignore) assert(ignore)
+#else
+#define UA_assert(ignore)
+#endif
 
 /* Heap memory functions */
+#define UA_free(ptr) _UA_free(ptr, # ptr, __FILE__, __LINE__)
 INLINE UA_Int32 _UA_free(void *ptr, char *pname, char *f, UA_Int32 l) {
     DBG_VERBOSE(printf("UA_free;%p;;%s;;%s;%d\n", ptr, pname, f, l); fflush(stdout));
     free(ptr); // checks if ptr != NULL in the background
     return UA_SUCCESS;
 }
 
-INLINE UA_Int32 _UA_alloc(void **ptr, UA_Int32 size, char *pname, char *sname, char *f, UA_Int32 l) {
-    if(ptr == UA_NULL)
-        return UA_ERR_INVALID_VALUE;
-    *ptr = malloc(size);
-    DBG_VERBOSE(printf("UA_alloc - %p;%d;%s;%s;%s;%d\n", *ptr, size, pname, sname, f, l); fflush(stdout));
-    if(*ptr == UA_NULL)
-        return UA_ERR_NO_MEMORY;
-    return UA_SUCCESS;
+#ifdef DEBUG
+#define UA_alloc(size) _UA_alloc(size, __FILE__, __LINE__) 
+INLINE void * _UA_alloc(UA_Int32 size, char *file, UA_Int32 line) {
+    DBG_VERBOSE(printf("UA_alloc - %d;%s;%d\n", size, file, line); fflush(stdout));
+    return malloc(size);
 }
-
-INLINE UA_Int32 _UA_alloca(void **ptr, UA_Int32 size, char *pname, char *sname, char *f, UA_Int32 l) {
-    if(ptr == UA_NULL)
-        return UA_ERR_INVALID_VALUE;
-#ifdef MSVC
-    *ptr = _alloca(size);
 #else
-    *ptr = alloca(size);
-#endif
-    DBG_VERBOSE(printf("UA_alloca - %p;%d;%s;%s;%s;%d\n", *ptr, size, pname, sname, f, l); fflush(stdout));
-    return UA_SUCCESS;
+#define UA_alloc(size) _UA_alloc(size) 
+INLINE void * _UA_alloc(UA_Int32 size) {
+    return malloc(size);
 }
+#endif
 
 INLINE void UA_memcpy(void *dst, void const *src, UA_Int32 size) {
     DBG_VERBOSE(printf("UA_memcpy - %p;%p;%d\n", dst, src, size));
     memcpy(dst, src, size);
 }
 
-#define UA_free(ptr) _UA_free(ptr, # ptr, __FILE__, __LINE__)
-#define UA_alloc(ptr, size) _UA_alloc(ptr, size, # ptr, # size, __FILE__, __LINE__)
-
-/** @brief UA_alloca assigns memory on the stack instead of the heap. It is a
-    very fast alternative to standard malloc. The memory is automatically
-    returned ('freed') when the current function returns. Use this only for
-    small temporary values. For more than 100Byte, it is more reasonable to use
-    proper UA_alloc. */
-#define UA_alloca(ptr, size) _UA_alloca(ptr, size, # ptr, # size, __FILE__, __LINE__)
-
 #endif /* UA_UTIL_H_ */

+ 8 - 5
tests/CMakeLists.txt

@@ -1,7 +1,7 @@
 find_package(Check REQUIRED)
 find_package(Threads REQUIRED)
 
-set(LIBS open62541 ${CHECK_LIBRARIES} m)
+set(LIBS ${CHECK_LIBRARIES})
 if(NOT WIN32)
     list(APPEND LIBS rt pthread)
 endif(NOT WIN32)
@@ -9,11 +9,14 @@ if(ENABLE_MULTITHREADING)
     list(APPEND LIBS urcu-cds urcu)
 endif(ENABLE_MULTITHREADING)
 
-add_executable(check_builtin check_builtin.c)
+# the unit test are built directly on the open62541 object files. so they can
+# access symbols that are hidden/not exported to the shared library
+
+add_executable(check_builtin $<TARGET_OBJECTS:open62541-objects> check_builtin.c)
 target_link_libraries(check_builtin ${LIBS})
 add_test(builtin ${CMAKE_CURRENT_BINARY_DIR}/check_builtin)
 
-add_executable(check_memory check_memory.c)
+add_executable(check_memory $<TARGET_OBJECTS:open62541-objects> check_memory.c)
 target_link_libraries(check_memory ${LIBS})
 add_test(memory ${CMAKE_CURRENT_BINARY_DIR}/check_memory)
 
@@ -25,11 +28,11 @@ add_test(memory ${CMAKE_CURRENT_BINARY_DIR}/check_memory)
 # target_link_libraries(check_base64 ${LIBS})
 # add_test(base64 ${CMAKE_CURRENT_BINARY_DIR}/check_base64)
 
-add_executable(check_services_view check_services_view.c)
+add_executable(check_services_view $<TARGET_OBJECTS:open62541-objects> check_services_view.c)
 target_link_libraries(check_services_view ${LIBS})
 add_test(services_view ${CMAKE_CURRENT_BINARY_DIR}/check_services_view)
 
-add_executable(check_nodestore check_nodestore.c)
+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)
 

+ 7 - 10
tests/check_builtin.c

@@ -121,7 +121,7 @@ START_TEST(UA_String_calcSizeWithNullArgumentShallReturnStorageSize) {
 	UA_UInt32  storageSize = UA_String_calcSizeBinary(arg);
 	// then
 	ck_assert_int_eq(storageSize, sizeof(UA_String));
-	ck_assert_int_ge(storageSize, UA_Int32_calcSizeBinary(UA_NULL) + sizeof(UA_NULL));
+	ck_assert_int_ge(storageSize, sizeof(UA_Int32) + sizeof(UA_NULL));
 }
 END_TEST
 START_TEST(UA_DateTime_calcSizeWithNullArgumentShallReturnStorageSize) {
@@ -149,7 +149,7 @@ START_TEST(UA_ByteString_calcSizeWithNullArgumentShallReturnStorageSize) {
 	UA_UInt32 storageSize = UA_ByteString_calcSizeBinary(arg);
 	// then
 	ck_assert_int_eq(storageSize, sizeof(UA_ByteString));
-	ck_assert_int_ge(storageSize, UA_Int32_calcSizeBinary(UA_NULL)+sizeof(UA_NULL));
+	ck_assert_int_ge(storageSize, sizeof(UA_Int32)+sizeof(UA_NULL));
 }
 END_TEST
 START_TEST(UA_XmlElement_calcSizeWithNullArgumentShallReturnStorageSize) {
@@ -159,7 +159,7 @@ START_TEST(UA_XmlElement_calcSizeWithNullArgumentShallReturnStorageSize) {
 	UA_UInt32 storageSize = UA_XmlElement_calcSizeBinary(arg);
 	// then
 	ck_assert_int_eq(storageSize, sizeof(UA_XmlElement));
-	ck_assert_int_ge(storageSize, UA_Int32_calcSizeBinary(UA_NULL)+sizeof(UA_NULL));
+	ck_assert_int_ge(storageSize, sizeof(UA_Int32)+sizeof(UA_NULL));
 }
 END_TEST
 START_TEST(UA_NodeId_calcSizeWithNullArgumentShallReturnStorageSize) {
@@ -1364,14 +1364,11 @@ START_TEST(UA_DateTime_toStringShallWorkOnExample) {
 	//1397467189... is Mon, 14 Apr 2014 09:19:49 GMT
 	//...1234567 are the milli-, micro- and nanoseconds
 
-	char      buf[80] = "80";
-	UA_Byte  *byteBuf = (UA_Byte *)buf;
-	UA_String dst     = { 80, byteBuf };
+	UA_String dst;
 
 	// when
 	UA_DateTime_toString(src, &dst);
 	// then
-	ck_assert_int_eq(dst.length, 80);
 	ck_assert_int_eq(dst.data[0], ' ');
 	ck_assert_int_eq(dst.data[1], '4');
 	ck_assert_int_eq(dst.data[2], '/');
@@ -1417,7 +1414,7 @@ START_TEST(UA_Array_copyByteArrayShallWorkOnExample) {
 	UA_Byte  *dstArray;
 	UA_Int32  size = 5;
 	UA_Int32  i    = 0;
-	UA_alloc((void **)&testString.data, size);
+	testString.data = UA_alloc(size);
 	testString.data[0] = 'O';
 	testString.data[1] = 'P';
 	testString.data[2] = 'C';
@@ -1673,7 +1670,7 @@ START_TEST(UA_Variant_copyShallWorkOnSingleValueExample) {
 	UA_Variant value, copiedValue;
 	UA_Variant_init(&value);
 	UA_Variant_init(&copiedValue);
-	UA_alloc((void**)&value.storage.data.dataPtr, sizeof(UA_String));
+	value.storage.data.dataPtr = UA_alloc(sizeof(UA_String));
 	*((UA_String*)value.storage.data.dataPtr) = testString;
 	value.vt = &UA_[UA_STRING];
 	value.storage.data.arrayLength = 1;
@@ -1705,7 +1702,7 @@ START_TEST(UA_Variant_copyShallWorkOn1DArrayExample) {
 	UA_String_copycstring("opc ua", &srcArray[2]);
 
 	UA_Int32 *dimensions;
-	UA_alloc((void **)&dimensions, UA_Int32_calcSizeBinary(UA_NULL));
+	dimensions = UA_alloc(sizeof(UA_Int32));
 	dimensions[0] = 3;
 
 	UA_Variant value, copiedValue;

+ 1 - 3
tools/generate_builtin.py

@@ -54,8 +54,6 @@ def skipType(name):
         return True
     if "Test" in name: #skip all Test types
         return True
-    if re.search("Attributes$", name) != None:
-        return True
     if re.search("NodeId$", name) != None:
         return True
     if args.only_needed and not(name in only_needed_types):
@@ -233,7 +231,7 @@ UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     if(!p) return;''')
     for n,t in membermap.iteritems():
         if t.find("*") != -1:
-            printc('\tp->%(n)sSize = 0;')
+            printc('\tp->%(n)sSize = -1;')
             printc('\tp->%(n)s = UA_NULL;')
         else:
             printc('\t%(t)s_init(&p->%(n)s);')

+ 1 - 3
tools/generate_namespace.py

@@ -65,8 +65,6 @@ def skipType(row):
         return True
     if "Test" in row[0]:
         return True
-    if re.search("Attributes$", row[0]) != None:
-        return True
     if args.only_needed and not(row[0] in only_needed_types):
         return True
     return False
@@ -106,7 +104,7 @@ printh('''/**********************************************************
  */
 
 UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id);\n
-extern const UA_VTable_Entry *UA_;
+extern const UA_VTable_Entry UA_EXPORT *UA_;
 
 /**
  * @brief the set of possible indices into UA_VTable

+ 1 - 1
tools/type_lists.py

@@ -21,5 +21,5 @@ only_needed_types = set([	"InvalidType", "Node", "NodeClass", "ReferenceNode", "
 							"BrowseDirection", "CloseSessionRequest", "AddNodesRequest", "AddNodesResponse", "AddNodesItem", "AddNodesResult",
 							"AddReferencesRequest", "AddReferencesResponse", "AddReferencesItem", "VariableNode", "MethodNode", "VariableTypeNode",
 							"ViewNode", "ReferenceTypeNode", "BrowseResultMask", "ServerState", "ServerStatusDataType", "BuildInfo", "ObjectNode",
-							"DataTypeNode", "ObjectTypeNode", "IdType" ])
+							"DataTypeNode", "ObjectTypeNode", "IdType", "VariableAttributes", "NodeAttributesMask" ])
 only_needed_types = only_needed_types.union(existing_types)