[13]open62541v1.2 official documents in Chinese_ Internals 2

brief introduction

When writing an application, it is more comfortable to use some GUI tools to create an information model. Most tools can export data according to OPC UA Nodeset XML schema. open62541 includes a python based nodeset compiler, which can transform these information model definitions into a working server.

Note that you can use tools / nodeset_ The nodeset compiler found in the compiler subfolder is not an XML conversion tool, but a compiler. This means that it will create an internal representation when parsing the XML file and try to understand and verify the correctness of the representation in order to generate C code.

target

Translation and supplement open62541v1 2 official manual.

Publish / subscribe

Work in progress! This part will become a new chapter in the future.

In PubSub, participating OPC UA applications play the role of publishers and subscribers. Publishers are the source of data, and subscribers consume it. Communication in PubSub is message based. Publishers send messages to message oriented middleware without knowing which subscribers (if any) they may have. Similarly, subscribers are interested in specific types of data and process messages containing that data without knowing which publishers are there.

Message oriented middleware is a software or hardware infrastructure that supports sending and receiving messages between distributed systems. OPC UA PubSub supports two different variants of message oriented middleware, namely broker free form and broker based form. Broker free form means that message oriented middleware is a network infrastructure that can route datagram based messages. Subscribers and publishers use datagram protocols, such as UDP. In the broker based form, the core component of message oriented middleware is a message broker. Subscribers and publishers communicate with brokers using standard message transfer protocols, such as AMQP or MQTT.

This makes PubSub suitable for applications that require location independence and / or scalability.

The PubSub extension of OPC UA can realize fast and effective 1:m communication. PubSub extensions are protocol independent and can be used with broker based protocols such as MQTT and AMQP or broker free implementations such as UDP multicasting.

The PubSub API uses the following scheme.

  1. Create a configuration for the required PubSub element.
  2. Call the add[element] function and pass in the configuration.
  3. The add[element] function returns the unique nodeId of the internally created element.

Check out the PubSub tutorial to learn more about API usage.

+-----------+
| UA_Server |
+-----------+
 |    |
 |    |
 |    |
 |    |  +----------------------+
 |    +--> UA_PubSubConnection  |  UA_Server_addPubSubConnection
 |       +----------------------+
 |        |    |
 |        |    |    +----------------+
 |        |    +----> UA_WriterGroup |  UA_PubSubConnection_addWriterGroup
 |        |         +----------------+
 |        |              |
 |        |              |    +------------------+
 |        |              +----> UA_DataSetWriter |  UA_WriterGroup_addDataSetWriter     +-+
 |        |                   +------------------+                                        |
 |        |                                                                               |
 |        |         +----------------+                                                    | r
 |        +---------> UA_ReaderGroup |    UA_PubSubConnection_addReaderGroup              | e
 |                  +----------------+                                                    | f
 |                       |                                                                |
 |                       |    +------------------+                                        |
 |                       +----> UA_DataSetReader |  UA_ReaderGroup_addDataSetReader       |
 |                            +------------------+                                        |
 |                                 |                                                      |
 |                                 |    +----------------------+                          |
 |                                 +----> UA_SubscribedDataSet |                          |
 |                                      +----------------------+                          |
 |                                           |                                            |
 |                                           |    +----------------------------+          |
 |                                           +----> UA_TargetVariablesDataType |          |
 |                                           |    +----------------------------+          |
 |                                           |                                            |
 |                                           |    +------------------------------------+  |
 |                                           +----> UA_SubscribedDataSetMirrorDataType |  |
 |                                                +------------------------------------+  |
 |                                                                                        |
 |       +---------------------------+                                                    |
 +-------> UA_PubSubPublishedDataSet |  UA_Server_addPublishedDataSet                   <-+
         +---------------------------+
               |
               |    +-----------------+
               +----> UA_DataSetField |  UA_PublishedDataSet_addDataSetField
                    +-----------------+

