How to uniquely identify a coherent set
Note: This article discusses the
coherent_set_infofield, 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 - guidPrefixand- writerEntityIdin the DATA packets, and we can get the Group GUID by concatenating them:

           In this example, we would concatenate: 
           0101421106c47ec2c449593b ( guidPrefix) with 
           80000002 ( writerEntityId),
           which gives us the Group GUID 0101421106c47ec2c449593b80000002.
- If the - access_scopeis 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- guidPrefixwith- virtualGUIDSuffix, and we can get the Group GUID by concatenating them:

           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). 
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_scopeis INSTANCE or TOPIC, use- coherent_set_sequence_number. This information is propagated within the DATA packet in- PID_COHERENT_SET.sequenceNumber:

- If - access_scopeis 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:

3. Summary table
The following table summarizes the different properties to consult depending on the case:
| access_scope (PresentationQosPolicyAccessScopeKind) | ||
| INSTANCE/TOPIC | GROUP | |
| 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
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.
