OpcServer setting ServerConfigData

Questions regarding the use of the C++ SDK for Server or Client development or integration into customer products ...

Moderator: uasdkcpp

Post Reply
wpramono
Full Member
Full Member
Posts: 6
Joined: 18 Aug 2017, 03:44

OpcServer setting ServerConfigData

Post by wpramono »

Hi,

I'm trying to load a ServerConfig.xml data to OpcServer. However, I need to modify some fields in the ServerConfigData before starting the server.

First, I create an instance of MyServerConfigXml class like this (MyServerConfigXml is derived from ServerConfigXml):
MyServerConfigXml* configData = new MyServerConfigXml("ServerConfig.xml", appPath, szAppPath, szAppPath);
configData->loadConfiguration();

... (modify the configData here) ...

Then, I set the configuration to the opc server like this:
OpcServer* pServer = new OpcServer;
pServer->setServerConfig(configData);

Finally, I start the server :
ret = pServer->start();
if ( ret != 0 )
{
delete pServer;
pServer = 0;
}

However, ret always returns the value of -1. Thus the pServer cannot start properly. I'm not sure what I'm doing wrong. Could someone help please? Thanks!

Also, I could not find any reference to "ServerConfigXmlBasic" class anywhere in the trial bundle SDK. Is that class not available in the trial verson? Thanks.

User avatar
Support Team
Hero Member
Hero Member
Posts: 3072
Joined: 18 Mar 2011, 15:09

Re: OpcServer setting ServerConfigData

Post by Support Team »

Hello wpramono,

I prepared an example to override the serverconfigxml class.

new file myserverconfigxml.h

Code: Select all

#ifndef MYSERVERCONFIGXML_H
#define MYSERVERCONFIGXML_H
#include "serverconfigxml.h"

class UaCoreServerApplication;
class UaServerApplicationCallback;

class MyServerConfigXml : public ServerConfigXml
{
    UA_DISABLE_COPY(MyServerConfigXml);
public:
    MyServerConfigXml(
        const UaString& sXmlFileName,
        const UaString& sApplicationPath,
        const UaString& sConfigPath,
        const UaString& sTracePath,
        UaCoreServerApplication* pUaCoreServerApplication,
        UaServerApplicationCallback* pUaServerApplicationCallback);
    virtual ~MyServerConfigXml();

    virtual UaStatus afterLoadConfiguration();
    virtual UaStatus startUp(ServerManager*);
    virtual UaStatus shutDown();
    virtual Session* createSession(OpcUa_Int32 sessionID, const UaNodeId &authenticationToken);
    virtual UaStatus logonSessionUser(Session* pSession, UaUserIdentityToken* pUserIdentityToken);

private:
    UaCoreServerApplication*     m_pUaCoreServerApplication;
    UaServerApplicationCallback* m_pUaServerApplicationCallback;
};
#endif // MYSERVERCONFIGXML_H
new file myserverconfigxml.cpp

Code: Select all

#include "myserverconfigxml.h"
#include "uacoreserverapplication.h"

MyServerConfigXml::MyServerConfigXml(
    const UaString& sXmlFileName,
    const UaString& sApplicationPath,
    const UaString& sConfigPath,
    const UaString& sTracePath,
    UaCoreServerApplication* pUaCoreServerApplication,
    UaServerApplicationCallback* pUaServerApplicationCallback)
    : ServerConfigXml(sXmlFileName, sApplicationPath, sConfigPath, sTracePath),
    m_pUaCoreServerApplication(pUaCoreServerApplication),
    m_pUaServerApplicationCallback(pUaServerApplicationCallback)
{}

MyServerConfigXml::~MyServerConfigXml()
{
}

UaStatus MyServerConfigXml::afterLoadConfiguration()
{
    // put your code to modify any setting here
    // e.g. don't allow SessionTimeout longer than 10min
    // !! just an example - don't copy !!
    if (m_maxSessionTimeout > 600000)
    {
        m_maxSessionTimeout = 600000;
    }

    return OpcUa_Good;
}
UaStatus MyServerConfigXml::startUp(ServerManager*)
{
    return OpcUa_Good;
}
UaStatus MyServerConfigXml::shutDown()
{
    return OpcUa_Good;
}

Session* MyServerConfigXml::createSession(OpcUa_Int32 sessionID, const UaNodeId &authenticationToken)
{
    if (m_pUaServerApplicationCallback)
    {
        return m_pUaServerApplicationCallback->createSession(sessionID, authenticationToken);
    }
    else
    {
        return m_pUaCoreServerApplication->createDefaultSession(sessionID, authenticationToken);
    }
}

