This lesson describes how to use Write Service.
Files used in this lesson:
Step 1: Write Service Call
To call Write Service, the parameters for the Write Service as defined in the OPC UA Specification are passed to UaClient_Session_BeginWrite. The Request Header is omitted because it is handled by the SDK. To influence its values, the UaClient_ServiceSettings can be given as an argument. Additional arguments are the session, the callback function to call upon completion, and user data. The user data is passed only to the callback of this particular service invocation, allowing to distinguish multiple concurrent calls to the same service using the same callback function. This Sample Client does not need to pass user data this way, as it only requires the user data attached to the session available in the callback.
{
OpcUa_Int32 numNodesToWrite = 1;
OpcUa_InitializeStatus(OpcUa_Module_Client, "Sample_Write");
OpcUa_WriteValue_Initialize(&nodesToWrite[0]);
OpcUa_String_StrnCpy(&nodesToWrite[0].NodeId.Identifier.String, OpcUa_String_FromCString("Demo.Static.Scalar.Int32"), OPCUA_STRING_LENDONTCARE);
OpcUa_Null,
numNodesToWrite,
nodesToWrite,
Sample_Write_CB,
OpcUa_Null);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_WriteValue_Clear(&nodesToWrite[0]);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_WriteValue_Clear(&nodesToWrite[0]);
OpcUa_FinishErrorHandling;
}
Step 2: Write Service Callback
Sample_Write_CB implements the callback for the Write service and gets called with the results of the service call.
OpcUa_Int32 a_NoOfResults,
OpcUa_Int32 a_NoOfDiagnosticInfos,
OpcUa_Void *a_pUserData)
{
SampleClientContext *pClientContext = a_pSession->
pUserData;
OpcUa_ReferenceParameter(a_NoOfDiagnosticInfos);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
OpcUa_ReferenceParameter(a_pUserData);
{
OpcUa_Int32 i;
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Sample_Write_CB:\n");
for (i = 0; i < a_NoOfResults; i++)
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " [%i]:\n", i);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " Status: 0x%08x\n", a_pResults[i]);
}
if (pClientContext->State == State_Write)
pClientContext->State = State_WriteDone;
else
pClientContext->State = State_Error;
}
else
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING,
"Sample_Write_CB failed (0x%08x)\n", a_pResponseHeader->
ServiceResult);
pClientContext->State = State_Error;
}
}
Step 3: Integration in Main loop
{
switch (clientContext.State)
{
case State_Idle:
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "UA Client: Connecting to %s ...\n", SERVER_ENDPOINT_URL);
OpcUa_GotoErrorIfBad(uStatus);
clientContext.State = State_Connect;
break;
case State_Connected:
uStatus = Sample_Browse(pSession, OpcUa_Null);
OpcUa_GotoErrorIfBad(uStatus);
clientContext.State = State_Browse;
break;
case State_BrowseDone:
uStatus = Sample_Write(pSession);
OpcUa_GotoErrorIfBad(uStatus);
clientContext.State = State_Write;
break;
case State_WriteDone:
OpcUa_GotoErrorIfBad(uStatus);
clientContext.State = State_Disconnect;
break;
case State_Disconnected:
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Sample successfully completed. Terminating now.\n");
bComplete = OpcUa_True;
break;
case State_Error:
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "An error occured. Terminating now.\n");
bComplete = OpcUa_True;
break;
default:
break;
}
if (OpcUa_IsBad(uStatus))
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "UaBase_DoCom failed (0x%08x)\n", uStatus);
bComplete = OpcUa_True;
}
}