Compilation flags for PubSub

  • ua_enable_pubsub

    Enable experimental OPC UA PubSub support. This option will include the PubSub UDP multicast plug-in. It is disabled by default.

  • ua_enable_pubsub_deltaframes

    PubSub messages are different from keyframe (containing all published values) and delta frame (containing only changed values) messages. The creation of Deltaframe message will consume some additional resources, which can be disabled with this flag. It is disabled by default. Compile the human readable name of StatusCodes into a binary file. It is disabled by default.

  • **ua_enable_pubsub_file_config **

    Enable loading OPC UA PubSub configuration from file / ByteString. Enabling the PubSub information model method will also add a method to the publish / subscribe object, allowing PubSub to be configured at run time.

  • ua_enable_pubsub_informationmodel

    Enables the information model representation of PubSub configuration. For more details, see the PubSub information model representation below. It is disabled by default.

  • ua_enable_pubsub_monitoring

    Enable experimental PubSub monitoring. This function provides a basic framework for monitoring / timeout checking of PubSub components. Initially, the MessageReceiveTimeout check of DataSetReader is provided. It is implemented using an internal server callback. The monitoring back end can be changed by the application to meet real-time requirements. It is disabled by default.

  • UA_ENABLE_PUBSUB_ETH_UADP

    Enable OPC UA Ethernet PubSub support to transmit UADP network messages as the payload of Ethernet II frames without IP or UDP headers. This option will include publishing and subscriptions based on EtherType B62C. It is disabled by default.

  • UA_ENABLE_PUBSUB_ETH_UADP_ETF

    Enable the ETF function to allow users to calculate the transmission time with nanosecond accuracy to transmit data packets. In addition, PubSub is also supported to transmit UADP network messages as the payload of Ethernet II frames. It is disabled by default.

  • UA_ENABLE_PUBSUB_ETH_UADP_XDP

    Enable the XDP function to allow users to receive data packets using eXpress Data Path (XDP). It bypasses the TCP/IP layer and transmits frames from hardware / network devices to user applications, thus reducing the reception time. In addition, PubSub supports the transmission of UADP network messages as the payload of Ethernet II frames. It is disabled by default.

PubSub information model representation

The complete PubSub configuration can be found in the information model. The entry point is the node "PublishSubscribe", which is located under the server node. This standard defines no new service set for PubSub. Configuration can be done through methods in the information model. The information model representation of the current PubSub configuration is automatically generated. This function can be changed by changing the UA_ ENABLE_ PUBSUB_ Information model option to enable / disable.

connect

PubSub connection is an abstraction between specific transport protocols and PubSub functions. It can create multiple connections with different transport protocols at run time.

See the PubSub tutorial for details on API usage.

typedef enum  {
    UA_PUBSUB_COMPONENT_CONNECTION,
    UA_PUBSUB_COMPONENT_WRITERGROUP,
    UA_PUBSUB_COMPONENT_DATASETWRITER,
    UA_PUBSUB_COMPONENT_READERGROUP,
    UA_PUBSUB_COMPONENT_DATASETREADER
} UA_PubSubComponentEnumType;

typedef enum {
    UA_PUBSUB_PUBLISHERID_NUMERIC,
    UA_PUBSUB_PUBLISHERID_STRING
} UA_PublisherIdType;

#ifdef UA_ENABLE_PUBSUB_ETH_UADP_ETF
typedef struct {
    UA_Int32 socketPriority;
    UA_Boolean sotxtimeEnabled;
    /* SO_TXTIME-specific additional socket config */
    UA_Int32 sotxtimeDeadlinemode;
    UA_Int32 sotxtimeReceiveerrors;
} UA_ETFConfiguration;
#endif

struct UA_PubSubConnectionConfig {
    UA_String name;
    UA_Boolean enabled;
    UA_PublisherIdType publisherIdType;
    union { /* std: valid types UInt or String */
        UA_UInt32 numeric;
        UA_String string;
    } publisherId;
    UA_String transportProfileUri;
    UA_Variant address;
    size_t connectionPropertiesSize;
    UA_KeyValuePair *connectionProperties;
    UA_Variant connectionTransportSettings;
#ifdef UA_ENABLE_PUBSUB_ETH_UADP_ETF
    /* ETF related connection configuration - Not in PubSub specfication */
    UA_ETFConfiguration etfConfiguration;
#endif
};

