RTPS APIs

The rtps component is a cross-platform foundation for building RTPS (Real-Time Publish-Subscribe) functionality on top of the ESPP socket component.

This version now implements the first RTPS discovery layer on top of the ESPP socket component:

  • RTPS header and DATA submessage framing helpers

  • standard RTPS UDPv4 port calculations

  • GUID, entity ID, locator, and sequence number utility types

  • SPDP participant announcements using PL_CDR parameter lists

  • SEDP publication and subscription announcements for local endpoints

  • parsing and tracking of discovered remote participants, writers, and readers

  • integration with the shared cdr component for CDR/PL_CDR payload handling

  • a participant transport layer that uses UdpSocket for metatraffic and user-traffic channels

  • optional best-effort user-data multicast transport, including endpoint-specific groups

The long-term target is interoperability with ROS 2 nodes over DDS/RTPS, including best-effort and reliable data flows. Discovery messages are now standards-shaped, but full wire-compatible ROS 2 interop still needs the remaining endpoint metadata, matching rules, and reliable RTPS state machines.

Expected Compatibility

The table below is deliberately conservative: expected means this is the intended compatibility envelope of the current code, not a claim that every peer implementation has already been validated in practice.

Peer implementation

Expected compatibility

Notes

ESPP rtps component / python/rtps_host.py

Yes for the current scaffold

Intended smoke-test path for SPDP, SEDP, and the temporary UInt32 ESPPDATA user-data payload.

Generic DDSI-RTPS 2.3 implementations

Partial

SPDP and SEDP messages are standards-shaped, but only the discovery slice is implemented today.

ROS 2 nodes backed by Fast DDS

Partial / discovery-targeted

The current discovery messages include ROS 2-relevant participant user data such as enclave=...;, but standards-based ROS 2 topic data exchange is not finished yet.

ROS 2 nodes backed by Cyclone DDS or other DDS vendors

Partial / unverified

Expected to be limited to the minimal discovery subset if the peer accepts the currently emitted parameter set; not validated yet.

Reliable DDS/RTPS endpoints

No

HEARTBEAT, ACKNACK, retransmission windows, and other reliable state-machine pieces are not implemented.

How RTPS Works

RTPS separates metatraffic from user traffic.

  • Metatraffic carries discovery and endpoint metadata. In this component, that means SPDP participant announcements plus SEDP publication and subscription announcements.

  • User traffic carries application samples. The current ESPP scaffold has a temporary best-effort UInt32 user-data path while the standards-based ROS 2 data plane is still being completed.

The current RtpsParticipant implementation opens three UDP sockets when start() is called:

  1. metatraffic multicast receive on the well-known SPDP multicast port

  2. metatraffic unicast receive on the participant-specific discovery port

  3. user unicast receive on the participant-specific user-data port

It then starts a periodic announce task which multicasts SPDP and unicasts SEDP endpoint announcements to each discovered peer.

        flowchart LR
  App["Application code"] --> Participant["RtpsParticipant"]
  Participant --> SPDP["SPDP participant DATA"]
  Participant --> SEDP["SEDP publication/subscription DATA"]
  Participant --> User["User DATA submessages"]
  SPDP --> MetaMC["Metatraffic multicast"]
  SEDP --> MetaUC["Metatraffic unicast"]
  User --> UserUC["User unicast"]
  MetaMC --> Peer["Remote participant"]
  MetaUC --> Peer
  UserUC --> Peer
    

Discovery Flow

At a high level, discovery proceeds like this:

        sequenceDiagram
  participant A as Local participant
  participant MC as 239.255.0.1
  participant B as Remote participant
  A->>MC: SPDP DATA(participant GUID, locators, enclave, builtin endpoints)
  MC-->>B: multicast delivery
  B->>MC: SPDP DATA(its participant metadata)
  MC-->>A: multicast delivery
  A->>B: SEDP publication DATA(topic/type/reliability)
  A->>B: SEDP subscription DATA(topic/type/reliability)
  B->>A: SEDP publication/subscription DATA
  Note over A,B: Matching user-data traffic can then use the user-unicast ports
    

When handle_metatraffic_message() receives SPDP, it parses:

  • the remote participant GUID

  • participant name

  • the enclave=...; entry carried in PID_USER_DATA

  • built-in endpoint bitmasks

  • metatraffic and user-data locators

For SEDP it parses the endpoint GUID, topic name, type name, reliability, inline-QoS expectation, and unicast locator, then updates the discovered reader or writer cache.

