ANSI C Based OPC UA Client/Server/PubSub SDK  1.9.4.474
Starting Points for Server and Client functionality in one process

Application merging Server and Client functionality together needs to initialize UA Stack in Startup sequence and cleanup UA Stack in Shutdown sequence only once.

/* Initialize OPC UA Stack */
..
..
... Server and Client Startup ...
... Main loop calling UaBase_DoCom() cyclically ...
... Server and Client Shutdown ...
/* Clean Up OPC UA Stack */

The application should either use one configuration file and one UaBase_Settings for both Server and Client or set bProxyStubInitialized and bTraceInitialized if both are handled independent of each other. This is to ensure that ProxyStub and Trace configuration is initialized only once based on one configuration file.

Application that uses two configuration files should set bProxyStubInitialized and bTraceInitialized in the UaBase_Settings instance that it uses later as shown in the example below:

Two UaBase_Settings instances:

/* The UA server settings instance */
static UaBase_Settings g_settings_server;
/* The UA client settings instance */
static UaBase_Settings g_settings_client;

Server Startup:

/* Initialize OPC UA Stack */
...
/* Initialize settings structure using passed config file */
uStatus = UaBase_Settings_Initialize(&g_settings_server, szConfigurationFileServer);
...
/* Create the PKI folder structure if it does not exist and create the application instance certificate */
uStatus = SetupServerPKIInfrastructure(&g_settings_server,...);
...
/*Initialize the Server SDK*/
uStatus = UaServer_Initialize(&g_UaServer);
...
/* Set configuration */
pServerConfiguration = UaServer_GetConfiguration( &g_UaServer );
uStatus = UaServer_Settings_GetConfigurationFromSettings(&g_settings_server, pServerConfiguration, ..);
...
/* Set the authentication type */
...
/* Initialize Providers */
...
/* StartUp Server */
uStatus = UaServer_StartUp( &g_UaServer );

Client Startup with bProxyStubInitialized and bTraceInitialized set to OpcUa_True:

/*Initialize settings structure using passed config file*/
uStatus = UaBase_Settings_Initialize(&g_settings_client, szConfigurationFileClient);
/* Set bProxyStubInitialized and bTraceInitialized */
g_settings_client.bProxyStubInitialized = OpcUa_True;
g_settings_client.bTraceInitialized = OpcUa_True;
...
SetupClientPKIInfrastructure(&g_settings_client,...);
...
/* Initialize the Client SDK */
uStatus = UaClient_Initialize(&g_UaClient);
...
/*Set configuration*/
pClientConfiguration = UaClient_GetConfiguration();
uStatus = UaClient_Settings_GetConfigurationFromSettings(&g_settings_client, pClientConfiguration);
/* Configure discovery and session for using in loop */
uStatus = UaClient_Discovery_Create(...);
...
uStatus = UaClient_Session_Create(...);
...
...
/* StartUp Client */
uStatus = UaClient_StartUp( &g_UaClient );

If custom structure DataTypes are registered for automatic encoding/decoding by the stack, the registration must be done after ProxyStub initialized but before any OPC UA communication is initiated on client or server side.

After UaServer_StartUp and UaClient_StartUp application should execute the main loop by calling UaBase_DoCom cyclically until it returns an error or the application should be shut down. Also, it should use UaServer_Shutdown in the Shutdown sequence instead of registering for shutdown keystroke if the main loop uses keystrokes like in example below.

/* Serve! */
while ( OpcUa_IsGood( uStatus ) )
{
if (bShutdown == OpcUa_False)
{
...
/* Display action menu */
...
if (_kbhit())
{
int iChar = _getch();
switch (iChar)
{
case '0':
...
...
}
}
}
uStatus = UaBase_DoCom();
}