#ifdef UA_ENABLE_PUBSUB_MONITORING

typedef enum {
    UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT
    // extend as needed
} UA_PubSubMonitoringType;

/* PubSub monitoring interface */
typedef struct {
    UA_StatusCode (*createMonitoring)(UA_Server *server, UA_NodeId Id, UA_PubSubComponentEnumType eComponentType,
                                      UA_PubSubMonitoringType eMonitoringType, void *data, UA_ServerCallback callback);
    UA_StatusCode (*startMonitoring)(UA_Server *server, UA_NodeId Id, UA_PubSubComponentEnumType eComponentType,
                                     UA_PubSubMonitoringType eMonitoringType, void *data);
    UA_StatusCode (*stopMonitoring)(UA_Server *server, UA_NodeId Id, UA_PubSubComponentEnumType eComponentType,
                                    UA_PubSubMonitoringType eMonitoringType, void *data);
    UA_StatusCode (*updateMonitoringInterval)(UA_Server *server, UA_NodeId Id, UA_PubSubComponentEnumType eComponentType,
                                              UA_PubSubMonitoringType eMonitoringType, void *data);
    UA_StatusCode (*deleteMonitoring)(UA_Server *server, UA_NodeId Id, UA_PubSubComponentEnumType eComponentType,
                                      UA_PubSubMonitoringType eMonitoringType, void *data);
} UA_PubSubMonitoringInterface;

#endif /* UA_ENABLE_PUBSUB_MONITORING */

/* General PubSub configuration */
struct UA_PubSubConfiguration {

    /* Callback for PubSub component state changes:
    If provided this callback informs the application about PubSub component state changes.
    E.g. state change from operational to error in case of a DataSetReader MessageReceiveTimeout.
    The status code provides additional information. */
    void (*pubsubStateChangeCallback)(UA_NodeId *Id,
                                      UA_PubSubState state,
                                      UA_StatusCode status);// TODO: maybe status code provides not enough information about the state change
#ifdef UA_ENABLE_PUBSUB_MONITORING
    UA_PubSubMonitoringInterface monitoringInterface;
#endif /* UA_ENABLE_PUBSUB_MONITORING */
};

The UA_ServerConfig_addPubSubTransportLayer is used to add a transport layer to the server configuration. The list memory is allocated and will be freed with UA_PubSubManager_delete.

Note

If the UA_String transportProfileUri was dynamically allocated the memory has to be freed when no longer required.

Note

This has to be done before the server is started with UA_Server_run.

UA_StatusCode
UA_ServerConfig_addPubSubTransportLayer(UA_ServerConfig *config,
                                        UA_PubSubTransportLayer *pubsubTransportLayer);

UA_StatusCode
UA_Server_addPubSubConnection(UA_Server *server,
                              const UA_PubSubConnectionConfig *connectionConfig,
                              UA_NodeId *connectionIdentifier);

/* Returns a deep copy of the config */
UA_StatusCode
UA_Server_getPubSubConnectionConfig(UA_Server *server,
                                    const UA_NodeId connection,
                                    UA_PubSubConnectionConfig *config);

/* Remove Connection, identified by the NodeId. Deletion of Connection
 * removes all contained WriterGroups and Writers. */
UA_StatusCode
UA_Server_removePubSubConnection(UA_Server *server, const UA_NodeId connection);

Published dataset

A published dataset (PDS) is a container for publishing information. PDS contains published variables and meta information. Metadata is usually generated automatically or given constant parameters as part of template functions. Template functions are standard defined and are intended to be used to configure tools. You should usually create an empty PDS and call the function to add new fields.

/* The UA_PUBSUB_DATASET_PUBLISHEDITEMS has currently no additional members and
 * thus no dedicated config structure. */

