OPC UA Development Toolkits

Licensing Model of the OPC UA C++ Development Toolkits [C++]

The Toolkit installation package installs a time limited but otherwise fully Toolkit package which can be used to develop OPC UA applications. Without entering a client or server license, the Toolkit-based application will stop to work after a runtime of 90 minutes. On Windows systems a message box will notify the user about the elapsed runtime of the demo version.

To remove the run time limitation in applications the appropriate license keys must be provided to the Toolkit during initialization of the application. Different license keys are available to individually enable different Toolkit features.

License keys depend on the target system. This means that, for example, a Server license for Windows will not unlock the Server feature in a VxWorks server application.

The available features are:

  • UA Server: enables all required functions for OPC UA servers.
  • UA Client: enables all required functions for OPC UA clients.

Note: If more than one feature shall be used (e.g. if you are developing both a client and server in the same module) all required features must be enabled separately.

Activating a license
The following code illustrates how to activate your license key XXXX-XXXX-XXXX-XXXX-XXXX:
ObjectPointer<Application> application = Application::instance();
application->activateLicense(EnumFeature_Server, _T("XXXX-XXXX-XXXX-XXXX-XXXX"));
application->activateLicense(EnumFeature_Client, _T("XXXX-XXXX-XXXX-XXXX-XXXX"));

OPC UA C++ Toolkits V5.5x.x Windows Source Code installation [C++]

Getting started instructions to install and build:

    1. Install the binary version of the toolkit setup.
    2. Extract the content of the source code archive (e.g. InstallOpcUaCppToolkitWindows5.52.0_Source.zip). The zip file is password protected and the password is the source code license key provided.
    3. Copy the content of the source code archive over the installed version of the toolkit e.g.: C:\ProgramData\Softing\OPCUACppToolkit\V5.5x\
    4. Use the Visual studio specific solutions to rebuild the toolkit core binaries. The compiled binaries will be binary license free.
    5. The toolkit binaries generated can be now used in new UA Applications compiled using the Softing OPC UA C++ Toolkits API

Error Handling / Enabling Tracing [C++]

Error Handling:
All functions that may encounter errors during execution use the enumeration EnumStatusCode to specify the error condition. The values of the StatusCode enumeration are defined by the OPC Foundation and are also used to denote errors in service calls. Also the quality of a variable’s value is denoted by the same StatusCode. See the reference manual to receive the complete list of all enumeration values.

The Toolkit provides the global function getEnumStatusCodeString() to retrieve the textual description of a StatusCode. This method can be useful for debugging error conditions.

The StatusCode class provides convenience methods for testing status codes. The static method StatusCode::isGood(), for example, may be used to test whether a given status code is 'good', i.e. does not indicate an error.

Enabling Tracing for the Toolkit Components:

If a status code does not provide enough information to identify a problem, you may turn on tracing of diagnostic messages. Tracing of diagnostic messages can be enabled in the Trace singleton class. The following code illustrates how to enable tracing to a log file: 

Trace::instance()->enableFileLogging(_T("logging.txt"), 10000, 5, 256);
Trace::instance()->enableTraceLevel(EnumTraceGroup_All, EnumTraceLevel_WarningAndHigher); 

The trace output can also be streamed over a TCP connection. See the Trace Viewer topic for further reference.

It is also possible to implement an individual tracing. To do this, invoke the Trace::enableCallbackLogging(). The given callback will be invoked on every enabled trace level / trace group.

Licensing OPC UA .NET Development Toolkits [.NET]

The installation package of the Softing OPC UA .NET Development Toolkit may be downloaded and used freely by anyone. By default, the installer will install and set up the base trial package. This may be used for OPC application development. The base trial package contains fully functional Softing OPC UA .NET Development Toolkit core dlls, which will run in trail version, unless a proper license is activated. The only limitation of the trial version is a 90 minutes run time limitation. After exceeding 90 minutes of runtime, the Softing OPC UA .NET Toolkit will stop working and a message box notifying the user will pop up.

There are 2 licensing models available for the Softing OPC UA .NET Development Toolkit V1.xx:

      • Source Code license - added when installing the product
      •  Binary license - provided by the OPC UA Client or Server application.


Binary License:

Accessing a licensed Softing OPC UA .NET Development Toolkit requires that the License key is programmatically provided by your OPC UA application before writing any other Softing OPC UA .NET Development Toolkit access code. For using licensing model an activation method must be called in your OPC UA application with the proper activation key.

Sample code in C#:
// Activate your OPC UA Server design time license
bool bActivated = application.ActivateLicense( LicenseFeature.Server, "XXXX-XXXX-XXXX-XXXX-XXXX");

