QoS Provider

This page provides information on using the QoS provider API of Eclipse Cyclone DDS. The QoS provider API allows users to specify the QoS settings of their DDS entities outside of application code in XML. This can be seen as a useful feature where code recompilation is restricted during the later stages of application development / during application support. The following sections explain the API and explain how to build QoS Profiles in XML.

XML file syntax

The syntax for the XML configuration file is defined in DDS Consolidated XML Syntax.

Entity QoS

To configure the QoS for a DDS Entity using XML, the following tags have to be used:

  • <domainparticipant_qos>

  • <publisher_qos>

  • <subscriber_qos>

  • <topic_qos>

  • <datawriter_qos>

  • <datareader_qos>

Each XML tag with or without an associated name can be uniquely identified by its fully qualified name in C++ style. In case of unnamed XML tag, only one tag of this kind is allowed in scope of parent <qos_profile>.

QoS Policies

The fields in a Qos policy are described in XML using a 1-to-1 mapping with the equivalent IDL representation in the DDS specification. For example, the Reliability Qos policy is represented with the following structures:

struct Duration_t {
  long sec;
  unsigned long nanosec;
};
struct ReliabilityQosPolicy {
  ReliabilityQosPolicyKind kind;
  Duration_t max_blocking_time;
};

The equivalent representation in XML is as follows:

<reliability>
  <kind></kind>
  <max_blocking_time>
    <sec></sec>
    <nanosec></nanosec>
  </max_blocking_time>
</reliability>

Sequences

In general, the sequences contained in the QoS policies are described with the following XML format:

<a_sequence_member_name>
  <element>...</element>
  <element>...</element>
  ...
</a_sequence_member_name>

Each element of the sequence is enclosed in an <element> tag, as shown in the following example:

<property>
  <value>
    <element>
      <name>my name</name>
      <value>my value</value>
    </element>
    <element>
      <name>my name2</name>
      <value>my value2</value>
    </element>
  </value>
</property>

Enumerations

Enumeration values are represented using their IDL string representation. For example:

<history>
  <kind>KEEP_ALL_HISTORY_QOS</kind>
</history>

Time values (Durations)

Following values can be used for fields that require seconds or nanoseconds:

  • DURATION_INFINITE_SEC

  • DURATION_INFINITE_NSEC

The following example shows the use of time values:

<deadline>
  <period>
    <sec>DURATION_INFINITE_SEC</sec>
    <nanosec>DURATION_INFINITE_NSEC</nanosec>
  </period>
</deadline>

QoS Profiles

A QoS profile groups a set of related QoS, usually one per entity. For example:

<qos_profile name="StrictReliableCommunicationProfile">
  <datareader_qos>
    <history>
      <kind>KEEP_LAST_HISTORY_QOS</kind>
      <depth>5</depth>
    </history>
  </datareader_qos>
  <datawriter_qos>
   <history>
      <kind>KEEP_LAST_HISTORY_QOS</kind>
      <depth>1</depth>
    </history>
  </datawriter_qos>
</qos_profile>

XML Example

Consider the following XML file that describes two QoS profiles:

  • FooQosProfile
    • DataReaderQos - KEEP_LAST (5)

    • DataWriterQos - KEEP_LAST (1)

    • TopicQos - KEEP_ALL

  • BarQosProfile
    • DataWriterQos - KEEP_ALL

    • TopicQos - KEEP_LAST (5)

<dds xmlns="http://www.omg.org/dds/"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="file://DDS_QoSProfile.xsd">
  <qos_library name="myqoslib">
    <qos_profile name="foo_profile">
      <datareader_qos>
        <history>
          <kind>KEEP_LAST_HISTORY_QOS</kind>
          <depth>5</depth>
        </history>
      </datareader_qos>
      <datawriter_qos>
       <history>
          <kind>KEEP_LAST_HISTORY_QOS</kind>
          <depth>1</depth>
        </history>
      </datawriter_qos>
      <topic_qos name="my_topic">
        <history>
          <kind>KEEP_ALL_HISTORY_QOS</kind>
        </history>
      </topic_qos>
    </qos_profile>
    <qos_profile name="bar_profile">
      <datawriter_qos>
        <history>
          <kind>KEEP_ALL_HISTORY_QOS</kind>
        </history>
      </datawriter_qos>
        <topic_qos name="my_topic">
          <history>
            <kind>KEEP_LAST_HISTORY_QOS</kind>
            <depth>10</depth>
          </history>
        </topic_qos>
    </qos_profile>
  </qos_library>
</dds>

Code Example

The following C application is an example to illustrate how the QoS settings from the above XML could be accessed.

#include "dds/dds.h"
#include "dds/ddsc/dds_qos_provider.h"
#include "datatypes.h"