Ports and Channels

The component follows the standard UDPv4 RTPS port mapping formula:

Channel

Formula

Domain 0, participant 0

Metatraffic multicast

7400 + 250 * domain + 0

7400

Metatraffic unicast

7400 + 250 * domain + 10 + 2 * participant

7410

User multicast

7400 + 250 * domain + 1

7401

User unicast

7400 + 250 * domain + 11 + 2 * participant

7411

Current ESPP Scope

The current implementation is intentionally focused on the first interoperability milestone:

  • RTPS message framing and parsing

  • SPDP participant discovery

  • SEDP publication and subscription discovery

  • participant / endpoint caches and discovery callbacks

  • simple CDR little-endian serialization helpers for std_msgs/msg/UInt32

The following pieces are not finished yet:

  • reliable RTPS state machines such as HEARTBEAT and ACKNACK

  • standards-based ROS 2 user-data writers/readers

  • full QoS matching beyond the currently emitted discovery parameters

Feature Status

Feature

Status

Notes

RTPS header / DATA submessage serialize + parse

Implemented

Core message framing is present.

Standard UDPv4 RTPS port mapping

Implemented

Uses the DDSI-RTPS well-known port formula.

SPDP participant announce send/receive

Implemented

Multicast announce plus participant cache updates.

SEDP publication / subscription announce send/receive

Implemented

Local endpoints are announced and remote endpoints are cached.

Participant / endpoint discovery callbacks

Implemented

Exposed through on_participant_discovered and on_endpoint_discovered.

Temporary UInt32 user-data path

Implemented

Uses the current ESPP-specific ESPPDATA payload, not a standards-based DDS sample representation.

Best-effort user-data multicast transport

Implemented

Supports shared participant-level multicast or endpoint-specific multicast locators advertised in SEDP; local readers only join the multicast groups configured for their topics.

QoS fields emitted in discovery

Partial

Reliability, durability, liveliness, and history parameters are advertised in SEDP.

QoS matching / policy enforcement

Not implemented

Remote QoS is parsed, but full writer/reader matching logic is still missing.

Standards-based DDS user-data serialization

Not implemented

The current data path is a temporary ESPP scaffold for std_msgs/msg/UInt32.

Inline QoS handling

Not implemented

Discovery and user-data handling assume no inline QoS.

Reliable RTPS (HEARTBEAT, ACKNACK, resend)

Not implemented

Reliable delivery is not interoperable yet.

Full ROS 2 topic interoperability

Not implemented

Discovery is the current milestone; ROS 2-compatible data writers/readers are still pending.

Relevant Specifications

These are the primary standards and references for understanding the current implementation and the remaining work:

Specification

Why it matters here

OMG DDSI-RTPS 2.3

Primary wire-level reference for RTPS headers, DATA submessages, SPDP, SEDP, locator encoding, GUIDs, and the UDP port mapping used by this component.

OMG DDS 1.4

Defines the conceptual participant, reader, writer, topic, and QoS model that RTPS discovery is advertising.

Example

The RTPS Example page demonstrates the current discovery scaffold by:

  • computing the RTPS ports for a participant

  • building and parsing locally generated SPDP and SEDP messages

  • round-tripping a UInt32 value through the CDR helper functions

  • registering best-effort and reliable topic endpoints in the participant API

API Reference

Header File

Classes

class RtpsParticipant : public espp::BaseComponent

Cross-platform RTPS protocol foundation built on top of the socket component.

RTPS Example

  std::string ip_address;
  espp::WifiSta wifi_sta({.ssid = CONFIG_ESP_WIFI_SSID,
                          .password = CONFIG_ESP_WIFI_PASSWORD,
                          .num_connect_retries = CONFIG_ESP_MAXIMUM_RETRY,
                          .on_connected = nullptr,
                          .on_disconnected = nullptr,
                          .on_got_ip = [&ip_address](ip_event_got_ip_t *eventdata) {
                            ip_address = fmt::format("{}.{}.{}.{}", IP2STR(&eventdata->ip_info.ip));
                            fmt::print("got IP: {}\n", ip_address);
                          }});

  logger.info("Waiting for WiFi connection...");
  while (!wifi_sta.is_connected()) {
    std::this_thread::sleep_for(100ms);
  }
  logger.info("WiFi connected, local IP {}", ip_address);

  const std::string node_name = CONFIG_RTPS_EXAMPLE_NODE_NAME;
  const std::string topic_prefix = CONFIG_RTPS_EXAMPLE_TOPIC_PREFIX;
  const std::string request_topic = topic_prefix + "/request";
  const std::string response_topic = topic_prefix + "/response";
