Browse Source

changed operation signature for external data sources
changes within the read service

FlorianPalm 10 years ago
parent
commit
0a77adcf16

+ 53 - 53
examples/nodestoreAccessExample.c

@@ -45,22 +45,22 @@ enum UA_AttributeId {
 
 #define CHECK_NODECLASS(CLASS)                                 \
     if(!(node->nodeClass & (CLASS))) {                         \
-        v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE; \
-        v[i].status       = UA_STATUSCODE_BADNOTREADABLE;         \
+        v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE; \
+        v[readValueIdIndices[i]].status       = UA_STATUSCODE_BADNOTREADABLE;         \
         break;                                                 \
     }                                                          \
 
 
-UA_Int32 readNodes(UA_ReadValueId * readValueIds, UA_UInt32 readValueIdsSize, UA_DataValue *v, UA_Boolean timeStampToReturn, UA_DiagnosticInfo *diagnosticInfo)
+UA_Int32 readNodes(UA_ReadValueId * readValueIds, UA_UInt32 *readValueIdIndices, UA_UInt32 readValueIdsSize, UA_DataValue *v, UA_Boolean timeStampToReturn, UA_DiagnosticInfo *diagnosticInfo)
 {
 	UA_ReadValueId *id;
 	UA_Int32 retval = UA_SUCCESS;
 	for(UA_UInt32 i = 0; i<readValueIdsSize; i++){
-		id = &readValueIds[i];
+		id = &readValueIds[readValueIdIndices[i]];
 
 
 
-		UA_DataValue_init(&v[i]);
+		UA_DataValue_init(&v[readValueIdIndices[i]]);
 
 		UA_Node const *node   = UA_NULL;
 
@@ -69,159 +69,159 @@ UA_Int32 readNodes(UA_ReadValueId * readValueIds, UA_UInt32 readValueIdsSize, UA
 		/*  */
 		switch(id->attributeId) {
 		case UA_ATTRIBUTEID_NODEID:
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_NODEID], &node->nodeId);
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_NODEID], &node->nodeId);
 			break;
 
 		case UA_ATTRIBUTEID_NODECLASS:
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_INT32], &node->nodeClass);
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_INT32], &node->nodeClass);
 			break;
 
 		case UA_ATTRIBUTEID_BROWSENAME:
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_QUALIFIEDNAME], &node->browseName);
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_QUALIFIEDNAME], &node->browseName);
 			break;
 
 		case UA_ATTRIBUTEID_DISPLAYNAME:
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_LOCALIZEDTEXT],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_LOCALIZEDTEXT],
 											  &node->displayName);
 			break;
 
 		case UA_ATTRIBUTEID_DESCRIPTION:
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_LOCALIZEDTEXT],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_LOCALIZEDTEXT],
 											  &node->description);
 			break;
 
 		case UA_ATTRIBUTEID_WRITEMASK:
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_UINT32], &node->writeMask);
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_UINT32], &node->writeMask);
 			break;
 
 		case UA_ATTRIBUTEID_USERWRITEMASK:
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_UINT32], &node->userWriteMask);
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_UINT32], &node->userWriteMask);
 			break;
 
 		case UA_ATTRIBUTEID_ISABSTRACT:
 			CHECK_NODECLASS(
 				UA_NODECLASS_REFERENCETYPE | UA_NODECLASS_OBJECTTYPE | UA_NODECLASS_VARIABLETYPE |
 				UA_NODECLASS_DATATYPE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
 			retval |=
-				UA_Variant_copySetValue(&v[i].value, &UA_[UA_BOOLEAN],
+				UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
 										&((UA_ReferenceTypeNode *)node)->isAbstract);
 			break;
 
 		case UA_ATTRIBUTEID_SYMMETRIC:
 			CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_BOOLEAN],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
 											  &((UA_ReferenceTypeNode *)node)->symmetric);
 			break;
 
 		case UA_ATTRIBUTEID_INVERSENAME:
 			CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_LOCALIZEDTEXT],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_LOCALIZEDTEXT],
 											  &((UA_ReferenceTypeNode *)node)->inverseName);
 			break;
 
 		case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
 			CHECK_NODECLASS(UA_NODECLASS_VIEW);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_BOOLEAN],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
 											  &((UA_ViewNode *)node)->containsNoLoops);
 			break;
 
 		case UA_ATTRIBUTEID_EVENTNOTIFIER:
 			CHECK_NODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_BYTE],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BYTE],
 											  &((UA_ViewNode *)node)->eventNotifier);
 			break;
 
 		case UA_ATTRIBUTEID_VALUE:
 			CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copy(&((UA_VariableNode *)node)->value, &v[i].value); // todo: zero-copy
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copy(&((UA_VariableNode *)node)->value, &v[readValueIdIndices[i]].value); // todo: zero-copy
 			break;
 
 		case UA_ATTRIBUTEID_DATATYPE:
 			CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_NODEID],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_NODEID],
 											  &((UA_VariableTypeNode *)node)->dataType);
 			break;
 
 		case UA_ATTRIBUTEID_VALUERANK:
 			CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_INT32],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_INT32],
 											  &((UA_VariableTypeNode *)node)->valueRank);
 			break;
 
 		case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
 			CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			UA_Variant_copySetArray(&v[i].value, &UA_[UA_UINT32],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			UA_Variant_copySetArray(&v[readValueIdIndices[i]].value, &UA_[UA_UINT32],
 									((UA_VariableTypeNode *)node)->arrayDimensionsSize,
 									&((UA_VariableTypeNode *)node)->arrayDimensions);
 			break;
 
 		case UA_ATTRIBUTEID_ACCESSLEVEL:
 			CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_BYTE],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BYTE],
 											  &((UA_VariableNode *)node)->accessLevel);
 			break;
 
 		case UA_ATTRIBUTEID_USERACCESSLEVEL:
 			CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_BYTE],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BYTE],
 											  &((UA_VariableNode *)node)->userAccessLevel);
 			break;
 
 		case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
 			CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_DOUBLE],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_DOUBLE],
 											  &((UA_VariableNode *)node)->minimumSamplingInterval);
 			break;
 
 		case UA_ATTRIBUTEID_HISTORIZING:
 			CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_BOOLEAN],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
 											  &((UA_VariableNode *)node)->historizing);
 			break;
 
 		case UA_ATTRIBUTEID_EXECUTABLE:
 			CHECK_NODECLASS(UA_NODECLASS_METHOD);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_BOOLEAN],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
 											  &((UA_MethodNode *)node)->executable);
 			break;
 
 		case UA_ATTRIBUTEID_USEREXECUTABLE:
 			CHECK_NODECLASS(UA_NODECLASS_METHOD);
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
-			retval |= UA_Variant_copySetValue(&v[i].value, &UA_[UA_BOOLEAN],
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT;
+			retval |= UA_Variant_copySetValue(&v[readValueIdIndices[i]].value, &UA_[UA_BOOLEAN],
 											  &((UA_MethodNode *)node)->userExecutable);
 			break;
 
 		default:
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
-			v[i].status       = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+			v[readValueIdIndices[i]].status       = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
 			break;
 		}
 
 		if(retval != UA_SUCCESS) {
-			v[i].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
-			v[i].status       = UA_STATUSCODE_BADNOTREADABLE;
+			v[readValueIdIndices[i]].encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+			v[readValueIdIndices[i]].status       = UA_STATUSCODE_BADNOTREADABLE;
 		}
 
 	}