typedef enum {
    UA_PUBSUB_DATASET_PUBLISHEDITEMS,
    UA_PUBSUB_DATASET_PUBLISHEDEVENTS,
    UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE,
    UA_PUBSUB_DATASET_PUBLISHEDEVENTS_TEMPLATE,
} UA_PublishedDataSetType;

typedef struct {
    UA_DataSetMetaDataType metaData;
    size_t variablesToAddSize;
    UA_PublishedVariableDataType *variablesToAdd;
} UA_PublishedDataItemsTemplateConfig;

typedef struct {
    UA_NodeId eventNotfier;
    UA_ContentFilter filter;
} UA_PublishedEventConfig;

typedef struct {
    UA_DataSetMetaDataType metaData;
    UA_NodeId eventNotfier;
    size_t selectedFieldsSize;
    UA_SimpleAttributeOperand *selectedFields;
    UA_ContentFilter filter;
} UA_PublishedEventTemplateConfig;

/* Configuration structure for PublishedDataSet */
typedef struct {
    UA_String name;
    UA_PublishedDataSetType publishedDataSetType;
    union {
        /* The UA_PUBSUB_DATASET_PUBLISHEDITEMS has currently no additional members
         * and thus no dedicated config structure.*/
        UA_PublishedDataItemsTemplateConfig itemsTemplate;
        UA_PublishedEventConfig event;
        UA_PublishedEventTemplateConfig eventTemplate;
    } config;
} UA_PublishedDataSetConfig;

void
UA_PublishedDataSetConfig_clear(UA_PublishedDataSetConfig *pdsConfig);

typedef struct {
    UA_StatusCode addResult;
    size_t fieldAddResultsSize;
    UA_StatusCode *fieldAddResults;
    UA_ConfigurationVersionDataType configurationVersion;
} UA_AddPublishedDataSetResult;

UA_AddPublishedDataSetResult
UA_Server_addPublishedDataSet(UA_Server *server,
                              const UA_PublishedDataSetConfig *publishedDataSetConfig,
                              UA_NodeId *pdsIdentifier);

/* Returns a deep copy of the config */
UA_StatusCode
UA_Server_getPublishedDataSetConfig(UA_Server *server, const UA_NodeId pds,
                                    UA_PublishedDataSetConfig *config);

/* Returns a deep copy of the DataSetMetaData for an specific PDS */
UA_StatusCode
UA_Server_getPublishedDataSetMetaData(UA_Server *server, const UA_NodeId pds,
                                      UA_DataSetMetaDataType *metaData);

/* Remove PublishedDataSet, identified by the NodeId. Deletion of PDS removes
 * all contained and linked PDS Fields. Connected WriterGroups will be also
 * removed. */
UA_StatusCode
UA_Server_removePublishedDataSet(UA_Server *server, const UA_NodeId pds);

Dataset field

The description of the published variable is named DataSetField. Each DataSetField contains a selection of information model nodes. DataSetField has additional parameters for publishing, sampling, and error handling.

typedef struct{
    UA_ConfigurationVersionDataType configurationVersion;
    UA_String fieldNameAlias;
    UA_Boolean promotedField;
    UA_PublishedVariableDataType publishParameters;

    /* non std. field */
    struct {
        UA_Boolean rtFieldSourceEnabled;
        /* If the rtInformationModelNode is set, the nodeid in publishParameter must point
         * to a node with external data source backend defined
         * */
        UA_Boolean rtInformationModelNode;
        //TODO -> decide if suppress C++ warnings and use 'UA_DataValue * * const staticValueSource;'
        UA_DataValue ** staticValueSource;
    } rtValueSource;


} UA_DataSetVariableConfig;

typedef enum {
    UA_PUBSUB_DATASETFIELD_VARIABLE,
    UA_PUBSUB_DATASETFIELD_EVENT
} UA_DataSetFieldType;

typedef struct {
    UA_DataSetFieldType dataSetFieldType;
    union {
        /* events need other config later */
        UA_DataSetVariableConfig variable;
    } field;
} UA_DataSetFieldConfig;