#if CONFIG_RTPS_EXAMPLE_USE_USER_MULTICAST
#if defined(CONFIG_RTPS_EXAMPLE_REQUEST_MULTICAST_GROUP) &&                                        \
    defined(CONFIG_RTPS_EXAMPLE_RESPONSE_MULTICAST_GROUP)
  const std::string request_multicast_group = CONFIG_RTPS_EXAMPLE_REQUEST_MULTICAST_GROUP;
  const std::string response_multicast_group = CONFIG_RTPS_EXAMPLE_RESPONSE_MULTICAST_GROUP;
#elif defined(CONFIG_RTPS_EXAMPLE_USER_MULTICAST_GROUP)
  const std::string request_multicast_group = CONFIG_RTPS_EXAMPLE_USER_MULTICAST_GROUP;
  const std::string response_multicast_group = CONFIG_RTPS_EXAMPLE_USER_MULTICAST_GROUP;
#else
  const std::string request_multicast_group = "239.255.0.11";
  const std::string response_multicast_group = "239.255.0.12";
#endif
#else
  const std::string request_multicast_group;
  const std::string response_multicast_group;
#endif

  std::atomic<uint32_t> request_count{0};
  std::atomic<uint32_t> response_count{0};
  std::atomic<uint32_t> next_request_value{1};
  std::atomic<uint32_t> last_sent_request{0};

  espp::RtpsParticipant participant({
      .node_name = node_name,
      .domain_id = CONFIG_RTPS_EXAMPLE_DOMAIN_ID,
      .participant_id = CONFIG_RTPS_EXAMPLE_PARTICIPANT_ID,
      .advertised_address = ip_address,
      .announce_period = std::chrono::milliseconds(CONFIG_RTPS_EXAMPLE_ANNOUNCE_PERIOD_MS),
      .on_participant_discovered =
          [&logger](const auto &proxy) {
            logger.info("Discovered participant '{}' at {} (meta {}, user {})",
                        proxy.name.empty() ? proxy.guid_prefix.to_string() : proxy.name,
                        proxy.address, proxy.ports.metatraffic_unicast, proxy.ports.user_unicast);
          },
      .on_endpoint_discovered =
          [&logger](const auto &endpoint) {
            logger.info("Discovered remote {} '{}' [{}]", endpoint.is_reader ? "reader" : "writer",
                        endpoint.topic_name, endpoint.type_name);
          },
      .log_level = espp::Logger::Verbosity::INFO,
      // Keep the underlying UDP sockets quieter than the participant so routine socket activity
      // does not clutter the logs. Raise this to debug transport issues independently.
      .socket_log_level = espp::Logger::Verbosity::WARN,
  });

#if CONFIG_RTPS_EXAMPLE_ROLE_INITIATOR
  participant.add_writer({
      .topic_name = request_topic,
      .type_name = std::string(kTypeName),
      .reliability = espp::RtpsParticipant::ReliabilityKind::BEST_EFFORT,
      .multicast_group = request_multicast_group,
      .entity_index = 0,
  });
  participant.add_reader({
      .topic_name = response_topic,
      .type_name = std::string(kTypeName),
      .reliability = espp::RtpsParticipant::ReliabilityKind::BEST_EFFORT,
      .multicast_group = response_multicast_group,
      .entity_index = 0,
      .on_sample =
          [&logger, &response_count, &last_sent_request](std::span<const uint8_t> cdr) {
            auto value = deserialize_uint32(cdr);
            if (!value) {
              return;
            }
            response_count++;
            logger.info("Received response {} (expected {})", *value, last_sent_request.load());
          },
  });
