Browse Source

make the server struct opaque for userspace and
auto-generate an array with the standard-nodeids (datatypes, referencetypes, objects) in ns0

Julius Pfrommer 10 years ago
parent
commit
0d7e0e5468

+ 24 - 18
README.md

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

+ 9 - 10
examples/networklayer_tcp.c

@@ -51,16 +51,15 @@ typedef struct TCPConnectionHandle {
 	NetworklayerTCP *layer;
 } TCPConnectionHandle;
 
-UA_StatusCode NetworklayerTCP_new(NetworklayerTCP **newlayer, UA_ConnectionConfig localConf,
-                                  UA_UInt32 port) {
-    *newlayer = malloc(sizeof(NetworklayerTCP));
-    if(*newlayer == NULL)
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-	(*newlayer)->localConf = localConf;
-	(*newlayer)->port = port;
-	(*newlayer)->connectionsSize = 0;
-	(*newlayer)->connections = NULL;
-	return UA_STATUSCODE_GOOD;
+NetworklayerTCP *NetworklayerTCP_new(UA_ConnectionConfig localConf, UA_UInt32 port) {
+    NetworklayerTCP *newlayer = malloc(sizeof(NetworklayerTCP));
+    if(newlayer == NULL)
+        return NULL;
+	newlayer->localConf = localConf;
+	newlayer->port = port;
+	newlayer->connectionsSize = 0;
+	newlayer->connections = NULL;
+	return newlayer;
 }
 
 // copy the array of connections, but _loose_ one. This does not close the

+ 1 - 5
examples/networklayer_tcp.h

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

+ 5 - 5
examples/opcuaClient.c

@@ -229,7 +229,7 @@ UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
 	UA_ReadRequest rq;
 	UA_ReadRequest_init(&rq);
 	rq.maxAge = 0;
-	UA_Array_new((void **)&rq.nodesToRead, nodeIds_size, &UA_[UA_READVALUEID]);
+	UA_Array_new((void **)&rq.nodesToRead, nodeIds_size, &UA_TYPES[UA_READVALUEID]);
 	rq.nodesToReadSize = nodeIds_size;
 	for(UA_Int32 i=0;i<nodeIds_size;i++) {
 		UA_ReadValueId_init(&(rq.nodesToRead[i]));
@@ -257,7 +257,7 @@ UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
 
 	UA_DateTime tic = UA_DateTime_now();
 	UA_Int32 sendret = send(sock, message->data, offset, 0);
-	UA_Array_delete(rq.nodesToRead,nodeIds_size,&UA_[UA_READVALUEID]);
+	UA_Array_delete(rq.nodesToRead,nodeIds_size,&UA_TYPES[UA_READVALUEID]);
 	UA_ByteString_delete(message);
 
 	if (sendret < 0) {
@@ -355,7 +355,7 @@ int main(int argc, char *argv[]) {
 	received = recv(sock, reply.data, reply.length, 0);
 
     UA_NodeId *nodesToRead;
-    UA_Array_new((void**)&nodesToRead,nodesToReadSize,&UA_[UA_NODEID]);
+    UA_Array_new((void**)&nodesToRead,nodesToReadSize,&UA_TYPES[UA_NODEID]);
 
 	for(UA_UInt32 i = 0; i<nodesToReadSize; i++) {
 		if(alwaysSameNode)
@@ -369,7 +369,7 @@ int main(int argc, char *argv[]) {
 	UA_DateTime tic, toc;
 	UA_Double *timeDiffs;
 
-	UA_Array_new((void**)&timeDiffs,tries,&UA_[UA_DOUBLE]);
+	UA_Array_new((void**)&timeDiffs,tries,&UA_TYPES[UA_DOUBLE]);
 	UA_Double sum = 0;
 
 	for(UA_UInt32 i = 0; i < tries; i++) {
@@ -404,7 +404,7 @@ int main(int argc, char *argv[]) {
     UA_OpenSecureChannelResponse_deleteMembers(&openSecChannelRsp);
 	UA_String_delete(endpointUrl);
 	UA_String_deleteMembers(&reply);
-	UA_Array_delete(nodesToRead,nodesToReadSize,&UA_[UA_NODEID]);
+	UA_Array_delete(nodesToRead,nodesToReadSize,&UA_TYPES[UA_NODEID]);
     UA_free(timeDiffs);
 	UA_CreateSessionResponse_deleteMembers(&createSessionResponse);
 

+ 9 - 13
examples/opcuaServer.c

@@ -52,18 +52,17 @@ UA_ByteString loadCertificate() {
 int main(int argc, char** argv) {
 	signal(SIGINT, stopHandler); /* catches ctrl-c */
 
-	UA_Server server;
 	UA_String endpointUrl;
 	UA_String_copycstring("opc.tcp://192.168.56.101:16664",&endpointUrl);
     UA_ByteString certificate = loadCertificate();
-	UA_Server_init(&server, &endpointUrl, &certificate);
-	Logger_Stdout_init(&server.logger);
+	UA_Server *server = UA_Server_new(&endpointUrl, &certificate);
+	//Logger_Stdout_init(&server->logger);
 
     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);
+    UA_Server_addScalarVariableNode(server, &myIntegerName, (void*)&myInteger, &UA_TYPES[UA_INT32],
+                                    &UA_NODEIDS[UA_OBJECTSFOLDER], &UA_NODEIDS[UA_HASCOMPONENT]);
 
 #ifdef BENCHMARK
     UA_UInt32 nodeCount = 500;
@@ -78,23 +77,20 @@ int main(int argc, char** argv) {
         tmpNode->nodeId.identifier.numeric = 19000+i;
         tmpNode->nodeClass = UA_NODECLASS_VARIABLE;
         //tmpNode->valueRank = -1;
-        tmpNode->value.vt = &UA_[UA_INT32];
+        tmpNode->value.vt = &UA_TYPES[UA_INT32];
         tmpNode->value.storage.data.dataPtr = &data;
         tmpNode->value.storageType = UA_VARIANT_DATA_NODELETE;
         tmpNode->value.storage.data.arrayLength = 1;
-        UA_Server_addNode(&server, (UA_Node**)&tmpNode, &server.objectsNodeId,
-                          &server.hasComponentReferenceTypeId);
+        UA_Server_addNode(server, (UA_Node**)&tmpNode, &UA_NODEIDS[UA_OBJECTSFOLDER], &UA_NODEIDS[UA_HASCOMPONENT]);
     }
 #endif
 	
 	#define PORT 16664
-	NetworklayerTCP* nl;
-	NetworklayerTCP_new(&nl, UA_ConnectionConfig_standard, PORT);
+	NetworklayerTCP* nl = NetworklayerTCP_new(UA_ConnectionConfig_standard, PORT);
 	printf("Server started, connect to to opc.tcp://127.0.0.1:%i\n", PORT);
 	struct timeval callback_interval = {1, 0}; // 1 second
-	UA_Int32 retval = NetworkLayerTCP_run(nl, &server, callback_interval,
-										  serverCallback, &running);
-	UA_Server_deleteMembers(&server);
+	UA_Int32 retval = NetworkLayerTCP_run(nl, server, callback_interval, serverCallback, &running);
+	UA_Server_delete(server);
 	NetworklayerTCP_delete(nl);
     UA_String_deleteMembers(&endpointUrl);
 	return retval == UA_STATUSCODE_GOOD ? 0 : retval;

+ 8 - 33
include/ua_server.h

@@ -27,47 +27,22 @@ extern "C" {
 
 /** @defgroup server Server */
 
-//identifier numbers are different for XML and binary, so we have to substract an offset for comparison
-#define UA_ENCODINGOFFSET_XML 1
-#define UA_ENCODINGOFFSET_BINARY 2
-
-struct UA_SecureChannelManager;
-typedef struct UA_SecureChannelManager UA_SecureChannelManager;
-
-struct UA_SessionManager;
-typedef struct UA_SessionManager UA_SessionManager;
-
 struct UA_NodeStore;
 typedef struct UA_NodeStore UA_NodeStore;
 
-typedef struct UA_Server {
-    UA_ApplicationDescription description;
-    UA_Int32 endpointDescriptionsSize;
-    UA_EndpointDescription *endpointDescriptions;
-    UA_ByteString serverCertificate;
-    
-    UA_SecureChannelManager *secureChannelManager;
-    UA_SessionManager *sessionManager;
-    UA_NodeStore *nodestore;
-    UA_Logger logger;
-
-    // todo: move these somewhere sane
-    UA_ExpandedNodeId objectsNodeId;
-    UA_NodeId hasComponentReferenceTypeId;
-} UA_Server;
+struct UA_Server;
+typedef struct UA_Server UA_Server;
 
-void UA_EXPORT UA_Server_init(UA_Server *server, UA_String *endpointUrl, UA_ByteString *serverCertificate);
-UA_StatusCode UA_EXPORT UA_Server_deleteMembers(UA_Server *server);
+UA_Server UA_EXPORT * UA_Server_new(UA_String *endpointUrl, UA_ByteString *serverCertificate);
+void UA_EXPORT UA_Server_delete(UA_Server *server);
 void UA_EXPORT UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);
 
 /* Services for local use */
+UA_AddNodesResult UA_EXPORT UA_Server_addNode(UA_Server *server, UA_Node **node, const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId);
+void UA_EXPORT UA_Server_addReference(UA_Server *server, const UA_AddReferencesRequest *request, UA_AddReferencesResponse *response);
 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);
+                                                            const UA_VTable_Entry *vt, const UA_NodeId *parentNodeId,
+                                                            const UA_NodeId *referenceTypeId );
 
 #ifdef __cplusplus
 } // extern "C"

+ 1 - 1
src/server/ua_nodestore.c

@@ -341,6 +341,6 @@ void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visit
     }
 }
 
-void UA_NodeStore_releaseManagedNode(const UA_Node *managed) {
+void UA_NodeStore_release(const UA_Node *managed) {
     ;
 }

+ 1 - 1
src/server/ua_nodestore.h

@@ -48,7 +48,7 @@ UA_StatusCode UA_NodeStore_get(const UA_NodeStore *ns, const UA_NodeId *nodeid,
 
 /** @brief Release a managed node. Do never insert a node that isn't stored in a
     namespace. */
-void UA_NodeStore_releaseManagedNode(const UA_Node *managed);
+void UA_NodeStore_release(const UA_Node *managed);
 
 /** @brief A function that can be evaluated on all entries in a namespace via
     UA_NodeStore_iterate. Note that the visitor is read-only on the nodes. */

+ 2 - 5
src/server/ua_nodestore_concurrent.c

@@ -164,10 +164,7 @@ static void markDead(struct rcu_head *head) {
 }
 
 /* Free the entry if it is dead and nobody uses it anymore */
-void UA_NodeStore_releaseManagedNode(const UA_Node *managed) {
-    if(managed == UA_NULL)
-        return;
-
+void UA_NodeStore_release(const UA_Node *managed) {
     UA_NodeStore_Entry *entry = caa_container_of(managed, UA_NodeStore_Entry, node); // pointer to the first entry
     if(uatomic_sub_return(&entry->readcount, 1) > 0)
         return;
@@ -350,7 +347,7 @@ void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visit
         const UA_Node      *node = &found_entry->node;
         rcu_read_unlock();
         visitor(node);
-        UA_NodeStore_releaseManagedNode((UA_Node *)node);
+        UA_NodeStore_release((UA_Node *)node);
         rcu_read_lock();
         cds_lfht_next(ht, &iter);
     }

+ 10 - 26
src/server/ua_securechannel_manager.c

@@ -1,6 +1,5 @@
 #include "ua_securechannel_manager.h"
 #include "ua_session.h"
-#include "ua_util.h"
 #include "ua_statuscodes.h"
 
 struct channel_list_entry {
@@ -8,33 +7,19 @@ struct channel_list_entry {
     LIST_ENTRY(channel_list_entry) pointers;
 };
 
-struct UA_SecureChannelManager {
-    UA_Int32    maxChannelCount;
-    UA_DateTime maxChannelLifetime;
-    LIST_HEAD(channel_list, channel_list_entry) channels;
-    UA_MessageSecurityMode securityMode;
-    UA_String   endpointUrl;
-    UA_DateTime channelLifeTime;
-    UA_Int32    lastChannelId;
-    UA_UInt32   lastTokenId;
-};
-
-UA_StatusCode UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 maxChannelCount,
-                                          UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
-                                          UA_UInt32 startTokenId, UA_String *endpointUrl) {
-    if(!(*cm = UA_alloc(sizeof(UA_SecureChannelManager))))
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-    UA_SecureChannelManager *channelManager = *cm;
-    LIST_INIT(&channelManager->channels);
-    channelManager->lastChannelId      = startChannelId;
-    channelManager->lastTokenId        = startTokenId;
-    UA_String_copy(endpointUrl, &channelManager->endpointUrl);
-    channelManager->maxChannelLifetime = tokenLifetime;
-    channelManager->maxChannelCount    = maxChannelCount;
+UA_StatusCode UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
+                                           UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
+                                           UA_UInt32 startTokenId, UA_String *endpointUrl) {
+    LIST_INIT(&cm->channels);
+    cm->lastChannelId      = startChannelId;
+    cm->lastTokenId        = startTokenId;
+    UA_String_copy(endpointUrl, &cm->endpointUrl);
+    cm->maxChannelLifetime = tokenLifetime;
+    cm->maxChannelCount    = maxChannelCount;
     return UA_STATUSCODE_GOOD;
 }
 
-void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
+void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm) {
     struct channel_list_entry *entry = LIST_FIRST(&cm->channels);
     while(entry) {
         LIST_REMOVE(entry, pointers);
@@ -47,7 +32,6 @@ void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
         entry = LIST_FIRST(&cm->channels);
     }
     UA_String_deleteMembers(&cm->endpointUrl);
-    UA_free(cm);
 }
 
 UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager           *cm,

+ 16 - 4
src/server/ua_securechannel_manager.h

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

+ 32 - 27
src/server/ua_server.c

@@ -1,4 +1,4 @@
-#include "ua_server.h"
+#include "ua_server_internal.h"
 #include "ua_services_internal.h" // AddReferences
 #include "ua_namespace_0.h"
 #include "ua_securechannel_manager.h"
@@ -6,22 +6,20 @@
 #include "ua_util.h"
 #include "ua_services.h"
 
-UA_StatusCode UA_Server_deleteMembers(UA_Server *server) {
+void UA_Server_delete(UA_Server *server) {
     UA_ApplicationDescription_deleteMembers(&server->description);
-    UA_SecureChannelManager_delete(server->secureChannelManager);
-    UA_SessionManager_delete(server->sessionManager);
+    UA_SecureChannelManager_deleteMembers(&server->secureChannelManager);
+    UA_SessionManager_deleteMembers(&server->sessionManager);
     UA_NodeStore_delete(server->nodestore);
     UA_ByteString_deleteMembers(&server->serverCertificate);
-    UA_Array_delete(server->endpointDescriptions, server->endpointDescriptionsSize, &UA_[UA_ENDPOINTDESCRIPTION]);
-    return UA_STATUSCODE_GOOD;
+    UA_Array_delete(server->endpointDescriptions, server->endpointDescriptionsSize, &UA_TYPES[UA_ENDPOINTDESCRIPTION]);
+    UA_free(server);
 }
 
-void UA_Server_init(UA_Server *server, UA_String *endpointUrl, UA_ByteString *serverCertificate) {
-    UA_ExpandedNodeId_init(&server->objectsNodeId);
-    server->objectsNodeId.nodeId.identifier.numeric = 85;
-
-    UA_NodeId_init(&server->hasComponentReferenceTypeId);
-    server->hasComponentReferenceTypeId.identifier.numeric = 47;
+UA_Server * UA_Server_new(UA_String *endpointUrl, UA_ByteString *serverCertificate) {
+    UA_Server *server = UA_alloc(sizeof(UA_Server));
+    if(!server)
+        return server;
     
     // mockup application description
     UA_ApplicationDescription_init(&server->description);
@@ -60,14 +58,13 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl, UA_ByteString *se
 #define STARTCHANNELID 1
 #define TOKENLIFETIME 10000
 #define STARTTOKENID 1
-    UA_SecureChannelManager_new(&server->secureChannelManager, MAXCHANNELCOUNT,
-                                TOKENLIFETIME, STARTCHANNELID, STARTTOKENID, endpointUrl);
+    UA_SecureChannelManager_init(&server->secureChannelManager, MAXCHANNELCOUNT,
+                                 TOKENLIFETIME, STARTCHANNELID, STARTTOKENID, endpointUrl);
 
 #define MAXSESSIONCOUNT 1000
 #define SESSIONLIFETIME 10000
 #define STARTSESSIONID 1
-    UA_SessionManager_new(&server->sessionManager, MAXSESSIONCOUNT, SESSIONLIFETIME,
-                          STARTSESSIONID);
+    UA_SessionManager_init(&server->sessionManager, MAXSESSIONCOUNT, SESSIONLIFETIME, STARTSESSIONID);
 
     UA_NodeStore_new(&server->nodestore);
 
@@ -468,8 +465,8 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl, UA_ByteString *se
     UA_QualifiedName_copycstring("NodeStoreArray", &namespaceArray->browseName);
     UA_LocalizedText_copycstring("NodeStoreArray", &namespaceArray->displayName);
     UA_LocalizedText_copycstring("NodeStoreArray", &namespaceArray->description);
-    UA_Array_new(&namespaceArray->value.storage.data.dataPtr, 2, &UA_[UA_STRING]);
-    namespaceArray->value.vt = &UA_[UA_STRING];
+    UA_Array_new(&namespaceArray->value.storage.data.dataPtr, 2, &UA_TYPES[UA_STRING]);
+    namespaceArray->value.vt = &UA_TYPES[UA_STRING];
     namespaceArray->value.storage.data.arrayLength = 2;
     UA_String_copycstring("http://opcfoundation.org/UA/", &((UA_String *)(namespaceArray->value.storage.data.dataPtr))[0]);
     UA_String_copycstring("http://localhost:16664/open62541/", &((UA_String *)(namespaceArray->value.storage.data.dataPtr))[1]);
@@ -504,7 +501,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl, UA_ByteString *se
     status->buildInfo.buildDate     = UA_DateTime_now();
     status->secondsTillShutdown     = 99999999;
     UA_LocalizedText_copycstring("because", &status->shutdownReason);
-    serverstatus->value.vt          = &UA_[UA_SERVERSTATUSDATATYPE]; // gets encoded as an extensionobject
+    serverstatus->value.vt          = &UA_TYPES[UA_SERVERSTATUSDATATYPE]; // gets encoded as an extensionobject
     serverstatus->value.storage.data.arrayLength = 1;
     serverstatus->value.storage.data.dataPtr        = status;
     UA_NodeStore_insert(server->nodestore, (UA_Node**)&serverstatus, UA_NODESTORE_INSERT_UNIQUE);
@@ -516,19 +513,24 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl, UA_ByteString *se
     UA_QualifiedName_copycstring("State", &state->browseName);
     UA_LocalizedText_copycstring("State", &state->displayName);
     UA_LocalizedText_copycstring("State", &state->description);
-    state->value.vt = &UA_[UA_SERVERSTATE];
+    state->value.vt = &UA_TYPES[UA_SERVERSTATE];
     state->value.storage.data.arrayDimensionsLength = 1; // added to ensure encoding in readreponse
     state->value.storage.data.arrayLength = 1;
     state->value.storage.data.dataPtr = &status->state; // points into the other object.
     state->value.storageType = UA_VARIANT_DATA_NODELETE;
     UA_NodeStore_insert(server->nodestore, (UA_Node**)&state, UA_NODESTORE_INSERT_UNIQUE);
 
-    UA_NodeStore_releaseManagedNode((const UA_Node *)root);
+    UA_NodeStore_release((const UA_Node *)root);
+
+    return server;
 }
 
-UA_AddNodesResult UA_Server_addNode(UA_Server *server, UA_Node **node, UA_ExpandedNodeId *parentNodeId,
-                                    UA_NodeId *referenceTypeId) {
-    return AddNode(server, &adminSession, node, parentNodeId, referenceTypeId);
+UA_AddNodesResult UA_Server_addNode(UA_Server *server, UA_Node **node, const UA_NodeId *parentNodeId,
+                                    const UA_NodeId *referenceTypeId) {
+    UA_ExpandedNodeId expParentNodeId;
+    UA_ExpandedNodeId_init(&expParentNodeId);
+    UA_NodeId_copy(parentNodeId, &expParentNodeId.nodeId);
+    return AddNode(server, &adminSession, node, &expParentNodeId, referenceTypeId);
 }
 
 void UA_Server_addReference(UA_Server *server, const UA_AddReferencesRequest *request,
@@ -537,8 +539,11 @@ void UA_Server_addReference(UA_Server *server, const UA_AddReferencesRequest *re
 }
 
 UA_AddNodesResult UA_Server_addScalarVariableNode(UA_Server *server, UA_String *browseName, void *value,
-                                                  const UA_VTable_Entry *vt, UA_ExpandedNodeId *parentNodeId,
-                                                  UA_NodeId *referenceTypeId ) {
+                                                  const UA_VTable_Entry *vt, const UA_NodeId *parentNodeId,
+                                                  const UA_NodeId *referenceTypeId ) {
+    UA_ExpandedNodeId expParentNodeId;
+    UA_ExpandedNodeId_init(&expParentNodeId);
+    UA_NodeId_copy(parentNodeId, &expParentNodeId.nodeId);
     UA_VariableNode *tmpNode = UA_VariableNode_new();
     UA_String_copy(browseName, &tmpNode->browseName.name);
     UA_String_copy(browseName, &tmpNode->displayName.text);
@@ -549,5 +554,5 @@ UA_AddNodesResult UA_Server_addScalarVariableNode(UA_Server *server, UA_String *
     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);
+    return AddNode(server, &adminSession, (UA_Node**)&tmpNode, &expParentNodeId, referenceTypeId);
 }

+ 2 - 2
src/server/ua_server_binary.c

@@ -1,4 +1,4 @@
-#include "ua_server.h"
+#include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 #include "ua_namespace_0.h"
@@ -152,7 +152,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
     UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
 
     UA_SecureChannel *channel;
-    UA_SecureChannelManager_get(server->secureChannelManager, secureChannelId, &channel);
+    UA_SecureChannelManager_get(&server->secureChannelManager, secureChannelId, &channel);
 
     // 2) Read the security header
     UA_UInt32 tokenId;

+ 20 - 0
src/server/ua_server_internal.h

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

+ 26 - 28
src/server/ua_services_attribute.c

@@ -1,3 +1,4 @@
+#include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 #include "ua_nodestore.h"
@@ -52,39 +53,37 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
     switch(id->attributeId) {
     case UA_ATTRIBUTEID_NODEID:
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_NODEID], &node->nodeId);
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_NODEID], &node->nodeId);
         break;
 
     case UA_ATTRIBUTEID_NODECLASS:
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_INT32], &node->nodeClass);
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_INT32], &node->nodeClass);
         break;
 
     case UA_ATTRIBUTEID_BROWSENAME:
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_QUALIFIEDNAME], &node->browseName);
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_QUALIFIEDNAME], &node->browseName);
         break;
 
     case UA_ATTRIBUTEID_DISPLAYNAME:
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
-                                          &node->displayName);
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT], &node->displayName);
         break;
 
     case UA_ATTRIBUTEID_DESCRIPTION:
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
-                                          &node->description);
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT], &node->description);
         break;
 
     case UA_ATTRIBUTEID_WRITEMASK:
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_UINT32], &node->writeMask);
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_UINT32], &node->writeMask);
         break;
 
     case UA_ATTRIBUTEID_USERWRITEMASK:
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_UINT32], &node->userWriteMask);
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_UINT32], &node->userWriteMask);
         break;
 
     case UA_ATTRIBUTEID_ISABSTRACT:
