ANSI C UA Server SDK  1.6.0.341
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Modules Pages
custom_provider_write.c
/*****************************************************************************
* *
* Copyright (c) 2006-2016 Unified Automation GmbH. All rights reserved. *
* *
* Software License Agreement ("SLA") Version 2.5 *
* *
* Unless explicitly acquired and licensed from Licensor under another *
* license, the contents of this file are subject to the Software License *
* Agreement ("SLA") Version 2.5, or subsequent versions as allowed by the *
* SLA, and You may not copy or use this file in either source code or *
* executable form, except in compliance with the terms and conditions of *
* the SLA. *
* *
* All software distributed under the SLA is provided strictly on an "AS *
* IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, *
* AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT *
* LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
* PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the SLA for specific *
* language governing rights and limitations under the SLA. *
* *
* The complete license agreement can be found here: *
* http://unifiedautomation.com/License/SLA/2.5/ *
* *
* Project: Unified Automation ANSI C based OPC UA Server SDK *
* *
*****************************************************************************/
#include <uaserver_config.h>
#include <opcua_statuscodes.h>
#include <uabase_p_atomic.h>
#include <uaserver_write.h>
#include <uaserver_basenode.h>
#include <uaserver_utilities.h>
#include "custom_provider_helper.h"
OPCUA_BEGIN_EXTERN_C
IFMETHODIMP(CustomProvider_WriteAsync)(UaServer_ProviderWriteContext* a_pWriteCtx)
{
OpcUa_Int32 i;
OpcUa_BaseNode *pNode;
UaServer_AddressSpace *pAddressSpace = &(g_pCustomProvider->AddressSpace);
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_WriteAsync");
OpcUa_ReturnErrorIfArgumentNull(a_pWriteCtx);
pReq = a_pWriteCtx->pRequest;
pRes = a_pWriteCtx->pResponse;
/* We will send exactly one callback */
UaBase_Atomic_Increment(&a_pWriteCtx->nOutstandingCbs);
/* Iterate over nodes and check if the provider is responsible for processing them */
for (i = 0; i < pReq->NoOfNodesToWrite; i++)
{
if (pReq->NodesToWrite[i].NodeId.NamespaceIndex == g_uCustomProvider_NamespaceIndex)
{
UaServer_GetNode(pAddressSpace, &pReq->NodesToWrite[i].NodeId, &pNode);
if (pNode)
{
UserDataCommon *pUserData = OpcUa_Null;
if ( (a_pWriteCtx->pRequest->NodesToWrite[i].AttributeId == OpcUa_Attributes_Value &&
OpcUa_BaseNode_GetType(pNode) == eVariable &&
(OpcUa_Variable_GetAccessLevel(pNode) & OpcUa_AccessLevels_CurrentWrite) == 0) )
{
pRes->Results[i] = OpcUa_BadNotWritable;
continue;
}
pUserData = (UserDataCommon*)OpcUa_BaseNode_GetUserData(pNode);
if (pUserData != OpcUa_Null &&
a_pWriteCtx->pRequest->NodesToWrite[i].AttributeId == OpcUa_Attributes_Value)
{
OpcUa_Variant *pValue = &a_pWriteCtx->pRequest->NodesToWrite[i].Value.Value;
switch (pUserData->Type)
{
case UserDataTemperature:
{
if (pValue->ArrayType == OpcUa_VariantArrayType_Scalar &&
pValue->Datatype == OpcUaType_Double)
{
TemperatureSensor *pSensor = (TemperatureSensor*)pUserData;
*pSensor->pValue = pValue->Value.Double;
pRes->Results[i] = OpcUa_Good;
}
else
{
pRes->Results[i] = OpcUa_BadTypeMismatch;
}
break;
}
case UserDataMachineSwitch:
{
if (pValue->ArrayType == OpcUa_VariantArrayType_Scalar &&
pValue->Datatype == OpcUaType_Boolean)
{
MachineSwitch *pSwitch = (MachineSwitch*)pUserData;
*pSwitch->pValue = pValue->Value.Boolean;
pRes->Results[i] = OpcUa_Good;
}
else
{
pRes->Results[i] = OpcUa_BadTypeMismatch;
}
break;
}
default:
{
pRes->Results[i] = OpcUa_BadNotWritable;
break;
}
}
}
else
{
/* Use the SDK's helper function to process the request */
UaServer_WriteInternal(pNode, a_pWriteCtx, i);
}
}
else
{
pRes->Results[i] = OpcUa_BadNodeIdUnknown;
}
}
}
/* Send callback */
UaServer_WriteComplete(a_pWriteCtx);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
OPCUA_END_EXTERN_C