#else
  auto *participant_ptr = &participant;
  participant.add_writer({
      .topic_name = response_topic,
      .type_name = std::string(kTypeName),
      .reliability = espp::RtpsParticipant::ReliabilityKind::BEST_EFFORT,
      .multicast_group = response_multicast_group,
      .entity_index = 0,
  });
  participant.add_reader({
      .topic_name = request_topic,
      .type_name = std::string(kTypeName),
      .reliability = espp::RtpsParticipant::ReliabilityKind::BEST_EFFORT,
      .multicast_group = request_multicast_group,
      .entity_index = 0,
      .on_sample =
          [&logger, &request_count, &response_topic,
           &participant_ptr](std::span<const uint8_t> cdr) {
            auto value = deserialize_uint32(cdr);
            if (!value) {
              return;
            }
            request_count++;
            logger.info("Received request {}, sending response", *value);
            if (!participant_ptr->publish(response_topic, serialize_uint32(*value))) {
              logger.warn("Failed to publish response {}", *value);
            }
          },
  });
#endif

  auto ports = participant.ports();
  logger.info("Role: {}",
#if CONFIG_RTPS_EXAMPLE_ROLE_INITIATOR
              "initiator"
#else
              "responder"
#endif
  );
  logger.info("Participant name: {}", node_name);
  logger.info("Participant GUID: {}", participant.participant_guid().to_string());
  logger.info("Domain ID: {}, Participant ID: {}", CONFIG_RTPS_EXAMPLE_DOMAIN_ID,
              CONFIG_RTPS_EXAMPLE_PARTICIPANT_ID);
  logger.info("Topic prefix: {}", topic_prefix);
  logger.info("Request topic: {}, Response topic: {}", request_topic, response_topic);
  logger.info("Ports: meta mc={}, meta uc={}, user mc={}, user uc={}", ports.metatraffic_multicast,
              ports.metatraffic_unicast, ports.user_multicast, ports.user_unicast);
#if CONFIG_RTPS_EXAMPLE_USE_USER_MULTICAST
  logger.info("User-data multicast enabled: request group {}, response group {}",
              request_multicast_group, response_multicast_group);
#endif

  if (!run_local_protocol_checks(logger, participant)) {
    return;
  }

  if (!participant.start()) {
    logger.error("Failed to start RTPS participant");
    return;
  }

Public Types

enum class ReliabilityKind : uint8_t

Delivery semantics advertised for a writer or reader endpoint.

Values:

enumerator BEST_EFFORT

Best-effort delivery semantics.

enumerator RELIABLE

Reliable delivery semantics.

enum class SubmessageKind : uint8_t

Supported RTPS submessage kinds used by the current implementation.

Values:

enumerator PAD

Padding submessage.

enumerator ACKNACK

Reliable-reader acknowledgement submessage.

enumerator HEARTBEAT

Reliable-writer heartbeat submessage.

enumerator INFO_TS

Timestamp information submessage.

enumerator INFO_DST

Destination GUID-prefix information submessage.

enumerator DATA

User or discovery data submessage.

Public Functions

explicit RtpsParticipant(const Config &config)

Construct an RTPS participant.

Parameters:

config – Participant configuration controlling ports, addresses, discovery, and callbacks.

~RtpsParticipant()

Destroy the participant and stop any active sockets/tasks.

bool start()

Start discovery sockets, user-data sockets, and periodic announcements.

Returns:

True if startup succeeded, false if the participant was already started or initialization failed.

void stop()

Stop sockets and background tasks associated with the participant.

bool is_started() const

Check whether the participant is currently started.

Returns:

True if the participant has been started and not yet stopped.

bool add_writer(const WriterConfig &writer_config)

Register a local writer endpoint to advertise through SEDP.

Parameters:

writer_config – Writer configuration to add.

Returns:

True after the writer has been stored.

bool add_reader(const ReaderConfig &reader_config)

Register a local reader endpoint to advertise through SEDP.

Parameters:

reader_config – Reader configuration to add.

Returns:

True after the reader has been stored.

std::vector<ParticipantProxy> discovered_participants() const

Get the currently discovered remote participants.

Returns:

A snapshot copy of the discovered participant list.

std::vector<EndpointProxy> discovered_writers() const

Get the currently discovered remote writer endpoints.

Returns:

A snapshot copy of the discovered writer list.

std::vector<EndpointProxy> discovered_readers() const

Get the currently discovered remote reader endpoints.

Returns:

A snapshot copy of the discovered reader list.

std::vector<WriterConfig> writers() const

Access the registered local writer configurations.

Returns:

A snapshot copy of the local writer list.

std::vector<ReaderConfig> readers() const

Access the registered local reader configurations.

Returns:

A snapshot copy of the local reader list.

PortMapping ports() const

Compute the standard RTPS UDP port mapping for this participant.

Returns:

The derived metatraffic and user-data ports for the configured domain and participant IDs.

