diff --git a/UA_PLC.c b/UA_PLC.c new file mode 100644 index 0000000..7152bf8 --- /dev/null +++ b/UA_PLC.c @@ -0,0 +1,1681 @@ + +#include "UA_PLC.h" +#include +static UA_StatusCode +nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void *handle); +void saveUA_ReferenceDescriptionToUAReferenceDescription(int j,UA_ReferenceDescription *ref,UAReferenceDescription *BrowseResult); +UA_Client *client; +u32 UA_Connect(STRING endpointUrl,UASessionConnectInfo SessionConnectInfo,long *ConnectionHdl){ + UA_Client *c = UA_Client_new(); + UA_StatusCode flag = UA_ClientConfig_setDefault(UA_Client_getConfig(c)); + UA_ClientConfig *config=UA_Client_getConfig(c); + + config->securityMode=SessionConnectInfo.SecurityMsgMode; + config->timeout=SessionConnectInfo.SessionTimeout; + if (flag == UA_STATUSCODE_GOOD) { + flag=UA_Client_connect(c, endpointUrl.data); + + }else + { + UA_Client_delete(c); + //memset(c,0,100); + return flag; + } + client = c; + *ConnectionHdl = (long *)c; + printf("ConnectionHdl %lld \n",*ConnectionHdl); + return flag; +} + + + +u32 UA_Disconnect(long ConnectionHdl){ + UA_Client *c =(UA_Client*)ConnectionHdl; + UA_Client_delete(ConnectionHdl); + return 0; +} + +u32 UA_NamespaceGetIndexList(long ConnectionHdl,u16 NamespaceUrisCount,STRING *NamespaceUris,u16 *NamespaceIndexes){ + UA_Client *c = (UA_Client*)ConnectionHdl; + int i; + u32 retval=0; + if(NamespaceUrisCount>MAX_ELEMENTS_NAMESPACES){ + retval=0xA0000002; + return retval; + } + for(i=0;i=0){ + ServerUri->length=ns[ServerIndex].length; + ServerUri->data=ns[ServerIndex].data; + }else{ + retval = 0xA0000200; + } + + return retval; +} + +u32 UA_ServerGetIndexByUriList(long ConnectionHdl,u16 ServerUrisCount,STRING ServerUris[],u16 *ServerIndexes){ + UA_Client *c = (UA_Client*)ConnectionHdl; + int i; + u32 retval; + if(ServerUrisCount>MAX_ELEMENTS_NAMESPACES){ + retval=0xA0000002; + return retval; + } + for(i=0;iMAX_ELEMENTS_RELATIVEPATH){ + retval=0xA0000002; + return retval; + } + for(int i=0;inodeId.nodeId.namespaceIndex==BrowsePaths[i].RelativePath.Elements[0].TargetName.NamespaceIndex){ + //printf("%d\n",ref->nodeId.nodeId.identifier.string.data); + //printf("%d\n",BrowsePaths[0].RelativePath.Elements[i].TargetName.Name.data); + if(my_strcmp(ref->nodeId.nodeId.identifier.string.data,BrowsePaths[i].RelativePath.Elements[0].TargetName.Name.data)==0){ + TargetNodeIDs[i].NamespaceIndex=ref->nodeId.nodeId.namespaceIndex; + TargetNodeIDs[i].IdentifierType=IdentifierTypeChange[ref->nodeId.nodeId.identifierType]; + TargetNodeIDs[i].Identifier.data=ref->nodeId.nodeId.identifier.string.data; + TargetNodeIDs[i].Identifier.length=ref->nodeId.nodeId.identifier.string.length; + flag = 1; + } + } + } + } + } + if(flag == 0){ + retval = 0xA0000200; + } + return retval; +} + +u32 UA_NodeGetHandleList(long ConnectionHdl,u16 NodeIDCount,UANodeID *NodeIDs,long *NodeHdls,u32 ErrorIDs[]){ + int i; + u32 retval=0; + UA_NodeId *NodeID=malloc(sizeof(UA_NodeId)*NodeIDCount); + if(NodeIDCount>MAX_ELEMENTS_NODELIST){ + retval=0xA0000002; + return retval; + } + + for(i=0;i=0&&NodeIDs[i].IdentifierType<4){ + switch(NodeIDs[i].IdentifierType){ + case 0:NodeID[i]=UA_NODEID_NUMERIC(NodeIDs[i].NamespaceIndex,NodeIDs[i].Identifier.data);break; + case 1:NodeID[i]=UA_NODEID_STRING(NodeIDs[i].NamespaceIndex,NodeIDs[i].Identifier.data);break; + case 2:NodeID[i].identifierType=4; + NodeID[i].identifier.string.data=NodeIDs[i].Identifier.data; + NodeID[i].identifier.string.length=NodeIDs[i].Identifier.length; + NodeID[i].namespaceIndex=NodeIDs[i].NamespaceIndex;break; + case 3:NodeID[i]=UA_NODEID_BYTESTRING(NodeIDs[i].NamespaceIndex,NodeIDs[i].Identifier.data);break; + } + ErrorIDs[i]=0; + }else{ + ErrorIDs[i]=0xA0000301; + retval=ErrorIDs[i]; + } + // NodeID[i].identifier.string.data=NodeIDs[i].Identifier.data; + // NodeID[i].identifier.string.length=NodeIDs[i].Identifier.length; + // NodeID[i].namespaceIndex=NodeIDs[i].NamespaceIndex; + NodeHdls[i]=&NodeID[i]; + //UA_NodeId *NodeID1=malloc(sizeof(UA_NodeId)*NodeIDCount); + //UA_NodeId_delete(&NodeID[i]); + } + + return retval; + +} + +u32 UA_NodeReleaseHandleList(long ConnectionHdl,u16 NodeHdlCount,long *NodeHdls,u32 ErrorIDs[]){ + int i; + u32 retval=0; + if(NodeHdlCount>MAX_ELEMENTS_NODELIST){ + retval=0xA0000002; + return retval; + } + for(i=0;i=0&&NodeID.IdentifierType<4){ + // switch(NodeID.IdentifierType){ + // case 0:NODEID.identifierType=0; + // case 1:NODEID.identifierType=3; + // case 2:NODEID.identifierType=4; + // case 3:NODEID.identifierType=5; + // } + // ret=0; + // }else{ + // ret=0xA0000301; + // } + // NODEID.identifier.string = UA_STRING(NodeID.Identifier.data); + UA_NodeClass outNodeClass; + UA_NodeClass_init(&outNodeClass); + retval=UA_Client_readNodeClassAttribute(c,NODEID,&outNodeClass); + if(retval!=0){ + ErrorIDs[0]=retval; + ret=retval; + } + u32 temp =outNodeClass; + NodeInfo->NodeClass=temp; + UA_NodeClass_clear(&outNodeClass); + + UA_QualifiedName outBrowseName; + UA_QualifiedName_init(&outBrowseName); + retval=UA_Client_readBrowseNameAttribute(c,NODEID,&outBrowseName); + if(retval!=0){ + ErrorIDs[1]=retval; + ret=retval; + } + NodeInfo->BrowseName.NamespaceIndex=outBrowseName.namespaceIndex; + NodeInfo->BrowseName.Name.length=outBrowseName.name.length; + NodeInfo->BrowseName.Name.data=outBrowseName.name.data; + UA_QualifiedName_clear(&outBrowseName); + + UA_LocalizedText outDisplayName; + UA_LocalizedText_init(&outDisplayName); + retval=UA_Client_readDisplayNameAttribute(c,NODEID,&outDisplayName); + if(retval!=0){ + ErrorIDs[2]=retval; + ret=retval; + } + NodeInfo->DisplayName.Locale=outDisplayName.locale.data; + NodeInfo->DisplayName.Text.length=outDisplayName.text.length; + NodeInfo->DisplayName.Text.data=outDisplayName.text.data; + UA_LocalizedText_clear(&outDisplayName); + + UA_LocalizedText outDescription; + UA_LocalizedText_init(&outDescription); + retval=UA_Client_readDescriptionAttribute(c,NODEID,&outDescription); + if(retval!=0){ + ErrorIDs[3]=retval; + ret=retval; + } + NodeInfo->Description.Locale=outDescription.locale.data; + NodeInfo->Description.Text.length=outDescription.text.length; + NodeInfo->Description.Text.data=outDescription.text.data; + UA_LocalizedText_clear(&outDescription); + + UA_UInt32 outWriteMask; + UA_UInt32_init(&outWriteMask); + retval=UA_Client_readWriteMaskAttribute(c,NODEID,&outWriteMask); + if(retval!=0){ + ErrorIDs[4]=retval; + ret=retval; + } + NodeInfo->WriteMask=outWriteMask; + UA_UInt32_clear(&outWriteMask); + + UA_UInt32 outUserWriteMask; + UA_UInt32_init(&outUserWriteMask); + retval=UA_Client_readUserWriteMaskAttribute(c,NODEID,&outUserWriteMask); + if(retval!=0){ + ErrorIDs[5]=retval; + ret=retval; + } + NodeInfo->UserWriteMask=outUserWriteMask; + UA_UInt32_clear(&outUserWriteMask); + + UA_Boolean outIsAbstract; + UA_Boolean_init(&outIsAbstract); + retval=UA_Client_readIsAbstractAttribute(c,NODEID,&outIsAbstract); + if(retval!=0){ + ErrorIDs[6]=retval; + //ret=retval; + } + NodeInfo->IsAbstract=outIsAbstract; + UA_Boolean_clear(&outIsAbstract); + + UA_Boolean outSymmetric; + UA_Boolean_init(&outSymmetric); + retval=UA_Client_readSymmetricAttribute(c,NODEID,&outSymmetric); + if(retval!=0){ + ErrorIDs[7]=retval; + //ret=retval; + } + NodeInfo->Symmetric=outSymmetric; + UA_Boolean_clear(&outSymmetric); + + UA_LocalizedText outInverseName; + UA_LocalizedText_init(&outInverseName); + retval=UA_Client_readInverseNameAttribute(c,NODEID,&outInverseName); + if(retval!=0){ + ErrorIDs[8]=retval; + //ret=retval; + } + NodeInfo->InverseName.length=outInverseName.text.length; + NodeInfo->InverseName.data=outInverseName.text.data; + UA_LocalizedText_clear(&outInverseName); + + UA_Boolean outContainsNoLoops; + UA_Boolean_init(&outContainsNoLoops); + retval=UA_Client_readContainsNoLoopsAttribute(c,NODEID,&outContainsNoLoops); + if(retval!=0){ + ErrorIDs[9]=retval; + //ret=retval; + } + NodeInfo->ContainsNoLoops=outContainsNoLoops; + UA_Boolean_clear(&outContainsNoLoops); + + UA_Byte outEventNotifier; + UA_Byte_init(&outEventNotifier); + retval=UA_Client_readEventNotifierAttribute(c,NODEID,&outEventNotifier); + if(retval!=0){ + ErrorIDs[10]=retval; + //ret=retval; + } + NodeInfo->EventNotifier=outEventNotifier; + UA_Byte_clear(&outEventNotifier); + + UA_NodeId outDataType; + UA_NodeId_init(&outDataType); + retval=UA_Client_readDataTypeAttribute(c,NODEID,&outDataType); + if(retval!=0){ + ErrorIDs[11]=retval; + ret=retval; + } + NodeInfo->DataType.NamespaceIndex=outDataType.namespaceIndex; + NodeInfo->DataType.IdentifierType=outDataType.identifierType; + NodeInfo->DataType.Identifier.length=outDataType.identifier.string.length; + NodeInfo->DataType.Identifier.data=outDataType.identifier.string.data; + UA_NodeId_clear(&outDataType); + + UA_Int32 outValueRank; + UA_Int32_init(&outValueRank); + retval=UA_Client_readValueRankAttribute(c,NODEID,&outValueRank); + if(retval!=0){ + ErrorIDs[12]=retval; + ret=retval; + } + NodeInfo->ValueRank=outValueRank; + UA_Int32_clear(&outValueRank); + + UA_UInt32 outArrayDimensions[MAX_ELEMENTS_ARRAYDIMENSION]; + //UA_UInt32_init(*outArrayDimensions); + int size; + retval=UA_Client_readArrayDimensionsAttribute(c,NODEID,&size,outArrayDimensions); + if(retval!=0){ + ErrorIDs[13]=retval; + ret=retval; + } + for(int i=0;iArrayDimension[i]=outArrayDimensions[i]; + } + + + UA_Byte outAccessLevel; + UA_Byte_init(&outAccessLevel); + retval=UA_Client_readAccessLevelAttribute(c,NODEID,&outAccessLevel); + if(retval!=0){ + ErrorIDs[14]=retval; + ret=retval; + } + NodeInfo->AccessLevel=outAccessLevel; + + UA_Byte outUserAccessLevel; + UA_Byte_init(&outUserAccessLevel); + retval=UA_Client_readUserAccessLevelAttribute(c,NODEID,&outUserAccessLevel); + if(retval!=0){ + ErrorIDs[15]=retval; + ret=retval; + } + NodeInfo->UserAccessLevel=outUserAccessLevel; + + UA_Double outMinSamplingInterval; + UA_Double_init(&outMinSamplingInterval); + retval=UA_Client_readMinimumSamplingIntervalAttribute(c,NODEID,&outMinSamplingInterval); + if(retval!=0){ + ErrorIDs[16]=retval; + ret=retval; + } + NodeInfo->MinimumSamplingInterval=outMinSamplingInterval; + + UA_Boolean outHistorizing; + UA_Boolean_init(&outHistorizing); + retval=UA_Client_readHistorizingAttribute(c,NODEID,&outHistorizing); + if(retval!=0){ + ErrorIDs[17]=retval; + ret=retval; + } + NodeInfo->Historizing=outHistorizing; + + UA_Boolean outExecutable; + UA_Boolean_init(&outExecutable); + retval=UA_Client_readExecutableAttribute(c,NODEID,&outExecutable); + if(retval!=0){ + ErrorIDs[18]=retval; + //ret=retval; + } + NodeInfo->Executable=outExecutable; + + UA_Boolean outUserExecutable; + UA_Boolean_init(&outUserExecutable); + retval=UA_Client_readUserExecutableAttribute(c,NODEID,&outUserExecutable); + if(retval!=0){ + ErrorIDs[19]=retval; + //ret=retval; + } + NodeInfo->UserExecutable=outUserExecutable; + + return ret; +} + +u32 UA_SubscriptionCreate(long ConnectionHdl,bool PublishingEnable,u16 Priority,long *SubscriptionHdl,TIME *PublishingInterval){ + UA_Client *c = (UA_Client*)ConnectionHdl; + UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default(); + request.requestedPublishingInterval=*PublishingInterval; + request.publishingEnabled=PublishingEnable; + request.priority=Priority; + UA_CreateSubscriptionResponse *response=malloc(sizeof(UA_CreateSubscriptionResponse)); + *response = UA_Client_Subscriptions_create(c,request,NULL,NULL,NULL); + u32 retval=response[0].responseHeader.serviceResult; + if(retval!=UA_STATUSCODE_GOOD){ + UA_CreateSubscriptionResponse_clear(&response[0]); + return retval; + } + printf("response[0].subscripstionId is %x\n",response[0].subscriptionId); + *SubscriptionHdl=(long *)response[0].subscriptionId; + UA_CreateSubscriptionResponse_clear(&response[0]); + return retval; +} + +u32 UA_SubscriptionDelete(long ConnectionHdl,long SubscriptionHdl){ + UA_Client *c = (UA_Client*)ConnectionHdl; + u32 retval=UA_Client_Subscriptions_deleteSingle(c,SubscriptionHdl); + return retval; +} + +u32 UA_SubscriptionModify(long ConnectionHdl,long SubscriptionHdl,bool PublishingEnable,u16 Priority,TIME *PublishingInterval){ + UA_Client *c = (UA_Client*)ConnectionHdl; + //UA_CreateSubscriptionRequest *request =(UA_CreateSubscriptionRequest *)SubscriptionHdl; + UA_ModifySubscriptionRequest request; + UA_ModifySubscriptionRequest_init(&request); + request.subscriptionId=SubscriptionHdl; + request.requestedPublishingInterval=*PublishingInterval; + //request.requestHeader.publishingEnabled=PublishingEnable; + request.priority=Priority; + UA_ModifySubscriptionResponse response=UA_Client_Subscriptions_modify(c,request); + u32 retval = response.responseHeader.serviceResult; + //SubscriptionHdl=(u32 *)&request; + + return retval; +} + +u32 UA_SubscriptionProcessed(long SubscriptionHdl){ + +} + +u32 SubscriptionHdlzu2[100]; +u32 MonItemHdlzu[100]; +UAMonitoredVariables MonVlaue[100]; +int MontNum=0; +static void handler_DataChanged(UA_Client *client, UA_UInt32 subId, + void *subContext, UA_UInt32 monId, + void *monContext, UA_DataValue *value) +{ + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Received Notification"); + + UA_NodeId *ptr = (UA_NodeId*)monContext; + SubscriptionHdlzu2[MontNum]=subId; + MonItemHdlzu[MontNum]=monId; + MonVlaue[MontNum].Values.data=value->value.data; + MonVlaue[MontNum].Values.type=value->value.type->typeId.identifier.numeric; + UA_DateTime now = UA_DateTime_nowMonotonic(); + MonVlaue[MontNum].TimeStamps=now; + MonVlaue[MontNum].NewValuesCount=1; + //MonVlaue[MontNum].NodeQualityIDs[0]=0; + //UA_Int32 currentValue = *(UA_Int32*)(value->value.data); + + MontNum++; +} + +u32 UA_MonitoredItemAddList(long ConnectionHdl,long SubscriptionHdl,u16 NodeHdlCount, + long *NodeHdls,UAMonitoringSyncMode SyncMode, + UANodeAdditionalInfo *NodeAddInfos,u32 *MonitoredItemHdls,u32 ErrorIDs[]){ + UA_Client *c = (UA_Client*)ConnectionHdl; + u32 retval=0; + if(NodeHdlCount>MAX_ELEMENTS_MONITORLIST){ + retval=0xA0000002; + return retval; + } + if(SyncMode==UAMS_ControllerSync){ + for(int i=0;iMAX_ELEMENTS_NODELIST){ + retval=0xA0000002; + } + else + { + for(i=0;idata; + variables[i].type=out->type->typeId.identifier.numeric; + } + else if(NodeAddInfos[i].AttributeID == UA_ATTRIBUTEID_NODECLASS) + { + UA_NodeClass *out1; + memcpy(out1, (UA_NodeClass*)res.value.data, sizeof(UA_NodeClass)); + variables[i].data=out1; + variables[i].type=UA_TYPES_NODECLASS; + } + else if(UA_Variant_isScalar(&res.value)) + { + memcpy(&variables[i].data, &res.value.data, res.value.type->memSize); + UA_free(res.value.data); + res.value.data = NULL; + variables[i].type=res.value.type->typeId.identifier.numeric; + } + else + { + retval = UA_STATUSCODE_BADUNEXPECTEDERROR; + } + + } + } //end for + } + else + { + + retval = UA_STATUSCODE_BADUNEXPECTEDERROR; + } + }//end if(retval == UA_STATUSCODE_GOOD) + + UA_ReadResponse_clear(&response); + } + +} + +*/ +u32 UA_ReadList(long ConnectionHdl,u16 NodeHdlCount,long *NodeHdls,UANodeAdditionalInfo *NodeAddInfos,UA_Value *variables,u32 ErrorIDs[]){ + //UA_Client *c = (UA_Client*)ConnectionHdl; + UA_Client *c=client; + int i; + u32 retval; + UA_ReadValueId item[NodeHdlCount]; + if(NodeHdlCount>MAX_ELEMENTS_NODELIST){ + retval=0xA0000002; + } + else + { + for(i=0;itypeId.identifier.numeric; + + } + else if(NodeAddInfos[i].AttributeID == UA_ATTRIBUTEID_NODECLASS) + { + //UA_NodeClass *out1; + //memcpy(out1, (UA_NodeClass*)res.value.data, sizeof(UA_NodeClass)); + memcpy(variables[i].data,res.value.data,8); + variables[i].type=UA_TYPES_NODECLASS; + } + else if(UA_Variant_isScalar(&res.value)) + { + //memcpy(&variables[i].data, &res.value.data, res.value.type->memSize); + //UA_free(res.value.data); + //res.value.data = 0; + variables[i].type=res.value.type->typeId.identifier.numeric; + } + else + { + retval = UA_STATUSCODE_BADUNEXPECTEDERROR; + } + + } + UA_free(res.value.data); //????? need or not + } + } //end for + } + else + { + + retval = UA_STATUSCODE_BADUNEXPECTEDERROR; + } + }//end if(retval == UA_STATUSCODE_GOOD) + // console_printf("------------#f8 --------------\n"); + // UA_ReadResponse_clear(&response); + } + + return retval; +} + +u32 UA_WriteList(long ConnectionHdl,u16 NodeHdlCount,long *NodeHdls,UANodeAdditionalInfo *NodeAddInfos,UA_Value *variables,u32 ErrorIDs[]){ + UA_Client *c = (UA_Client*)ConnectionHdl; + int i; + UA_StatusCode retval=0; + if(NodeHdlCount>MAX_ELEMENTS_NODELIST){ + retval=0xA0000002; + return retval; + } + //UA_NodeId NODEid= UA_NODEID_STRING(1, "A1.the anwser2"); + //UA_Client_writeValueAttribute(c,NODEid,&in); + UA_WriteValue wValue[NodeHdlCount]; + for(i=0;iMAX_ELEMENTS_METHOD){ + retval=0xA0000002; + return retval; + } + + for(int i = 0;iMAX_ELEMENTS_METHOD){ + retval=0xA0000002; + return retval; + } + for(i=0;iArgumentSize]; + for(int i=0;iArgumentSize;i++){ + UA_Variant_init(&newValue[i]); + UA_Variant_setScalar(&newValue[i],InputArguments->value[i].data,&UA_TYPES[InputArguments->value[i].type-1]); + } + request.methodsToCall->inputArguments = &newValue; // cast const...(UA_Variant *)(void*)(uintptr_t) + request.methodsToCall->inputArgumentsSize = InputArguments->ArgumentSize; + size_t outputSzie; + UA_Variant *outputValue; + // UA_Variant inValue[2]; + // UA_Variant_init(&inValue[0]); + // UA_Variant_init(&inValue[1]); + // UA_UInt16 a1=1; + // UA_UInt16 a2=2; + // UA_Variant_setScalar(&inValue[0],&a1,&UA_TYPES[UA_TYPES_INT16]); + // UA_Variant_setScalar(&inValue[1],&a2,&UA_TYPES[UA_TYPES_INT16]); + // UA_Client_call(c,UA_NODEID_STRING(0,"A1"),UA_NODEID_STRING(1,"test"),2,inValue,&outputSzie,&outputValue); + /* Call the service */ + UA_CallResponse response = UA_Client_Service_call(c, request); + UA_StatusCode retval = response.responseHeader.serviceResult; + if(retval == UA_STATUSCODE_GOOD) { + if(response.resultsSize == 1) + retval = response.results[0].statusCode; + else + retval = UA_STATUSCODE_BADUNEXPECTEDERROR; + } + if(retval != UA_STATUSCODE_GOOD) { + UA_CallResponse_clear(&response); + return retval; + } + + /* Move the output arguments */ + if(&OutputArguments->value != NULL && &OutputArguments->ArgumentSize != NULL) { + OutputArguments->ArgumentSize==response.results[0].outputArgumentsSize; + for(int i=0;iArgumentSize;i++){ + UA_Variant output; + UA_Variant_init(&output); + output = response.results[0].outputArguments[i]; + OutputArguments->value[i].data=output.data; + OutputArguments->value[i].type=output.type->typeId.identifier.numeric; + } + } + //UA_CallResponse_clear(&response); + return retval; +} + + + +u32 UA_Browse(long ConnectionHdl,UABrowseDescription BrowseDescription,u32 ContinuationPointIn,u16 *BrowseResultCount,UAReferenceDescription *BrowseResult,u32 ContinuationPointOut){ + UA_Client *c = (UA_Client*)ConnectionHdl; + UA_StatusCode retval; + if(ContinuationPointIn==0){ + UA_BrowseRequest bReq; + UA_BrowseRequest_init(&bReq); + bReq.requestedMaxReferencesPerNode = 0; + bReq.nodesToBrowse = UA_BrowseDescription_new(); + bReq.nodesToBrowseSize = 1; + switch(BrowseDescription.StartingNodeID.IdentifierType){ + case 0:bReq.nodesToBrowse[0].nodeId=UA_NODEID_NUMERIC(BrowseDescription.StartingNodeID.NamespaceIndex,BrowseDescription.StartingNodeID.Identifier.data);break; + case 1:bReq.nodesToBrowse[0].nodeId=UA_NODEID_STRING(BrowseDescription.StartingNodeID.NamespaceIndex,BrowseDescription.StartingNodeID.Identifier.data);break; + case 2:bReq.nodesToBrowse[0].nodeId.identifierType=4; + bReq.nodesToBrowse[0].nodeId.identifier.string.data=BrowseDescription.StartingNodeID.Identifier.data; + bReq.nodesToBrowse[0].nodeId.identifier.string.length=BrowseDescription.StartingNodeID.Identifier.length; + bReq.nodesToBrowse[0].nodeId.namespaceIndex=BrowseDescription.StartingNodeID.NamespaceIndex;break; + case 3:bReq.nodesToBrowse[0].nodeId=UA_NODEID_BYTESTRING(BrowseDescription.StartingNodeID.NamespaceIndex,BrowseDescription.StartingNodeID.Identifier.data);break; + default:retval=UA_STATUSCODE_BADUNEXPECTEDERROR; + } + if(BrowseDescription.ReferenceTypeID.Identifier.length!=NULL) + bReq.nodesToBrowse[0].referenceTypeId=UA_NODEID_NUMERIC(0,BrowseDescription.ReferenceTypeID.Identifier.length); + if(BrowseDescription.ResultMask==1||BrowseDescription.ResultMask==2||BrowseDescription.ResultMask==4||BrowseDescription.ResultMask==8||BrowseDescription.ResultMask==16) + bReq.nodesToBrowse[0].resultMask = BrowseDescription.ResultMask; + if(BrowseDescription.Direction==2||BrowseDescription.Direction==1||BrowseDescription.Direction==0) + bReq.nodesToBrowse[0].browseDirection = BrowseDescription.Direction; + if(BrowseDescription.IncludeSubtypes==0||BrowseDescription.IncludeSubtypes==1) + bReq.nodesToBrowse[0].includeSubtypes = BrowseDescription.IncludeSubtypes; + if(BrowseDescription.NodeClass!=NULL) + bReq.nodesToBrowse[0].nodeClassMask = BrowseDescription.NodeClass; + + UA_BrowseResponse bResp = UA_Client_Service_browse(c, bReq); + retval = bResp.responseHeader.serviceResult; + if(retval == UA_STATUSCODE_GOOD) { + if(bResp.results[0].referencesSize<=MAX_ELEMENTS_NODELIST){ + *BrowseResultCount=bResp.results[0].referencesSize; + for(size_t j = 0; j < bResp.results[0].referencesSize; ++j){ + UA_ReferenceDescription *ref = &bResp.results[0].references[j]; + saveUA_ReferenceDescriptionToUAReferenceDescription(j,ref,BrowseResult); + } + ContinuationPointOut=0; + }else if(bResp.results[0].referencesSize>MAX_ELEMENTS_NODELIST){ + *BrowseResultCount=MAX_ELEMENTS_NODELIST; + UA_ReferenceDescription *ref1=malloc(sizeof(UA_ReferenceDescription)*(bResp.results[0].referencesSize-MAX_ELEMENTS_NODELIST+1)); + for(size_t j = 0; j < MAX_ELEMENTS_NODELIST; ++j){ + UA_ReferenceDescription *ref = &bResp.results[0].references[j]; + saveUA_ReferenceDescriptionToUAReferenceDescription(j,ref,BrowseResult); + } + for(size_t j=MAX_ELEMENTS_NODELIST+1;j<=bResp.results[0].referencesSize;j++){ + ref1[j-MAX_ELEMENTS_NODELIST]=bResp.results[0].references[j]; + } + ref1[0].browseName.namespaceIndex=bResp.results[0].referencesSize-MAX_ELEMENTS_NODELIST; + ContinuationPointOut=(u32 *)ref1; + } + + } + //UA_BrowseRequest_clear(&bReq); + //UA_BrowseResponse_clear(&bResp); + }else{ + UA_ReferenceDescription *ref=(UA_ReferenceDescription *)ContinuationPointOut; + if(ref[0].browseName.namespaceIndex<=MAX_ELEMENTS_NODELIST){ + for(size_t j = 1; j < ref[0].browseName.namespaceIndex+1; ++j){ + saveUA_ReferenceDescriptionToUAReferenceDescription(j,ref,BrowseResult); + } + ContinuationPointOut=0; + }else if(ref[0].browseName.namespaceIndex>MAX_ELEMENTS_NODELIST){ + UA_ReferenceDescription *ref1=malloc(sizeof(UA_ReferenceDescription)*(ref[0].browseName.namespaceIndex-MAX_ELEMENTS_NODELIST+1)); + for(size_t j = 1; j < MAX_ELEMENTS_NODELIST+1; ++j){ + saveUA_ReferenceDescriptionToUAReferenceDescription(j,ref,BrowseResult); + } + for(size_t j=MAX_ELEMENTS_NODELIST+1;j<=ref[0].browseName.namespaceIndex;j++){ + ref1[j-MAX_ELEMENTS_NODELIST]=ref[j]; + } + ref1[0].browseName.namespaceIndex=ref[0].browseName.namespaceIndex-MAX_ELEMENTS_NODELIST; + ContinuationPointOut=(u32 *)ref1; + } + + } + + return retval; +} + +u32 SubscriptionHdlzu[100]; +u32 EventItemHdlzu[100]; +UAEventField EventFields[100]; +int EventNum=0; +static void events_callback(UA_Client *client,UA_UInt32 subId,void *subContext,UA_UInt32 monId, + void *monContext, size_t nEventFields,UA_Variant *eventFields){ + UA_LOG_INFO(UA_Log_Stdout,UA_LOGCATEGORY_USERLAND,"Notification"); + + //UA_assert(*(UA_UInt32*)monContext == monId); + SubscriptionHdlzu[EventNum]=subId; + EventItemHdlzu[EventNum]=monId; + + int j=0; + STRING *context = (STRING *)monContext; + for(size_t i = 0;itext.length,lt->text.data); + EventFields[EventNum].Message.data=lt->text.length; + EventFields[EventNum].Message.length=lt->text.data; + }else if(UA_Variant_hasScalarType(&eventFields[i],&UA_TYPES[UA_TYPES_NODEID])){ + int flag=1; + while(flag){ + if(!strcmp(context[j].data,"EventType")){ + //UA_LOG_INFO(UA_Log_Stdout,UA_LOGCATEGORY_USERLAND,"EventType"); + UA_NodeId nodeid; + UA_NodeId_copy((UA_NodeId *)eventFields[i].data,&nodeid); + EventFields[EventNum].EventType.NamespaceIndex=nodeid.namespaceIndex; + switch (nodeid.identifierType) + { + case 0: EventFields[EventNum].EventType.IdentifierType=0; + EventFields[EventNum].EventType.Identifier.length=nodeid.identifier.numeric; + break; + case 3: EventFields[EventNum].EventType.IdentifierType=1; + EventFields[EventNum].EventType.Identifier.data=nodeid.identifier.string.data; + EventFields[EventNum].EventType.Identifier.length=nodeid.identifier.string.length; + break; + case 4: EventFields[EventNum].EventType.IdentifierType=2;break; + //EventFields[EventNum].EventType.Identifier.data=nodeid.identifier.guid.; + case 5: EventFields[EventNum].EventType.IdentifierType=3; + EventFields[EventNum].EventType.Identifier.data=nodeid.identifier.byteString.data; + EventFields[EventNum].EventType.Identifier.length=nodeid.identifier.byteString.length; + break; + default: + break; + } + j++; + flag=0; + }else if(!strcmp(context[j].data,"SourceNode")){ + UA_NodeId nodeid; + UA_NodeId_copy((UA_NodeId *)eventFields[i].data,&nodeid); + EventFields[EventNum].SourceNode.NamespaceIndex=nodeid.namespaceIndex; + switch (nodeid.identifierType) + { + case 0: EventFields[EventNum].SourceNode.IdentifierType=0; + EventFields[EventNum].SourceNode.Identifier.length=nodeid.identifier.numeric; + break; + case 3: EventFields[EventNum].SourceNode.IdentifierType=1; + EventFields[EventNum].SourceNode.Identifier.data=nodeid.identifier.string.data; + EventFields[EventNum].SourceNode.Identifier.length=nodeid.identifier.string.length; + break; + case 4: EventFields[EventNum].SourceNode.IdentifierType=2;break; + //EventFields[EventNum].SourceNode.Identifier.data=nodeid.identifier.guid.; + case 5: EventFields[EventNum].SourceNode.IdentifierType=3; + EventFields[EventNum].SourceNode.Identifier.data=nodeid.identifier.byteString.data; + EventFields[EventNum].SourceNode.Identifier.length=nodeid.identifier.byteString.length; + break; + default: + break; + } + j++; + flag=0; + }else{ + j++; + } + } + //UA_LOG_INFO(UA_Log_Stdout,UA_LOGCATEGORY_USERLAND,"UA_TYPES_NODEID"); + }else if(UA_Variant_hasScalarType(&eventFields[i],&UA_TYPES[UA_TYPES_DATETIME])){ + //UA_LOG_INFO(UA_Log_Stdout,UA_LOGCATEGORY_USERLAND,"UA_TYPES_DATETIME"); + int flag=1; + while(flag){ + if(!strcmp(context[j].data,"Time")){ + UA_LOG_INFO(UA_Log_Stdout,UA_LOGCATEGORY_USERLAND,"Time"); + TIME time =*(UA_DateTime *)eventFields[i].data; + EventFields[EventNum].Time=time; + j++; + flag=0; + }else if(!strcmp(context[j].data,"ReceiveTime")){ + UA_LOG_INFO(UA_Log_Stdout,UA_LOGCATEGORY_USERLAND,"ReceiveTime"); + TIME time =*(UA_DateTime *)eventFields[i].data; + EventFields[EventNum].ReceiveTime=time; + j++; + flag=0; + }else{ + j++; + } + } + + } + else{ + //UA_LOG_INFO(UA_Log_Stdout,UA_LOGCATEGORY_USERLAND,"Don't know how to handle type:'%s'",eventFields[i].type->typeName); + } + } + EventNum=EventNum+1; +} + + +u32 UA_EventItemAdd(long ConnectionHdl,long SubscriptionHdl,long NodeHdl, + UANodeID EventType,u16 EventFieldSelectionCount, + UARelativePath *EventFieldSelections,long *EventItemHdl){ + UA_Client *c = (UA_Client*)ConnectionHdl; + u32 retval; + if(EventFieldSelectionCount>MAX_ELEMENTS_SELECTIONS){ + retval=0xA0000002; + return retval; + } + UA_MonitoredItemCreateRequest item; + UA_MonitoredItemCreateRequest_init(&item); + item.itemToMonitor.nodeId = UA_NODEID_NUMERIC(0,2253); + item.itemToMonitor.attributeId = UA_ATTRIBUTEID_EVENTNOTIFIER; + item.monitoringMode = UA_MONITORINGMODE_REPORTING; + + UA_EventFilter fielter; + UA_EventFilter_init(&fielter); + + UA_SimpleAttributeOperand *selectClauses = (UA_SimpleAttributeOperand*) + UA_Array_new(2,&UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]); + STRING *contex=malloc(sizeof(STRING)*EventFieldSelectionCount); + if(!selectClauses){ + retval=UA_STATUSCODE_BADUNEXPECTEDERROR; + return retval; + } + for(size_t i=0;iMAX_ELEMENTS_EVENTITEMLIST){ + retval=0xA0000002; + return retval; + } + UA_Client_run_iterate(c, 1000); + int i,j,flag=0; + for(i=0;iMAX_ELEMENTS_EVENTITEMLIST){ + retval=0xA0000002; + return retval; + } + for(int i=0;itype = i; + outValue->data = value.data; + } + return retval; +} + +unsigned int UA_printValue(UA_Value *value) { + if (value->data != NULL&&value->type != NULL) { + switch (value->type) + { + case UA_TYPES_BOOLEAN:{ + UA_Boolean variableValue = *(UA_Boolean*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %d\n", variableValue); + break; + } + case UA_TYPES_SBYTE:{ + UA_SByte variableValue = *(UA_SByte*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: 0x%x\n", (unsigned char)variableValue); + break; + } + case UA_TYPES_BYTE:{ + UA_Byte variableValue = *(UA_Byte*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: 0x%x\n", variableValue); + break; + } + case UA_TYPES_INT16:{ + UA_Int16 variableValue = *(UA_Int16*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %hd\n", variableValue); + break; + } + case UA_TYPES_UINT16:{ + UA_UInt16 variableValue = *(UA_UInt16*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %hu\n", variableValue); + break; + } + case UA_TYPES_INT32: { + UA_Int32 variableValue = *(UA_Int32*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %d\n", variableValue); + break; + } + case UA_TYPES_UINT32: { + UA_UInt32 variableValue = *(UA_UInt32*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %u\n", variableValue); + break; + } + case UA_TYPES_INT64: { + UA_Int64 variableValue = *(UA_Int64*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %lld\n", variableValue); + break; + } + case UA_TYPES_UINT64: { + UA_UInt64 variableValue = *(UA_UInt64*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %llu\n", variableValue); + break; + } + case UA_TYPES_FLOAT:{ + UA_Float variableValue = *(UA_Float*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %f\n", variableValue); + break; + } + case UA_TYPES_DOUBLE: { + UA_Double variableValue = *(UA_Double*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %f\n", variableValue); + break; + } + case UA_TYPES_STRING: { + UA_String variableValue = *(UA_String*)value->data; + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Variable Value is: %s\n", variableValue.data); + break; + } + default: + return 1; + } + return UA_STATUSCODE_GOOD; + } + return 1; + +} + +static void printTimestamp(char *name, UA_DateTime date) +{ + UA_DateTimeStruct dts = UA_DateTime_toStruct(date); + if (name){ + printf("%s: %02u-%02u-%04u %02u:%02u:%02u.%03u, ", name, + dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec); + } + else + printf("%02u-%02u-%04u %02u:%02u:%02u.%03u, ", + dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec); +} + +static void printDataValue(UA_DataValue *value) +{ + // Print status and timestamps + if (value->hasServerTimestamp){ + printTimestamp("ServerTime", value->serverTimestamp); + } + if (value->hasSourceTimestamp) + printTimestamp("SourceTime", value->sourceTimestamp); + + if (value->hasStatus) + printf("Status 0x%08x, ", value->status); + + if (value->value.type == &UA_TYPES[UA_TYPES_INT32]) { + UA_UInt32 hrValue = *(UA_UInt32 *)value->value.data; + printf("Uint32Value %u\n", hrValue); + } + + if (value->value.type == &UA_TYPES[UA_TYPES_DOUBLE]) { + UA_Double hrValue = *(UA_Double *)value->value.data; + printf("DoubleValue %f\n", hrValue); + } +} + +static UA_Boolean readRaw(const UA_HistoryData *data) +{ + printf("readRaw Value count: %lu\n", (long unsigned)data->dataValuesSize); + + // Iterate over all values + for (UA_UInt32 i = 0; i < data->dataValuesSize; ++i) + { + printDataValue(&data->dataValues[i]); + } + + // We want more data! + return true; +} + + + +UA_Boolean readHist(UA_Client *client, const UA_NodeId *nodeId, + UA_Boolean moreDataAvailable, + const UA_ExtensionObject *data, void *unused) +{ + printf("\nRead historical callback:\n"); + printf("\tHas more data:\t%d\n\n", moreDataAvailable); + if (data->content.decoded.type == &UA_TYPES[UA_TYPES_HISTORYDATA]) + { + return readRaw((UA_HistoryData*)data->content.decoded.data); + } + + return true; +} + + +unsigned int UA_Client_writeValue(long client,char *NodeName,void *value,int type) { + UA_Client *c = (UA_Client*)client; + const UA_NodeId nodeId = UA_NODEID_STRING(1, NodeName); + UA_Variant newValue; + UA_Variant_init(&newValue); + UA_Variant_setScalar(&newValue,value,&UA_TYPES[type]); + UA_StatusCode retval; + retval = UA_Client_writeValueAttribute(c, nodeId, &newValue); + return retval; +} + +unsigned int +UA_Client_HistoryRead(long client, char *NodeName) { + UA_Client *c = (UA_Client*)client; + const UA_NodeId nodeId = UA_NODEID_STRING(1, NodeName); + return UA_Client_HistoryRead_raw(c,&nodeId,readHist, + UA_DateTime_fromUnixTime(0), UA_DateTime_now(), + UA_STRING_NULL, false, 10, + UA_TIMESTAMPSTORETURN_BOTH, NULL); +} + +const char * emptyStatusCodeName = ""; +const char * UA_StatusCodeName(UA_StatusCode code) { + return emptyStatusCodeName; +} + +void UA_Value_Clear(UA_Value *p) { + free(p); +} +void Browse(long client){ + UA_Client *c = (UA_Client*)client; + UA_NodeId parent = UA_NODEID_STRING(0, "A1"); + UA_Client_forEachChildNodeCall(c,parent,nodeIter, &parent); +} + +static UA_StatusCode +nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void *handle) { + if (isInverse) + return UA_STATUSCODE_GOOD; + UA_NodeId *parent = (UA_NodeId *)handle; + switch (childId.identifierType) + { + case UA_NODEIDTYPE_NUMERIC: + printf("%d, %d --- %d ---> NodeId %d, %d\n", + parent->namespaceIndex, parent->identifier.numeric, + referenceTypeId.identifier.numeric, childId.namespaceIndex, + childId.identifier.numeric); + break; + case UA_NODEIDTYPE_STRING: + printf("%d, %d --- %d ---> NodeId %d, %s\n", + parent->namespaceIndex, parent->identifier.numeric, + referenceTypeId.identifier.numeric, childId.namespaceIndex, + childId.identifier.string.data); + break; + case UA_NODEIDTYPE_GUID: + break; + case UA_NODEIDTYPE_BYTESTRING: + break; + default: + break; + } + + return UA_STATUSCODE_GOOD; +} + + + + + + +// unsigned int UA_SubscriptionCreate1(UA_Client *client,bool PublishingEnable,UA_Byte Priority) +// { +// /* Create a subscription */ +// UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default(); +// UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request, +// NULL, NULL, NULL); + +// UA_UInt32 subId = response.subscriptionId; +// if(response.responseHeader.serviceResult == UA_STATUSCODE_GOOD) +// { +// UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "Create subscription succeeded, id %u\n", subId); +// } +// unsigned int retval=response.responseHeader.serviceResult; +// return retval; + +// } + + + +void UA_readNodeList(u32 client){ + UA_Client *c = (UA_Client*)client; + UA_String *namespaceUri; + //UA_String_init(namespaceUri); + UA_UInt16 *namespaceIndex; + UA_Client_NamespaceGetIndex(c,namespaceUri,namespaceIndex); +} + +// unsigned int UA_MethodCall(long client){ + +// } + +// unsigned int UA_ReadList(bool Execute,long client,u16 NodeHdlCount,u32 *NodeHdls,UANodeAdditionalInfo *NodeAddInfos, +// TIME Timeout,UA_ReadListOutput *output,Variable_Identification *Variables){ +// UA_Client *c = (UA_Client*)client; +// int i; +// UA_Value value; +// UA_Value_init(&value); +// for(i=0;ibrowseName.name.data,ref->browseName.name.length); + BrowseResult[j].BrowseName.length=ref->browseName.name.length; + memcpy(BrowseResult[j].DisplayName.Locale,ref->displayName.locale.data,ref->displayName.locale.length); + memcpy(BrowseResult[j].DisplayName.Text.data,ref->displayName.text.data,ref->displayName.text.length); + BrowseResult[j].IsForward=ref->isForward; + BrowseResult[j].NodeClass=ref->nodeClass; + BrowseResult[j].NodeID.ID.NamespaceIndex=ref->nodeId.nodeId.namespaceIndex; + BrowseResult[j].NodeID.ID.IdentifierType=ref->nodeId.nodeId.identifierType; + BrowseResult[j].NodeID.ID.Identifier.length=ref->nodeId.nodeId.identifier.string.length; + BrowseResult[j].NodeID.ID.Identifier.data=ref->nodeId.nodeId.identifier.string.data; + BrowseResult[j].NodeID.NamespaceURI.length=ref->nodeId.namespaceUri.length; + memcpy(BrowseResult[j].NodeID.NamespaceURI.data,ref->nodeId.namespaceUri.data,ref->nodeId.namespaceUri.length); + BrowseResult[j].NodeID.ServerIndex=ref->nodeId.serverIndex; + BrowseResult[j].ReferenceTypeID.NamespaceIndex=ref->referenceTypeId.namespaceIndex; + BrowseResult[j].ReferenceTypeID.IdentifierType=ref->referenceTypeId.identifierType; + BrowseResult[j].ReferenceTypeID.Identifier.length=ref->referenceTypeId.identifier.string.length; + //memcpy(BrowseResult[j].ReferenceTypeID.Identifier.data,ref->referenceTypeId.identifier.string.data,ref->referenceTypeId.identifier.string.length); + BrowseResult[j].TypeDefinition.ID.NamespaceIndex=ref->typeDefinition.nodeId.namespaceIndex; + BrowseResult[j].TypeDefinition.ID.IdentifierType=ref->typeDefinition.nodeId.identifierType; + BrowseResult[j].TypeDefinition.ID.Identifier.length=ref->typeDefinition.nodeId.identifier.string.length; + memcpy(BrowseResult[j].TypeDefinition.ID.Identifier.data,ref->typeDefinition.nodeId.identifier.string.data,ref->typeDefinition.nodeId.identifier.string.length); + BrowseResult[j].TypeDefinition.NamespaceURI.length=ref->typeDefinition.namespaceUri.length; + memcpy(BrowseResult[j].TypeDefinition.NamespaceURI.data,ref->typeDefinition.namespaceUri.data,ref->typeDefinition.namespaceUri.length); + BrowseResult[j].TypeDefinition.ServerIndex=ref->typeDefinition.serverIndex; +}