UA ANSI C Server Professional  1.4.2.297
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Modules Pages
custom_provider_call.c
/******************************************************************************
**
** Copyright (C) 2011-2014 Unified Automation GmbH. All Rights Reserved.
** Web: http://www.unifiedautomation.com
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** Project: OPC Ansi C OPC Server Examples
**
******************************************************************************/
#include <uaserver_config.h>
#include <opcua_statuscodes.h>
#include <uaserver_call.h>
#include <uaserver_basenode.h>
#include <uaserver_utilities.h>
#include <uaserver_p_atomic.h>
#include "custom_provider_helper.h"
OPCUA_BEGIN_EXTERN_C
IFMETHODIMP(CustomProvider_CallAsync)(UaServer_ProviderCallContext *a_pCallContext)
{
OpcUa_CallRequest *pRequest;
OpcUa_CallResponse *pResponse;
OpcUa_Int32 i;
OpcUa_BaseNode *pNode;
UaServer_AddressSpace *pAddressSpace = &(g_pCustomProvider->AddressSpace);
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CallAsync");
OpcUa_ReturnErrorIfArgumentNull(a_pCallContext);
pRequest = a_pCallContext->pRequest;
pResponse = a_pCallContext->pResponse;
/* We will send exactly one callback */
/* Iterate over methods and check if the provider is responsible for processing them */
for (i = 0; i < pRequest->NoOfMethodsToCall; i++)
{
if (pRequest->MethodsToCall[i].MethodId.NamespaceIndex == g_uCustomProvider_NamespaceIndex &&
pRequest->MethodsToCall[i].ObjectId.NamespaceIndex == g_uCustomProvider_NamespaceIndex)
{
UaServer_GetNode(pAddressSpace, &pRequest->MethodsToCall[i].MethodId, &pNode);
if (pNode != OpcUa_Null)
{
UserDataCommon *pUserData = (UserDataCommon*)OpcUa_BaseNode_GetUserData(pNode);
if (pUserData != OpcUa_Null)
{
switch (pUserData->Type)
{
case UserDataMachine:
{
Machine *pMachine = (Machine*)pUserData;
/* Check if the method was called on the appropriate Machine */
if (OpcUa_NodeId_Compare(&pRequest->MethodsToCall[i].ObjectId, &pMachine->nodeId) != 0)
{
pResponse->Results[i].StatusCode = OpcUa_BadNotFound;
break;
}
/* Check input arguments */
if (pRequest->MethodsToCall[i].NoOfInputArguments == 1)
{
OpcUa_Variant *pInArg = &pRequest->MethodsToCall[i].InputArguments[0];
OpcUa_CallMethodResult *pResult = &pResponse->Results[i];
pResult->NoOfInputArgumentResults = 1;
pResult->InputArgumentResults = (OpcUa_StatusCode*)OpcUa_Alloc(sizeof(OpcUa_StatusCode));
if (pInArg->ArrayType == OpcUa_VariantArrayType_Scalar &&
pInArg->Datatype == OpcUaType_Boolean)
{
/* Set switch state */
*pMachine->pHeaterSwitch->pValue = pInArg->Value.Boolean;
pResult->InputArgumentResults[0] = OpcUa_Good;
}
else
{
pResult->InputArgumentResults[0] = OpcUa_BadTypeMismatch;
}
/* Fill output arguments */
pResult->NoOfOutputArguments = 1;
pResult->OutputArguments = (OpcUa_Variant*)OpcUa_Alloc(sizeof(OpcUa_Variant));
OpcUa_Variant_Initialize(&pResult->OutputArguments[0]);
pResult->OutputArguments[0].Datatype = OpcUaType_Double;
pResult->OutputArguments[0].Value.Double = *pMachine->pTemperatureSensor->pValue;
pResult->StatusCode = OpcUa_Good;
}
else
{
pResponse->Results[i].StatusCode = OpcUa_BadArgumentsMissing;
}
break;
}
default:
{
pResponse->Results[i].StatusCode = OpcUa_BadNotFound;
break;
}
}
}
}
}
}
/* Send callback */
UaServer_CallComplete(a_pCallContext);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OPCUA_END_EXTERN_C