/* Validates the user identity token and sets the user for a session.
*  @param pSession             Interface to the Session context for the method call
*  @param pUserIdentityToken   Secret session Id created by the server application.
*  @return                     Error code.
*/
UaStatus MyServerConfigXml::logonSessionUser(
    Session*             pSession,
    UaUserIdentityToken* pUserIdentityToken)
{
    OpcUa_Boolean  bEnableAnonymous;
    OpcUa_Boolean  bEnableUserPw;
    OpcUa_Boolean  bEnableCertificate;
    OpcUa_Boolean  bEnableKerberosTicket;

    // Get the settings for user identity tokens to support
    getUserIdentityTokenConfig(bEnableAnonymous, bEnableUserPw, bEnableCertificate, bEnableKerberosTicket);

    if (pUserIdentityToken->getTokenType() == OpcUa_UserTokenType_Anonymous)
    {
        if (bEnableAnonymous == OpcUa_False)
        {
            return OpcUa_BadIdentityTokenRejected;
        }
        else
        {
            if (m_pUaServerApplicationCallback)
            {
                return m_pUaServerApplicationCallback->logonSessionUser(pSession, pUserIdentityToken, this);
            }
            else
            {
                return OpcUa_Good;
            }
        }
    }
    else if (pUserIdentityToken->getTokenType() == OpcUa_UserTokenType_UserName)
    {
        if (bEnableUserPw == OpcUa_False)
        {
            return OpcUa_BadIdentityTokenRejected;
        }
        else
        {
            if (m_pUaServerApplicationCallback)
            {
                return m_pUaServerApplicationCallback->logonSessionUser(pSession, pUserIdentityToken, this);
            }
            else
            {
                return OpcUa_BadIdentityTokenRejected;
            }
        }
    }
    else if (pUserIdentityToken->getTokenType() == OpcUa_UserTokenType_Certificate)
    {
        if (bEnableCertificate == OpcUa_False)
        {
            return OpcUa_BadIdentityTokenRejected;
        }
        else
        {
            if (m_pUaServerApplicationCallback)
            {
                return m_pUaServerApplicationCallback->logonSessionUser(pSession, pUserIdentityToken, this);
            }
            else
            {
                return OpcUa_BadIdentityTokenRejected;
            }
        }
    }
    else if (pUserIdentityToken->getTokenType() == 4/*OpcUa_UserTokenType_KerberosToken*/)
    {
        if (bEnableKerberosTicket == OpcUa_False)
        {
            return OpcUa_BadIdentityTokenRejected;
        }
        else
        {
            if (m_pUaServerApplicationCallback)
            {
                return m_pUaServerApplicationCallback->logonSessionUser(pSession, pUserIdentityToken, this);
            }
            else
            {
                return OpcUa_BadIdentityTokenRejected;
            }
        }
    }

    return OpcUa_Bad;
}
modify servermain.cpp (DemoServer example)

Code: Select all

        // Create and initialize server object
        OpcServer* pServer = new OpcServer;

        // Set the callback for user authentication
        MyServerCallback serverCallback;
        pServer->setCallback(&serverCallback);

        //pServer->setServerConfig(sConfigFileName, szAppPath);

        // Create ServerConfig
        MyServerConfigXml* pServerConfig = new MyServerConfigXml(
            sConfigFileName,
            szAppPath,
            szAppPath,
            szAppPath,
            pServer,
            &serverCallback);

        pServer->setServerConfig(pServerConfig);
In MyServerConfigXml::afterLoadConfiguration() you can put any code you like to modify settings.
Best regards
Unified Automation Support Team

wpramono
Full Member
Full Member
Posts: 6
Joined: 18 Aug 2017, 03:44

Re: OpcServer setting ServerConfigData

Post by wpramono »

Dear Support Team,

Thank you. It works. Server can now be started.
The reason we want to modify the ServerConfig data is because we want to modify the existing UaEndpoint and also add a new UaEndpoint dynamically.
Do you have an example on how to do this? I've tried the following:
In the afterLoadConfiguration() function, I tried to modify an existing UaEndpointSecuritySetting:

Code: Select all

UaEndpoint* endpoint = m_uaEndpointArray[index];
endpoint->securitySettings().clear();    //Or addObject, or modify securitySettings()[index];
But securitySettings() returned value is a const that cannot be modified.

When trying to add a new UaEndpoint, I tried the following:

Code: Select all