// Activate your OPC UA Client design time license
bool bActivated = application.ActivateLicense( LicenseFeature.Client, "XXXX-XXXX-XXXX-XXXX-XXXX");

In the sample code above the placeholder "XXXX-XXXX-XXXX-XXXX-XXXX" shall be replaced by a valid License key. The License key is not bound to a specific PC and can be transferred to another PC. If you don't have a valid License key please contact the Softing's Sales Department


Source Code License:

Using a Softing OPC UA .NET Development Toolkit with activated Source Code License provides full source code of the Softing OPC UA .NET Development Toolkit 1.xx and enables the user to compile his activation free version of the Softing OPC UA .NET Development Toolkit 1.xx.

Activation of the Source Code License key must be done within the Installation Setup. 
After activation the source code for the activated components/features will be installed/extracted on your machine. If you don't have a valid Source Code License key please contact the Softing's Sales Department.

Note: After installing Softing OPC UA .NET Development Toolkit V1.xx with Source code license option, the Sdk Client and/or Sdk Server must be compiled. Use one of the Visual Studio solutions available in the ProgramData\Softing\OpcUaNetToolkit\V1.xx\src\Core folder.

When installing a later version of the Toolkit or its components over V1.20 the user must be aware that some components will be installed in parallel to the older ones. This behaviour is due to the fact that the installation folder names have changed from V1.20 to later versions. For example on upgrading the Toolkit from V1.20 to V1.25 there will be two versions of both Softing OPC Client and UA Demo Server but there will be only one version of the Server and Client Gateways. After any upgrades from V1.20 a check of the installation folders is recommended.

UserName and Password of the OPC UA Demo Server

Please enter the following UserName and Password in the OPC UA Demo Client to be able to connect to the OPC UA Demo Server.

UserName: usr 
Password: pwd

Where can I find the OPC UA Local Discovery Server?

OPC Foundation is providing an implementation of the OPC UA Local Discovery Server. The LDS ensures the very first interoperability step between OPC UA Clients and Servers. The LDS is expected to open well known port (4840) specified in the OPC UA Specification in order to respond to server registration respective clients interrogation calls, therefore it is impossible to run multiple variants of LDS server on the same machine. Softing, together with other vendors decided to support the OPC Foundation’s LDS implementation and to use and recommend it to be used by customers.

All Softing’s Windows based OPC UA products (toolkits, clients and servers) are redistributing the OPC Foundation’s LDS as a separate component in their setups.

We encourage the customers to download and deploy by themselves the LDS from the OPC Foundation website as well. The most recent version can be found here: 

No Local Discovery Server (LDS) exists for Linux systems [C++]

All Softing’s Windows based OPC UA products (toolkits, clients and servers) are redistributing the OPC Foundation’s LDS (Local Discovery Server) as a separate component in their setups.
Unfortunately the OPC Foundation doesn’t provide an LDS for Linux systems.

The Windows installation of the Toolkit installs the LDS and we deliver the batch file “update_discovery_server_store.bat”, which copies the LDS certificate to the server PKI store and the server certificate to the LDS PKI store.
That is how the file “cert_discovery_server.der” appears in the server PKI store.

Currently the only way to use a server on Linux with an LDS is to install and register the LDS on a remote Windows machine.
This step requires to exchange the certificates manually and to configure the correct IP address to the LDS in the sample.
For a quick approach, simply install the C++ Toolkit for Windows on that Windows machine, then have a look at “<installdir>/Source/PKI/update_discovery_server_store.bat“, where to get and insert the certificate files.

Note: the use of an LDS mainly makes sense when there are several servers and when you need one entry point, where all existing servers are visible. For one server only, the self discovery is sufficient. When you ask that server, which servers are available, then the server replies with the contact data of itself. This feature is automatically provided by the toolkit without additional configuration.

Note: it is not necessary to create a certificate for the Local Discovery Server. The LDS should be existent locally. The LDS can register itself.

install.bat generates the certificates but some of them are empty

install.bat might not work properly, if there are more than one network adapters present or if the adapter has an IPv6 address.
As workaround you should call the script with parameters:

install.bat <HostName> <UserDnsDomain> <IpAddress>

How to setup certificates in VxWorks [C++]

The batch file (for Windows) or shell script (for Linux) to create the PKI store can be called with command line parameters to configure the PKI store for any IP address or hostname (use the --help argument to see the options and required syntax).
Create a PKI store for your VxWorks device, copy it somewhere where the device can find it (on the device directly, a network path or a plugged flash card ...).
Then you also have to configure the application code to use the correct path.

Note: When you use the client and server on different machines, then both need an own PKI store, where you have to copy the "own" certificates to the "trusted" folder of the other ones PKI store.

