Browse Source

services return status in the responseheader, functions for service calls with administrator session

Julius Pfrommer 10 years ago
parent
commit
2b03aefb49

+ 6 - 0
include/ua_server.h

@@ -49,6 +49,12 @@ void UA_LIBEXPORT UA_Server_init(UA_Server *server, UA_String *endpointUrl);
 UA_Int32 UA_LIBEXPORT UA_Server_deleteMembers(UA_Server *server);
 UA_Int32 UA_LIBEXPORT UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);
 
+/* Services for local use */
+void Server_addNodes(UA_Server *server, const UA_AddNodesRequest *request,
+                     UA_AddNodesResponse *response);
+void Server_addReferences(UA_Server *server, const UA_AddReferencesRequest *request,
+                          UA_AddReferencesResponse *response);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif

+ 12 - 0
src/server/ua_server.c

@@ -4,6 +4,7 @@
 #include "ua_securechannel_manager.h"
 #include "ua_session_manager.h"
 #include "ua_util.h"
+#include "ua_services.h"
 
 UA_Int32 UA_Server_deleteMembers(UA_Server *server) {
     UA_ApplicationDescription_deleteMembers(&server->description);
@@ -566,3 +567,14 @@ void UA_Server_init(UA_Server *server, UA_String *endpointUrl) {
 
     UA_NodeStore_releaseManagedNode((const UA_Node *)root);
 }
+
+
+void Server_addNodes(UA_Server *server, const UA_AddNodesRequest *request,
+                     UA_AddNodesResponse *response) {
+    Service_AddNodes(server, &adminSession, request, response);
+}
+
+void Server_addReferences(UA_Server *server, const UA_AddReferencesRequest *request,
+                          UA_AddReferencesResponse *response) {
+    Service_AddReferences(server, &adminSession, request, response);
+}

+ 27 - 32
src/server/ua_services.h

@@ -29,9 +29,8 @@
  * the configuration information required to establish a SecureChannel and a
  * Session.
  */
-UA_Int32 Service_GetEndpoints(UA_Server                    *server,
-                              const UA_GetEndpointsRequest *request,
-                              UA_GetEndpointsResponse      *response);
+void Service_GetEndpoints(UA_Server                    *server,
+                          const UA_GetEndpointsRequest *request, UA_GetEndpointsResponse *response);
 // Service_RegisterServer
 /** @} */
 
@@ -48,14 +47,14 @@ UA_Int32 Service_GetEndpoints(UA_Server                    *server,
 /** @brief This Service is used to open or renew a SecureChannel that can be
    used to ensure Confidentiality and Integrity for Message exchange during a
    Session. */
-UA_Int32 Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
-                                   const UA_OpenSecureChannelRequest *request,
-                                   UA_OpenSecureChannelResponse *response);
+void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
+                               const UA_OpenSecureChannelRequest *request,
+                               UA_OpenSecureChannelResponse *response);
 
 /** @brief This Service is used to terminate a SecureChannel. */
-UA_Int32 Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel,
-                                    const UA_CloseSecureChannelRequest *request,
-                                    UA_CloseSecureChannelResponse *response);
+void Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel,
+                                const UA_CloseSecureChannelRequest *request,
+                                UA_CloseSecureChannelResponse *response);
 /** @} */
 
 /**
@@ -74,9 +73,8 @@ UA_Int32 Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel
  * logs and in the Server’s address space. The second is the authenticationToken
  * which is used to associate an incoming request with a Session.
  */
-UA_Int32 Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
-                               const UA_CreateSessionRequest *request,
-                               UA_CreateSessionResponse *response);
+void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
+                           const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
 
 /**
  * @brief This Service is used by the Client to submit its SoftwareCertificates
@@ -85,16 +83,14 @@ UA_Int32 Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
  * Client before it issues any other Service request after CreateSession.
  * Failure to do so shall cause the Server to close the Session.
  */