Guid participant_guid() const

Get the local participant GUID.

Returns:

GUID built from the local GUID prefix and participant entity ID.

Guid writer_guid(size_t index) const

Get the GUID for a local writer entity slot.

Parameters:

index – Zero-based local writer entity index.

Returns:

GUID for the derived local writer entity.

Guid reader_guid(size_t index) const

Get the GUID for a local reader entity slot.

Parameters:

index – Zero-based local reader entity index.

Returns:

GUID for the derived local reader entity.

std::vector<uint8_t> build_announce_message() const

Build the default participant announce message.

Returns:

Serialized SPDP participant announce message.

std::vector<uint8_t> build_spdp_announce_message() const

Build the SPDP participant announcement message for this participant.

Returns:

Serialized SPDP message describing the local participant.

std::vector<uint8_t> build_sedp_publication_message(const WriterConfig &writer_config) const

Build an SEDP publication announcement for a local writer.

Parameters:

writer_config – Writer configuration to serialize.

Returns:

Serialized SEDP publication message for the writer.

std::vector<uint8_t> build_sedp_subscription_message(const ReaderConfig &reader_config) const

Build an SEDP subscription announcement for a local reader.

Parameters:

reader_config – Reader configuration to serialize.

Returns:

Serialized SEDP subscription message for the reader.

std::vector<uint8_t> build_data_message(const WriterConfig &writer_config, std::span<const uint8_t> cdr_payload) const

Build a standard RTPS user-data DATA message carrying a CDR-encoded sample.

Parameters:
  • writer_config – Local writer configuration used for the topic and writer entity ID.

  • cdr_payload – CDR-encapsulated serialized payload (encapsulation header + body) to carry as the DATA submessage serializedPayload.

Returns:

Serialized RTPS DATA message containing the sample.

bool publish(std::string_view topic_name, std::span<const uint8_t> cdr_payload)

Publish a CDR-encoded sample on a topic using the configured user-data transport.

Parameters:
  • topic_name – Topic name to publish on. Must match a registered local writer.

  • cdr_payload – CDR-encapsulated serialized payload (encapsulation header + body) to send.

Returns:

True if at least one send call succeeded, false otherwise.

inline const std::string &get_name() const

Get the name of the component

Note

This is the tag of the logger

Returns:

A const reference to the name of the component

inline void set_log_tag(const std::string_view &tag)

Set the tag for the logger

Parameters:

tag – The tag to use for the logger

inline espp::Logger::Verbosity get_log_level() const

Get the log level for the logger

Returns:

The verbosity level of the logger

inline void set_log_level(espp::Logger::Verbosity level)

Set the log level for the logger

Parameters:

level – The verbosity level to use for the logger

inline void set_log_verbosity(espp::Logger::Verbosity level)

Set the log verbosity for the logger

See also

set_log_level

Note

This is a convenience method that calls set_log_level

Parameters:

level – The verbosity level to use for the logger

inline espp::Logger::Verbosity get_log_verbosity() const

Get the log verbosity for the logger

See also

get_log_level

Note

This is a convenience method that calls get_log_level

Returns:

The verbosity level of the logger

inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)

Set the rate limit for the logger

Note

Only calls to the logger that have _rate_limit suffix will be rate limited

Parameters:

rate_limit – The rate limit to use for the logger

Public Static Functions

static PortMapping compute_port_mapping(uint16_t domain_id, uint16_t participant_id)

Compute the standard RTPS UDP port mapping for a domain/participant pair.

Parameters:
  • domain_id – RTPS domain ID.

  • participant_id – RTPS participant ID.

Returns:

Derived RTPS metatraffic and user-data ports.

struct Config

Top-level participant configuration.

Public Members

std::string node_name = {"espp_rtps"}

Local participant name advertised in discovery.

uint16_t domain_id = {0}

RTPS domain ID used for port derivation and discovery scope.

uint16_t participant_id = {0}

RTPS participant ID used for GUID and port derivation.

std::string bind_address = {"0.0.0.0"}

Local IPv4 address to bind sockets to.

std::string advertised_address{"127.0.0.1"}

IPv4 address advertised to peers for unicast traffic.

std::string metatraffic_multicast_group{"239.255.0.1"}

Multicast group used for RTPS metatraffic discovery.

std::string user_multicast_group{"239.255.0.1"}

Multicast group used for best-effort user-data multicast when enabled.

bool use_multicast_for_user_data = {false}

