ANSI C Based OPC UA Client/Server SDK  1.8.3.398
samplesubscription.c
/*****************************************************************************
* *
* Copyright (c) 2006-2018 Unified Automation GmbH. All rights reserved. *
* *
* Software License Agreement ("SLA") Version 2.7 *
* *
* 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.7, 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.7/ *
* *
* Project: Unified Automation ANSI C based OPC UA Server SDK *
* *
*****************************************************************************/
#include "samplesubscription.h"
#include <stdlib.h>
#include <opcua_datetime.h>
#include <opcua_memory.h>
#include <opcua_trace.h>
static OpcUa_Void SampleSubscription_Created_CB(UaClient_Subscription *a_pUaSubscription,
OpcUa_StatusCode a_status,
OpcUa_ResponseHeader *a_pResponseHeader,
OpcUa_Void *a_pUserData)
{
SampleSubscription *pSampleSubscription = a_pUaSubscription->pUserData;
OpcUa_ReferenceParameter(a_pResponseHeader);
OpcUa_ReferenceParameter(a_pUserData);
if (OpcUa_IsGood(a_status))
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_Created_CB succeeded (0x%08x)\n", a_status);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " Revised PublishingInterval: %f\n", a_pUaSubscription->RevisedPublishingInterval);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " Revised LifetimeCount: %u\n", a_pUaSubscription->RevisedLifetimeCount);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " Revised MaxKeepAliveCount: %u\n", a_pUaSubscription->RevisedMaxKeepAliveCount);
if (pSampleSubscription->State == State_SampleSubscription_SubscriptionCreate)
pSampleSubscription->State = State_SampleSubscription_SubscriptionCreateDone;
else
pSampleSubscription->State = State_SampleSubscription_Error;
}
else
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_Created_CB failed (0x%08x)\n", a_status);
pSampleSubscription->State = State_SampleSubscription_Error;
}
}
static OpcUa_Void SampleSubscription_Deleted_CB(UaClient_Subscription *a_pUaSubscription,
OpcUa_StatusCode a_status,
OpcUa_ResponseHeader *a_pResponseHeader,
OpcUa_Void *a_pUserData)
{
SampleSubscription *pSampleSubscription = a_pUaSubscription->pUserData;
OpcUa_ReferenceParameter(a_pResponseHeader);
OpcUa_ReferenceParameter(a_pUserData);
if (OpcUa_IsGood(a_status))
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_Deleted_CB succeeded (0x%08x)\n", a_status);
if (pSampleSubscription->State == State_SampleSubscription_SubscriptionDelete)
pSampleSubscription->State = State_SampleSubscription_SubscriptionDeleteDone;
else
pSampleSubscription->State = State_SampleSubscription_Error;
}
else
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_Deleted_CB failed (0x%08x)\n", a_status);
pSampleSubscription->State = State_SampleSubscription_Error;
}
}
static OpcUa_Void SampleSubscription_StatusChanged_CB(UaClient_Subscription *a_pSubscription,
OpcUa_StatusCode a_status)
{
OpcUa_ReferenceParameter(a_pSubscription);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_StatusChanged_CB (0x%08x)\n", a_status);
}
static OpcUa_Void SampleSubscription_DataChange_CB(UaClient_Subscription *a_pSubscription,
OpcUa_Int32 a_noOfMonitoredItems,
OpcUa_MonitoredItemNotification *a_pMonitoredItems,
OpcUa_Int32 a_noOfDiagnosticInfos,
OpcUa_DiagnosticInfo *a_pDiagnosticInfos)
{
SampleSubscription *pSampleSubscription = a_pSubscription->pUserData;
OpcUa_Int32 i;
OpcUa_ReferenceParameter(a_noOfDiagnosticInfos);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_DataChange_CB\n");
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " noOfMonitoredItems: %i\n", a_noOfMonitoredItems);
for (i = 0; i < a_noOfMonitoredItems; i++)
{
OpcUa_CharA szDateTime[64] = {0};
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " [%i]:\n", i);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " StatusCode: 0x%08x\n", a_pMonitoredItems[i].Value.StatusCode);
if (OpcUa_IsGood(a_pMonitoredItems[i].Value.StatusCode))
{
OpcUa_DateTime_GetStringFromDateTime(a_pMonitoredItems[i].Value.SourceTimestamp, szDateTime, sizeof(szDateTime));
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " SourceTimestamp: %s\n", szDateTime);
OpcUa_DateTime_GetStringFromDateTime(a_pMonitoredItems[i].Value.ServerTimestamp, szDateTime, sizeof(szDateTime));
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " ServerTimestamp: %s\n", szDateTime);
OpcUa_DateTime_GetStringFromDateTime(a_pMonitoredItems[i].Value.Value.Value.DateTime, szDateTime, sizeof(szDateTime));
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " Value: %s\n", szDateTime);
pSampleSubscription->uDataCount++;
}
}
}
static OpcUa_Void SampleSubscription_MonitoredItems_Created_CB(const UaClient_Subscription *a_pSubscription,
OpcUa_ResponseHeader *a_pResponseHeader,
OpcUa_Int32 a_NoOfResults,
OpcUa_Int32 a_NoOfDiagnosticInfos,
OpcUa_DiagnosticInfo *a_pDiagnosticInfos,
OpcUa_Void *a_pUserData)
{
SampleSubscription *pSampleSubscription = a_pSubscription->pUserData;
OpcUa_ReferenceParameter(a_pUserData);
OpcUa_ReferenceParameter(a_NoOfDiagnosticInfos);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
if (a_NoOfResults == 1 && OpcUa_IsGood(a_pResponseHeader->ServiceResult) && OpcUa_IsGood(a_pResults[0].StatusCode))
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_MonitoredItems_Created_CB succeeded (0x%08x)\n", a_pResults[0].StatusCode);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " MonitoredItemId: %u\n", a_pResults[0].MonitoredItemId);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " RevisedSamplingInterval: %f\n", a_pResults[0].RevisedSamplingInterval);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " RevisedQueueSize: %u\n", a_pResults[0].RevisedQueueSize);
pSampleSubscription->uMonitoredItemId = a_pResults[0].MonitoredItemId;
if (pSampleSubscription->State == State_SampleSubscription_MonitoredItemCreate)
pSampleSubscription->State = State_SampleSubscription_MonitoredItemCreateDone;
else
pSampleSubscription->State = State_SampleSubscription_Error;
}
else
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_MonitoredItems_Created_CB failed (0x%08x)\n", a_pResponseHeader->ServiceResult);
pSampleSubscription->State = State_SampleSubscription_Error;
}
}
static OpcUa_Void SampleSubscription_MonitoredItems_Deleted_CB(const UaClient_Subscription *a_pSubscription,
OpcUa_ResponseHeader *a_pResponseHeader,
OpcUa_Int32 a_NoOfResults,
OpcUa_StatusCode *a_pResults,
OpcUa_Int32 a_NoOfDiagnosticInfos,
OpcUa_DiagnosticInfo *a_pDiagnosticInfos,
OpcUa_Void *a_pUserData)
{
SampleSubscription *pSampleSubscription = a_pSubscription->pUserData;
OpcUa_ReferenceParameter(a_pUserData);
OpcUa_ReferenceParameter(a_NoOfDiagnosticInfos);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
if (a_NoOfResults == 1 && OpcUa_IsGood(a_pResponseHeader->ServiceResult) && OpcUa_IsGood(a_pResults[0]))
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_MonitoredItems_Deleted_CB succeeded (0x%08x)\n", a_pResults[0]);
if (pSampleSubscription->State == State_SampleSubscription_MonitoredItemDelete)
pSampleSubscription->State = State_SampleSubscription_MonitoredItemDeleteDone;
else
pSampleSubscription->State = State_SampleSubscription_Error;
}
else
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SampleSubscription_MonitoredItems_Deleted_CB failed (0x%08x)\n", a_pResponseHeader->ServiceResult);
pSampleSubscription->State = State_SampleSubscription_Error;
}
}
SampleSubscription *SampleSubscription_Create(UaClient_Session *pSession)
{
SampleSubscription *pSampleSubscription = OpcUa_Null;
UaClient_Subscription_Callback subscriptionCallback;
UaClient_Subscription *pSubscription = OpcUa_Null;
/* Allocate memory for the SampleSubscription */
pSampleSubscription = OpcUa_Alloc(sizeof(*pSampleSubscription));
if (pSampleSubscription == OpcUa_Null)
{
return OpcUa_Null;
}
/* Set callbacks */
OpcUa_MemSet(&subscriptionCallback, 0, sizeof(subscriptionCallback));
subscriptionCallback.pfStatusChanged_CB = SampleSubscription_StatusChanged_CB;
subscriptionCallback.pfDataChange_CB = SampleSubscription_DataChange_CB;
/* Create the underlying UaClient_Subscription */
uStatus = UaClient_Subscription_Create(pSession, &subscriptionCallback, &pSubscription);
if (OpcUa_IsBad(uStatus))
{
OpcUa_Free(pSampleSubscription);
return OpcUa_Null;
}
/* Initialize the SampleSubscription structure */
pSampleSubscription->pSubscription = pSubscription;
pSampleSubscription->uDataCount = 0;
pSampleSubscription->uMonitoredItemId = 0;
pSampleSubscription->State = State_SampleSubscription_Idle;
/* Set the most important Subscription properties */
pSubscription->pUserData = pSampleSubscription;
pSubscription->PublishingInterval = 1000.0;
return pSampleSubscription;
}
OpcUa_Void SampleSubscription_Delete(SampleSubscription **ppSampleSubscription)
{
SampleSubscription *pSampleSubscription = *ppSampleSubscription;
if (pSampleSubscription == OpcUa_Null)
return;
UaClient_Subscription_Delete(&pSampleSubscription->pSubscription);
OpcUa_Free(pSampleSubscription);
*ppSampleSubscription = OpcUa_Null;
}
OpcUa_StatusCode SampleSubscription_CreateSubscription(SampleSubscription *pSampleSubscription)
{
pSampleSubscription->State = State_SampleSubscription_SubscriptionCreate;
return UaClient_Subscription_BeginCreateSubscription(pSampleSubscription->pSubscription,
OpcUa_Null,
SampleSubscription_Created_CB,
OpcUa_Null);
}
OpcUa_StatusCode SampleSubscription_DeleteSubscription(SampleSubscription *pSampleSubscription)
{
pSampleSubscription->State = State_SampleSubscription_SubscriptionDelete;
return UaClient_Subscription_BeginDeleteSubscription(pSampleSubscription->pSubscription,
OpcUa_Null,
SampleSubscription_Deleted_CB,
OpcUa_Null);
}
OpcUa_StatusCode SampleSubscription_CreateMonitoredItem(SampleSubscription *pSampleSubscription)
{
OpcUa_Int32 i;
OpcUa_Int32 numItemsToCreate = 1;
pSampleSubscription->State = State_SampleSubscription_MonitoredItemCreate;
for (i = 0; i < numItemsToCreate; i++)
{
OpcUa_MonitoredItemCreateRequest_Initialize(&createRequest[i]);
createRequest[i].ItemToMonitor.AttributeId = OpcUa_Attributes_Value;
createRequest[i].RequestedParameters.SamplingInterval = 1000.0;
createRequest[i].RequestedParameters.QueueSize = 1;
createRequest[i].RequestedParameters.DiscardOldest = OpcUa_True;
}
createRequest[0].ItemToMonitor.NodeId.Identifier.Numeric = OpcUaId_Server_ServerStatus_CurrentTime;
return UaClient_Subscription_BeginCreateMonitoredItems(pSampleSubscription->pSubscription,
OpcUa_Null,
numItemsToCreate,
createRequest,
SampleSubscription_MonitoredItems_Created_CB,
OpcUa_Null);
}
OpcUa_StatusCode SampleSubscription_DeleteMonitoredItem(SampleSubscription *pSampleSubscription)
{
OpcUa_Int32 numItemsToDelete = 1;
OpcUa_UInt32 MonitoredItemIds[1];
pSampleSubscription->State = State_SampleSubscription_MonitoredItemDelete;
MonitoredItemIds[0] = pSampleSubscription->uMonitoredItemId;
return UaClient_Subscription_BeginDeleteMonitoredItems(pSampleSubscription->pSubscription,
OpcUa_Null,
numItemsToDelete,
MonitoredItemIds,
SampleSubscription_MonitoredItems_Deleted_CB,
OpcUa_Null);
}