void
UA_DataSetFieldConfig_clear(UA_DataSetFieldConfig *dataSetFieldConfig);

typedef struct {
    UA_StatusCode result;
    UA_ConfigurationVersionDataType configurationVersion;
} UA_DataSetFieldResult;

UA_DataSetFieldResult
UA_Server_addDataSetField(UA_Server *server,
                          const UA_NodeId publishedDataSet,
                          const UA_DataSetFieldConfig *fieldConfig,
                          UA_NodeId *fieldIdentifier);

/* Returns a deep copy of the config */
UA_StatusCode
UA_Server_getDataSetFieldConfig(UA_Server *server, const UA_NodeId dsf,
                                UA_DataSetFieldConfig *config);

UA_DataSetFieldResult
UA_Server_removeDataSetField(UA_Server *server, const UA_NodeId dsf);

Custom callback implementation

Users can publish and subscribe using their own callback implementation. Users must pay attention to calling callbacks within the time interval of each publication or subscription.

typedef struct {
    UA_StatusCode (*addCustomCallback)(UA_Server *server, UA_NodeId identifier,
                                       UA_ServerCallback callback,
                                       void *data, UA_Double interval_ms, UA_UInt64 *callbackId);

    UA_StatusCode (*changeCustomCallbackInterval)(UA_Server *server, UA_NodeId identifier,
                                                  UA_UInt64 callbackId, UA_Double interval_ms);

    void (*removeCustomCallback)(UA_Server *server, UA_NodeId identifier, UA_UInt64 callbackId);

} UA_PubSub_CallbackLifecycle;

Write group configuration

All writing groups are created in PubSubConnection. If the connection is deleted, it will be deleted automatically. WriterGroup is mainly used as DataSetWriter And network message settings. WriterGroup can be imagined as a producer of network messages. The creation of network messages is controlled by parameters, such as publishing interval, which is included in WriterGroup.

typedef enum {
    UA_PUBSUB_ENCODING_BINARY,
    UA_PUBSUB_ENCODING_JSON,
    UA_PUBSUB_ENCODING_UADP
} UA_PubSubEncodingType;

Write group configuration

Information release can be configured according to real-time requirements. RT level is consistent with different requirements. The levels listed below can be configured.

UA_ PUBSUB_ RT_ None -- > description.

Default "non RT" mode - > required. - > Restrictions- UA_PUBSUB_RT_DIRECT_VALUE_ACCESS (Preview - not implemented) – Description: the default "non RT" mode. Usually, the latest value of each DataSetField will be read out from the information model.

In this RT mode, the value source of each field is configured as a static pointer to a DataValue.

The publish cycle does not use the call server read function. - > requirement. All fields must be configured with a "staticValueSource". - > Restrictions- UA_PUBSUB_RT_FIXED_LENGTH (Preview - not implemented) - > description. All DataSetFields have a known, unchanging length.

The server will generate some buffers in advance and only use the memcopy operation to generate the requested PubSub package. - > requirement.

DataSetFields with variable size cannot be used in this mode. - > Restrictions.

The configuration must be frozen and cannot be changed when the WriterGroup is in the "running" state. UA_PUBSUB_RT_DETERMINISTIC (Preview - not implemented) – Description: – requirements. – > Restrictions-

Warning! For hard real-time requirements, the underlying system must be RT capable.

typedef enum {
    UA_PUBSUB_RT_NONE = 0,
    UA_PUBSUB_RT_DIRECT_VALUE_ACCESS = 1,
    UA_PUBSUB_RT_FIXED_SIZE = 2,
    UA_PUBSUB_RT_DETERMINISTIC = 4,
} UA_PubSubRTLevel;