int main (int argc, char **argv)
{
  (void) argc;
  (void) argv;

  // provider will contains:
  // myqoslib::foo_profile                     READER (KEEP_LAST 5)
  // myqoslib::foo_profile                     WRITER (KEEP_LAST 1)
  // myqoslib::foo_profile::my_topic           TOPIC  (KEEP_ALL)
  // myqoslib::bar_profile                     WRITER (KEEP_ALL)
  // myqoslib::bar_profile::my_topic           TOPIC  (KEEP_LAST 10)
  dds_qos_provider_t *provider;
  dds_return_t ret = dds_create_qos_provider ("/path/to/qos_definitions.xml", &provider);
  assert (ret == DDS_RETCODE_OK);

  const dds_qos_t *tp_qos, *wr_qos;
  // qos can be accessed by <lib_name>::<profile_name>::[entity_name] if exist.
  ret = dds_qos_provider_get_qos (provider, DDS_TOPIC_QOS, "myqoslib::bar_profile::my_topic", &tp_qos);
  assert (ret == DDS_RETCODE_OK);
  // or if entity_qos is unnamed only by <lib_name>::<profile_name>.
  ret = dds_qos_provider_get_qos (provider, DDS_WRITER_QOS, "myqoslib::bar_profile", &wr_qos);
  assert (ret == DDS_RETCODE_OK);

  dds_entity_t pp = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL);
  dds_entity_t tp = dds_create_topic (pp, &mydatatype_desc, "topic_A", tp_qos, NULL);
  dds_entity_t wr = dds_create_writer (pp, tp, wr_qos, NULL);
  dds_delete (pp);
  dds_delete_qos_provider (provider);

  return 0;
}

Also C API allows you to specify which library, profile QoS Provider should contains. Let’s extend XML file example above, and omit QoS settings details for simplicity.

<dds xmlns="http://www.omg.org/dds/"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="file://DDS_QoSProfile.xsd">
  <qos_library name="qos1_lib">
    <qos_profile name="foo_profile">
      <datareader_qos/>
      <datawriter_qos/>
      <topic_qos/>
    </qos_profile>
    <qos_profile name="bar_profile">
      <datawriter_qos/>
      <topic_qos/>
    </qos_profile>
  </qos_library>
  <qos_library name="qos2_lib">
    <qos_profile name="foo_profile">
      <datareader_qos/>
      <datawriter_qos/>
      <topic_qos/>
    </qos_profile>
    <qos_profile name="bar_profile">
      <datawriter_qos/>
      <topic_qos/>
    </qos_profile>
  </qos_library>
</dds>

Let’s create QoS Provider that contains versions of both profiles from different libraries.

#include "dds/dds.h"
#include "dds/ddsc/dds_qos_provider.h"
#include "datatypes.h"

int main (int argc, char **argv)
{
  (void) argc;
  (void) argv;

  // foo_provider will contains:
  // qos1_lib::foo_profile                     READER
  // qos1_lib::foo_profile                     WRITER
  // qos1_lib::foo_profile                     TOPIC
  // qos2_lib::foo_profile                     READER
  // qos2_lib::foo_profile                     WRITER
  // qos2_lib::foo_profile                     TOPIC
  dds_qos_provider_t *foo_provider;
  char *foo_scope = "*::foo_profile";
  dds_return_t ret = dds_create_qos_provider_scope ("/path/to/qos_definitions.xml", &foo_provider, foo_scope);
  assert (ret == DDS_RETCODE_OK);

  // bar_provider will contains:
  // qos1_lib::bar_profile                     WRITER
  // qos1_lib::bar_profile                     TOPIC
  // qos2_lib::bar_profile                     WRITER
  // qos2_lib::bar_profile                     TOPIC
  dds_qos_provider_t *bar_provider;
  char *bar_scope = "*::bar_profile";
  dds_return_t ret = dds_create_qos_provider_scope ("/path/to/qos_definitions.xml", &bar_provider, bar_scope);
  assert (ret == DDS_RETCODE_OK);
  ...
  dds_delete_qos_provider (foo_provider);
  dds_delete_qos_provider (bar_provider);

  return 0;
}

Known limitations

  • Inheritance of QoS policies and QoS profiles in XML using the “base_name” attribute is not supported

  • The “topic_filter” attribute for writer, reader and topic QoSes to associate a set of topics to a specific QoS when that QoS is part of a DDS profile, is not supported yet.

  • The “entity_factory” attribute for participant, writer and reader QoSes, is not supported yet.

  • The <(user|topic|group)_data> base64 syntax is not supported yet.

  • The C++ API QosProvider may throw an UnsupportedError when trying to access a policy that is not supported yet.