Sfoglia il codice sorgente

better structure in browse service, fixes in UA_ReferenceDescription encoding/decoding/calcsize

FlorianPalm 10 anni fa
parent
commit
b4b2ca1bc2
3 ha cambiato i file con 158 aggiunte e 10 eliminazioni
  1. 3 3
      src/ua_application.c
  2. 145 2
      src/ua_services_view.c
  3. 10 5
      src/ua_types_encoding_binary.c

+ 3 - 3
src/ua_application.c

@@ -73,9 +73,9 @@ void appMockup_init() {
 	UA_ObjectNode_new(&folderType);
 	folderType->nodeId = NS0NODEID(61);
 	folderType->nodeClass = UA_NODECLASS_OBJECT; // I should not have to set this manually
-	folderType->browseName = (UA_QualifiedName){0, {4, "FolderType"}};
-	folderType->displayName = (UA_LocalizedText){{2,"EN"},{4, "FolderType"}};
-	folderType->description = (UA_LocalizedText){{2,"EN"},{4, "FolderType"}};
+	folderType->browseName = (UA_QualifiedName){0, {10, "FolderType"}};
+	folderType->displayName = (UA_LocalizedText){{2,"EN"},{10, "FolderType"}};
+	folderType->description = (UA_LocalizedText){{2,"EN"},{10, "FolderType"}};
 	folderType->referencesSize = 0;
 	folderType->references = UA_NULL;
 

+ 145 - 2
src/ua_services_view.c

@@ -1,6 +1,147 @@
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 
+UA_Int32 Service_Browse_getReferenceDescription(Namespace *ns,UA_ReferenceNode* reference,
+		UA_UInt32 nodeClassMask ,UA_UInt32 resultMask, UA_ReferenceDescription* referenceDescription)
+{
+	const UA_Node* foundNode = UA_NULL;
+	Namespace_Entry_Lock *lock;
+	if(Namespace_get(ns,&reference->targetId.nodeId,&foundNode, &lock)==UA_SUCCESS && foundNode != UA_NULL)
+	{
+		UA_UInt32 mask = 0;
+		referenceDescription->resultMask = 0;
+		for (mask = 0x01; mask <= 0x40; mask *= 2) {
+			switch (mask & (resultMask)) {
+			case UA_BROWSERESULTMASK_REFERENCETYPEID:
+				UA_NodeId_copy(
+						&reference->referenceTypeId,
+						&referenceDescription->referenceTypeId);
+				referenceDescription->resultMask |= UA_BROWSERESULTMASK_REFERENCETYPEID;
+				break;
+			case UA_BROWSERESULTMASK_ISFORWARD:
+				referenceDescription->isForward = !reference->isInverse;
+				referenceDescription->resultMask |= UA_BROWSERESULTMASK_ISFORWARD;
+				break;
+			case UA_BROWSERESULTMASK_NODECLASS:
+				UA_NodeClass_copy(&foundNode->nodeClass,
+						&referenceDescription->nodeClass);
+				referenceDescription->resultMask |= UA_BROWSERESULTMASK_NODECLASS;
+				break;
+			case UA_BROWSERESULTMASK_BROWSENAME:
+				UA_QualifiedName_copy(&foundNode->browseName,
+						&referenceDescription->browseName);
+				referenceDescription->resultMask |= UA_BROWSERESULTMASK_BROWSENAME;
+				break;
+			case UA_BROWSERESULTMASK_DISPLAYNAME:
+				UA_LocalizedText_copy(&foundNode->displayName,
+						&referenceDescription->displayName);
+				referenceDescription->resultMask |= UA_BROWSERESULTMASK_DISPLAYNAME;
+				break;
+			case UA_BROWSERESULTMASK_TYPEDEFINITION:
+				if (referenceDescription->nodeClass == UA_NODECLASS_OBJECT
+						|| referenceDescription->nodeClass
+								== UA_NODECLASS_VARIABLE) {
+					UA_NodeId_copy(&foundNode->nodeId,
+							&referenceDescription->typeDefinition.nodeId);
+					//TODO mockup
+					referenceDescription->typeDefinition.serverIndex = 0;
+					referenceDescription->typeDefinition.namespaceUri.length = 0;
+
+					referenceDescription->resultMask |= UA_BROWSERESULTMASK_TYPEDEFINITION;
+				}
+				break;
+			}
+		}
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+UA_Boolean Service_Browse_returnReference(UA_BrowseDescription *browseDescription, UA_ReferenceNode* reference)
+{
+	UA_Boolean c = UA_FALSE;
+
+	c = c || ((reference->isInverse == UA_TRUE) && (browseDescription->browseDirection == UA_BROWSEDIRECTION_INVERSE));
+	c = c || ((reference->isInverse == UA_FALSE) && (browseDescription->browseDirection == UA_BROWSEDIRECTION_FORWARD));
+	c = c || (browseDescription->browseDirection == UA_BROWSEDIRECTION_BOTH);
+	c = c && &browseDescription->referenceTypeId == UA_NULL;
+	c = c || UA_NodeId_equal(&browseDescription->referenceTypeId, &reference->referenceTypeId);
+	//TODO subtypes
+	return c;
+}
+UA_Int32 Service_Browse_getBrowseResult(Namespace *ns,UA_BrowseDescription *browseDescription,UA_UInt32 requestedMaxReferencesPerNode, UA_BrowseResult *browseResult)
+{
+	UA_Int32 retval = UA_SUCCESS;
+	const UA_Node* foundNode = UA_NULL;
+	Namespace_Entry_Lock *lock;
+	if(Namespace_get(ns, &browseDescription->nodeId, &foundNode, &lock) == UA_SUCCESS && foundNode)
+	{
+		UA_Int32 i = 0;
+		UA_list_List referenceDescriptionList;
+		UA_list_init(&referenceDescriptionList);
+		for(i = 0; i < (foundNode->referencesSize) && ((UA_UInt32)referenceDescriptionList.size < requestedMaxReferencesPerNode); i++)
+		{
+			if(Service_Browse_returnReference(browseDescription, &foundNode->references[i]) == UA_TRUE)
+			{
+				UA_ReferenceDescription *referenceDescription = UA_NULL;
+				UA_ReferenceDescription_new(&referenceDescription);
+
+				retval |= Service_Browse_getReferenceDescription(ns, &foundNode->references[i],
+					browseDescription->nodeClassMask,browseDescription->resultMask,referenceDescription);
+				if(retval == UA_SUCCESS){
+					retval |= UA_list_addPayloadToBack(&referenceDescriptionList,referenceDescription);
+				}
+			}
+		}
+		//create result array and copy all data from list into it
+		UA_Array_new((void**) &browseResult->references, referenceDescriptionList.size,
+				&UA_.types[UA_REFERENCEDESCRIPTION]);
+
+		browseResult->referencesSize = referenceDescriptionList.size;
+		UA_list_Element *element = referenceDescriptionList.first;
+		UA_Int32 l = 0;
+
+		for (l = 0; l < referenceDescriptionList.size; l++) {
+			UA_ReferenceDescription_copy(
+					(UA_ReferenceDescription*) element->payload,
+					&browseResult->references[l]);
+			element = element->next;
+		}
+		UA_list_destroy(&referenceDescriptionList,
+				(UA_list_PayloadVisitor) UA_ReferenceDescription_delete);
+		return retval;
+	}
+	return UA_ERROR;
+}
+UA_Int32 Service_Browse(SL_Channel *channel, const UA_BrowseRequest *request,
+		UA_BrowseResponse *response) {
+	UA_Int32 retval = UA_SUCCESS;
+	DBG_VERBOSE(UA_NodeId_printf("BrowseService - view=", &request->view.viewId));
+	UA_Int32 i = 0;
+	Namespace *ns = UA_indexedList_findValue(
+			channel->session->application->namespaces,
+			request->nodesToBrowse[i].nodeId.namespace);
+	//TODO request->view not used atm
+	if(ns)
+	{
+		UA_Array_new((void**) &(response->results), request->nodesToBrowseSize,
+				&UA_.types[UA_BROWSERESULT]);
+		response->resultsSize = request->nodesToBrowseSize;
+
+		for(i=0; i < request->nodesToBrowseSize; i++)
+		{
+			retval |= Service_Browse_getBrowseResult(ns,
+					request->nodesToBrowse,
+					request->requestedMaxReferencesPerNode,
+					&response->results[i]);
+		}
+		return retval;
+		response->diagnosticInfosSize = 0;
+		response->diagnosticInfos = UA_NULL;
+		//TODO fill Diagnostic info array
+	}
+	return UA_ERROR;
+}
+/*
 UA_Int32 Service_Browse(SL_Channel *channel, const UA_BrowseRequest *request,
 		UA_BrowseResponse *response) {
 	UA_Int32 retval = UA_SUCCESS;
@@ -83,7 +224,7 @@ UA_Int32 Service_Browse(SL_Channel *channel, const UA_BrowseRequest *request,
 										|| rd->nodeClass
 												== UA_NODECLASS_VARIABLE) {
 									UA_NodeId_copy(&targetNode->nodeId,
-											&rd->typeDefinition.nodeId);
+											&rd->typeDefinition);
 									rd->resultMask |= (1 << 5);
 								}
 								break;
@@ -91,7 +232,6 @@ UA_Int32 Service_Browse(SL_Channel *channel, const UA_BrowseRequest *request,
 						}
 						UA_list_addPayloadToBack(&referencesToReturn, rd);
 						j++;
-
 					}
 				}
 				k++;
@@ -112,9 +252,12 @@ UA_Int32 Service_Browse(SL_Channel *channel, const UA_BrowseRequest *request,
 		UA_list_destroy(&referencesToReturn,
 				(UA_list_PayloadVisitor) UA_ReferenceDescription_delete);
 	}
+	response->diagnosticInfosSize = 0;
+
 	return retval;
 
 }
+*/
 //UA_BrowseResult br;
 //UA_ReferenceNode rn;
 

+ 10 - 5
src/ua_types_encoding_binary.c

@@ -49,7 +49,7 @@ static UA_Int32 UA_Array_calcSizeBinary_asExtensionObject(UA_Int32 nElements, UA
 
 UA_Int32 UA_Array_encodeBinary(const void *src, UA_Int32 noElements, UA_VTable_Entry *vt, UA_ByteString *dst,
                                UA_UInt32 *offset) {
-	if(vt == UA_NULL || dst == UA_NULL || offset == UA_NULL || (src == UA_NULL && noElements > 0))
+	if(vt == UA_NULL || dst == UA_NULL || offset == UA_NULL || ((src == UA_NULL) && (noElements > 0)))
 		return UA_ERROR;
 
 	//Null Arrays are encoded with length = -1 // part 6 - §5.24
@@ -994,6 +994,7 @@ UA_Int32 UA_ReferenceDescription_calcSizeBinary(UA_ReferenceDescription const *p
 	if(p == UA_NULL) // internal size for UA_memalloc
 		return sizeof(UA_ReferenceDescription);
 	UA_Int32 length = 0;
+	length += UA_ExpandedNodeId_calcSizeBinary(&p->nodeId);
 	if((p->resultMask & 0x01) != 0) // UA_BROWSERESULTMASK_REFERENCETYPEID = 1
 		length += UA_NodeId_calcSizeBinary(&p->referenceTypeId);
 	if((p->resultMask & 0x02) != 0) // UA_BROWSERESULTMASK_ISFORWARD = 2
@@ -1016,12 +1017,15 @@ UA_Int32 UA_ReferenceDescription_encodeBinary(UA_ReferenceDescription const *src
 		retval |= UA_NodeId_encodeBinary(&src->referenceTypeId, dst, offset);
 	if((src->resultMask & 0x02) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_ISFORWARD = 2
 		retval |= UA_Boolean_encodeBinary(&src->isForward, dst, offset);
-	if((src->resultMask & 0x04) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_NODECLASS = 4
-		retval |= UA_NodeClass_encodeBinary(&src->nodeClass, dst, offset);
+
+	UA_ExpandedNodeId_encodeBinary(&src->nodeId,dst,offset);
 	if((src->resultMask & 0x08) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_BROWSENAME = 8
 		retval |= UA_QualifiedName_encodeBinary(&src->browseName, dst, offset);
 	if((src->resultMask & 0x10) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_DISPLAYNAME = 16
 		retval |= UA_LocalizedText_encodeBinary(&src->displayName, dst, offset);
+
+	if((src->resultMask & 0x04) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_NODECLASS = 4
+		retval |= UA_NodeClass_encodeBinary(&src->nodeClass, dst, offset);
 	if((src->resultMask & 0x20) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_TYPEDEFINITION = 32
 		retval |= UA_ExpandedNodeId_encodeBinary(&src->typeDefinition, dst, offset);
 	return retval;
@@ -1040,12 +1044,13 @@ UA_Int32 UA_ReferenceDescription_decodeBinary(UA_String const *src, UA_UInt32 *o
 		retval |= UA_NodeId_decodeBinary(src, offset, &dst->referenceTypeId);
 	if((resultMask & 0x02) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_ISFORWARD = 2
 		retval |= UA_Boolean_decodeBinary(src, offset, &dst->isForward);
-	if((resultMask & 0x04) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_NODECLASS = 4
-		retval |= UA_NodeClass_decodeBinary(src, offset, &dst->nodeClass);
+	retval |= UA_ExpandedNodeId_decodeBinary(src,offset,&dst->nodeId);
 	if((resultMask & 0x08) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_BROWSENAME = 8
 		retval |= UA_QualifiedName_decodeBinary(src, offset, &dst->browseName);
 	if((resultMask & 0x10) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_DISPLAYNAME = 16
 		retval |= UA_LocalizedText_decodeBinary(src, offset, &dst->displayName);
+	if((resultMask & 0x04) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_NODECLASS = 4
+		retval |= UA_NodeClass_decodeBinary(src, offset, &dst->nodeClass);
 	if((resultMask & 0x20) != 0 && retval == UA_SUCCESS) // UA_BROWSERESULTMASK_TYPEDEFINITION = 32
 		retval |= UA_ExpandedNodeId_decodeBinary(src, offset, &dst->typeDefinition);
 	return retval;