typedef struct {
    UA_String name;
    UA_Boolean enabled;
    UA_UInt16 writerGroupId;
    UA_Duration publishingInterval;
    UA_Double keepAliveTime;
    UA_Byte priority;
    UA_MessageSecurityMode securityMode;
    UA_ExtensionObject transportSettings;
    UA_ExtensionObject messageSettings;
    size_t groupPropertiesSize;
    UA_KeyValuePair *groupProperties;
    UA_PubSubEncodingType encodingMimeType;
    /* PubSub Manager Callback */
    UA_PubSub_CallbackLifecycle pubsubManagerCallback;
    /* non std. config parameter. maximum count of embedded DataSetMessage in
     * one NetworkMessage */
    UA_UInt16 maxEncapsulatedDataSetMessageCount;
    /* non std. field */
    UA_PubSubRTLevel rtLevel;
} UA_WriterGroupConfig;

void
UA_WriterGroupConfig_clear(UA_WriterGroupConfig *writerGroupConfig);

/* Add a new WriterGroup to an existing Connection */
UA_StatusCode
UA_Server_addWriterGroup(UA_Server *server, const UA_NodeId connection,
                         const UA_WriterGroupConfig *writerGroupConfig,
                         UA_NodeId *writerGroupIdentifier);

/* Returns a deep copy of the config */
UA_StatusCode
UA_Server_getWriterGroupConfig(UA_Server *server, const UA_NodeId writerGroup,
                               UA_WriterGroupConfig *config);

UA_StatusCode
UA_Server_updateWriterGroupConfig(UA_Server *server, UA_NodeId writerGroupIdentifier,
                                  const UA_WriterGroupConfig *config);

/* Get state of WriterGroup */
UA_StatusCode
UA_Server_WriterGroup_getState(UA_Server *server, UA_NodeId writerGroupIdentifier,
                               UA_PubSubState *state);

UA_StatusCode
UA_Server_removeWriterGroup(UA_Server *server, const UA_NodeId writerGroup);

UA_StatusCode
UA_Server_freezeWriterGroupConfiguration(UA_Server *server, const UA_NodeId writerGroup);

UA_StatusCode
UA_Server_unfreezeWriterGroupConfiguration(UA_Server *server, const UA_NodeId writerGroup);

UA_StatusCode
UA_Server_setWriterGroupOperational(UA_Server *server, const UA_NodeId writerGroup);

UA_StatusCode
UA_Server_setWriterGroupDisabled(UA_Server *server, const UA_NodeId writerGroup);

Write group configuration

DataSetWriter is the link between WriterGroups and published datasets. The DataSetWriter contains configuration parameters and flags that affect the creation of DataSet messages. These messages are encapsulated in network messages. DataSetWriter must be connected to an existing PublishedDataSet and included in the WriterGroup.

typedef struct {
    UA_String name;
    UA_UInt16 dataSetWriterId;
    UA_DataSetFieldContentMask dataSetFieldContentMask;
    UA_UInt32 keyFrameCount;
    UA_ExtensionObject messageSettings;
    UA_ExtensionObject transportSettings;
    UA_String dataSetName;
    size_t dataSetWriterPropertiesSize;
    UA_KeyValuePair *dataSetWriterProperties;
} UA_DataSetWriterConfig;

void
UA_DataSetWriterConfig_clear(UA_DataSetWriterConfig *pdsConfig);

/* Add a new DataSetWriter to a existing WriterGroup. The DataSetWriter must be
 * coupled with a PublishedDataSet on creation.
 *
 * Part 14, 7.1.5.2.1 defines: The link between the PublishedDataSet and
 * DataSetWriter shall be created when an instance of the DataSetWriterType is
 * created. */
UA_StatusCode
UA_Server_addDataSetWriter(UA_Server *server,
                           const UA_NodeId writerGroup, const UA_NodeId dataSet,
                           const UA_DataSetWriterConfig *dataSetWriterConfig,
                           UA_NodeId *writerIdentifier);

/* Returns a deep copy of the config */
UA_StatusCode
UA_Server_getDataSetWriterConfig(UA_Server *server, const UA_NodeId dsw,
                                 UA_DataSetWriterConfig *config);

/* Get state of DataSetWriter */
UA_StatusCode
UA_Server_DataSetWriter_getState(UA_Server *server, UA_NodeId dataSetWriterIdentifier,
                               UA_PubSubState *state);

