High Performance OPC UA Server SDK  1.3.1.248
server_main.c
/*****************************************************************************
* *
* Copyright (c) 2006-2019 Unified Automation GmbH. All rights reserved. *
* *
* Software License Agreement ("SLA") Version 2.7 *
* *
* Unless explicitly acquired and licensed from Licensor under another *
* license, the contents of this file are subject to the Software License *
* Agreement ("SLA") Version 2.7, or subsequent versions as allowed by the *
* SLA, and You may not copy or use this file in either source code or *
* executable form, except in compliance with the terms and conditions of *
* the SLA. *
* *
* All software distributed under the SLA is provided strictly on an "AS *
* IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, *
* AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT *
* LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
* PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the SLA for specific *
* language governing rights and limitations under the SLA. *
* *
* The complete license agreement can be found here: *
* http://unifiedautomation.com/License/SLA/2.7/ *
* *
*****************************************************************************/
#include <stdio.h>
#include <uaapplication/application.h>
#include <uaserver/init.h>
#include <trace/trace.h>
#include <appconfig.h>
#include <uaprovider/server/uaprovider_server.h>
#include <uaprotocol/uaseconv/sechan.h>
#include <platform/hostname.h>
#include <platform/shutdown.h>
#include <crashhandler/crashhandler.h>
#include <memory/memory_layout.h>
#include "provider_minimal.h"
#include "args.h"
#ifdef HAVE_PKI
# include <crypto/crypto.h>
# include "cert_data.c"
#endif
#ifdef HAVE_PKI
static struct sechan_cert g_sechan_certs[1];
#endif
static struct uaapplication g_app;
unsigned int g_shutdown_time = 5; /* seconds */
/* global endpoint url which gets filled on startup */
static struct ua_string g_endpoint_url;
static struct uaserver_provider g_provider[] = {
{-1, uaprovider_server_init},
{-1, provider_minimal_init}
};
int server_main_clear(void)
{
unsigned int sec;
for (sec = g_shutdown_time; sec > 2; --sec) {
TRACE_NOTICE(TRACE_FAC_APPLICATION, "Sending shutdown notice to client (%u)...\n", sec);
/* inform clients about shutdown */
uaapplication_shutdown(&g_app, 1000); /* process events */
}
/* stop the server: no more info is sent to client */
TRACE_NOTICE(TRACE_FAC_APPLICATION, "Stopping server...\n");
for (; sec > 0; --sec) {
TRACE_NOTICE(TRACE_FAC_APPLICATION, "Waiting for server to cleanup resources (%u)...\n", sec);
uaapplication_shutdown(&g_app, 1000); /* process events */
}
TRACE_NOTICE(TRACE_FAC_APPLICATION, "Final cleanup.\n");
/* final cleanup */
uaserver_clear(g_provider, countof(g_provider));
#ifdef HAVE_PKI
crypto_key_clear(&g_sechan_certs[0].own_priv_key);
#endif
ua_string_clear(&g_endpoint_url);
return 0;
}
int server_main_init(int trace_level, int facility_mask)
{
int ret;
unsigned int i;
static char fqdn[64];
/* get fully qualified domain name */
ua_get_fqdn(fqdn, sizeof(fqdn));
g_appconfig.dns = fqdn;
#if defined(HAVE_PKI) && !defined(SUPPORT_FILE_IO)
/* use hardcoded certificate when filesystem is not available */
ua_bytestring_attach(&g_sechan_certs[0].own_cert, (char*) g_cert1024_der, (int) sizeof(g_cert1024_der));
ret = crypto_key_from_pem(g_private1024_key, sizeof(g_private1024_key), 0, 0, crypto_key_type_rsa_private, &g_sechan_certs[0].own_priv_key);
if (ret != 0) {
TRACE_ERROR(TRACE_FAC_APPLICATION, "server_main_init: ERROR Could not load private key\n");
goto out_pki;
}
g_appconfig.endpoint.sechan_certs = g_sechan_certs;
g_appconfig.endpoint.num_sechan_certs = countof(g_sechan_certs);
#endif
uaapplication_init(&g_app, trace_level, facility_mask, NULL);
/* create endpoint URL dynamically */
ua_string_snprintf(&g_endpoint_url, 50, "opc.tcp://%s:4840", fqdn);
for (i = 0; i < g_appconfig.endpoint.num_endpoints; ++i) {
/* assign endpoint url to appconfig */
g_appconfig.endpoint.endpoints[i].endpoint_url = ua_string_const_data(&g_endpoint_url);
}
TRACE_INFO(TRACE_FAC_APPLICATION, "Initializing providers...\n");
ret = uaserver_init(g_provider, countof(g_provider));
if (ret < 0) goto out_server_init;
TRACE_INFO(TRACE_FAC_APPLICATION, "Starting server...\n");
ret = uaserver_start();
if (ret < 0) goto out_server_start;
return 0;
out_server_start:
uaserver_clear(g_provider, countof(g_provider));
out_server_init:
#if defined(HAVE_PKI) && !defined(SUPPORT_FILE_IO)
crypto_key_clear(&g_sechan_certs[0].own_priv_key);
out_pki:
#endif
return ret;
}
int main(int argc, char *argv[])
{
int ret;
unsigned int i;
struct commandline_args args;
#ifdef WITH_COMMANDLINE_ARGS
parse_commandline(argc, argv, &args);
g_appconfig.ipc.ipc_size = args.memory * 1024;
#else
UA_UNUSED(argc);
UA_UNUSED(argv);
args.facility_mask = TRACE_FAC_ALL;
#endif
ret = server_main_init(args.trace_level, args.facility_mask);
if (ret != 0) {
printf("server_main_init() failed with error 0x%08x\n", ret);
exit(EXIT_FAILURE);
}
printf("Server is up and running.\n");
for (i = 0; i < g_appconfig.endpoint.num_endpoints; ++i) {
printf("Listening on %s\n", g_appconfig.endpoint.endpoints[i].endpoint_url);
}
fflush(stdout);
while (ua_shutdown_should_shutdown() == 0) {
}
TRACE_NOTICE(TRACE_FAC_APPLICATION, "Shutting down server...\n");
server_main_clear();
return 0;
}