UaEndpoint* endpoint = new UaEndpoint();
endpoint->setEndpointUrl(UaString(serverUrl->GetUrl().c_str()), OpcUa_True);
m_uaEndpointArray.addObject(endpoint);
UaEndpointSecuritySetting securityPolicy;
securityPolicy.addMessageSecurityMode(OpcUa_MessageSecurityMode_None);
securityPolicy.setSecurityPolicy("http://opcfoundation.org/UA/SecurityPolicy#None");
endpoint->addSecuritySetting(securityPolicy);
endpoint->setIsDiscoveryUrl(OpcUa_True);
endpoint->setIsVisible(OpcUa_True);
endpoint->setSerializerType(OpcUa_Endpoint_SerializerType_Binary);
But the endpoint always fails to be created.

Any help would be much appreciated. Thanks again!

-Wil

User avatar
Support Team
Hero Member
Hero Member
Posts: 3072
Joined: 18 Mar 2011, 15:09

Re: OpcServer setting ServerConfigData

Post by Support Team »

Why do you want to change the Endpoint when loading the configuration instead of settings the correct EndpointConfiguration in the xml config file? What do you mean by "dynamically add new Ednpoint"? When should that happen?
Best regards
Unified Automation Support Team

wpramono
Full Member
Full Member
Posts: 6
Joined: 18 Aug 2017, 03:44

Re: OpcServer setting ServerConfigData

Post by wpramono »

Dear Support Team,

We actually have a separate configuration tool that generates a config file (system.xml) that includes configuration of the underlying system as well as configuration for the server endpoints. The idea is to first load the default ServerConfig.xml as the default settings then apply the other settings from the system.xml config file settings. When the opc ua server starts, it should already have all the proper configuration needed to run both the underlying system and opc ua server.
Is this possible? Thanks.

-Wil

User avatar
Support Team
Hero Member
Hero Member
Posts: 3072
Joined: 18 Mar 2011, 15:09

Re: OpcServer setting ServerConfigData

Post by Support Team »

Hello Wil,

There's much more you need to set for the Endpoint e.g. CertificateStoreConfiguration, CertificateConfiguration. This all happens in the implementation of UaEndpointXml::setXmlConfig.
the ServerConfigXml and UaEndpointXml classes are designed to read all information from XML. There's not really an easy way to overwrite some settings. You should either implement your own configuration class or make sure the ServerConfig.xml already contains the settings you need.
Best regards
Unified Automation Support Team

wpramono
Full Member
Full Member
Posts: 6
Joined: 18 Aug 2017, 03:44

Re: OpcServer setting ServerConfigData

Post by wpramono »

Dear Support Team,

It looks like I have to create my own ServerConfigData from scratch without loading the ServerConfig.xml. is this correct? If so, is there an example/documentation on how to create a new ServerConfigData?
Another approach would be to modify the ServerConfig.xml directly and then let ServerConfigXml load it. Is this correct? But this seems like a "hacky" way to do it. We would very much prefer the first approach if at all possible.
Thanks again for the response. It's been very helpful.

-Wil

User avatar
Support Team
Hero Member
Hero Member
Posts: 3072
Joined: 18 Mar 2011, 15:09

Re: OpcServer setting ServerConfigData

Post by Support Team »

Hello Wil,

yes you can use the ServerConfigXml as is, you can subclass it like in the example above and change parameters or write your own ServerConfig class.
I can provide an example for a ServerConfig implementation without using the XML or INI format.

ServerConfigBase.h:

Code: Select all

#ifndef SERVERCONFIGBASE_H
#define SERVERCONFIGBASE_H

#include "serverconfigdata.h"

class UaCoreServerApplication;
class UaServerApplicationCallback;
class UaEndpointBase;

class ServerConfigBase : public ServerConfigData
{
    UA_DISABLE_COPY(ServerConfigBase);
public:
    ServerConfigBase(
        const UaString&              sApplicationPath,
        const UaString&              sConfigurationPath,
        const UaString&              sTracePath,
        const UaString&              sProductUri,
        const UaString&              sManufacturerName,
        const UaString&              sProductName,
        const UaString&              sSoftwareVersion,
        const UaString&              sBuildNumber,
        const UaString&              sServerInstanceUri,
        const UaString&              sServerInstanceName,
        UaCoreServerApplication*     pUaCoreServerApplication,
        UaServerApplicationCallback* pUaServerApplicationCallback);
    virtual ~ServerConfigBase();

    void addEndpoint(UaEndpointBase* pEndpoint);

    // Implement ServerConfigData
    virtual UaStatus afterLoadConfiguration();