UA_StatusCode
UA_Server_removeDataSetWriter(UA_Server *server, const UA_NodeId dsw);

Subscription dataset

SubscribedDataSet describes the processing of the received dataset. SubscribedDataSet defines which field in the dataset is mapped to which variable in the OPC UA application. SubscribedDataSet has two subtypes called TargetVariablesType and SubscribedDataSetMirrorType. SubscribedDataSetMirrorType is not currently supported. SubscribedDataSet is set to TargetVariablesType, and then create a target variable list in Subscriber AddressSpace. TargetVariables is a list of variables to add to the subscriber address space. It defines a list of variable mappings between the received dataset fields and the variables added in the subscriber address space.

/* SubscribedDataSetDataType Definition */
typedef enum {
    UA_PUBSUB_SDS_TARGET,
    UA_PUBSUB_SDS_MIRROR
} UA_SubscribedDataSetEnumType;

typedef struct {
    /* Standard-defined FieldTargetDataType */
    UA_FieldTargetDataType targetVariable;

    /* If realtime-handling is required, set this pointer non-NULL and it will be used
     * to memcpy the value instead of using the Write service.
     * If the afterWrite method pointer is set, it will be called after a memcpy update
     * to the value. */
    UA_DataValue **externalDataValue;
    void *targetVariableContext; /* user-defined pointer */
    void (*afterWrite)(UA_Server *server,
                       const UA_NodeId *readerIdentifier,
                       const UA_NodeId *readerGroupIdentifier,
                       const UA_NodeId *targetVariableIdentifier,
                       void *targetVariableContext,
                       UA_DataValue **externalDataValue);
} UA_FieldTargetVariable;

typedef struct {
    size_t targetVariablesSize;
    UA_FieldTargetVariable *targetVariables;
} UA_TargetVariables;

/* Return Status Code after creating TargetVariables in Subscriber AddressSpace */
UA_StatusCode
UA_Server_DataSetReader_createTargetVariables(UA_Server *server,
                                              UA_NodeId dataSetReaderIdentifier,
                                              size_t targetVariablesSize,
                                              const UA_FieldTargetVariable *targetVariables);

/* To Do:Implementation of SubscribedDataSetMirrorType
 * UA_StatusCode
 * A_PubSubDataSetReader_createDataSetMirror(UA_Server *server, UA_NodeId dataSetReaderIdentifier,
 * UA_SubscribedDataSetMirrorDataType* mirror) */

data collector

DataSetReader can receive interested DataSetMessages sent by NetworkMessages and Publisher. DataSetReaders represent the necessary configuration for receiving and processing DataSetMessages on the subscriber side. DataSetReader must be linked to SubscribedDataSet and included in ReaderGroup.

/* Parameters for PubSubSecurity */
typedef struct {
    UA_Int32 securityMode;          /* placeholder datatype 'MessageSecurityMode' */
    UA_String securityGroupId;
    size_t keyServersSize;
    UA_Int32 *keyServers;
} UA_PubSubSecurityParameters;

/* Parameters for PubSub DataSetReader Configuration */
typedef struct {
    UA_String name;
    UA_Variant publisherId;
    UA_UInt16 writerGroupId;
    UA_UInt16 dataSetWriterId;
    UA_DataSetMetaDataType dataSetMetaData;
    UA_DataSetFieldContentMask dataSetFieldContentMask;
    UA_Double messageReceiveTimeout;
    UA_PubSubSecurityParameters securityParameters;
    UA_ExtensionObject messageSettings;
    UA_ExtensionObject transportSettings;
    UA_SubscribedDataSetEnumType subscribedDataSetType;
    /* TODO UA_SubscribedDataSetMirrorDataType subscribedDataSetMirror */
    union {
        UA_TargetVariables subscribedDataSetTarget;
        // UA_SubscribedDataSetMirrorDataType subscribedDataSetMirror;
    } subscribedDataSet;
} UA_DataSetReaderConfig;