@@ -93,35 +92,34 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
             UA_NODECLASS_DATATYPE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
         retval |=
-            UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
-                                    &((UA_ReferenceTypeNode *)node)->isAbstract);
+            UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN], &((UA_ReferenceTypeNode *)node)->isAbstract);
         break;
 
     case UA_ATTRIBUTEID_SYMMETRIC:
         CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
                                           &((UA_ReferenceTypeNode *)node)->symmetric);
         break;
 
     case UA_ATTRIBUTEID_INVERSENAME:
         CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_LOCALIZEDTEXT],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_LOCALIZEDTEXT],
                                           &((UA_ReferenceTypeNode *)node)->inverseName);
         break;
 
     case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
         CHECK_NODECLASS(UA_NODECLASS_VIEW);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
                                           &((UA_ViewNode *)node)->containsNoLoops);
         break;
 
     case UA_ATTRIBUTEID_EVENTNOTIFIER:
         CHECK_NODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
                                           &((UA_ViewNode *)node)->eventNotifier);
         break;
 
@@ -134,21 +132,21 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
     case UA_ATTRIBUTEID_DATATYPE:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_NODEID],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_NODEID],
                                           &((UA_VariableTypeNode *)node)->dataType);
         break;
 
     case UA_ATTRIBUTEID_VALUERANK:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_INT32],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_INT32],
                                           &((UA_VariableTypeNode *)node)->valueRank);
         break;
 
     case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        UA_Variant_copySetArray(&v.value, &UA_[UA_UINT32],
+        UA_Variant_copySetArray(&v.value, &UA_TYPES[UA_UINT32],
                                 ((UA_VariableTypeNode *)node)->arrayDimensionsSize,
                                 &((UA_VariableTypeNode *)node)->arrayDimensions);
         break;
@@ -156,42 +154,42 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
     case UA_ATTRIBUTEID_ACCESSLEVEL:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
                                           &((UA_VariableNode *)node)->accessLevel);
         break;
 
     case UA_ATTRIBUTEID_USERACCESSLEVEL:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BYTE],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BYTE],
                                           &((UA_VariableNode *)node)->userAccessLevel);
         break;
 
     case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_DOUBLE],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_DOUBLE],
                                           &((UA_VariableNode *)node)->minimumSamplingInterval);
         break;
 
     case UA_ATTRIBUTEID_HISTORIZING:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
                                           &((UA_VariableNode *)node)->historizing);
         break;
 
     case UA_ATTRIBUTEID_EXECUTABLE:
         CHECK_NODECLASS(UA_NODECLASS_METHOD);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
                                           &((UA_MethodNode *)node)->executable);
         break;
 
     case UA_ATTRIBUTEID_USEREXECUTABLE:
         CHECK_NODECLASS(UA_NODECLASS_METHOD);
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-        retval |= UA_Variant_copySetValue(&v.value, &UA_[UA_BOOLEAN],
+        retval |= UA_Variant_copySetValue(&v.value, &UA_TYPES[UA_BOOLEAN],
                                           &((UA_MethodNode *)node)->userExecutable);
         break;
 
@@ -201,7 +199,7 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
         break;
     }
 
