ANSI C Based OPC UA Client/Server SDK  1.9.0.430
custom_provider.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 "custom_provider.h"
#include <uaserver_utilities.h>
#include "custom_provider_helper.h"
OPCUA_BEGIN_EXTERN_C
/* Global provider data */
UaServer_Provider *g_pCustomProvider;
UaServer_pProviderInterface *g_pCustomProviderInterface;
OpcUa_UInt16 g_uCustomProvider_NamespaceIndex = OpcUa_UInt16_Max;
/* Forward declarations */
IFMETHODIMP(CustomProvider_Cleanup)(OpcUa_Void);
IFMETHODIMP(CustomProvider_ReadAsync)(UaServer_ProviderReadContext *a_pReadCtx);
IFMETHODIMP(CustomProvider_WriteAsync)(UaServer_ProviderWriteContext *a_pWriteCtx);
IFMETHODIMP(CustomProvider_BrowseAsync)(UaServer_ProviderBrowseContext *a_pBrowseCtx);
IFMETHODIMP(CustomProvider_TranslateAsync)(UaServer_ProviderTranslateContext *a_pTranslateCtx);
IFMETHODIMP(CustomProvider_AddItem)(UaServer_MonitoredItem *a_pItem);
IFMETHODIMP(CustomProvider_RemoveItem)(UaServer_MonitoredItem *a_pItem);
IFMETHODIMP(CustomProvider_Subscribe)(UaServer_ProviderSubscribeContext *a_pCtx);
OpcUa_StatusCode CustomProvider_Subscription_Initialize();
OpcUa_StatusCode CustomProvider_Subscription_Cleanup();
OpcUa_StatusCode CustomProvider_CreateSampleNodes(OpcUa_BaseNode *a_pOwner, OpcUa_NodeId *a_pStartingNodeId)
{
OpcUa_DataVariable *pVariable = OpcUa_Null;
OpcUa_Variant *pValue = OpcUa_Null;
UaServer_AddressSpace *pAddressSpace = &g_pCustomProvider->AddressSpace;
UaServer_AddressSpace *pServerAddressSpace = OpcUa_Null;
OpcUa_NodeId nodeId, referenceNodeId, typeNodeId;
OpcUa_uid_t uidAnonymous = 0, uidRoot = 0;
OpcUa_gid_t gidAnonymous = 0, gidRoot = 0;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateSampleNodes");
OpcUa_ReturnErrorIfArgumentNull(a_pOwner);
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
UaServer_AddressSpace_Get(0, &pServerAddressSpace);
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
OpcUa_NodeId_Initialize(&typeNodeId);
uStatus = UaServer_GetUserId(OpcUa_String_FromCString("anonymous"), &uidAnonymous, &gidAnonymous);
OpcUa_GotoErrorIfBad(uStatus);
uStatus = UaServer_GetUserId(OpcUa_String_FromCString("root"), &uidRoot, &gidRoot);
OpcUa_GotoErrorIfBad(uStatus);
/* Create variable that is read- and writable by all users */
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateDataVariable(pAddressSpace,
&pVariable,
a_pOwner,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Sample_WriteAll_ReadAll");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pVariable, OpcUaId_UInt32, 0);
pValue = OpcUa_Variable_GetValue(pVariable);
pValue->Datatype = OpcUaType_UInt32;
pValue->Value.UInt32 = 100;
UaServer_UserMgt_SetPermissions((OpcUa_BaseNode*)pVariable,
uidAnonymous,
gidAnonymous,
0x0FFF);
/* Create variable that is readable by all users and only writable by user 'root' */
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateDataVariable(pAddressSpace,
&pVariable,
a_pOwner,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Sample_WriteRoot_ReadAll");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pVariable, OpcUaId_UInt32, 0);
pValue = OpcUa_Variable_GetValue(pVariable);
pValue->Datatype = OpcUaType_UInt32;
pValue->Value.UInt32 = 100;
UaServer_UserMgt_SetPermissions((OpcUa_BaseNode*)pVariable,
uidRoot,
gidRoot,
/* Create variable that is read- and writable only by user 'root' */
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateDataVariable(pAddressSpace,
&pVariable,
a_pOwner,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Sample_WriteRoot_ReadRoot");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pVariable, OpcUaId_UInt32, 0);
pValue = OpcUa_Variable_GetValue(pVariable);
pValue->Datatype = OpcUaType_UInt32;
pValue->Value.UInt32 = 100;
UaServer_UserMgt_SetPermissions((OpcUa_BaseNode*)pVariable,
uidRoot,
gidRoot,
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/* Internal Helper For Creating The AddressSpace In The Server */
OpcUa_StatusCode CustomProvider_CreateAddressSpace()
{
OpcUa_UInt16 uNsIdx = g_uCustomProvider_NamespaceIndex;
OpcUa_Folder *pCustomProvider = OpcUa_Null;
OpcUa_Folder *pFolder = OpcUa_Null;
OpcUa_NodeId nodeId;
UaServer_AddressSpace *pAddressSpace = &(g_pCustomProvider->AddressSpace);
UaServer_AddressSpace *pServerAddressSpace = OpcUa_Null;
OpcUa_BaseNode_DefaultValues *pBaseNode_DefaultValues = OpcUa_BaseNode_DefaultValues_Get();
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateAddressSpace");
OpcUa_NodeId_Initialize(&nodeId);
/* Set default values for node creation */
#if UASERVER_ENABLE_MINSAMPLINGINTERVAL
pBaseNode_DefaultValues->MinimumSamplingInterval = 50.0;
#endif
pBaseNode_DefaultValues->AccessLevel = OpcUa_AccessLevels_CurrentReadOrWrite;
#if UASERVER_SUPPORT_AUTHORIZATION == OPCUA_CONFIG_NO
pBaseNode_DefaultValues->UserAccessLevel = OpcUa_AccessLevels_CurrentReadOrWrite;
#endif
/* Get objects folder node */
UaServer_AddressSpace_Get(0, &pServerAddressSpace);
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ObjectsFolder;
UaServer_GetNode(pServerAddressSpace, &nodeId, (OpcUa_BaseNode**)&pFolder);
/* Create custom provider base node */
nodeId.Identifier.Numeric++;
uStatus = UaServer_CreateFolder(pAddressSpace,
&pCustomProvider,
(OpcUa_BaseNode*)pFolder,
nodeId.Identifier.Numeric,
uNsIdx,
"Custom Provider");
OpcUa_GotoErrorIfBad(uStatus);
/* create demo nodes */
uStatus = CustomProvider_CreateSampleNodes((OpcUa_BaseNode*)pCustomProvider, &nodeId);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/* Initialization function called by the server */
IFMETHODIMP(CustomProvider_Initialize)(UaServer_Provider *a_pProvider,
UaServer_pProviderInterface *a_pProviderInterface)
{
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_Initialize");
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Initialize CustomProvider ...\n");
/* Store values */
g_pCustomProvider = a_pProvider;
g_pCustomProviderInterface = a_pProviderInterface;
OpcUa_MemSet(g_pCustomProviderInterface, 0, sizeof(UaServer_pProviderInterface));
/* Register service handlers */
a_pProviderInterface->Cleanup = CustomProvider_Cleanup;
a_pProviderInterface->ReadAsync = CustomProvider_ReadAsync;
a_pProviderInterface->WriteAsync = CustomProvider_WriteAsync;
a_pProviderInterface->BrowseAsync = CustomProvider_BrowseAsync;
a_pProviderInterface->TranslateAsync = CustomProvider_TranslateAsync;
a_pProviderInterface->AddItem = CustomProvider_AddItem;
a_pProviderInterface->RemoveItem = CustomProvider_RemoveItem;
a_pProviderInterface->Subscribe = CustomProvider_Subscribe;
/* Register address space */
uStatus = UaServer_RegisterAddressSpace((OpcUa_Handle *)a_pProvider,
&g_uCustomProvider_NamespaceIndex,
"http://www.unifiedautomation.com/customprovider/",
1009);
OpcUa_ReturnErrorIfBad(uStatus);
/* Create address space */
uStatus = CustomProvider_CreateAddressSpace();
OpcUa_ReturnErrorIfBad(uStatus);
/* Initialize subscription management */
uStatus = CustomProvider_Subscription_Initialize();
OpcUa_ReturnErrorIfBad(uStatus);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Initialize CustomProvider DONE!\n");
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/* Clean up the custom provider */
IFMETHODIMP(CustomProvider_Cleanup)()
{
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_Cleanup");
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Cleanup CustomProvider ...\n");
/* Cleanup subscription management */
CustomProvider_Subscription_Cleanup();
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Cleanup CustomProvider DONE!\n");
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
#ifdef BUILD_SHARED_LIBS
CUSTOMPROVIDER_API(OpcUa_StatusCode) InitializeProvider(UaServer_Provider* pProvider,
UaServer_pProviderInterface* pProviderInterface)
{
return CustomProvider_Initialize(pProvider, pProviderInterface);
}
#endif
OPCUA_END_EXTERN_C