+ 1 - 1
examples/nodestoreAccessExample.h

@@ -9,6 +9,6 @@
 #define NODESTOREACCESSEXAMPLE_H_
 
 
-UA_Int32 readNodes(UA_ReadValueId * readValueIds, UA_UInt32 readValueIdsSize, UA_DataValue *v, UA_Boolean timeStampToReturn, UA_DiagnosticInfo *diagnosticInfo);
+UA_Int32 readNodes(UA_ReadValueId * readValueIds, UA_UInt32 *readValueIdIndices, UA_UInt32 readValueIdsSize, UA_DataValue *v, UA_Boolean timeStampToReturn, UA_DiagnosticInfo *diagnosticInfo);
 
 #endif /* NODESTOREACCESSEXAMPLE_H_ */

+ 7 - 7
include/ua_server.h

@@ -60,16 +60,16 @@ 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_addNodes)(UA_AddNodesItem *nodesToAdd,UA_UInt32 *indices,UA_UInt32 NodesToAddSize, UA_AddNodesResult* result, UA_DiagnosticInfo *diagnosticInfo);
+typedef UA_Int32 (*UA_NodeStore_addReferences)(UA_AddReferencesItem* referencesToAdd,UA_UInt32 *indices,UA_UInt32 ReferencesToAddSize, 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_deleteNodes)(UA_DeleteNodesItem *nodesToDelete,UA_UInt32 *indices,UA_UInt32 NodesToDeleteSize, UA_StatusCode *result, UA_DiagnosticInfo *diagnosticInfo);
+typedef UA_Int32 (*UA_NodeStore_deleteReferences)(UA_DeleteReferencesItem referenceToDelete,UA_UInt32 *indices, UA_UInt32 ReferencesToDeleteSize,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);
+typedef UA_Int32 (*UA_NodeStore_readNodes)(UA_ReadValueId *readValueIds,UA_UInt32 *indices,UA_UInt32 ReadValueIdsSize,UA_DataValue *value, UA_Boolean timeStampToReturn, UA_DiagnosticInfo *diagnosticInfo);
+typedef UA_Int32 (*UA_NodeStore_writeNodes)(UA_WriteValue *writeValues,UA_UInt32 *indices ,UA_UInt32 WriteValuesSize, UA_StatusCode *result, UA_DiagnosticInfo *diagnosticInfo);
+typedef UA_Int32 (*UA_NodeStore_browseNodes)(UA_UInt32 requestedMaxReferencesPerNode, UA_BrowseDescription *browseDescriptions,UA_Int32 *indices,UA_UInt32 BrowseDescriptionsSize, UA_BrowseResult *browseResult, UA_DiagnosticInfo *diagnosticInfo);
 
 
 