    // Implement ServerConfig
    virtual UaStatus loadConfiguration();
    virtual UaStatus startUp(ServerManager* pServerManager);
    virtual UaStatus shutDown();
    virtual UaStatus saveConfiguration();
    virtual Session* createSession(OpcUa_Int32 sessionID, const UaNodeId &authenticationToken);
    virtual UaStatus logonSessionUser(Session* pSession, UaUserIdentityToken* pUserIdentityToken);

    // Additional Setter
    UaStatus setStackTraceSettings(
        OpcUa_Boolean bTraceEnabled,
        OpcUa_UInt32  uTraceLevel);

    UaStatus setServerTraceSettings(
        OpcUa_Boolean   bTraceEnabled,       //!< [in] Globally enable/disable trace output from the SDK
        OpcUa_UInt32    uTraceLevel,         /**< [in] Configures the level of messages traced
                                                - (0) NoTrace - No Trace
                                                - (1) Errors - Unexpected errors
                                                - (2) Warning - Unexpected behaviour that is not an error
                                                - (3) Info - Information about important activities like connection establishment
                                                - (4) InterfaceCall - Calls to module interfaces
                                                - (5) CtorDtor - Creation and destruction of objects
                                                - (6) ProgramFlow - Internal program flow
                                                - (7) Data - Data */
        OpcUa_UInt32    uMaxTraceEntries,    //!< [in] Maximum number of trace entries in one trace file
        OpcUa_UInt32    uMaxBackupFiles,     //!< [in] Maximum number of backup files
        const UaString& sTraceFile,          //!< [in] Name and path of the trace file
        OpcUa_Boolean   bDisableFlush        //!< [in] Disable flushing the trace file after each trace entry
    );

    // these 2 setter are actually missing in ServerConfigData class
    void setRejectedUserCertificatesCount(OpcUa_UInt32 nRejectedUserCertificatesCount);
    void setRejectedUserCertificatesDirectory(const UaString& sDirectory);

protected:
    UaCoreServerApplication*        m_pUaCoreServerApplication;
    UaServerApplicationCallback*    m_pUaServerApplicationCallback;
};

class UaEndpointBase : public UaEndpoint
{
    UA_DISABLE_COPY(UaEndpointBase);
public:
    UaEndpointBase();
    UaEndpointBase(const UaString& sPort, bool isSecure = true);
    void setCertificateStore(OpcUa_UInt32 endpointCertificateStoreIndex, CertificateStoreConfiguration* pEndpointCertificateStore);
    virtual ~UaEndpointBase();
};

#endif // SERVERCONFIGBASE_H
ServerConfigBase.cpp

Code: Select all

#include "serverconfigbase.h"
#include "uacoreserverapplication.h"

ServerConfigBase::ServerConfigBase(
    const UaString&  sApplicationPath,   //!< The path to the server executable.
    const UaString&  sConfigurationPath, //!< The path to the configuration files.
    const UaString&  sTracePath,         //!< The path to the log files.
    const UaString&  sProductUri,        //!< The product URI of the server.
    const UaString&  sManufacturerName,  //!< The manufacturer name of the server.
    const UaString&  sProductName,       //!< The product name of the server.
    const UaString&  sSoftwareVersion,   //!< The software version of the server.
    const UaString&  sBuildNumber,       //!< The build number of the server.
    const UaString&  sServerInstanceUri, //!< The application instance URI of the server. The placeholder [NodeName] can be used to automatically insert the host name.
    const UaString&  sServerInstanceName, //!< The application instance name of the server. The placeholder [NodeName] can be used to automatically insert the host name.
    UaCoreServerApplication*     pUaCoreServerApplication, //!< The main server application object.
    UaServerApplicationCallback* pUaServerApplicationCallback) //!< The user application callback interface.