/* Update configuration to the dataSetReader */
UA_StatusCode
UA_Server_DataSetReader_updateConfig(UA_Server *server, UA_NodeId dataSetReaderIdentifier,
                                     UA_NodeId readerGroupIdentifier,
                                     const UA_DataSetReaderConfig *config);

/* Get configuration of the dataSetReader */
UA_StatusCode
UA_Server_DataSetReader_getConfig(UA_Server *server, UA_NodeId dataSetReaderIdentifier,
                                  UA_DataSetReaderConfig *config);

/* Get state of DataSetReader */
UA_StatusCode
UA_Server_DataSetReader_getState(UA_Server *server, UA_NodeId dataSetReaderIdentifier,
                               UA_PubSubState *state);

Read group

The reader group is used to group the list of data set readers. All reader groups are created in PubSubConnection. If the connection is deleted, it will be deleted automatically. All network message related filters are only available in DataSetReader.

RT levels are accompanied by different requirements. The levels listed below can be configured for a ReaderGroup. UA_PUBSUB_RT_NONE – no RT is applied to this level of PUBSUB_CONFIG_FASTPATH_FIXED_OFFSETS – extends PubSub's RT capabilities and enables fast path message decoding among subscribers. Buffered network messages are used and only the necessary offsets stored in the offset buffer are decoded.

/* ReaderGroup configuration */
typedef struct {
    UA_String name;
    UA_PubSubSecurityParameters securityParameters;
    /* PubSub Manager Callback */
    UA_PubSub_CallbackLifecycle pubsubManagerCallback;
    /* non std. field */
    UA_PubSubRTLevel rtLevel;
} UA_ReaderGroupConfig;

/* Add DataSetReader to the ReaderGroup */
UA_StatusCode
UA_Server_addDataSetReader(UA_Server *server, UA_NodeId readerGroupIdentifier,
                                      const UA_DataSetReaderConfig *dataSetReaderConfig,
                                      UA_NodeId *readerIdentifier);

/* Remove DataSetReader from ReaderGroup */
UA_StatusCode
UA_Server_removeDataSetReader(UA_Server *server, UA_NodeId readerIdentifier);

/* To Do: Update Configuration of ReaderGroup
 * UA_StatusCode
 * UA_Server_ReaderGroup_updateConfig(UA_Server *server, UA_NodeId readerGroupIdentifier,
 *                                    const UA_ReaderGroupConfig *config);
 */

/* Get configuraiton of ReaderGroup */
UA_StatusCode
UA_Server_ReaderGroup_getConfig(UA_Server *server, UA_NodeId readerGroupIdentifier,
                               UA_ReaderGroupConfig *config);

/* Get state of ReaderGroup */
UA_StatusCode
UA_Server_ReaderGroup_getState(UA_Server *server, UA_NodeId readerGroupIdentifier,
                               UA_PubSubState *state);

/* Add ReaderGroup to the created connection */
UA_StatusCode
UA_Server_addReaderGroup(UA_Server *server, UA_NodeId connectionIdentifier,
                                   const UA_ReaderGroupConfig *readerGroupConfig,
                                   UA_NodeId *readerGroupIdentifier);

/* Remove ReaderGroup from connection */
UA_StatusCode
UA_Server_removeReaderGroup(UA_Server *server, UA_NodeId groupIdentifier);

UA_StatusCode
UA_Server_freezeReaderGroupConfiguration(UA_Server *server, const UA_NodeId readerGroupId);

UA_StatusCode
UA_Server_unfreezeReaderGroupConfiguration(UA_Server *server, const UA_NodeId readerGroupId);

UA_StatusCode
UA_Server_setReaderGroupOperational(UA_Server *server, const UA_NodeId readerGroupId);

UA_StatusCode
UA_Server_setReaderGroupDisabled(UA_Server *server, const UA_NodeId readerGroupId);

#endif /* UA_ENABLE_PUBSUB */

Recent updates

To view recent updates to this article, click

Keywords: IoT ARM MCU

Added by JVassie on Sat, 15 Jan 2022 00:28:20 +0200