How to uniquely identify a coherent set

Note: This article discusses the coherent_set_info field, which is only available in Connext Professional 6.1.0 and higher.

The information about the coherent set that a sample belongs to is stored in the optional field coherent_set_info, which is part of the SampleInfo structure. This optional field is only set if the sample belongs to a coherent set.

This article explains how to correlate the coherent_set_info, accessed at the API level, with the information transmitted on the wire, in order to uniquely identify (both in code and by looking at a Wireshark capture) the coherent set that a sample belongs to. This information is useful when the way to process a sample depends on the coherent set it belongs to, or when the coherent set has a semantic meaning at the application level.

1. Coherent Set Group GUID

 

The Coherent Set Group GUID identifies the group of DataWriters publishing the coherent set. It is stored in the group_guid field of coherent_set_info (see “The SampleInfo Structure” in the Core Libraries User’s Manual).

The value of the Group GUID depends on the kind of access_scope set in the Subscriber’s Presentation QoS policy (PresentationQosPolicyAccessScopeKind):

  • If access_scope is INSTANCE or TOPIC, the Group GUID will be the same as the DataWriter’s GUID, since the group of DataWriters only spans across a single DataWriter. In this case, the Group GUID is transmitted on the wire by means of the properties guidPrefix and writerEntityId in the DATA packets, and we can get the Group GUID by concatenating them:

Wireshark capture showing how to obtain the Group GUID when access_scope is INSTANCE or TOPIC

           In this example, we would concatenate:
           0101421106c47ec2c449593b ( guidPrefix) with
           80000002 ( writerEntityId),
           which gives us the Group GUID 0101421106c47ec2c449593b80000002.

  • If the access_scope is GROUP, the Group GUID identifies all the DataWriters of the group within the same Publisher. This Group GUID is propagated along with the DATA packet on the wire, by means of inlineQos.PID_ORIGINAL_WRITER_INFO’s guidPrefix with virtualGUIDSuffix, and we can get the Group GUID by concatenating them:

Wireshark capture showing how to obtain the GUID when access_scope is set to GROUP

           In this example, we would concatenate:
           2b51640e47f46f9bbccfb9ae ( inlineQos.PID_ORIGINAL_WRITER_INFO.guidPrefix) with
           387109ab ( inlineQos.PID_ORIGINAL_WRITER_INFO.virtualGUIDSuffix),
           which gives us the Group GUID: 2b51640e47f46f9bbccfb9ae387109ab.

2. Coherent Set Sequence Number

Every coherent set is assigned a Sequence Number (SN) within the DataWriter (if access_scope is INSTANCE or TOPIC) or within a group of DataWriters (if access_scope is  GROUP). 

The access_scope determines which field from the coherent_set_info struct we will use to get the Coherent Set SN of a given sample. (See “The SampleInfo Structure” section of the Core Libraries User’s Manual for more details):
  • If access_scope is INSTANCE or TOPIC, use coherent_set_sequence_number. This information is propagated within the DATA packet in PID_COHERENT_SET.sequenceNumber:

Wireshark capture showing how to obtain the Coherent Set SN when access_scope is set to INSTANCE or TOPIC
  • If access_scope is GROUP, use group_coherent_set_sequence_number.
    This information is propagated within the DATA packet in the  PID_GROUP_COHERENT_SET.Group coherent set sequence number:

Wireshark capture showing how to obtain the Coherent Set SN when access_scope is set to GROUP

3. Summary table

The following table summarizes the different properties to consult depending on the case:

Summary Table
 access_scope (PresentationQosPolicyAccessScopeKind)
 INSTANCE/TOPICGROUP
Coherent
set ID

sample_info.coherent_set_info.group_guid

+

sample_info.coherent_set_info.
coherent_set_sequence_number

sample_info.coherent_set_info.group_guid

+

sample_info.coherent_set_info.
group_coherent_set_sequence_number

4. Example code snippet

The following code snippet shows an example callback where the coherent set of each retrieved sample is found and printed, using the Connext Professional C++11 API:
 
void process_data(dds::sub::Subscriber subscriber)
{
    {
    CoherentAccess coherent_access(subscriber);  // Begin coherent access
    std::vector<AnyDataReader> readers;
    // Get the list of readers with samples that have not been read yet
    find(subscriber,
        dds::sub::status::SampleState::not_read(),
        std::back_inserter(readers));
    // Iterate through the returned readers list and take their samples
    for (AnyDataReader reader : readers)
    {
        dds::sub::LoanedSamples<coherent> samples =
                  reader.get<coherent>().take();
        for (const auto &sample : samples)
        {
            std::cout << sample << std::endl;
            if (sample.info().valid())
            {
                if (sample.info().extensions().coherent_set_info().has_value())
                {
                     const rti::core::CoherentSetInfo &set_info =
                            *sample.info().extensions().coherent_set_info();
                     std::cout << "Sample is part of the coherent set with (GGUID, SN): ("
                               << set_info.group_guid() << ", "
                               << set_info.group_coherent_set_sequence_number() << ");\n"
                               << std::endl;
                }
            }
        }
    }
}
Note: Support for Coherent Access with Group Presentation QoS in the Wireshark dissector is available in Wireshark 3.6.0 and higher.
 
Programming Language: