15.15. Remote type discovery and endpoint matching

This section explains how to create an endpoint using a remotely discovered data type that was previously unknown to the local participant.

15.15.1. Prerequisites

This use case focuses on the strategy to follow in order to create an endpoint at runtime in a previously unknown topic using the information provided by the remote endpoint discovery information. Therefore, the prerequisites are:

  • Two participants, A and B, running in different process (type information is shared within the same DomainParticipantFactory).

  • Participant A must not know the data type registered in participant B.

  • Participant B data type must be registered using the code generated by eProsima Fast DDS-Gen without disabling the TypeObjectSupport code generation.

  • Participant B must create an endpoint using the data type unknown by participant A.

  • Participant A must be attached to a DomainParticipantListener.

15.15.2. Remote type discovery

Following the participant discovery phase, the endpoint information is exchanged. The appropriate on_data_reader_discovery() or on_data_writer_discovery() callback is called, depending on the kind of endpoint created on the remote participant. The endpoint discovery callback provides access to the remotely discovered information including the TypeInformation.

Provided the TypeInformation, ITypeObjectRegistry singleton can be queried for the corresponding TypeObject representation calling ITypeObjectRegistry::get_type_object API.

15.15.3. Register remote type

DynamicTypeBuilderFactory provides a specific API that given a TypeObject representation returns the corresponding DynamicTypeBuilder: DynamicTypeBuilderFactory::create_type_w_type_object. The DynamicType can then be obtained and registered using DynamicPubSubType.

15.15.4. Create local endpoint

Once the remote type has been locally registered, a Topic can be created within the DomainParticipant and endpoints using this Topic might be also created.

Note

Endpoint matching takes into consideration QoS consistency. Consequently, for the local endpoint to match, the remote QoS has to be taken into account. The remote endpoint discovery information provided by the discovery callback includes also this data.

15.15.5. Example

The following snippet shows the previously explained steps:

class RemoteDiscoveryDomainParticipantListener : public DomainParticipantListener
{
    /* Custom Callback on_data_reader_discovery */
    void on_data_reader_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::ReaderDiscoveryStatus reason,
            const eprosima::fastdds::rtps::SubscriptionBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        // Get remote type information
        xtypes::TypeObject remote_type_object;
        if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
                    info.type_information.type_information.complete().typeid_with_size().type_id(),
                    remote_type_object))
        {
            // Error
            return;
        }
        // Register remotely discovered type
        DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
            remote_type_object)->build();
        TypeSupport dyn_type_support(new DynamicPubSubType(remote_type));
        dyn_type_support.register_type(participant);

        // Create a Topic with the remotely discovered type.
        Topic* topic =
                participant->create_topic(info.topic_name.to_string(), dyn_type_support.get_type_name(),
                        TOPIC_QOS_DEFAULT);
        if (nullptr == topic)
        {
            // Error
            return;
        }

        // Create endpoint
        Publisher* publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
        if (nullptr == publisher)
        {
            // Error
            return;
        }

        DataWriter* data_writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
        if (nullptr == data_writer)
        {
            // Error
            return;
        }
    }

    /* Custom Callback on_data_writer_discovery */
    void on_data_writer_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::WriterDiscoveryStatus reason,
            const eprosima::fastdds::dds::PublicationBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        // Get remote type information
        xtypes::TypeObject remote_type_object;
        if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
                    info.type_information.type_information.complete().typeid_with_size().type_id(),
                    remote_type_object))
        {
            // Error
            return;
        }
        // Register remotely discovered type
        DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
            remote_type_object)->build();
        TypeSupport dyn_type_support(new DynamicPubSubType(remote_type));
        dyn_type_support.register_type(participant);

        // Create a Topic with the remotely discovered type.
        Topic* topic =
                participant->create_topic(info.topic_name.to_string(), dyn_type_support.get_type_name(),
                        TOPIC_QOS_DEFAULT);
        if (nullptr == topic)
        {
            // Error
            return;
        }

        // Create endpoint
        Subscriber* subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
        if (nullptr == subscriber)
        {
            // Error
            return;
        }

        // The QoS depends on the remote endpoint QoS. For simplicity, default QoS have been assumed.
        DataReader* data_reader = subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
        if (nullptr == data_reader)
        {
            // Error
            return;
        }
    }

};