If true, join the user multicast group and publish temporary user-data samples via multicast.

Task::BaseConfig receive_task_config  {.name = "RtpsRx",.stack_size_bytes = 6 * 1024}

Base task configuration for receive sockets.

Task::BaseConfig announce_task_config  {.name = "RtpsAnnounce",.stack_size_bytes = 6 * 1024}

Task configuration for periodic discovery announcements.

std::chrono::milliseconds announce_period = {1000}

Interval between periodic SPDP/SEDP sends.

std::string enclave = {"/"}

User-data enclave string advertised in SPDP.

std::function<void(const ParticipantProxy &participant)> on_participant_discovered{nullptr}

Callback invoked when a remote participant is first discovered.

std::function<void(const EndpointProxy &endpoint)> on_endpoint_discovered{nullptr}

Callback invoked when a remote endpoint is first discovered.

espp::Logger::Verbosity log_level = {espp::Logger::Verbosity::INFO}

Participant log verbosity.

espp::Logger::Verbosity socket_log_level = {espp::Logger::Verbosity::WARN}

Log verbosity for the participant’s underlying UDP sockets. Defaults to WARN so routine socket activity does not clutter the logs; raise it to debug transport issues independently of the participant log level.

struct EndpointProxy

Cached information about a discovered remote reader or writer endpoint.

Public Members

Guid guid = {}

Discovered endpoint GUID.

Guid participant_guid = {}

GUID of the participant that owns this endpoint.

std::string topic_name = {}

Discovered topic name.

std::string type_name = {"std_msgs/msg/UInt32"}

Discovered type name.

ReliabilityKind reliability = {ReliabilityKind::BEST_EFFORT}

Advertised endpoint reliability.

bool is_reader = {false}

True for discovered readers, false for discovered writers.

bool expects_inline_qos = {false}

Whether the remote endpoint requested inline QoS.

Locator unicast_locator = {}

Preferred unicast locator advertised by the endpoint.

std::vector<Locator> multicast_locators = {}

Multicast locators advertised by the endpoint for user-data traffic.

struct EntityId

4-byte entity identifier within a participant.

Public Functions

bool operator==(const EntityId &other) const = default

Compare two entity identifiers for equality.

Parameters:

other – Entity identifier to compare against.

Returns:

True if both entity identifiers contain identical bytes.

std::string to_string() const

Convert the entity identifier to a printable hex string.

Returns:

Colon-separated hexadecimal representation of the entity identifier.

Public Members

std::array<uint8_t, 4> value = {}

Raw 4-byte entity identifier value.

struct Guid

Globally unique identifier for an RTPS entity.

Public Functions

bool operator==(const Guid &other) const = default

Compare two GUIDs for equality.

Parameters:

other – GUID to compare against.

Returns:

True if both GUIDs have the same prefix and entity identifier.

std::string to_string() const

Convert the GUID to a printable string.

Returns:

Combined printable representation of the prefix and entity identifier.

Public Members

GuidPrefix prefix = {}

Participant GUID prefix portion.

EntityId entity_id = {}

Entity identifier portion within the participant.

struct GuidPrefix

12-byte prefix that identifies an RTPS participant.

Public Functions

bool operator==(const GuidPrefix &other) const = default

Compare two GUID prefixes for equality.

Parameters:

other – Prefix to compare against.

Returns:

True if both prefixes contain identical bytes.

std::string to_string() const

Convert the GUID prefix to a printable hex string.

Returns:

Colon-separated hexadecimal representation of the prefix.

Public Members

std::array<uint8_t, 12> value = {}

Raw 12-byte GUID prefix value.

struct Header

RTPS message header fields.

Public Members

ProtocolVersion protocol_version = {}

RTPS protocol version.

VendorId vendor_id = {}

Sender vendor identifier.

GuidPrefix guid_prefix = {}

Sender participant GUID prefix.

struct Locator

RTPS network locator for a unicast or multicast transport endpoint.

Public Types

enum class Kind : int32_t

Supported locator transport kinds.

Values:

enumerator INVALID

Locator is not initialized or not valid.

enumerator UDP_V4

UDP over IPv4 locator.

Public Functions

std::string address_string() const

Convert the locator address to a printable IPv4 string.

Returns:

Dotted-decimal IPv4 address, or `0.0.0.0` if the locator is not UDPv4.

Public Members

Kind kind = {Kind::INVALID}

Transport kind of this locator.