+ 65 - 11
src/server/ua_services_attribute.c

@@ -227,25 +227,78 @@ void Service_Read(UA_Server *server, UA_Session *session,
         response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
         return;
     }
+
+    if(UA_Array_new((void **)&response->diagnosticInfos, request->nodesToReadSize, &UA_[UA_DIAGNOSTICINFO]) != UA_SUCCESS) {
+        response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+        return;
+    }
     response->resultsSize = request->nodesToReadSize;
-    for(UA_Int32 i = 0;i < response->resultsSize;i++){
-    	UA_Namespace *tmpNamespace;
-    	UA_NamespaceManager_getNamespace(server->namespaceManager,
-    			request->nodesToRead[i].nodeId.namespaceIndex, &tmpNamespace);
 
-    	//(UA_ReadValueId *readValueIds,UA_UInt32 sizeReadValueIds, UA_DataValue *value, UA_Boolean timeStampToReturn, UA_DiagnosticInfo *diagnosticInfo);
+    UA_Int32 *numberOfFoundIndices;
+    UA_Int16 *associatedIndices;
+    UA_UInt32 differentNamespaceIndexCount = 0;
+    if(UA_Array_new((void **)&numberOfFoundIndices,request->nodesToReadSize,&UA_[UA_UINT32]) != UA_SUCCESS){
+    	response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+    	return ;
+    }
+
+    if(UA_Array_new((void **)&associatedIndices,request->nodesToReadSize,&UA_[UA_UINT16]) != UA_SUCCESS){
+    	response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+    	return ;
+    }
+    // find out count of different namespace indices
+
+   for(UA_Int32 i = 0; i<request->nodesToReadSize; i++){
+
+    	for(UA_UInt32 j = 0; j <= differentNamespaceIndexCount; j++){
+    		if( associatedIndices[j] == request->nodesToRead[i].nodeId.namespaceIndex){
+    			numberOfFoundIndices[j]++;
+    			break;
+    		}
+    		else if(j == (differentNamespaceIndexCount - 1)){
+    			associatedIndices[j] = request->nodesToRead[i].nodeId.namespaceIndex;
+    			associatedIndices[j] = 1;
+    			differentNamespaceIndexCount++;
+    		}
+    	}
+    }
 
+	UA_UInt32 *readValueIdIndices;
+    if(UA_Array_new((void **)&readValueIdIndices,request->nodesToReadSize,&UA_[UA_UINT32]) != UA_SUCCESS){
+    	response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
+    	return ;
+    }
 
-    	if(tmpNamespace!=UA_NULL){
-    		tmpNamespace->nodeStore->readNodes(&request->nodesToRead[i],
-    				request->nodesToReadSize,
-    				&response->results[i],
+    for(UA_UInt32 i = 0; i < differentNamespaceIndexCount; i++){
+    	UA_Namespace *tmpNamespace;
+    	UA_NamespaceManager_getNamespace(server->namespaceManager,associatedIndices[i],&tmpNamespace);
+    	if(tmpNamespace != UA_NULL){
+
+    	    //build up index array for each read operation onto a different namespace
+    	    UA_UInt32 n = 0;
+    	    for(UA_Int32 j = 0; j < request->nodesToReadSize; j++){
+    	    	if(request->nodesToRead[j].nodeId.namespaceIndex == associatedIndices[i]){
+    	    		readValueIdIndices[n] = j;
+    	    	}
+    	    }
+    	    //call read for every namespace
+    		tmpNamespace->nodeStore->readNodes(request->nodesToRead,
+    				readValueIdIndices,
+    				numberOfFoundIndices[i],
+    				response->results,
     				request->timestampsToReturn,
-    				&response->diagnosticInfos[i]);
+    				response->diagnosticInfos);
 
-			//	response->results[i] = service_read_node(server, &request->nodesToRead[i]);
     	}
     }
+    UA_free(readValueIdIndices);
+
+    /*
+    for(UA_Int32 i = 0;i < response->resultsSize;i++){
+				response->results[i] = service_read_node(server, &request->nodesToRead[i]);
+    	}
+    }
+    */
 
 
 }
@@ -404,3 +457,4 @@ void Service_Write(UA_Server *server, UA_Session *session,
     for(UA_Int32 i = 0;i < request->nodesToWriteSize;i++)
         Service_Write_writeNode(server, &request->nodesToWrite[i], &response->results[i]);
 }
+

+ 9 - 2
src/server/ua_services_view.c

@@ -222,11 +222,18 @@ void Service_Browse(UA_Server *server, UA_Session *session,
         response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
         return;
     }
-        
+
     response->resultsSize = request->nodesToBrowseSize;
-    for(UA_Int32 i = 0;i < request->nodesToBrowseSize;i++)
+
+
+
+
+
+    for(UA_Int32 i = 0;i < request->nodesToBrowseSize;i++){
         Service_Browse_getBrowseResult(server->nodestore, &request->nodesToBrowse[i],
                                        request->requestedMaxReferencesPerNode, &response->results[i]);
+    }
+
 }