Why is my VxWorks application unable to discover other RTI Connext applications after a restart?

Note: Applies to RTI Connext 4.x and above

For dynamic discovery to work properly, RTI Connext relies on a globally unique identifier (GUID) that uniquely identifies each instance of a participant in the network. By default, RTI Connext will automatically choose values for the host ID and app ID that will generate unique GUIDs for different participant instances. This is documented in the wire_protocol Qos Policy (section DomainParticipantQoS). 

Currently, RTI Connext bases the host ID on the IPv4 address of the host (although this might change in the future). The app ID is calculated from the process (or task) ID and a counter that is incremented per new participant created in the process. 

Note that the app ID is not based upon the participant index. When restarting an application with the same participant index, the application should announce itself as a new participant (with a different GUID) on the network, so other participants can respond with their configuration info. Therefore, RTI Connext will assign it a different app ID, even if the participant uses the same participant index (and ports). After all, it is a different instance of this participant. If the app ID were unchanged, remote participants would simply interpret the announcement as an "I am still alive" message and not reply with their own information. 

On many real-time operating systems, and even on some non-real-time operating systems, when a node is rebooted and applications are automatically started, process IDs are deterministically assigned. That is, when the system restarts or if an application dies and is restarted, the application will be reassigned the same process or task ID. If this occurs before other applications in the system can detect that the previous application has died, the new application will appear to be the same as the previous application due to their identical GUIDs. 

In such cases, to prevent duplicate GUIDs, you can set the host ID and/or app ID manually using the  wire_protocol Qos Policy before creating the participant. 

In the publisher main:

struct DDS_DomainParticipantQos participant_qos;
...
// Initialize participant_qos with default values
DDS_DomainParticipantFactory_get_default_participant_qos(
        DDS_TheParticipantFactory, 
	&participant_qos);

// set the rtps host and/or app id.
participant_qos.wire_protocol.rtps_host_id = aRandomOrIncrementingValue;
participant_qos.wire_protocol.rtps_app_id = aRandomOrIncrementingValue;

// Create participant using modified DDS_DomainParticipantQos
participant = DDS_DomainParticipantFactory_create_participant(
      DDS_TheParticipantFactory, domainId, &participant_qos,
      NULL /* listener */, DDS_STATUS_MASK_NONE);

When the application is restarted, RTI Connext assigns it a different host and app ID—in which case the GUID becomes unique and other applications will recognize this as a new instance of an application and will exchange discovery information.

Displaying the GUID

One can observe the GUID using RTI Protocol Analyzer with Wireshark or by turning on high verbosity output level for both the subscriber and publisher.

Set the NDDS_Config_LogCategory to  NDDS_CONFIG_LOG_CATEGORY_ENTITIES to log messages pertaining to local and remote entities and to the discovery process.

NDDS_Config_Logger_set_verbosity_by_category(NDDS_Config_Logger_get_instance(), 
                                             NDDS_CONFIG_LOG_CATEGORY_ENTITIES, 
                                             NDDS_CONFIG_LOG_VERBOSITY_STATUS_ALL); 

Look for the following line in output from both subscriber and publisher applications:

DISCDynamicParticipantSelfAnnouncer_enable:announcing participant: 0x7F000001,0x00100001,0x000001C1 

The GUID is composed of three parts:

  1. host ID: identifies the host on which the participant is running.
  2. app ID: uniquely identifies a particular instance of a participant on this host.
  3. object ID: has a fixed value in the case of a participant. Will be used to uniquely identify entities (pubs, subs) that belong to the participant.
Platform:
Keywords:

Comments

I am using RTI 5.0 and participant_qos.wire_protocol.rtps_host_id = aRandomOrIncrementingValue;
is returning a error. I cannot locate managed_infrastructure.h withing my build environment.
therefore aRandomOrIncrementingValue in undefined.

Has this value changed or where is the header?

Hi,

aRandomOrIncrementingValue is just a label that represents any random or incrementing value. It's not a constant defined in RTI header files. Your code needs to generate the value you want to assign to your host_id.

 

Hi,

I'm a bit confused by the above article. According to the connext 5.0 API doc it seems there are three 32-bit fields of interest that could be set by the user with respect to the rtps wire protocol GUID. These fields are

  •  rtps_host_id 
  •  rtps_app_id
  • rtps_instance_id  

Let's say, for example, I wish to use a custom 64 bit GUID for identifying my embedded system. For simplicity, let's assume this system runs a single application that hosts a single domain participant. Now, If I split the GUID into the rtps_host_id  and rtps_app_id fields (e.g. by most significant vs. least significant bits), I can recover the guid from the instance handle that is returned by various API calls in a remote application running on another entity. This would allow me, for instance, to determine who just violated a liveliness contract within my domain. In the event of a reboot, wouldn't it be sufficient to change only the rtps_instance_id using 'aRandomIncrementingValue' ? The API doc says the same thing for both rtps_app_id and rtps_instance_id:

"If a participant dies and is restarted, it is recommended that it be given an app ID that is distinct from the previous one so that other participants in the domain can distinguish between them."

Thanks