DomainParticipants will automatically generate a GUID based on rtps_host_id, rtps_app_id, and rtps_instance_id in the wire protocol QoS settings. Is there any way to access this GUID through the domain participant? We have one domain participant per app, and each app needs a GUID for som app-level logic, so I was hoping to just use the GUID that DDS generates without having to generate my own.
Edit:
On a somewhat related qeustion: How is the instance handle computed for a DomainParticipant. As I mentioned, I have one DomainParticipant per application. Under this, there are multiple publishers/subscribers. I want subscribers to ignore publishers within the same application, so I used
participant->ignore_participant(participant->get_instance_handle())
Which does block communication between local entties, but if I spawn two separate applications (separate domain participants) on the same machine, they ignore each other as well. Why do two separate Domain Participants in separate address spaces and processes have the same isntance handle?
Thanks,
-Neal
Hello Neal,
The GUID is available as part of the DomainParticipantQos.
For a locally-created DomainParticipant you can call
get_qos()
to get the DomainParticipantQos. There you will see an attribute called wire_protocol of type WireProtocolQosPolicy. The combination of the first four attributes:participant_id
,rtps_host_id
,rtps_app_id
, andrtps_instance_id
form the 16-byte GUID.If it is a remote DomainParticipant, then you can find its GUID on the DomainParticipantBuiltinTopicData that is propagated via DDS discovery and accessible via the builtin ParticipantBuiltinTopicDataDataReader. Within that structure, the attribute named
key
contains the 16-byte GUID for the DomainParticipant.Regarding your question on how the InstanceHandle for the DomainParticipant, the InstanceHandle is essentially the GUID. However the formatting is a little bit different and the implementation is opaque meaning an application should not rely on the format. It is just a unique way to refer to a participant that has been discovered...
What you are doing to have subscribers ignore publisher from the same application seems correct to me and it should only ignore the one DomainParticipant not the other ones on the same computer. To be more precice, DomainParticipants will have different values for IntanceHandle. This is true wether the DomainParticipant entities are in different computers, different processes in the same computer, or even different participants created within the same process. I do not understand why it is not working for you... I can try to reproduce it in a simple example... What platform are you running on?
Gerardo
I am still somwhat struggeling to understand the interconnection between a participant GUID, an instance handel, and a topic key with the main problem being how they are interdependent and when which should be used.
Some facts I collected so far on the related (C++) types:
From what I gathered so far, those three things (GUID, instance handle, and the topic key) are more or less the same thing when related to a participant. This assumption is mainly based upon this post by Gerardo where lists the locations where the GUID of a remote participant appears:
key
attributeparticipant_key
attribute.participant_key
attribute.All the referenced attributes, however, are topic keys and in his post Gerardo uses a type cast from an instance handle to a GUID, essentially implying that all those 128bit constructs (topic key, instance handel, GUID) are more or less the same.
A problem arises as to determining the GUID of the local participant.
This post most likely presents the quickest way, calling
get_instance_handle()
on the local participant. Where it gets a little confusing is this post where the internal structure of a participant GUID is explained: according to the post a GUID is actually only a 64 bit value and is comprised ofc0c80aa3
translates to IP address 192.200.10.163. This will allow you to determine the node having the GUID problem.GetCurrentProcessId()
.ps -ef
.This structure seems to be in line with Gerardo's explenations above, where the GUID is related to the WireProtocolQosPolicy. However, there is some room for ambiguity as the Wire Protocol only seems to control 96 bits of the 128 bit GUID (compare §8.5.9.4 in the RTI User Manual, "Controlling How the GUID is Set (rtps_auto_id_kind)"). Gerarodo seems to say that the
participant_id
is used to fill the missing 32bits, however on my machine the last 32 bits always end up being 0x1C1, which is neither nor.The debug code above created the following output:
Besides the obivous solution of simply using
get_instance_handle()
and not messing with the participant GUID's building blocks, could somebody shed some light on those last 32bits?On re-reading my previous post I realized that my actual question got totally lost in the details. So here another attempt at paraphrasing it:
Task
The task is to find a way to use DDS built in methods to uniquly identify participants in the user code. The goal is to enable participant user code to realize who they are, and whom they are talking to.
All involveld, however, need to use the same GUIDs so that when participant A and B "talk" about participant C, they both mean the same participant.
Accessing GUID data of other participants
Getting access to GUIDs of other participants is easily accomplished via getting the respective GUID data during discovery from
key
attributeparticipant_key
attribute.participant_key
attribute.During regular data messaging, this data is recoverable via
Accessing GUID data of the local participant
Getting the GUID of the local participant appears to be the simplest when using
participant->get_instance_handle()
. , especially when considering the alternatives of rebuliding the GUID from the underlying sources (see the section with the Wire QoS in my post above).The Problem
How can I savely compare the local participants GUID data, which is of type DDS_InstanceHandle_t, to the GUID data of the other participants, which are given as a DDS_BuiltinTopicKey_t.
What is a safe way to check thos two for equality? Do I need to be conserned about endianess issues when comparing the (potentially not intended to be public) underlying "raw" 128 bit of data?
Hello Neal,
Thank you for the follow-up clarification. It helps a lot to understand what you are trying to do...
To answer your question: The BuiltinTopicKey_t and the InstanceHandle_t contain the same information about the DDS_GUID_t, but as you stated they represent it differently. The BuiltinTopicKey_t represents GUID_t information as 4 integers. On the other hand the InstanceHandle_t represents it using a 16-byte array. As you suspected, the fact that they are different representations (one as 4 integers, and the other as 16 bytes) means that endianess issues do get it the way and you cannot compare them directly. See below for one proper way to compare.
For clarity lets use the DDS_GUID_t as the normalized representation, so DDS_GUID_t comparison can be done with the function DDS_GUID_equals().
These two utility functions DDS_InstanceHandle_to_GUID and DDS_BuiltinTopicKey_to_GUID shown below perform conversions from InstanceHandle_t and BuiltinTopicKey_t to GUID_t. Note that I have not tested them do I am not 100% sure I got them right, but you can see the idea here of what needs to be done.
Gerardo
Hi Gerardo
Thank you for this tremendeoulsy helpful post, I appreciate the effort of providing sample code.
And here some related operators to make working with DDS_GUID_t a little easier: