ANSI C Based OPC UA Client/Server/PubSub SDK  1.9.1.442
main_win.c
/*****************************************************************************
* *
* Copyright (c) 2006-2020 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/ *
* *
* Project: Unified Automation ANSI C based OPC UA Server SDK *
* *
*****************************************************************************/
/*============================================================================
* Includes
*===========================================================================*/
/* direct platform access */
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#if defined (HAVE_VISUAL_LEAK_DETECTOR)
#include <vld.h>
#elif defined (_MSC_VER) && !defined (_WIN32_WCE)
#include <crtdbg.h>
#endif
#ifdef _WIN32_WCE
#include <winsock2.h>
#include <wce_unistd.h>
int wceex_getopt(int argc, char * const argv[], const char *optstring);
#define getopt wceex_getopt
#else
/* windows getopt replacement */
#include "getopt.h"
#endif
#include <opcua_proxystub.h>
#include <opcua_trace.h>
#include "demoserver.h"
/*============================================================================
* Includes End
*===========================================================================*/
/*============================================================================
* Global Variables
*===========================================================================*/
static UaBase_Settings g_settings;
static char g_szHostname[256] = "";
/*============================================================================
* Global Variables End
*===========================================================================*/
int GetFQHostname( char *szHostname, int len )
{
struct hostent *pEnt = 0;
int ret = gethostname( szHostname, len );
if ( ret != 0 ) return ret;
pEnt = gethostbyname( szHostname );
if ( pEnt == 0 ) return -1;
OpcUa_StrlCpyA( szHostname, pEnt->h_name, len );
szHostname[len - 1] = 0;
return 0;
}
void PrintUsage(const char *szAppName)
{
printf( "Usage: %s [-h] [-v] [-n <hostname>] [-c <config file>] [-s <shutdown delay>]\n", szAppName );
printf( " -h: Shows this help\n" );
printf( " -v: Shows detailed version information\n" );
printf( " -n: Sets the hostname to bind on\n" );
printf( " -c: Sets the configuration file to use (default=settings.ini)\n" );
printf( " -s: Sets the shutdown delay in seconds (default=1)\n");
}
int main( int argc, char *argv[] )
{
int ret = EXIT_SUCCESS;
char szConfigurationFile[UABASE_PATH_MAX] = "settings.ini";
int shutdownDelay = 1;
#if defined(_WIN32_WCE)
/* WindowsCE doesn't have multi byte string OS functions, so we need to use wchar_t here */
wchar_t wszConfigurationFile[UABASE_PATH_MAX] = {0};
DWORD retTmp = GetModuleFileName(NULL, wszConfigurationFile, sizeof(wszConfigurationFile) / sizeof(wchar_t));
if (retTmp > 0)
{
wchar_t *szTmp = wcsrchr(wszConfigurationFile, '\\');
if (szTmp)
{
*szTmp = L'\0';
wcsncat(wszConfigurationFile, L"\\settings.ini", UABASE_PATH_MAX - wcslen(wszConfigurationFile) - 1);
wcstombs(szConfigurationFile, wszConfigurationFile, UABASE_PATH_MAX - 1);
szConfigurationFile[UABASE_PATH_MAX - 1] = '\0';
}
else
{
printf("Could not find '\\' in module file path!\n");
}
}
else
{
printf("GetModuleFileName failed!\n");
}
#else
int opt;
# if !defined (HAVE_VISUAL_LEAK_DETECTOR) && defined (_MSC_VER)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
/* _CrtSetBreakAlloc(2432); */
# endif
/* parse commandline arguments */
while ( ( opt = getopt( argc, argv, "hvn:c:s:" ) ) != -1 )
{
switch ( opt )
{
case 'h':
PrintUsage( argv[0] );
exit( EXIT_SUCCESS );
break;
case 'v':
PrintVersionInfo();
exit( EXIT_SUCCESS );
break;
case 'n':
OpcUa_StrlCpyA( g_szHostname, optarg, sizeof(g_szHostname) );
break;
case 'c':
OpcUa_StrlCpyA( szConfigurationFile, optarg, sizeof(szConfigurationFile) );
break;
case 's':
shutdownDelay = atoi(optarg);
if (shutdownDelay < 0) shutdownDelay = 0;
break;
default: /* '?' */
PrintUsage( argv[0] );
exit( EXIT_FAILURE );
}
}
#endif
/* Setup OPC UA */
uStatus = InitializeOpcUaStack();
if (OpcUa_IsNotGood(uStatus)) return EXIT_FAILURE;
/* check if hostname was given */
if ( g_szHostname[0] == 0 )
{
/* no hostname was given so read out the fully qualified hostname. */
GetFQHostname( g_szHostname, sizeof( g_szHostname ) );
}
do {
uStatus = UaBase_Settings_Initialize(&g_settings, szConfigurationFile);
if (OpcUa_IsNotGood(uStatus))
{
printf( "Could not open configuration file '%s'\n", szConfigurationFile);
ret = EXIT_FAILURE;
break;
}
uStatus = ServerMain(&g_settings, g_szHostname, shutdownDelay);
UaBase_Settings_Clear(&g_settings);
} while (uStatus == OpcUa_BadContinue);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadShutdown && uStatus != OpcUa_BadContinue) {ret = EXIT_FAILURE;}
CleanupOpcUaStack();
return ret;
}
#ifdef _WIN32_WCE
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nShowCmd)
{
OpcUa_ReferenceParameter(hInstance);
OpcUa_ReferenceParameter(hPrevInstance);
OpcUa_ReferenceParameter(lpCmdLine);
OpcUa_ReferenceParameter(nShowCmd);
return main(0, OpcUa_Null);
}
#endif