ANSI C Based OPC UA Client/Server/PubSub SDK  1.9.1.442
samplesubscription.c
/*****************************************************************************
* *
* Copyright (c) 2006-2019 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>
#include <opcua_errorhandling.h>
#include <opcua_string.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_NewEvent_CB(UaClient_Subscription *a_pSubscription,
OpcUa_Int32 a_noOfEvents,
OpcUa_EventFieldList *a_pEvents)
{
SampleSubscription *pSampleSubscription = a_pSubscription->pUserData;
OpcUa_Variant message = a_pEvents->EventFields[0];
OpcUa_Variant sourceName = a_pEvents->EventFields[1];
OpcUa_Variant severity = a_pEvents->EventFields[2];
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "\n--> SampleSubscription_NewEvent_CB\n\n");
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " noOfEvents: %i\n", a_noOfEvents);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Message = %s\n", OpcUa_String_GetRawString(&message.Value.LocalizedText->Text));
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "SourceName = %s\n", OpcUa_String_GetRawString(&sourceName.Value.String));
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Severity = %u\n", severity.Value.UInt16);
if (pSampleSubscription->State == State_SampleSubscription_WaitForNewEvent)
pSampleSubscription->State = State_SampleSubscription_NewEventReceived;
else
pSampleSubscription->State = State_SampleSubscription_Error;
}
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 *a_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;
subscriptionCallback.pfNewEvents_CB = SampleSubscription_NewEvent_CB;
/* Create the underlying UaClient_Subscription */
uStatus = UaClient_Subscription_Create(a_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 **a_ppSampleSubscription)
{
SampleSubscription *pSampleSubscription = *a_ppSampleSubscription;
if (pSampleSubscription == OpcUa_Null)
return;
UaClient_Subscription_Delete(&pSampleSubscription->pSubscription);
OpcUa_Free(pSampleSubscription);
*a_ppSampleSubscription = OpcUa_Null;
}
OpcUa_StatusCode SampleSubscription_CreateSubscription(SampleSubscription *a_pSampleSubscription)
{
a_pSampleSubscription->State = State_SampleSubscription_SubscriptionCreate;
return UaClient_Subscription_BeginCreateSubscription(a_pSampleSubscription->pSubscription,
OpcUa_Null,
SampleSubscription_Created_CB,
OpcUa_Null);
}
OpcUa_StatusCode SampleSubscription_DeleteSubscription(SampleSubscription *a_pSampleSubscription)
{
a_pSampleSubscription->State = State_SampleSubscription_SubscriptionDelete;
return UaClient_Subscription_BeginDeleteSubscription(a_pSampleSubscription->pSubscription,
OpcUa_Null,
SampleSubscription_Deleted_CB,
OpcUa_Null);
}
OpcUa_StatusCode SampleSubscription_CreateMonitoredItem(SampleSubscription *a_pSampleSubscription)
{
OpcUa_Int32 i;
OpcUa_Int32 numItemsToCreate = 1;
OpcUa_EventFilter *pEventFilter = OpcUa_Null;
OpcUa_LiteralOperand *pRawOperand = OpcUa_Null;
OpcUa_Int32 noOfSelectClauses = 3;
OpcUa_InitializeStatus(OpcUa_Module_Client, "SampleSubscription_CreateMonitoredItem");
a_pSampleSubscription->State = State_SampleSubscription_MonitoredItemCreate;
/* Fill in details of event monitored item */
OpcUa_MonitoredItemCreateRequest_Initialize(&itemsToCreate);
itemsToCreate.ItemToMonitor.AttributeId = OpcUa_Attributes_EventNotifier;
itemsToCreate.RequestedParameters.QueueSize = 0;
itemsToCreate.RequestedParameters.DiscardOldest = OpcUa_True;
itemsToCreate.ItemToMonitor.NodeId.Identifier.Numeric = OpcUaId_Server;
/* Set the Event Filter */
uStatus = OpcUa_EncodeableObject_CreateExtension(&OpcUa_EventFilter_EncodeableType,
&itemsToCreate.RequestedParameters.Filter,
(OpcUa_Void**)&pEventFilter);
OpcUa_GotoErrorIfBad(uStatus);
/* Fill in the eventfields to send with each event */
pEventFilter->NoOfSelectClauses = noOfSelectClauses;
pEventFilter->SelectClauses = (OpcUa_SimpleAttributeOperand*)OpcUa_Alloc(noOfSelectClauses * sizeof(OpcUa_SimpleAttributeOperand));
OpcUa_GotoErrorIfAllocFailed(pEventFilter->SelectClauses);
for (i = 0; i < noOfSelectClauses; i++)
{
OpcUa_SimpleAttributeOperand_Initialize(&pEventFilter->SelectClauses[i]);
}
pEventFilter->SelectClauses[0].NoOfBrowsePath = 1;
pEventFilter->SelectClauses[0].BrowsePath = (OpcUa_QualifiedName*)OpcUa_Alloc(sizeof(OpcUa_QualifiedName));
OpcUa_GotoErrorIfAllocFailed(pEventFilter->SelectClauses[0].BrowsePath);
OpcUa_QualifiedName_Initialize(pEventFilter->SelectClauses[0].BrowsePath);
uStatus = OpcUa_String_AttachCopy(&(pEventFilter->SelectClauses[0].BrowsePath->Name), "Message");
OpcUa_GotoErrorIfBad(uStatus);
pEventFilter->SelectClauses[0].BrowsePath->NamespaceIndex = 0;
pEventFilter->SelectClauses[0].AttributeId = OpcUa_Attributes_Value;
pEventFilter->SelectClauses[0].TypeDefinitionId.Identifier.Numeric = OpcUaId_BaseEventType;
pEventFilter->SelectClauses[1].NoOfBrowsePath = 1;
pEventFilter->SelectClauses[1].BrowsePath = (OpcUa_QualifiedName*)OpcUa_Alloc(sizeof(OpcUa_QualifiedName));
OpcUa_GotoErrorIfAllocFailed(pEventFilter->SelectClauses[1].BrowsePath);
OpcUa_QualifiedName_Initialize(pEventFilter->SelectClauses[1].BrowsePath);
uStatus = OpcUa_String_AttachCopy(&(pEventFilter->SelectClauses[1].BrowsePath->Name), "SourceName");
OpcUa_GotoErrorIfBad(uStatus);
pEventFilter->SelectClauses[1].BrowsePath->NamespaceIndex = 0;
pEventFilter->SelectClauses[1].AttributeId = OpcUa_Attributes_Value;
pEventFilter->SelectClauses[1].TypeDefinitionId.Identifier.Numeric = OpcUaId_BaseEventType;
pEventFilter->SelectClauses[2].NoOfBrowsePath = 1;
pEventFilter->SelectClauses[2].BrowsePath = (OpcUa_QualifiedName*)OpcUa_Alloc(sizeof(OpcUa_QualifiedName));
OpcUa_GotoErrorIfAllocFailed(pEventFilter->SelectClauses[2].BrowsePath);
OpcUa_QualifiedName_Initialize(pEventFilter->SelectClauses[2].BrowsePath);
uStatus = OpcUa_String_AttachCopy(&(pEventFilter->SelectClauses[2].BrowsePath->Name), "Severity");
OpcUa_GotoErrorIfBad(uStatus);
pEventFilter->SelectClauses[2].BrowsePath->NamespaceIndex = 0;
pEventFilter->SelectClauses[2].AttributeId = OpcUa_Attributes_Value;
pEventFilter->SelectClauses[2].TypeDefinitionId.Identifier.Numeric = OpcUaId_BaseEventType;
/* Fill in the Filter Operator and Filter Operand */
pEventFilter->WhereClause.NoOfElements = 1;
OpcUa_GotoErrorIfAllocFailed(pEventFilter->WhereClause.Elements);
pEventFilter->WhereClause.Elements->NoOfFilterOperands = 1;
OpcUa_GotoErrorIfAllocFailed(pEventFilter->WhereClause.Elements->FilterOperands);
uStatus = OpcUa_EncodeableObject_CreateExtension(&OpcUa_LiteralOperand_EncodeableType,
(OpcUa_Void**)&pRawOperand);
OpcUa_GotoErrorIfBad(uStatus);
/* Fill in details of "HeaterSwitchedEventType" included in lesson05 server */
pRawOperand->Value.Datatype = OpcUaType_NodeId;
pRawOperand->Value.Value.NodeId = (OpcUa_NodeId*)OpcUa_Alloc(sizeof(OpcUa_NodeId));
OpcUa_GotoErrorIfAllocFailed(pRawOperand->Value.Value.NodeId);
OpcUa_NodeId_Initialize(pRawOperand->Value.Value.NodeId);
pRawOperand->Value.Value.NodeId->NamespaceIndex = 4;
pRawOperand->Value.Value.NodeId->IdentifierType = OpcUa_IdentifierType_Numeric;
pRawOperand->Value.Value.NodeId->Identifier.Numeric = 2;
uStatus = UaClient_Subscription_BeginCreateMonitoredItems(a_pSampleSubscription->pSubscription,
OpcUa_Null,
numItemsToCreate,
&itemsToCreate,
SampleSubscription_MonitoredItems_Created_CB,
OpcUa_Null);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_MonitoredItemCreateRequest_Clear(&itemsToCreate);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_MonitoredItemCreateRequest_Clear(&itemsToCreate);
OpcUa_FinishErrorHandling;
}
OpcUa_StatusCode SampleSubscription_DeleteMonitoredItem(SampleSubscription *a_pSampleSubscription)
{
OpcUa_Int32 numItemsToDelete = 1;
OpcUa_UInt32 MonitoredItemIds[1];
a_pSampleSubscription->State = State_SampleSubscription_MonitoredItemDelete;
MonitoredItemIds[0] = a_pSampleSubscription->uMonitoredItemId;
return UaClient_Subscription_BeginDeleteMonitoredItems(a_pSampleSubscription->pSubscription,
OpcUa_Null,
numItemsToDelete,
MonitoredItemIds,
SampleSubscription_MonitoredItems_Deleted_CB,
OpcUa_Null);
}