Просмотр исходного кода

set point of interface to nodestore. defined ua-service-like operations to interact with generic nodestore
added namespaceManager to handle various datasources

= лет назад: 10
Родитель
Сommit
4b58940009

+ 5 - 2
CMakeLists.txt

@@ -19,7 +19,7 @@ set(lib_sources src/ua_types.c
                 ${PROJECT_BINARY_DIR}/src_generated/ua_namespace_0.c
                 src/ua_transport.c
                 ${PROJECT_BINARY_DIR}/src_generated/ua_transport_generated.c
-				src/ua_connection.c
+		src/ua_connection.c
                 src/ua_securechannel.c
                 src/ua_session.c
                 src/ua_util.c
@@ -27,7 +27,8 @@ set(lib_sources src/ua_types.c
                 src/server/ua_server.c
                 src/server/ua_securechannel_manager.c
                 src/server/ua_session_manager.c
-                src/server/ua_server_binary.c
+                src/server/ua_namespace_manager.c
+		src/server/ua_server_binary.c
                 src/server/ua_services_attribute.c
                 src/server/ua_services_session.c
                 src/server/ua_services_discovery.c
@@ -35,6 +36,7 @@ set(lib_sources src/ua_types.c
                 src/server/ua_services_nodemanagement.c
                 src/server/ua_services_view.c
                 src/server/ua_services_monitoreditems.c
+		
                 ${headers}
                 ${generated_headers})
 
@@ -110,6 +112,7 @@ if(ENABLE_MULTITHREADING)
     list(APPEND lib_sources src/server/ua_nodestore_concurrent.c)
 else()
     list(APPEND lib_sources src/server/ua_nodestore.c)
+    list(APPEND lib_sources src/server/ua_nodestoreExample.c)
 endif()
 
 add_library(open62541-objects OBJECT ${lib_sources}) # static version that exports all symbols

src/server/ua_nodestore_concurrent.c → examples/ua_nodestore_concurrent.c


+ 59 - 5
include/ua_server.h

@@ -24,7 +24,7 @@ extern "C" {
 #include "ua_types_generated.h"
 #include "ua_connection.h"
 #include "ua_log.h"
-//not good, is it?
+
 
 /** @defgroup server Server */
 
@@ -38,24 +38,71 @@ typedef struct UA_SecureChannelManager UA_SecureChannelManager;
 struct UA_SessionManager;
 typedef struct UA_SessionManager UA_SessionManager;
 
+
+
+
 struct UA_NodeStore;
 typedef struct UA_NodeStore UA_NodeStore;
 
-struct ServiceFunctionpointers;
-typedef struct ServiceFunctionpointers ServiceFunctionpointers;
+struct UA_NodeStoreExample;
+typedef struct UA_NodeStoreExample UA_NodeStoreExample;
+
+
+//struct UA_Namespace;
+//typedef struct UA_Namespace UA_Namespace;
+typedef struct UA_Namespace
+{
+	UA_UInt16 index;
+	UA_NodeStore *nodeStore;
+}UA_Namespace;
+
+struct UA_NamespaceManager;
+typedef struct UA_NamespaceManager UA_NamespaceManager;
+
+
+typedef UA_Int32 (*UA_NodeStore_addNodes)(UA_AddNodesItem *nodesToAdd,UA_UInt32 sizeNodesToAdd, UA_AddNodesResult* result, UA_DiagnosticInfo *diagnosticInfo);
+typedef UA_Int32 (*UA_NodeStore_addReferences)(UA_AddReferencesItem* referencesToAdd,UA_UInt32 sizeReferencesToAdd, UA_StatusCode *result, UA_DiagnosticInfo diagnosticInfo);
+
+typedef UA_Int32 (*UA_NodeStore_deleteNodes)(UA_DeleteNodesItem *nodesToDelete,UA_UInt32 sizeNodesToDelete, UA_StatusCode *result, UA_DiagnosticInfo *diagnosticInfo);
+typedef UA_Int32 (*UA_NodeStore_deleteReferences)(UA_DeleteReferencesItem referenceToDelete, UA_UInt32 sizeReferencesToDelete,UA_StatusCode result, UA_DiagnosticInfo diagnosticInfo);
+
+
+typedef UA_Int32 (*UA_NodeStore_readNodes)(UA_ReadValueId *readValueIds,UA_UInt32 sizeReadValueIds, UA_DataValue *value, UA_Boolean timeStampToReturn, UA_DiagnosticInfo *diagnosticInfo);
+typedef UA_Int32 (*UA_NodeStore_writeNodes)(UA_WriteValue *writeValues, UA_UInt32 sizeWriteValues, UA_StatusCode *result, UA_DiagnosticInfo *diagnosticInfo);
+typedef UA_Int32 (*UA_NodeStore_browseNodes)(UA_UInt32 requestedMaxReferencesPerNode, UA_BrowseDescription *browseDescriptions,UA_UInt32 sizeBrowseDescriptions, UA_BrowseResult *browseResult, UA_DiagnosticInfo *diagnosticInfo);
+
+
+
+
+struct  UA_NodeStore{
+	//new, set, get, remove,
+	UA_NodeStore_addNodes addNodes;
+	UA_NodeStore_deleteNodes deleteNodes;
+	UA_NodeStore_writeNodes writeNodes;
+	UA_NodeStore_readNodes readNodes;
+	UA_NodeStore_browseNodes browseNodes;
+	UA_NodeStore_addReferences addReferences;
+	UA_NodeStore_deleteReferences deleteReferences;
+};
+
+
+
 
 typedef struct UA_Server {
     UA_ApplicationDescription description;
     UA_SecureChannelManager *secureChannelManager;
     UA_SessionManager *sessionManager;
-    UA_NodeStore *nodestore;
+    UA_NamespaceManager* namespaceManager;
+    UA_NodeStoreExample *nodestore;
     UA_Logger logger;
     UA_ByteString serverCertificate;
 
+
     // todo: move these somewhere sane
     UA_ExpandedNodeId objectsNodeId;
     UA_NodeId hasComponentReferenceTypeId;
-    ServiceFunctionpointers *serviceImplementations;
+
+
 } UA_Server;
 
 void UA_EXPORT UA_Server_init(UA_Server *server, UA_String *endpointUrl);
@@ -71,6 +118,13 @@ UA_AddNodesResult UA_EXPORT UA_Server_addNode(UA_Server *server, UA_Node **node,
 void UA_EXPORT UA_Server_addReferences(UA_Server *server, const UA_AddReferencesRequest *request,
                                        UA_AddReferencesResponse *response);
 
+
+UA_Int32 UA_Server_addNamespace(UA_Server *server, UA_UInt16 namespaceIndex, UA_NodeStore *nodeStore);
+
+UA_Int32 UA_Server_removeNamespace(UA_Server *server, UA_UInt16 namespaceIndex);
+
+UA_Int32 UA_Server_setNodeStore(UA_Server *server, UA_UInt16 namespaceIndex, UA_NodeStore *nodeStore);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif

+ 66 - 329
src/server/ua_nodestore.c

@@ -2,356 +2,93 @@
 #include "ua_util.h"
 #include "ua_statuscodes.h"
 
-struct UA_NodeStore {
-    const UA_Node **entries;
-    UA_UInt32       size;
-    UA_UInt32       count;
-    UA_UInt32       sizePrimeIndex;
-};
 
-typedef UA_UInt32 hash_t;
-/* The size of the hash-map is always a prime number. They are chosen to be
-   close to the next power of 2. So the size ca. doubles with each prime. */
-static hash_t const primes[] = {
-    7,         13,         31,         61,         127,         251,
-    509,       1021,       2039,       4093,       8191,        16381,
-    32749,     65521,      131071,     262139,     524287,      1048573,
-    2097143,   4194301,    8388593,    16777213,   33554393,    67108859,
-    134217689, 268435399,  536870909,  1073741789, 2147483647,  4294967291
-};
 
-static INLINE hash_t mod(hash_t h, hash_t size) {
-    return h % size;
-}
-static INLINE hash_t mod2(hash_t h, hash_t size) {
-    return 1 + (h % (size - 2));
+UA_Int32 UA_NodeStore_registerAddNodesOperation(UA_NodeStore *nodeStore, UA_NodeStore_addNodes addNodes)
+{
+	if(nodeStore==UA_NULL){
+		return UA_ERROR;
+	}
+	nodeStore->addNodes = addNodes;
+	return UA_SUCCESS;
 }
 
-static INLINE UA_Int16 higher_prime_index(hash_t n) {
-    UA_UInt16 low  = 0;
-    UA_UInt16 high = sizeof(primes) / sizeof(hash_t);
-    while(low != high) {
-        UA_UInt16 mid = low + (high - low) / 2;
-        if(n > primes[mid])
-            low = mid + 1;
-        else
-            high = mid;
-    }
-    return low;
+UA_Int32 UA_NodeStore_registerAddReferencesOperation(UA_NodeStore *nodeStore, UA_NodeStore_addReferences addReferences)
+{
+	if(nodeStore==UA_NULL){
+		return UA_ERROR;
+	}
+	nodeStore->addReferences = addReferences;
+	return UA_SUCCESS;
 }
 
-/* Based on Murmur-Hash 3 by Austin Appleby (public domain, freely usable) */
-static INLINE hash_t hash_array(const UA_Byte *data, UA_UInt32 len, UA_UInt32 seed) {
-    const int32_t   nblocks = len / 4;
-    const uint32_t *blocks;
-
-    static const uint32_t c1 = 0xcc9e2d51;
-    static const uint32_t c2 = 0x1b873593;
-    static const uint32_t r1 = 15;
-    static const uint32_t r2 = 13;
-    static const uint32_t m  = 5;
-    static const uint32_t n  = 0xe6546b64;
-    hash_t hash = seed;
-
-    if(data == UA_NULL)
-        return 0;
-
-    blocks = (const uint32_t *)data;
-    for(int32_t i = 0;i < nblocks;i++) {
-        uint32_t k = blocks[i];
-        k    *= c1;
-        k     = (k << r1) | (k >> (32 - r1));
-        k    *= c2;
-        hash ^= k;
-        hash  = ((hash << r2) | (hash >> (32 - r2))) * m + n;
-    }
-
-    const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
-    uint32_t       k1   = 0;
-
-    switch(len & 3) {
-    case 3:
-        k1 ^= tail[2] << 16;
-
-    case 2:
-        k1 ^= tail[1] << 8;
-
-    case 1:
-        k1   ^= tail[0];
-        k1   *= c1;
-        k1    = (k1 << r1) | (k1 >> (32 - r1));
-        k1   *= c2;
-        hash ^= k1;
-    }
-
-    hash ^= len;
-    hash ^= (hash >> 16);
-    hash *= 0x85ebca6b;
-    hash ^= (hash >> 13);
-    hash *= 0xc2b2ae35;
-    hash ^= (hash >> 16);
-
-    return hash;
+UA_Int32 UA_NodeStore_registerDeleteNodesOperation(UA_NodeStore *nodeStore, UA_NodeStore_deleteNodes deleteNodes)
+{
+	if(nodeStore==UA_NULL){
+		return UA_ERROR;
+	}
+	nodeStore->deleteNodes = deleteNodes;
+	return UA_SUCCESS;
 }
 
-static INLINE hash_t hash(const UA_NodeId *n) {
-    switch(n->identifierType) {
-    case UA_NODEIDTYPE_NUMERIC:
-        /*  Knuth's multiplicative hashing */
-        return (n->identifier.numeric + n->namespaceIndex) * 2654435761;   // mod(2^32) is implicit
-
-    case UA_NODEIDTYPE_STRING:
-        return hash_array(n->identifier.string.data, n->identifier.string.length, n->namespaceIndex);
-
-    case UA_NODEIDTYPE_GUID:
-        return hash_array((UA_Byte *)&(n->identifier.guid), sizeof(UA_Guid), n->namespaceIndex);
-
-    case UA_NODEIDTYPE_BYTESTRING:
-        return hash_array((UA_Byte *)n->identifier.byteString.data, n->identifier.byteString.length, n->namespaceIndex);
-
-    default:
-        UA_assert(UA_FALSE);
-        return 0;
-    }
+UA_Int32 UA_NodeStore_registerDeleteReferencesOperation(UA_NodeStore *nodeStore, UA_NodeStore_deleteReferences deleteReferences)
+{
+	if(nodeStore==UA_NULL){
+		return UA_ERROR;
+	}
+	nodeStore->deleteReferences = deleteReferences;
+	return UA_SUCCESS;
 }
 
-static INLINE void clear_entry(UA_NodeStore *ns, const UA_Node **entry) {
-    const UA_Node *node;
-    if(entry == UA_NULL || *entry == UA_NULL)
-        return;
-
-    node = *entry;
-    switch(node->nodeClass) {
-    case UA_NODECLASS_OBJECT:
-        UA_ObjectNode_delete((UA_ObjectNode *)node);
-        break;
 
-    case UA_NODECLASS_VARIABLE:
-        UA_VariableNode_delete((UA_VariableNode *)node);
-        break;
-
-    case UA_NODECLASS_METHOD:
-        UA_MethodNode_delete((UA_MethodNode *)node);
-        break;
-
-    case UA_NODECLASS_OBJECTTYPE:
-        UA_ObjectTypeNode_delete((UA_ObjectTypeNode *)node);
-        break;
-
-    case UA_NODECLASS_VARIABLETYPE:
-        UA_VariableTypeNode_delete((UA_VariableTypeNode *)node);
-        break;
-
-    case UA_NODECLASS_REFERENCETYPE:
-        UA_ReferenceTypeNode_delete((UA_ReferenceTypeNode *)node);
-        break;
-
-    case UA_NODECLASS_DATATYPE:
-        UA_DataTypeNode_delete((UA_DataTypeNode *)node);
-        break;
-
-    case UA_NODECLASS_VIEW:
-        UA_ViewNode_delete((UA_ViewNode *)node);
-        break;
-
-    default:
-        UA_assert(UA_FALSE);
-        break;
-    }
-    entry = UA_NULL;
-    ns->count--;
+UA_Int32 UA_NodeStore_registerReadOperation(UA_NodeStore *nodeStore, UA_NodeStore_readNodes readNodes)
+{
+	if(nodeStore==UA_NULL){
+		return UA_ERROR;
+	}
+	nodeStore->readNodes = readNodes;
+	return UA_SUCCESS;
 }
 
-/* Returns UA_SUCCESS if an entry was found. Otherwise, UA_ERROR is returned and the "entry"
-   argument points to the first free entry under the NodeId. */
-static INLINE UA_Int32 find_entry(const UA_NodeStore *ns, const UA_NodeId *nodeid, const UA_Node ***entry) {
-    hash_t          h     = hash(nodeid);
-    UA_UInt32       size  = ns->size;
-    hash_t          index = mod(h, size);
-    const UA_Node **e     = &ns->entries[index];
-
-    if(*e == UA_NULL) {
-        *entry = e;
-        return UA_ERROR;
-    }
-
-    if(UA_NodeId_equal(&(*e)->nodeId, nodeid) == UA_EQUAL) {
-        *entry = e;
-        return UA_SUCCESS;
-    }
-
-    hash_t hash2 = mod2(h, size);
-    for(;;) {
-        index += hash2;
-        if(index >= size)
-            index -= size;
-
-        e = &ns->entries[index];
-
-        if(*e == UA_NULL) {
-            *entry = e;
-            return UA_ERROR;
-        }
-
-        if(UA_NodeId_equal(&(*e)->nodeId, nodeid) == UA_EQUAL) {
-            *entry = e;
-            return UA_SUCCESS;
-        }
-    }
-
-    /* NOTREACHED */
-    return UA_SUCCESS;
+UA_Int32 UA_NodeStore_registerWriteOperation(UA_NodeStore *nodeStore, UA_NodeStore_writeNodes writeNodes)
+{
+	if(nodeStore==UA_NULL){
+		return UA_ERROR;
+	}
+	nodeStore->writeNodes = writeNodes;
+	return UA_SUCCESS;
 }
 
-/* The following function changes size of memory allocated for the entries and
-   repeatedly inserts the table elements. The occupancy of the table after the
-   call will be about 50%. If memory allocation failures occur, this function
-   will return UA_ERROR. */
-static UA_Int32 expand(UA_NodeStore *ns) {
-    const UA_Node **nentries;
-    int32_t nsize;
-    UA_UInt32       nindex;
-
-    const UA_Node **oentries = ns->entries;
-    int32_t osize = ns->size;
-    const UA_Node **olimit   = &oentries[osize];
-    int32_t count = ns->count;
-
-    /* Resize only when table after removal of unused elements is either too full or too empty.  */
-    if(count * 2 < osize && (count * 8 > osize || osize <= 32))
-        return UA_SUCCESS;
-
-    nindex = higher_prime_index(count * 2);
-    nsize  = primes[nindex];
-
-    if(!(nentries = UA_alloc(sizeof(UA_Node *) * nsize)))
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-
-    memset(nentries, 0, nsize * sizeof(UA_Node *));
-    ns->entries = nentries;
-    ns->size    = nsize;
-    ns->sizePrimeIndex = nindex;
-
-    const UA_Node **p = oentries;
-    do {
-        if(*p != UA_NULL) {
-            const UA_Node **e;
-            find_entry(ns, &(*p)->nodeId, &e);  /* We know this returns an empty entry here */
-            *e = *p;
-        }
-        p++;
-    } while(p < olimit);
-
-    UA_free(oentries);
-    return UA_SUCCESS;
+UA_Int32 UA_NodeStore_registerBrowseOperation(UA_NodeStore *nodeStore, UA_NodeStore_browseNodes browseNodes)
+{
+	if(nodeStore==UA_NULL){
+		return UA_ERROR;
+	}
+	nodeStore->browseNodes = browseNodes;
+	return UA_SUCCESS;
 }
+/*
+UA_Boolean UA_NodeStore_nodeExists(UA_NodeStore* nodestore, const UA_NodeId *nodeId)
+{
+	UA_DataValue *value;
+	UA_ReadValueId readValueId;
+	readValueId.attributeId = UA_ATTRIBUTEWRITEMASK_NODEID;
+	readValueId.nodeId = nodeId;
+	readValueId.indexRange.data = UA_NULL;
+	readValueId.indexRange.length = 0;
+	UA_NodeStore_readNode r;
+
+	if(nodestore->readNodes(nodeId,readValueId,&value) == UA_SUCCESS &&
+			value->value.storage.data.dataPtr != UA_NULL){
+		return UA_TRUE;
+	}
+	return UA_FALSE;
 
-/**********************/
-/* Exported functions */
-/**********************/
-
-UA_Int32 UA_NodeStore_new(UA_NodeStore **result) {
-    UA_NodeStore *ns;
-    UA_UInt32     sizePrimeIndex, size;
-    if(!(ns = UA_alloc(sizeof(UA_NodeStore))))
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-
-    sizePrimeIndex = higher_prime_index(32);
-    size = primes[sizePrimeIndex];
-    if(!(ns->entries = UA_alloc(sizeof(UA_Node *) * size))) {
-        UA_free(ns);
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-    }
-
-    /* set entries to zero */
-    memset(ns->entries, 0, size * sizeof(UA_Node *));
-
-    *ns     = (UA_NodeStore) {ns->entries, size, 0, sizePrimeIndex };
-    *result = ns;
-    return UA_SUCCESS;
 }
+*/
 
-UA_Int32 UA_NodeStore_delete(UA_NodeStore *ns) {
-    UA_UInt32       size    = ns->size;
-    const UA_Node **entries = ns->entries;
 
-    for(UA_UInt32 i = 0;i < size;i++)
-        clear_entry(ns, &entries[i]);
-
-    UA_free(ns->entries);
-    UA_free(ns);
-    return UA_SUCCESS;
-}
 
-UA_Int32 UA_NodeStore_insert(UA_NodeStore *ns, UA_Node **node, UA_Byte flags) {
-    if(ns == UA_NULL || node == UA_NULL || *node == UA_NULL)
-        return UA_ERROR;
 
-    if(ns->size * 3 <= ns->count * 4) {
-        if(expand(ns) != UA_SUCCESS)
-            return UA_ERROR;
-    }
 
-    const UA_Node **entry;
-    UA_Int32 found = find_entry(ns, &(*node)->nodeId, &entry);
 
-    if(flags & UA_NODESTORE_INSERT_UNIQUE) {
-        if(found == UA_SUCCESS)
-            return UA_ERROR;    /* There is already an entry for that nodeid */
-        else
-            *entry = *node;
-    } else {
-        if(found == UA_SUCCESS)
-            clear_entry(ns, entry);
-        *entry = *node;
-    }
-
-    if(!(flags & UA_NODESTORE_INSERT_GETMANAGED))
-        *node = UA_NULL;
-
-    ns->count++;
-    return UA_SUCCESS;
-}
-
-UA_Int32 UA_NodeStore_get(const UA_NodeStore *ns, const UA_NodeId *nodeid, const UA_Node **managedNode) {
-    const UA_Node **entry;
-    if(ns == UA_NULL || nodeid == UA_NULL || managedNode == UA_NULL)
-        return UA_ERROR;
-
-    if(find_entry(ns, nodeid, &entry) != UA_SUCCESS)
-        return UA_ERROR;
-
-    *managedNode = *entry;
-    return UA_SUCCESS;
-}
-
-UA_Int32 UA_NodeStore_remove(UA_NodeStore *ns, const UA_NodeId *nodeid) {
-    const UA_Node **entry;
-    if(find_entry(ns, nodeid, &entry) != UA_SUCCESS)
-        return UA_ERROR;
-
-    // Check before if deleting the node makes the UA_NodeStore inconsistent.
-    clear_entry(ns, entry);
-
-    /* Downsize the hashmap if it is very empty */
-    if(ns->count * 8 < ns->size && ns->size > 32)
-        expand(ns);
-
-    return UA_SUCCESS;
-}
-
-UA_Int32 UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visitor) {
-    if(ns == UA_NULL || visitor == UA_NULL)
-        return UA_ERROR;
-
-    for(UA_UInt32 i = 0;i < ns->size;i++) {
-        const UA_Node *node = ns->entries[i];
-        if(node != UA_NULL)
-            visitor(node);
-    }
-    return UA_SUCCESS;
-}
-
-void UA_NodeStore_releaseManagedNode(const UA_Node *managed) {
-    ;
-}

+ 8 - 44
src/server/ua_nodestore.h

@@ -3,60 +3,24 @@
 
 #include "ua_server.h"
 
-/**
-   @ingroup server
 
-   @defgroup nodestore NodeStore
 
-   @brief The nodestore is the central storage for nodes in the UA address
-   space. Internally, the nodestore is realised as hash-map where nodes are
-   stored and retrieved with their nodeid.
 
-   The nodes in the nodestore are immutable. To change the content of a node, it
-   needs to be replaced as a whole. When a node is inserted into the namespace,
-   it gets replaced with a pointer to a managed node. Managed nodes shall never
-   be freed by the user. This is done by the namespace when the node is removed
-   and no readers (in other threads) access the node.
-
-   @{
- */
-
-/** @brief Create a new namespace */
-UA_Int32 UA_NodeStore_new(UA_NodeStore **result);
-
-/** @brief Delete the namespace and all nodes in it */
-UA_Int32 UA_NodeStore_delete(UA_NodeStore *ns);
+UA_Int32 UA_NodeStore_registerAddNodesOperation(UA_NodeStore *nodeStore, UA_NodeStore_addNodes addNode);
+UA_Int32 UA_NodeStore_registerAddReferenceOperation(UA_NodeStore *nodeStore, UA_NodeStore_addReferences addReference);
+UA_Int32 UA_NodeStore_registerDeleteNodesOperation(UA_NodeStore *nodeStore, UA_NodeStore_deleteNodes deleteNode);
+UA_Int32 UA_NodeStore_registerDeleteReferencesOperation(UA_NodeStore *nodeStore, UA_NodeStore_deleteReferences deleteReference);
+UA_Int32 UA_NodeStore_registerReadOperation(UA_NodeStore *nodeStore, UA_NodeStore_readNodes readNode);
+UA_Int32 UA_NodeStore_registerWriteOperation(UA_NodeStore *nodeStore, UA_NodeStore_writeNodes writeNode);
+UA_Int32 UA_NodeStore_registerBrowseOperation(UA_NodeStore *nodeStore, UA_NodeStore_browseNodes browseNode);
 
 #define UA_NODESTORE_INSERT_UNIQUE 1
 #define UA_NODESTORE_INSERT_GETMANAGED 2
-/** @brief Insert a new node into the namespace
-
-    With the UNIQUE flag, the node is only inserted if the nodeid does not
-    already exist. With the GETMANAGED flag, the node pointer is replaced with
-    the managed pointer. Otherwise, it is set to UA_NULL. */
-UA_Int32 UA_NodeStore_insert(UA_NodeStore *ns, UA_Node **node, UA_Byte flags);
-
-/** @brief Remove a node from the namespace. Always succeeds, even if the node
-    was not found. */
-UA_Int32 UA_NodeStore_remove(UA_NodeStore *ns, const UA_NodeId *nodeid);
 
-/** @brief Retrieve a node (read-only) from the namespace. Nodes are immutable.
-    They can only be replaced. After the Node is no longer used, the locked
-    entry needs to be released. */
-UA_Int32 UA_NodeStore_get(const UA_NodeStore *ns, const UA_NodeId *nodeid,
-                          const UA_Node **managedNode);
 
-/** @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);
 
-/** @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. */
-typedef void (*UA_NodeStore_nodeVisitor)(const UA_Node *node);
 
-/** @brief Iterate over all nodes in a namespace. */
-UA_Int32 UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visitor);
+UA_Boolean UA_NodeStore_nodeExists(UA_NodeId nodeId);
 
-/// @} /* end of group */
 
 #endif /* UA_NODESTORE_H_ */

+ 39 - 48
src/server/ua_server.c

@@ -1,4 +1,5 @@
 #include "ua_server.h"
+#include "ua_nodestoreExample.h"
 #include "ua_services_internal.h" // AddReferences
 #include "ua_namespace_0.h"
 #include "ua_securechannel_manager.h"
@@ -10,16 +11,13 @@ UA_Int32 UA_Server_deleteMembers(UA_Server *server) {
     UA_ApplicationDescription_deleteMembers(&server->description);
     UA_SecureChannelManager_delete(server->secureChannelManager);
     UA_SessionManager_delete(server->sessionManager);
-    UA_NodeStore_delete(server->nodestore);
+    UA_NodeStoreExample_delete(server->nodestore);
     UA_ByteString_deleteMembers(&server->serverCertificate);
     return UA_SUCCESS;
 }
 
 void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
-
-	server->serviceImplementations = (ServiceFunctionpointers*)UA_alloc(sizeof(ServiceFunctionpointers));
-
-	UA_ExpandedNodeId_init(&server->objectsNodeId);
+    UA_ExpandedNodeId_init(&server->objectsNodeId);
     server->objectsNodeId.nodeId.identifier.numeric = 85;
 
     UA_NodeId_init(&server->hasComponentReferenceTypeId);
@@ -27,12 +25,6 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
 
     UA_ApplicationDescription_init(&server->description);
     UA_ByteString_init(&server->serverCertificate);
-
-
-
-
-
-
 #define MAXCHANNELCOUNT 100
 #define STARTCHANNELID 1
 #define TOKENLIFETIME 10000
@@ -46,7 +38,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_SessionManager_new(&server->sessionManager, MAXSESSIONCOUNT, SESSIONLIFETIME,
                           STARTSESSIONID);
 
-    UA_NodeStore_new(&server->nodestore);
+    UA_NodeStoreExample_new(&server->nodestore);
     //ns0: C2UA_STRING("http://opcfoundation.org/UA/"));
     //ns1: C2UA_STRING("http://localhost:16664/open62541/"));
 
@@ -87,7 +79,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     NODE##REFTYPE##TARGET_NODEID.targetId = TARGET_NODEID; \
     AddReference(server->nodestore, (UA_Node *)NODE, &NODE##REFTYPE##TARGET_NODEID); \
     } while(0)
-    
+
     UA_ReferenceTypeNode *references;
     UA_ReferenceTypeNode_new(&references);
     references->nodeId    = RefTypeId_References.nodeId;
@@ -97,7 +89,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_LocalizedText_copycstring("References", &references->description);
     references->isAbstract = UA_TRUE;
     references->symmetric  = UA_TRUE;
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&references, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&references, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hierarchicalreferences;
     UA_ReferenceTypeNode_new(&hierarchicalreferences);
@@ -109,7 +101,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hierarchicalreferences->isAbstract = UA_TRUE;
     hierarchicalreferences->symmetric  = UA_FALSE;
     ADDREFERENCE(hierarchicalreferences, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_References);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hierarchicalreferences, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hierarchicalreferences, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *nonhierarchicalreferences;
     UA_ReferenceTypeNode_new(&nonhierarchicalreferences);
@@ -121,7 +113,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     nonhierarchicalreferences->isAbstract = UA_TRUE;
     nonhierarchicalreferences->symmetric  = UA_FALSE;
     ADDREFERENCE(nonhierarchicalreferences, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_References);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&nonhierarchicalreferences, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&nonhierarchicalreferences, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *haschild;
     UA_ReferenceTypeNode_new(&haschild);
@@ -133,7 +125,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     haschild->isAbstract = UA_TRUE;
     haschild->symmetric  = UA_FALSE;
     ADDREFERENCE(haschild, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&haschild, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&haschild, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *organizes;
     UA_ReferenceTypeNode_new(&organizes);
@@ -146,7 +138,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     organizes->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("OrganizedBy", &organizes->inverseName);
     ADDREFERENCE(organizes, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&organizes, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&organizes, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *haseventsource;
     UA_ReferenceTypeNode_new(&haseventsource);
@@ -159,7 +151,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     haseventsource->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("EventSourceOf", &haseventsource->inverseName);
     ADDREFERENCE(haseventsource, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&haseventsource, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&haseventsource, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hasmodellingrule;
     UA_ReferenceTypeNode_new(&hasmodellingrule);
@@ -172,7 +164,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hasmodellingrule->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("ModellingRuleOf", &hasmodellingrule->inverseName);
     ADDREFERENCE(hasmodellingrule, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hasmodellingrule, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasmodellingrule, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hasencoding;
     UA_ReferenceTypeNode_new(&hasencoding);
@@ -185,7 +177,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hasencoding->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("EncodingOf", &hasencoding->inverseName);
     ADDREFERENCE(hasencoding, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hasencoding, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasencoding, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hasdescription;
     UA_ReferenceTypeNode_new(&hasdescription);
@@ -198,7 +190,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hasdescription->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("DescriptionOf", &hasdescription->inverseName);
     ADDREFERENCE(hasdescription, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hasdescription, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasdescription, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hastypedefinition;
     UA_ReferenceTypeNode_new(&hastypedefinition);
@@ -211,7 +203,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hastypedefinition->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("TypeDefinitionOf", &hastypedefinition->inverseName);
     ADDREFERENCE(hastypedefinition, RefTypeId_HasSubtype, UA_TRUE,  RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hastypedefinition, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hastypedefinition, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *generatesevent;
     UA_ReferenceTypeNode_new(&generatesevent);
@@ -224,7 +216,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     generatesevent->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("GeneratedBy", &generatesevent->inverseName);
     ADDREFERENCE(generatesevent, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&generatesevent, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&generatesevent, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *aggregates;
     UA_ReferenceTypeNode_new(&aggregates);
@@ -236,7 +228,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     aggregates->isAbstract = UA_TRUE;
     aggregates->symmetric  = UA_FALSE;
     ADDREFERENCE(aggregates, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HasChild);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&aggregates, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&aggregates, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hassubtype;
     UA_ReferenceTypeNode_new(&hassubtype);
@@ -249,7 +241,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hassubtype->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("SubtypeOf", &hassubtype->inverseName);
     ADDREFERENCE(hassubtype, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HasChild);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hassubtype, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hassubtype, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hasproperty;
     UA_ReferenceTypeNode_new(&hasproperty);
@@ -262,7 +254,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hasproperty->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("PropertyOf", &hasproperty->inverseName);
     ADDREFERENCE(hasproperty, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_Aggregates);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hasproperty, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasproperty, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hascomponent;
     UA_ReferenceTypeNode_new(&hascomponent);
@@ -275,7 +267,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hascomponent->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("ComponentOf", &hascomponent->inverseName);
     ADDREFERENCE(hascomponent, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_Aggregates);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hascomponent, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hascomponent, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hasnotifier;
     UA_ReferenceTypeNode_new(&hasnotifier);
@@ -288,7 +280,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hasnotifier->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("NotifierOf", &hasnotifier->inverseName);
     ADDREFERENCE(hasnotifier, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HasEventSource);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hasnotifier, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasnotifier, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hasorderedcomponent;
     UA_ReferenceTypeNode_new(&hasorderedcomponent);
@@ -301,7 +293,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hasorderedcomponent->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("OrderedComponentOf", &hasorderedcomponent->inverseName);
     ADDREFERENCE(hasorderedcomponent, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_HasComponent);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hasorderedcomponent, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasorderedcomponent, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hasmodelparent;
     UA_ReferenceTypeNode_new(&hasmodelparent);
@@ -314,7 +306,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hasmodelparent->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("ModelParentOf", &hasmodelparent->inverseName);
     ADDREFERENCE(hasmodelparent, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hasmodelparent, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hasmodelparent, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *fromstate;
     UA_ReferenceTypeNode_new(&fromstate);
@@ -327,7 +319,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     fromstate->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("ToTransition", &fromstate->inverseName);
     ADDREFERENCE(fromstate, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&fromstate, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&fromstate, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *tostate;
     UA_ReferenceTypeNode_new(&tostate);
@@ -340,7 +332,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     tostate->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("FromTransition", &tostate->inverseName);
     ADDREFERENCE(tostate, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&tostate, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&tostate, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hascause;
     UA_ReferenceTypeNode_new(&hascause);
@@ -353,7 +345,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hascause->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("MayBeCausedBy", &hascause->inverseName);
     ADDREFERENCE(hascause, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hascause, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hascause, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *haseffect;
     UA_ReferenceTypeNode_new(&haseffect);
@@ -366,7 +358,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     haseffect->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("MayBeEffectedBy", &haseffect->inverseName);
     ADDREFERENCE(haseffect, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_NonHierarchicalReferences);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&haseffect, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&haseffect, UA_NODESTORE_INSERT_UNIQUE);
 
     UA_ReferenceTypeNode *hashistoricalconfiguration;
     UA_ReferenceTypeNode_new(&hashistoricalconfiguration);
@@ -379,7 +371,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     hashistoricalconfiguration->symmetric  = UA_FALSE;
     UA_LocalizedText_copycstring("HistoricalConfigurationOf", &hashistoricalconfiguration->inverseName);
     ADDREFERENCE(hashistoricalconfiguration, RefTypeId_HasSubtype, UA_TRUE, RefTypeId_Aggregates);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&hashistoricalconfiguration, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&hashistoricalconfiguration, UA_NODESTORE_INSERT_UNIQUE);
 
 
     // ObjectTypes (Ids only)
@@ -404,7 +396,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_QualifiedName_copycstring("FolderType", &folderType->browseName);
     UA_LocalizedText_copycstring("FolderType", &folderType->displayName);
     UA_LocalizedText_copycstring("FolderType", &folderType->description);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&folderType, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&folderType, UA_NODESTORE_INSERT_UNIQUE);
 
     // Root
     UA_ObjectNode *root;
@@ -419,7 +411,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     ADDREFERENCE(root, RefTypeId_Organizes, UA_FALSE, ObjId_TypesFolder);
     ADDREFERENCE(root, RefTypeId_Organizes, UA_FALSE, ObjId_ViewsFolder);
     /* root becomes a managed node. we need to release it at the end.*/
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&root, UA_NODESTORE_INSERT_UNIQUE | UA_NODESTORE_INSERT_GETMANAGED);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&root, UA_NODESTORE_INSERT_UNIQUE | UA_NODESTORE_INSERT_GETMANAGED);
 
     // Objects
     UA_ObjectNode *objects;
@@ -431,7 +423,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_LocalizedText_copycstring("Objects", &objects->description);
     ADDREFERENCE(objects, RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType);
     ADDREFERENCE(objects, RefTypeId_Organizes, UA_FALSE, ObjId_Server);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&objects, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&objects, UA_NODESTORE_INSERT_UNIQUE);
 
     // Types
     UA_ObjectNode *types;
@@ -442,7 +434,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_LocalizedText_copycstring("Types", &types->displayName);
     UA_LocalizedText_copycstring("Types", &types->description);
     ADDREFERENCE(types, RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&types, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&types, UA_NODESTORE_INSERT_UNIQUE);
 
     // Views
     UA_ObjectNode *views;
@@ -453,7 +445,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     UA_LocalizedText_copycstring("Views", &views->displayName);
     UA_LocalizedText_copycstring("Views", &views->description);
     ADDREFERENCE(views, RefTypeId_HasTypeDefinition, UA_FALSE, ObjTypeId_FolderType);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&views, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&views, UA_NODESTORE_INSERT_UNIQUE);
 
     // Server
     UA_ObjectNode *servernode;
@@ -467,7 +459,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     ADDREFERENCE(servernode, RefTypeId_HasComponent, UA_FALSE, ObjId_NamespaceArray);
     ADDREFERENCE(servernode, RefTypeId_HasProperty, UA_FALSE, ObjId_ServerStatus);
     ADDREFERENCE(servernode, RefTypeId_HasProperty, UA_FALSE, ObjId_ServerArray);
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&servernode, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&servernode, UA_NODESTORE_INSERT_UNIQUE);
 
     // NamespaceArray
     UA_VariableNode *namespaceArray;
@@ -491,7 +483,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     namespaceArray->valueRank       = 1;
     namespaceArray->minimumSamplingInterval = 1.0;
     namespaceArray->historizing     = UA_FALSE;
-    UA_NodeStore_insert(server->nodestore, (UA_Node**)&namespaceArray, UA_NODESTORE_INSERT_UNIQUE);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&namespaceArray, UA_NODESTORE_INSERT_UNIQUE);
 
     // ServerStatus
     UA_VariableNode *serverstatus;
@@ -517,7 +509,7 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     serverstatus->value.vt          = &UA_[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);
+    UA_NodeStoreExample_insert(server->nodestore, (UA_Node**)&serverstatus, UA_NODESTORE_INSERT_UNIQUE);
 
     // State (Component of ServerStatus)
     UA_VariableNode *state;
@@ -532,9 +524,9 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
     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_NodeStoreExample_insert(server->nodestore, (UA_Node**)&state, UA_NODESTORE_INSERT_UNIQUE);
 
-    UA_NodeStore_releaseManagedNode((const UA_Node *)root);
+    UA_NodeStoreExample_releaseManagedNode((const UA_Node *)root);
 }
 
 UA_AddNodesResult UA_Server_addNode(UA_Server *server, UA_Node **node, UA_ExpandedNodeId *parentNodeId,
@@ -544,8 +536,7 @@ UA_AddNodesResult UA_Server_addNode(UA_Server *server, UA_Node **node, UA_Expand
 
 void UA_Server_addReference(UA_Server *server, const UA_AddReferencesRequest *request,
                             UA_AddReferencesResponse *response) {
-
-	server->serviceImplementations->AddReferences(server, &adminSession, request, response);
+    Service_AddReferences(server, &adminSession, request, response);
 }
 
 UA_AddNodesResult UA_Server_addScalarVariableNode(UA_Server *server, UA_String *browseName, void *value,

+ 22 - 44
src/server/ua_server_binary.c

@@ -6,10 +6,6 @@
 #include "ua_session_manager.h"
 #include "ua_util.h"
 
-
-
-
-
 static UA_Int32 UA_ByteStringArray_deleteMembers(UA_ByteStringArray *stringarray) {
     if(!stringarray)
         return UA_ERROR;
@@ -25,7 +21,6 @@ static void processHello(UA_Connection *connection, const UA_ByteString *msg,
         connection->close(connection->callbackHandle);
         return;
     }
-
     connection->remoteConf.maxChunkCount   = helloMessage.maxChunkCount;
     connection->remoteConf.maxMessageSize  = helloMessage.maxMessageSize;
     connection->remoteConf.protocolVersion = helloMessage.protocolVersion;
@@ -89,7 +84,7 @@ static void processOpen(UA_Connection *connection, UA_Server *server,
     // perform request
     UA_OpenSecureChannelResponse p;
     UA_OpenSecureChannelResponse_init(&p);
-    server->serviceImplementations->OpenSecureChannel(server, connection, &r, &p);
+    Service_OpenSecureChannel(server, connection, &r, &p);
 
     // response
     UA_TcpMessageHeader respHeader;
@@ -136,36 +131,20 @@ static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r
             return;                  \
         } } while(0)
 
-#define INVOKE_SERVICE(TYPE) do {  \
-        if(server->serviceImplementations->TYPE != UA_NULL){ \
-			UA_##TYPE##Request p;  \
-			UA_##TYPE##Response r; \
-			CHECK_PROCESS(UA_##TYPE##Request_decodeBinary(msg, pos, &p),; );                                  \
-			UA_##TYPE##Response_init(&r);                                                                     \
-			init_response_header(&p.requestHeader, &r.responseHeader);                                        \
-			DBG_VERBOSE(printf("Invoke Service: %s\n", # TYPE));    \
-			server->serviceImplementations->TYPE(server, channel->session, &p, &r);  \
-			DBG_VERBOSE(printf("Finished Service: %s\n", # TYPE));                                            \
-			UA_ByteString_newMembers(message, UA_##TYPE##Response_calcSizeBinary(&r)); \
-			UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset);     \
-			UA_##TYPE##Request_deleteMembers(&p);                                                             \
-			UA_##TYPE##Response_deleteMembers(&r);                                                            \
-			responseType = requestType.nodeId.identifier.numeric + 3; \
-		}else { \
-	        printf("SL_processMessage - unknown request, namespace=%d, request=%d\n", \
-	               requestType.nodeId.namespaceIndex, requestType.nodeId.identifier.numeric); \
-	        UA_RequestHeader  p; \
-	        UA_ResponseHeader r; \
-	        CHECK_PROCESS(UA_RequestHeader_decodeBinary(msg, pos, &p),; ); \
-	        UA_ResponseHeader_init(&r); \
-	        r.requestHandle = p.requestHandle; \
-	        r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED; \
-	        UA_ByteString_newMembers(message, UA_ResponseHeader_calcSizeBinary(&r)); \
-	        UA_ResponseHeader_encodeBinary(&r, message, &sendOffset); \
-	        UA_RequestHeader_deleteMembers(&p); \
-	        UA_ResponseHeader_deleteMembers(&r); \
-	        responseType = UA_RESPONSEHEADER_NS0 + 2; \
-		}\
+#define INVOKE_SERVICE(TYPE) do {                                                                         \
+        UA_##TYPE##Request p;                                                                             \
+        UA_##TYPE##Response r;                                                                            \
+        CHECK_PROCESS(UA_##TYPE##Request_decodeBinary(msg, pos, &p),; );                                  \
+        UA_##TYPE##Response_init(&r);                                                                     \
+        init_response_header(&p.requestHeader, &r.responseHeader);                                        \
+        DBG_VERBOSE(printf("Invoke Service: %s\n", # TYPE));                                              \
+        Service_##TYPE(server, channel->session, &p, &r);                                                 \
+        DBG_VERBOSE(printf("Finished Service: %s\n", # TYPE));                                            \
+        UA_ByteString_newMembers(message, UA_##TYPE##Response_calcSizeBinary(&r)); \
+        UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset);     \
+        UA_##TYPE##Request_deleteMembers(&p);                                                             \
+        UA_##TYPE##Response_deleteMembers(&r);                                                            \
+        responseType = requestType.nodeId.identifier.numeric + 3;                                         \
 } while(0)
 
 static void processMessage(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
@@ -184,7 +163,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
 
     channel->sequenceNumber = sequenceHeader.sequenceNumber;
     channel->requestId = sequenceHeader.requestId;
-    // todogo
+    // todo
     //UA_SecureChannel_checkSequenceNumber(channel,sequenceHeader.sequenceNumber);
     //UA_SecureChannel_checkRequestId(channel,sequenceHeader.requestId);
 
@@ -211,7 +190,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         CHECK_PROCESS(UA_GetEndpointsRequest_decodeBinary(msg, pos, &p),; );
         UA_GetEndpointsResponse_init(&r);
         init_response_header(&p.requestHeader, &r.responseHeader);
-        server->serviceImplementations->GetEndpoints(server, &p, &r);
+        Service_GetEndpoints(server, &p, &r);
         UA_ByteString_newMembers(message, UA_GetEndpointsResponse_calcSizeBinary(&r));
         UA_GetEndpointsResponse_encodeBinary(&r, message, &sendOffset);
         UA_GetEndpointsRequest_deleteMembers(&p);
@@ -226,8 +205,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         CHECK_PROCESS(UA_CreateSessionRequest_decodeBinary(msg, pos, &p),; );
         UA_CreateSessionResponse_init(&r);
         init_response_header(&p.requestHeader, &r.responseHeader);
-        server->serviceImplementations->CreateSession(server, channel, &p, &r);
-        //Service_CreateSession(server, channel,  &p, &r);
+        Service_CreateSession(server, channel,  &p, &r);
         UA_ByteString_newMembers(message, UA_CreateSessionResponse_calcSizeBinary(&r));
         UA_CreateSessionResponse_encodeBinary(&r, message, &sendOffset);
         UA_CreateSessionRequest_deleteMembers(&p);
@@ -243,7 +221,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         UA_ActivateSessionResponse_init(&r);
         init_response_header(&p.requestHeader, &r.responseHeader);
 
-        server->serviceImplementations->ActivateSession(server, channel,  &p, &r);
+        Service_ActivateSession(server, channel,  &p, &r);
         UA_ByteString_newMembers(message, UA_ActivateSessionResponse_calcSizeBinary(&r));
         UA_ActivateSessionResponse_encodeBinary(&r, message, &sendOffset);
         UA_ActivateSessionRequest_deleteMembers(&p);
@@ -258,7 +236,8 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         CHECK_PROCESS(UA_CloseSessionRequest_decodeBinary(msg, pos, &p),; );
         UA_CloseSessionResponse_init(&r);
         init_response_header(&p.requestHeader, &r.responseHeader);
-        server->serviceImplementations->CloseSession(server, &p, &r);
+
+        Service_CloseSession(server, &p, &r);
         UA_ByteString_newMembers(message, UA_CloseSessionResponse_calcSizeBinary(&r));
         UA_CloseSessionResponse_encodeBinary(&r, message, &sendOffset);
         UA_CloseSessionRequest_deleteMembers(&p);
@@ -360,8 +339,7 @@ static void processClose(UA_Connection *connection, UA_Server *server, const UA_
     UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
 
 	//the two last parameter is ignored since no answer is needed
-    server->serviceImplementations->CloseSecureChannel(server,secureChannelId);
-	//Service_CloseSecureChannel(server, secureChannelId);
+	Service_CloseSecureChannel(server, secureChannelId);
 }
 
 UA_Int32 UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg) {

+ 37 - 183
src/server/ua_services.h

@@ -6,161 +6,6 @@
 #include "ua_server.h"
 #include "ua_session.h"
 
-#define DEFINE_SERVICE_TYPEDEF(TYPE)   \
-		typedef void (*Service_##TYPE##_funcPtr)(UA_Server *,UA_Session *,const UA_##TYPE##Request*,UA_##TYPE##Response *) ;
-
-DEFINE_SERVICE_TYPEDEF(FindServers)
-
-typedef void (*Service_GetEndpoints_funcPtr)(UA_Server *, const UA_GetEndpointsRequest*, UA_GetEndpointsResponse *) ;
-
-DEFINE_SERVICE_TYPEDEF(RegisterServer)
-
-typedef void (*Service_OpenSecureChannel_funcPtr)(UA_Server *,const UA_Connection*,UA_OpenSecureChannelRequest*, UA_OpenSecureChannelResponse *) ;
-typedef void (*Service_CloseSecureChannel_funcPtr)(UA_Server *, UA_Int32 );
-
-typedef void (*Service_CreateSession_funcPtr)(UA_Server *, UA_SecureChannel*, const UA_CreateSessionRequest*, UA_CreateSessionResponse *) ;
-typedef void (*Service_ActivateSession_funcPtr)(UA_Server *, UA_SecureChannel*, const UA_ActivateSessionRequest*, UA_ActivateSessionResponse *) ;
-typedef void (*Service_CloseSession_funcPtr)(UA_Server *, const UA_CloseSessionRequest*, UA_CloseSessionResponse *) ;
-
-DEFINE_SERVICE_TYPEDEF(Cancel)
-
-DEFINE_SERVICE_TYPEDEF(AddNodes)
-DEFINE_SERVICE_TYPEDEF(AddReferences)
-DEFINE_SERVICE_TYPEDEF(DeleteNodes)
-DEFINE_SERVICE_TYPEDEF(DeleteReferences)
-DEFINE_SERVICE_TYPEDEF(Browse)
-DEFINE_SERVICE_TYPEDEF(BrowseNext)
-DEFINE_SERVICE_TYPEDEF(TranslateBrowsePathsToNodeIds)
-DEFINE_SERVICE_TYPEDEF(RegisterNodes)
-DEFINE_SERVICE_TYPEDEF(UnregisterNodes)
-
-DEFINE_SERVICE_TYPEDEF(QueryFirst)
-DEFINE_SERVICE_TYPEDEF(QueryNext)
-
-DEFINE_SERVICE_TYPEDEF(Read)
-DEFINE_SERVICE_TYPEDEF(HistoryRead)
-DEFINE_SERVICE_TYPEDEF(Write)
-DEFINE_SERVICE_TYPEDEF(HistoryUpdate)
-
-DEFINE_SERVICE_TYPEDEF(Call)
-
-DEFINE_SERVICE_TYPEDEF(CreateMonitoredItems)
-DEFINE_SERVICE_TYPEDEF(ModifyMonitoredItems)
-DEFINE_SERVICE_TYPEDEF(SetMonitoringMode)
-DEFINE_SERVICE_TYPEDEF(SetTriggering)
-DEFINE_SERVICE_TYPEDEF(DeleteMonitoredItems)
-
-DEFINE_SERVICE_TYPEDEF(CreateSubscription)
-DEFINE_SERVICE_TYPEDEF(ModifySubscription)
-DEFINE_SERVICE_TYPEDEF(SetPublishingMode)
-DEFINE_SERVICE_TYPEDEF(Publish)
-DEFINE_SERVICE_TYPEDEF(Republish)
-DEFINE_SERVICE_TYPEDEF(TransferSubscriptions)
-DEFINE_SERVICE_TYPEDEF(DeleteSubscriptions)
-
-struct ServiceFunctionpointers {
-	Service_FindServers_funcPtr FindServers;
-	Service_GetEndpoints_funcPtr GetEndpoints;
-	Service_RegisterServer_funcPtr RegisterServer;
-
-	Service_OpenSecureChannel_funcPtr OpenSecureChannel;
-	Service_CloseSecureChannel_funcPtr CloseSecureChannel;
-
-	Service_CreateSession_funcPtr CreateSession;
-	Service_ActivateSession_funcPtr ActivateSession;
-	Service_CloseSession_funcPtr CloseSession;
-	Service_Cancel_funcPtr Cancel;
-
-	Service_AddNodes_funcPtr AddNodes;
-	Service_AddReferences_funcPtr AddReferences;
-	Service_DeleteNodes_funcPtr DeleteNodes;
-	Service_DeleteReferences_funcPtr DeleteReferences;
-	Service_Browse_funcPtr Browse;
-	Service_BrowseNext_funcPtr BrowseNext;
-	Service_TranslateBrowsePathsToNodeIds_funcPtr TranslateBrowsePathsToNodeIds;
-	Service_RegisterNodes_funcPtr RegisterNodes;
-	Service_UnregisterNodes_funcPtr UnregisterNodes;
-
-	Service_QueryFirst_funcPtr QueryFirst;
-	Service_QueryNext_funcPtr QueryNext;
-
-	Service_Read_funcPtr Read;
-	Service_HistoryRead_funcPtr HistoryRead;
-	Service_Write_funcPtr Write;
-	Service_HistoryUpdate_funcPtr HistoryUpdate;
-	Service_Call_funcPtr Call;
-
-	Service_CreateMonitoredItems_funcPtr CreateMonitoredItems;
-	Service_ModifyMonitoredItems_funcPtr ModifyMonitoredItems;
-	Service_SetMonitoringMode_funcPtr SetMonitoringMode;
-	Service_SetTriggering_funcPtr SetTriggering;
-	Service_DeleteMonitoredItems_funcPtr DeleteMonitoredItems;
-
-	Service_CreateSubscription_funcPtr CreateSubscription;
-	Service_ModifySubscription_funcPtr ModifySubscription;
-	Service_SetPublishingMode_funcPtr SetPublishingMode;
-	Service_Publish_funcPtr Publish;
-	Service_Republish_funcPtr Republish;
-	Service_TransferSubscriptions_funcPtr TransferSubscription;
-	Service_DeleteSubscriptions_funcPtr DeleteSubscription;
-};
-
-void UA_registerDiscoveryServiceSet(ServiceFunctionpointers *sfp,
-Service_FindServers_funcPtr findServers,
-Service_GetEndpoints_funcPtr getEndpoints,
-Service_RegisterServer_funcPtr registerServer);
-
-void UA_registerSecureChannelServiceSet(ServiceFunctionpointers *sfp,
-		Service_OpenSecureChannel_funcPtr openSecureChannel,
-		Service_CloseSecureChannel_funcPtr closeSecureChannel);
-
-void UA_registerSessionServiceSet(ServiceFunctionpointers *sfp,
-		Service_CreateSession_funcPtr createSession,
-		Service_ActivateSession_funcPtr activateSession,
-		Service_CloseSession_funcPtr closeSession,
-		Service_Cancel_funcPtr cancel);
-
-void UA_registerNodeManagementServiceSet(ServiceFunctionpointers *sfp,
-		Service_AddNodes_funcPtr addNodes,
-		Service_AddReferences_funcPtr addReferences,
-		Service_DeleteNodes_funcPtr deleteNodes,
-		Service_DeleteReferences_funcPtr deleteReferences);
-
-void UA_registerViewServiceSet(ServiceFunctionpointers *sfp,
-		Service_Browse_funcPtr browse,
-		Service_BrowseNext_funcPtr browseNext,
-		Service_TranslateBrowsePathsToNodeIds_funcPtr translateBrowsePathsToNodeIds,
-		Service_RegisterNodes_funcPtr registerNodes,
-		Service_UnregisterNodes_funcPtr unregisterNodes);
-
-void UA_registerQueryServiceSet(ServiceFunctionpointers *sfp,
-		Service_QueryFirst_funcPtr queryFirst,
-		Service_QueryNext_funcPtr queryNext);
-
-void UA_registerAttributeServiceSet(ServiceFunctionpointers *sfp,
-		Service_Read_funcPtr read,
-		Service_HistoryRead_funcPtr historyRead,
-		Service_Write_funcPtr write,
-		Service_HistoryUpdate_funcPtr historyUpdate);
-
-void UA_registerMethodeServiceSet(ServiceFunctionpointers *sfp,
-		Service_Call_funcPtr call);
-
-void UA_registerMonitoredItemServiceSet(ServiceFunctionpointers *sfp,
-		Service_CreateMonitoredItems_funcPtr createMonitoredItems,
-		Service_ModifyMonitoredItems_funcPtr modifyMonitoredItems,
-		Service_SetMonitoringMode_funcPtr setMonitoringMode,
-		Service_SetTriggering_funcPtr setTriggering,
-		Service_DeleteMonitoredItems_funcPtr deleteMonitoredItems);
-
-void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
-		Service_CreateSubscription_funcPtr createSubscription,
-		Service_ModifySubscription_funcPtr modifySubscription,
-		Service_SetPublishingMode_funcPtr setPublishingMode,
-		Service_Publish_funcPtr publish,
-		Service_Republish_funcPtr republish,
-		Service_TransferSubscriptions_funcPtr transferSubscriptions,
-		Service_DeleteSubscriptions_funcPtr deleteSubscriptions);
 /**
  * @defgroup services Services
  *
@@ -178,13 +23,14 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
  * @{
  */
 // Service_FindServers
+
 /**
  * @brief This Service returns the Endpoints supported by a Server and all of
  * the configuration information required to establish a SecureChannel and a
  * Session.
  */
-// void 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
 /** @} */
 
@@ -199,13 +45,14 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
  */
 
 /** @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. */
-//void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
-//                               const UA_OpenSecureChannelRequest *request,
-//                               UA_OpenSecureChannelResponse *response);
+   used to ensure Confidentiality and Integrity for Message exchange during a
+   Session. */
+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. */
-//void Service_CloseSecureChannel(UA_Server *server, UA_Int32 channelId);
+void Service_CloseSecureChannel(UA_Server *server, UA_Int32 channelId);
 /** @} */
 
 /**
@@ -224,8 +71,9 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
  * logs and in the Server’s address space. The second is the authenticationToken
  * which is used to associate an incoming request with a Session.
  */
-//void 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
  * to the Server for validation and to specify the identity of the user
@@ -233,12 +81,13 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
  * Client before it issues any other Service request after CreateSession.
  * Failure to do so shall cause the Server to close the Session.
  */
-//void 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.
  */
-//void Service_CloseSession(UA_Server *server, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
+void Service_CloseSession(UA_Server *server, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
 // Service_Cancel
 /** @} */
 
@@ -255,13 +104,15 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
 /**
  * @brief This Service is used to add one or more Nodes into the AddressSpace hierarchy.
  */
-//void 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
  */
-//void 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
 /** @} */
@@ -280,20 +131,22 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
  * The browse can be further limited by the use of a View. This Browse Service
  * also supports a primitive filtering capability.
  */
-//void 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.
  */
-//void 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
 // Service_UnregisterNodes
 /** @} */
 
+
 /* Part 4: 5.9 Query Service Set */
 /**
  * @name Query Service Set
@@ -329,8 +182,8 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
  * values as a composite, to read individual elements or to read ranges of
  * elements of the composite.
  */
-// void 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
@@ -339,8 +192,8 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
  *  values as a composite, to write individual elements or to write ranges of
  *  elements of the composite.
  */
-// void 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
 /** @} */
 
@@ -348,7 +201,7 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
  * @name Method Service Set
  *
  * The Method Service Set defines the means to invoke methods. A method shall be
- a component of an Object.
+   a component of an Object.
  *
  * @{
  */
@@ -407,5 +260,6 @@ void UA_registerSubscriptionServiceSet(ServiceFunctionpointers *sfp,
 // Service_DeleteSubscription
 /** @} */
 
-/** @} */// end of group
+/** @} */ // end of group
+
 #endif

+ 13 - 8
src/server/ua_services_attribute.c

@@ -1,6 +1,8 @@
 #include "ua_services.h"
+#include "ua_nodestoreExample.h"
 #include "ua_statuscodes.h"
 #include "ua_nodestore.h"
+
 #include "ua_namespace_0.h"
 #include "ua_util.h"
 
@@ -41,7 +43,7 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
     UA_DataValue_init(&v);
 
     UA_Node const *node   = UA_NULL;
-    UA_Int32       result = UA_NodeStore_get(server->nodestore, &(id->nodeId), &node);
+    UA_Int32       result = UA_NodeStoreExample_get(server->nodestore, &(id->nodeId), &node);
     if(result != UA_SUCCESS || node == UA_NULL) {
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
         v.status       = UA_STATUSCODE_BADNODEIDUNKNOWN;
@@ -201,7 +203,7 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
         break;
     }
 
-    UA_NodeStore_releaseManagedNode(node);
+    UA_NodeStoreExample_releaseManagedNode(node);
 
     if(retval != UA_SUCCESS) {
         v.encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
@@ -211,6 +213,7 @@ static UA_DataValue service_read_node(UA_Server *server, const UA_ReadValueId *i
 
     return v;
 }
+
 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);
@@ -224,17 +227,20 @@ void Service_Read(UA_Server *server, UA_Session *session,
         response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
         return;
     }
-
     response->resultsSize = request->nodesToReadSize;
-    for(UA_Int32 i = 0;i < response->resultsSize;i++)
-        response->results[i] = service_read_node(server, &request->nodesToRead[i]);
+    for(UA_Int32 i = 0;i < response->resultsSize;i++){
+    	//server->nodestore->readNode(&request->nodesToRead[i],&response->results[i],request->timestampsToReturn, &response->diagnosticInfos[i])
+		response->results[i] = service_read_node(server, &request->nodesToRead[i]);
+    }
+
+
 }
 
 UA_Int32 Service_Write_writeNode(UA_Server *server, UA_WriteValue *writeValue,
                                  UA_StatusCode *result) {
     UA_Int32 retval = UA_SUCCESS;
     const UA_Node *node;
-    if(UA_NodeStore_get(server->nodestore, &writeValue->nodeId, &node) != UA_SUCCESS)
+    if(UA_NodeStoreExample_get(server->nodestore, &writeValue->nodeId, &node) != UA_SUCCESS)
         return UA_ERROR;
 
     switch(writeValue->attributeId) {
@@ -243,7 +249,6 @@ UA_Int32 Service_Write_writeNode(UA_Server *server, UA_WriteValue *writeValue,
         *result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
         return UA_ERROR;
         break;
-
     case UA_ATTRIBUTEID_NODECLASS:
         /* if(writeValue->value.encodingMask == UA_DATAVALUE_ENCODINGMASK_VARIANT){ } */
         *result = UA_STATUSCODE_BADWRITENOTSUPPORTED;
@@ -366,7 +371,7 @@ UA_Int32 Service_Write_writeNode(UA_Server *server, UA_WriteValue *writeValue,
         break;
     }
 
-    UA_NodeStore_releaseManagedNode(node);
+    UA_NodeStoreExample_releaseManagedNode(node);
     return retval;
 
 }

+ 1 - 1
src/server/ua_services_internal.h

@@ -13,6 +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 *nodestore, UA_Node *node, UA_ReferenceNode *reference);
+UA_Int32 AddReference(UA_NodeStoreExample *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);

+ 16 - 16
src/server/ua_services_nodemanagement.c

@@ -1,7 +1,7 @@
 #include "ua_services.h"
 #include "ua_namespace_0.h"
 #include "ua_statuscodes.h"
-#include "ua_nodestore.h"
+#include "ua_nodestoreExample.h"
 #include "ua_services_internal.h"
 #include "ua_session.h"
 #include "ua_util.h"
@@ -81,7 +81,7 @@ static UA_StatusCode parseVariableNode(UA_ExtensionObject *attributes, UA_Node *
     return UA_STATUSCODE_GOOD;
 }
 
-UA_Int32 AddReference(UA_NodeStore *nodestore, UA_Node *node, UA_ReferenceNode *reference);
+UA_Int32 AddReference(UA_NodeStoreExample *nodestore, UA_Node *node, UA_ReferenceNode *reference);
 
 /**
    If adding the node succeeds, the pointer will be set to zero. If the nodeid
@@ -92,15 +92,15 @@ 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) {
+    if(UA_NodeStoreExample_get(server->nodestore, &parentNodeId->nodeId, &parent) != UA_SUCCESS) {
         result.statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID;
         return result;
     }
 
     const UA_ReferenceTypeNode *referenceType;
-    if(UA_NodeStore_get(server->nodestore, referenceTypeId, (const UA_Node**)&referenceType) != UA_SUCCESS) {
+    if(UA_NodeStoreExample_get(server->nodestore, referenceTypeId, (const UA_Node**)&referenceType) != UA_SUCCESS) {
         result.statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
         goto ret;
     }
@@ -118,7 +118,7 @@ UA_AddNodesResult AddNode(UA_Server *server, UA_Session *session, UA_Node **node
     // todo: test if the referenetype is hierarchical
 
     if(UA_NodeId_isNull(&(*node)->nodeId)) {
-        if(UA_NodeStore_insert(server->nodestore, node,
+        if(UA_NodeStoreExample_insert(server->nodestore, node,
                                UA_NODESTORE_INSERT_UNIQUE | UA_NODESTORE_INSERT_GETMANAGED) != UA_SUCCESS) {
             result.statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
             goto ret2;
@@ -130,13 +130,13 @@ UA_AddNodesResult AddNode(UA_Server *server, UA_Session *session, UA_Node **node
             goto ret2;
         }
 
-        if(UA_NodeStore_insert(server->nodestore, node, UA_NODESTORE_INSERT_GETMANAGED) != UA_SUCCESS) {
+        if(UA_NodeStoreExample_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
@@ -146,13 +146,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_NodeStoreExample_releaseManagedNode(*node);
     *node = UA_NULL;
-    
+
  ret2:
-    UA_NodeStore_releaseManagedNode((UA_Node*)referenceType);
+    UA_NodeStoreExample_releaseManagedNode((UA_Node*)referenceType);
  ret:
-    UA_NodeStore_releaseManagedNode(parent);
+    UA_NodeStoreExample_releaseManagedNode(parent);
 
     return result;
 }
@@ -194,7 +194,7 @@ void Service_AddNodes(UA_Server *server, UA_Session *session,
         response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
         return;
     }
-    
+
     response->resultsSize = request->nodesToAddSize;
     for(int i = 0;i < request->nodesToAddSize;i++)
         addNodeFromAttributes(server, session, &request->nodesToAdd[i], &response->results[i]);
@@ -223,7 +223,7 @@ static UA_Int32 AddSingleReference(UA_Node *node, UA_ReferenceNode *reference) {
     return UA_SUCCESS;
 }
 
-UA_Int32 AddReference(UA_NodeStore *nodestore, UA_Node *node, UA_ReferenceNode *reference) {
+UA_Int32 AddReference(UA_NodeStoreExample *nodestore, UA_Node *node, UA_ReferenceNode *reference) {
     UA_Int32 retval = AddSingleReference(node, reference);
     UA_Node *targetnode;
     UA_ReferenceNode inversereference;
@@ -231,7 +231,7 @@ UA_Int32 AddReference(UA_NodeStore *nodestore, UA_Node *node, UA_ReferenceNode *
         return retval;
 
     // Do a copy every time?
-    if(UA_NodeStore_get(nodestore, &reference->targetId.nodeId, (const UA_Node **)&targetnode) != UA_SUCCESS)
+    if(UA_NodeStoreExample_get(nodestore, &reference->targetId.nodeId, (const UA_Node **)&targetnode) != UA_SUCCESS)
         return UA_ERROR;
 
     inversereference.referenceTypeId       = reference->referenceTypeId;
@@ -240,7 +240,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_NodeStoreExample_releaseManagedNode(targetnode);
 
     return retval;
 }

+ 15 - 13
src/server/ua_services_view.c

@@ -1,14 +1,14 @@
 #include "ua_services.h"
 #include "ua_statuscodes.h"
-#include "ua_nodestore.h"
+#include "ua_nodestoreExample.h"
 #include "ua_namespace_0.h"
 #include "ua_util.h"
 
-UA_Int32 Service_Browse_getReferenceDescription(UA_NodeStore *ns, UA_ReferenceNode *reference,
+UA_Int32 Service_Browse_getReferenceDescription(UA_NodeStoreExample *ns, UA_ReferenceNode *reference,
                                                 UA_UInt32 nodeClassMask, UA_UInt32 resultMask,
                                                 UA_ReferenceDescription *referenceDescription) {
     const UA_Node *foundNode;
-    if(UA_NodeStore_get(ns, &reference->targetId.nodeId, &foundNode) != UA_SUCCESS)
+    if(UA_NodeStoreExample_get(ns, &reference->targetId.nodeId, &foundNode) != UA_SUCCESS)
         return UA_ERROR;
 
     UA_NodeId_copy(&foundNode->nodeId, &referenceDescription->nodeId.nodeId);
@@ -55,7 +55,7 @@ UA_Int32 Service_Browse_getReferenceDescription(UA_NodeStore *ns, UA_ReferenceNo
         }
     }
 
-    UA_NodeStore_releaseManagedNode(foundNode);
+    UA_NodeStoreExample_releaseManagedNode(foundNode);
     return UA_SUCCESS;
 }
 
@@ -66,7 +66,7 @@ struct SubRefTypeId {
 };
 SLIST_HEAD(SubRefTypeIdList, SubRefTypeId);
 
-static UA_UInt32 walkReferenceTree(UA_NodeStore *ns, const UA_ReferenceTypeNode *current,
+static UA_UInt32 walkReferenceTree(UA_NodeStoreExample *ns, const UA_ReferenceTypeNode *current,
                                    struct SubRefTypeIdList *list) {
     // insert the current referencetype
     struct SubRefTypeId *element = UA_alloc(sizeof(struct SubRefTypeId));
@@ -80,10 +80,11 @@ static UA_UInt32 walkReferenceTree(UA_NodeStore *ns, const UA_ReferenceTypeNode
         if(current->references[i].referenceTypeId.identifier.numeric == 45 /* HasSubtype */ &&
            current->references[i].isInverse == UA_FALSE) {
             const UA_Node *node;
-            if(UA_NodeStore_get(ns, &current->references[i].targetId.nodeId, &node) == UA_SUCCESS
+
+            if(UA_NodeStoreExample_get(ns, &current->references[i].targetId.nodeId, &node) == UA_SUCCESS
                && node->nodeClass == UA_NODECLASS_REFERENCETYPE) {
                 count += walkReferenceTree(ns, (UA_ReferenceTypeNode *)node, list);
-                UA_NodeStore_releaseManagedNode(node);
+                UA_NodeStoreExample_releaseManagedNode(node);
             }
         }
     }
@@ -91,7 +92,7 @@ static UA_UInt32 walkReferenceTree(UA_NodeStore *ns, const UA_ReferenceTypeNode
 }
 
 /* We do not search across namespaces so far. The id of the father-referencetype is returned in the array also. */
-static UA_Int32 findSubReferenceTypes(UA_NodeStore *ns, UA_NodeId *rootReferenceType,
+static UA_Int32 findSubReferenceTypes(UA_NodeStoreExample *ns, UA_NodeId *rootReferenceType,
                                       UA_NodeId **ids, UA_UInt32 *idcount) {
     struct SubRefTypeIdList list;
     UA_UInt32 count;
@@ -99,11 +100,12 @@ static UA_Int32 findSubReferenceTypes(UA_NodeStore *ns, UA_NodeId *rootReference
 
     // walk the tree
     const UA_ReferenceTypeNode *root;
-    if(UA_NodeStore_get(ns, rootReferenceType, (const UA_Node **)&root) != UA_SUCCESS ||
+
+    if(UA_NodeStoreExample_get(ns, rootReferenceType, (const UA_Node **)&root) != UA_SUCCESS ||
        root->nodeClass != UA_NODECLASS_REFERENCETYPE)
         return UA_ERROR;
     count = walkReferenceTree(ns, root, &list);
-    UA_NodeStore_releaseManagedNode((const UA_Node *)root);
+    UA_NodeStoreExample_releaseManagedNode((const UA_Node *)root);
 
     // copy results into an array
     *ids = UA_alloc(sizeof(UA_NodeId)*count);
@@ -137,14 +139,14 @@ static INLINE UA_Boolean Service_Browse_returnReference(UA_BrowseDescription *br
 }
 
 /* Return results to a single browsedescription. */
-static void Service_Browse_getBrowseResult(UA_NodeStore         *ns,
+static void Service_Browse_getBrowseResult(UA_NodeStoreExample         *ns,
                                            UA_BrowseDescription *browseDescription,
                                            UA_UInt32             maxReferences,
                                            UA_BrowseResult      *browseResult) {
     const UA_Node *node;
     UA_NodeId     *relevantReferenceTypes = UA_NULL;
     UA_UInt32      relevantReferenceTypesCount = 0;
-    if(UA_NodeStore_get(ns, &browseDescription->nodeId, &node) != UA_SUCCESS) {
+    if(UA_NodeStoreExample_get(ns, &browseDescription->nodeId, &node) != UA_SUCCESS) {
         browseResult->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
         return;
     }
@@ -202,7 +204,7 @@ static void Service_Browse_getBrowseResult(UA_NodeStore         *ns,
         // Todo. Set the Statuscode and the continuation point.
     }
 
-    UA_NodeStore_releaseManagedNode(node);
+    UA_NodeStoreExample_releaseManagedNode(node);
     UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesCount, &UA_[UA_NODEID]);
 }