: ServerConfigData(sApplicationPath, sConfigurationPath, sTracePath),
  m_pUaCoreServerApplication(pUaCoreServerApplication),
  m_pUaServerApplicationCallback(pUaServerApplicationCallback)
{
    setProductUri(sProductUri);
    setManufacturerName(sManufacturerName);
    setProductName(sProductName);
    setSoftwareVersion(sSoftwareVersion);
    setBuildNumber(sBuildNumber);

    char szHostname[256];
    UA_GetHostname(szHostname, sizeof(szHostname));
    UaString sHostName(szHostname);
    UaString sReplacedServerInstanceUri(sServerInstanceUri);
    replaceNodeName(sReplacedServerInstanceUri, sHostName);
    setServerUri(sReplacedServerInstanceUri);
    UaString sReplacedServerInstanceName(sServerInstanceName);
    replaceNodeName(sReplacedServerInstanceName, sHostName);
    setServerName(sReplacedServerInstanceName);

    m_sTraceFile = "[TracePath]/UaServerCPP.log";
    replaceTracePath(m_sTracePath, m_sTracePath);
    replaceTracePath(m_sTraceFile, m_sTracePath);

    // Create default certificat store
    CertificateStoreConfiguration* pDefaultCertificateStore = new CertificateStoreConfiguration;
    pDefaultCertificateStore->m_maxTrustListSize = 100;
    pDefaultCertificateStore->m_sCertificateTrustListLocation = UaString("%1/pkiserver/trusted/certs/").arg(sConfigurationPath);
    pDefaultCertificateStore->m_sCertificateRevocationListLocation = UaString("%1/pkiserver/trusted/crl/").arg(sConfigurationPath);
    pDefaultCertificateStore->m_sIssuersCertificatesLocation = UaString("%1/pkiserver/issuers/certs/").arg(sConfigurationPath);
    pDefaultCertificateStore->m_sIssuersRevocationListLocation = UaString("%1/pkiserver/issuers/crl/").arg(sConfigurationPath);

    // Create default certificat configuration
    CertificateConfiguration* pNewCertificate = new CertificateConfiguration;
    pNewCertificate->m_sCertificateLocation = UaString("%1/pkiserver/own/certs/uaservercpp.der").arg(sConfigurationPath);
    pNewCertificate->m_sPrivateKeyLocation = UaString("%1/pkiserver/own/private/uaservercpp.pem").arg(sConfigurationPath);
    pNewCertificate->m_createCertificate = true;
    pNewCertificate->m_autoCompleteCertificateChain = true;
    pNewCertificate->m_certificateCreateSetting.m_sCommonName = sReplacedServerInstanceName;
    pNewCertificate->m_certificateCreateSetting.m_sDomainComponent = sHostName;
    pNewCertificate->m_certificateCreateSetting.m_sOrganization = "Organization";
    pNewCertificate->m_certificateCreateSetting.m_sOrganizationUnit = "Unit";
    pNewCertificate->m_certificateCreateSetting.m_sLocality = "LocationName";
    pNewCertificate->m_certificateCreateSetting.m_sState = "";
    pNewCertificate->m_certificateCreateSetting.m_sCountry = "DE";
    pNewCertificate->m_certificateCreateSetting.m_certificateType = CertificateCreateSettings::CertificateType_RsaSha256;
    pNewCertificate->m_certificateCreateSetting.m_arrDNSNames.create(1);
    sHostName.copyTo(&pNewCertificate->m_certificateCreateSetting.m_arrDNSNames[0]);

    // Add certificate to store
    pDefaultCertificateStore->addCertificate(pNewCertificate);
    pNewCertificate->releaseReference();
    // Add certificate store to configuration
    addCertificateStoreConfiguration(pDefaultCertificateStore);
    pDefaultCertificateStore->releaseReference();
}

/** Destroys the ServerConfigBase object */
ServerConfigBase::~ServerConfigBase()
{
}

/** Adds an endpoint to the server configuration.
 *
 *  It sets also the default certificate store if no certificate store is configured for the endpoint.
 */
void ServerConfigBase::addEndpoint(UaEndpointBase* pEndpoint)
{
    if ((pEndpoint->pEndpointCertificateStore() == NULL) && (m_certificateStores.length() > 0))
    {
        pEndpoint->setCertificateStore(0, m_certificateStores[0]);
    }
    m_uaEndpointArray.addObject(pEndpoint);
}

UaStatus ServerConfigBase::afterLoadConfiguration()
{
    return OpcUa_Good;
}
UaStatus ServerConfigBase::loadConfiguration()
{
    return OpcUa_Good;
}
UaStatus ServerConfigBase::startUp(ServerManager* pServerManager)
{
    OpcUa_ReferenceParameter(pServerManager);
    if (m_uaEndpointArray.length() == 0)
    {
        return OpcUa_BadInvalidState;
    }
    return OpcUa_Good;
}
UaStatus ServerConfigBase::shutDown()
{
    return OpcUa_Good;
}
UaStatus ServerConfigBase::saveConfiguration()
{
    return OpcUa_BadNotImplemented;
}

Session* ServerConfigBase::createSession(OpcUa_Int32 sessionID, const UaNodeId &authenticationToken)
{
    if (m_pUaServerApplicationCallback)
    {
        return m_pUaServerApplicationCallback->createSession(sessionID, authenticationToken);
    }
    else
    {
        return m_pUaCoreServerApplication->createDefaultSession(sessionID, authenticationToken);
    }
}

