ANSI C UA Server SDK  1.6.0.341
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Modules Pages
custom_provider.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 "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();
/* Creates the TemperatureSensorType nodes in the address space.
* @param [in,out] a_pStartingNodeId A numeric NodeId to use for the new NodeIds.
The identifier is incremented for each created NodeId.
* @param [out] a_ppTemperatureSensorType The newly created TemperatureSensorType.
* @return OpcUa_Good on success.
*/
OpcUa_StatusCode CustomProvider_CreateTemperatureSensorType(OpcUa_NodeId *a_pStartingNodeId,
OpcUa_ObjectType **a_ppTemperatureSensorType)
{
OpcUa_ObjectType *pNewSensorType = OpcUa_Null;
OpcUa_DataVariable *pVariable = OpcUa_Null;
OpcUa_BaseNode *pBaseNode = OpcUa_Null;
UaServer_AddressSpace *pAddressSpace = &g_pCustomProvider->AddressSpace;
UaServer_AddressSpace *pServerAddressSpace = OpcUa_Null;
OpcUa_Variant *pValue = OpcUa_Null;
OpcUa_NodeId nodeId, referenceNodeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateTemperatureSensorType");
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
OpcUa_ReturnErrorIfArgumentNull(a_ppTemperatureSensorType);
*a_ppTemperatureSensorType = OpcUa_Null;
UaServer_AddressSpace_Get(0, &pServerAddressSpace);
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
/* Create object type */
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_BaseObjectType;
UaServer_GetNode(pServerAddressSpace, &nodeId, &pBaseNode);
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateObjectType(pAddressSpace,
&pNewSensorType,
pBaseNode,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"TemperatureSensorType");
OpcUa_GotoErrorIfBad(uStatus);
/* Create Temperature property */
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateDataVariable(pAddressSpace,
&pVariable,
(OpcUa_BaseNode*)pNewSensorType,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Temperature");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pVariable, OpcUaId_Double, 0);
pValue = OpcUa_Variable_GetValue(pVariable);
pValue->Datatype = OpcUaType_Double;
pValue->Value.Double = 25.0;
/* Set ModellingRule Mandatory for Temperature property */
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ModellingRule_Mandatory;
referenceNodeId.Identifier.Numeric = OpcUaId_HasModellingRule;
uStatus = OpcUa_BaseNode_AddReferenceToNodeId(pVariable, &nodeId, &referenceNodeId);
OpcUa_GotoErrorIfBad(uStatus);
*a_ppTemperatureSensorType = pNewSensorType;
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/* Creates the MachineType nodes in the address space.
* @param [in,out] a_pStartingNodeId A numeric NodeId to use for the new NodeIds.
The identifier is incremented for each created NodeId.
* @param [out] a_ppMachineType The newly created MachineType.
* @param [out] a_ppTemperatureSensorType The newly created TemperatureSensorType.
* @return OpcUa_Good on success.
*/
OpcUa_StatusCode CustomProvider_CreateMachineType(OpcUa_NodeId *a_pStartingNodeId,
OpcUa_ObjectType **a_ppMachineType,
OpcUa_ObjectType **a_ppTemperatureSensorType)
{
OpcUa_ObjectType *pNewMachineType = OpcUa_Null;
OpcUa_Object *pTemperatureSensor = OpcUa_Null;
OpcUa_DataVariable *pVariable = OpcUa_Null;
OpcUa_BaseNode *pBaseNode = OpcUa_Null;
UaServer_AddressSpace *pAddressSpace = &g_pCustomProvider->AddressSpace;
UaServer_AddressSpace *pServerAddressSpace = OpcUa_Null;
OpcUa_Variant *pValue = OpcUa_Null;
OpcUa_NodeId nodeId, referenceNodeId;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateMachineType");
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
OpcUa_ReturnErrorIfArgumentNull(a_ppMachineType);
OpcUa_ReturnErrorIfArgumentNull(a_ppTemperatureSensorType);
*a_ppMachineType = OpcUa_Null;
*a_ppTemperatureSensorType = OpcUa_Null;
UaServer_AddressSpace_Get(0, &pServerAddressSpace);
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
uStatus = CustomProvider_CreateTemperatureSensorType(a_pStartingNodeId, a_ppTemperatureSensorType);
OpcUa_GotoErrorIfBad(uStatus);
/* Create MachineType object type */
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_BaseObjectType;
UaServer_GetNode(pServerAddressSpace, &nodeId, &pBaseNode);
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateObjectType(pAddressSpace,
&pNewMachineType,
pBaseNode,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"MachineType");
OpcUa_GotoErrorIfBad(uStatus);
/* Create HeaterSwitch property */
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateDataVariable(pAddressSpace,
&pVariable,
(OpcUa_BaseNode*)pNewMachineType,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"HeaterSwitch");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pVariable, OpcUaId_Boolean, 0);
pValue = OpcUa_Variable_GetValue(pVariable);
pValue->Datatype = OpcUaType_Boolean;
pValue->Value.Boolean = OpcUa_False;
/* Set ModellingRule Mandatory for Temperature property */
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ModellingRule_Mandatory;
referenceNodeId.Identifier.Numeric = OpcUaId_HasModellingRule;
uStatus = OpcUa_BaseNode_AddReferenceToNodeId(pVariable, &nodeId, &referenceNodeId);
OpcUa_GotoErrorIfBad(uStatus);
/* Create TemperatureSensor child object */
referenceNodeId.Identifier.Numeric = OpcUaId_HasComponent;
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateNode(pAddressSpace,
(OpcUa_BaseNode **)&pTemperatureSensor,
(OpcUa_BaseNode*)pNewMachineType,
a_pStartingNodeId,
OpcUa_NodeClass_Object,
&referenceNodeId,
OpcUa_BaseNode_GetId(*a_ppTemperatureSensorType),
"TemperatureSensor",
"TemperatureSensor",
"TemperatureSensor");
OpcUa_GotoErrorIfBad(uStatus);
/* Set ModellingRule Mandatory for TemperatureSensor child object */
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ModellingRule_Mandatory;
referenceNodeId.Identifier.Numeric = OpcUaId_HasModellingRule;
uStatus = OpcUa_BaseNode_AddReferenceToNodeId(pTemperatureSensor, &nodeId, &referenceNodeId);
OpcUa_GotoErrorIfBad(uStatus);
/* Create TemperatureSensor's Temperature property */
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateDataVariable(pAddressSpace,
&pVariable,
(OpcUa_BaseNode*)pTemperatureSensor,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Temperature");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pVariable, OpcUaId_Double, 0);
pValue = OpcUa_Variable_GetValue(pVariable);
pValue->Datatype = OpcUaType_Double;
pValue->Value.Double = 25.0;
/* Set ModellingRule Mandatory for TemperatureSensor's Temperature property */
nodeId.NamespaceIndex = 0;
nodeId.Identifier.Numeric = OpcUaId_ModellingRule_Mandatory;
referenceNodeId.Identifier.Numeric = OpcUaId_HasModellingRule;
uStatus = OpcUa_BaseNode_AddReferenceToNodeId(pVariable, &nodeId, &referenceNodeId);
OpcUa_GotoErrorIfBad(uStatus);
*a_ppMachineType = pNewMachineType;
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/* Creates a new TemperatureSensor instance in the address space.
* @param [in] a_sSensorName The name of the new sensor.
* @param [in] a_pOwner The parent node of the new TemperatureSensor.
* @param [in] a_pTemperatureSensorTypeId The type NodeId to use for the new TemperatureSensor instance.
* @param [in,out] a_pStartingNodeId A numeric NodeId to use for the new NodeIds.
The identifier is incremented for each created NodeId.
* @return OpcUa_Good on success.
*/
OpcUa_StatusCode CustomProvider_CreateTemperatureSensor(const OpcUa_CharA *a_sSensorName,
OpcUa_BaseNode *a_pOwner,
OpcUa_NodeId *a_pTemperatureSensorTypeId,
OpcUa_NodeId *a_pStartingNodeId)
{
OpcUa_Object *pObject = OpcUa_Null;
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;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateTemperatureSensor");
OpcUa_ReturnErrorIfArgumentNull(a_sSensorName);
OpcUa_ReturnErrorIfArgumentNull(a_pOwner);
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
UaServer_AddressSpace_Get(0, &pServerAddressSpace);
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
/* Create new TemperatureSensor instance in the address space */
referenceNodeId.Identifier.Numeric = OpcUaId_HasComponent;
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateNode(pAddressSpace,
(OpcUa_BaseNode **)&pObject,
a_pOwner,
a_pStartingNodeId,
OpcUa_NodeClass_Object,
&referenceNodeId,
a_pTemperatureSensorTypeId,
a_sSensorName,
a_sSensorName,
a_sSensorName);
OpcUa_GotoErrorIfBad(uStatus);
/* Create Temperature property */
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateDataVariable(pAddressSpace,
&pVariable,
(OpcUa_BaseNode*)pObject,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"Temperature");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pVariable, OpcUaId_Double, 0);
pValue = OpcUa_Variable_GetValue(pVariable);
pValue->Datatype = OpcUaType_Double;
pValue->Value.Double = 25.0;
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/* Creates a new Machine instance in the address space.
* @param [in] a_sMachineName The name of the new Machine.
* @param [in] a_sTemperatureSensorName The name of the new Machine's TemperatureSensor.
* @param [in] a_pOwner The parent node of the new Machine.
* @param [in] a_pMachineTypeId The type NodeId to use for the new Machine instance.
* @param [in] a_pTemperatureSensorTypeId The type NodeId to use for the new TemperatureSensor instance.
* @param [in,out] a_pStartingNodeId A numeric NodeId to use for the new NodeIds.
The identifier is incremented for each created NodeId.
* @return OpcUa_Good on success.
*/
OpcUa_StatusCode CustomProvider_CreateMachine(const OpcUa_CharA *a_sMachineName,
const OpcUa_CharA *a_sTemperatureSensorName,
OpcUa_BaseNode *a_pOwner,
OpcUa_NodeId *a_pMachineTypeId,
OpcUa_NodeId *a_pTemperatureSensorTypeId,
OpcUa_NodeId *a_pStartingNodeId)
{
OpcUa_Object *pObject = OpcUa_Null;
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;
OpcUa_InitializeStatus(OpcUa_Module_Server, "CustomProvider_CreateMachine");
OpcUa_ReturnErrorIfArgumentNull(a_sMachineName);
OpcUa_ReturnErrorIfArgumentNull(a_sTemperatureSensorName);
OpcUa_ReturnErrorIfArgumentNull(a_pOwner);
OpcUa_ReturnErrorIfArgumentNull(a_pStartingNodeId);
UaServer_AddressSpace_Get(0, &pServerAddressSpace);
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_NodeId_Initialize(&referenceNodeId);
/* Create new Machine instance in the address space */
referenceNodeId.Identifier.Numeric = OpcUaId_Organizes;
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateNode(pAddressSpace,
(OpcUa_BaseNode **)&pObject,
a_pOwner,
a_pStartingNodeId,
OpcUa_NodeClass_Object,
&referenceNodeId,
a_pMachineTypeId,
a_sMachineName,
a_sMachineName,
a_sMachineName);
OpcUa_GotoErrorIfBad(uStatus);
/* Create HeaterSwitch property */
a_pStartingNodeId->Identifier.Numeric++;
uStatus = UaServer_CreateDataVariable(pAddressSpace,
&pVariable,
(OpcUa_BaseNode*)pObject,
a_pStartingNodeId->Identifier.Numeric,
g_uCustomProvider_NamespaceIndex,
"HeaterSwitch");
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_Variable_SetDataType_Numeric(pVariable, OpcUaId_Boolean, 0);
pValue = OpcUa_Variable_GetValue(pVariable);
pValue->Datatype = OpcUaType_Boolean;
pValue->Value.Boolean = OpcUa_False;
/* Create TemperatureSensor */
uStatus = CustomProvider_CreateTemperatureSensor(a_sTemperatureSensorName,
(OpcUa_BaseNode*)pObject,
a_pTemperatureSensorTypeId,
a_pStartingNodeId);
OpcUa_GotoErrorIfBad(uStatus);
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_ObjectType *pMachineType = OpcUa_Null;
OpcUa_ObjectType *pTemperatureSensorType = 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 */
pBaseNode_DefaultValues->MinimumSamplingInterval = 50.0;
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 object types */
nodeId.NamespaceIndex = uNsIdx;
nodeId.Identifier.Numeric = 1;
uStatus = CustomProvider_CreateMachineType(&nodeId, &pMachineType, &pTemperatureSensorType);
OpcUa_GotoErrorIfBad(uStatus);
/* 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 instance of MachineType */
uStatus = CustomProvider_CreateMachine("MyCustomMachine",
"MyCustomTemperatureSensor",
(OpcUa_BaseNode*)pCustomProvider,
OpcUa_BaseNode_GetId(pMachineType),
OpcUa_BaseNode_GetId(pTemperatureSensorType),
&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");
printf("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);
printf("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");
printf("Cleanup CustomProvider ...\n");
/* Cleanup subscription management */
CustomProvider_Subscription_Cleanup();
printf("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