File: C:/Redmine-4.x/redmine-4.2.9/files/180306055903_OpenOpcUaClientLib.cpp
/*****************************************************************************
Author
©. Michel Condemine, 4CE Industry (2010-2013)
Contributors
This software is a computer program whose purpose is to
implement behavior describe in the OPC UA specification.
see wwww.opcfoundation.org for more details about OPC.
This software is governed by the CeCILL-C license under French law and
abiding by the rules of distribution of free software. You can use,
modify and/ or redistribute the software under the terms of the CeCILL-C
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info".
As a counterpart to the access to the source code and rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty and the software's author, the holder of the
economic rights, and the successive licensors have only limited
liability.
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL-C license and that you accept its terms.
*****************************************************************************/
#include "stdafx.h"
#include "Application.h"
#include "OpenOpcUaClientLib.h"
#include "MonitoredItemClient.h"
#include "MonitoredItemsNotification.h"
#include "SubscriptionClient.h"
#include "ClientSession.h"
#include "LoggerMessage.h"
#include "ClientApplication.h"
#include "ClientAttribute.h" // Attribute structure used for lookup
#include "UABuiltInType.h" // BuiltIn type structure used for lookup
#include "opcua_base64.h"
#include "XmlParser.h"
using namespace OpenOpcUa;
using namespace UACoreClient;
using namespace UASharedLib;
CClientApplicationList g_pUaClientApplicationList;
OpcUa_Boolean g_bAbstractionLayerInitialized=OpcUa_False;
OpcUa_UInt32 g_ServiceCallTimeout = CLIENTLIB_DEFAULT_TIMEOUT;
OpcUa_UInt32 CClientApplication::m_uiRequestHandle = 1;
OpcUa_Boolean g_bAutoConnectMecanism=OpcUa_True;
void OpenOpcUa_AutoConnectMecanismState(OpcUa_Boolean bActive)
{
g_bAutoConnectMecanism = bActive;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Initialisation de la bibliothèque. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 02/01/2018. </remarks>
///
/// <param name="szApplicationName"> [in,out] If non-null, name of the application. </param>
/// <param name="hApplication"> [in,out] If non-null, the application. </param>
/// <param name="uiDefaultTimeout"> This timeout in milliseconds is used in the Client side
/// Communication Stack to set the timeout on a per-call base.
/// See (timeoutHint) OPC UA Part 4. §7.28 for detail </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_InitializeAbstractionLayer(OpcUa_CharA* szApplicationName, OpcUa_Handle* hApplication, OpcUa_UInt32 uiDefaultTimeout)
{
OpcUa_Trace(OpcUa_Null, OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_InitializeAbstractionLayer\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (!szApplicationName)
uStatus=OpcUa_BadInvalidArgument;
else
{
//if (!g_bAbstractionLayerInitialized)
{
CClientApplication* g_pUaClientApplication=new CClientApplication();
g_pUaClientApplicationList.push_back(g_pUaClientApplication);
*hApplication=(OpcUa_Handle)g_pUaClientApplication;
OpcUa_LocalizedText aAppName;
OpcUa_LocalizedText_Initialize(&aAppName);
OpcUa_String_AttachCopy(&(aAppName.Text),szApplicationName);
OpcUa_String_AttachCopy(&(aAppName.Locale),(OpcUa_CharA*)"en-US");
g_pUaClientApplication->SetApplicationName(&aAppName);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = g_pUaClientApplication->GetTraceConfiguration();
uStatus=OpcUa_Good;
g_bAbstractionLayerInitialized=OpcUa_True;
// Save the function timeout
g_ServiceCallTimeout = uiDefaultTimeout;
// Il restera a initialiser l'ApplicationDescription du client
// Elle sera mise en place lors de l'appel à OpenOpcUa_InitializeSecurity
// On place le niveau de trace
// Mise en place du nom du fichier de sortie
OpcUa_LocalizedText* sApplicationName=OpcUa_Null;
OpcUa_String strFileName;
OpcUa_String_Initialize(&strFileName);
OpcUa_String strBakFileName;
OpcUa_String_Initialize(&strBakFileName);
// extension du fichier
OpcUa_String strExtension;
OpcUa_String_Initialize(&strExtension);
OpcUa_String_AttachCopy(&strExtension,".log");
// extension de la sauvegarde
OpcUa_String strBakExtension;
OpcUa_String_Initialize(&strBakExtension);
OpcUa_String_AttachCopy(&strBakExtension,".bak");
sApplicationName=g_pUaClientApplication->GetApplicationName();
if (sApplicationName)
{
OpcUa_String_CopyTo(&(sApplicationName->Text),&strFileName);
OpcUa_String_CopyTo(&(sApplicationName->Text),&strBakFileName);
// creation du nom du fichier de log
OpcUa_String_StrnCat(&strFileName,&strExtension,OpcUa_String_StrLen(&strExtension));
// creation du nom du fichier de sauvegarde
OpcUa_String_StrnCat(&strBakFileName,&strBakExtension,OpcUa_String_StrLen(&strBakExtension));
OpcUa_Trace_SetTraceFile(pTraceConfiguration,strFileName);
//
// On sauvegarde une eventuelle trace existante
FILE* hFile=OpcUa_Null;
OpcUa_CharA* szFileName = OpcUa_String_GetRawString(&strFileName);
hFile=fopen(szFileName, "r");
if (hFile)
{
// Ouverture du fichier de sauvegarde
FILE* hFileBak=OpcUa_Null;
OpcUa_CharA* szBakFileName = OpcUa_String_GetRawString(&strBakFileName);
hFileBak=fopen(szBakFileName, "w");
char bakBuffer;
// On lit l'ensemble du fichier dans le buffer
// On copie dans la sauvegarde
while (fread(&bakBuffer,sizeof(char),1,hFile)==1)
fwrite(&bakBuffer,sizeof(char),1,hFileBak);
fclose(hFileBak);
hFileBak = OpcUa_Null;
fclose(hFile);
// On supprime l'ancien fichier
hFile = OpcUa_Null;
hFile = fopen(szFileName, "w");
if (hFile)
fclose(hFile);
}
g_pUaClientApplication->SetTraceLevel(OPCUA_TRACE_CLIENT_LEVEL_ERROR);
g_pUaClientApplication->SetTraceOutput(OPCUA_TRACE_OUTPUT_FILE);
OpcUa_Trace_SetTraceFile(pTraceConfiguration,strFileName);
}
OpcUa_String_Clear(&strExtension);
OpcUa_String_Clear(&strFileName);
OpcUa_String_Clear(&strBakExtension);
OpcUa_String_Clear(&strBakFileName);
OpcUa_LocalizedText_Clear(&aAppName);
}
}
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_SetTimeoutHint(OpcUa_UInt32 uiDefaultTimeout)
{
OpcUa_StatusCode uStatus=OpcUa_Good;
OpcUa_Trace(OpcUa_Null, OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_SetTimeoutHint\n");
if (g_bAbstractionLayerInitialized)
{
if (uiDefaultTimeout > 15000)
g_ServiceCallTimeout = uiDefaultTimeout;
else
uStatus = OpcUa_BadInvalidArgument;
}
else
uStatus = OpcUa_BadInternalError;
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_ClearAbstractionLayer(OpcUa_Handle hApplication)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_ClearAbstractionLayer\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
OpcUa_LocalizedText* sApplicationName=OpcUa_Null;
if (g_bAbstractionLayerInitialized)
{
OpcUa_LocalizedText_Initialize(sApplicationName);
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
for (CClientApplicationList::iterator it=g_pUaClientApplicationList.begin();it!=g_pUaClientApplicationList.end();it++)
{
if (*it==pUaClientApplication)
{
delete pUaClientApplication;
pUaClientApplication = OpcUa_Null;
g_pUaClientApplicationList.erase(it);
break;
}
}
uStatus=OpcUa_Good;
}
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_InitializeSecurity(OpcUa_Handle hApplication,OpcUa_String szCertificateStore)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_InitializeSecurity\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
OpcUa_String sApplicationUri;
OpcUa_LocalizedText* pApplicationName=OpcUa_Null;
if (g_bAbstractionLayerInitialized)
{
OpcUa_LocalizedText_Initialize(pApplicationName);
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
pApplicationName=pUaClientApplication->GetApplicationName();
// L'application URI est fabriquée a partifir de l'applicationName
OpcUa_String_Initialize(&sApplicationUri);
OpcUa_String_AttachCopy(
&(sApplicationUri),(OpcUa_CharA*)"http://www.OpenOpcUa.org/UAClientLib/");
OpcUa_String_StrnCat(&(sApplicationUri), &(pApplicationName->Text), OpcUa_String_StrLen(&(pApplicationName->Text)));
//
//uStatus=pUaClientApplication->InitializeSecurity(
// szCertificateStore,
// &sApplicationUri,
// sApplicationName,
// OpcUa_False); // will use the DER
pUaClientApplication->SetCertificateStorePath(szCertificateStore);
uStatus=pUaClientApplication->LoadPFXCertificate();
if (uStatus==OpcUa_Good)
{
// on va tenter de lire le fichier DER afin de vérifier qu'il s'agit du bon DER
// a savoir :
// 1- il existe
// 2- sa clé correpsond acelle du pfx
uStatus=pUaClientApplication->LoadDERCertificate();
if (uStatus!=OpcUa_Good)
uStatus=pUaClientApplication->CreateCertificate();
}
else
{
uStatus=pUaClientApplication->CreateCertificate();
}
uStatus = pUaClientApplication->InitializeSecurity(&sApplicationUri, pApplicationName);
if (uStatus==OpcUa_Good)
{
// Maintenant que tout est pret on va remplir l'ApplicationDescription de ce client
// Creation et remplissage d'un OpcUa_ApplicationDescription.
// Il contient l'ensemble des informations relative a cette application UA (client)
OpcUa_ApplicationDescription* pAppDescription=(OpcUa_ApplicationDescription*)OpcUa_Alloc(sizeof(OpcUa_ApplicationDescription));
OpcUa_ApplicationDescription_Initialize(pAppDescription);
pAppDescription->ApplicationType=OpcUa_ApplicationType_Client;
// ApplicationUri
OpcUa_String_CopyTo(&sApplicationUri, &(pAppDescription->ApplicationUri));
// ApplicationName
OpcUa_LocalizedText_CopyTo(pApplicationName, &(pAppDescription->ApplicationName));
// ProductUri
OpcUa_String_CopyTo(&sApplicationUri, &(pAppDescription->ProductUri));
pUaClientApplication->SetApplicationDescription(pAppDescription);
OpcUa_ApplicationDescription_Clear(pAppDescription);
OpcUa_Free(pAppDescription);
}
}
OpcUa_String_Clear(&sApplicationUri);
//if (pApplicationName)
//{
// OpcUa_LocalizedText_Clear(pApplicationName);
// OpcUa_Free(pApplicationName);
//}
return uStatus;
}
// FindServers
// L'usage classique de cette fonction consiste a demander au LDS ou au server ses ApplicationDescription
OpcUa_StatusCode OpenOpcUa_FindServers(OpcUa_Handle hApplication,OpcUa_String* hostName,OpcUa_Int32* uiNoOfServer,OpcUa_ApplicationDescription** pServers)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_FindServers\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
OpcUa_RequestHeader tRequestHeader;
OpcUa_String sDiscoveryUrl;
OpcUa_String sLocaleIds;
OpcUa_String sServerUris;
OpcUa_ResponseHeader tResponseHeader;
OpcUa_RequestHeader_Initialize(&tRequestHeader);
OpcUa_String_Initialize(&sDiscoveryUrl);
OpcUa_String_Initialize(&sLocaleIds);
OpcUa_String_Initialize(&sServerUris);
OpcUa_ResponseHeader_Initialize(&tResponseHeader);
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
// Construction de la discoveryUrl
std::string tmpDiscoveryUrl;
// construct the discovery url from the host name.
tmpDiscoveryUrl.append("opc.tcp://");
if (OpcUa_String_StrLen(hostName)>0)
tmpDiscoveryUrl.append(OpcUa_String_GetRawString(hostName));
else
tmpDiscoveryUrl.append("localhost");
tmpDiscoveryUrl.append(":4840");
uStatus=OpcUa_String_AttachCopy(&sDiscoveryUrl,(OpcUa_CharA*)tmpDiscoveryUrl.c_str());
//
tmpDiscoveryUrl.clear();
CChannel channel(pUaClientApplication);
OpcUa_MessageSecurityMode eSecurityMode = OpcUa_MessageSecurityMode_None;
OpcUa_String szSecurityPolicy;
OpcUa_String_Initialize(&szSecurityPolicy);
uStatus = channel.Connect(sDiscoveryUrl,eSecurityMode,szSecurityPolicy);
if (uStatus==OpcUa_Good)
{
// find the servers.
tRequestHeader.TimeoutHint = g_ServiceCallTimeout;// UTILS_DEFAULT_TIMEOUT;
tRequestHeader.Timestamp = OpcUa_DateTime_UtcNow();
tRequestHeader.RequestHandle = CClientApplication::m_uiRequestHandle++;
// find the servers.
uStatus = OpcUa_ClientApi_FindServers(
channel.GetInternalHandle(),
&tRequestHeader,
&sDiscoveryUrl,
0,
&sLocaleIds,
0,
&sServerUris,
&tResponseHeader,
uiNoOfServer,
pServers);
}
tmpDiscoveryUrl.clear();
}
OpcUa_String_Clear(&sDiscoveryUrl);
OpcUa_String_Clear(&sLocaleIds);
OpcUa_String_Clear(&sServerUris);
}
return uStatus;
}
// GetEndpoints
OpcUa_StatusCode OpenOpcUa_GetEndpoints(OpcUa_Handle hApplication,OpcUa_String* discoveryUrl,OpcUa_UInt32* uiNoOfEndpointDescription,OpcUa_EndpointDescription** ppEndpointDescription)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetEndpoints\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CEndpointDescriptionList* pEndpoints=new CEndpointDescriptionList();
if (pEndpoints)
{
uStatus = pUaClientApplication->DiscoverEndpoints(*discoveryUrl, pEndpoints);
if (uStatus == OpcUa_Good)
{
*uiNoOfEndpointDescription = pEndpoints->size();
OpcUa_EndpointDescription* pTmpEndpointDescription = (OpcUa_EndpointDescription*)OpcUa_Alloc((*uiNoOfEndpointDescription)*sizeof(OpcUa_EndpointDescription));
*ppEndpointDescription = pTmpEndpointDescription;
for (unsigned int ii = 0; ii < (*uiNoOfEndpointDescription); ii++)
{
CEndpointDescription* pEndpointDescription = pEndpoints->at(ii);
if (pEndpointDescription)
{
OpcUa_EndpointDescription_Initialize(&pTmpEndpointDescription[ii]);
OpcUa_EndpointDescription* pInternalEndpointDescription = pEndpointDescription->GetInternalEndPointDescription();
if (pInternalEndpointDescription)
{
///////////////////////////////////////////////////////////////////////////////////////
// Copy the EndpointUrl
if (OpcUa_String_Compare(discoveryUrl, &(pInternalEndpointDescription->EndpointUrl)) == 0)
OpcUa_String_CopyTo(&(pInternalEndpointDescription->EndpointUrl), &(pTmpEndpointDescription[ii].EndpointUrl));
else
OpcUa_String_CopyTo(discoveryUrl, &(pTmpEndpointDescription[ii].EndpointUrl));
// Copy the UserIdentity Tokens
pTmpEndpointDescription[ii].NoOfUserIdentityTokens = pInternalEndpointDescription->NoOfUserIdentityTokens;
OpcUa_UInt32 iLen = pTmpEndpointDescription[ii].NoOfUserIdentityTokens;
if (iLen)
{
pTmpEndpointDescription[ii].UserIdentityTokens = (OpcUa_UserTokenPolicy*)OpcUa_Alloc(iLen*sizeof(OpcUa_UserTokenPolicy));
ZeroMemory(pTmpEndpointDescription[ii].UserIdentityTokens, iLen*sizeof(OpcUa_UserTokenPolicy));
for (unsigned int iii = 0; iii < iLen; iii++)
{
OpcUa_String_CopyTo(&(pInternalEndpointDescription->UserIdentityTokens[iii].IssuedTokenType),
&(pTmpEndpointDescription[ii].UserIdentityTokens[iii].IssuedTokenType));
OpcUa_String_CopyTo(&(pInternalEndpointDescription->UserIdentityTokens[iii].IssuerEndpointUrl),
&(pTmpEndpointDescription[ii].UserIdentityTokens[iii].IssuerEndpointUrl));;
OpcUa_String_CopyTo(&(pInternalEndpointDescription->UserIdentityTokens[iii].PolicyId),
&(pTmpEndpointDescription[ii].UserIdentityTokens[iii].PolicyId));
OpcUa_String_CopyTo(&(pInternalEndpointDescription->UserIdentityTokens[iii].SecurityPolicyUri),
&(pTmpEndpointDescription[ii].UserIdentityTokens[iii].SecurityPolicyUri));
pTmpEndpointDescription[ii].UserIdentityTokens[iii].TokenType = pInternalEndpointDescription->UserIdentityTokens[iii].TokenType;
}
}
// Copy SecurityLevel and SecurityMode
pTmpEndpointDescription[ii].SecurityLevel = pInternalEndpointDescription->SecurityLevel;
pTmpEndpointDescription[ii].SecurityMode = pInternalEndpointDescription->SecurityMode;
// Copy SecurityPolicyUri
OpcUa_String aString = pInternalEndpointDescription->SecurityPolicyUri;
OpcUa_String_CopyTo(&aString, &(pTmpEndpointDescription[ii].SecurityPolicyUri));
//Copy ApplicationDescription
//OpcUa_ApplicationDescription* pApplicationDescription=Utils::Copy(&(pInternalEndpointDescription->Server));
// fill the ApplicationDescription
// ApplicationName
OpcUa_LocalizedText_CopyTo(&(pInternalEndpointDescription->Server.ApplicationName),
&(pTmpEndpointDescription[ii].Server.ApplicationName));
// ApplicationType
pTmpEndpointDescription[ii].Server.ApplicationType = pInternalEndpointDescription->Server.ApplicationType;
// ApplicationUri
OpcUa_String_CopyTo(&(pInternalEndpointDescription->Server.ApplicationUri),
&(pTmpEndpointDescription[ii].Server.ApplicationUri));
// DiscoveryProfileUri
OpcUa_String_CopyTo(&(pInternalEndpointDescription->Server.DiscoveryProfileUri),
&(pTmpEndpointDescription[ii].Server.DiscoveryProfileUri));
// DiscoveryUrls
if (pInternalEndpointDescription->Server.NoOfDiscoveryUrls > 0)
{
pTmpEndpointDescription[ii].Server.NoOfDiscoveryUrls = pInternalEndpointDescription->Server.NoOfDiscoveryUrls;
pTmpEndpointDescription[ii].Server.DiscoveryUrls = (OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String)*pInternalEndpointDescription->Server.NoOfDiscoveryUrls);
for (OpcUa_Int32 u = 0; u < pInternalEndpointDescription->Server.NoOfDiscoveryUrls; u++)
{
OpcUa_String_Initialize(&(pTmpEndpointDescription[ii].Server.DiscoveryUrls[u]));
OpcUa_String_CopyTo(&(pInternalEndpointDescription->Server.DiscoveryUrls[u]),
&(pTmpEndpointDescription[ii].Server.DiscoveryUrls[u]));
}
}
// GatewayServerUri
OpcUa_String_CopyTo(&(pInternalEndpointDescription->Server.GatewayServerUri),
&(pTmpEndpointDescription[ii].Server.GatewayServerUri));
// ProductUri
OpcUa_String_CopyTo(&(pInternalEndpointDescription->Server.ProductUri),
&(pTmpEndpointDescription[ii].Server.ProductUri));
// Copy ServerCertificate
OpcUa_ByteString_CopyTo(&(pInternalEndpointDescription->ServerCertificate), &(pTmpEndpointDescription[ii].ServerCertificate));
// Copy TransportProfileUri
OpcUa_String_CopyTo(&(pInternalEndpointDescription->TransportProfileUri), &(pTmpEndpointDescription[ii].TransportProfileUri));
}
}
}
}
// clear and release pEndPoints discovered
CEndpointDescriptionList::iterator it;
for (it = pEndpoints->begin(); it != pEndpoints->end(); it++)
{
CEndpointDescription* pEndpointDescription = *it;
delete pEndpointDescription;
}
pEndpoints->clear();
delete pEndpoints;
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> recupère une ApplicationDescription en fonction de sont Handle. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="pAppDescription"> [in,out] If non-null, information describing the application.
/// </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetApplicationDescription(OpcUa_Handle hApplication, OpcUa_ApplicationDescription* pAppDescription)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetApplicationDescription\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
pAppDescription=pUaClientApplication->GetApplicationDescription()->GetInternalApplicationDescription();
uStatus=OpcUa_Good;
}
}
return uStatus;
}// recupère une EndpointDescription en fonction de sont Handle
// Il s'agit des recupérer les informations sur le serveur sur lequel le client est connecté actuellement
OpcUa_StatusCode OpenOpcUa_GetEndpointDescription(OpcUa_Handle hApplication, OpcUa_Handle hSession, OpcUa_EndpointDescription** pEndpointDescription)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetEndpointDescription\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
CEndpointDescription* pUAEndpointDescription = pSession->GetEndpointDescription();
if (pUAEndpointDescription)
{
*pEndpointDescription = pUAEndpointDescription->GetInternalEndPointDescription();
uStatus = OpcUa_Good;
}
}
}
}
return uStatus;
}
// Activate Session
/// <summary>
/// Activate the previously created hSession.
/// </summary>
/// <param name="hApplication">Handle of your Application.</param>
/// <param name="hSession">Hadnle of the Session to activcate.</param>
/// <returns></returns>
OpcUa_StatusCode OpenOpcUa_ActivateSession(OpcUa_Handle hApplication, OpcUa_Handle hSession,
OpcUa_UserTokenType userTokenType,
OpcUa_String* pszPolicyId,
OpcUa_String* pszEncryptionAlgorithm,
OpcUa_String* pszUserName,
OpcUa_ByteString* PasswordorCertificateData)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_ActivateSession\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
// Those are the two legal encryption algorythm name
// So adjust the name receive from the client according to those one
OpcUa_String szRSA_OAEP;
OpcUa_String_Initialize(&szRSA_OAEP);
OpcUa_String_AttachCopy(&szRSA_OAEP, "http://www.w3.org/2001/04/xmlenc#rsa-oaep");
OpcUa_String szRSA_15;
OpcUa_String_Initialize(&szRSA_15);
OpcUa_String_AttachCopy(&szRSA_15, "http://www.w3.org/2001/04/xmlenc#rsa-1_5");
// expected cypher name
OpcUa_String basic128RSA15;
OpcUa_String_Initialize(&basic128RSA15);
OpcUa_String_AttachCopy(&basic128RSA15, "Basic128Rsa15");
OpcUa_String basic256;
OpcUa_String_Initialize(&basic256);
OpcUa_String_AttachCopy(&basic256, "Basic256");
OpcUa_String basic256Sha256;
OpcUa_String_Initialize(&basic256Sha256);
OpcUa_String_AttachCopy(&basic256Sha256, "Basic256Sha256");
if (OpcUa_String_Compare(pszEncryptionAlgorithm, &basic128RSA15) == 0)
{
OpcUa_String_Clear(pszEncryptionAlgorithm);
OpcUa_String_Initialize(pszEncryptionAlgorithm);
OpcUa_String_CopyTo(&szRSA_15, pszEncryptionAlgorithm);
}
else
{
if (OpcUa_String_Compare(pszEncryptionAlgorithm, &basic256) == 0)
{
OpcUa_String_Clear(pszEncryptionAlgorithm);
OpcUa_String_Initialize(pszEncryptionAlgorithm);
OpcUa_String_CopyTo(&szRSA_15, pszEncryptionAlgorithm);
}
}
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
uStatus = pSession->Activate(userTokenType,pszPolicyId,pszEncryptionAlgorithm,pszUserName,PasswordorCertificateData);
if (uStatus == OpcUa_Good)
pSession->AutoConnectThreadUnlock();
}
}
else
uStatus=OpcUa_BadInvalidArgument;
}
OpcUa_String_Clear(&szRSA_OAEP);
OpcUa_String_Clear(&szRSA_15);
OpcUa_String_Clear(&basic128RSA15);
OpcUa_String_Clear(&basic256);
OpcUa_String_Clear(&basic256Sha256);
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Create Session. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 03/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="pEndpointDescription"> [in,out] If non-null, information describing
/// the endpoint.
/// </param>
/// <param name="nRequestedClientSessionTimeout"> The requested client session timeout. </param>
/// <param name="aSessionName"> Name of the session. </param>
/// <param name="hSession"> [in,out] If non-null, the session. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_CreateSession(OpcUa_Handle hApplication,
OpcUa_EndpointDescription* pUAEndpointDescription,
OpcUa_Double nRequestedClientSessionTimeout,
OpcUa_String aSessionName,
OpcUa_Handle* hSession)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_CreateSession\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
if (pUAEndpointDescription->SecurityMode != OpcUa_MessageSecurityMode_None)
pUaClientApplication->TrustCertificate(&(pUAEndpointDescription->ServerCertificate));
CSessionClient* pSession=new CSessionClient(pUaClientApplication);
if (pSession)
{
if (pSession->GetInternalServerStatus() != OpcUa_BadInternalError)
{
CEndpointDescription* pEndpointDescription = new CEndpointDescription(pUAEndpointDescription);
uStatus = pSession->Create(pEndpointDescription, &aSessionName, nRequestedClientSessionTimeout);
if (uStatus == OpcUa_Good)
{
pUaClientApplication->AddSessionClient(pSession);
*hSession = (OpcUa_Handle)pSession;
// creation de la thread de surveillance du serveur
pSession->StartWatchingThread();
// creation de la thread de publication
pSession->StartPublishingThread();
}
else
delete pSession;
delete pEndpointDescription;
}
else
{
uStatus=OpcUa_BadInternalError;
delete pSession;
}
}
else
uStatus = OpcUa_BadOutOfMemory;
}
else
uStatus=OpcUa_BadInvalidArgument;
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Get the session params for the session associate with a given handle (hSession). </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 03/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="pSessionParam"> [in,out] If non-null, the session parameter. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetSessionParams(OpcUa_Handle hApplication, OpcUa_Handle hSession, OpenOpcUa_SessionParam* pSessionParam)
{
OpcUa_StatusCode uStatus = OpcUa_BadInternalError;
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetSessionParams\n");
if (pSessionParam)
{
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = OpcUa_Null;// (CSessionClient*)hSession;
uStatus = pUaClientApplication->GetSession(hSession, &pSession);
if ((uStatus == OpcUa_Good) && (pSession))
{
// SessionTimeout
pSessionParam->dblSessionTimeout = pSession->GeSessionTimeout();
// SessionName
OpcUa_CharA* pszTmpString=OpcUa_Null;
OpcUa_String* pSessionName = pSession->GetSessionName();
OpcUa_UInt32 uiLen = OpcUa_String_StrLen(pSessionName);
pszTmpString = OpcUa_String_GetRawString(pSessionName);
pSessionParam->szSessionName = (OpcUa_CharA*)OpcUa_Alloc(uiLen + 1);
ZeroMemory(pSessionParam->szSessionName, uiLen + 1);
memcpy(pSessionParam->szSessionName, pszTmpString, uiLen);
// EndpointDescription
CEndpointDescription* pEndpointDescription=pSession->GetEndpointDescription();
pSessionParam->pEndpoint = Utils::Copy(pEndpointDescription->GetInternalEndPointDescription());
// SessionId
OpcUa_NodeId aNodeId = pSession->GetSessionId();
OpcUa_NodeId_CopyTo(&aNodeId, &(pSessionParam->sessionId));
// UserName
OpcUa_String szUserName = pSession->GetSessionUserName();
uiLen = OpcUa_String_StrLen(&szUserName);
pszTmpString = OpcUa_String_GetRawString(&szUserName);
pSessionParam->szUserName= (OpcUa_CharA*)OpcUa_Alloc(uiLen + 1);
ZeroMemory(pSessionParam->szUserName, uiLen + 1);
memcpy(pSessionParam->szUserName, pszTmpString, uiLen);
// UserTokenType
pSessionParam->userTokenType=pSession->GetUserTokenType();
uStatus = OpcUa_Good;
}
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Close Session. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 03/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_CloseSession(OpcUa_Handle hApplication,OpcUa_Handle hSession)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_CloseSession\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pUaClientApplication->GetTraceConfiguration();
CSessionClient* pSession = OpcUa_Null;// (CSessionClient*)hSession;
uStatus = pUaClientApplication->GetSession(hSession, &pSession);
if ( (uStatus==OpcUa_Good) && (pSession) )
{
if (!pSession->IsWatchingThreadDetectError())
{
// First of all we need to stop the watching thread to avoid side effets
pSession->StopWatchingThread();
//
uStatus = pSession->DeleteAllSubscriptions(OpcUa_True);
if (uStatus != OpcUa_Good)
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_ERROR, "DeleteAllSubscriptions failed 0x%05x\n", uStatus);
else
{
uStatus = pUaClientApplication->RemoveSessionClient(pSession);
}
}
else
{
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_ERROR, "The Watching Thread DetectError detected an error. The session has been closed that way\n");
uStatus = OpcUa_Good;
}
}
}
else
uStatus=OpcUa_BadInvalidArgument;
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Create Subscription. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 03/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="dblPublishingInterval"> [in,out] If non-null, the publishing interval.
/// </param>
/// <param name="uiLifetimeCount"> [in,out] If non-null, number of lifetimes. </param>
/// <param name="uiMaxKeepAliveCount"> [in,out] If non-null, number of maximum keep
/// alives.
/// </param>
/// <param name="uiMaxNotificationsPerPublish"> The maximum notifications per publish. </param>
/// <param name="bPublishingEnabled"> The publishing enabled. </param>
/// <param name="aPriority"> The priority. </param>
/// <param name="hSubscription"> [in,out] If non-null, the subscription. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_CreateSubscription(OpcUa_Handle hApplication,OpcUa_Handle hSession,
OpcUa_Double* dblPublishingInterval, // In/Out param
OpcUa_UInt32* uiLifetimeCount, // In/Out param
OpcUa_UInt32* uiMaxKeepAliveCount,// In/Out param
OpcUa_UInt32 uiMaxNotificationsPerPublish,
OpcUa_Boolean bPublishingEnabled,
OpcUa_Byte aPriority,
OpcUa_Handle* hSubscription)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_ERROR, "Call OpenOpcUa_CreateSubscription\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSessionClient = (CSessionClient*)hSession;
if (pSessionClient)
{
//OpcUa_Mutex_Lock(pSessionClient->m_AutoConnectThreadMutex);
uStatus = pSessionClient->CreateSubscription(dblPublishingInterval,
uiLifetimeCount,
uiMaxKeepAliveCount,
uiMaxNotificationsPerPublish,
bPublishingEnabled,
aPriority, hSubscription);
pSessionClient->SetInternalServerStatus(uStatus);
pSessionClient->SetInternalPublishStatus(uStatus);
//OpcUa_Mutex_Unlock(pSessionClient->m_AutoConnectThreadMutex);
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Delete Subscription. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 03/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="hSubscription"> The subscription. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_DeleteSubscription(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_ERROR, "Call OpenOpcUa_DeleteSubscription\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSessionClient = (CSessionClient*)hSession;
if (pSessionClient)
{
CSubscriptionClient* pSubscriptionClient=(CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
pSubscriptionClient->MarkForDeletion(OpcUa_True);
OpcUa_Mutex_Lock(pSessionClient->m_AutoConnectThreadMutex);
uStatus = pSessionClient->DeleteSubscription(pSubscriptionClient, OpcUa_True);
if (uStatus!=OpcUa_Good)
pSubscriptionClient->MarkForDeletion(OpcUa_False);
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_ERROR, "OpenOpcUa_DeleteSubscription DONE 0x%05x\n",uStatus);
OpcUa_Mutex_Unlock(pSessionClient->m_AutoConnectThreadMutex);
}
else
uStatus=OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Modify Subscription. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="hSubscription"> The subscription. </param>
/// <param name="dblPublishingInterval"> [in,out] If non-null, the publishing interval.
/// </param>
/// <param name="uiLifetimeCount"> [in,out] If non-null, number of lifetimes. </param>
/// <param name="uiMaxKeepAliveCount"> [in,out] If non-null, number of maximum keep
/// alives.
/// </param>
/// <param name="uiMaxNotificationsPerPublish"> The maximum notifications per publish. </param>
/// <param name="aPriority"> The priority. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_ModifySubscription(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_Double* dblPublishingInterval, // In/Out param
OpcUa_UInt32* uiLifetimeCount, // In/Out param
OpcUa_UInt32* uiMaxKeepAliveCount,// In/Out param
OpcUa_UInt32 uiMaxNotificationsPerPublish,
OpcUa_Byte aPriority)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_ModifySubscription\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient=(CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
uStatus=pSubscriptionClient->ModifySubscription(*dblPublishingInterval,*uiLifetimeCount,*uiMaxKeepAliveCount,uiMaxNotificationsPerPublish,aPriority);
}
else
uStatus=OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> retrieve the subscription attached to this monitoredItem. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="hMonitoredItem"> The monitored item. </param>
/// <param name="hSubscription"> [in,out] If non-null, the subscription. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetSubscriptionOfMonitoredItem(OpcUa_Handle hApplication, OpcUa_Handle hSession, OpcUa_Handle hMonitoredItem, OpcUa_Handle* hSubscription)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetSubscriptionOfMonitoredItem\n");
OpcUa_StatusCode uStatus = OpcUa_BadNotFound;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
if (!hSession)
{
// will scan all sessions
CSubscriptionClient* pSubscriptionClient = OpcUa_Null;
uStatus=pUaClientApplication->GetSubscriptionOfMonitoredItem(hMonitoredItem,&pSubscriptionClient);
if (uStatus==OpcUa_Good)
{
(*hSubscription) = (OpcUa_Handle)pSubscriptionClient;
}
}
else
{
// scan just hSession
CSessionClient* pSession = OpcUa_Null;
uStatus = pUaClientApplication->GetSession(hSession, &pSession);
if (uStatus == OpcUa_Good)
{
CSubscriptionClient* pSubscriptionClient = OpcUa_Null;
uStatus=pSession->GetSubscriptionOfMonitoredItem(hMonitoredItem,&pSubscriptionClient);
if (uStatus==OpcUa_Good)
{
(*hSubscription) = (OpcUa_Handle)pSubscriptionClient;
}
}
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Retrieve the subscription params of the given subscription (hSubscription) </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="hSubscription"> The subscription. </param>
/// <param name="pSubscriptionParam"> [in,out] If non-null, the subscription parameter. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetSubscriptionParams(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpenOpcUa_SubscriptionParam* pSubscriptionParam)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetSubscriptionParams\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (pSubscriptionParam)
{
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
pSubscriptionParam->uiSubscriptionId = pSubscriptionClient->GetSubscriptionId();
pSubscriptionParam->bPublishingEnabled = pSubscriptionClient->GetPublishingEnabled();
pSubscriptionParam->dblPublishingInterval = pSubscriptionClient->GetPublishingInterval();
pSubscriptionParam->uiLifetimeCount = pSubscriptionClient->GetLifetimeCount();
pSubscriptionParam->uiMaxKeepAliveCount = pSubscriptionClient->GetMaxKeepAliveCount();
pSubscriptionParam->aPriority = pSubscriptionClient->GetPriority();
pSubscriptionParam->uiMaxNotificationsPerPublish = pSubscriptionClient->GetMaxNotificationsPerPublish();
}
else
uStatus = OpcUa_BadInvalidArgument;
}
else
uStatus = OpcUa_BadInvalidArgument;
}
else
uStatus = OpcUa_BadInvalidArgument;
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA set publishing mode. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="hSubscription"> The subscription. </param>
/// <param name="bPublishMode"> The publish mode. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_SetPublishingMode(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_Boolean bPublishMode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_SetPublishingMode\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient=(CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
uStatus=pSubscriptionClient->SetPublishingMode(bPublishMode);
}
else
uStatus=OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
}
return uStatus;
}
// Create MonitoredItems
OpcUa_StatusCode OpenOpcUa_CreateMonitoredItemsEx( OpcUa_Handle hApplication,// in
OpcUa_Handle hSession, // in
OpcUa_Handle hSubscription,// in
OpcUa_UInt32 NoOfItemsToCreate, // in
OpcUa_MonitoredItemToCreate* pItemsToCreate, // in
OpcUa_MonitoredItemCreated** ppItemsCreated) // out
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_CreateMonitoredItemsEx\n");
OpcUa_StatusCode uStatus = OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
OpcUa_Mutex_Lock(pSession->m_AutoConnectThreadMutex);
if ((pSession->GetSessionState() == SESSION_STATE_ON_ACTIVE) || (pSession->GetSessionState() == SESSION_STATE_SUBSCRIBED))
{
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
if (NoOfItemsToCreate > 0)
{
OpcUa_MonitoredItemCreateRequest* pItemsToCreateRequest = (OpcUa_MonitoredItemCreateRequest*)OpcUa_Alloc(sizeof(OpcUa_MonitoredItemCreateRequest)*NoOfItemsToCreate);
if (pItemsToCreateRequest)
{
//OpcUa_UInt32 uiNoOfMonitoreditem = 0;
//OpcUa_Handle* phMonitoredItem = OpcUa_Null;
ZeroMemory(pItemsToCreateRequest, sizeof(OpcUa_MonitoredItemCreateRequest)*NoOfItemsToCreate);
for (OpcUa_UInt32 i = 0; i < NoOfItemsToCreate; i++)
{
pItemsToCreateRequest[i].ItemToMonitor.AttributeId = pItemsToCreate[i].m_AttributeId;
OpcUa_String_Initialize(&(pItemsToCreateRequest[i].ItemToMonitor.IndexRange));
//if (OpcUa_String_StrLen(&(pItemsToCreate[i].m_IndexRange))>0)
// OpcUa_String_CopyTo(&(pItemsToCreate[i].m_IndexRange), &(pItemsToCreateRequest[i].ItemToMonitor.IndexRange));
OpcUa_NodeId_CopyTo(&(pItemsToCreate[i].m_NodeId), &(pItemsToCreateRequest[i].ItemToMonitor.NodeId));
pItemsToCreateRequest[i].MonitoringMode = pItemsToCreate[i].m_MonitoringMode;
pItemsToCreateRequest[i].RequestedParameters.ClientHandle = pItemsToCreate[i].m_ClientHandle;
pItemsToCreateRequest[i].RequestedParameters.DiscardOldest = pItemsToCreate[i].m_DiscardOldest;
// Filter;
OpcUa_ExtensionObject_Initialize(&(pItemsToCreateRequest[i].RequestedParameters.Filter));
pItemsToCreateRequest[i].RequestedParameters.Filter.TypeId.NodeId.Identifier.Numeric = OpcUaId_DataChangeFilter_Encoding_DefaultBinary;
pItemsToCreateRequest[i].RequestedParameters.Filter.Encoding = OpcUa_ExtensionObjectEncoding_EncodeableObject;
//pItemsToCreateRequest[i].RequestedParameters.Filter.Body.EncodeableObject.Type = (OpcUa_EncodeableType*)OpcUa_Alloc(sizeof(OpcUa_EncodeableType));
pItemsToCreateRequest[i].RequestedParameters.Filter.Body.EncodeableObject.Type = &OpcUa_DataChangeFilter_EncodeableType;
OpcUa_DataChangeFilter* pDataChangeFilter = (OpcUa_DataChangeFilter*)OpcUa_Alloc(sizeof(OpcUa_DataChangeFilter));
if (pDataChangeFilter)
{
OpcUa_DataChangeFilter_Initialize(pDataChangeFilter);
pDataChangeFilter->DeadbandType = pItemsToCreate[i].m_DeadbandType;
pDataChangeFilter->DeadbandValue = pItemsToCreate[i].m_DeadbandValue;
pDataChangeFilter->Trigger = (OpcUa_DataChangeTrigger)pItemsToCreate[i].m_DatachangeTrigger;
pItemsToCreateRequest[i].RequestedParameters.Filter.Body.EncodeableObject.Object = (void*)pDataChangeFilter;
}
pItemsToCreateRequest[i].RequestedParameters.QueueSize = pItemsToCreate[i].m_QueueSize;
pItemsToCreateRequest[i].RequestedParameters.SamplingInterval = pItemsToCreate[i].m_SamplingInterval;
}
OpcUa_TimestampsToReturn sharedTimestampToReturn = pItemsToCreate[0].m_TimestampsToReturn;
OpcUa_MonitoredItemCreateResult* pResult = OpcUa_Null;
OpcUa_UInt32* hMonitoredItems = OpcUa_Null;
// We will subscribe to the requested nodes
uStatus = pSubscriptionClient->CreateMonitoredItems(
(OpcUa_TimestampsToReturn)sharedTimestampToReturn,
NoOfItemsToCreate,
pItemsToCreateRequest,
&pResult,
&hMonitoredItems);
if (uStatus == OpcUa_Good)
{
OpcUa_Int32 iNodNodesToRead = 0;
//OpcUa_DataValue* pResults = OpcUa_Null;
iNodNodesToRead = NoOfItemsToCreate;
//////////////
// Fill the result of the creation
(*ppItemsCreated) = (OpcUa_MonitoredItemCreated*)OpcUa_Alloc(sizeof(OpcUa_MonitoredItemCreated)*NoOfItemsToCreate);
ZeroMemory((*ppItemsCreated), sizeof(OpcUa_MonitoredItemCreated)*NoOfItemsToCreate);
for (OpcUa_UInt32 ii = 0; ii < NoOfItemsToCreate; ii++)
{
(*ppItemsCreated)[ii].m_hMonitoredItem = (OpcUa_Handle)hMonitoredItems[ii];
(*ppItemsCreated)[ii].m_MonitoredItemId = pResult[ii].MonitoredItemId;
(*ppItemsCreated)[ii].m_pRevisedQueueSize = pResult[ii].RevisedQueueSize;
(*ppItemsCreated)[ii].m_Result = pResult[ii].StatusCode;
(*ppItemsCreated)[ii].m_RevisedSamplingInterval = pResult[ii].RevisedSamplingInterval;
OpcUa_MonitoredItemCreateResult_Clear(&pResult[ii]);
}
OpcUa_Free(pResult);
}
else
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_INFO, "OpenOpcUa_CreateMonitoredItemsEx>CSubscriptionClient::CreateMonitoredItems failed:0x%05x\n", uStatus);
// Free filter used
for (OpcUa_UInt32 i = 0; i < NoOfItemsToCreate; i++)
{
OpcUa_DataChangeFilter* pDataChangeFilter = (OpcUa_DataChangeFilter*) pItemsToCreateRequest[i].RequestedParameters.Filter.Body.EncodeableObject.Object;
if (pDataChangeFilter != OpcUa_Null)
{
OpcUa_DataChangeFilter_Clear(pDataChangeFilter);
OpcUa_Free(pDataChangeFilter);
}
}
OpcUa_Free(pItemsToCreateRequest);
OpcUa_Free(hMonitoredItems);
}
else
uStatus = OpcUa_BadOutOfMemory;
}
else
uStatus = OpcUa_BadNothingToDo;
}
else
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_INFO, "OpenOpcUa_CreateMonitoredItemsEx>Critical error. hSubscription is NULL\n");
}
else
{
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_INFO, "OpenOpcUa_CreateMonitoredItemsEx>The session is not in a correct state. %u\n", pSession->GetSessionState());
uStatus = OpcUa_BadInvalidState;
}
OpcUa_Mutex_Unlock(pSession->m_AutoConnectThreadMutex);
}
else
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_INFO, "OpenOpcUa_CreateMonitoredItemsEx>Critical error. hSession is NULL\n");
}
else
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_INFO, "OpenOpcUa_CreateMonitoredItemsEx>Critical error. hApplication is NULL\n");
}
else
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_INFO, "OpenOpcUa_CreateMonitoredItemsEx>Critical error. AbstractionLayer is not initialized\n");
return uStatus;
}
// Create MonitoredItems
OpcUa_StatusCode OpenOpcUa_CreateMonitoredItems(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_Byte aTimestampsToReturn,
OpcUa_UInt32 NoOfItemsToCreate,
OpcUa_MonitoredItemCreateRequest* pItemsToCreate,
OpcUa_MonitoredItemCreateResult** ppResult,
OpcUa_Handle** hMonitoredItems)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_CreateMonitoredItems\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient=(CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
OpcUa_UInt32* puiMonitoredItems = OpcUa_Null; // (OpcUa_UInt32*)OpcUa_Alloc(sizeof(OpcUa_UInt32)*NoOfItemsToCreate);
//ZeroMemory(puiMonitoredItems, sizeof(OpcUa_UInt32)*NoOfItemsToCreate);
// We will subscribe to the requested nodes
uStatus=pSubscriptionClient->CreateMonitoredItems(
(OpcUa_TimestampsToReturn)aTimestampsToReturn,
NoOfItemsToCreate,
pItemsToCreate,
ppResult,
&puiMonitoredItems);
if (uStatus==OpcUa_Good)
{
puiMonitoredItems = (OpcUa_UInt32*)OpcUa_Alloc(sizeof(OpcUa_UInt32)*NoOfItemsToCreate);
ZeroMemory(puiMonitoredItems, sizeof(OpcUa_UInt32)*NoOfItemsToCreate);
OpcUa_Int32 iNodNodesToRead=0;
OpcUa_ReadValueId* pNodesToRead=OpcUa_Null;
OpcUa_DataValue* pResults=OpcUa_Null;
iNodNodesToRead=NoOfItemsToCreate;
pNodesToRead=(OpcUa_ReadValueId*)OpcUa_Alloc(iNodNodesToRead*sizeof(OpcUa_ReadValueId));
// Read BrowseName for all Added Nodes
for (OpcUa_UInt32 ii=0;ii<NoOfItemsToCreate;ii++)
{
OpcUa_ReadValueId_Initialize(&pNodesToRead[ii]);
pNodesToRead[ii].AttributeId=OpcUa_Attributes_BrowseName;
OpcUa_NodeId_CopyTo(&(pItemsToCreate[ii].ItemToMonitor.NodeId), &(pNodesToRead[ii].NodeId));
}
uStatus=OpenOpcUa_ReadAttributes(hApplication,hSession,OpcUa_TimestampsToReturn_Both,iNodNodesToRead,pNodesToRead,&pResults);
if (uStatus==OpcUa_Good)
{
for (OpcUa_UInt32 ii=0;ii<NoOfItemsToCreate;ii++)
{
CMonitoredItemClient* pMonitoredItem = pSubscriptionClient->FindMonitoredItemByHandle((OpcUa_UInt64)puiMonitoredItems[ii]);
if (pMonitoredItem)
{
if (pResults[ii].Value.Value.QualifiedName)
{
(*hMonitoredItems)[ii] = (OpcUa_Handle)puiMonitoredItems[ii];
pMonitoredItem->SetMonitoredItemName(pResults[ii].Value.Value.QualifiedName->Name);
OpcUa_QualifiedName_Clear(pResults[ii].Value.Value.QualifiedName);
}
}
OpcUa_DataValue_Clear(&pResults[ii]);
}
}
for (OpcUa_UInt32 ii = 0; ii < NoOfItemsToCreate; ii++)
{
OpcUa_NodeId_Clear(&(pNodesToRead[ii].NodeId));
}
if (pResults)
{
OpcUa_Free(pResults);
pResults = OpcUa_Null;
}
// Read Value for all Added Nodes
for (OpcUa_UInt32 ii=0;ii<NoOfItemsToCreate;ii++)
{
OpcUa_ReadValueId_Initialize(&pNodesToRead[ii]);
pNodesToRead[ii].AttributeId=OpcUa_Attributes_Value;
OpcUa_NodeId_CopyTo(&(pItemsToCreate[ii].ItemToMonitor.NodeId),&(pNodesToRead[ii].NodeId));
}
uStatus=OpenOpcUa_ReadAttributes(hApplication,hSession,OpcUa_TimestampsToReturn_Both,iNodNodesToRead,pNodesToRead,&pResults);
if (uStatus==OpcUa_Good)
{
for (OpcUa_UInt32 ii=0;ii<NoOfItemsToCreate;ii++)
{
CMonitoredItemClient* pMonitoredItem = pSubscriptionClient->FindMonitoredItemByHandle((OpcUa_UInt64)puiMonitoredItems[ii]);// (CMonitoredItemClient*)(*hMonitoredItems)[ii];
if (pMonitoredItem)
{
pMonitoredItem->SetValue(&pResults[ii]);
}
OpcUa_ReadValueId_Clear(pNodesToRead);
OpcUa_DataValue_Clear(&pResults[ii]);
}
}
if (pResults)
{
OpcUa_Free(pResults);
pResults = OpcUa_Null;
}
for (OpcUa_UInt32 ii = 0; ii < NoOfItemsToCreate; ii++)
{
OpcUa_NodeId_Clear(&(pNodesToRead[ii].NodeId));
}
if (pNodesToRead)
{
OpcUa_Free(pNodesToRead);
pNodesToRead = OpcUa_Null;
}
}
if (puiMonitoredItems)
OpcUa_Free(puiMonitoredItems);
}
}
}
}
return uStatus;
}
// Delete MonitoredItems
OpcUa_StatusCode OpenOpcUa_DeleteMonitoredItems(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_Int32 iNoOfMonitoredItem,
OpcUa_Handle* hMonitoredItems,
OpcUa_StatusCode** ppStatusCode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_DeleteMonitoredItems\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
// let's prepare the list of monitoredItem to delete
OpcUa_Mutex monitoredItemListMutex = pSubscriptionClient->GetMonitoredItemListMutex();
OpcUa_Mutex_Lock(monitoredItemListMutex);
CMonitoredItemClientList* pMonitoredItemList = new CMonitoredItemClientList();
for (OpcUa_Int32 i = 0; i < iNoOfMonitoredItem; i++)
{
CMonitoredItemClient* pMonitoredItem = pSubscriptionClient->FindMonitoredItemByHandle((OpcUa_UInt64)hMonitoredItems[i]);
if (pMonitoredItem)
pMonitoredItemList->push_back(pMonitoredItem);
}
OpcUa_Mutex_Unlock(monitoredItemListMutex);
// Now lets inform the server that we want to delete it
if (iNoOfMonitoredItem > 0)
uStatus=pSubscriptionClient->DeleteMonitoredItems(pMonitoredItemList,OpcUa_True);
else
uStatus = OpcUa_BadInvalidArgument;
delete pMonitoredItemList;
}
}
else
uStatus = OpcUa_BadInvalidArgument;
}
else
uStatus = OpcUa_BadInvalidArgument;
}
return uStatus;
}
// Modify MonitoredItems All parameter are input parameters
OpcUa_StatusCode OpenOpcUa_ModifyMonitoredItems(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_Handle hMonitoredItem,
OpcUa_Byte aTimestampsToReturn,
OpcUa_Boolean bDiscardOldest,
OpcUa_UInt32 uiQueueSize,
OpcUa_Double dblSamplingInterval,
OpcUa_UInt32 DeadbandType,
OpcUa_Double DeadbandValue,
OpcUa_Byte DatachangeTrigger)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_ModifyMonitoredItems\n");
OpcUa_StatusCode uStatus = OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
uStatus = pSubscriptionClient->ModifyMonitoredItems(hMonitoredItem,aTimestampsToReturn,bDiscardOldest,uiQueueSize,dblSamplingInterval,DeadbandType,DeadbandValue,DatachangeTrigger);
}
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> SetMonitoringMode. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="hSubscription"> The subscription. </param>
/// <param name="iNoOfMonitoredItem"> Zero-based index of the no of monitored item. </param>
/// <param name="hMonitoredItems"> [in,out] If non-null, the monitored items. </param>
/// <param name="eMonitoringMode"> The monitoring mode. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_SetMonitoringMode(OpcUa_Handle hApplication, OpcUa_Handle hSession, OpcUa_Handle hSubscription,
OpcUa_Int32 iNoOfMonitoredItem,
OpcUa_Handle* hMonitoredItems,
OpcUa_MonitoringMode eMonitoringMode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_SetMonitoringMode\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (hMonitoredItems)
{
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
pSubscriptionClient->SetDefaultMonitoringMode(eMonitoringMode);
if (iNoOfMonitoredItem > 0)
uStatus = pSubscriptionClient->SetMonitoringMode(eMonitoringMode, iNoOfMonitoredItem, (OpcUa_UInt32*)hMonitoredItems);
else
uStatus = OpcUa_Good;
}
}
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Read Attributes. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="eTimestampsToReturn"> The timestamps to return. </param>
/// <param name="iNoOfNodesToRead"> Zero-based index of the no of nodes to read. </param>
/// <param name="pNodesToRead"> [in,out] If non-null, the nodes to read. </param>
/// <param name="ppResults"> [in,out] If non-null, the results. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_ReadAttributes( OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_TimestampsToReturn eTimestampsToReturn,
OpcUa_Int32 iNoOfNodesToRead,
OpcUa_ReadValueId* pNodesToRead,
OpcUa_DataValue** ppResults)
{
//CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
//OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
//OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_ReadAttributes\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
OpcUa_ReadValueIdList aReadValueIdList;
OpcUa_DataValueList Results;
OpcUa_DataValueList::iterator iteratorResult;
// on demande les attributs que l'on souhaite lire
for (int ii = 0;ii<iNoOfNodesToRead;ii++)
{
aReadValueIdList.push_back(&pNodesToRead[ii]);
}
uStatus=pSession->Read(aReadValueIdList,eTimestampsToReturn,&Results);
if (uStatus==OpcUa_Good)
{
OpcUa_UInt32 iii=0;
OpcUa_UInt32 iSizeResult = Results.size();
if (iSizeResult > 0)
{
(*ppResults) = (OpcUa_DataValue*)OpcUa_Alloc(iSizeResult*sizeof(OpcUa_DataValue));
if ((*ppResults))
{
for (OpcUa_UInt32 ij = 0; ij < Results.size(); ij++)
{
OpcUa_DataValue_Initialize(&((*ppResults)[iii]));
OpcUa_DataValue* pDataValue = Results.at(ij);
(*ppResults)[iii].ServerPicoseconds = pDataValue->ServerPicoseconds;
(*ppResults)[iii].ServerTimestamp = pDataValue->ServerTimestamp;
(*ppResults)[iii].SourcePicoseconds = pDataValue->SourcePicoseconds;
(*ppResults)[iii].SourceTimestamp = pDataValue->SourceTimestamp;
(*ppResults)[iii].StatusCode = pDataValue->StatusCode;
if (pDataValue->StatusCode == OpcUa_Good)
OpcUa_Variant_CopyTo(&(pDataValue->Value), &((*ppResults)[iii].Value));
else
{
(*ppResults)[iii].Value.ArrayType = pDataValue->Value.ArrayType;
(*ppResults)[iii].Value.Datatype = pDataValue->Value.Datatype;
}
iii++;
OpcUa_DataValue_Clear(pDataValue);
OpcUa_Free(pDataValue);
pDataValue = OpcUa_Null;
}
Results.clear();
}
}
else
uStatus = OpcUa_BadNothingToDo;
}
aReadValueIdList.clear();
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Write Attributes. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="iNoOfNodesToWrite"> Zero-based index of the no of nodes to write. </param>
/// <param name="pNodesToWrite"> [in,out] If non-null, the nodes to write. </param>
/// <param name="ppStatusCode"> [in,out] If non-null, the status code. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_WriteAttributes(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Int32 iNoOfNodesToWrite,
OpcUa_WriteValue* pNodesToWrite,
OpcUa_StatusCode** ppStatusCode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_WriteAttributes\n");
OpcUa_StatusCode uStatus=OpcUa_Good;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
uStatus = pSession->Write(iNoOfNodesToWrite, pNodesToWrite, ppStatusCode);
}
}
}
return uStatus;
}
OpcUa_StatusCode HistoryReadCallback(
OpcUa_Channel hChannel,
OpcUa_Void* pResponse,
OpcUa_EncodeableType* pResponseType,
OpcUa_Void* pCallbackData,
OpcUa_StatusCode StatusCode)
{
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA history read raw. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="bModified"> The modified. </param>
/// <param name="eTimestampsToReturn"> The timestamps to return. </param>
/// <param name="iNoOfNodesToRead"> Zero-based index of the no of nodes to read. </param>
/// <param name="pNodesToRead"> [in,out] If non-null, the nodes to read. </param>
/// <param name="ipNoOfResults"> [in,out] If non-null, the IP no of results. </param>
/// <param name="ppHistoryResults"> [in,out] If non-null, the history results. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_HistoryReadRaw(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Boolean bModified,
OpcUa_TimestampsToReturn eTimestampsToReturn,
OpcUa_Int32 iNoOfNodesToRead,
OpenOpcUa_HistoryReadValueId* pNodesToRead,
OpcUa_Int32* ipNoOfResults,
OpenOpcUa_HistoryReadResult** ppHistoryResults)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_HistoryReadRaw\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
OpcUa_RequestHeader tRequestHeader;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
OpcUa_RequestHeader_Initialize(&tRequestHeader);
tRequestHeader.TimeoutHint = g_ServiceCallTimeout;// UTILS_DEFAULT_TIMEOUT;
tRequestHeader.Timestamp = OpcUa_DateTime_UtcNow();
tRequestHeader.AuthenticationToken.IdentifierType = OpcUa_IdentifierType_Numeric;
tRequestHeader.AuthenticationToken.NamespaceIndex = 0;
OpcUa_NodeId_CopyTo(pSession->GetAuthenticationToken(), &(tRequestHeader.AuthenticationToken));
tRequestHeader.RequestHandle = CClientApplication::m_uiRequestHandle++;
// Let's make the asynchronous call
CChannel* pChannel = pSession->GetChannel();
OpcUa_Channel aChannel = pChannel->GetInternalHandle();
OpcUa_ExtensionObject* pHistoryReadDetails=OpcUa_Null;
OpcUa_Boolean bReleaseContinuationPoints = OpcUa_False;
OpcUa_HistoryReadValueId* pHistoryReadValueId;
void* pCallbackData = OpcUa_Null;
if (iNoOfNodesToRead > 0)
{
pHistoryReadValueId = (OpcUa_HistoryReadValueId*)OpcUa_Alloc(sizeof(OpcUa_HistoryReadValueId)*iNoOfNodesToRead);
if (pHistoryReadValueId)
{
uStatus=OpcUa_ClientApi_BeginHistoryRead(aChannel,
&tRequestHeader,
pHistoryReadDetails,
eTimestampsToReturn,
bReleaseContinuationPoints,
iNoOfNodesToRead,
pHistoryReadValueId,
(OpcUa_Channel_PfnRequestComplete*)&HistoryReadCallback,
pCallbackData);
}
}
else
uStatus = OpcUa_BadInvalidArgument;
}
}
}
return uStatus;
}
// Call
OpcUa_StatusCode OpenOpcUa_Call(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Int32 iNoOfMethodsToCall,
OpcUa_CallMethodRequest* pMethodsToCall,
OpcUa_CallMethodResult** ppResults)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_Call\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
OpcUa_RequestHeader tRequestHeader;
OpcUa_ResponseHeader* pResponseHeader = (OpcUa_ResponseHeader*)OpcUa_Alloc(sizeof(OpcUa_ResponseHeader));
OpcUa_ResponseHeader_Initialize(pResponseHeader);
OpcUa_Int32 nNoOfDiagnosticInfos = 0;
OpcUa_DiagnosticInfo* pDiagnosticInfos = OpcUa_Null;
OpcUa_DiagnosticInfo_Initialize(pDiagnosticInfos);
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
OpcUa_Int32 iNoOfResults=0;
OpcUa_RequestHeader_Initialize(&tRequestHeader);
tRequestHeader.TimeoutHint = g_ServiceCallTimeout;// UTILS_DEFAULT_TIMEOUT;
tRequestHeader.Timestamp = OpcUa_DateTime_UtcNow();
OpcUa_NodeId* pNodeId = pSession->GetAuthenticationToken();
OpcUa_NodeId_CopyTo(pNodeId, &(tRequestHeader.AuthenticationToken));
tRequestHeader.RequestHandle = CClientApplication::m_uiRequestHandle++;
// Let's make the asynchronous call
CChannel* pChannel = pSession->GetChannel();
if (pChannel)
{
//OpcUa_CallMethodResult_Initialize(*ppResults);
OpcUa_Channel aChannel = pChannel->GetInternalHandle();
uStatus = OpcUa_ClientApi_Call(
aChannel,
&tRequestHeader,
iNoOfMethodsToCall,
pMethodsToCall,
pResponseHeader,
&iNoOfResults,
ppResults,
&nNoOfDiagnosticInfos,
&pDiagnosticInfos);
}
}
}
}
OpcUa_Free(pResponseHeader);
return uStatus;
}
// Recupère la session a laquelle appartient cette souscription
OpcUa_StatusCode OpenOpcUa_GetSessionOfSubscription(OpcUa_Handle hSubscription,OpcUa_Handle* hSession)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetSessionOfSubscription\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
OpenOpcUa_HandleType aHandleType;
uStatus=OpenOpcUa_WhatIsIt(hSubscription,&aHandleType);
if (aHandleType==OPENOPCUA_SUBSCRIPTION)
{
CSubscriptionClient* pSubscriptionClient=(CSubscriptionClient*)hSubscription;
CSessionClient *pSession=pSubscriptionClient->GetSession();
if (pSession)
*hSession=(OpcUa_Handle)pSession;
}
else
{
*hSession=OpcUa_Null;
uStatus=OpcUa_BadInvalidArgument;
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Called tby the client application to set the Callback functions.
/// </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="hSubscription"> The subscription. </param>
/// <param name="lpCallback"> The callback. </param>
/// <param name="pCallbackData"> [in,out] If non-null, information describing the callback.
/// </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_SetPublishCallback(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
PFUNC lpCallback,
void* pCallbackData)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_SetPublishCallback\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient=(CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
pSubscriptionClient->SetNotificationCallback(lpCallback);
pSubscriptionClient->SetNotificationCallbackData(pCallbackData);
uStatus=OpcUa_Good;
}
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Callback, called when the open opc UA set shutdown. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="lpCallback"> The callback. </param>
/// <param name="pCallbackData"> [in,out] If non-null, information describing the callback.
/// </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_SetShutdownCallback(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
PFUNCSHUTDOWN lpCallback, void* pCallbackData)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_SetShutdownCallback\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
pSession->SetShutdownCallback(lpCallback);
pSession->SetShutdownCallbackData(pCallbackData);
uStatus=OpcUa_Good;
}
}
}
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_ReleaseInternalNode(OpenOpcUa_InternalNode* pInternalNode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_ReleaseInternalNode\n");
OpcUa_StatusCode uStatus=OpcUa_Good;
if (pInternalNode)
{
OpcUa_NodeId_Clear(&(pInternalNode->m_NodeId));
OpcUa_String_Clear(&(pInternalNode->m_BrowseName));
OpcUa_DataValue_Clear(&(pInternalNode->m_DataValue));
OpcUa_DataValue_Clear(&(pInternalNode->m_DataValue));
pInternalNode->m_hMonitoredItem=OpcUa_Null;
if (pInternalNode->m_pMonitoredItemParam)
OpcUa_Free(pInternalNode->m_pMonitoredItemParam);
OpcUa_Free(pInternalNode);
}
else
uStatus=OpcUa_BadInvalidArgument;
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_GetInternalNodeByMonitoredItemId(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_UInt32 MonitoredItemId,
OpenOpcUa_InternalNode** pInternalNode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetInternalNodeByMonitoredItemId\n");
OpcUa_StatusCode uStatus = OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
// pSession->FindSubscription(hSubscription,&pSubscriptionClient); This call can also works
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
CMonitoredItemClient* pMonitoredItemClient =pSubscriptionClient->FindMonitoredItemById(MonitoredItemId);
if (pMonitoredItemClient)
{
(*pInternalNode) = (OpenOpcUa_InternalNode*)OpcUa_Alloc(sizeof(OpenOpcUa_InternalNode));
if (*pInternalNode)
{
// NodeId
OpcUa_NodeId_Initialize(&((*pInternalNode)->m_NodeId));
OpcUa_NodeId aNodeId = pMonitoredItemClient->GetNodeId();
OpcUa_NodeId_CopyTo(&aNodeId, &((*pInternalNode)->m_NodeId));
// BrowseName
OpcUa_String_Initialize(&((*pInternalNode)->m_BrowseName));
OpcUa_String* pString = pMonitoredItemClient->GetMonitoredItemName();
if (OpcUa_String_StrLen(pString)>0)
{
OpcUa_String_CopyTo(pString, &((*pInternalNode)->m_BrowseName));
}
// DataValue
OpcUa_DataValue_Initialize(&((*pInternalNode)->m_DataValue));
OpcUa_DataValue* pDataValue = pMonitoredItemClient->GetValue();
OpcUa_DataValue_CopyTo(pDataValue, &((*pInternalNode)->m_DataValue));
// OpcUa_Handle
(*pInternalNode)->m_hMonitoredItem = (OpcUa_Handle)pMonitoredItemClient->GetClientHandle();
// Let's fill the OpenOpcUa_MonitoredItemParam* but first we need to allocate it
(*pInternalNode)->m_pMonitoredItemParam = (OpenOpcUa_MonitoredItemParam*)OpcUa_Alloc(sizeof(OpenOpcUa_MonitoredItemParam));
if ((*pInternalNode)->m_pMonitoredItemParam)
{
// TimestampsToReturn
(*pInternalNode)->m_pMonitoredItemParam->m_aTimestampsToReturn = (OpcUa_Byte)pMonitoredItemClient->GetTimestampsToReturn();
// DiscardOldest
(*pInternalNode)->m_pMonitoredItemParam->m_bDiscardOldest = pMonitoredItemClient->IsDiscardOldest();
// SamplingInterval
(*pInternalNode)->m_pMonitoredItemParam->m_dblSamplingInterval = pMonitoredItemClient->GetSamplingInterval();
// Deadband
OpcUa_ExtensionObject* pExtensionObject = pMonitoredItemClient->GetFilterToUse();
if (pExtensionObject)
{
// Deadband Default value.
(*pInternalNode)->m_pMonitoredItemParam->m_DeadbandType = OpcUa_DeadbandType_None;
(*pInternalNode)->m_pMonitoredItemParam->m_dblDeadbandValue = 0;
(*pInternalNode)->m_pMonitoredItemParam->m_DataChangeTrigger = OpcUa_DataChangeTrigger_StatusValueTimestamp;
if (pExtensionObject->Body.EncodeableObject.Type)
{
if (pExtensionObject->Body.EncodeableObject.Type->TypeId == OpcUaId_DataChangeFilter)
{
OpcUa_DataChangeFilter* pDataChangeFilter =
(OpcUa_DataChangeFilter*)pExtensionObject->Body.EncodeableObject.Object;
if (pDataChangeFilter)
{
(*pInternalNode)->m_pMonitoredItemParam->m_DeadbandType = pDataChangeFilter->DeadbandType;
(*pInternalNode)->m_pMonitoredItemParam->m_dblDeadbandValue = pDataChangeFilter->DeadbandValue;
(*pInternalNode)->m_pMonitoredItemParam->m_DataChangeTrigger = pDataChangeFilter->Trigger;
}
}
}
}
// QueueSize
(*pInternalNode)->m_pMonitoredItemParam->m_uiQueueSize = pMonitoredItemClient->GetQueueSize();
uStatus = OpcUa_Good;
}
else
uStatus = OpcUa_BadOutOfMemory;
}
else
uStatus = OpcUa_BadOutOfMemory;
}
}
}
}
}
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_GetInternalNodeByClientHandle(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_UInt32 ClientHandle,
OpenOpcUa_InternalNode** pInternalNode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetInternalNodeByClientHandle\n");
OpcUa_StatusCode uStatus = OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
// pSession->FindSubscription(hSubscription,&pSubscriptionClient); This call can also works
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
CMonitoredItemClient* pMonitoredItemClient = pSubscriptionClient->FindMonitoredItemByHandle((OpcUa_UInt64)ClientHandle);
if (pMonitoredItemClient)
{
*pInternalNode = (OpenOpcUa_InternalNode*)OpcUa_Alloc(sizeof(OpenOpcUa_InternalNode));
if (*pInternalNode)
{
// NodeId
OpcUa_NodeId_Initialize(&((*pInternalNode)->m_NodeId));
OpcUa_NodeId aNodeId = pMonitoredItemClient->GetNodeId();
OpcUa_NodeId_CopyTo(&aNodeId, &((*pInternalNode)->m_NodeId));
// BrowseName
OpcUa_String_Initialize(&((*pInternalNode)->m_BrowseName));
OpcUa_String* pString = pMonitoredItemClient->GetMonitoredItemName();
if (OpcUa_String_StrLen(pString)>0)
{
OpcUa_String_CopyTo(pString, &((*pInternalNode)->m_BrowseName));
}
// DataValue
OpcUa_DataValue_Initialize(&((*pInternalNode)->m_DataValue));
OpcUa_DataValue* pDataValue = pMonitoredItemClient->GetValue();
(*pInternalNode)->m_DataValue = *Utils::Copy(pDataValue);
// OpcUa_Handle
(*pInternalNode)->m_hMonitoredItem = (OpcUa_Handle)pMonitoredItemClient->GetClientHandle();
// Let's fill the OpenOpcUa_MonitoredItemParam* but first we need to allocate it
(*pInternalNode)->m_pMonitoredItemParam = (OpenOpcUa_MonitoredItemParam*)OpcUa_Alloc(sizeof(OpenOpcUa_MonitoredItemParam));
if ((*pInternalNode)->m_pMonitoredItemParam)
{
// TimestampsToReturn
(*pInternalNode)->m_pMonitoredItemParam->m_aTimestampsToReturn = (OpcUa_Byte)pMonitoredItemClient->GetTimestampsToReturn();
// DiscardOldest
(*pInternalNode)->m_pMonitoredItemParam->m_bDiscardOldest = pMonitoredItemClient->IsDiscardOldest();
// SamplingInterval
(*pInternalNode)->m_pMonitoredItemParam->m_dblSamplingInterval = pMonitoredItemClient->GetSamplingInterval();
// Deadband
OpcUa_ExtensionObject* pExtensionObject = pMonitoredItemClient->GetFilterToUse();
if (pExtensionObject)
{
// Deadband Default value.
(*pInternalNode)->m_pMonitoredItemParam->m_DeadbandType = OpcUa_DeadbandType_None;
(*pInternalNode)->m_pMonitoredItemParam->m_dblDeadbandValue = 0;
(*pInternalNode)->m_pMonitoredItemParam->m_DataChangeTrigger = OpcUa_DataChangeTrigger_StatusValueTimestamp;
if (pExtensionObject->Body.EncodeableObject.Type)
{
if (pExtensionObject->Body.EncodeableObject.Type->TypeId == OpcUaId_DataChangeFilter)
{
OpcUa_DataChangeFilter* pDataChangeFilter =
(OpcUa_DataChangeFilter*)pExtensionObject->Body.EncodeableObject.Object;
if (pDataChangeFilter)
{
(*pInternalNode)->m_pMonitoredItemParam->m_DeadbandType = pDataChangeFilter->DeadbandType;
(*pInternalNode)->m_pMonitoredItemParam->m_dblDeadbandValue = pDataChangeFilter->DeadbandValue;
(*pInternalNode)->m_pMonitoredItemParam->m_DataChangeTrigger = pDataChangeFilter->Trigger;
}
}
}
}
// QueueSize
(*pInternalNode)->m_pMonitoredItemParam->m_uiQueueSize = pMonitoredItemClient->GetQueueSize();
uStatus = OpcUa_Good;
}
else
uStatus = OpcUa_BadOutOfMemory;
}
else
uStatus = OpcUa_BadOutOfMemory;
}
}
}
}
}
return uStatus;
}
/// <summary>
/// Opens the opc ua_ get internal node.
/// </summary>
/// <param name="hApplication">The h application.</param>
/// <param name="hSession">The h session.</param>
/// <param name="hSubscription">The h subscription.</param>
/// <param name="hMonitoredItem">The h monitored item.</param>
/// <param name="pInternalNode">The p internal node.</param>
/// <returns></returns>
OpcUa_StatusCode OpenOpcUa_GetInternalNode(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_Handle hMonitoredItem,
OpenOpcUa_InternalNode** pInternalNode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetInternalNode\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
// pSession->FindSubscription(hSubscription,&pSubscriptionClient); This call can also works
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
CMonitoredItemClient* pMonitoredItemClient = pSubscriptionClient->FindMonitoredItemByHandle((OpcUa_UInt64)hMonitoredItem);
if (pMonitoredItemClient)
{
*pInternalNode=( OpenOpcUa_InternalNode*)OpcUa_Alloc(sizeof(OpenOpcUa_InternalNode));
if (*pInternalNode)
{
// NodeId
OpcUa_NodeId_Initialize(&((*pInternalNode)->m_NodeId));
OpcUa_NodeId aNodeId = pMonitoredItemClient->GetNodeId();
OpcUa_NodeId_CopyTo(&aNodeId,&((*pInternalNode)->m_NodeId));
// BrowseName
OpcUa_String_Initialize(&((*pInternalNode)->m_BrowseName));
OpcUa_String* pString=pMonitoredItemClient->GetMonitoredItemName();
if (OpcUa_String_StrLen(pString)>0)
{
OpcUa_String_CopyTo(pString, &((*pInternalNode)->m_BrowseName));
}
// DataValue
OpcUa_DataValue_Initialize(&((*pInternalNode)->m_DataValue));
OpcUa_DataValue* pDataValue=pMonitoredItemClient->GetValue();
//(*pInternalNode)->m_DataValue=*Utils::Copy(pDataValue);
OpcUa_DataValue_CopyTo(pDataValue, &((*pInternalNode)->m_DataValue));
// OpcUa_Handle
(*pInternalNode)->m_hMonitoredItem = (OpcUa_Handle)pMonitoredItemClient->GetClientHandle();
// Let's fill the OpenOpcUa_MonitoredItemParam* but first we need to allocate it
(*pInternalNode)->m_pMonitoredItemParam=(OpenOpcUa_MonitoredItemParam*)OpcUa_Alloc(sizeof(OpenOpcUa_MonitoredItemParam));
if ((*pInternalNode)->m_pMonitoredItemParam)
{
// TimestampsToReturn
(*pInternalNode)->m_pMonitoredItemParam->m_aTimestampsToReturn = (OpcUa_Byte)pMonitoredItemClient->GetTimestampsToReturn();
// DiscardOldest
(*pInternalNode)->m_pMonitoredItemParam->m_bDiscardOldest = pMonitoredItemClient->IsDiscardOldest();
// SamplingInterval
(*pInternalNode)->m_pMonitoredItemParam->m_dblSamplingInterval = pMonitoredItemClient->GetSamplingInterval();
// Deadband
OpcUa_ExtensionObject* pExtensionObject = pMonitoredItemClient->GetFilterToUse();
{
// Deadband Default value.
(*pInternalNode)->m_pMonitoredItemParam->m_DeadbandType = OpcUa_DeadbandType_None;
(*pInternalNode)->m_pMonitoredItemParam->m_dblDeadbandValue = 0;
(*pInternalNode)->m_pMonitoredItemParam->m_DataChangeTrigger = OpcUa_DataChangeTrigger_StatusValueTimestamp;
if (pExtensionObject->Body.EncodeableObject.Type)
{
if (pExtensionObject->Body.EncodeableObject.Type->TypeId == OpcUaId_DataChangeFilter)
{
OpcUa_DataChangeFilter* pDataChangeFilter =
(OpcUa_DataChangeFilter*)pExtensionObject->Body.EncodeableObject.Object;
if (pDataChangeFilter)
{
(*pInternalNode)->m_pMonitoredItemParam->m_DeadbandType = pDataChangeFilter->DeadbandType;
(*pInternalNode)->m_pMonitoredItemParam->m_dblDeadbandValue = pDataChangeFilter->DeadbandValue;
(*pInternalNode)->m_pMonitoredItemParam->m_DataChangeTrigger = pDataChangeFilter->Trigger;
}
}
}
}
// QueueSize
(*pInternalNode)->m_pMonitoredItemParam->m_uiQueueSize = pMonitoredItemClient->GetQueueSize();
uStatus = OpcUa_Good;
}
else
uStatus=OpcUa_BadOutOfMemory;
}
else
uStatus=OpcUa_BadOutOfMemory;
}
}
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA what is iterator. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hHandle"> The handle. </param>
/// <param name="aHandleType"> [in,out] If non-null, type of the handle. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_WhatIsIt(OpcUa_Handle hHandle, OpenOpcUa_HandleType* aHandleType)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_WhatIsIt\n");
OpcUa_StatusCode uStatus=OpcUa_BadInvalidArgument;
*aHandleType=OPENOPCUA_UNKNOWN;
if (hHandle)
{
// Check s'il s'agit d'une Application
for (OpcUa_UInt32 ii=0;ii<g_pUaClientApplicationList.size();ii++)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(ii);
if (pApplication==(CClientApplication*)hHandle)
{
*aHandleType=OPENOPCUA_APPLICATION;
uStatus=OpcUa_Good;
break;
}
}
if (uStatus!=OpcUa_Good)
{
// check s'il s'agit d'une session
for (OpcUa_UInt32 ii=0;ii<g_pUaClientApplicationList.size();ii++)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(ii);
CSessionClient* pSession=OpcUa_Null;
uStatus=pApplication->GetSession(hHandle,&pSession);
if (uStatus==OpcUa_Good)
{
*aHandleType=OPENOPCUA_SESSION;
break;
}
}
if (uStatus!=OpcUa_Good)
{
// check s'il s'agit d'une souscription
for (OpcUa_UInt32 ii=0;ii<g_pUaClientApplicationList.size();ii++)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(ii);
CSubscriptionClient* pSubscription=OpcUa_Null;
uStatus=pApplication->GetSubscription(hHandle,&pSubscription);
if (uStatus==OpcUa_Good)
{
*aHandleType=OPENOPCUA_SUBSCRIPTION;
break;
}
}
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Transform a Variant in a String.
/// </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 15/01/2017. </remarks>
///
/// <param name="Var"> [in,out] The variable. </param>
/// <param name="strValue"> [in,out] If non-null, the value. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_VariantToString(OpcUa_Handle hApplication, OpcUa_Handle hSession, OpcUa_Variant Var, OpcUa_String** strValue)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_VariantToString\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (strValue)
{
//OpcUa_ByteString byteString; // This is the base64 Encoded DataTypedictionnary
//OpcUa_ByteString_Initialize(&byteString);
if (Var.Datatype == OpcUaType_ExtensionObject)
{
if (Var.ArrayType==OpcUa_VariantArrayType_Scalar)
uStatus=OpenOpcUa_ExtensionObjectToString(hApplication, hSession,Var.Value.ExtensionObject, strValue);
else
{
if (Var.ArrayType == OpcUa_VariantArrayType_Array)
{
if (Var.Value.Array.Length == 0)
OpcUa_String_AttachCopy((*strValue), "Empty ExtensionObject");
for (OpcUa_Int32 i = 0 ; i < Var.Value.Array.Length; i++)
{
uStatus = OpenOpcUa_ExtensionObjectToString(hApplication, hSession, /*byteString,*/ &Var.Value.Array.Value.ExtensionObjectArray[i], strValue);
}
}
else
uStatus = OpcUa_BadNotImplemented;
}
}
else
uStatus=Utils::OpcUaVariantToString(Var,strValue);
}
else
uStatus=OpcUa_BadInvalidArgument;
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_DateTimeToString(OpcUa_DateTime aDateTime,OpcUa_String** strTime)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_DateTimeToString\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
uStatus=Utils::OpcUaDateTimeToString(aDateTime,strTime);
return uStatus;
}
// Transforme un chaine en nodeId.
// pour que la transformation fonctionne la chaine doit avoir la forme ns=x;i=yyy ou ns=x;s=zzz
OpcUa_StatusCode OpenOpcUa_StringToNodeId(OpcUa_String strNodeId,OpcUa_NodeId* pNodeId)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
//OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_StringToNodeId\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (!pNodeId)
uStatus=OpcUa_BadInvalidArgument;
else
{
OpcUa_NodeId_Initialize(pNodeId);
OpcUa_UInt32 iNs=0,iId=0;
char* pBuff=OpcUa_String_GetRawString(&strNodeId);
if (pBuff)
{
int iRes = sscanf(pBuff, "ns=%u;i=%u", (unsigned int*)&iNs, (unsigned int*)&iId);
if (iRes == 2)
{
pNodeId->IdentifierType = OpcUa_IdentifierType_Numeric;
pNodeId->NamespaceIndex = (OpcUa_UInt16)iNs;
pNodeId->Identifier.Numeric = iId;
uStatus = OpcUa_Good;
}
else
{
if (iRes == 1)
{
// probably another format
OpcUa_CharA* strId = (OpcUa_CharA*)OpcUa_Alloc(256);
if (strId)
{
char* ptr = strchr(pBuff, ';');
if (ptr)
{
//char* subStr = strchr(ptr, '=');
ZeroMemory(strId, 256);
int iRes = sscanf(pBuff, "ns=%u;s=%255s", (unsigned int*)&iNs, strId);
if (iRes == 2)
{
pNodeId->IdentifierType = OpcUa_IdentifierType_String;
pNodeId->NamespaceIndex = (OpcUa_UInt16)iNs;
uStatus = OpcUa_String_AttachCopy(&(pNodeId->Identifier.String), strId); //++subStr
}
else
{
iRes = sscanf(pBuff, "ns=%u;g=%255s", (unsigned int*)&iNs, strId);
if (iRes == 2)
{
pNodeId->Identifier.Guid = (OpcUa_Guid*)OpcUa_Alloc(sizeof(OpcUa_Guid));
if (pNodeId->Identifier.Guid)
{
pNodeId->IdentifierType = OpcUa_IdentifierType_Guid;
pNodeId->NamespaceIndex = (OpcUa_UInt16)iNs;
uStatus = OpcUa_Guid_FromString(strId, pNodeId->Identifier.Guid);
}
}
else
{
OpcUa_CharA* bstrId = (OpcUa_CharA*)OpcUa_Alloc(1024);
if (bstrId)
{
iRes = sscanf(pBuff, "ns=%u;b=%1023s", (unsigned int*)&iNs, bstrId);
if (iRes == 2)
{
pNodeId->IdentifierType = OpcUa_IdentifierType_Opaque;
pNodeId->NamespaceIndex = (OpcUa_UInt16)iNs;
OpcUa_ByteString_Initialize(&pNodeId->Identifier.ByteString);
uStatus = OpcUa_Base64_Decode(bstrId, &pNodeId->Identifier.ByteString.Length, &pNodeId->Identifier.ByteString.Data);
}
else
uStatus = OpcUa_BadInvalidArgument;
OpcUa_Free(bstrId);
}
}
}
}
else
OpcUa_Trace(pTraceConfiguration, OPCUA_TRACE_CLIENT_LEVEL_ERROR, "Error>OpenOpcUa_StringToNodeId was called with an inconsistent string: %s\n", OpcUa_String_GetRawString(&strNodeId));
OpcUa_Free(strId);
}
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Transform a NodeId in its string representation according the the UA Spec rules.
/// </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="aNodeId"> Identifier for the node. </param>
/// <param name="strNodeId"> [in,out] If non-null, identifier for the node. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_NodeIdToString(OpcUa_NodeId aNodeId,OpcUa_String* strNodeId)
{
//CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
//OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
//OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_NodeIdToString\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (strNodeId)
{
switch (aNodeId.IdentifierType)
{
case OpcUa_IdentifierType_Numeric: // Numeric
{
char* buffer=(char*)malloc(20);
if (buffer)
{
memset(buffer, 0, 20);
sprintf(buffer, "ns=%u;i=%u", aNodeId.NamespaceIndex, (unsigned int)aNodeId.Identifier.Numeric);
OpcUa_String_AttachCopy(strNodeId, buffer);
uStatus = OpcUa_Good;
memset(buffer, 0, 20);
free(buffer);
}
else
uStatus = OpcUa_BadOutOfMemory;
}
break;
case OpcUa_IdentifierType_String: // string
{
char* buffer=(char*)malloc(512);
if (buffer)
{
ZeroMemory(buffer, 512);
sprintf(buffer, "ns=%u;s=%s", aNodeId.NamespaceIndex, OpcUa_String_GetRawString(&(aNodeId.Identifier.String)));
OpcUa_String_AttachCopy(strNodeId, buffer);
uStatus = OpcUa_Good;
ZeroMemory(buffer, 512);
free(buffer);
}
else
uStatus = OpcUa_BadOutOfMemory;
}
break;
case OpcUa_IdentifierType_Guid: // guid
{
uStatus=OpcUa_BadNotSupported;
}
break;
case OpcUa_IdentifierType_Opaque: // opaque (ByteString)
{
uStatus=OpcUa_BadNotSupported;
}
break;
default:
uStatus=OpcUa_BadInvalidArgument;
break;
}
}
else
uStatus=OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA browse ex. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 25/09/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="iNoOfNodesToBrowse"> Zero-based index of the no of nodes to browse.
/// </param>
/// <param name="pNodesToBrowse"> The nodes to browse. </param>
/// <param name="iNoOfReferenceDescription"> [in,out] If non-null, information describing the
/// no of reference.
/// </param>
/// <param name="pReferenceList"> [in,out] If non-null, list of references. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_BrowseEx(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Int32 iNoOfNodesToBrowse,
const OpcUa_BrowseDescription* pNodesToBrowse,
OpcUa_Int32* iNoOfReferenceDescription,
OpenOpcUa_ReferenceDescription** ppReferenceList)
{
//CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
//OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
//OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_BrowseEx\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
OpcUa_NodeId parentNodeId;
OpcUa_NodeId_Initialize(&parentNodeId);
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
OpcUa_ReferenceDescriptionList aReferences;
uStatus = pSession->Browse(iNoOfNodesToBrowse, pNodesToBrowse, &aReferences);
if (uStatus == OpcUa_Good)
{
OpcUa_UInt32 uiNoOfReferencesDescrition= aReferences.size();
if (uiNoOfReferencesDescrition > 0)
{
*iNoOfReferenceDescription = 1;
(*ppReferenceList) = (OpenOpcUa_ReferenceDescription*)OpcUa_Alloc(sizeof(OpenOpcUa_ReferenceDescription));
OpenOpcUa_ReferenceDescription* pReferenceList = (*ppReferenceList);
pReferenceList->m_pOpcUa_ReferenceDescription = OpcUa_Null;
pReferenceList->m_pOpcUa_ReferenceDescription = (OpcUa_ReferenceDescription*)OpcUa_Alloc(uiNoOfReferencesDescrition*sizeof(OpcUa_ReferenceDescription));
pReferenceList->m_noOfOpcUa_ReferenceDescription = uiNoOfReferencesDescrition;
OpcUa_NodeId_Initialize(&pReferenceList->m_ParentNodeId);
OpcUa_NodeId_CopyTo(&pNodesToBrowse[0].NodeId, &parentNodeId); // for initialization purpose
for (OpcUa_UInt32 ii = 0; ii < uiNoOfReferencesDescrition; ii++)
{
OpcUa_ReferenceDescription* pReferenceDescription = aReferences.at(ii);
if (pReferenceDescription)
{
if ((!pReferenceDescription->IsForward) && (pReferenceDescription->NodeId.NodeId.Identifier.Numeric!= 0))
{
OpcUa_NodeId_Initialize(&pReferenceList->m_ParentNodeId);
OpcUa_NodeId_CopyTo(&pReferenceDescription->NodeId.NodeId, &parentNodeId);
}
OpcUa_NodeId_Clear(&pReferenceList->m_ParentNodeId); // may overwriting pReferenceList->m_ParentNodeId
OpcUa_NodeId_CopyTo(&parentNodeId, &(pReferenceList->m_ParentNodeId));
//
OpcUa_ReferenceDescription_Initialize(&(pReferenceList->m_pOpcUa_ReferenceDescription[ii]));
OpcUa_QualifiedName_CopyTo(&(pReferenceDescription->BrowseName), &(pReferenceList->m_pOpcUa_ReferenceDescription[ii].BrowseName));
OpcUa_LocalizedText_CopyTo(&(pReferenceDescription->DisplayName), &(pReferenceList->m_pOpcUa_ReferenceDescription[ii].DisplayName));
pReferenceList->m_pOpcUa_ReferenceDescription[ii].IsForward = pReferenceDescription->IsForward;
pReferenceList->m_pOpcUa_ReferenceDescription[ii].NodeClass = pReferenceDescription->NodeClass;
OpcUa_ExpandedNodeId_CopyTo(&(pReferenceDescription->NodeId), &(pReferenceList->m_pOpcUa_ReferenceDescription[ii].NodeId));
OpcUa_NodeId_CopyTo(&(pReferenceDescription->ReferenceTypeId), &(pReferenceList->m_pOpcUa_ReferenceDescription[ii].ReferenceTypeId));
OpcUa_ExpandedNodeId_CopyTo(&(pReferenceDescription->TypeDefinition), &(pReferenceList->m_pOpcUa_ReferenceDescription[ii].TypeDefinition));
}
}
}
OpcUa_ReferenceDescriptionList::iterator it;
for (it = aReferences.begin(); it != aReferences.end();it++)
{
OpcUa_ReferenceDescription* pReferenceDescription = *it;
OpcUa_ReferenceDescription_Clear(pReferenceDescription);
OpcUa_Free(pReferenceDescription);
}
aReferences.clear();
}
}
}
}
OpcUa_NodeId_Clear(&parentNodeId);
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA browse. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 25/09/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="iNoOfNodesToBrowse"> Zero-based index of the no of nodes to browse.
/// </param>
/// <param name="pNodesToBrowse"> The nodes to browse. </param>
/// <param name="iNoOfReferenceDescription"> [in,out] If non-null, information describing the
/// no of reference.
/// </param>
/// <param name="pReferenceList"> [in,out] If non-null, list of references. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_Browse(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Int32 iNoOfNodesToBrowse,
const OpcUa_BrowseDescription* pNodesToBrowse,
OpcUa_Int32* iNoOfReferenceDescription,
OpcUa_ReferenceDescription** pReferenceList)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_Browse\n");
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession=(CSessionClient*)hSession;
if (pSession)
{
OpcUa_ReferenceDescriptionList aReferences;
uStatus=pSession->Browse(iNoOfNodesToBrowse,pNodesToBrowse,&aReferences);
if (uStatus==OpcUa_Good)
{
*iNoOfReferenceDescription=aReferences.size();
if (aReferences.size() > 0)
{
*pReferenceList = (OpcUa_ReferenceDescription*)OpcUa_Alloc(aReferences.size()*sizeof(OpcUa_ReferenceDescription));
for (OpcUa_UInt32 ii = 0; ii < aReferences.size(); ii++)
{
OpcUa_ReferenceDescription* pReferenceDescription = aReferences.at(ii);
if (pReferenceDescription)
{
OpcUa_ReferenceDescription_Initialize(&((*pReferenceList)[ii]));
OpcUa_QualifiedName_CopyTo(&(pReferenceDescription->BrowseName), &((*pReferenceList)[ii].BrowseName));
OpcUa_LocalizedText_CopyTo(&(pReferenceDescription->DisplayName), &((*pReferenceList)[ii].DisplayName));
(*pReferenceList)[ii].IsForward = pReferenceDescription->IsForward;
(*pReferenceList)[ii].NodeClass = pReferenceDescription->NodeClass;
OpcUa_ExpandedNodeId_CopyTo(&(pReferenceDescription->NodeId), &((*pReferenceList)[ii].NodeId));
OpcUa_NodeId_CopyTo(&(pReferenceDescription->ReferenceTypeId), &((*pReferenceList)[ii].ReferenceTypeId));
OpcUa_ExpandedNodeId_CopyTo(&(pReferenceDescription->TypeDefinition), &((*pReferenceList)[ii].TypeDefinition));
}
}
}
OpcUa_ReferenceDescriptionList::iterator it;
while (!aReferences.empty())
{
it=aReferences.begin();
OpcUa_ReferenceDescription* pReferenceDescription=*it;
OpcUa_ReferenceDescription_Clear(pReferenceDescription);
OpcUa_Free(pReferenceDescription);
aReferences.erase(it);
}
}
}
}
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA get trace file. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 04/01/2017. </remarks>
///
/// <param name="strFileName"> [in,out] If non-null, filename of the file. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetTraceFile(OpcUa_String* strFileName)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetTraceFile\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (strFileName)
{
for (OpcUa_UInt32 ii = 0; ii < g_pUaClientApplicationList.size(); ii++)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(ii);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace_GetTraceFile(pTraceConfiguration,strFileName);
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA get trace level. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 04/01/2017. </remarks>
///
/// <returns> An OpcUa_UInt32. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_UInt32 OpenOpcUa_GetTraceLevel()
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetTraceLevel\n");
return OpcUa_Trace_GetTraceLevel(pTraceConfiguration);
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA set trace level. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 04/01/2017. </remarks>
///
/// <param name="iTraceLevel"> Zero-based index of the trace level. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_SetTraceLevel(OpcUa_UInt32 iTraceLevel)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_SetTraceLevel\n");
OpcUa_StatusCode uStatus=OpcUa_Good;
switch (iTraceLevel)
{
case OPCUA_TRACE_CLIENT_LEVEL_DEBUG:
case OPCUA_TRACE_CLIENT_LEVEL_ERROR:
case OPCUA_TRACE_CLIENT_LEVEL_WARNING:
case OPCUA_TRACE_CLIENT_LEVEL_INFO:
{
for (OpcUa_UInt32 ii = 0; ii < g_pUaClientApplicationList.size(); ii++)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(ii);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace_SetTraceLevel(pTraceConfiguration,iTraceLevel);
}
}
break;
default:
uStatus = OpcUa_BadInvalidArgument;
break;
}
return uStatus;
}
//#define OPCUA_TRACE_LEVEL_ERROR 0x00000020 /* in-system errors, which require bugfixing */
//#define OPCUA_TRACE_LEVEL_WARNING 0x00000010 /* in-system warnings and extern errors */
//#define OPCUA_TRACE_LEVEL_SYSTEM 0x00000008 /* rare system messages (start, stop, connect) */
//#define OPCUA_TRACE_LEVEL_INFO 0x00000004 /* more detailed information about system events */
//#define OPCUA_TRACE_LEVEL_DEBUG 0x00000002 /* information needed for debug reasons */
//#define OPCUA_TRACE_LEVEL_CONTENT 0x00000001 /* all message content */
OpcUa_StatusCode OpenOpcUa_Trace(OpcUa_Handle hApplication, OpcUa_UInt32 a_uTraceLevel, const OpcUa_CharA* format,...)
{
OpcUa_StatusCode uStatus=OpcUa_BadInternalError;
char* outBuffer=(char*)malloc(1024);
ZeroMemory(outBuffer, 1024);
char* outTmpBuffer = (char*)malloc(1024);
ZeroMemory(outTmpBuffer, 1024);
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication=(CClientApplication*)hApplication;
if (pUaClientApplication)
{
va_list args;
va_start(args, format);
//char* tmpStr=va_arg( args, char* );
CLoggerMessage* pLoggerMessage=new CLoggerMessage();
pLoggerMessage->m_pString=(OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String));
// recherche des caractères % dans format afin de déterminer ce qui vient de nous être passé
if (format)
{
int iSize=strlen(format);
// get first position of %
int iFirstPos=-1;
//save the first pos
memcpy(outBuffer, format, iSize);
for (int ii=0;ii<iSize;ii++)
{
if (format[ii]==0x25)
{
if (iFirstPos==-1)
iFirstPos=ii;
// analyse du contenu de l'octet suivant
switch (format[ii+1])
{
case 'u':
{
unsigned int uiVal=va_arg(args,unsigned int);
// Concatenation dans l'outBuffer
sprintf(outTmpBuffer, "%s %u", outBuffer, uiVal);
}
break;
case 'i':
case 'd':
{
int uiVal=va_arg(args,int);
// Concatenation dans l'outBuffer
sprintf(outTmpBuffer, "%s %u", outBuffer, uiVal);
}
break;
case 'e':
case 'f':
{
double fltVal=va_arg(args,double);
sprintf(outTmpBuffer, "%s %f", outBuffer, fltVal);
}
break;
case 's':
{
char* cVal=va_arg(args,char*);
// Concatenation dans l'outBuffer
sprintf(outTmpBuffer, "%s %s", outBuffer, cVal);
}
break;
case 'X':
case 'x':
{
unsigned int uiVal=va_arg(args,unsigned int);
// Concatenation dans l'outBuffer
sprintf(outTmpBuffer, "%s %x", outBuffer, uiVal);
}
break;
default:
break;
}
strcpy(outBuffer, outTmpBuffer);
}
}
}
OpcUa_String_AttachCopy(pLoggerMessage->m_pString,outBuffer);
pLoggerMessage->m_uiLevel=a_uTraceLevel;
pUaClientApplication->AddLoggerMessage(pLoggerMessage);
va_end(args);
}
}
free(outBuffer);
free(outTmpBuffer);
return uStatus;
}
// this function will provide the details for an attributes. This is not related to hApplication or hSession
// This function is just an helper
OpcUa_StatusCode OpenOpcUa_GetAttributeDetails(OpcUa_Int32 iAttributeId, OpcUa_String** szAttributeName, OpcUa_String** szAttributeDescription)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetAttributeDetails\n");
OpcUa_StatusCode uStatus=OpcUa_Good;
if (szAttributeName && szAttributeDescription)
{
if ( (iAttributeId>0) && (iAttributeId<23) )
{
// AttributeName
*szAttributeName=(OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String));
OpcUa_String_Initialize(*szAttributeName);
OpcUa_String_AttachCopy(*szAttributeName, OpcUa_Attributes[iAttributeId-1].szAttribute);
// Attribute description
*szAttributeDescription=(OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String));
OpcUa_String_Initialize(*szAttributeDescription);
OpcUa_String_AttachCopy(*szAttributeDescription, OpcUa_Attributes[iAttributeId-1].szAttributeText);
}
else
uStatus=OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
return uStatus;
}
// Function name : OpenOpcUa_GetBuiltInTypeDetails
// Description :
// This function will provide detail for BuiltInTypes. This is just an helper function
// Application have to release allocated ressources, szBuiltInTypeName, szBuiltInTypeDescription
// Return type : OpcUa_StatusCode
// Argument : OpcUa_Int32 iBuiltInTypeId
// Argument : OpcUa_String** szBuiltInTypeName output param
// Argument : OpcUa_String** szBuiltInTypeDescription output param
OpcUa_StatusCode OpenOpcUa_GetBuiltInTypeDetails(OpcUa_Int32 iBuiltInTypeId, OpcUa_String** szBuiltInTypeName, OpcUa_String** szBuiltInTypeDescription)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetBuiltInTypeDetails\n");
OpcUa_StatusCode uStatus=OpcUa_Good;
if (szBuiltInTypeName && szBuiltInTypeDescription)
{
if ( (iBuiltInTypeId>=0) && (iBuiltInTypeId<26) )
{
// BuilInTypeName
*szBuiltInTypeName=(OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String));
OpcUa_String_Initialize(*szBuiltInTypeName);
OpcUa_String_AttachCopy(*szBuiltInTypeName, OpcUa_BuiltInTypes[iBuiltInTypeId].szBuilInType);
// Attribute description
*szBuiltInTypeDescription=(OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String));
OpcUa_String_Initialize(*szBuiltInTypeDescription);
OpcUa_String_AttachCopy(*szBuiltInTypeDescription, OpcUa_BuiltInTypes[iBuiltInTypeId].szBuilInTypeText);
}
else
uStatus=OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
return uStatus;
}
// Get the NodeClassName based ont the NodeClassId
OpcUa_StatusCode OpenOpcUa_GetNodeClassDetails(OpcUa_Int32 iNodeClass, OpcUa_String** szNodeClassName)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetNodeClassDetails\n");
OpcUa_StatusCode uStatus=OpcUa_Good;
*szNodeClassName=(OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String));
OpcUa_String_Initialize(*szNodeClassName);
switch (iNodeClass)
{
case 0:
OpcUa_String_AttachCopy(*szNodeClassName,"Unspecified");
break;
case 1:
OpcUa_String_AttachCopy(*szNodeClassName,"Object");
break;
case 2:
OpcUa_String_AttachCopy(*szNodeClassName,"Variable");
break;
case 4:
OpcUa_String_AttachCopy(*szNodeClassName,"Method");
break;
case 8:
OpcUa_String_AttachCopy(*szNodeClassName,"ObjectType");
break;
case 16:
OpcUa_String_AttachCopy(*szNodeClassName,"VariableType");
break;
case 32:
OpcUa_String_AttachCopy(*szNodeClassName,"ReferenceType");
break;
case 64:
OpcUa_String_AttachCopy(*szNodeClassName,"DataType");
break;
case 128:
OpcUa_String_AttachCopy(*szNodeClassName,"View");
break;
default:
uStatus=OpcUa_BadInvalidArgument;
OpcUa_String_Clear(*szNodeClassName);
break;
}
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_GetAccessLevel(OpcUa_Byte AccessLevel, OpcUa_String** szAccessLevel)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetAccessLevel\n");
OpcUa_StatusCode uStatus=OpcUa_Good;
*szAccessLevel = (OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String));
if (*szAccessLevel)
{
OpcUa_String StreamAccess, HistoryAccess;
OpcUa_String_Initialize(&StreamAccess);
OpcUa_String_Initialize(&HistoryAccess);
OpcUa_String_Initialize((*szAccessLevel));
if (AccessLevel == OpcUa_AccessLevels_None)
OpcUa_String_AttachCopy(&StreamAccess, "None");
if ((AccessLevel&OpcUa_AccessLevels_CurrentRead) == OpcUa_AccessLevels_CurrentRead)
OpcUa_String_AttachCopy(&StreamAccess, "Read");
if ((AccessLevel&OpcUa_AccessLevels_CurrentWrite) == OpcUa_AccessLevels_CurrentWrite)
OpcUa_String_AttachCopy(&StreamAccess, "Write");
if ((AccessLevel&OpcUa_AccessLevels_CurrentReadOrWrite) == OpcUa_AccessLevels_CurrentReadOrWrite)
OpcUa_String_AttachCopy(&StreamAccess, "Read or Write");
if ((AccessLevel&OpcUa_AccessLevels_HistoryRead) == OpcUa_AccessLevels_HistoryRead)
OpcUa_String_AttachCopy(&HistoryAccess, "History Read");
if ((AccessLevel&OpcUa_AccessLevels_HistoryWrite) == OpcUa_AccessLevels_HistoryWrite)
OpcUa_String_AttachCopy(&HistoryAccess, "History Write");
if ((AccessLevel&OpcUa_AccessLevels_HistoryReadOrWrite) == OpcUa_AccessLevels_HistoryReadOrWrite)
OpcUa_String_AttachCopy(&HistoryAccess, "History Read and Write");
//OpcUa_String_StrnCpy((*szAccessLevel), &StreamAccess, OpcUa_String_StrLen(&StreamAccess));
OpcUa_String_CopyTo(&StreamAccess,(*szAccessLevel));
if (OpcUa_String_StrLen(&HistoryAccess) > 0)
OpcUa_String_StrnCat((*szAccessLevel), &HistoryAccess, OpcUa_String_StrLen(&HistoryAccess));
OpcUa_String_Clear(&StreamAccess);
OpcUa_String_Clear(&HistoryAccess);
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Get the UserAccessLevel. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="AccessLevel"> The access level. </param>
/// <param name="szUserAccessLevel"> [in,out] If non-null, the user access level. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetUserAccessLevel(OpcUa_Byte AccessLevel, OpcUa_String** szUserAccessLevel)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetUserAccessLevel\n");
return OpenOpcUa_GetAccessLevel(AccessLevel, szUserAccessLevel);
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// Transform an OpcUa_String to OpcUa_Variant according to the requested DataType.
/// </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 17/02/2017. </remarks>
///
/// <param name="pString"> [in,out] If non-null, the string. </param>
/// <param name="iDataType"> Type of the data. </param>
/// <param name="pVariant"> [in,out] If non-null, the variant. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_StringToVariant(OpcUa_String* pString, OpcUa_Int32 iDataType,OpcUa_Variant** pVariant)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_StringToVariant\n");
OpcUa_StatusCode uStatus=OpcUa_Good;
if (pString)
{
if (OpcUa_String_StrLen(pString) > 0)
{
*pVariant = (OpcUa_Variant*)OpcUa_Alloc(sizeof(OpcUa_Variant));
OpcUa_Variant_Initialize(*pVariant);
switch (iDataType)
{
case OpcUaType_Boolean:
(*pVariant)->Datatype = OpcUaType_Boolean;
(*pVariant)->Value.Boolean = (OpcUa_Boolean)atoi(OpcUa_String_GetRawString(pString));
break;
case OpcUaType_Byte:
(*pVariant)->Datatype = OpcUaType_Byte;
(*pVariant)->Value.Byte = (OpcUa_Byte)atoi(OpcUa_String_GetRawString(pString));
break;
case OpcUaType_ByteString:
break;
case OpcUaType_DataValue:
break;
case OpcUaType_DateTime:
break;
case OpcUaType_DiagnosticInfo:
uStatus = OpcUa_BadNotSupported;
break;
case OpcUaType_Double:
{
(*pVariant)->Datatype = OpcUaType_Double;
OpcUa_Double dblVal = 0.0;
if (sscanf(OpcUa_String_GetRawString(pString), "%lf", &dblVal) == 1)
(*pVariant)->Value.Double = dblVal;
else
uStatus = OpcUa_BadInvalidArgument;
}
break;
case OpcUaType_ExpandedNodeId:
uStatus = OpcUa_BadNotSupported;
break;
case OpcUaType_ExtensionObject:
uStatus = OpcUa_BadNotSupported;
break;
case OpcUaType_Float:
{
(*pVariant)->Datatype = OpcUaType_Float;
OpcUa_Float fltVal = 0.0;
if (sscanf(OpcUa_String_GetRawString(pString), "%f", &fltVal) == 1)
(*pVariant)->Value.Float = fltVal;
else
uStatus = OpcUa_BadInvalidArgument;
}
break;
case OpcUaType_Guid:
uStatus = OpcUa_BadNotSupported;
break;
case OpcUaType_Int16:
(*pVariant)->Datatype = OpcUaType_Int16;
(*pVariant)->Value.Int16 = (OpcUa_Int16)atoi(OpcUa_String_GetRawString(pString));
break;
case OpcUaType_Int32:
(*pVariant)->Datatype = OpcUaType_Int32;
(*pVariant)->Value.Int32 = (OpcUa_Int32)atoi(OpcUa_String_GetRawString(pString));
break;
case OpcUaType_Int64:
break;
case OpcUaType_LocalizedText:
break;
case OpcUaType_NodeId:
{
OpcUa_NodeId nodeId;
OpcUa_NodeId_Initialize(&nodeId);
OpcUa_String szVal;
OpcUa_String_Initialize(&szVal);
if (pString)
{
OpcUa_String_CopyTo(pString, &szVal);
uStatus = OpenOpcUa_StringToNodeId(szVal, &nodeId);
if (uStatus == OpcUa_Good)
{
(*pVariant)->Value.NodeId = (OpcUa_NodeId*)OpcUa_Alloc(sizeof(OpcUa_NodeId));
OpcUa_NodeId_Initialize((*pVariant)->Value.NodeId);
(*pVariant)->Datatype = OpcUaType_NodeId;
OpcUa_NodeId_CopyTo(&nodeId, (*pVariant)->Value.NodeId);;
}
}
OpcUa_String_Clear(&szVal);
OpcUa_NodeId_Clear(&nodeId);
}
break;
case OpcUaType_Null:
uStatus = OpcUa_BadNotSupported;
break;
case OpcUaType_QualifiedName:
break;
case OpcUaType_SByte:
break;
case OpcUaType_StatusCode:
break;
case OpcUaType_String:
(*pVariant)->Datatype = OpcUaType_String;
OpcUa_String_StrnCpy(&((*pVariant)->Value.String), pString, OpcUa_String_StrLen(pString));
break;
case OpcUaType_UInt16:
(*pVariant)->Datatype = OpcUaType_UInt16;
(*pVariant)->Value.UInt16 = (OpcUa_UInt16)atoi(OpcUa_String_GetRawString(pString));
break;
case OpcUaType_UInt32:
(*pVariant)->Datatype = OpcUaType_UInt32;
(*pVariant)->Value.UInt32 = (OpcUa_UInt32)atoi(OpcUa_String_GetRawString(pString));
break;
case OpcUaType_UInt64:
break;
case OpcUaType_Variant:
uStatus = OpcUa_BadNotSupported;
break;
case OpcUaType_XmlElement:
uStatus = OpcUa_BadNotSupported;
break;
default:
uStatus = OpcUa_BadDataTypeIdUnknown;
}
if (uStatus != OpcUa_Good)
OpcUa_Variant_Clear(*pVariant);
}
else
uStatus = OpcUa_BadInvalidArgument;
}
else
uStatus=OpcUa_BadInvalidArgument;
return uStatus;
}
// Function for configuration file manipulation. Configuration file are conform to OpenOpcUaClientConfig.xsd
OpcUa_StatusCode OpenOpcUa_LoadConfig(OpcUa_Handle hApplication, OpcUa_String szConfigFileName)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_LoadConfig\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
OpcUa_CharA* localPath = OpcUa_Null;
OpcUa_CharA* fileName = OpcUa_Null;
OpcUa_CharA* chFileName = OpcUa_String_GetRawString(&szConfigFileName);
// séparation du path et du nom de fichier
basic_string<char> myString(chFileName);
basic_string<char>::size_type index = 0;
#ifdef _GNUC_
index = myString.rfind("/");
#else
#ifdef WIN32
index = myString.rfind("\\");
#endif
#endif
if (index != basic_string<char>::npos)
{
// path
basic_string<char> tmpStr = myString.substr(0, index + 1);
localPath = (char*)OpcUa_Alloc(tmpStr.size() + 1);
if (localPath)
{
ZeroMemory(localPath, tmpStr.size() + 1);
memcpy(localPath, tmpStr.c_str(), tmpStr.size());
// fileName
tmpStr = myString.substr(index + 1, myString.size() - index);
fileName = (char*)OpcUa_Alloc(tmpStr.size() + 1);
if (fileName)
{
ZeroMemory(fileName, tmpStr.size() + 1);
memcpy(fileName, tmpStr.c_str(), tmpStr.size());
if ((localPath) && (fileName))
{
uStatus = pUaClientApplication->LoadUaClientConfiguration(localPath, fileName);
if (uStatus != OpcUa_Good)
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_ERROR, "Critical error>Cannot load ClientConfiguration file\n");
}
else
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_ERROR, "Critical error>Memory error, ClientConfiguration corrupted\n");
if (fileName)
OpcUa_Free(fileName);
}
if (localPath)
OpcUa_Free(localPath);
}
else
{
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_ERROR, "OpenOpcUa_LoadConfig failed. Not enough memory\n");
uStatus = OpcUa_BadOutOfMemory;
}
}
else
{
uStatus = OpcUa_BadFileNotFound;
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_ERROR, "Critical error>Full ClientConfiguration filename is corrupted\n");
}
}
else
{
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_ERROR, "Your Application handle is invalid\n");
uStatus = OpcUa_BadInvalidArgument;
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA save configuration. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="szConfigFileName"> Filename of the configuration file. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_SaveConfig(OpcUa_Handle hApplication, OpcUa_String szConfigFileName)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_SaveConfig\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
OpcUa_CharA* localPath = OpcUa_Null;
OpcUa_CharA* fileName = OpcUa_Null;
OpcUa_CharA* chFileName = OpcUa_String_GetRawString(&szConfigFileName);
// séparation du path et du nom de fichier
basic_string<char> myString(chFileName);
basic_string<char>::size_type index = 0;
#ifdef _GNUC_
index = myString.rfind("/");
#else
#ifdef WIN32
index = myString.rfind("\\");
#endif
#endif
if (index != basic_string<char>::npos)
{
// path
basic_string<char> tmpStr = myString.substr(0, index + 1);
localPath = (char*)OpcUa_Alloc(tmpStr.size() + 1);
if (localPath)
{
ZeroMemory(localPath, tmpStr.size() + 1);
memcpy(localPath, tmpStr.c_str(), index);
// Path
//localPath = myString.substr(0, index);
// fileName
tmpStr = myString.substr(index + 1, myString.size() - index);
fileName = (char*)OpcUa_Alloc(tmpStr.size() + 1);
if (fileName)
{
ZeroMemory(fileName, tmpStr.size() + 1);
memcpy(fileName, tmpStr.c_str(), tmpStr.size());
if ((localPath) && (fileName))
{
uStatus=pUaClientApplication->SaveUaClientConfiguration(localPath, fileName);
}
}
}
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Retrive sessions for a hApplication. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="uiNoOfSessions"> [in,out] If non-null, the no of sessions. </param>
/// <param name="hSessions"> [in,out] If non-null, the sessions. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetSessions(OpcUa_Handle hApplication,
OpcUa_UInt32* uiNoOfSessions, // out
OpcUa_Handle** hSessions) // out
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetSessions\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
uStatus = pUaClientApplication->GetSessions(uiNoOfSessions,hSessions);
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA get subscriptions. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 05/01/2017. </remarks>
///
/// <param name="hApplication"> The application. </param>
/// <param name="hSession"> The session. </param>
/// <param name="uiNoOfSubscription"> [in,out] If non-null, the no of subscription. </param>
/// <param name="hSubscription"> [in,out] If non-null, the subscription. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetSubscriptions(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_UInt32* uiNoOfSubscription, // out
OpcUa_Handle** hSubscription) // out
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetSubscriptions\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
uStatus=pSession->GetSubscriptions(uiNoOfSubscription,hSubscription);
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
// retrieve the hMonitoredItems for a hSubscription
/// <summary>
/// Opens the opc ua_ get monitored items.
/// </summary>
/// <param name="hApplication">The h application.</param>
/// <param name="hSession">The h session.</param>
/// <param name="hSubscription">The h subscription.</param>
/// <param name="uiNoOfMonitoredItems">The UI no of monitored items.</param>
/// <param name="hMonitoredItems">hMonitoredItems is an input parameter it should be null in the call. It will be release by the caller</param>
/// <returns></returns>
OpcUa_StatusCode OpenOpcUa_GetMonitoredItems(OpcUa_Handle hApplication,
OpcUa_Handle hSession,
OpcUa_Handle hSubscription,
OpcUa_UInt32* uiNoOfMonitoredItems, // out
OpcUa_Handle** hMonitoredItems) // out
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetMonitoredItems\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (hMonitoredItems)
{
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
CSessionClient* pSession = (CSessionClient*)hSession;
if (pSession)
{
CSubscriptionClient* pSubscriptionClient = (CSubscriptionClient*)hSubscription;
if (pSubscriptionClient)
{
uStatus = pSubscriptionClient->GetMonitoredItems(uiNoOfMonitoredItems, hMonitoredItems);
}
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
// Retrieve the dataType of the UAVariable (aNodeId)
OpcUa_StatusCode OpenOpcUa_GetUAVariableDatatype(OpcUa_Handle hApplication, OpcUa_Handle hSession, OpcUa_NodeId aNodeId, OpcUa_NodeId* pDataType)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_GetUAVariableDatatype\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
OpcUa_DataValue* pResults = OpcUa_Null;
OpcUa_ReadValueId* pNodesToRead = OpcUa_Null;
if (g_bAbstractionLayerInitialized)
{
CClientApplication* pUaClientApplication = (CClientApplication*)hApplication;
if (pUaClientApplication)
{
OpcUa_Int32 iNodNodesToRead = 1;
pNodesToRead = (OpcUa_ReadValueId*)OpcUa_Alloc(iNodNodesToRead*sizeof(OpcUa_ReadValueId));
OpcUa_ReadValueId_Initialize(&pNodesToRead[0]);
pNodesToRead[0].AttributeId = OpcUa_Attributes_DataType;
pNodesToRead[0].NodeId = aNodeId;
OpcUa_NodeId_CopyTo(&aNodeId, &(pNodesToRead[0].NodeId));
uStatus = OpenOpcUa_ReadAttributes(hApplication, hSession, OpcUa_TimestampsToReturn_Both, iNodNodesToRead, pNodesToRead, &pResults);
if (uStatus == OpcUa_Good)
{
// dans le cas du DataType le type est dans un NodeId
if (pResults[0].StatusCode == OpcUa_Good)
{
if (!pDataType)
pDataType=(OpcUa_NodeId*)OpcUa_Alloc(sizeof(OpcUa_NodeId));
OpcUa_NodeId_Initialize(pDataType);
OpcUa_NodeId_CopyTo(pResults[0].Value.Value.NodeId, pDataType);
}
if (pResults)
{
OpcUa_DataValue_Clear(pResults);
OpcUa_Free(pResults);
}
}
OpcUa_ReadValueId_Clear(pNodesToRead);
OpcUa_Free(pNodesToRead);
}
}
return uStatus;
}
// Caller must clear and release the extensionObject
OpcUa_StatusCode OpenOpcUa_CreateFilterObject(OpcUa_UInt32 DeadbandType,
OpcUa_Double DeadbandValue,
OpcUa_Byte DatachangeTrigger,
OpcUa_ExtensionObject** pExtensionObject)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_CreateFilterObject\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (!(*pExtensionObject))
{
(*pExtensionObject) = (OpcUa_ExtensionObject*)OpcUa_Alloc(sizeof(OpcUa_ExtensionObject));
OpcUa_ExtensionObject_Initialize((*pExtensionObject));
(*pExtensionObject)->TypeId.NodeId.Identifier.Numeric = OpcUaId_DataChangeFilter_Encoding_DefaultBinary;
(*pExtensionObject)->Encoding = OpcUa_ExtensionObjectEncoding_EncodeableObject;
(*pExtensionObject)->Body.EncodeableObject.Type = (OpcUa_EncodeableType*)OpcUa_Alloc(sizeof(OpcUa_EncodeableType));
(*pExtensionObject)->Body.EncodeableObject.Type = &OpcUa_DataChangeFilter_EncodeableType;
//DataChangeFilter.Body.EncodeableObject.Type->TypeId = OpcUaId_DataChangeFilter;
OpcUa_DataChangeFilter* pDataChangeFilter = (OpcUa_DataChangeFilter*)OpcUa_Alloc(sizeof(OpcUa_DataChangeFilter));
pDataChangeFilter->DeadbandType = DeadbandType;
pDataChangeFilter->DeadbandValue = DeadbandValue;
pDataChangeFilter->Trigger = (OpcUa_DataChangeTrigger)DatachangeTrigger;
(*pExtensionObject)->Body.EncodeableObject.Object = (void*)pDataChangeFilter;
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
// Give a string representation of an StatusCode
OpcUa_StatusCode OpenOpcUa_StatusCodeToString(OpcUa_StatusCode inStatus, OpcUa_String** pszStatusCode)
{
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "Call OpenOpcUa_StatusCodeToString\n");
OpcUa_StatusCode uStatus = OpcUa_Good;
if (!(*pszStatusCode))
{
(*pszStatusCode) = (OpcUa_String*)OpcUa_Alloc(sizeof(OpcUa_String));
if ((*pszStatusCode))
{
OpcUa_String_Initialize((*pszStatusCode));
switch (inStatus)
{
case OpcUa_GoodCallAgain:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodCallAgain");
break;
case OpcUa_GoodClamped:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodClamped");
break;
case OpcUa_GoodCommunicationEvent:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodCommunicationEvent");
break;
case OpcUa_GoodCompletesAsynchronously:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodCompletesAsynchronously");
break;
case OpcUa_GoodDataIgnored:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodDataIgnored");
break;
case OpcUa_GoodEntryInserted:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodEntryInserted");
break;
case OpcUa_GoodEntryReplaced:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodEntryReplaced");
break;
case OpcUa_GoodLocalOverride:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodLocalOverride");
break;
case OpcUa_GoodMoreData:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodMoreData");
break;
case OpcUa_GoodNoData:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodNoData");
break;
case OpcUa_GoodNonCriticalTimeout:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodNonCriticalTimeout");
break;
case OpcUa_GoodOverload:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodOverload");
break;
case OpcUa_GoodResultsMayBeIncomplete:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodResultsMayBeIncomplete");
break;
case OpcUa_GoodShutdownEvent:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodShutdownEvent");
break;
case OpcUa_GoodSubscriptionTransferred:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodSubscriptionTransferred");
break;
case OpcUa_GoodTimeout:
OpcUa_String_AttachCopy((*pszStatusCode), "GoodTimeout");
break;
case OpcUa_Good:
OpcUa_String_AttachCopy((*pszStatusCode), "Good");
break;
case OpcUa_Uncertain:
OpcUa_String_AttachCopy((*pszStatusCode), "Uncertain");
break;
case OpcUa_BadTimeout:
OpcUa_String_AttachCopy((*pszStatusCode), "BadTimeout");
break;
case OpcUa_BadCommunicationError:
OpcUa_String_AttachCopy((*pszStatusCode), "BadCommunicationError");
break;
case OpcUa_BadConnectionClosed:
OpcUa_String_AttachCopy((*pszStatusCode), "BadCertificateIssuerRevocationUnknown");
break;
case OpcUa_BadCertificateInvalid:
OpcUa_String_AttachCopy((*pszStatusCode), "BadCertificateInvalid");
break;
case OpcUa_BadCertificateTimeInvalid:
OpcUa_String_AttachCopy((*pszStatusCode), "BadCertificateTimeInvalid");
break;
case OpcUa_BadCertificateRevoked:
OpcUa_String_AttachCopy((*pszStatusCode), "BadCertificateRevoked");
break;
case OpcUa_BadCertificateUntrusted:
OpcUa_String_AttachCopy((*pszStatusCode), "BadCertificateUntrusted");
break;
case OpcUa_BadCertificateIssuerRevocationUnknown:
OpcUa_String_AttachCopy((*pszStatusCode), "BadCertificateIssuerRevocationUnknown");
break;
case OpcUa_BadConnectionRejected:
OpcUa_String_AttachCopy((*pszStatusCode), "BadConnectionRejected");
break;
default:
{
OpcUa_CharA* buf=(OpcUa_CharA*)OpcUa_Alloc(15);
ZeroMemory(buf, 15);
sprintf(buf, "0x%05x", (unsigned int)inStatus);
OpcUa_String_AttachCopy((*pszStatusCode), buf);
free(buf);
}
break;
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Decode from DataTypeDictionnaries of the connected server associated with hSession
/// and transfert in a OpenOpcUa_Definition.
/// The Datatype definition to retrive is pointed by NodeId We will extract its browseName in order to retrive the Datatype.
/// </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 17/01/2017. </remarks>
///
/// <param name="hApplication"> [Input] The application handle. </param>
/// <param name="hSession"> [Input] The session handle. </param>
/// <param name="nodeId"> [Input] Identifier for the node containing the DataType to decode. </param>
/// <param name="pDefinition"> [out] The OpenOpcUa_Definition that contains the found definition. </param>
///
/// <returns> An OpcUa_StatusCode OpcUa_Good if works properly. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetDataTypeDefinition(OpcUa_Handle hApplication,OpcUa_Handle hSession, OpcUa_NodeId nodeId, OpenOpcUa_Definition** ppDefinition)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
OpcUa_UInt32 uiNoOfDataTypeDictionnary = 0;
OpcUa_ByteString* dataTypeDictionnaries = OpcUa_Null;
// Find the DataType dictionnaries for this server
uStatus = OpenOpcUa_GetBinaryDataTypeDictionnaries(hApplication, hSession, &uiNoOfDataTypeDictionnary, &dataTypeDictionnaries);
if (uStatus == OpcUa_Good)
{
OpcUa_QualifiedName dataTypeBrowseName;
OpcUa_QualifiedName_Initialize(&dataTypeBrowseName);
///////////////////////////////////////////////////
// Search BrowseName and NodeClass for nodeId
//
OpcUa_Int32 iNodNodesToRead = 2;
OpcUa_ReadValueId* pNodesToRead = (OpcUa_ReadValueId*)OpcUa_Alloc(iNodNodesToRead*sizeof(OpcUa_ReadValueId));
OpcUa_ReadValueId_Initialize(&pNodesToRead[0]);
OpcUa_ReadValueId_Initialize(&pNodesToRead[1]);
OpcUa_DataValue* pResults = OpcUa_Null;
pNodesToRead[0].AttributeId = OpcUa_Attributes_BrowseName;
OpcUa_NodeId_CopyTo(&nodeId,&pNodesToRead[0].NodeId);
pNodesToRead[1].AttributeId = OpcUa_Attributes_NodeClass;
OpcUa_NodeId_CopyTo(&nodeId,&pNodesToRead[1].NodeId);
// Read attribute (value)
//CSessionClient* pSession = (CSessionClient*)hSession;
uStatus = OpenOpcUa_ReadAttributes(
hApplication,
hSession,
OpcUa_TimestampsToReturn_Both,
iNodNodesToRead,
pNodesToRead,
&pResults);
// If the read succeed why then we can continue the DataType extraction based on the dataTypeBrowseName
if (uStatus == OpcUa_Good)
{
if (pResults)
{
if (pResults[0].Value.Datatype == OpcUaType_QualifiedName)
OpcUa_QualifiedName_CopyTo(pResults[0].Value.Value.QualifiedName, &dataTypeBrowseName);
if (pResults[1].Value.Value.UInt32 == OpcUa_NodeClass_DataType)
{
for (OpcUa_UInt32 i = 0; i < uiNoOfDataTypeDictionnary; i++)
{
if (dataTypeDictionnaries[i].Length > 0)
{
OpcUa_StringA pEncodedData = (OpcUa_StringA)OpcUa_Alloc(dataTypeDictionnaries[i].Length + 1);
if (pEncodedData)
{
ZeroMemory(pEncodedData, dataTypeDictionnaries[i].Length + 1);
memcpy(pEncodedData, dataTypeDictionnaries[i].Data, dataTypeDictionnaries[i].Length);
OpcUa_Byte* pBytes = OpcUa_Null; // Base64 decoded XML Schema
OpcUa_Int32 iByteCount = 0; // size in byte of the Base64 decoded XML Schema
uStatus = OpcUa_Base64_Decode(pEncodedData, &iByteCount, &pBytes);
if (uStatus == OpcUa_Good)
{
CXmlParser* pXmlParser = new CXmlParser(pBytes, iByteCount);
if (pXmlParser)
{
if (pXmlParser->IsDataTypeDictionnary())
{
OpenOpcUa_Definition* pDefinition = (OpenOpcUa_Definition*)OpcUa_Alloc(sizeof(OpenOpcUa_Definition));
OpenOpcUa_Definition_Initialize(pDefinition);
// Fill the NodeId of the definition. This is the m_Type Attribute
OpcUa_NodeId_CopyTo(&nodeId, &pDefinition->m_Type);
uStatus = pXmlParser->SearchDataTypeDefinition(dataTypeBrowseName.Name, &pDefinition);
if (uStatus == OpcUa_Good)
{
(*ppDefinition) = pDefinition;
delete pXmlParser;
// clean up
OpcUa_Free(pBytes);
pBytes = OpcUa_Null;
OpcUa_Free(pEncodedData);
break;
}
else
{
OpenOpcUa_Definition_Clear(pDefinition);
OpcUa_Free(pDefinition);
pDefinition = OpcUa_Null;
}
}
delete pXmlParser;
}
OpcUa_Free(pBytes);
pBytes = OpcUa_Null;
}
OpcUa_Free(pEncodedData);
}
}
}
}
OpcUa_DataValue_Clear(&pResults[0]);
OpcUa_DataValue_Clear(&pResults[1]);
OpcUa_Free(pResults);
pResults = OpcUa_Null;
}
else
uStatus = OpcUa_BadInternalError;
}
OpcUa_ReadValueId_Clear(&pNodesToRead[0]);
OpcUa_ReadValueId_Clear(&pNodesToRead[1]);
OpcUa_Free(pNodesToRead);
// clean up
OpcUa_QualifiedName_Clear(&dataTypeBrowseName);
for (OpcUa_UInt32 i = 0; i < uiNoOfDataTypeDictionnary; i++)
OpcUa_ByteString_Clear(&dataTypeDictionnaries[i]);
OpcUa_Free(dataTypeDictionnaries);
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> This function parse an XML Element and its attributes :
/// ELEMENT attr1 attr2 attr3
/// </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 17/01/2017. </remarks>
///
/// <param name="rawBuffer"> [in] If non-null, buffer for raw data. </param>
/// <param name="pszElement"> [out] If non-null, the element. </param>
/// <param name="iNoOfAttributes"> [out] number of attribute extracted.
/// </param>
/// <param name="ppszAttributes"> [in,out] Attributes name it always contains iNoOfAttributes attribute name. </param>
/// <param name="ppAttributeValues"> [in,out] Attributes value it always contains iNoOfAttributes attribute value. </param>
/// <param name="pbOpen"> [in,out] Report if the XMLElement is close of not. </param>
///
/// <returns> An OpcUa_StatusCode. OpcUa_Good if it works properly. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode XMLParseElement(OpcUa_CharA* rawBuffer, OpcUa_String* pszElement, OpcUa_Int32* iNoOfAttributes, OpcUa_String** ppszAttributes, OpcUa_String** ppAttributeValues, OpcUa_Boolean* pbOpen)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
CClientApplication* pApplication = g_pUaClientApplicationList.at(0);
OpcUa_ProxyStubConfiguration* pTraceConfiguration = pApplication->GetTraceConfiguration();
OpcUa_Trace(pTraceConfiguration,OPCUA_TRACE_CLIENT_LEVEL_INFO, "%s\n", rawBuffer);
OpcUa_Int32 i = 0;
OpcUa_Int32 nIndex = 0;
OpcUa_Boolean bEndElement = OpcUa_False; // mark end of XML element (/ found)
std::vector<tAttribute*> Attributes;
OpcUa_String_Initialize(pszElement);
while (rawBuffer[i] != '<')
i ++ ;
// Jump <
if (rawBuffer[i] == '<')
i++;
OpcUa_CharA* pszLocalElement = (OpcUa_CharA*)OpcUa_Alloc(1024);
OpcUa_CharA* pszLocalAttribute = (OpcUa_CharA*)OpcUa_Alloc(1024);
ZeroMemory(pszLocalElement, 1024);
ZeroMemory(pszLocalAttribute, 1024);
tAttribute* pAttribute = (tAttribute*)OpcUa_Alloc(sizeof(tAttribute));
while (rawBuffer[i] != 0)
{
OpcUa_String_Initialize(&pAttribute->szAttr);
OpcUa_String_Initialize(&pAttribute->szVal);
// Step 1. Extract the element
nIndex = 0;
while (rawBuffer[i] != 0x20)
{
if ((rawBuffer[i] != 0x0a) && (rawBuffer[i] != 0x0d) && (rawBuffer[i] != '>'))
pszLocalElement[nIndex++] = rawBuffer[i];
if (rawBuffer[i] != '>')
break;
else
i++;
}
if (nIndex > 0)
OpcUa_String_AttachCopy(pszElement, pszLocalElement);
// Step 2. Extract the attributes
// Jump the space (0x20)
while (rawBuffer[i] == 0x20)
i++;
// Attribute itself
nIndex = 0;
ZeroMemory(pszLocalAttribute, 1024);
OpcUa_Boolean bNameAttributeParsingStarted = OpcUa_False;
OpcUa_Boolean bValueAttributeParsingStarted = OpcUa_False;
while ((rawBuffer[i] != '>') && (rawBuffer[i] != 0) )
{
switch (rawBuffer[i])
{
case 0x20: // SPACE
if ((bNameAttributeParsingStarted) || (bValueAttributeParsingStarted) )
pszLocalAttribute[nIndex++] = rawBuffer[i++];
if ((OpcUa_String_StrLen(&pAttribute->szAttr)>0) && (OpcUa_String_StrLen(&pAttribute->szVal)>0) )
{
Attributes.push_back(pAttribute);
pAttribute = (tAttribute*)OpcUa_Alloc(sizeof(tAttribute));
OpcUa_String_Initialize(&pAttribute->szAttr);
OpcUa_String_Initialize(&pAttribute->szVal);
}
pszLocalAttribute[nIndex++] = rawBuffer[i];
i++;
break;
case 0x22: // "
// End parsing Value
if ((!bNameAttributeParsingStarted) && (bValueAttributeParsingStarted) )
{
OpcUa_String_AttachCopy(&pAttribute->szVal, pszLocalAttribute);
bValueAttributeParsingStarted = OpcUa_False;
}
else
{
// Start parsing Value
if ((!bNameAttributeParsingStarted) && (!bValueAttributeParsingStarted))
{
if (OpcUa_String_StrLen(&pAttribute->szAttr) > 0)
bValueAttributeParsingStarted = OpcUa_True;
else
bNameAttributeParsingStarted = OpcUa_True;
}
}
nIndex = 0;
ZeroMemory(pszLocalAttribute, 1024);
//pszLocalAttribute[nIndex++] = rawBuffer[i];
i++;
break;
case 0x3D: // =
if ((bNameAttributeParsingStarted) && (!bValueAttributeParsingStarted))
{
if (pszLocalAttribute[0])
OpcUa_String_AttachCopy(&pAttribute->szAttr, pszLocalAttribute);
bNameAttributeParsingStarted = OpcUa_False;
nIndex = 0;
ZeroMemory(pszLocalAttribute, 1024);
}
bValueAttributeParsingStarted = OpcUa_False;
//pszLocalAttribute[nIndex++] = rawBuffer[i];
i++;
break;
case 0x5c: // '\'
i++;
break;
case 0x2F: // /
pszLocalAttribute[nIndex++] = rawBuffer[i];
bEndElement = OpcUa_True;
i++;
break;
case 0x3E: // >
if (bEndElement)
(*pbOpen) = bEndElement;
nIndex = 0;
ZeroMemory(pszLocalAttribute, 1024);
i++;
break;
default:
if ((!bNameAttributeParsingStarted) && (!bValueAttributeParsingStarted))
bNameAttributeParsingStarted = OpcUa_True;
if ((rawBuffer[i] != 0x0a) && (rawBuffer[i] != 0x0d))
pszLocalAttribute[nIndex++] = rawBuffer[i];
bEndElement = OpcUa_False;
i++;
break;
}
}
i++;
}
// Transfort from Attributes
(*iNoOfAttributes)= Attributes.size();
if ((*iNoOfAttributes) > 0)
{
(*ppszAttributes) = (OpcUa_String*)OpcUa_Alloc((*iNoOfAttributes)*sizeof(OpcUa_String));
(*ppAttributeValues) = (OpcUa_String*)OpcUa_Alloc((*iNoOfAttributes)*sizeof(OpcUa_String));
}
for (OpcUa_UInt32 iv = 0; iv < Attributes.size(); iv++)
{
OpcUa_String_Initialize(&(*ppszAttributes)[iv]);
OpcUa_String_Initialize(&(*ppAttributeValues)[iv]);
tAttribute* pAttribute = Attributes.at(iv);
OpcUa_String_CopyTo(&pAttribute->szAttr, &(*ppszAttributes)[iv]);
OpcUa_String_CopyTo(&pAttribute->szVal, &(*ppAttributeValues)[iv]);
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Represent any extensionObject asa sequence of byte put in a OpcUa_String. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 15/01/2017. </remarks>
///
/// <param name="byteString"> The byte string. </param>
/// <param name="extensionObject"> The extension object. </param>
/// <param name="ppStrValue"> [in,out] If non-null, the string value. </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_ExtensionObjectToString(OpcUa_Handle hApplication, OpcUa_Handle hSession,OpcUa_ExtensionObject* pExtensionObject,OpcUa_String** ppStrValue)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
OpenOpcUa_Definition* pDefinition = OpcUa_Null;
// first check if the dataTypeDictonnary is provided or not
//if (byteString.Length != 0)
{
OpcUa_NodeId aNodeId;
OpcUa_NodeId_Initialize(&aNodeId);
// First step we will find the namespaceIndex of the ExtensionObject to read
// Read 2255 NamespaceArray
OpcUa_NodeId nodeId;
OpcUa_NodeId_Initialize(&nodeId);
nodeId.IdentifierType = OpcUa_IdentifierType_Numeric;
nodeId.Identifier.Numeric = OpcUaId_Server_NamespaceArray;
OpcUa_Int32 iNodNodesToRead = 1;
OpcUa_ReadValueId* pNodesToRead = (OpcUa_ReadValueId*)OpcUa_Alloc(iNodNodesToRead*sizeof(OpcUa_ReadValueId));
OpcUa_ReadValueId_Initialize(&pNodesToRead[0]);
OpcUa_DataValue* pResults = OpcUa_Null;
pNodesToRead[0].AttributeId = OpcUa_Attributes_Value;
OpcUa_NodeId_CopyTo(&nodeId, &pNodesToRead[0].NodeId);
// Read attribute (value)
//CSessionClient* pSession = (CSessionClient*)hSession;
uStatus = OpenOpcUa_ReadAttributes(
hApplication,
hSession,
OpcUa_TimestampsToReturn_Both,
iNodNodesToRead,
pNodesToRead,
&pResults);
if (uStatus == OpcUa_Good)
{
if (pResults)
{
if ((pResults[0].Value.Datatype == OpcUaType_String) && (pResults[0].Value.ArrayType == OpcUa_VariantArrayType_Array))
{
OpcUa_Boolean bFound = OpcUa_False;
if (pExtensionObject->Body.EncodeableObject.Type->NamespaceUri)
{
OpcUa_String szUri;
OpcUa_String_Initialize(&szUri);
OpcUa_String_AttachCopy(&szUri, pExtensionObject->Body.EncodeableObject.Type->NamespaceUri);
for (OpcUa_Int32 i = 0; i < pResults[0].Value.Value.Array.Length; i++)
{
OpcUa_String szValue = pResults[0].Value.Value.Array.Value.StringArray[i];
if (OpcUa_String_Compare(&szValue, &szUri) == 0)
{
bFound = OpcUa_True;
aNodeId.NamespaceIndex = (OpcUa_UInt16)i;
aNodeId.Identifier.Numeric = pExtensionObject->Body.EncodeableObject.Type->TypeId;
break;
}
}
OpcUa_String_Clear(&szUri);
}
else
{
bFound = OpcUa_True;
aNodeId.Identifier.Numeric = pExtensionObject->Body.EncodeableObject.Type->TypeId;
}
OpcUa_DataValue_Clear(pResults);
OpcUa_Free(pResults);
if (bFound)
{
uStatus = OpenOpcUa_GetDataTypeDefinition(hApplication, hSession, aNodeId, &pDefinition);
if (uStatus == OpcUa_Good)
{
uStatus =InternalExtensionObjectToString(pDefinition,pExtensionObject->Body.EncodeableObject.Object, ppStrValue);
OpenOpcUa_Definition_Clear(pDefinition);
}
}
}
}
}
OpcUa_ReadValueId_Clear(&pNodesToRead[0]);
OpcUa_Free(pNodesToRead);
}
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary>
/// This function return the Binary representation of the Datatype Dictionnary available in
/// the server associate with the session handle.
/// </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 15/01/2017. </remarks>
///
/// <param name="hApplication"> The data type dictionnaries. </param>
/// <param name="hSession"> The session. </param>
/// <param name="puiNodeOfDataTypeDictionnary"> [out] Contains the number of DatatypeDictionnary return.
/// </param>
/// <param name="ppDataTypeDictionnaries"> [out] Contains the dataType dictionnaries.
/// </param>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_GetBinaryDataTypeDictionnaries(OpcUa_Handle hApplication, OpcUa_Handle hSession, OpcUa_UInt32* puiNodeOfDataTypeDictionnary, OpcUa_ByteString** ppDataTypeDictionnaries)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
std::vector<OpcUa_ByteString*> dataTypeDictionnaries;
OpcUa_Int32 iNoOfReferenceDescription = 0;
OpcUa_ReferenceDescription* pReferenceList = OpcUa_Null;
OpcUa_BrowseDescription* pNodesToBrowse = OpcUa_Null;
OpcUa_Int32 a_nNoOfNodesToBrowse = 1;
pNodesToBrowse = (OpcUa_BrowseDescription*)OpcUa_Alloc((sizeof(OpcUa_BrowseDescription)*a_nNoOfNodesToBrowse));
OpcUa_BrowseDescription_Initialize(&pNodesToBrowse[0]);
pNodesToBrowse[0].BrowseDirection = OpcUa_BrowseDirection_Forward;
pNodesToBrowse[0].IncludeSubtypes = true;
pNodesToBrowse[0].NodeClassMask = OpcUa_NodeClass_Variable; //
pNodesToBrowse[0].ResultMask = OpcUa_BrowseResultMask_All;
//Start browsing from pFromNodeId; nodeId i=93 (Opc Binary) this is a UAObject.
// It contains UAVariable of type ByteString. The ByteString value is a Base64 xsd encoded
OpcUa_NodeId* pFromNodeId = (OpcUa_NodeId*)OpcUa_Alloc(sizeof(OpcUa_NodeId));
OpcUa_NodeId_Initialize(pFromNodeId);
pFromNodeId->Identifier.Numeric = 93; // Opc Binary
OpcUa_NodeId_CopyTo(pFromNodeId, &(pNodesToBrowse[0].NodeId));
OpcUa_NodeId_Initialize(&(pNodesToBrowse[0].ReferenceTypeId));
pNodesToBrowse[0].ReferenceTypeId.IdentifierType = OpcUa_IdentifierType_Numeric;
pNodesToBrowse[0].ReferenceTypeId.NamespaceIndex = 0;
pNodesToBrowse[0].ReferenceTypeId.Identifier.Numeric = OpcUaId_HierarchicalReferences; //OpcUaId_References;
uStatus = OpenOpcUa_Browse(hApplication, hSession, a_nNoOfNodesToBrowse, pNodesToBrowse, &iNoOfReferenceDescription, &pReferenceList);
if (uStatus == OpcUa_Good)
{
for (OpcUa_Int32 i = 0; i < iNoOfReferenceDescription; i++)
{
if (pReferenceList[i].NodeClass == OpcUa_NodeClass_Variable)
{
// Get the ByteString from the UAVariable
// Decode with OpcUa_Base64_Decode
OpcUa_DataValue* pResults = OpcUa_Null;
OpcUa_ReadValueId* pNodesToRead = OpcUa_Null;
OpcUa_Int32 iNodNodesToRead = 0;
;
iNodNodesToRead = 1;
pNodesToRead = (OpcUa_ReadValueId*)OpcUa_Alloc(iNodNodesToRead*sizeof(OpcUa_ReadValueId));
OpcUa_ReadValueId_Initialize(&pNodesToRead[0]);
pNodesToRead[0].AttributeId = OpcUa_Attributes_Value;
OpcUa_NodeId_CopyTo(&pReferenceList[i].NodeId.NodeId,&pNodesToRead[0].NodeId);
// Read attribute (value)
uStatus = OpenOpcUa_ReadAttributes(
hApplication,
hSession,
OpcUa_TimestampsToReturn_Both,
iNodNodesToRead,
pNodesToRead,
&pResults);
// si la lecture aboutie on attends
if (uStatus == OpcUa_Good)
{
if (pResults)
{
// Extract the value
if (pResults[0].Value.Datatype != OpcUaType_ByteString)
uStatus = OpcUa_BadInternalError; // Read ok but wrong DataType
else
{
if (pResults[0].Value.ArrayType == OpcUa_VariantArrayType_Scalar)
{
OpcUa_ByteString* pDataTypeDictonnary = (OpcUa_ByteString*)OpcUa_Alloc(sizeof(OpcUa_ByteString));
OpcUa_ByteString_Initialize(pDataTypeDictonnary);
OpcUa_ByteString_CopyTo(&pResults[0].Value.Value.ByteString, pDataTypeDictonnary);
dataTypeDictionnaries.push_back(pDataTypeDictonnary);
}
else
uStatus = OpcUa_BadInternalError; // Read ok but wrong ArrayType
}
OpcUa_DataValue_Clear(pResults);
OpcUa_Free(pResults);
pResults = OpcUa_Null;
}
}
OpcUa_ReadValueId_Clear(pNodesToRead);
OpcUa_Free(pNodesToRead);
}
OpcUa_ReferenceDescription_Clear(&pReferenceList[i]);
}
OpcUa_Free(pReferenceList);
}
// Transfert from dataTypeDictionnary to OpcUa_ByteString*
if (dataTypeDictionnaries.size() > 0)
{
(*puiNodeOfDataTypeDictionnary) = dataTypeDictionnaries.size();
(*ppDataTypeDictionnaries) = (OpcUa_ByteString*)OpcUa_Alloc((*puiNodeOfDataTypeDictionnary) * sizeof(OpcUa_ByteString));
for (OpcUa_UInt32 i = 0; i < dataTypeDictionnaries.size(); i++)
{
OpcUa_ByteString_Initialize(&(*ppDataTypeDictionnaries)[i]);
OpcUa_ByteString* pdataTypeDisctionnary = dataTypeDictionnaries.at(i);
OpcUa_ByteString_CopyTo(pdataTypeDisctionnary, &(*ppDataTypeDictionnaries)[i]);
//
OpcUa_ByteString_Clear(pdataTypeDisctionnary);
OpcUa_Free(pdataTypeDisctionnary);
}
}
OpcUa_BrowseDescription_Clear(pNodesToBrowse);
OpcUa_Free(pNodesToBrowse);
OpcUa_NodeId_Clear(pFromNodeId);
OpcUa_Free(pFromNodeId);
return uStatus;
}
#define VarriantArray_SetAt(xArray, nIndex, xValue, xType) \
{ \
(xArray)[nIndex].Datatype = (OpcUa_Byte) OpcUaType_##xType; \
OpcUa_##xType##_Initialize(&(xArray)[nIndex].Value.xType); \
OpcUa_##xType##_CopyTo(xValue, &(xArray)[nIndex].Value.xType); \
}
#define VarriantArray_SetAtP(xArray, nIndex, xValue, xType) \
{ \
if (OpcUa_Null == (xArray)[nIndex].Value.xType) \
(xArray)[nIndex].Value.xType = (OpcUa_##xType*) OpcUa_Alloc(sizeof(OpcUa_##xType)); \
(xArray)[nIndex].Datatype = (OpcUa_Byte) OpcUaType_##xType; \
OpcUa_##xType##_Initialize((xArray)[nIndex].Value.xType); \
OpcUa_##xType##_CopyTo(xValue, (xArray)[nIndex].Value.xType); \
}
OpcUa_StatusCode OpenOpcUa_GetInstanceValue(OpcUa_NodeId* pSourceNodeId, OpenOpcUa_Definition* pDefinition, OpcUa_Variant rawValue,OpcUa_Variant** ppVariantVal)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
if (pSourceNodeId)
{
if (pDefinition)
{
if (pDefinition->m_baseType.Identifier.Numeric == OpcUaId_Structure)
{
// Expand the extensionObject in the ppVariantVal
OpcUa_UInt32 uiSize = pDefinition->m_uiNoOfField;
if (rawValue.ArrayType == OpcUa_VariantArrayType_Scalar)
{
(*ppVariantVal) = (OpcUa_Variant*)OpcUa_Alloc(uiSize*sizeof(OpcUa_Variant)); // Regular value
if (rawValue.Value.ExtensionObject)
{
OpcUa_Boolean bHandled = OpcUa_False;
void* pObject = rawValue.Value.ExtensionObject->Body.EncodeableObject.Object;
if (rawValue.Value.ExtensionObject->Body.EncodeableObject.Type)
{
if (OpcUaId_ServerStatusDataType == rawValue.Value.ExtensionObject->Body.EncodeableObject.Type->TypeId)
{
OpcUa_ServerStatusDataType* pStatus = (OpcUa_ServerStatusDataType*) pObject;
VarriantArray_SetAt(*ppVariantVal, 0, &pStatus->StartTime, DateTime); /* StartTime */
VarriantArray_SetAt(*ppVariantVal, 1, &pStatus->CurrentTime, DateTime); /* CurrentTime */
VarriantArray_SetAt(*ppVariantVal, 2, &pStatus->State, Int32); /* State */
VarriantArray_SetAt(*ppVariantVal, 3, &pStatus->BuildInfo.ProductUri, String); /* BuildInfo.ProductUri */
VarriantArray_SetAt(*ppVariantVal, 4, &pStatus->BuildInfo.ManufacturerName, String); /* BuildInfo.ManufacturerName */
VarriantArray_SetAt(*ppVariantVal, 5, &pStatus->BuildInfo.ProductName, String); /* BuildInfo.ProductName */
VarriantArray_SetAt(*ppVariantVal, 6, &pStatus->BuildInfo.SoftwareVersion, String); /* BuildInfo.SoftwareVersion */
VarriantArray_SetAt(*ppVariantVal, 7, &pStatus->BuildInfo.BuildNumber, String); /* BuildInfo.BuildNumber */
VarriantArray_SetAt(*ppVariantVal, 8, &pStatus->BuildInfo.BuildDate, DateTime); /* BuildInfo.BuildDate */
VarriantArray_SetAt(*ppVariantVal, 9, &pStatus->SecondsTillShutdown, UInt32); /* SecondsTillShutdown */
VarriantArray_SetAtP(*ppVariantVal, 10, &pStatus->ShutdownReason, LocalizedText); /* ShutdownReason */
/* clear ServerStatusDataType used */
OpcUa_ServerStatusDataType_Clear(pStatus);
bHandled = OpcUa_True;
}
}
if (!bHandled)
{
void* pObject = rawValue.Value.ExtensionObject->Body.EncodeableObject.Object;
for (OpcUa_UInt32 i = 0; i < uiSize; i++)
{
OpenOpcUa_Field* pField = pDefinition->m_pFields[i];
if (pField->m_DataType.NamespaceIndex == 0)
{
switch (pField->m_DataType.Identifier.Numeric)
{
case OpcUaType_Boolean:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.Boolean), 1, pObject, 1);
((OpcUa_Byte*&)pObject) += 1; //
}
break;
case OpcUaType_SByte:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.SByte), 1, pObject, 1);
((OpcUa_Byte*&)pObject) += 1; //
}
break;
case OpcUaType_Byte:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.Byte), 1, pObject, 1);
((OpcUa_Byte*&)pObject) += 1; //
}
break;
case OpcUaType_Int16:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.Int16), 2, pObject, 2);
((OpcUa_Byte*&)pObject) += 2; //
}
break;
case OpcUaType_UInt16:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.UInt16), 2, pObject, 2);
((OpcUa_Byte*&)pObject) += 2; //
}
break;
case OpcUaType_Int32:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.Int32), 4, pObject, 4);
((OpcUa_Byte*&)pObject) += 4; //
}
break;
case OpcUaType_UInt32:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.UInt32), 4, pObject, 4);
((OpcUa_Byte*&)pObject) += 4; //
}
break;
case OpcUaType_Int64:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.Int64), 8, pObject, 8);
((OpcUa_Byte*&)pObject) += 8; //
}
break;
case OpcUaType_UInt64:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.UInt64), 8, pObject, 8);
((OpcUa_Byte*&)pObject) += 8; //
}
break;
case OpcUaType_Float:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.Float), 4, pObject, 4);
((OpcUa_Byte*&)pObject) += 4; //
}
break;
case OpcUaType_Double:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.Double), 8, pObject, 8);
((OpcUa_Byte*&)pObject) += 8; //
}
break;
case OpcUaType_String:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_String_Initialize(&((*ppVariantVal)[i].Value.String));
uStatus = InternalExtractString(pObject, &((*ppVariantVal)[i].Value.String));
((OpcUa_Byte*&)pObject) += sizeof(OpcUa_String);
}
break;
case OpcUaType_DateTime:
{
(*ppVariantVal)[i].Datatype = (OpcUa_Byte)pField->m_DataType.Identifier.Numeric;
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.DateTime.dwLowDateTime), 4, pObject, 4);
((OpcUa_Byte*&)pObject) += 4; //
OpcUa_MemCpy(&((*ppVariantVal)[i].Value.DateTime.dwHighDateTime), 4, pObject, 4);
((OpcUa_Byte*&)pObject) += 4; //
}
break;
case OpcUaType_Guid:
break;
case OpcUaType_ByteString:
break;
case OpcUaType_NodeId:
break;
case OpcUaType_ExpandedNodeId:
break;
case OpcUaType_StatusCode:
break;
case OpcUaType_QualifiedName:
break;
case OpcUaType_LocalizedText:
break;
case OpcUaType_ExtensionObject:
// Search for this extension object in the DataType dictionnary
break;
case OpcUaType_DataValue:
break;
case OpcUaType_Variant:
break;
case OpcUaType_DiagnosticInfo:
break;
default:
uStatus = OpcUa_BadNotSupported;
break;
}
}
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
}
else
{
if (rawValue.ArrayType == OpcUa_VariantArrayType_Array)
{
for (OpcUa_Int32 i = 0; i < rawValue.Value.Array.Length; i++)
{
void* pObject = rawValue.Value.Array.Value.ExtensionObjectArray[i].Body.EncodeableObject.Object;
}
}
}
}
else
{
if (pDefinition->m_baseType.Identifier.Numeric == OpcUaId_Enumeration)
{
(*ppVariantVal) = (OpcUa_Variant*)OpcUa_Alloc(sizeof(OpcUa_Variant)); // Regular value
OpcUa_Variant_Initialize((*ppVariantVal));
OpenOpcUa_Field* pField = pDefinition->m_pFields[rawValue.Value.UInt32];
(*ppVariantVal)->Datatype = OpcUaType_String;
OpcUa_String_Initialize(&(*ppVariantVal)->Value.String);
OpcUa_String_CopyTo(&pField->m_Name,&((*ppVariantVal)->Value.String));
}
else
{
(*ppVariantVal) = (OpcUa_Variant*)OpcUa_Alloc(sizeof(OpcUa_Variant)); // Regular value
OpcUa_Variant_Initialize((*ppVariantVal));
OpcUa_Variant_CopyTo(&rawValue, (*ppVariantVal));
}
}
}
else
uStatus = OpcUa_BadInvalidArgument;
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA definition initialize. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 18/04/2017. </remarks>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_Definition_Initialize(OpenOpcUa_Definition* pDefinition)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
if (pDefinition)
{
ZeroMemory(pDefinition, sizeof(OpenOpcUa_Definition));
OpcUa_String_Initialize(&pDefinition->m_Description);
OpcUa_String_Initialize(&pDefinition->m_Name);
OpcUa_NodeId_Initialize(&pDefinition->m_baseType);
OpcUa_NodeId_Initialize(&pDefinition->m_Type);
pDefinition->m_uiNoOfField = 0;
pDefinition->m_pFields = OpcUa_Null;
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
///-------------------------------------------------------------------------------------------------
/// <summary> Opens opc UA definition clear. </summary>
///
/// <remarks> Michel Condemine - OpenOpcUa, 18/04/2017. </remarks>
///
/// <returns> An OpcUa_StatusCode. </returns>
///-------------------------------------------------------------------------------------------------
OpcUa_StatusCode OpenOpcUa_Definition_Clear(OpenOpcUa_Definition* pDefinition)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
if (pDefinition)
{
OpcUa_NodeId_Clear(&pDefinition->m_baseType);
OpcUa_String_Clear(&pDefinition->m_Description);
OpcUa_String_Clear(&pDefinition->m_Name);
OpcUa_NodeId_Clear(&pDefinition->m_Type);
OpenOpcUa_Field** pFields = pDefinition->m_pFields;
for (OpcUa_UInt32 i = 0; i < pDefinition->m_uiNoOfField; i++)
{
OpenOpcUa_Field* pField=pFields[i];
OpenOpcUa_Field_Clear(pField);
OpcUa_Free(pField);
}
OpcUa_Free(pDefinition->m_pFields);
pDefinition->m_pFields = OpcUa_Null;
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
// Not exported
OpenOpcUa_Definition* Copy(OpenOpcUa_Definition* pDefinition);
OpenOpcUa_Field* Copy(OpenOpcUa_Field* pField);
OpcUa_StatusCode OpenOpcUa_Definition_AddField(OpenOpcUa_Definition* pDefinition, OpenOpcUa_Field* pNewField)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
// Save the exisiting Field
OpenOpcUa_Fields fieldList;
for (OpcUa_UInt32 i = 0; i < pDefinition->m_uiNoOfField; i++)
{
OpenOpcUa_Field* pField = pDefinition->m_pFields[i];
// Do not copy but use directly
//fieldList.push_back(Copy(pField));
fieldList.push_back(pField);
}
// Add the newOne
fieldList.push_back(pNewField);
if (pDefinition->m_pFields)
{
// Expand the pDefinition->m_pFields
/* No need to free since they were added back to fieldList above
for (OpcUa_UInt32 ii = 0; ii < pDefinition->m_uiNoOfField; ii++)
{
OpenOpcUa_Field_Clear(pDefinition->m_pFields[ii]);
OpcUa_Free(pDefinition->m_pFields[ii]);
pDefinition->m_pFields[ii] = OpcUa_Null;
}
*/
OpcUa_Free(pDefinition->m_pFields);
pDefinition->m_pFields = OpcUa_Null;
}
// Allocate for the new size
if (!pDefinition->m_pFields)
{
pDefinition->m_pFields = (OpenOpcUa_Field**)OpcUa_Alloc(fieldList.size()*sizeof(OpenOpcUa_Field*));
/* no need to allocate memory here wich will be replaced just below
for (OpcUa_UInt32 ii = 0; ii < fieldList.size(); ii++)
{
pDefinition->m_pFields[ii] = (OpenOpcUa_Field*)OpcUa_Alloc(sizeof(OpenOpcUa_Field));
ZeroMemory(pDefinition->m_pFields[ii], sizeof(OpenOpcUa_Field));
}
*/
}
pDefinition->m_uiNoOfField = fieldList.size();
for (OpcUa_UInt32 i = 0; i < fieldList.size(); i++)
{
OpenOpcUa_Field* pField = fieldList.at(i);
pDefinition->m_pFields[i] = pField;
}
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_Field_Initialize(OpenOpcUa_Field* pField)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
if (pField)
{
OpcUa_NodeId_Initialize(&pField->m_DataType);
OpcUa_String_Initialize(&pField->m_Description);
pField->m_FieldType = UNKNOWN_FIELD;
pField->m_iFieldSize = 0;
OpcUa_String_Initialize(&pField->m_Name);
pField->m_pDefinition = OpcUa_Null;
OpcUa_String_Initialize(&pField->m_SymbolicName);
OpcUa_String_Initialize(&pField->m_TypeName);
OpcUa_Variant_Initialize(&pField->m_Value);
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
OpcUa_StatusCode OpenOpcUa_Field_Clear(OpenOpcUa_Field* pField)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
if (pField)
{
OpcUa_NodeId_Clear(&pField->m_DataType);
OpcUa_String_Clear(&pField->m_Description);
pField->m_FieldType = UNKNOWN_FIELD;
pField->m_iFieldSize = 0;
OpcUa_String_Clear(&pField->m_Name);
pField->m_pDefinition = OpcUa_Null;
OpcUa_String_Clear(&pField->m_SymbolicName);
OpcUa_String_Clear(&pField->m_TypeName);
OpcUa_Variant_Clear(&pField->m_Value);
}
else
uStatus = OpcUa_BadInvalidArgument;
return uStatus;
}
OpenOpcUa_Field* Copy(OpenOpcUa_Field* pField)
{
OpenOpcUa_Field* pNewField= (OpenOpcUa_Field*)OpcUa_Alloc(sizeof(OpenOpcUa_Field));
OpenOpcUa_Field_Initialize(pNewField);
OpcUa_NodeId_CopyTo(&pField->m_DataType,&pNewField->m_DataType);
OpcUa_String_CopyTo(&pField->m_Description,&pNewField->m_Description);
pNewField->m_FieldType = pField->m_FieldType;
pNewField->m_iFieldSize = pField->m_iFieldSize;
OpcUa_String_CopyTo(&pField->m_Name,&pNewField->m_Name);
pNewField->m_pDefinition = (void*)pField->m_pDefinition; //Copy((OpenOpcUa_Definition*)pField->m_pDefinition);
OpcUa_String_CopyTo(&pField->m_SymbolicName, &pNewField->m_SymbolicName);
OpcUa_String_CopyTo(&pField->m_TypeName, &pNewField->m_TypeName);
OpcUa_Variant_CopyTo(&pField->m_Value, &pNewField->m_Value);
return pNewField;
}
OpenOpcUa_Definition* Copy(OpenOpcUa_Definition* pDefinition)
{
OpenOpcUa_Definition* pNewDefinition = (OpenOpcUa_Definition*)OpcUa_Alloc(sizeof(OpenOpcUa_Definition));
OpenOpcUa_Definition_Initialize(pNewDefinition);
OpcUa_NodeId_CopyTo(&pDefinition->m_baseType, &pNewDefinition->m_baseType);
pNewDefinition->m_bUnion = pDefinition->m_bUnion;
OpcUa_String_CopyTo(&pDefinition->m_Description,&pNewDefinition->m_Description);
pNewDefinition->m_LengthInBits = pDefinition->m_LengthInBits;
OpcUa_String_CopyTo(&pDefinition->m_Name,&pNewDefinition->m_Name);
for (OpcUa_UInt32 i = 0; i < pDefinition->m_uiNoOfField; i++)
{
OpenOpcUa_Field* pField = pDefinition->m_pFields[i];
OpenOpcUa_Field* pNewField = Copy(pField);
OpenOpcUa_Definition_AddField(pNewDefinition, pNewField);
}
OpcUa_NodeId_CopyTo(&pDefinition->m_Type,&pNewDefinition->m_Type) ;
pNewDefinition->m_uiNoOfField = pDefinition->m_uiNoOfField;
return pNewDefinition;
}