-    UA_NodeStore_releaseManagedNode(node);
+    UA_NodeStore_release(node);
 
     if(retval != UA_STATUSCODE_GOOD) {
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
@@ -218,7 +216,7 @@ void Service_Read(UA_Server *server, UA_Session *session, const UA_ReadRequest *
         return;
     }
 
-    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToReadSize, &UA_[UA_DATAVALUE]);
+    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToReadSize, &UA_TYPES[UA_DATAVALUE]);
     if(retval) {
         response->responseHeader.serviceResult = retval;
         return;
@@ -353,7 +351,7 @@ static UA_StatusCode Service_Write_writeNode(UA_Server *server, UA_WriteValue *w
         break;
     }
 
-    UA_NodeStore_releaseManagedNode(node);
+    UA_NodeStore_release(node);
     return retval;
 
 }
@@ -362,7 +360,7 @@ 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);
 
-    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToWriteSize, &UA_[UA_STATUSCODE]);
+    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToWriteSize, &UA_TYPES[UA_STATUSCODE]);
     if(retval) {
         response->responseHeader.serviceResult = retval;
         return;

+ 1 - 0
src/server/ua_services_discovery.c

@@ -1,3 +1,4 @@
+#include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_namespace_0.h"
 #include "ua_util.h"

+ 1 - 1
src/server/ua_services_internal.h

@@ -15,4 +15,4 @@
  */
 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);