UaStatus ServerConfigBase::logonSessionUser(Session* pSession, UaUserIdentityToken* pUserIdentityToken)
{
    OpcUa_Boolean  bEnableAnonymous;
    OpcUa_Boolean  bEnableUserPw;
    OpcUa_Boolean  bEnableCertificate;
    OpcUa_Boolean  bEnableKerberosTicket;

    // Get the settings for user identity tokens to support
    getUserIdentityTokenConfig(bEnableAnonymous, bEnableUserPw, bEnableCertificate, bEnableKerberosTicket);

    if (pUserIdentityToken->getTokenType() == OpcUa_UserTokenType_Anonymous)
    {
        if (bEnableAnonymous == OpcUa_False)
        {
            return OpcUa_BadIdentityTokenRejected;
        }
        else
        {
            if (m_pUaServerApplicationCallback)
            {
                return m_pUaServerApplicationCallback->logonSessionUser(pSession, pUserIdentityToken, this);
            }
            else
            {
                return OpcUa_Good;
            }
        }
    }
    else if (pUserIdentityToken->getTokenType() == OpcUa_UserTokenType_UserName)
    {
        if (bEnableUserPw == OpcUa_False)
        {
            return OpcUa_BadIdentityTokenRejected;
        }
        else
        {
            if (m_pUaServerApplicationCallback)
            {
                return m_pUaServerApplicationCallback->logonSessionUser(pSession, pUserIdentityToken, this);
            }
            else
            {
                return OpcUa_BadIdentityTokenRejected;
            }
        }
    }
    else if (pUserIdentityToken->getTokenType() == OpcUa_UserTokenType_Certificate)
    {
        if (bEnableCertificate == OpcUa_False)
        {
            return OpcUa_BadIdentityTokenRejected;
        }
        else
        {
            if (m_pUaServerApplicationCallback)
            {
                return m_pUaServerApplicationCallback->logonSessionUser(pSession, pUserIdentityToken, this);
            }
            else
            {
                return OpcUa_BadIdentityTokenRejected;
            }
        }
    }
    else if (pUserIdentityToken->getTokenType() == 4/*OpcUa_UserTokenType_KerberosToken*/)
    {
        if (bEnableKerberosTicket == OpcUa_False)
        {
            return OpcUa_BadIdentityTokenRejected;
        }
        else
        {
            if (m_pUaServerApplicationCallback)
            {
                return m_pUaServerApplicationCallback->logonSessionUser(pSession, pUserIdentityToken, this);
            }
            else
            {
                return OpcUa_BadIdentityTokenRejected;
            }
        }
    }

    return OpcUa_Bad;
}


UaStatus ServerConfigBase::setStackTraceSettings(OpcUa_Boolean bTraceEnabled, OpcUa_UInt32  uTraceLevel)
{
    m_bTraceEnabled = bTraceEnabled;
    m_uTraceLevel = uTraceLevel;
    return OpcUa_Good;
}

UaStatus ServerConfigBase::setServerTraceSettings(
    OpcUa_Boolean   bTraceEnabled,       //!< [in] Globally enable/disable trace output from the SDK
    OpcUa_UInt32    uTraceLevel,         /**< [in] Configures the level of messages traced
                                         - (0) NoTrace - No Trace
                                         - (1) Errors - Unexpected errors
                                         - (2) Warning - Unexpected behaviour that is not an error
                                         - (3) Info - Information about important activities like connection establishment
                                         - (4) InterfaceCall - Calls to module interfaces
                                         - (5) CtorDtor - Creation and destruction of objects
                                         - (6) ProgramFlow - Internal program flow
                                         - (7) Data - Data */
    OpcUa_UInt32    uMaxTraceEntries,    //!< [in] Maximum number of trace entries in one trace file
    OpcUa_UInt32    uMaxBackupFiles,     //!< [in] Maximum number of backup files
    const UaString& sTraceFile,          //!< [in] Name and path of the trace file
    OpcUa_Boolean   bDisableFlush        //!< [in] Disable flushing the trace file after each trace entry
)
{
    m_bSdkTraceEnabled = bTraceEnabled;
    m_uSdkTraceLevel = uTraceLevel;
    m_uMaxTraceEntries = uMaxTraceEntries;
    m_uMaxBackupFiles = uMaxBackupFiles;
    m_sTraceFile = sTraceFile;
    m_bDisableFlush = bDisableFlush;
    return OpcUa_Good;
}