-UA_Int32 Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
-                                 const UA_ActivateSessionRequest *request,
-                                 UA_ActivateSessionResponse *response);
+void Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
+                             const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
 
 /**
  * @brief This Service is used to terminate a Session.
  */
-UA_Int32 Service_CloseSession(UA_Server *server, UA_Session *session,
-                              const UA_CloseSessionRequest *request,
-                              UA_CloseSessionResponse *response);
+void Service_CloseSession(UA_Server *server, UA_Session *session,
+                          const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
 // Service_Cancel
 /** @} */
 
@@ -111,15 +107,14 @@ UA_Int32 Service_CloseSession(UA_Server *server, UA_Session *session,
 /**
  * @brief This Service is used to add one or more Nodes into the AddressSpace hierarchy.
  */
-UA_Int32 Service_AddNodes(UA_Server *server, UA_Session *session,
-                          const UA_AddNodesRequest *request, UA_AddNodesResponse *response);
+void Service_AddNodes(UA_Server *server, UA_Session *session,
+                      const UA_AddNodesRequest *request, UA_AddNodesResponse *response);
 
 /**
  * @brief This Service is used to add one or more References to one or more Nodes
  */
-UA_Int32 Service_AddReferences(UA_Server *server, UA_Session *session,
-                               const UA_AddReferencesRequest *request,
-                               UA_AddReferencesResponse *response);
+void Service_AddReferences(UA_Server *server, UA_Session *session,
+                           const UA_AddReferencesRequest *request, UA_AddReferencesResponse *response);
 
 // Service_DeleteNodes
 // Service_DeleteReferences
@@ -139,15 +134,15 @@ UA_Int32 Service_AddReferences(UA_Server *server, UA_Session *session,
  * The browse can be further limited by the use of a View. This Browse Service
  * also supports a primitive filtering capability.
  */
-UA_Int32 Service_Browse(UA_Server *server, UA_Session *session,
-                        const UA_BrowseRequest *request, UA_BrowseResponse *response);
+void Service_Browse(UA_Server *server, UA_Session *session,
+                    const UA_BrowseRequest *request, UA_BrowseResponse *response);
 
 /**
  * @brief This Service is used to translate textual node paths to their respective ids.
  */
-UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
-                                               const UA_TranslateBrowsePathsToNodeIdsRequest *request,
-                                               UA_TranslateBrowsePathsToNodeIdsResponse *response);
+void Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
+                                           const UA_TranslateBrowsePathsToNodeIdsRequest *request,
+                                           UA_TranslateBrowsePathsToNodeIdsResponse *response);
 // Service_BrowseNext
 // Service_TranslateBrowsePathsToNodeIds
 // Service_RegisterNodes
@@ -190,8 +185,8 @@ UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *se
  * values as a composite, to read individual elements or to read ranges of
  * elements of the composite.
  */
-UA_Int32 Service_Read(UA_Server *server, UA_Session *session, const UA_ReadRequest *request,
-                      UA_ReadResponse *response);
+void Service_Read(UA_Server *server, UA_Session *session,
+                  const UA_ReadRequest *request, UA_ReadResponse *response);
 // Service_HistoryRead
 /**
  * @brief This Service is used to write one or more Attributes of one or more
@@ -200,8 +195,8 @@ UA_Int32 Service_Read(UA_Server *server, UA_Session *session, const UA_ReadReque
  *  values as a composite, to write individual elements or to write ranges of
  *  elements of the composite.
  */
-UA_Int32 Service_Write(UA_Server *server, UA_Session *session, const UA_WriteRequest *request,
-                       UA_WriteResponse *response);
+void Service_Write(UA_Server *server, UA_Session *session,
+                   const UA_WriteRequest *request, UA_WriteResponse *response);
 // Service_HistoryUpdate
 /** @} */
 

+ 26 - 35
src/server/ua_services_attribute.c

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

+ 3 - 5
src/server/ua_services_discovery.c

@@ -1,9 +1,9 @@
 #include "ua_services.h"
 #include "ua_namespace_0.h"
 
-UA_Int32 Service_GetEndpoints(UA_Server                    *server,
-                              const UA_GetEndpointsRequest *request,
-                              UA_GetEndpointsResponse      *response) {
+void Service_GetEndpoints(UA_Server                    *server,
+                          const UA_GetEndpointsRequest *request,
+                          UA_GetEndpointsResponse      *response) {
     UA_GetEndpointsResponse_init(response);
     response->endpointsSize = 1;
     UA_Array_new((void **)&response->endpoints, response->endpointsSize, &UA_[UA_ENDPOINTDESCRIPTION]);
@@ -37,6 +37,4 @@ UA_Int32 Service_GetEndpoints(UA_Server                    *server,
     UA_LocalizedText_copycstring("The open62541 application", &(response->endpoints[0].server.applicationName));
     // FIXME: This should be a feature of the application and an enum
     response->endpoints[0].server.applicationType = UA_APPLICATIONTYPE_SERVER;
-
-	return UA_SUCCESS;
 }

+ 18 - 21
src/server/ua_services_nodemanagement.c

@@ -1,4 +1,5 @@
 #include "ua_services.h"
+#include "ua_namespace_0.h"
 #include "ua_statuscodes.h"
 #include "ua_nodestore.h"
 #include "ua_services_internal.h"
@@ -57,28 +58,24 @@ ret:
     return result;
 }
 
-UA_Int32 Service_AddNodes(UA_Server *server, UA_Session *session,
-                          const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
-    if(session == UA_NULL)
-        return UA_ERROR;    // TODO: Return error message
+void Service_AddNodes(UA_Server *server, UA_Session *session,
+                      const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
+    UA_assert(server != UA_NULL && session != UA_NULL);
 
-    UA_Int32 nodestoaddsize = request->nodesToAddSize;
-    if(nodestoaddsize <= 0) {
+    if(request->nodesToAddSize <= 0) {
         response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
-        response->resultsSize = 0;
-        return UA_SUCCESS;
+        return;
     }
 
-    response->resultsSize = nodestoaddsize;
-    UA_alloc((void **)&response->results, sizeof(void *) * nodestoaddsize);
-    for(int i = 0;i < nodestoaddsize;i++) {
-        DBG_VERBOSE(UA_QualifiedName_printf("service_addnodes - name=", &(request->nodesToAdd[i].browseName)));
-        response->results[i] = addSingleNode(server, &request->nodesToAdd[i]);
+    if(UA_Array_new((void **)&response->results, request->nodesToAddSize, &UA_[UA_ADDNODESRESULT])
+       != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
     }
-    response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
-    response->diagnosticInfosSize = -1;
-    return UA_SUCCESS;
-
+    
+    response->resultsSize = request->nodesToAddSize;
+    for(int i = 0;i < request->nodesToAddSize;i++)
+        response->results[i] = addSingleNode(server, &request->nodesToAdd[i]);
 }
 
 static UA_Int32 AddSingleReference(UA_Node *node, UA_ReferenceNode *reference) {
@@ -128,8 +125,8 @@ UA_Int32 AddReference(UA_NodeStore *targetns, UA_Node *node, UA_ReferenceNode *r
     return retval;
 }
 
-UA_Int32 Service_AddReferences(UA_Server *server, UA_Session *session,
-                               const UA_AddReferencesRequest *request,
-                               UA_AddReferencesResponse *response) {
-    return UA_ERROR;
+void Service_AddReferences(UA_Server *server, UA_Session *session,
+                           const UA_AddReferencesRequest *request,
+                           UA_AddReferencesResponse *response) {
+    response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTIMPLEMENTED;
 }

+ 9 - 11
src/server/ua_services_securechannel.c

@@ -1,21 +1,19 @@
 #include "ua_services.h"
 #include "ua_securechannel_manager.h"
 
-UA_Int32 Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
-                                   const UA_OpenSecureChannelRequest *request,
-                                   UA_OpenSecureChannelResponse *response) {
-    UA_Int32 retval = UA_SUCCESS;
+void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
+                               const UA_OpenSecureChannelRequest *request,
+                               UA_OpenSecureChannelResponse *response) {
     // todo: if(request->clientProtocolVersion != protocolVersion)
     if(request->requestType == UA_SECURITYTOKEN_ISSUE)
-        retval |= UA_SecureChannelManager_open(server->secureChannelManager, connection, request, response);
+        UA_SecureChannelManager_open(server->secureChannelManager, connection, request, response);
     else
-        retval |= UA_SecureChannelManager_renew(server->secureChannelManager, connection, request, response);
-    return retval;
+        UA_SecureChannelManager_renew(server->secureChannelManager, connection, request, response);
 }
 
-UA_Int32 Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel,
-                                    const UA_CloseSecureChannelRequest *request,
-                                    UA_CloseSecureChannelResponse *response) {
-    return UA_SecureChannelManager_close(server->secureChannelManager, channel->securityToken.channelId);
+void Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel,
+                                const UA_CloseSecureChannelRequest *request,
+                                UA_CloseSecureChannelResponse *response) {
+    UA_SecureChannelManager_close(server->secureChannelManager, channel->securityToken.channelId);
     // 62451 Part 6 Chapter 7.1.4 - The server does not send a CloseSecureChannel response
 }

+ 19 - 24
src/server/ua_services_session.c

@@ -1,19 +1,19 @@
 #include "ua_services.h"
 #include "ua_server.h"
 #include "ua_session_manager.h"
+#include "ua_statuscodes.h"
 
-UA_Int32 Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
-                               const UA_CreateSessionRequest *request,
-                               UA_CreateSessionResponse *response) {
+void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
+                           const UA_CreateSessionRequest *request,
+                           UA_CreateSessionResponse *response) {
     // creates a session and adds a pointer to the channel. Only when the
     // session is activated will the channel point to the session as well
-    UA_Int32 retval = UA_SUCCESS;
 	UA_Session *newSession;
-    retval |= UA_SessionManager_createSession(server->sessionManager, channel, &newSession);
-	if(retval != UA_SUCCESS)
-	{
-		return retval;
-	}
+    response->responseHeader.serviceResult = UA_SessionManager_createSession(server->sessionManager,
+                                                                             channel, &newSession);
+	if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
+		return;
+
     //TODO get maxResponseMessageSize
     UA_String_copy(&request->sessionName, &newSession->sessionName);
     newSession->maxResponseMessageSize = request->maxResponseMessageSize;
@@ -22,28 +22,24 @@ UA_Int32 Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
     response->revisedSessionTimeout = newSession->timeout;
     response->authenticationToken = newSession->authenticationToken;
     //channel->session = newSession;
-    return retval;
 }
 
-UA_Int32 Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
-                                 const UA_ActivateSessionRequest *request,
-                                 UA_ActivateSessionResponse *response) {
+void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
+                             const UA_ActivateSessionRequest *request,
+                             UA_ActivateSessionResponse *response) {
     // make the channel know about the session
 	UA_Session *foundSession;
-
-	UA_SessionManager_getSessionByToken(server->sessionManager,(UA_NodeId*)&request->requestHeader.authenticationToken,&foundSession);
+	UA_SessionManager_getSessionByToken(server->sessionManager,
+                                        (UA_NodeId*)&request->requestHeader.authenticationToken,
+                                        &foundSession);
 
 	if(foundSession == UA_NULL)
-	{
-		return UA_ERROR;
-	}
-
-    channel->session = foundSession;
-
-    return UA_SUCCESS;
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
+    else
+        channel->session = foundSession;
 }
 
-UA_Int32 Service_CloseSession(UA_Server *server, UA_Session *session,
+void Service_CloseSession(UA_Server *server, UA_Session *session,
                               const UA_CloseSessionRequest *request,
                               UA_CloseSessionResponse *response) {
     session->channel->session = UA_NULL;
@@ -53,5 +49,4 @@ UA_Int32 Service_CloseSession(UA_Server *server, UA_Session *session,
 
     /* UA_SessionManager_removeSession(&sessionId); */
     // FIXME: set response
-    return UA_SUCCESS;
 }

+ 35 - 30
src/server/ua_services_view.c

@@ -158,7 +158,10 @@ static void Service_Browse_getBrowseResult(UA_NodeStore         *ns,
     if(!browseDescription->includeSubtypes ||
        findSubReferenceTypes(ns, &browseDescription->referenceTypeId, &relevantReferenceTypes,
                              &relevantReferenceTypesCount) != UA_SUCCESS) {
-        UA_alloc((void **)&relevantReferenceTypes, sizeof(UA_NodeId));
+        if(UA_alloc((void **)&relevantReferenceTypes, sizeof(UA_NodeId)) != UA_SUCCESS) {
+
+            return;
+        }
         UA_NodeId_copy(&browseDescription->referenceTypeId, relevantReferenceTypes);
         relevantReferenceTypesCount = 1;
     }
@@ -205,45 +208,47 @@ static void Service_Browse_getBrowseResult(UA_NodeStore         *ns,
     UA_Array_delete(relevantReferenceTypes, relevantReferenceTypesCount, &UA_[UA_NODEID]);
 }
 
-UA_Int32 Service_Browse(UA_Server *server, UA_Session *session,
-                        const UA_BrowseRequest *request, UA_BrowseResponse *response) {
-    UA_Int32 retval = UA_SUCCESS;
-    if(server == UA_NULL || session == UA_NULL)
-        return UA_ERROR;
-
-    //TODO request->view not used atm
-    UA_Array_new((void **)&(response->results), request->nodesToBrowseSize, &UA_[UA_BROWSERESULT]);
-    response->resultsSize = request->nodesToBrowseSize;
+void Service_Browse(UA_Server *server, UA_Session *session,
+                    const UA_BrowseRequest *request, UA_BrowseResponse *response) {
+    UA_assert(server != UA_NULL && session != UA_NULL && request != UA_NULL && response != UA_NULL);
 
-    for(UA_Int32 i = 0;i < request->nodesToBrowseSize;i++) {
-        // Service_Browse_getBrowseResult has no return value. All errors are resolved internally.
-        Service_Browse_getBrowseResult(server->nodestore, &request->nodesToBrowse[i],
-                                       request->requestedMaxReferencesPerNode,
-                                       &response->results[i]);
+    if(request->nodesToBrowseSize <= 0) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
+        return;
     }
 
-    //TODO fill Diagnostic info array
-    response->diagnosticInfosSize = 0;
-    response->diagnosticInfos     = UA_NULL;
-    return retval;
+    if(UA_Array_new((void **)&(response->results), request->nodesToBrowseSize, &UA_[UA_BROWSERESULT])
+       != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
+    }
+        
+    response->resultsSize = request->nodesToBrowseSize;
+    for(UA_Int32 i = 0;i < request->nodesToBrowseSize;i++)
+        Service_Browse_getBrowseResult(server->nodestore, &request->nodesToBrowse[i],
+                                       request->requestedMaxReferencesPerNode, &response->results[i]);
 }
 
 
-UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
-                                               const UA_TranslateBrowsePathsToNodeIdsRequest *request,
-                                               UA_TranslateBrowsePathsToNodeIdsResponse *response) {
-    UA_Int32 retval = UA_SUCCESS;
-    DBG_VERBOSE(printf("TranslateBrowsePathsToNodeIdsService - %i path(s)", request->browsePathsSize));
+void Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
+                                           const UA_TranslateBrowsePathsToNodeIdsRequest *request,
+                                           UA_TranslateBrowsePathsToNodeIdsResponse *response) {
+    UA_assert(server != UA_NULL && session != UA_NULL && request != UA_NULL && response != UA_NULL);
+
+    if(request->browsePathsSize <= 0) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
+        return;
+    }
 
     // Allocate space for a correct answer
     response->resultsSize = request->browsePathsSize;
     // _init of the elements is done in Array_new
-    UA_Array_new((void **)&response->results, request->browsePathsSize, &UA_[UA_BROWSEPATHRESULT]);
-
-    for(UA_Int32 i = 0;i < request->browsePathsSize;i++) {
-        //FIXME: implement
-        response->results[i].statusCode = UA_STATUSCODE_BADNOMATCH;
+    if(UA_Array_new((void **)&response->results, request->browsePathsSize, &UA_[UA_BROWSEPATHRESULT])
+       != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
     }
 
-    return retval;
+    for(UA_Int32 i = 0;i < request->browsePathsSize;i++)
+        response->results[i].statusCode = UA_STATUSCODE_BADNOMATCH; //FIXME: implement
 }

+ 8 - 5
src/server/ua_session_manager.c

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

+ 2 - 2
src/server/ua_session_manager.h

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

+ 36 - 0
src/ua_session.c

@@ -4,6 +4,42 @@
 #include "ua_session.h"
 #include "ua_util.h"
 
+UA_Session anonymousSession = {
+    .clientDescription =  {.applicationUri = {-1, UA_NULL},
+                           .productUri = {-1, UA_NULL},
+                           .applicationName = {.locale = {-1, UA_NULL}, .text = {-1, UA_NULL}},
+                           .applicationType = UA_APPLICATIONTYPE_CLIENT,
+                           .gatewayServerUri = {-1, UA_NULL},
+                           .discoveryProfileUri = {-1, UA_NULL},
+                           .discoveryUrlsSize = -1,
+                           .discoveryUrls = UA_NULL},
+    .sessionName = {sizeof("Anonymous Session")-1, (UA_Byte*)"Anonymous Session"},
+    .authenticationToken = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0}, // is never used, as this session is not stored in the sessionmanager
+    .sessionId = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0},
+    .maxRequestMessageSize = UA_UINT32_MAX,
+    .maxResponseMessageSize = UA_UINT32_MAX,
+    .timeout = UA_INT64_MAX,
+    .validTill = UA_INT64_MAX,
+    .channel = UA_NULL};
+
+UA_Session adminSession = {
+    .clientDescription =  {.applicationUri = {-1, UA_NULL},
+                           .productUri = {-1, UA_NULL},
+                           .applicationName = {.locale = {-1, UA_NULL}, .text = {-1, UA_NULL}},
+                           .applicationType = UA_APPLICATIONTYPE_CLIENT,
+                           .gatewayServerUri = {-1, UA_NULL},
+                           .discoveryProfileUri = {-1, UA_NULL},
+                           .discoveryUrlsSize = -1,
+                           .discoveryUrls = UA_NULL},
+    .sessionName = {sizeof("Administrator Session")-1, (UA_Byte*)"Administrator Session"},
+    .authenticationToken = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 1}, // is never used, as this session is not stored in the sessionmanager
+    .sessionId = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 1},
+    .maxRequestMessageSize = UA_UINT32_MAX,
+    .maxResponseMessageSize = UA_UINT32_MAX,
+    .timeout = UA_INT64_MAX,
+    .validTill = UA_INT64_MAX,
+    .channel = UA_NULL};
+
 UA_Int32 UA_Session_new(UA_Session **session) {
     UA_Int32 retval = UA_SUCCESS;
     retval |= UA_alloc((void **)session, sizeof(UA_Session));

+ 3 - 0
src/ua_session.h

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