Accessing the GUID of Connext DDS Entities

 

What is a GUID?

In a RTI Connext DDS deployment, every entity --local or remote-- can be univocally identified by means of its GUID, which is an acronym that stands for Global Unique IDentifier. Such 
identification can be used by applications to ignore certain entities, identify who published a certain sample, or detect which entity has changed its state.
 
In RTI Connext, the GUID is implemented as a 128 bits value (16 octets) and it can be accessed in different ways.

Accessing the GUID of local RTI Connext entities

An InstanceHandle is a 128 bit value used by RTI Connext to identify different instances. In RTI Connext a DDS_instanceHandle_t is equivalent to a DDS_GUID_t type, as both consist
 of 16 octets.

The DDS_Entity::get_instance_handle() method can be used to access the DDS_InstanceHandle_t of an RTI Connext entity. For instance:

In C:
DDS_InstanceHandle_t handle = DDS_HANDLE_NIL; 

handle =DDS_Entity_get_instance_handle((DDS_Entity *) participant ); 
or in C++:
DDS_InstanceHandle_t handle; 

/* Create participant and publications */ 
...

handle = participant->get_instance_handle(); 
 
Once we have the instance handle of an entity, it can be converted easily to a  DDS_GUID_t using the following code:
memcpy(guid->value, (DDS_Octet *)instanceHandle->keyHash->value, 16);  

Accessing the GUID of remote RTI Connext entities:

In RTI Connnext it is also possible to access to the GUID of remote entities using two different methods:

Equivalence GUID, InstanceHandle and BuiltinTopicKey

The DDS_BuiltinTopicKey_t contains the same information as the  DDS_GUID_t type, but using a different representation: while in the case of  DDS_BuiltinTopicKey_t the key is stored as four 32bit integers, in the case of  DDS_GUID_t it consist on an array of 16 octets. Hence, if we have the key of the remote entity, it is pretty straightforward to translate from one to another. The only thing that has to be taken into account is the endianness of the machine to swap the bytes if necessary, as we do in the following code:

#include <endian.h>

...

void DDS_BuiltinTopicKey_to_GUID(struct DDS_GUID_t *guid /* out */ , DDS_BuiltinTopicKey_t *buitinTopicKey /* in */ ) { 

#if __BYTE_ORDER == __LITTLE_ENDIAN /* Little Endian */ 
int i; 
DDS_Octet *guidElement; 
DDS_Octet *topicKeyBuffer = (DDS_Octet *)buitinTopicKey; 
DDS_Octet *keyBufferElement; 

for ( i=0; i< 4; ++i ) { 
   DDS_Octet *guidElement = &guid->value[i*4];
   DDS_Octet *keyBufferElement = (DDS_Octet *)(&buitinTopicKey->value[i]); 
   guidElement[0] = keyBufferElement[3]; 
   guidElement[1] = keyBufferElement[2]; 
   guidElement[2] = keyBufferElement[1]; 
   guidElement[3] = keyBufferElement[0]; 
} 
#else /* Big Endian */ 
   memcpy(guid->value, (DDS_Octet *)buitinTopicKey->value, 16); 
#endif 

}

 

Setting the GUID manually:

Althought RTI Connext usually assigns automatically the DDS_GUID_t to DDS entities, it is possible to set manually the GUID prefix used by a DDS Domain Participant and the contained entities. It can be established before enabling the DDS DomainParticipant using the QoS policy WireProtocolQosPolicy. This policy contains three members ( rtps_host_idrtps_app_id and rtps_instance_id) that define the GUID prefix shared by all the entities created within such DDS DomainParticipant.