void ServerConfigBase::setRejectedUserCertificatesCount(OpcUa_UInt32 nRejectedUserCertificatesCount)
{
    m_nRejectedUserCertificatesCount = nRejectedUserCertificatesCount;
}

void ServerConfigBase::setRejectedUserCertificatesDirectory(const UaString& sRejectedUserCertificatesDirectory)
{
    m_sRejectedUserCertificatesDirectory = sRejectedUserCertificatesDirectory;
}


/** Creates an instance of the UaEndpointBase class with default settings
*
*  The default endpoint is created with the standard OPC UA port 4840 and without security
*/
UaEndpointBase::UaEndpointBase()
{
    // initialize the EndpointUrl with NodeName
    char szHostName[256] = "127.0.0.1";
    UA_GetHostname(szHostName, 256);
    setEndpointUrl(UaString("opc.tcp://%1:4840").arg(szHostName), OpcUa_True);

    setSerializerType(OpcUa_Endpoint_SerializerType_Binary);
    UaEndpointSecuritySetting securitySetting;
    securitySetting.setSecurityPolicy(OpcUa_SecurityPolicy_None);
    securitySetting.addMessageSecurityMode(OPCUA_ENDPOINT_MESSAGESECURITYMODE_NONE);
    addSecuritySetting(securitySetting);
}

/** Creates an instance of the ServerConfigBase class working without file access
* @param sPort the port that is used by the endpoint.
* @param isSecure flag indicating if security is required for the endpoint.
*/
UaEndpointBase::UaEndpointBase(const UaString& sPort, bool isSecure)
{
    // initialize the EndpointUrl with NodeName
    char szHostName[256] = "127.0.0.1";
    UA_GetHostname(szHostName, 256);
    setEndpointUrl(UaString("opc.tcp://%1:%2").arg(szHostName).arg(sPort), OpcUa_True);

    setSerializerType(OpcUa_Endpoint_SerializerType_Binary);
    UaEndpointSecuritySetting securitySetting;
    if (isSecure)
    {
        securitySetting.setSecurityPolicy(OpcUa_SecurityPolicy_Basic256Sha256);
        securitySetting.addMessageSecurityMode(OPCUA_ENDPOINT_MESSAGESECURITYMODE_SIGN);
        securitySetting.addMessageSecurityMode(OPCUA_ENDPOINT_MESSAGESECURITYMODE_SIGNANDENCRYPT);
        addSecuritySetting(securitySetting);
    }
    else
    {
        securitySetting.setSecurityPolicy(OpcUa_SecurityPolicy_None);
        securitySetting.addMessageSecurityMode(OPCUA_ENDPOINT_MESSAGESECURITYMODE_NONE);
        addSecuritySetting(securitySetting);
    }
}

/** Destroys the UaEndpointBase object */
UaEndpointBase::~UaEndpointBase()
{
}

/** Set the certificate store for the endpoint.
*/
void UaEndpointBase::setCertificateStore(
    OpcUa_UInt32 endpointCertificateStoreIndex, //!< The index of the CertificateSore used for the endpoint
    CertificateStoreConfiguration* pEndpointCertificateStore) //!< The CertificateStoreConfiguration object for the endpoint
{
    if (m_pEndpointCertificateStore)
    {
        m_pEndpointCertificateStore->releaseReference();
    }
    if (m_pEndpointCertificateSettings)
    {
        m_pEndpointCertificateSettings->releaseReference();
    }

    m_endpointCertificateStoreIndex = endpointCertificateStoreIndex;
    m_pEndpointCertificateStore = pEndpointCertificateStore;
    if (m_pEndpointCertificateStore)
    {
        m_pEndpointCertificateStore->addReference();
        if (m_pEndpointCertificateStore->certificateCount() > 0)
        {
            m_pEndpointCertificateSettings = m_pEndpointCertificateStore->getCertificate(0);
            if (m_pEndpointCertificateSettings)
            {
                m_pEndpointCertificateSettings->addReference();
            }
        }
    }
}
Best regards
Unified Automation Support Team

User avatar
Support Team
Hero Member
Hero Member
Posts: 3072
Joined: 18 Mar 2011, 15:09

Re: OpcServer setting ServerConfigData

Post by Support Team »

For testing with DemoServer modify servermain.cpp:

Code: Select all

#define USE_SERVERCONFIG_BASE TRUE

