UA ANSI C Server Professional  1.4.0.285
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
oversampling_provider_read.c
/******************************************************************************
**
** **************************** auto-generated ****************************
** This code was generated by a tool: UaModeler
** Runtime Version: 1.2.0, using ANSI C DemoProvider 1.4.0 template
**
** This is a template file that was generated for your convenience.
** This file will not be overwritten when generating code again.
** ADD YOUR IMPLEMTATION HERE!
** **************************** auto-generated ****************************
** Copyright (c) 2006-2014 Unified Automation GmbH All rights reserved.
** Web: http://www.unifiedautomation.com
**
** Software License Agreement ("SLA") Version 2.3
**
** 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.3, 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.
**
** Project: OPC Ansi C OverSamplingProvider for namespace http://www.unifiedautomation.com/OverSampling
**
** Description: OPC Unified Architecture Software Development Kit.
**
** The complete license agreement can be found here:
** http://unifiedautomation/License/SLA/2.3/
**
** Created: 04.02.2014
**
******************************************************************************/
#include <uaserver_config.h>
#include <pthread.h>
#include <errno.h>
#include <opcua_statuscodes.h>
#include <opcua_attributes.h>
#include <uaserver_basenode.h>
#include <uaserver_utilities.h>
#include <uaserver_p_atomic.h>
#include <uaserver_read.h>
#include "uaprovider_oversampling_helper.h"
#include "uaprovider_oversampling_identifiers_1.h"
OpcUa_List g_ReadJobs;
pthread_t g_ReadThread;
pthread_attr_t g_ReadAttr;
pthread_mutex_t g_ReadMutex;
pthread_cond_t g_ReadCondition;
OPCUA_BEGIN_EXTERN_C
void* UaProvider_OverSampling_ReadThread(void *arg)
{
OpcUa_ReferenceParameter(arg);
while (1)
{
OpcUa_ReadRequest *pReq;
OpcUa_ReadResponse *pRes;
int i;
OpcUa_BaseNode *pNode;
OpcUa_ReadValueId *pNodeToRead;
OpcUa_NodeId *pNodeId;
UaServer_AddressSpace *pAddressSpace = &(g_pOverSamplingProvider->AddressSpace);
UaServer_ProviderReadContext *pReadCtx = OpcUa_Null;
pthread_mutex_lock(&g_ReadMutex);
pReadCtx = (UaServer_ProviderReadContext*)OpcUa_List_RemoveFirstElement(&g_ReadJobs);
while (!pReadCtx && g_bShutdown == OpcUa_False)
{
pthread_cond_wait(&g_ReadCondition, &g_ReadMutex);
pReadCtx = (UaServer_ProviderReadContext*)OpcUa_List_RemoveFirstElement(&g_ReadJobs);
}
pthread_mutex_unlock(&g_ReadMutex);
if (g_bShutdown)
{
while (pReadCtx)
{
pReadCtx = (UaServer_ProviderReadContext*)OpcUa_List_RemoveFirstElement(&g_ReadJobs);
}
break;
}
pReq = pReadCtx->pRequest;
pRes = pReadCtx->pResponse;
for (i = 0; i < pReq->NoOfNodesToRead; i++)
{
pNodeToRead = &pReq->NodesToRead[i];
pNodeId = &pNodeToRead->NodeId;
if (pNodeId->NamespaceIndex != g_UaProviderOverSampling_uNamespaceIndex1) continue;
UaServer_GetNode(pAddressSpace, pNodeId, &pNode);
if (pNode)
{
/* check if value is readable */
if (pNodeToRead->AttributeId == OpcUa_Attributes_Value
&& OpcUa_BaseNode_GetType(pNode) == eVariable
&& (OpcUa_Variable_GetAccessLevel(pNode) & OpcUa_AccessLevels_CurrentRead) == 0)
{
pRes->Results[i].StatusCode = OpcUa_BadNotReadable;
continue;
}
#if UASERVER_SUPPORT_AUTHORIZATION
/* check if current user is allowed to read */
if ((pNodeToRead->AttributeId == OpcUa_Attributes_Value
|| (pNodeToRead->AttributeId != OpcUa_Attributes_Value
{
pRes->Results[i].StatusCode = OpcUa_BadNotReadable;
continue;
}
#endif
if (pNodeToRead->AttributeId == OpcUa_Attributes_Value)
{
switch (pNodeToRead->NodeId.Identifier.Numeric)
{
case OverSampling_Objects_S1KHz_Voltage:
case OverSampling_Objects_S1KHz_Current:
if (OpcUa_String_IsNull(&pNodeToRead->DataEncoding.Name))
{
if (OpcUa_String_IsNull(&pNodeToRead->IndexRange))
{
switch (pNodeToRead->NodeId.Identifier.Numeric)
{
case OverSampling_Objects_S1KHz_Voltage:
pRes->Results[i].StatusCode = OpcUa_Good;
if (pReq->TimestampsToReturn == OpcUa_TimestampsToReturn_Both || pReq->TimestampsToReturn == OpcUa_TimestampsToReturn_Server)
{
pRes->Results[i].ServerTimestamp = OpcUa_DateTime_UtcNow();
}
if (pReq->TimestampsToReturn == OpcUa_TimestampsToReturn_Both || pReq->TimestampsToReturn == OpcUa_TimestampsToReturn_Source)
{
pRes->Results[i].SourceTimestamp = OpcUa_DateTime_UtcNow();
}
pRes->Results[i].Value.Datatype = OpcUaType_Double;
pRes->Results[i].Value.ArrayType = OpcUa_VariantArrayType_Scalar;
pRes->Results[i].Value.Value.Double = g_Voltage;
break;
case OverSampling_Objects_S1KHz_Current:
pRes->Results[i].StatusCode = OpcUa_Good;
if (pReq->TimestampsToReturn == OpcUa_TimestampsToReturn_Both || pReq->TimestampsToReturn == OpcUa_TimestampsToReturn_Server)
{
pRes->Results[i].ServerTimestamp = OpcUa_DateTime_UtcNow();
}
if (pReq->TimestampsToReturn == OpcUa_TimestampsToReturn_Both || pReq->TimestampsToReturn == OpcUa_TimestampsToReturn_Source)
{
pRes->Results[i].SourceTimestamp = OpcUa_DateTime_UtcNow();
}
pRes->Results[i].Value.Datatype = OpcUaType_Double;
pRes->Results[i].Value.ArrayType = OpcUa_VariantArrayType_Scalar;
pRes->Results[i].Value.Value.Double = g_Current;
break;
default:
break;
}
}
else
{
pRes->Results[i].StatusCode = OpcUa_BadIndexRangeInvalid;
}
}
else
{
pRes->Results[i].StatusCode = OpcUa_BadDataEncodingUnsupported;
}
break;
default:
UaServer_ReadInternal(pNode, pReadCtx, i);
break;
}
}
else
{
UaServer_ReadInternal(pNode, pReadCtx, i);
}
}
else
{
pRes->Results[i].StatusCode = OpcUa_BadNodeIdUnknown;
}
}
/* send callback */
}
return 0;
}
IFMETHODIMP(UaProvider_OverSampling_ReadAsync)(UaServer_ProviderReadContext* a_pReadCtx)
{
/* we will send exactly one callback */
UaServer_Atomic_Increment(&a_pReadCtx->nOutstandingCbs);
pthread_mutex_lock(&g_ReadMutex);
OpcUa_List_AddElementToEnd(&g_ReadJobs, a_pReadCtx);
pthread_cond_signal(&g_ReadCondition);
pthread_mutex_unlock(&g_ReadMutex);
return OpcUa_Good;
}
OPCUA_END_EXTERN_C