#include "democlient.h"
#include <opcua_memory.h>
#include <opcua_datetime.h>
#include <opcua_string.h>
#include <opcua_proxystub.h>
#include <opcua_trace.h>
#include <opcua_pkifactory.h>
#include <uaclient_module.h>
#include <uaclient_discovery.h>
#include <uaclient_session.h>
#include <uaclient_subscription.h>
#include <uabase_p_filesystem.h>
#if OPCUA_SUPPORT_PKI && UABASE_USE_FILESYSTEM
# include <uabase_pki.h>
#endif
#define UACLIENT_APPLICATION_NAME "UaClientC@[gethostname]"
#define UACLIENT_APPLICATION_URI "urn:[gethostname]:UnifiedAutomation:UaDemoClientAnsiC"
#define UACLIENT_PRODUCT_NAME "ANSI C SDK UA Sample Client"
#define UACLIENT_PRODUCT_URI "urn:UnifiedAutomation:UaDemoClientAnsiC"
static OpcUa_Handle g_hProxyStubPlatformLayer = OpcUa_Null;
#ifdef WIN32
#include <conio.h>
#else
#include <termios.h>
#include <unistd.h>
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard()
{
printf("Initializing keyboard.\n");
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard()
{
printf("Restoring keyboard settings.\n");
tcsetattr(0, TCSANOW, &initial_settings);
}
int _kbhit()
{
unsigned char ch;
int nread;
if (peek_character != -1) return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if (nread == 1)
{
peek_character = ch;
return 1;
}
return 0;
}
int _getch()
{
char ch = 0;
ssize_t ret;
if (peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
ret = read(0,&ch,1);
OpcUa_ReferenceParameter(ret);
return ch;
}
#endif
int InitializeOpcUaStack(OpcUa_UInt32 uTraceLevel)
{
OpcUa_StatusCode uStatus;
OpcUa_ProxyStubConfiguration proxyStubConfiguration;
printf( "UA Client: Initializing Stack...\n" );
proxyStubConfiguration.bProxyStub_Trace_Enabled = OpcUa_True;
proxyStubConfiguration.uProxyStub_Trace_Level = uTraceLevel;
return uStatus;
}
void CleanupOpcUaStack()
{
}
#if OPCUA_SUPPORT_PKI && UABASE_USE_FILESYSTEM
void SetupPKIInfrastructure(
UaBase_Settings *pSettings,
const char *szHostname)
{
OpcUa_Int iRet;
OpcUa_StatusCode uStatus = OpcUa_Good;
UaBase_File *pFile = OpcUa_Null;
OpcUa_Boolean bGenerateCertificate = OpcUa_False;
OpcUa_Boolean bCertAvailable = OpcUa_True;
char szCertificateFile[UABASE_PATH_MAX];
char szCertificateKeyFile[UABASE_PATH_MAX];
char szTrustListPath[UABASE_PATH_MAX];
char szCRLPath[UABASE_PATH_MAX];
char szIssuerTrustListPath[UABASE_PATH_MAX];
char szIssuerCRLPath[UABASE_PATH_MAX];
if (iRet !=
UABASE_SUCCESS) {printf(
"Could not create trust list path (ret=%i)\n", iRet);}
if (iRet !=
UABASE_SUCCESS) {printf(
"Could not create CRL path (ret=%i)\n", iRet);}
if (iRet !=
UABASE_SUCCESS) {printf(
"Could not create issuer trust list path (ret=%i)\n", iRet);}
if (iRet !=
UABASE_SUCCESS) {printf(
"Could not create issuer CRL path (ret=%i)\n", iRet);}
if (bGenerateCertificate == OpcUa_False)
{
return;
}
pFile = UaBase_Fopen( szCertificateFile, "r" );
if ( pFile != NULL )
{
UaBase_Fclose( pFile );
}
else
{
bCertAvailable = OpcUa_False;
}
pFile = UaBase_Fopen( szCertificateKeyFile, "r" );
if ( pFile != NULL )
{
UaBase_Fclose( pFile );
}
else
{
bCertAvailable = OpcUa_False;
}
pFile = NULL;
if ( bCertAvailable == OpcUa_False )
{
char szPath[UABASE_PATH_MAX];
char szCommonName[UABASE_PATH_MAX];
char szOrganization[UABASE_PATH_MAX];
char szOrganizationUnit[UABASE_PATH_MAX];
char szLocality[UABASE_PATH_MAX];
char szState[UABASE_PATH_MAX];
char szCountry[UABASE_PATH_MAX];
char szApplicationName[UABASE_PATH_MAX] = UACLIENT_APPLICATION_NAME;
char szApplicationURI[UABASE_PATH_MAX] = UACLIENT_APPLICATION_URI;
OpcUa_UInt iYearsValidFor = 0;
OpcUa_UInt iKeyLength = 0;
UaBase_Settings_ReplaceString(szApplicationURI, sizeof(szApplicationURI), "[gethostname]", szHostname);
UaBase_Settings_ReplaceString(szApplicationName, sizeof(szApplicationName), "[gethostname]", szHostname);
UaBase_Settings_ReplaceString(szCommonName, sizeof(szCommonName), "[ApplicationName]", szApplicationName);
if (OpcUa_IsNotGood(uStatus)) {printf("UaClient_PkiRsaKeyPair_Create failed (ret=0x%08x)\n", uStatus);}
certificateInfo.sURI = szApplicationURI;
certificateInfo.
sIP =
"";
certificateInfo.
sDNS = (OpcUa_StringA)szHostname;
certificateInfo.sEMail = "";
certificateInfo.validTime = 3600 * 24 * 365 * iYearsValidFor;
subject.sCommonName = szCommonName;
subject.sOrganization = szOrganization;
subject.sOrganizationUnit = szOrganizationUnit;
subject.sLocality = szLocality;
subject.sState = szState;
subject.sCountry = szCountry;
subject.sDomainComponent = "";
&pCertificate,
certificateInfo,
subject,
*pSubjectKeyPair,
subject,
*pSubjectKeyPair );
if (OpcUa_IsNotGood(uStatus)) {printf("UaClient_PkiCertificate_Create failed (ret=0x%08x)\n", uStatus);}
strlcpy(szPath, szCertificateFile, sizeof(szPath));
if (iRet !=
UABASE_SUCCESS) {printf(
"Could not create certificate path (ret=%i)\n", iRet);}
if (OpcUa_IsNotGood(uStatus)) {printf("UaClient_PkiCertificate_ToDERFile failed (ret=0x%08x)\n", uStatus);}
strlcpy(szPath, szCertificateKeyFile, sizeof(szPath));
if (iRet !=
UABASE_SUCCESS) {printf(
"Could not create private key path (ret=%i)\n", iRet);}
if (OpcUa_IsNotGood(uStatus)) {printf("UaClient_PkiRsaKeyPair_ToPEMFile failed (ret=0x%08x)\n", uStatus);}
}
}
#endif
void PrintActions()
{
printf("\n");
printf("-------------------------------------------------------\n");
printf("- Press x to close client -\n");
printf("-------------------------------------------------------\n");
printf("- Press 0 to start discovery -\n");
printf("- Press 1 to connect to server -\n");
printf("- Press 2 to connect to server w. AutomaticReconnect -\n");
printf("- Press 3 to disconnect from server -\n");
printf("- Press 4 to read values -\n");
printf("- Press 5 to create a subscription -\n");
printf("- Press 6 to modify a subscription -\n");
printf("- Press 7 to delete a subscription -\n");
printf("- Press 8 to create monitored items -\n");
printf("- Press 9 to delete monitored items -\n");
printf("-------------------------------------------------------\n");
printf("\n");
}
typedef struct _Demo_Discovery
{
OpcUa_String DiscoveryUrl;
OpcUa_List lstDiscoveryUrls;
OpcUa_List lstEndpoints;
} Demo_Discovery;
OpcUa_Int32 a_NoOfServers,
OpcUa_Void *a_pUserData)
{
Demo_Discovery *pDemoDiscovery = (Demo_Discovery*)a_pUserData;
OpcUa_ReferenceParameter(a_pDiscovery);
{
OpcUa_Int32 i, j;
printf(
"Demo_FindServers_CB result (0x%08x):\n", a_pResponseHeader->
ServiceResult);
for (i = 0; i < a_NoOfServers; i++)
{
printf("[%i] %s:\n", i, OpcUa_String_GetRawString(&a_pServers[i].ApplicationName.Text));
for (j = 0; j < a_pServers[i].NoOfDiscoveryUrls; j++)
{
OpcUa_String *pCopy = OpcUa_Alloc(sizeof(OpcUa_String));
OpcUa_String_Initialize(&a_pServers[i].DiscoveryUrls[j]);
OpcUa_List_AddElementToEnd(&pDemoDiscovery->lstDiscoveryUrls, pCopy);
printf(" %s\n", OpcUa_String_GetRawString(pCopy));
}
}
}
else
{
printf(
"Demo_FindServers_CB: bad status (0x%08x)\n", a_pResponseHeader->
ServiceResult);
PrintActions();
}
}
OpcUa_Int32 a_NoOfEndpoints,
OpcUa_Void *a_pUserData)
{
Demo_Discovery *pDemoDiscovery = (Demo_Discovery*)a_pUserData;
OpcUa_ReferenceParameter(a_pDiscovery);
{
OpcUa_Int32 i;
printf(
"Demo_GetEndpoints_CB result (0x%08x):\n", a_pResponseHeader->
ServiceResult);
for (i = 0; i < a_NoOfEndpoints; i++)
{
*pCopy = a_pEndpoints[i];
OpcUa_EndpointDescription_Initialize(&a_pEndpoints[i]);
OpcUa_List_AddElementToEnd(&pDemoDiscovery->lstEndpoints, pCopy);
printf(
"[%i]: %s\n", i, OpcUa_String_GetRawString(&pCopy->
EndpointUrl));
}
}
else
{
printf(
"Demo_GetEndpoints_CB: bad status (0x%08x)\n", a_pResponseHeader->
ServiceResult);
PrintActions();
}
}
{
const char *pStatus = "INVALID";
OpcUa_ReferenceParameter(a_pSession);
switch (a_status)
{
default: break;
}
printf("\n--> Demo_ConnectionStatusChanged_CB: %s\n\n", pStatus);
}
OpcUa_StatusCode a_error,
OpcUa_Boolean a_clientSideError)
{
const char *pServiceType = "INVALID";
OpcUa_ReferenceParameter(a_pSession);
switch (a_serviceType)
{
default: break;
}
printf("Demo_ConnectError_CB:\n");
printf(" ServiceType: %s\n", pServiceType);
printf(" Error: 0x%08x\n", a_error);
printf(" ClientSideError: %s\n", a_clientSideError == OpcUa_False ? "false" : "true");
return OpcUa_False;
}
OpcUa_Int32 a_NoOfResults,
OpcUa_DataValue *a_pResults,
OpcUa_Int32 a_NoOfDiagnosticInfos,
OpcUa_DiagnosticInfo *a_pDiagnosticInfos,
OpcUa_Void *a_pUserData)
{
OpcUa_ReferenceParameter(a_pSession);
OpcUa_ReferenceParameter(a_NoOfDiagnosticInfos);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
OpcUa_ReferenceParameter(a_pUserData);
{
OpcUa_Int32 i;
printf("Demo_Read_CB:\n");
for (i = 0; i < a_NoOfResults; i++)
{
char szSourceTimestamp[64] = {0};
char szServerTimestamp[64] = {0};
OpcUa_DateTime_GetStringFromDateTime(a_pResults[i].SourceTimestamp, szSourceTimestamp, sizeof(szSourceTimestamp));
OpcUa_DateTime_GetStringFromDateTime(a_pResults[i].ServerTimestamp, szServerTimestamp, sizeof(szServerTimestamp));
printf(" [%i]:\n", i);
printf(" Status: 0x%08x\n", a_pResults[i].StatusCode);
printf(" SourceTimestamp: %s\n", szSourceTimestamp);
printf(" ServerTimestamp: %s\n", szServerTimestamp);
printf(" Value: %i\n", a_pResults[i].Value.Value.Int32);
}
}
else
{
printf(
"Demo_Read_CB failed (0x%08x)\n", a_pResponseHeader->
ServiceResult);
}
PrintActions();
}
{
OpcUa_ReadValueId_Initialize(&nodeToRead);
nodeToRead.
NodeId.NamespaceIndex = 0;
nodeToRead.
NodeId.IdentifierType = OpcUa_IdentifierType_Numeric;
nodeToRead.
NodeId.Identifier.Numeric = OpcUaId_Server_ServerStatus_State;
OpcUa_Null,
0,
1,
&nodeToRead,
Demo_Read_CB,
OpcUa_Null);
}
OpcUa_StatusCode a_status,
OpcUa_Void *a_pUserData)
{
OpcUa_ReferenceParameter(a_pResponseHeader);
OpcUa_ReferenceParameter(a_pUserData);
if (OpcUa_IsGood(a_status))
{
printf("Demo_CreateSubscription_CB succeeded (0x%08x)\n", a_status);
}
else
{
printf("Demo_CreateSubscription_CB failed (0x%08x)\n", a_status);
}
PrintActions();
}
OpcUa_StatusCode a_status,
OpcUa_Void *a_pUserData)
{
OpcUa_ReferenceParameter(a_pResponseHeader);
OpcUa_ReferenceParameter(a_pUserData);
if (OpcUa_IsGood(a_status))
{
printf("Demo_ModifySubscription_CB succeeded (0x%08x)\n", a_status);
}
else
{
printf("Demo_ModifySubscription_CB failed (0x%08x)\n", a_status);
}
PrintActions();
}
OpcUa_StatusCode a_status,
OpcUa_Void *a_pUserData)
{
OpcUa_ReferenceParameter(a_pUaSubscription);
OpcUa_ReferenceParameter(a_pResponseHeader);
OpcUa_ReferenceParameter(a_pUserData);
if (OpcUa_IsGood(a_status))
{
printf("Demo_DeleteSubscription_CB succeeded (0x%08x)\n", a_status);
}
else
{
printf("Demo_DeleteSubscription_CB failed (0x%08x)\n", a_status);
}
PrintActions();
}
OpcUa_Int32 a_NoOfResults,
OpcUa_Int32 a_NoOfDiagnosticInfos,
OpcUa_DiagnosticInfo *a_pDiagnosticInfos,
OpcUa_Void *a_pUserData)
{
OpcUa_StatusCode uStatus;
OpcUa_UInt32 *pMonitoredItemId = a_pUserData;
OpcUa_ReferenceParameter(a_pSubscription);
OpcUa_ReferenceParameter(a_NoOfDiagnosticInfos);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
OpcUa_ReferenceParameter(a_pUserData);
if (OpcUa_IsGood(uStatus))
{
}
if (OpcUa_IsGood(uStatus) && a_NoOfResults == 1)
{
printf("Demo_CreateMonitoredItems_CB succeeded (0x%08x)\n", uStatus);
printf(" MonitoredItemId: %u\n", a_pResults[0].MonitoredItemId);
printf(" RevisedSamplingInterval: %f\n", a_pResults[0].RevisedSamplingInterval);
printf(" RevisedQueueSize: %u\n", a_pResults[0].RevisedQueueSize);
}
else
{
printf("Demo_CreateMonitoredItems_CB failed (0x%08x)\n", uStatus);
}
PrintActions();
}
OpcUa_Int32 a_NoOfResults,
OpcUa_StatusCode *a_pResults,
OpcUa_Int32 a_NoOfDiagnosticInfos,
OpcUa_DiagnosticInfo *a_pDiagnosticInfos,
OpcUa_Void *a_pUserData)
{
OpcUa_StatusCode uStatus;
OpcUa_ReferenceParameter(a_pSubscription);
OpcUa_ReferenceParameter(a_NoOfDiagnosticInfos);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
OpcUa_ReferenceParameter(a_pUserData);
if (OpcUa_IsGood(uStatus))
{
uStatus = a_pResults[0];
}
if (OpcUa_IsGood(uStatus) && a_NoOfResults == 1)
{
printf("Demo_DeleteMonitoredItems_CB succeeded (0x%08x)\n", uStatus);
}
else
{
printf("Demo_DeleteMonitoredItems_CB failed (0x%08x)\n", uStatus);
}
PrintActions();
}
OpcUa_StatusCode a_status)
{
OpcUa_ReferenceParameter(a_pSubscription);
printf("Demo_Subscription_StatusChanged_CB (0x%08x)\n", a_status);
}
{
OpcUa_ReferenceParameter(a_pSubscription);
printf("Demo_Subscription_KeepAlive_CB\n");
}
OpcUa_UInt32 a_previousSequenceNumber,
OpcUa_UInt32 a_newSequenceNumber)
{
OpcUa_ReferenceParameter(a_pSubscription);
printf("Demo_Subscription_NotificationsMissing_CB\n");
printf(" PreviousSequenceNumber: %u\n", a_previousSequenceNumber);
printf(" NewSequenceNumber: %u\n", a_newSequenceNumber);
}
OpcUa_Int32 a_noOfMonitoredItems,
OpcUa_MonitoredItemNotification *a_pMonitoredItems,
OpcUa_Int32 a_noOfDiagnosticInfos,
OpcUa_DiagnosticInfo *a_pDiagnosticInfos)
{
OpcUa_Int32 i;
OpcUa_ReferenceParameter(a_pSubscription);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
printf("Demo_Subscription_DataChange_CB\n");
printf(" noOfMonitoredItems: %i\n", a_noOfMonitoredItems);
for (i = 0; i < a_noOfMonitoredItems; i++)
{
OpcUa_CharA szDateTime[64] = {0};
printf(" [%i]:\n", i);
printf(" ClientHandle: %u\n", a_pMonitoredItems[i].ClientHandle);
printf(" StatusCode: 0x%08x\n", a_pMonitoredItems[i].Value.StatusCode);
if (OpcUa_IsGood(a_pMonitoredItems[i].Value.StatusCode))
{
OpcUa_DateTime_GetStringFromDateTime(a_pMonitoredItems[i].Value.SourceTimestamp, szDateTime, sizeof(szDateTime));
printf(" SourceTimestamp: %s\n", szDateTime);
OpcUa_DateTime_GetStringFromDateTime(a_pMonitoredItems[i].Value.ServerTimestamp, szDateTime, sizeof(szDateTime));
printf(" ServerTimestamp: %s\n", szDateTime);
OpcUa_DateTime_GetStringFromDateTime(a_pMonitoredItems[i].Value.Value.Value.DateTime, szDateTime, sizeof(szDateTime));
printf(" Value: %s\n", szDateTime);
}
}
printf(" noOfDiagnosticInfos: %i\n", a_noOfDiagnosticInfos);
}
OpcUa_Int32 a_noOfEvents,
OpcUa_EventFieldList *a_pEvents)
{
OpcUa_ReferenceParameter(a_pSubscription);
OpcUa_ReferenceParameter(a_pEvents);
printf("Demo_Subscription_NewEvents_CB\n");
printf(" noOfEvents: %i\n", a_noOfEvents);
}
int ClientMain(
UaBase_Settings *pSettings,
const char *szHostname,
const char *szUrl)
{
OpcUa_StatusCode uStatus = OpcUa_Good;
OpcUa_Boolean bClientInitialized = OpcUa_False;
OpcUa_Boolean bShutdown = OpcUa_False;
Demo_Discovery demoDiscovery;
OpcUa_String *pDiscoveryUrl;
char szValue[UABASE_PATH_MAX] = {0};
OpcUa_UInt32 monitoredItemId = 0;
OpcUa_DeclareErrorTraceModule( OpcUa_Module_Client );
OpcUa_ReferenceParameter(pSettings);
OpcUa_GotoErrorIfBad( uStatus );
bClientInitialized = OpcUa_True;
OpcUa_GotoErrorIfBad( uStatus );
uStatus = UaClient_Discovery_Create(&demoDiscovery.pDiscovery);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_List_Initialize(&demoDiscovery.lstDiscoveryUrls);
OpcUa_List_Initialize(&demoDiscovery.lstEndpoints);
OpcUa_MemSet(&sessionCallback, 0, sizeof(sessionCallback));
sessionCallback.pfConnectionStatusChanged_CB = Demo_ConnectionStatusChanged_CB;
sessionCallback.pfConnectError_CB = Demo_ConnectError_CB;
OpcUa_MemSet(&subscriptionCallback, 0, sizeof(subscriptionCallback));
subscriptionCallback.pfStatusChanged_CB = Demo_Subscription_StatusChanged_CB;
subscriptionCallback.pfKeepAlive_CB = Demo_Subscription_KeepAlive_CB;
subscriptionCallback.pfNotificationsMissing_CB = Demo_Subscription_NotificationsMissing_CB;
subscriptionCallback.pfDataChange_CB = Demo_Subscription_DataChange_CB;
subscriptionCallback.pfNewEvents_CB = Demo_Subscription_NewEvents_CB;
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_GotoErrorIfBad(uStatus);
if (szUrl == OpcUa_Null || strlen(szUrl) <= 0)
{
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_GotoErrorIfBad(uStatus);
if (uStatus == OpcUa_UncertainSubstituteValue)
{
OpcUa_GotoErrorIfBad(uStatus);
}
}
else
{
uStatus = OpcUa_String_AttachCopy(&demoDiscovery.DiscoveryUrl, szUrl);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_GotoErrorIfBad(uStatus);
}
OpcUa_GotoErrorIfBad(uStatus);
if (strcmp(szValue, "Anonymous") == 0)
{
pSession->UserToken.TokenType = OpcUa_UserTokenType_Anonymous;
}
else if (strcmp(szValue, "UserName") == 0)
{
pSession->UserToken.TokenType = OpcUa_UserTokenType_UserName;
OpcUa_String_Initialize(&pSession->UserToken.Token.UserName.User);
OpcUa_String_Initialize(&pSession->UserToken.Token.UserName.Password);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_GotoErrorIfBad(uStatus);
}
else if (strcmp(szValue, "Certificate") == 0)
{
OpcUa_PKIProvider PKIProvider;
OpcUa_CertificateStoreConfiguration PKIConfig;
OpcUa_Handle hCertificateStore = OpcUa_Null;
OpcUa_MemSet(&PKIProvider, 0, sizeof(PKIProvider));
OpcUa_CertificateStoreConfiguration_Initialize(&PKIConfig);
pSession->UserToken.TokenType = OpcUa_UserTokenType_Certificate;
OpcUa_ByteString_Initialize(&pSession->UserToken.Token.X509.UserCertificate);
OpcUa_ByteString_Initialize(&pSession->UserToken.Token.X509.UserPrivateKey);
PKIConfig.strPkiType = (char*)OPCUA_P_PKI_TYPE_OPENSSL;
OpcUa_GotoErrorIfBad(uStatus);
PKIConfig.strTrustedCertificateListLocation = szValue;
uStatus = OpcUa_PKIProvider_Create(&PKIConfig, &PKIProvider);
OpcUa_GotoErrorIfBad(uStatus);
uStatus = PKIProvider.OpenCertificateStore(&PKIProvider,
&hCertificateStore);
OpcUa_GotoErrorIfBad(uStatus);
uStatus = PKIProvider.LoadCertificate(&PKIProvider,
szValue,
hCertificateStore,
&pSession->UserToken.Token.X509.UserCertificate);
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_GotoErrorIfBad(uStatus);
uStatus = PKIProvider.LoadPrivateKeyFromFile(szValue,
OpcUa_Crypto_Encoding_PEM,
OpcUa_Null,
&pSession->UserToken.Token.X509.UserPrivateKey);
OpcUa_GotoErrorIfBad(uStatus);
uStatus = PKIProvider.CloseCertificateStore(&PKIProvider, &hCertificateStore);
OpcUa_GotoErrorIfBad(uStatus);
}
OpcUa_GotoErrorIfBad( uStatus );
#ifndef WIN32
init_keyboard();
#endif
PrintActions();
while ( OpcUa_IsGood( uStatus ) )
{
if (bShutdown == OpcUa_False)
{
OpcUa_UInt32 uNoOfDiscoveryUrls = 0, uNoOfEndpoints = 0;
OpcUa_List_GetNumberOfElements(&demoDiscovery.lstDiscoveryUrls, &uNoOfDiscoveryUrls);
OpcUa_List_GetNumberOfElements(&demoDiscovery.lstEndpoints, &uNoOfEndpoints);
if (uNoOfDiscoveryUrls > 0 && demoDiscovery.pDiscovery->Connected == OpcUa_False)
{
pDiscoveryUrl = OpcUa_List_RemoveFirstElement(&demoDiscovery.lstDiscoveryUrls);
OpcUa_String_Clear(&demoDiscovery.DiscoveryUrl);
demoDiscovery.DiscoveryUrl = *pDiscoveryUrl;
OpcUa_Free(pDiscoveryUrl);
OpcUa_Null,
&demoDiscovery.DiscoveryUrl,
0,
OpcUa_Null,
0,
OpcUa_Null,
Demo_GetEndpoints_CB,
&demoDiscovery);
OpcUa_GotoErrorIfBad(uStatus);
}
else if (uNoOfDiscoveryUrls == 0 && uNoOfEndpoints > 0 && demoDiscovery.pDiscovery->Connected == OpcUa_False)
{
OpcUa_UInt32 i = 0;
int iChosen = -1;
printf("Select one of the following endpoints by pressing the according key:\n");
OpcUa_List_ResetCurrent(&demoDiscovery.lstEndpoints);
pEndpoint = OpcUa_List_GetCurrentElement(&demoDiscovery.lstEndpoints);
while (pEndpoint)
{
printf("[%i]:\n", i);
printf(
" EndpointUrl: %s\n", OpcUa_String_GetRawString(&pEndpoint->
EndpointUrl));
printf(" SecurityMode: %s\n", szSecurityMode);
printf(
" SecurityMode: %s\n", OpcUa_String_GetRawString(&pEndpoint->
SecurityPolicyUri));
pEndpoint = OpcUa_List_GetNextElement(&demoDiscovery.lstEndpoints);
i++;
}
while (iChosen == -1)
{
iChosen = _getch() - '0';
if (iChosen >= 0 && iChosen < (int)uNoOfEndpoints)
{
i = 0;
OpcUa_List_ResetCurrent(&demoDiscovery.lstEndpoints);
pEndpoint = OpcUa_List_GetCurrentElement(&demoDiscovery.lstEndpoints);
while (pEndpoint)
{
if (i == (OpcUa_UInt32)iChosen)
{
OpcUa_String sUrl;
OpcUa_String_Initialize(&sUrl);
printf("Using endpoint #%i\n", i);
OpcUa_EndpointDescription_Initialize(pEndpoint);
#if OPCUA_SUPPORT_PKI
OpcUa_String_FromCString(OpcUa_SecurityPolicy_None),
OPCUA_STRING_LENDONTCARE,
OpcUa_False) != 0)
{
if (OpcUa_IsBad(uStatus))
{
printf("\nThe server's certificate is not trusted yet.\n");
printf("Press 1 to add certificate to trust list\n");
printf("Press any other key to do nothing\n");
iChosen = _getch() - '0';
if (iChosen == 1)
{
UaClient_TrustCertificate(&pClientConfiguration->
PkiConfig,
printf("\n");
printf("Stored server certificate in the client trust list\n");
printf("Make sure the client certificate is in server trust list\n\n");
}
}
}
#endif
OpcUa_GotoErrorIfBad(uStatus);
if (uStatus != OpcUa_UncertainSubstituteValue && OpcUa_String_StrLen(&sUrl) > 0)
{
OpcUa_String_Initialize(&sUrl);
}
OpcUa_String_Clear(&sUrl);
}
else
{
OpcUa_EndpointDescription_Clear(pEndpoint);
}
OpcUa_Free(pEndpoint);
pEndpoint = OpcUa_List_GetNextElement(&demoDiscovery.lstEndpoints);
i++;
}
OpcUa_List_Clear(&demoDiscovery.lstEndpoints);
PrintActions();
}
else
{
printf("Invalid choice, please try again\n");
iChosen = -1;
}
}
}
else if (_kbhit())
{
int iChar = _getch();
switch (iChar)
{
case '0':
OpcUa_Null,
&demoDiscovery.DiscoveryUrl,
0,
OpcUa_Null,
0,
OpcUa_Null,
Demo_FindServers_CB,
&demoDiscovery);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
break;
case '1':
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
break;
case '2':
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
break;
case '3':
if (pSubscription->
IsValid != OpcUa_False)
{
OpcUa_Null,
Demo_DeleteSubscription_CB,
OpcUa_Null);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
}
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
break;
case '4':
uStatus = Demo_Read(pSession);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
break;
case '5':
if (pSubscription->
IsValid == OpcUa_False)
{
OpcUa_Null,
Demo_CreateSubscription_CB,
&pSubscription);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
}
else
{
printf("Subscription already exists!\n");
}
break;
case '6':
if (pSubscription->
IsValid != OpcUa_False)
{
OpcUa_Null,
Demo_ModifySubscription_CB,
OpcUa_Null);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
}
else
{
printf("Subscription does not exist!\n");
}
break;
case '7':
if (pSubscription->
IsValid != OpcUa_False)
{
OpcUa_Null,
Demo_DeleteSubscription_CB,
OpcUa_Null);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
}
else
{
printf("Subscription does not exist!\n");
}
break;
case '8':
if (pSubscription->
IsValid == OpcUa_False)
{
printf("Subscription does not exist!\n");
}
else if (monitoredItemId != 0)
{
printf("MonitoredItem already created!\n");
}
else
{
OpcUa_MonitoredItemCreateRequest_Initialize(&createRequest);
createRequest.
ItemToMonitor.
NodeId.Identifier.Numeric = OpcUaId_Server_ServerStatus_CurrentTime;
OpcUa_Null,
1,
&createRequest,
Demo_CreateMonitoredItems_CB,
&monitoredItemId);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
}
break;
case '9':
if (pSubscription->
IsValid == OpcUa_False)
{
printf("Subscription does not exist!\n");
}
else if (monitoredItemId == 0)
{
printf("MonitoredItem not created!\n");
}
else
{
OpcUa_Null,
1,
&monitoredItemId,
Demo_DeleteMonitoredItems_CB,
OpcUa_Null);
monitoredItemId = 0;
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
}
break;
case 'x':
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
bShutdown = OpcUa_True;
break;
default:
printf("Unrecognized command '%c'\n", iChar);
PrintActions();
break;
}
}
}
{
break;
}
}
#ifndef WIN32
close_keyboard();
#endif
OpcUa_GotoErrorIfBad(uStatus);
UaClient_Discovery_Delete(&demoDiscovery.pDiscovery);
OpcUa_List_Clear(&demoDiscovery.lstDiscoveryUrls);
OpcUa_List_Clear(&demoDiscovery.lstEndpoints);
OpcUa_String_Clear(&demoDiscovery.DiscoveryUrl);
printf( "UA Client: Main stopped successfully.\n" );
return ( int )uStatus;
Error:
if ( bClientInitialized != OpcUa_False )
{
}
printf( "UA Client: Main stopped due ERROR! (0x%X)\nPress Enter to close Window!\n", ( unsigned int )uStatus );
getchar();
return ( int )uStatus;
}
static void PrintStackInfo(const char *szParamName, const char *szParamList)
{
char szTmp[512];
char *pszToken;
strlcpy( szTmp, szParamList, sizeof(szTmp) );
szTmp[511] = '\0';
printf( "%s:\n", szParamName );
pszToken = strtok( szTmp, "\\" );
while ( pszToken )
{
printf( " %s\n", pszToken );
pszToken = strtok( 0, "\\" );
}
}
void PrintVersionInfo()
{
printf( "Sample Client of OPC UA SDK ANSI C %u.%u.%u (Build %u)\n", UASDK_MAJOR_VERSION, UASDK_MINOR_VERSION, UASDK_PATCH_VERSION, UASDK_BUILD_VERSION );
printf( "Copyright (C) 2015, Unified Automation GmbH\n" );
PrintStackInfo( "UaStack Version", OpcUa_ProxyStub_GetVersion() );
PrintStackInfo( "UaStack StaticConfigString", OpcUa_ProxyStub_GetStaticConfigString() );
PrintStackInfo( "UaStack Platform Layer Version", OpcUa_P_GetVersion() );
PrintStackInfo( "UaStack Platform Layer ConfigString", OpcUa_P_GetConfigString() );
}