High Performance OPC UA Server SDK  1.2.1.203
main.c
/*****************************************************************************
* *
* Copyright (c) 2006-2018 Unified Automation GmbH. All rights reserved. *
* *
* Software License Agreement ("SLA") Version 2.7 *
* *
* Unless explicitly acquired and licensed from Licensor under another *
* license, the contents of this file are subject to the Software License *
* Agreement ("SLA") Version 2.7, or subsequent versions as allowed by the *
* SLA, and You may not copy or use this file in either source code or *
* executable form, except in compliance with the terms and conditions of *
* the SLA. *
* *
* All software distributed under the SLA is provided strictly on an "AS *
* IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, *
* AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT *
* LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
* PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the SLA for specific *
* language governing rights and limitations under the SLA. *
* *
* The complete license agreement can be found here: *
* http://unifiedautomation.com/License/SLA/2.7/ *
* *
*****************************************************************************/
#include <platform/shutdown.h>
#include <memory/memory.h>
#ifdef SUPPORT_FILE_IO
# include <platform/file.h>
#endif
#include <getopt.h>
#include <appconfig.h>
#include <uaapplication/application.h>
#include <trace/trace.h>
#include "sample_client.h"
#include "client_utils.h"
#define USERNAME_PW_BUFFER_LEN 128
#if defined(WIN32) && !defined(_WIN32_WCE)
#include <conio.h>
#endif
struct appconfig g_appconfig;
static void usage(const char *appname)
{
fprintf(stderr, "Usage: %s [-d debug_level] [-f facility_mask] [-c config_file] [-u <url>] [-l] [-h]\n", appname);
fprintf(stderr, " -d: sets the debug level bit mask of the trace output (default=ERROR)\n");
fprintf(stderr, " -f: sets the facility bit mask of the trace output (default=ALL)\n");
fprintf(stderr, " -c: sets the configuration file to use\n");
fprintf(stderr, " -l: lists all debug_levels and facility_masks\n");
fprintf(stderr, " -u: Sets the URL to use (default is to use the URLs from the configuration file)\n" );
fprintf(stderr, " -h: prints this help\n");
}
static void print_debug_flags(void)
{
fprintf(stderr, "debug levels:\n");
fprintf(stderr, " TRACE_LEVEL_DEBUG 1\n");
fprintf(stderr, " TRACE_LEVEL_DATA 2\n");
fprintf(stderr, " TRACE_LEVEL_INFO 4\n");
fprintf(stderr, " TRACE_LEVEL_FUNC_ENTER 8\n");
fprintf(stderr, " TRACE_LEVEL_FUNC_LEAVE 16\n");
fprintf(stderr, " TRACE_LEVEL_FUNC 24\n");
fprintf(stderr, " TRACE_LEVEL_NOTICE 32\n");
fprintf(stderr, " TRACE_LEVEL_WARNING 64\n");
fprintf(stderr, " TRACE_LEVEL_ERROR 128\n");
fprintf(stderr, " TRACE_LEVEL_INSANE 256\n");
fprintf(stderr, " TRACE_LEVEL_ALL 511\n");
fprintf(stderr, "debug facilities:\n");
fprintf(stderr, " TRACE_FAC_PLATFORM 1\n");
fprintf(stderr, " TRACE_FAC_NETWORK 2\n");
fprintf(stderr, " TRACE_FAC_CRYPTO 4\n");
fprintf(stderr, " TRACE_FAC_IPC 8\n");
fprintf(stderr, " TRACE_FAC_BASE 16\n");
fprintf(stderr, " TRACE_FAC_MEMORY 32\n");
fprintf(stderr, " TRACE_FAC_UATCP 64\n");
fprintf(stderr, " TRACE_FAC_ENCODER 128\n");
fprintf(stderr, " TRACE_FAC_SESSION 256\n");
fprintf(stderr, " TRACE_FAC_PROVIDER 512\n");
fprintf(stderr, " TRACE_FAC_APPLICATION 1024\n");
fprintf(stderr, " TRACE_FAC_ADDRSPACE 2048\n");
fprintf(stderr, " TRACE_FAC_TIMER 4096\n");
fprintf(stderr, " TRACE_FAC_PKI 8192\n");
fprintf(stderr, " TRACE_FAC_SUBSCRIPTION 16384\n");
fprintf(stderr, " TRACE_FAC_ALL 32767\n");
}
static inline int poll_key(struct sample_client *ctx)
{
while (!_kbhit()) {
sample_client_docom(ctx);
}
return _getch();
}
static int read_input(const char *prompt, char *buffer, int buffer_len)
{
size_t len;
printf("%s: ", prompt);
/* flush to make sure the prompt is printed */
fflush(stdout);
if (fgets(buffer, buffer_len, stdin) == NULL) {
printf("\nFailed to read input\n");
return -1;
}
printf("\n");
len = strlen(buffer);
if (buffer[len-1] == '\n') {
len--;
buffer[len] = 0;
}
return 0;
}
static int menu_choose_endpoint(struct sample_client *ctx, char *url)
{
int ret = emenu_choose_endpoint;
int iChar;
bool have_policy_id = ua_string_length(&ctx->security.token_policy_id) > 0;
if (ctx->discovery.endpoint_url.len != 0)
url = ctx->discovery.endpoint_url.d.data;
printf("-------------------------------------------------------\n");
printf("- Press x to close client \n");
printf("-------------------------------------------------------\n");
printf("- Press 0 to start discovery at %s \n", url);
printf("- Press 1 to connect to %s \n", url);
if (have_policy_id) {
printf("- Press 2 to set username and password\n");
}
iChar = poll_key(ctx);
switch (iChar) {
case '0':
if (sample_client_start_discovery(ctx, url) != 0) {
TRACE_ERROR(TRACE_FAC_USERAPPLICATION, "get endpoints failed.\n");
} else {
ret = emenu_choose_endpoint;
}
break;
case '1':
if (sample_client_connect(ctx, url) != 0) {
TRACE_ERROR(TRACE_FAC_USERAPPLICATION, "ua_client_begin_connect failed.\n");
} else {
ret = emenu_connected;;
}
break;
case '2':
if (have_policy_id) {
char buffer[USERNAME_PW_BUFFER_LEN];
struct ua_auth_credentials cred;
if (read_input("Enter username", buffer, sizeof(buffer)) != 0) {
return ret;
}
ua_string_set(&cred.cred.pwd.username, buffer);
if (read_input("Enter password", buffer, sizeof(buffer)) != 0) {
return ret;
}
ua_string_set(&cred.cred.pwd.password, buffer);
ua_string_copy(&cred.policy_id, &ctx->security.token_policy_id);
cred.cred_type = UA_AUTH_USERNAMEPASSWORD;
cred.security_policy_id = ctx->security.token_sec_policy;
ua_client_set_credentials(&ctx->client, &cred);
}
break;
case 'x':
ret =eclose_application;
break;
}
return ret;
}
static int menu_connected(struct sample_client *ctx)
{
int ret = emenu_connected;
int iChar;
printf("-------------------------------------------------------\n");
printf("- Press x to close client -\n");
printf("-------------------------------------------------------\n");
printf("- Press 3 to disconnect from server -\n");
printf("- Press 4 to browse server -\n");
printf("- Press 5 to read values -\n");
#ifdef ENABLE_SERVICE_SUBSCRIPTION
printf("- Press 6 to create a subscription -\n");
printf("- Press 7 to modify a subscription -\n");
printf("- Press 8 to delete a subscription -\n");
printf("- Press 9 to create monitored items -\n");
printf("- Press a to delete monitored items -\n");
#endif
printf("- Press b to call a method -\n");
printf("-------------------------------------------------------\n");
printf("\n");
iChar = poll_key(ctx);
switch (iChar) {
case 'x':
ret =eclose_application;
break;
case '3':
sample_client_delete_subscription(ctx);
ret = sample_client_disconnect(ctx);
if (ret != 0) {
TRACE_ERROR(TRACE_FAC_USERAPPLICATION, "ua_client_begin_disconnect failed.\n");
}
break;
case '4':
sample_client_browse_node(ctx);
break;
case '5':
sample_client_read_variable(ctx);
break;
#ifdef ENABLE_SERVICE_SUBSCRIPTION
case '6':
sample_client_delete_subscription(ctx);
sample_client_create_sub(ctx);
break;
/* Press 7 to modify a subscription */
case '7':
break;
case '8':
sample_client_delete_subscription(ctx);
break;
/* Press 9 to create monitored items */
case '9':
break;
/* Press a to delete monitored items */
case 'a':
break;
#endif
case 'b':
sample_client_call_method(ctx);
break;
}
return ret;
}
int main(int argc, char *argv[])
{
int ret, opt;
enum state_t state = emenu_choose_endpoint;
char url[128] = "opc.tcp://localhost";
#ifdef HAVE_CRYPTO
const char *config_file = "settings.conf";
#else
const char *config_file = "settings_micro.conf";
#endif
int trace_level = TRACE_LEVEL_ERROR;
int facility_mask = TRACE_FAC_ALL;
struct sample_client sample_client;
ua_memset(&sample_client, 0, sizeof(sample_client));
/* parse commandline arguments */
while ((opt = getopt(argc, argv, "hd:f:lc:u:")) != -1) {
switch (opt) {
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
case 'd':
trace_level = atoi(optarg);
break;
case 'f':
facility_mask = atoi(optarg);
break;
case 'c':
config_file = optarg;
break;
case 'l':
print_debug_flags();
exit(EXIT_SUCCESS);
case 'u':
strncpy(url, optarg, sizeof(url) );
break;
default: /* '?' */
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
g_appconfig.manufacturer_name = "Unified Automation GmbH";
g_appconfig.product_name = "HP SDK UA Demo Client";
g_appconfig.product_uri = "urn:UnifiedAutomation:UaDemoServerHP";
g_appconfig.application_name = "HP SDK UA Demo Client";
g_appconfig.application_uri = "urn:UnifiedAutomation:HPC:Example";
ret = uaapplication_init(&sample_client.app, trace_level, facility_mask, config_file);
if (ret != 0) {
fprintf(stderr, "uaapplication_init failed.\n");
return EXIT_FAILURE;
}
ret = sample_client_init(&sample_client);
if (ret != 0) {
TRACE_ERROR(TRACE_FAC_USERAPPLICATION, "ua_client_init failed.\n");
uaapplication_cleanup(&sample_client.app);
return EXIT_FAILURE;
}
init_keyboard();
do {
switch (state) {
case emenu_choose_endpoint:
state = menu_choose_endpoint(&sample_client, url);
break;
case emenu_connected:
state = menu_connected(&sample_client);
break;
case eclose_application:
printf("closing application");
break;
}
sample_client_docom(&sample_client);
} while (state != eclose_application);
sample_client_delete_subscription(&sample_client);
sample_client_disconnect(&sample_client);
sample_client_cleanup(&sample_client);
uaapplication_cleanup(&sample_client.app);
close_keyboard();
return EXIT_SUCCESS;
}