Certificate basics [C++]

OPC UA applications usually have an Application Instance Certificate.

      1. If a signed or encrypted connection shall be established, then the client and server have to trust each other Application Instance Certificate (the certificates are in the trust lists).If that is the case, then the certificates are used to sign and/or encrypt the communication.

      2. If a client and server want to establish a not signed and not encrypted communication with anonymous authentication, then the trust relationship between client and server may, but does not have to exist. Then the client can decide to not configure an application instance certificate at all, because no certificate is transported.

      3. If the connection shall be established with an authentication token different to anonymous, then the server may demand a user token security policy.
        This is used to encrypt a certain part of the token, in case of the UserNameIdentityToken, the transported password is encrypted, otherwise without having a message encryption, the password would be transported unencrypted and could be read from everybody who listens at the network traffic. For this user token encryption again the server and client certificates are required and transported between the applications.
        The difference to case 1 is, that the certificates are not checked whether they are trusted, they are only needed to encrypt the user token at the connection establishment.

        You need an Application Instance Certificate for your application. Please have a look at the batch files that we use to create the demo store certificates of our test and sample applications at <installdir>\Source\PKI\batches. You are free to modify them to your needs.
        You also need to set a PKIStoreConfiguration that has at least a configured trust list location.
        This trust list can be an empty folder, when your client does not have to trust any server certificate. Unfortunately this trust list has to be configured and has to exist in any case.</installdir>

Is it possible to run an OPC UA application without an application certificate? [.NET]

No, because the current version of the OPC UA specification requires that all OPC UA applications have a certificate that is exchanged and validated when creating a Session.

Exception: ‘Certificate is not trusted’ [.NET]

This exception will be thrown if the certificate of the server is not found in the trust list of the client or the certificate of the client is not found in the trust list of the server.
In this case the connection will be refused.

In order to establish a trust relationship between two applications (client and server) a manual copy of the certificate’s public keys to the trust list of the partner application need to be performed. This means the public key certificate of the client application needs to be copied to the trust list location of the server application and the public key certificate of the server application needs to be copied to the trust list of the client application.

You will probably find the missing certificate in the rejected certificate store.
Make sure that the certificate is in the trusted PKI folder and not in the rejected certificate store.  (e.g. C:\ProgramData\Softing\OpcUaNetDemoServer\pki\trusted\certs\)

Exception: 'The Certificate Generator utility is not installed' [.NET]

The Sdk uses the Opc.Ua.CertificateGenerator.exe utility to create a new self signed instance certificate if one does not exist. This utility is installed by the Softing OPC UA .NET Development Toolkit installer and by the Softing OPC UA .Net DemoServer installer. 
It should be located in \Program Files\Common Files\OPC Foundation\UA\v1.0\Bin. If isn't installed in this location, the Sdk also looks for this utility in the same folder as the application.

Exception: ‘Could not create a certificate via a proxy: Input file was not processed properly’ [.NET]

The error appears because the CertificateGenerator tool cannot be found on the local machine.

The OPC UA .NET Development Toolkit SDK uses the Opc.Ua.CertificateGenerator.exe utility to create a new self signed instance certificate if one does not exist. 
The CertificateGenerator tool is provided by the OPC Foundation as part of the standard "Local Discovery Server" installation.
This utility is also installed by the Softing OPC UA .NET Development Toolkit installation package and by the Softing OPC UA .Net DemoServer setup. It should be located in

\Program Files\Common Files\OPC Foundation\UA\v1.0\Bin.

If isn't installed in this location, the SDK also looks for this utility in the same folder as the application.

The problem can be fixed by copying the .exe file of the tool from another machine where Softing .NET Toolkit is installed.

If the thumbprint was explicitly specified in the configuration file of the application, it can also cause that a new certificate cannot be generated. The “Thumbprint” entry in the SecurityConfiguration\ApplicationCertificate path needs to be removed before a new self signed certificate can be created. Also, if the “SubjectName” has the format [CN=ApplicationName, DC=domain], the format must be reduced to contain only the [ApplicationName].  

Another problem might be that the file path where the application is located is too long. In this case, the application folder should be moved to a lower level in the folder structure (e.g. directly on the root folder).

Exception: ‘Thumbprint was explicitly specified in the configuration. Cannot generate a new certificate’ [.NET]

The "Thumbprint was explicitly specified in the configuration. Cannot generate a new certificate" error appears in case the Thumbprint is specified in the xml configuration file and the certificate was moved or deleted.

The fix is to delete the thumbprint manually from the configuration file and leave only the path and the subject.

      <SubjectName>UA Demo Server</SubjectName>

