OPCUA WTF

OPCUA has a lot of surprising things in this article we will try to list some of them.

NodeID parsing

It is impossible to reuse code for parsing Node IDs for JSON and UADP.

JSON NodeID types:
  • Numeric - 0

  • String - 1

  • Guid - 2

  • ByteString - 3

UADP NodeID types:
  • TwoByte - 0

  • FourByte - 1

  • Numeric - 2

  • String - 3

  • Guid - 4

  • ByteString - 5

  • OPCUA encodings JSON and UADP has different NodeID formats and type enums. The can be a little hack UADPNodeIDType = JsonIDType + 2 can work. But it is useless unwanted logic.

  • Numeric types can be inferenced from range of a number. For example if a number is in range of 0-255 it is a TwoByte NodeID. If a number is in range of 0-65535 it is a FourByte NodeID. If a number is in range of 0-4294967295 it is a Numeric NodeID. The problem is that some systems can force to use for example Numeric types instead of TwoByte. In this case it is impossible to inferenced NodeID type from a number.

Namespace Index not constant

Namespace index is not constant in general. Every server can load several companion specifications from XML files Nodeset2.xml. If two servers controlling the same kind of machines but loads XML in different order you will get same Address space hierarchy but NodeIDs wil have different NamespaceIndex.

It is unclear how to handle this situation. The only way is to use ExpandedNodeID with NamespaceURI. But I haven’t seen any server that uses NamespaceURI in general: they use NamespaceIndexes.

The second problem. Address space of a server contains two predefined namespaces: NS0 with index 0, and local namespace with Index 1. Usually XML files do not use NamespaceUri for nodeIDs but use NamespaceIndex. Namespace Indexes in files starts from 1, NodeIDs are in the string representation. Because of this loading of any XML file require fixing NodeIDs: parse, change namespace, and save back.