+                          const UA_ExpandedNodeId *parentNodeId, const UA_NodeId *referenceTypeId);

+ 8 - 7
src/server/ua_services_nodemanagement.c

@@ -1,3 +1,4 @@
+#include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_namespace_0.h"
 #include "ua_statuscodes.h"
@@ -77,7 +78,7 @@ static UA_StatusCode parseVariableNode(UA_ExtensionObject *attributes, UA_Node *
     UA_VariableAttributes_deleteMembers(&attr);
 
     *new_node = (UA_Node*)vnode;
-    *vt = &UA_[UA_VARIABLENODE];
+    *vt = &UA_TYPES[UA_VARIABLENODE];
     return UA_STATUSCODE_GOOD;
 }
 
@@ -89,7 +90,7 @@ UA_Int32 AddReference(UA_NodeStore *nodestore, UA_Node *node, UA_ReferenceNode *
    returned in the AddNodesResult.
  */
 UA_AddNodesResult AddNode(UA_Server *server, UA_Session *session, UA_Node **node,
-                          UA_ExpandedNodeId *parentNodeId, UA_NodeId *referenceTypeId) {
+                          const UA_ExpandedNodeId *parentNodeId, const UA_NodeId *referenceTypeId) {
     UA_AddNodesResult result;
     UA_AddNodesResult_init(&result);
     
@@ -146,13 +147,13 @@ UA_AddNodesResult AddNode(UA_Server *server, UA_Session *session, UA_Node **node
 
     // todo: error handling. remove new node from nodestore
 
-    UA_NodeStore_releaseManagedNode(*node);
+    UA_NodeStore_release(*node);
     *node = UA_NULL;
     
  ret2:
-    UA_NodeStore_releaseManagedNode((UA_Node*)referenceType);
+    UA_NodeStore_release((UA_Node*)referenceType);
  ret:
-    UA_NodeStore_releaseManagedNode(parent);
+    UA_NodeStore_release(parent);
 
     return result;
 }
@@ -187,7 +188,7 @@ void Service_AddNodes(UA_Server *server, UA_Session *session,
         return;
     }
 
-    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToAddSize, &UA_[UA_ADDNODESRESULT]);
+    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToAddSize, &UA_TYPES[UA_ADDNODESRESULT]);
     if(retval) {
         response->responseHeader.serviceResult = retval;
         return;
@@ -238,7 +239,7 @@ UA_Int32 AddReference(UA_NodeStore *nodestore, UA_Node *node, UA_ReferenceNode *
     inversereference.targetId.namespaceUri = UA_STRING_NULL;
     inversereference.targetId.serverIndex  = 0;
     retval = AddSingleReference(targetnode, &inversereference);
-    UA_NodeStore_releaseManagedNode(targetnode);
+    UA_NodeStore_release(targetnode);
 
     return retval;
 }

+ 4 - 3
src/server/ua_services_securechannel.c

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

+ 5 - 6
src/server/ua_services_session.c

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

+ 11 - 10
src/server/ua_services_view.c

@@ -1,3 +1,4 @@
+#include "ua_server_internal.h"
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 #include "ua_nodestore.h"
@@ -41,7 +42,7 @@ static UA_StatusCode fillReferenceDescription(UA_NodeStore *ns, const UA_Node *c
     }
 
     if(currentNode)
-        UA_NodeStore_releaseManagedNode(currentNode);
+        UA_NodeStore_release(currentNode);
     if(retval)
         UA_ReferenceDescription_deleteMembers(referenceDescription);
     return retval;
@@ -79,7 +80,7 @@ static UA_Boolean isRelevantTargetNode(UA_NodeStore *ns, const UA_BrowseDescript
         return UA_FALSE;
 
     if(((*currentNode)->nodeClass & browseDescription->nodeClassMask) == 0) {
-        UA_NodeStore_releaseManagedNode(*currentNode);
+        UA_NodeStore_release(*currentNode);
         return UA_FALSE;
     }
 
@@ -139,11 +140,11 @@ static UA_StatusCode findRelevantReferenceTypes(UA_NodeStore *ns, const UA_NodeI
             if(retval)
                 currentLastIndex--; // undo if we need to delete the typeArray
         }
-        UA_NodeStore_releaseManagedNode((UA_Node*)node);
+        UA_NodeStore_release((UA_Node*)node);
     } while(++currentIndex <= currentLastIndex && retval == UA_STATUSCODE_GOOD);
 
     if(retval)
-        UA_Array_delete(typeArray, currentLastIndex, &UA_[UA_NODEID]);
+        UA_Array_delete(typeArray, currentLastIndex, &UA_TYPES[UA_NODEID]);
     else {
         *referenceTypes = typeArray;
         *referenceTypesSize = currentLastIndex + 1;
@@ -176,7 +177,7 @@ static void getBrowseResult(UA_NodeStore *ns, const UA_BrowseDescription *browse
     if(UA_NodeStore_get(ns, &browseDescription->nodeId, &parentNode) != UA_STATUSCODE_GOOD) {
         browseResult->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
         if(!returnAll && browseDescription->includeSubtypes)
-            UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesSize, &UA_[UA_NODEID]);
+            UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesSize, &UA_TYPES[UA_NODEID]);
         return;
     }
 
@@ -202,7 +203,7 @@ static void getBrowseResult(UA_NodeStore *ns, const UA_BrowseDescription *browse
             // 2) Fill the reference description. This also releases the current node.
             if(fillReferenceDescription(ns, currentNode, &parentNode->references[i], browseDescription->resultMask,
                                         &browseResult->references[currentRefs]) != UA_STATUSCODE_GOOD) {
-                UA_Array_delete(browseResult->references, currentRefs, &UA_[UA_REFERENCEDESCRIPTION]);
+                UA_Array_delete(browseResult->references, currentRefs, &UA_TYPES[UA_REFERENCEDESCRIPTION]);
                 currentRefs = 0;
                 browseResult->references = UA_NULL;
                 browseResult->statusCode = UA_STATUSCODE_UNCERTAINNOTALLNODESAVAILABLE;
@@ -213,9 +214,9 @@ static void getBrowseResult(UA_NodeStore *ns, const UA_BrowseDescription *browse
         browseResult->referencesSize = currentRefs;
     }
 
-    UA_NodeStore_releaseManagedNode(parentNode);
+    UA_NodeStore_release(parentNode);
     if(!returnAll && browseDescription->includeSubtypes)
-        UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesSize, &UA_[UA_NODEID]);
+        UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesSize, &UA_TYPES[UA_NODEID]);
 }
 
 void Service_Browse(UA_Server *server, UA_Session *session, const UA_BrowseRequest *request, UA_BrowseResponse *response) {
@@ -224,7 +225,7 @@ void Service_Browse(UA_Server *server, UA_Session *session, const UA_BrowseReque
         return;
     }
 
-    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToBrowseSize, &UA_[UA_BROWSERESULT]);
+    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToBrowseSize, &UA_TYPES[UA_BROWSERESULT]);
     if(retval) {
         response->responseHeader.serviceResult = retval;
         return;
@@ -244,7 +245,7 @@ void Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *sessio
         return;
     }
 