If the “SubjectName” has the format [CN=ApplicationName, DC=domain], the format must be reduced to contain only the [ApplicationName].

Exception when calling connect(): SubjectName does not match the SubjectName of the current certificate [.NET]

The issue can be caused in different scenarios.
Please check the following:

      • make sure creating a new certificate when moving the client application on another PC. Delete the certificates from pki\own folder when moving the application on another machine. The Client should create a new certificate for the actual host at the first time. Therefore the CertificateGenerator utility should also be available on the new machine for this purpose.
      • make sure not calling the LoadApplicationConfiguration() method multiple times in your code. It should be called just at the startup. (The same for Application.Configuration.Validate() method.)
      • make sure setting the Application.Configuration.ApplicationName parameter without "CN=" or "DC=" inside (for eg. "Softing OPC UA .NET Toolkit UA Client Sample").

In case the issue still exists please send us the call stack of the exception.

Retrieving the supported endpoints [.NET]

The GetEndpoints service returns the list of endpoints supported by the Server and all the configuration information required to establish a SecureChannel and a Session. The server certificate is also contained in the EndpointDescription data. If this information is already known to the Client (e.g. read it from a configuration file), the GetEndpoints call is not necessary.

Timestamps are transported as UTC time

According to OPC UA specifications the timestamps are transported as UTC time in order to avoid inconsistencies in case Client and Server applications are running on different time zones.

The UA applications should convert these values to the local time at the receive moment (now.ToLocalTime()).

Two different Client APIs are provided with the OPC UA .NET Toolkit [.NET]

The Softing OPC UA .NET Client Toolkit is composed of two different APIs. Applications can be built using both of them:

      • simplified API (Toolkit)
      • advanced API (SDK)

- simplified application public interface, developed on top of the Client SDK. Applications can be very easily built with this API. But this API exposes only the basic OPC UA functionality for a client application. 
Classes to be used are contained in the Softing.Opc.Ua.Toolkit namespace.

SDK - advanced application public interface that can be used to develop advanced OPC UA features. This API is not very easy to use. 
Classes to be used are contained in the Softing.Opc.Ua.Sdk namespace.

What is the difference between the Session.KeepAliveInterval and the Subsription.LifeTimeCount settings? [.NET]

The Session.KeepAliveInterval defines the value (in milliseconds) indicating how frequently the server connection is checked to see whether the communication is still working or not.
This parameter is used by Clients to detect a connection failure with the Server.

In case you are using the "Softing.Opc.Ua.Sdk.Client.dll" for your Client application, a SessionReconnectHandler can be used for detecting the communication failures and for automatic restore of the session in this case.

If you are using the "Softing.Opc.Ua.Toolkit.dll" library for your Client application, the reconnect mechanism happens automatically in the background in case a connection is lost. 
It is recommended using this simplified Toolkit API for your UA Client application implementation.

The Subscription.LifeTimeCount represents the keep-alive mechanism negotiated at subscription level and it is used by the Server to inform the Client that the monitored items of the subscription don't have a value change for a longer period. 
If there is a number of publish intervals (represented by LifeTimeCount) without notifications then an empty publish message will be sent to the Client.

When establishing a connection to a B&R PLC an error occurs regarding ServerEndpoints [.NET]

When trying to establish a connection to a B&R PLC the following error message appears:
The list of ServerEndpoints returned at CreateSession does not match the list from GetEndpoints.