int OpcServerMain(const char* szAppPath, const char* szConfigFileName)
{
    int ret = 0;

    //- Initialize the environment --------------
#if SUPPORT_XML_PARSER
    // Initialize the XML Parser
    UaXmlDocument::initParser();
#endif
    // Initialize the UA Stack platform layer
    ret = UaPlatformLayer::init();
    //-------------------------------------------

    if ( ret == 0 )
    {
        //- Start up OPC server ---------------------
        // This code can be integrated into a start up
        // sequence of the application where the
        // OPC server should be integrated
        //-------------------------------------------
        // Create and initialize server object
        OpcServer* pServer = new OpcServer;
        // Set the callback for user authentication
        MyServerCallback serverCallback;

#if USE_SERVERCONFIG_BASE
        OpcUa_ReferenceParameter(szConfigFileName);
        char szHostName[256];
        UaString sHostname;
        if (0 == UA_GetHostname(szHostName, 256))
        {
            sHostname = szHostName;
        }
        ServerConfigBase* pServerConfig = new ServerConfigBase(
            szAppPath,
            szAppPath,
            szAppPath,
            SERVERCONFIG_PRODUCTURI,
            SERVERCONFIG_MANUFACTURERNAME,
            SERVERCONFIG_PRODUCTNAME,
            SERVERCONFIG_SOFTWAREVERSION,
            SERVERCONFIG_BUILDNUMBER,
            UaString("urn:%1:UnifiedAutomation:UaServerCpp").arg(sHostname),
            UaString("UaServerCpp@%1").arg(sHostname),
            pServer,
            &serverCallback);

        // add Endpoint None endpoint and Basic256
        UaEndpointBase* pEndpoint = new UaEndpointBase("48010", false);

        // add Endpoint Basic256
        UaEndpointSecuritySetting securitySetting;
        securitySetting.setSecurityPolicy(OpcUa_SecurityPolicy_Basic256);
        securitySetting.addMessageSecurityMode(OPCUA_ENDPOINT_MESSAGESECURITYMODE_SIGNANDENCRYPT);
        pEndpoint->addSecuritySetting(securitySetting);

        // configure rejected directory
        pServerConfig->setRejectedCertificatesDirectory(UaString("%1/pkiserver/rejected").arg(szAppPath));

        // configure available user tokens
        pServerConfig->setEnableUserPw(OpcUa_True);
        pServerConfig->setEnableCertificate(OpcUa_True);
        pServerConfig->setUserIdentityTokenSecurityPolicy(OpcUa_SecurityPolicy_Basic256);
        pServerConfig->setRejectedUserCertificatesCount(123);
        pServerConfig->setRejectedUserCertificatesDirectory(UaString("%1/pkiuser/rejected").arg(szAppPath));

        // configure certificate store for user certificates
        CertificateStoreConfiguration* pCertConfig = NULL;
        UaString sRejected;
        OpcUa_UInt32 nNumRejected = 0;
        OpcUa_Boolean bCertTokenconfigured = OpcUa_False;

        pServerConfig->getDefaultUserCertificateStore(
            &pCertConfig,
            sRejected,
            nNumRejected,
            bCertTokenconfigured);

        pCertConfig->m_sCertificateTrustListLocation = UaString("%1/pkiuser/trusted/certs").arg(szAppPath);
        pCertConfig->m_sCertificateRevocationListLocation = UaString("%1/pkiuser/trusted/crl").arg(szAppPath);
        pCertConfig->m_sIssuersCertificatesLocation = UaString("%1/pkiuser/issuers/certs").arg(szAppPath);
        pCertConfig->m_sIssuersRevocationListLocation = UaString("%1/pkiuser/issuers/crl").arg(szAppPath);

        // add Endpoint
        pServerConfig->addEndpoint(pEndpoint);
        // set ServerConfig
        pServer->setServerConfig(pServerConfig);
        pServer->setCallback(&serverCallback);
#else // USE_SERVERCONFIG_BASE
        // Create configuration file name
        UaString sConfigFileName;

        if (szConfigFileName == 0)
        {
            sConfigFileName = UaString(szAppPath);

#if SUPPORT_XML_PARSER
            sConfigFileName += "/ServerConfig.xml";
#else
            sConfigFileName += "/ServerConfig.ini";
#endif
        }
        else
        {
            sConfigFileName = UaString(szConfigFileName);
        }

        pServer->setServerConfig(sConfigFileName, szAppPath);
        pServer->setCallback(&serverCallback);
#endif // USE_SERVERCONFIG_BASE

        // Add NodeManager for Unified Automation Demo namespace
        Demo::NodeManagerDemo *pDemoNodeManager = new Demo::NodeManagerDemo(OpcUa_True, szAppPath);
        ...
Best regards
Unified Automation Support Team

Post Reply