-    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->browsePathsSize, &UA_[UA_BROWSEPATHRESULT]);
+    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->browsePathsSize, &UA_TYPES[UA_BROWSEPATHRESULT]);
     if(retval) {
         response->responseHeader.serviceResult = retval;
         return;

+ 7 - 19
src/server/ua_session_manager.c

@@ -13,28 +13,17 @@ struct session_list_entry {
     LIST_ENTRY(session_list_entry) pointers;
 };
 
-struct UA_SessionManager {
-    LIST_HEAD(session_list, session_list_entry) sessions;
-    UA_UInt32    maxSessionCount;
-    UA_Int32     lastSessionId;
-    UA_UInt32    currentSessionCount;
-    UA_DateTime  maxSessionLifeTime;
-    UA_DateTime  sessionTimeout;
-};
-
-UA_StatusCode UA_SessionManager_new(UA_SessionManager **sessionManager, UA_UInt32 maxSessionCount,
+UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
                                     UA_UInt32 sessionTimeout, UA_UInt32 startSessionId) {
-    if(!(*sessionManager = UA_alloc(sizeof(UA_SessionManager))))
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-    LIST_INIT(&(*sessionManager)->sessions);
-    (*sessionManager)->maxSessionCount = maxSessionCount;
-    (*sessionManager)->lastSessionId   = startSessionId;
-    (*sessionManager)->sessionTimeout  = sessionTimeout;
-    (*sessionManager)->currentSessionCount = 0;
+    LIST_INIT(&sessionManager->sessions);
+    sessionManager->maxSessionCount = maxSessionCount;
+    sessionManager->lastSessionId   = startSessionId;
+    sessionManager->sessionTimeout  = sessionTimeout;
+    sessionManager->currentSessionCount = 0;
     return UA_STATUSCODE_GOOD;
 }
 
-void UA_SessionManager_delete(UA_SessionManager *sessionManager) {
+void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager) {
     struct session_list_entry *current = LIST_FIRST(&sessionManager->sessions);
     while(current) {
         LIST_REMOVE(current, pointers);
@@ -44,7 +33,6 @@ void UA_SessionManager_delete(UA_SessionManager *sessionManager) {
         UA_free(current);
         current = LIST_FIRST(&sessionManager->sessions);
     }
-    UA_free(sessionManager);
 }
 
 UA_StatusCode UA_SessionManager_getSessionById(UA_SessionManager *sessionManager, UA_NodeId *sessionId, UA_Session **session) {

+ 12 - 2
src/server/ua_session_manager.h

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

+ 5 - 5
src/ua_types.c

@@ -811,7 +811,7 @@ void UA_Variant_init(UA_Variant *p) {
     p->storage.data.dataPtr        = UA_NULL;
     p->storage.data.arrayDimensions       = UA_NULL;
     p->storage.data.arrayDimensionsLength = -1;
-    p->vt = &UA_[UA_INVALIDTYPE];
+    p->vt = &UA_TYPES[UA_INVALIDTYPE];
 }
 
 /** This function performs a deep copy. The resulting StorageType is UA_VARIANT_DATA. */
@@ -836,7 +836,7 @@ UA_StatusCode UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
         dst->vt = src->vt;
         dstdata->arrayLength = srcdata->arrayLength;
         if(srcdata->arrayDimensions) {
-            retval |= UA_Array_copy(srcdata->arrayDimensions, srcdata->arrayDimensionsLength, &UA_[UA_INT32],
+            retval |= UA_Array_copy(srcdata->arrayDimensions, srcdata->arrayDimensionsLength, &UA_TYPES[UA_INT32],
                                     (void **)&dstdata->arrayDimensions);
             if(retval == UA_STATUSCODE_GOOD)
                 dstdata->arrayDimensionsLength = srcdata->arrayDimensionsLength;
@@ -891,8 +891,8 @@ void UA_Variant_print(const UA_Variant *p, FILE *stream) {
         return;
     }
     fprintf(stream, "(UA_Variant){/*%s*/", p->vt->name);
-    if(p->vt == &UA_[ns0id])
-        fprintf(stream, "UA_[%d]", ns0id);
+    if(p->vt == &UA_TYPES[ns0id])
+        fprintf(stream, "UA_TYPES[%d]", ns0id);
     else
         fprintf(stream, "ERROR (not a builtin type)");
     UA_Int32_print(&p->storage.data.arrayLength, stream);
@@ -902,7 +902,7 @@ void UA_Variant_print(const UA_Variant *p, FILE *stream) {
     UA_Int32_print(&p->storage.data.arrayDimensionsLength, stream);
     fprintf(stream, ",");
     UA_Array_print(p->storage.data.arrayDimensions, p->storage.data.arrayDimensionsLength,
-                   &UA_[UA_INT32], stream);
+                   &UA_TYPES[UA_INT32], stream);
     fprintf(stream, "}");
 }
 #endif

+ 11 - 11
src/ua_types_encoding_binary.c

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

+ 4 - 0
src/ua_util.h

@@ -21,6 +21,10 @@
 #define UA_TRUE (42 == 42)
 #define UA_FALSE (!UA_TRUE)
 
+//identifier numbers are different for XML and binary, so we have to substract an offset for comparison
+#define UA_ENCODINGOFFSET_XML 1
+#define UA_ENCODINGOFFSET_BINARY 2
+
 /* Debug macros */
 #define DBG_VERBOSE(expression) // omit debug code
 #define DBG_ERR(expression)     // omit debug code

+ 21 - 21
tests/check_builtin.c

@@ -253,7 +253,7 @@ START_TEST(UA_Variant_calcSizeFixedSizeArrayShallReturnEncodingSize) {
 	// given
 	UA_Variant arg;
 	UA_Variant_init(&arg);
-	arg.vt = &UA_[UA_INT32];
+	arg.vt = &UA_TYPES[UA_INT32];
 #define ARRAY_LEN 8
 	arg.storage.data.arrayLength = ARRAY_LEN;
 	UA_Int32 *data[ARRAY_LEN];
@@ -271,7 +271,7 @@ START_TEST(UA_Variant_calcSizeVariableSizeArrayShallReturnEncodingSize) {
 	// given
 	UA_Variant arg;
 	UA_Variant_init(&arg);
-	arg.vt = &UA_[UA_STRING];
+	arg.vt = &UA_TYPES[UA_STRING];
 #define ARRAY_LEN 3
 	arg.storage.data.arrayLength = ARRAY_LEN;
 	UA_String strings[3];
@@ -642,7 +642,7 @@ START_TEST(UA_Variant_decodeWithOutArrayFlagSetShallSetVTAndAllocateMemoryForArr
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_int_eq(pos, 5);
-	ck_assert_ptr_eq((void *)dst.vt, (void *)&UA_[UA_INT32]);
+	ck_assert_ptr_eq((void *)dst.vt, (void *)&UA_TYPES[UA_INT32]);
 	ck_assert_int_eq(dst.storage.data.arrayLength, 1);
 	ck_assert_int_eq(*(UA_Int32 *)dst.storage.data.dataPtr, 255);
 	// finally
@@ -664,7 +664,7 @@ START_TEST(UA_Variant_decodeWithArrayFlagSetShallSetVTAndAllocateMemoryForArray)
 	// then
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_int_eq(pos, 1+4+2*4);
-	ck_assert_ptr_eq((void*)dst.vt, (void*)&UA_[UA_INT32]);
+	ck_assert_ptr_eq((void*)dst.vt, (void*)&UA_TYPES[UA_INT32]);
 	ck_assert_int_eq(dst.storage.data.arrayLength, 2);
 	ck_assert_int_eq(((UA_Int32 *)dst.storage.data.dataPtr)[0], 255);
 	ck_assert_int_eq(((UA_Int32 *)dst.storage.data.dataPtr)[1], -1);
@@ -1087,7 +1087,7 @@ START_TEST(UA_DataValue_encodeShallWorkOnExampleWithVariant) {
 	src.serverTimestamp    = 80;
 	src.encodingMask       = UA_DATAVALUE_ENCODINGMASK_VARIANT | UA_DATAVALUE_ENCODINGMASK_SERVERTIMESTAMP; //Variant & SourvePicoseconds
 	UA_Variant_init(&src.value);
-	src.value.vt           = &UA_[UA_INT32];
+	src.value.vt           = &UA_TYPES[UA_INT32];
 	src.value.storage.data.arrayLength  = 1; // one element (encoded as not an array)
 	UA_Int32  vdata  = 45;
 	src.value.storage.data.dataPtr = (void *)&vdata;
@@ -1204,7 +1204,7 @@ START_TEST(UA_Array_copyByteArrayShallWorkOnExample) {
 	testString.length  = 5;
 
 	//when
-	UA_Array_copy((const void *)testString.data, 5, &UA_[UA_BYTE], (void **)&dstArray);
+	UA_Array_copy((const void *)testString.data, 5, &UA_TYPES[UA_BYTE], (void **)&dstArray);
 	//then
 	for(i = 0;i < size;i++)
 		ck_assert_int_eq(testString.data[i], dstArray[i]);
@@ -1220,14 +1220,14 @@ START_TEST(UA_Array_copyUA_StringShallWorkOnExample) {
 	// given
 	UA_Int32   i, j;
 	UA_String *srcArray;
-    UA_Array_new((void**)&srcArray, 3, &UA_[UA_STRING]);
+    UA_Array_new((void**)&srcArray, 3, &UA_TYPES[UA_STRING]);
 	UA_String *dstArray;
 
 	UA_String_copycstring("open", &srcArray[0]);
 	UA_String_copycstring("62541", &srcArray[1]);
 	UA_String_copycstring("opc ua", &srcArray[2]);
 	//when
-	UA_Array_copy((const void *)srcArray, 3, &UA_[UA_STRING], (void **)&dstArray);
+	UA_Array_copy((const void *)srcArray, 3, &UA_TYPES[UA_STRING], (void **)&dstArray);
 	//then
 	for(i = 0;i < 3;i++) {
 		for(j = 0;j < 3;j++)
@@ -1235,8 +1235,8 @@ START_TEST(UA_Array_copyUA_StringShallWorkOnExample) {
 		ck_assert_int_eq(srcArray[i].length, dstArray[i].length);
 	}
 	//finally
-	UA_Array_delete(srcArray, 3, &UA_[UA_STRING]);
-	UA_Array_delete(dstArray, 3, &UA_[UA_STRING]);
+	UA_Array_delete(srcArray, 3, &UA_TYPES[UA_STRING]);
+	UA_Array_delete(dstArray, 3, &UA_TYPES[UA_STRING]);
 }
 END_TEST
 
@@ -1407,7 +1407,7 @@ START_TEST(UA_Variant_copyShallWorkOnSingleValueExample) {
 	UA_Variant_init(&copiedValue);
 	value.storage.data.dataPtr = UA_alloc(sizeof(UA_String));
 	*((UA_String*)value.storage.data.dataPtr) = testString;
-	value.vt = &UA_[UA_STRING];
+	value.vt = &UA_TYPES[UA_STRING];
 	value.storage.data.arrayLength = 1;
 
 	//when
@@ -1431,7 +1431,7 @@ END_TEST
 START_TEST(UA_Variant_copyShallWorkOn1DArrayExample) {
 	// given
 	UA_String *srcArray;
-    UA_Array_new((void**)&srcArray, 3, &UA_[UA_STRING]);
+    UA_Array_new((void**)&srcArray, 3, &UA_TYPES[UA_STRING]);
 	UA_String_copycstring("__open", &srcArray[0]);
 	UA_String_copycstring("_62541", &srcArray[1]);
 	UA_String_copycstring("opc ua", &srcArray[2]);
@@ -1445,10 +1445,10 @@ START_TEST(UA_Variant_copyShallWorkOn1DArrayExample) {
 	UA_Variant_init(&copiedValue);
 
 	value.storage.data.arrayLength = 3;
-	value.storage.data.dataPtr  = (void *)srcArray;
+	value.storage.data.dataPtr = (void *)srcArray;
 	value.storage.data.arrayDimensionsLength = 1;
-	value.storage.data.arrayDimensions  = dimensions;
-	value.vt = &UA_[UA_STRING];
+	value.storage.data.arrayDimensions = dimensions;
+	value.vt = &UA_TYPES[UA_STRING];
 
 	//when
 	UA_Variant_copy(&value, &copiedValue);
@@ -1479,7 +1479,7 @@ END_TEST
 START_TEST(UA_Variant_copyShallWorkOn2DArrayExample) {
 	// given
 	UA_Int32 *srcArray;
-    UA_Array_new((void**)&srcArray, 6, &UA_[UA_INT32]);
+    UA_Array_new((void**)&srcArray, 6, &UA_TYPES[UA_INT32]);
 	srcArray[0] = 0;
 	srcArray[1] = 1;
 	srcArray[2] = 2;
@@ -1488,9 +1488,9 @@ START_TEST(UA_Variant_copyShallWorkOn2DArrayExample) {
 	srcArray[5] = 5;
 
 	UA_Int32 *dimensions;
-    UA_Array_new((void**)&dimensions, 2, &UA_[UA_INT32]);
-	UA_Int32  dim1 = 3;
-	UA_Int32  dim2 = 2;
+    UA_Array_new((void**)&dimensions, 2, &UA_TYPES[UA_INT32]);
+	UA_Int32 dim1 = 3;
+	UA_Int32 dim2 = 2;
 	dimensions[0] = dim1;
 	dimensions[1] = dim2;
 
@@ -1499,10 +1499,10 @@ START_TEST(UA_Variant_copyShallWorkOn2DArrayExample) {
 	UA_Variant_init(&copiedValue);
 
 	value.storage.data.arrayLength = 6;
-	value.storage.data.dataPtr        = (void **)srcArray;
+	value.storage.data.dataPtr     = (void **)srcArray;
 	value.storage.data.arrayDimensionsLength = 2;
 	value.storage.data.arrayDimensions       = dimensions;
-	value.vt = &UA_[UA_INT32];
+	value.vt = &UA_TYPES[UA_INT32];
 
 	//when
 	UA_Variant_copy(&value, &copiedValue);

+ 37 - 37
tests/check_memory.c

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

+ 8 - 8
tests/check_nodestore.c

@@ -56,8 +56,8 @@ START_TEST(findNodeInUA_NodeStoreWithSingleEntry) {
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_ptr_eq((void*)nr, (void*)n1);
 	// finally
-	UA_NodeStore_releaseManagedNode(n1);
-	UA_NodeStore_releaseManagedNode(nr);
+	UA_NodeStore_release(n1);
+	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef MULTITHREADING
 	rcu_unregister_thread();
@@ -84,7 +84,7 @@ START_TEST(failToFindNodeInOtherUA_NodeStore) {
 	ck_assert_int_ne(retval, UA_STATUSCODE_GOOD);
 	// finally
 	UA_Node_delete(n);
-	UA_NodeStore_releaseManagedNode(nr);
+	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef MULTITHREADING
 	rcu_unregister_thread();
@@ -114,8 +114,8 @@ START_TEST(findNodeInUA_NodeStoreWithSeveralEntries) {
 	ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 	ck_assert_ptr_eq((void*)nr, (void*)n3);
 	// finally
-	UA_NodeStore_releaseManagedNode(n3);
-	UA_NodeStore_releaseManagedNode(nr);
+	UA_NodeStore_release(n3);
+	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef MULTITHREADING
 	rcu_unregister_thread();
@@ -174,7 +174,7 @@ START_TEST(findNodeInExpandedNamespace) {
 	ck_assert_int_eq(nr->nodeId.identifier.numeric,n->nodeId.identifier.numeric);
 	// finally
 	UA_free((void*)n);
-	UA_NodeStore_releaseManagedNode(nr);
+	UA_NodeStore_release(nr);
 	UA_NodeStore_delete(ns);
 #ifdef MULTITHREADING
 	rcu_unregister_thread();
@@ -261,7 +261,7 @@ void *profileGetThread(void *arg) {
 		for (UA_Int32 i=test->min_val; i<max_val; i++) {
 			id.identifier.numeric = i;
 			UA_NodeStore_get(ns,&id, &cn);
-			UA_NodeStore_releaseManagedNode(cn);
+			UA_NodeStore_release(cn);
 		}
 	}
 	rcu_unregister_thread();
@@ -304,7 +304,7 @@ START_TEST(profileGetDelete) {
 	    for(i=0; i<N; i++) {
 	        id.identifier.numeric = i;
 			UA_NodeStore_get(ns,&id, &cn);
-			UA_NodeStore_releaseManagedNode(cn);
+			UA_NodeStore_release(cn);
         }
     }
 	end = clock();

+ 6 - 6
tools/generate_builtin.py

@@ -173,7 +173,7 @@ def createStructured(element):
         if t in fixed_size:
             printc('\t + sizeof(%(t)s) // %(n)s')
         elif t.find("*") != -1:
-            printc('\t + UA_Array_calcSizeBinary(ptr->%(n)sSize,&UA_['+ t[0:t.find("*")].upper() +
+            printc('\t + UA_Array_calcSizeBinary(ptr->%(n)sSize,&UA_TYPES['+ t[0:t.find("*")].upper() +
                    "],ptr->%(n)s)")
             has_fixed_size = False
         else:
@@ -188,7 +188,7 @@ def createStructured(element):
     UA_StatusCode retval = UA_STATUSCODE_GOOD;''')
     for n,t in membermap.iteritems():
         if t.find("*") != -1:
-            printc("\tretval |= UA_Array_encodeBinary(src->%(n)s,src->%(n)sSize,&UA_[" + t[0:t.find("*")].upper() + "],dst,offset);")
+            printc("\tretval |= UA_Array_encodeBinary(src->%(n)s,src->%(n)sSize,&UA_TYPES[" + t[0:t.find("*")].upper() + "],dst,offset);")
         else:
             printc('\tretval |= %(t)s_encodeBinary(&src->%(n)s,dst,offset);')
     printc("\treturn retval;\n}\n")
@@ -201,7 +201,7 @@ def createStructured(element):
     for n,t in membermap.iteritems():
         if t.find("*") != -1:
             printc('\tretval |= UA_Int32_decodeBinary(src,offset,&dst->%(n)sSize);')
-            printc('\tif(!retval) { retval |= UA_Array_decodeBinary(src,offset,dst->%(n)sSize,&UA_[' + t[0:t.find("*")].upper() + '],(void**)&dst->%(n)s); }')
+            printc('\tif(!retval) { retval |= UA_Array_decodeBinary(src,offset,dst->%(n)sSize,&UA_TYPES[' + t[0:t.find("*")].upper() + '],(void**)&dst->%(n)s); }')
             printc('\tif(retval) { dst->%(n)sSize = -1; }') # arrays clean up internally. But the size needs to be set here for the eventual deleteMembers.
         else:
             printc('\tretval |= %(t)s_decodeBinary(src,offset,&dst->%(n)s);')
@@ -224,7 +224,7 @@ UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     for n,t in membermap.iteritems():
         if not t in fixed_size: # dynamic size on the wire
             if t.find("*") != -1:
-		printc("\tUA_Array_delete((void*)p->%(n)s,p->%(n)sSize,&UA_["+t[0:t.find("*")].upper()+"]);")
+		printc("\tUA_Array_delete((void*)p->%(n)s,p->%(n)sSize,&UA_TYPES["+t[0:t.find("*")].upper()+"]);")
             else:
 		printc('\t%(t)s_deleteMembers(&p->%(n)s);')
     printc("}\n")
@@ -250,7 +250,7 @@ UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     for n,t in membermap.iteritems():
         if t.find("*") != -1:
             printc('\tdst->%(n)sSize = src->%(n)sSize;')
-            printc("\tretval |= UA_Array_copy(src->%(n)s, src->%(n)sSize,&UA_[" + t[0:t.find("*")].upper() + "],(void**)&dst->%(n)s);")
+            printc("\tretval |= UA_Array_copy(src->%(n)s, src->%(n)sSize,&UA_TYPES[" + t[0:t.find("*")].upper() + "],(void**)&dst->%(n)s);")
             continue
         if not t in fixed_size: # there are members of variable size    
             printc('\tretval |= %(t)s_copy(&src->%(n)s,&dst->%(n)s);')
@@ -267,7 +267,7 @@ UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     for i,(n,t) in enumerate(membermap.iteritems()):
         if t.find("*") != -1:
             printc('\tUA_Int32_print(&p->%(n)sSize, stream);')
-            printc("\tUA_Array_print(p->%(n)s, p->%(n)sSize, &UA_[" + t[0:t.find("*")].upper()+"], stream);")
+            printc("\tUA_Array_print(p->%(n)s, p->%(n)sSize, &UA_TYPES[" + t[0:t.find("*")].upper()+"], stream);")
         else:
             printc('\t%(t)s_print(&p->%(n)s,stream);')
         if i == len(membermap)-1:

+ 38 - 13
tools/generate_namespace.py

@@ -104,14 +104,10 @@ printh('''/**********************************************************
  */
 
 UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id);\n
-extern const UA_VTable_Entry UA_EXPORT *UA_;
+extern const UA_VTable_Entry UA_EXPORT *UA_TYPES;
+extern const UA_NodeId UA_EXPORT *UA_NODEIDS;
 
-/**
- * @brief the set of possible indices into UA_VTable
- *
- * Enumerated type to define the types that the open62541 stack can handle
- */
-enum UA_VTableIndex_enum {''')
+/** The entries of UA_TYPES can be accessed with the following indices */ ''')
 
 printc('''/**********************************************************
  * '''+args.outfile.split("/")[-1]+'''.cgen -- do not modify
@@ -138,15 +134,27 @@ for row in rows:
     else:
         name = "UA_" + row[0]
 	
-    printh("\t"+name.upper()+" = "+str(i)+",")
+    printh("#define "+name.upper()+" "+str(i))
     printc('\tcase '+row[1]+': retval='+name.upper()+'; break; //'+row[2])
     i = i+1
 
-printh("};\n")
+printh('\n#define SIZE_UA_VTABLE '+str(i));
+printh("") # newline
+printh("/** In UA_NODEIDS are the nodeids of the types, referencetypes and objects */")
+# assign indices to the reference types afterwards
+for row in rows:
+    if row[0] == "" or (row[2] != "ReferenceType" and (row[2] != "Object" or "_Encoding_Default" in row[0])):
+        continue
+    name = "UA_" + row[0]
+    printh("#define "+name.upper()+" "+str(i))
+    i=i+1
+
 printc('''\n}\nreturn retval;\n}\n''');
 
-printc('''const UA_VTable_Entry *UA_ = (UA_VTable_Entry[]){''')
-i = 0
+printh("") # newline
+printh("/** These are the actual (numeric) nodeids of the types, not the indices to the vtable */")
+
+printc('''const UA_VTable_Entry *UA_TYPES = (UA_VTable_Entry[]){''')
 for row in rows:
     if skipType(row):
         continue
@@ -156,7 +164,6 @@ for row in rows:
         name = "UA_ExtensionObject"
     else:
 	name = "UA_" + row[0]
-	i=i+1
     printh('#define '+name.upper()+'_NS0 '+row[1])
 
     printc("\t{.typeId={.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric=" + row[1] + "}" + 
@@ -181,7 +188,25 @@ for row in rows:
 
 printc('};')
 
-printh('\n#define SIZE_UA_VTABLE '+str(i));
+# make the nodeids available as well
+printc('''const UA_NodeId *UA_NODEIDS = (UA_NodeId[]){''')
+for row in rows:
+    if skipType(row):
+        continue
+    if row[0] == "BaseDataType":
+        name = "UA_Variant"
+    elif row[0] == "Structure":
+        name = "UA_ExtensionObject"
+    else:
+	name = "UA_" + row[0]
+    printc("\t{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = " + row[1] + "},")
+
+for row in rows:
+    if row[0] == "" or (row[2] != "ReferenceType" and (row[2] != "Object" or "_Encoding_Default" in row[0])):
+        continue
+    printc("\t{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = " + row[1] + "},")
+
+printc('};')
 
 printh('\n#endif /* OPCUA_NAMESPACE_0_H_ */')