uint32_t port = {0}

Transport port number in host byte order.

std::array<uint8_t, 16> address = {}

Raw 16-byte RTPS locator address field.

Public Static Functions

static Locator udp_v4(std::string_view ipv4_address, uint16_t port)

Build a UDPv4 locator from a dotted IPv4 address and port.

Parameters:
  • ipv4_address – Dotted-decimal IPv4 address string.

  • port – UDP port number to advertise.

Returns:

A locator configured for UDPv4 with the IPv4 address stored in RTPS locator form.

struct Message

RTPS message consisting of a header and a sequence of submessages.

Public Functions

std::vector<uint8_t> serialize() const

Serialize the RTPS message to bytes.

Returns:

A complete RTPS message buffer ready to send on the network.

Public Members

Header header = {}

RTPS message header.

std::vector<Submessage> submessages = {}

Serialized submessages carried by this RTPS message.

Public Static Functions

static std::optional<Message> parse(std::span<const uint8_t> data)

Parse an RTPS message from bytes.

Parameters:

data – Serialized RTPS message bytes.

Returns:

A parsed message on success, or `std::nullopt` if the input is invalid.

struct ParticipantProxy

Cached information about a discovered remote participant.

Public Members

Guid participant_guid = {}

Discovered participant GUID.

GuidPrefix guid_prefix = {}

Discovered participant GUID prefix.

std::string name = {}

Remote participant name, if advertised.

std::string enclave = {"/"}

Remote ROS 2 enclave/user-data hint, if advertised.

std::string address = {}

Preferred remote IPv4 address for user traffic.

PortMapping ports = {}

Remote participant port mapping derived from discovery data.

uint32_t builtin_endpoints = {0}

Remote builtin-endpoint bitmask from SPDP.

struct PortMapping

Standard RTPS UDP port mapping derived from domain and participant IDs.

Public Members

uint16_t metatraffic_multicast = {0}

Multicast discovery/metatraffic port.

uint16_t metatraffic_unicast = {0}

Unicast discovery/metatraffic port for this participant.

uint16_t user_multicast = {0}

Multicast user-data port.

uint16_t user_unicast = {0}

Unicast user-data port for this participant.

struct ProtocolVersion

RTPS protocol version carried in the RTPS message header.

Public Members

uint8_t major = {2}

Major RTPS version number.

uint8_t minor = {3}

Minor RTPS version number.

struct ReaderConfig

Configuration for a locally advertised reader endpoint.

Public Members

std::string topic_name = {}

Topic name advertised through SEDP.

std::string type_name = {"std_msgs/msg/UInt32"}

Type name advertised through SEDP.

ReliabilityKind reliability = {ReliabilityKind::BEST_EFFORT}

Reliability QoS advertised for the reader.

std::string multicast_group = {}

joined on the standard RTPS user-multicast port when set.

Optional multicast group advertised for this reader and

uint32_t entity_index = {0}

Local entity slot used to derive the RTPS entity ID.

std::function<void(std::span<const uint8_t>)> on_sample{nullptr}

Callback invoked with the raw CDR-encapsulated serialized payload (encapsulation header + body) of a matching received sample. The span is only valid for the duration of the callback.

struct SequenceNumber

RTPS sequence number wrapper.

Public Members

int64_t value = {1}

Signed 64-bit RTPS sequence number value.

struct Submessage

One RTPS submessage within an RTPS message.

Public Members

SubmessageKind kind = {SubmessageKind::PAD}

Submessage kind discriminator.

uint8_t flags = {0x01}

Raw RTPS submessage flags byte.

std::vector<uint8_t> payload = {}

Serialized submessage payload bytes without the 4-byte submessage header.

struct VendorId

RTPS vendor identifier carried in the RTPS message header.

Public Members

std::array<uint8_t, 2> value = {0xca, 0xfe}

Two-byte vendor identifier.

struct WriterConfig

Configuration for a locally advertised writer endpoint.

Public Members

std::string topic_name = {}

Topic name advertised through SEDP.

std::string type_name = {"std_msgs/msg/UInt32"}

Type name advertised through SEDP.

ReliabilityKind reliability = {ReliabilityKind::BEST_EFFORT}

Reliability QoS advertised for the writer.

std::string multicast_group = {}

Optional multicast group advertised for this writer and used by `publish()` when set.

uint32_t entity_index = {0}

Local entity slot used to derive the RTPS entity ID.