This is a known problem of the B&R PLCs that we are already aware.
Normally this erroneous behaviour should be solved on the server side (the server doesn't respect the security requirements).

Softing has made a compromise regarding this and implemented a workaround.
The validation of the endpoints cannot be skipped because it is a requirement for OPC UA compliance. Therefore the validation will be performed, but the OPC UA .NET Toolkit only logs the error and allows the connection to be established.

The workaround is available up to the version 1.30 of the OPC UA .NET Toolkit.
Please install the latest version of the OPC UA .NET Toolkit from the web site.

Connecting an OPC UA Session over the http protocol sometimes fails [.NET]

Connecting an OPC UA Session over the http protocol sometimes fails, even if a session over the opc.tcp binary protocol is possible with the same security configuration.

Some OPC Servers don't respond to the GetEndpoints service over the http protocol with no security.
A solution is to call the Session.InitializeWithDiscoveryEndpointDescription before connecting the session. The method takes an EndpointDescription parameter that must be retrieved from the Application.Discovery method. This way all the missing Endpoint information, like the Server instance certificate, will be available before establishing the connection.

Some servers accept connections over http with no security if the url string is prefixed with "/None" like in "http://localhost:51511/UA/DemoServer/None".

Handles of Monitored Items are reassigned after an automatic reconnection [.NET]

After an automatic reconnection of the OPC UA .NET Toolkit, the values of Client handles will be reassigned. The previous assignment of a DataChangeNotification is then lost.

The handles for the MonitoredItems are changing in case the items are recreated on the Server side because they represent Server assigned identifiers.

In case unique names are assigned at application level, the DisplayName can be used for identifying the items instead of the handles.

In some cases the session from the Server is destroyed after the connection is lost (e.g. the Server application was restarted or the Server destroyed the session due to a timeout).
In this case the client will recreate a session with the same configuration (subscriptions, monitored items) but some new identifiers will be generated by the Server (SessionId, SubscriptionIds, MI Ids).

Therefore it is not safe to relay on the initially assigned handles.

In addition, it is recommended using at least the version 1.30 of the OPC UA .NET Development Toolkits. It has some improvements in the reconnect mechanism. i.e. it attempts to regain the server session if possible.

What is the difference between the Namespace Index (ns) and the Namespace URI (nsu) access? [.NET]

In OPC UA the server's address space is described using the name-spaces concept. All addressable entities in the server must belong to one single namespace.

The namespace must contain unique identifiers and using different name-spaces, the server's designer, can ensure a name collision free addressing even in case the same identifiers are used.

A namespace in the server is uniquely represented by an URI (string). The server exposes the list of it's namespace URIs in an array. The index () location of an namespace URI is this array very important because on the regular read/write/subscribe operations only the namespace index will be used for performance reasons. (It is faster to transport an integer value than a full blown string.)

In a server the namespace URIs may not change, but the position of a certain namespace URI in the namespace array may change. That's the reason of existence of a so called ExpandedNodeID structure that besides the namespaceID and Identifier contains the URI of the namespace as well. This ExpandedNodeID should only be used for persisting the identifiers at the client side and for validating that the namespace indexes did not change on the server after a server restart. Nn order to read / write / monitor, the API requires the application to provide a NodeID. This structure is supposed to uniquely identify a certain resource in the address space of a server.

The NodeID consists of a NamespaceIndex (ns) and an Identifier (which is a union and can be a string or an integer or a GUID or a byteArray - opaque). For the NodeID no Namespace URI (nsu) is required. The nsu is only required for an ExpandedNodeID definition.

The namespace URI string is never used in the actual interaction with the server, just the namespace index is used.

The namespace index is always mandatory, the namespace URI is optional and actually not required when NodeID class is used.

What is the purpose of the ServerIndex property in the expanded node id? [.NET]

The ServerIndex is an advanced field that provides the information if the addressed NodeID is located on the local Server, or it resides on a remote Server. This is relevant for the Servers that act as aggregation Servers and retrieve their data from underlying OPC Servers. Therefore there is the ServerIndex that identifies the Server that contains the TargetNode. This Server may be the local Server or a remote Server.

This index is the index of that Server in the local Server's Server table. 
The index of the local Server in the Server table is always 0. 
All remote Servers have indexes greater than 0.

The Server table is contained in the Server Object in the AddressSpace. The Client may read the Server table Variable to access the description of the target Server.

Using a normal non aggregation Server / Server chaining solution that parameter is always 0.

Continuation Point / Data Restriction per Client request or on Server side

Some OPC UA services (e.g. HistoryRead to retrieve historical values from a variable) allow clients to restrict the maximum number of results per request. If a server has more results to deliver, it returns a continuation point along with the results which the client can use to request more results. A server application must be able to deliver the remaining result with context information stored within a continuation point.

Browsing the Address Space
OPC UA provides the services Browse and BrowseNext to browse the address space of a server. Browsing the address space is a way to get all nodes that are connected to another node by references. To retrieve for example complete trees or the whole address space, several browse calls are necessary which use the results of previous browse calls. The service allows both the client and the server to restrict the number of the returned results. If the number of results exceeds this maximum, a so-called continuation point is created in the server and passed to the client. The continuation can be passed with the BrowseNext to retrieve the remaining browse results.

How to write a single value into a multi-dimensional array [.NET]

The following code snippet in .NET demonstrates how to write a single value into a two-dimensional array:    
// Write with IndexRange    
WriteValue valueToWrite = new WriteValue();    
valueToWrite.NodeID = new NodeID("ns=2;s=/Static/All Profiles/Arrays2D/Int32"); // DemoServer:   
valueToWrite.AttributeID = AttributeID.Value;    
valueToWrite.IndexRange = "0,0";    
valueToWrite.Value = new DataValue();    
valueToWrite.Value.Value = new int[,] { {100}};    

Console.WriteLine("Writing the value for NodeID: {0}", valueToWrite.NodeID);    

    StatusCode writeResult = session.Write(valueToWrite);        
    // Display the result.         
    Console.WriteLine("Write Result = {0}", writeResult);    
catch (Exception ex)    
    Console.WriteLine("Write error: {0}", ex.Message);    

Please make sure when setting "valueToWrite.Value.Value" to use a two-dimensional value with the correct data type (even if it contains a single value).

In the OPC UA specification the IndexRange syntax for multi-dimensional arrays is specified as follows:  
Multi-dimensional arrays can be indexed by specifying a range for each dimension separated by a ‘,’. For example, a 2x2 block in a 4x4 matrix could be selected with the range “1:2,0:1”. 
A single element in a multi-dimensional array can be selected by specifying a single number instead of a range. For example, “1,1” specifies selects the [1,1] element in a two dimensional array.
Dimensions are specified in the order that they appear in the ArrayDimensions Attribute. All dimensions shall be specified for a NumericRange to be valid.
All indexes start with 0. The maximum value for any index is one less than the length of the dimension.

How to create Monitored Items efficiently using the simplified Client API [.NET]

In order to create multiple monitored items in a single service call you need to do the following sequence:

      • create a Subscription object in "Disconnected" state (you can do this by either calling Disconnect after creation or creating it on a disconnected session)
      • add all the required monitored items to the Subscription (by passing the subscription in the constructor)
      • call subscription.Connect() with "deep" and "active" parameters set to true. This will create the items in a single service request

A small code sample based on Softing Demo Server:

Subscription subscription = new Subscription(m_session, "ClientSubscription");

// Create 100 items
for (int j = 0; j <= 99; j++)
   string itemId = String.Format("ns=2;s=/Dynamic/All Profiles/Scalar Mass/Int32/Int320{0}", j);
   // add a monitored item.
   MonitoredItem monitoredItem = new MonitoredItem(subscription, new NodeId(itemId),
      AttributeId.Value, null, String.Format("MonitoredItem{0}", (j + 1)));
   // subscribe to DataChange notification event.
   monitoredItem.DataChangesReceived += new EventHandler<datachangesnotificationeventargs>(DataChangeNotification);

Events are not received in the same order as they were triggered [.NET]

In a multi-threading environment it is possible that some events are not received in the same order as they were triggered. It happens especially in heavy load scenarios, when having multiple fast changing values.
This situation is also described in the OPC UA specifications and it can happen on both Server- and Client side.

On the Client side, the value of ServerTimestamp can be used for sorting the data. The ServerTimestamp for item notification can be retrieved from the dataChangeNotification.Value.ServerTimestamp.

The DataChangeNotification.SequenceNo will also identify the subscription publish message that the notification belongs to. It happens sometimes that the order of Publish responses arriving from the Server are something like this sequence: 1, 2, 4, 3. This behavior is also accepted as valid in the OPC UA specification.

In a C# Client you can use the Subscription.DataChangesReceived event instead of MonitoredItem.DataChangesReceived. This event will send the complete list of notifications from a publish response. In this case the chance of a wrong order is lower because it can be processed faster.

OPC UA Client cannot connect to OPC UA Server [.NET]

In case you are not able to connect to an OPC UA Server running on a different machine then please check the following:

      • make sure the Server endpoint is accessible. i.e. the Server machine can be accessed over the network and the Server port is not blocked (Firewall).
      • make sure that Softing OPC UA Client certificate is trusted by the Server application. Softing OPC UA Client will display a pop-up and the user can decide what to do in case the Server certificate is not trusted. So no manual steps required.
      • make sure that the Client and Server clocks are synchronized (also the TimeZone). OPC UA applications require Client and Server clocks to be in sync and sometimes this can be the source of rejected connections.
      • make sure that at least the Client can discover the available Server endpoints. In "Session Connect" window, you go to "Manual\Double Click to Add Server...". Insert the Server address and click the button from the right side. If the server is accessible you should see all available endpoints. Choose one of them and try to connect to it.

If still not working please check what kind of error you get in the Client logs. Softing OPC UA Client has a live message log viewer on the bottom side of the main window. Copy the exact error message you get in the client log and send it to us for further investigation.

Using for logging different versions of the log4net.dll assemblies [.NET]

When the application is using for logging a different version of the log4net.dll assembly than the one required by the assemblies of the Softing Sdk then an assembly binding can be defined in the app.config file. The different versions of the log4net.dll file can be stored in different locations, like in the example below: 

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" />
        <codeBase version="" href="Log4Net\v.1.2.11\log4net.dll" />
        <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
        <codeBase version="" href="Log4Net\v.1.2.10\log4net.dll" />

Another option would be to copy the different versions of the log4net.dll file in the Global Assembly Cache (the %windir%\assembly\). 

Best Practices for Big Data Support on OPC UA Clients [C++]

When dealing with big data (lots of variables, that shall be read, written or subscribed), there are three general aspects that have to be considered:

      • Message Size
      • Timing
      • Resources

All OPC UA services are designed to handle the requests and responses for multiple nodes (like read, write and subscribe) and many of them can contain optional data.

In general, the more nodes are handled within service calls (the bigger the messages), compared to several smaller service calls, the less is the message overhead and the better the performance.

On the other hand, be aware that the OPC UA stacks have has a maximum message size, e.g. the C Stack of the OPC UA C++ Toolkit has a fixed size of 16 MB. 
Trying to send or receive bigger messages will produce errors. Try to limit the maximum message size by splitting too big service calls to several smaller ones or by specific configuration options (like Subscription::setMaxItemsPerPublish() or Application::setMaxMonitoredItemsPerService()).

Splitting operations into several smaller ones might increase the total required time, but might help to prevent timeout problems, as every single service can be processed faster.

Regarding the optional data, try to strip down not required optional information to reduce the message size and increase the speed. 
For example when reading values, you can reduce the size of each transported value by 16 bytes by not requesting the Server- and SourceTimestamps of the values.

The more data is transferred, the longer it will take to process it. Have a look on the configured service timeouts, they might need to be increased to prevent timeouts.

The client itself shouldn't have any resource problems, as a client usually does not have big memory storages or value monitors, but it influences the server's resources, like memory and CPU usage.

Theoretically the server should define proper limits to prevent resource problems, but even the client might think about a proper usage. 
For example the subscription service requires some memory for the buffering and some CPU for the observation at the Server, where the read service only needs to copy current values once but cannot collect only the changed values. 
Try to use subscriptions only for regularly changing nodes or for data that is important to be received as soon as possible (like alarms and events). 
Prefer the read service to receive values that have to be received seldom.

Is it possible to determine the structure of a UA server via the browse functionality? [C++]

In addition to the reference-specific information, the Browse Service supports only the Mandatory Basic node attributes (NodeId, NodeClass, BrowseName, DisplayName) that each node type must have.

All optional and type-specific attributes can only be handled via the Read Service.  

Does the Softing OPC UA C++ Toolkit support QNX operating system? [C++]

Our toolkit’s basic architecture is platform independent. With the same code basis we support 3 operating systems as reference implementation:

      • Windows,
      • Linux and
      • VxWorks.

The only difference between the 3 is a small platform abstraction layer. The toolkit can be easily ported on various other operating systems respective hardware platforms.  

Normally you have the complete source code for the toolkit therefore you can compile it yourself for various hardware platforms. The make-files are also prepared to be ready to use with cross-compilers use. The code itself is written in a platform independent manner.  

Softing can offer a small integration project for a specific operating system and HW platform as well. 
The pre-requirements for such an integration project are:

      • access to the build tool chain (cross-compiler) installed, and the tool chain usage exemplified with an sample
      • access to a target platform for execution of the tests and
      • a technical contact to assist us with details regarding the build tool chain and test platform.

The integration project consists of generating the toolkit binaries for the target platform, building the client & server test applications to run on this platform and executing the system tests on the target platform. Potential issues found during tests will be addressed and fixed by Softing. In case you’re interested in an integration project, please contact our sales department info.automation@softing.com regarding the commercial aspects.

How to load the OPC UA Toolkit libraries dynamically? [C++]

Normally when loading a DLL library dynamically, the whole initialization is done during a DllMain function. None the less, some operations are very risky to be called within a DllMain, like synchronization with other threads, this can cause deadlocks (see msdn.microsoft.com/en-us/library/windows/desktop/dn633971%28v=vs.85%29.aspx
The loadToolbox() function does this kind of synchronization which would likely cause such a deadlock.

To fix the problem, call loadToolbox() or unloadToolbox() after loading the DLLs, respectively before unloading the DLLs. This can be done via functions or static methods. Also keep in mind, that all instances of toolkit classes (including data classes) are destroyed before unloadToolbox() is called.

Redundancy support [C++]

The naming about the redundancy can be a bit confusing, we don't provide support for the server redundancy on the server side, but server redundancy on the client side - the client can communicate with a set of redundant servers.

Besides that, the Toolkit only supports the redundancy modes cold and warm.
The displayed enumeration displays all possibly existing redundancy types, but not all of them are supported.
The transparent redundancy mode is implicitly supported for the client, because this mode looks like a single server to clients.

The Toolkit provides only support on the client side to handle redundant servers.
The Toolkit does not provide support for redundancy on the server side, as all the sophisticated details depend on the application. (How to calculate the service levels? Shall the secondary server be started on a primary failure or is it always running? Is there data to be exchanged between the servers and how to exchange it?...).
But of course, it is possible using the OPC UA C++ Toolkit to build redundant servers.

None of the client specific callbacks will be called [C++]

Please check, if you initialized your Application as Client (or Server and Client). See ApplicationDescription::setApplicationType().
If that is not correctly set, everything seems to work fine, but none of the client specific callbacks to the API will ever be called.
In future versions, we will report some configuration errors for such problems.

HTTPs Support [C++]

Does the toolkit support HTTPS UA Binary & HTTPS UA XML facets?
The toolkit supports only the binary encoding for HTTPS.

Does the toolkit support HTTPS protocol over a VPN tunnel?
The toolkit cannot establish a VPN connection. This has to be done by a third party program.
Once a VPN connection is established, the target network is treated like a local network and the OPC UA communication should work. We didn't test such a VPN connection scenario yet.

How HTTPS certificates (Client and Server) are supported by the toolkit?
PKI configuration, self-signed, CA-chain, etc.
In OPC UA, every application requires to have an application instance certificate, which is used for anything related to security.
This specific application instance certificate is used also for the HTTPS communication.
The toolkit supports all common certificate features (self signed certificates, CA-chains, revocation lists ...).

Note: As HTTPS is always encrypted, the trust relationship between Client and Server must be established before the very first communication.
Some other OPC UA clients can have problems using typically insecure services
(like GetEndpoints) on a secure HTTPS channel.

BadWriteNotSupported [C++]

Write operations to some third party servers get rejected with the status "EnumStatusCode_BadWriteNotSupported".

Not all OPC UA Servers support writing timestamps. This is not a bug of the Softing OPC C++ UA Toolkit or the third party Server, it is the official way of a Server to say, that it doesn't support writing timestamps.

Don't call DataValue::setServerTimestamp() and maybe not even DataValue::setSourceTimestamp() on the DataValue that shall be written, respectively call these methods with an empty DateTime variable to clear existing timestamps.

BadHostUnknown [C++]

The BadHostUnknown error indicates that the hostname cannot be resolved. The operating system cannot resolve the hostname, or the hostname is incorrect. 
The DNS is not configured properly. 
A "ping <computer name>" will usually also not work.

In such cases, use the URL with the IP address to configure the session, or configure the name resolution (or edit the "hosts" file).

Debug Assertion during shutdown [C++]

Debug assertions during shutdown indicate that a toolkit class instance is still alive during unloadToolbox(). In general when toolkit class instances are destroyed after unloadToolbox(), this might cause memory leaks or crashes (accessing freed resources).

Make sure that all toolkit instances are destroyed before unloadToolbox().

If you use toolkit classes as global variables, you should better replace them with pointers, which can be assigned and released after loadToolbox() and before unloadToolbox().

Application::stop() and Application::uninitialize() should also be called before calling unloadToolbox().
Application::stop() will close the endpoints and this way the client connections will be closed as well.

How to read a Property value [C++]

Mixing up Attributes and Properties is a common misinterpretation.

An Attribute is some data, bound to a certain node class (Object, ObjectType,Variable, VariableType, ReferenceType, DataType and View). The available Attribues are fixed, thus they cannot be extended to contain additional data.

Properties have almost the same syntactical meaning as Attributes, but Properties are completely different nodes (of the node class Variable) with own Attributes. The Property node is referenced from the parent node via a HasProperty reference.

To read a Property value, you have to get the NodeId of that Property (e.g. via TranslateBrowsePathsToNodeIds) and perform a read on the Value Attribute.

How can I use a different OpenSSL version in my application than what is used by the toolkit? [C++]

If you have the source code of the toolkit, you can download the desired OpenSSL ".tar.gz" file to <InstallDir>/Source/Core/OpenSSL, move/remove the prior ".tar.gz" file from that folder and try to build the toolkit with the different OpenSSL (see OpenSSL Functionality). The toolkit should be compatible with most OpenSSL versions, otherwise it will report compilation errors.

If you have the binary version of the Windows toolkit, then the only problem is, that the two different OpenSSL DLLs typically want to have the same names. To solve that, you can rename the libraries libeay32.dll and ssleay32.dll to names with an equal length, e.g. libeayua.dll and ssleayua.dll. Then you can open the DLLs TB5STACK.dll (or TB5STACKx64.dll) and the renamed ssleay32.dll in an editor and search and rename the original DLL names by the new names.

Note: This will work only if the old and new DLL names have the same size, changing the size of the DLL content will cause problems!