nros rmw-cffi
C vtable for plugging a third-party RMW backend into nros
Loading...
Searching...
No Matches
Data Structures | Macros | Typedefs | Enumerations | Functions
rmw_entity.h File Reference

Typed entity structs for the nros RMW C surface. More...

#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "nros/rmw_ret.h"
Include dependency graph for rmw_entity.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  rmw_byte_span_t
 
struct  rmw_client_t
 
struct  rmw_gid_t
 
struct  rmw_message_info_t
 
struct  rmw_message_type_support_t
 
struct  rmw_mut_byte_span_t
 
struct  rmw_network_flow_endpoint_t
 
struct  rmw_node_t
 
struct  rmw_publisher_options_t
 
struct  rmw_publisher_t
 
struct  rmw_qos_profile_t
 
struct  rmw_service_t
 
struct  rmw_service_type_support_t
 
struct  rmw_session_options_t
 
struct  rmw_session_property_t
 
struct  rmw_session_t
 
struct  rmw_subscription_options_t
 
struct  rmw_subscription_t
 
struct  rmw_topic_endpoint_info_t
 

Macros

#define NROS_RMW_DURABILITY_SYSTEM_DEFAULT   0
 
#define NROS_RMW_DURABILITY_TRANSIENT_LOCAL   1
 
#define NROS_RMW_DURABILITY_UNKNOWN   3
 
#define NROS_RMW_DURABILITY_VOLATILE   2
 
#define NROS_RMW_DURATION_INFINITE_MS   UINT32_MAX
 
#define NROS_RMW_HISTORY_KEEP_ALL   2
 
#define NROS_RMW_HISTORY_KEEP_LAST   1
 
#define NROS_RMW_HISTORY_SYSTEM_DEFAULT   0
 
#define NROS_RMW_HISTORY_UNKNOWN   3
 
#define NROS_RMW_QOS_PROFILE_DEFAULT
 
#define NROS_RMW_QOS_PROFILE_PARAMETERS
 
#define NROS_RMW_QOS_PROFILE_SENSOR_DATA
 
#define NROS_RMW_QOS_PROFILE_SERVICES_DEFAULT   NROS_RMW_QOS_PROFILE_DEFAULT
 
#define NROS_RMW_QOS_PROFILE_SYSTEM_DEFAULT
 
#define NROS_RMW_RELIABILITY_BEST_EFFORT   2
 
#define NROS_RMW_RELIABILITY_RELIABLE   1
 
#define NROS_RMW_RELIABILITY_SYSTEM_DEFAULT   0
 
#define NROS_RMW_RELIABILITY_UNKNOWN   3
 
#define RMW_GID_STORAGE_SIZE   24u
 
#define RMW_INET_ADDRSTRLEN   48
 
#define RMW_MESSAGE_INFO_SEQUENCE_NUMBER_UNSUPPORTED   UINT64_MAX
 
#define RMW_SESSION_MAX_PROPERTIES   16
 

Typedefs

typedef void(* rmw_content_filter_visit_fn) (void *ctx, const char *expression, const char *const *parameters, size_t parameter_count)
 
typedef bool(* rmw_network_flow_endpoint_visit_fn) (void *ctx, const rmw_network_flow_endpoint_t *endpoint)
 
typedef int64_t rmw_time_point_value_t
 

Enumerations

enum  nros_rmw_qos_clash_t {
  NROS_RMW_QOS_CLASH_NONE = 0 , NROS_RMW_QOS_CLASH_RELIABILITY = 1u << 0 , NROS_RMW_QOS_CLASH_DURABILITY = 1u << 1 , NROS_RMW_QOS_CLASH_DEADLINE = 1u << 2 ,
  NROS_RMW_QOS_CLASH_LIVELINESS_KIND = 1u << 3 , NROS_RMW_QOS_CLASH_LIVELINESS_LEASE = 1u << 4
}
 
enum  rmw_endpoint_type_t { RMW_ENDPOINT_INVALID = 0 , RMW_ENDPOINT_PUBLISHER = 1 , RMW_ENDPOINT_SUBSCRIPTION = 2 }
 
enum  rmw_feature_t { RMW_FEATURE_MESSAGE_INFO_PUBLICATION_SEQUENCE_NUMBER = 0 , RMW_FEATURE_MESSAGE_INFO_RECEPTION_SEQUENCE_NUMBER = 1 }
 
enum  rmw_internet_protocol_t { RMW_INTERNET_PROTOCOL_UNKNOWN = 0 , RMW_INTERNET_PROTOCOL_IPV4 = 1 , RMW_INTERNET_PROTOCOL_IPV6 = 2 , RMW_INTERNET_PROTOCOL_COUNT = 3 }
 
enum  rmw_liveliness_kind_t {
  NROS_RMW_LIVELINESS_SYSTEM_DEFAULT = 0 , NROS_RMW_LIVELINESS_AUTOMATIC = 1 , NROS_RMW_LIVELINESS_MANUAL_BY_NODE = 2 , NROS_RMW_LIVELINESS_MANUAL_BY_TOPIC = 3 ,
  NROS_RMW_LIVELINESS_UNKNOWN = 4
}
 
enum  rmw_log_severity_t {
  RMW_LOG_SEVERITY_UNSET = 0 , RMW_LOG_SEVERITY_DEBUG = 10 , RMW_LOG_SEVERITY_INFO = 20 , RMW_LOG_SEVERITY_WARN = 30 ,
  RMW_LOG_SEVERITY_ERROR = 40 , RMW_LOG_SEVERITY_FATAL = 50
}
 
enum  rmw_qos_compatibility_type_t { RMW_QOS_COMPATIBILITY_OK = 0 , RMW_QOS_COMPATIBILITY_WARNING = 1 , RMW_QOS_COMPATIBILITY_ERROR = 2 }
 
enum  rmw_transport_protocol_t { RMW_TRANSPORT_PROTOCOL_UNKNOWN = 0 , RMW_TRANSPORT_PROTOCOL_UDP = 1 , RMW_TRANSPORT_PROTOCOL_TCP = 2 , RMW_TRANSPORT_PROTOCOL_COUNT = 3 }
 

Functions

rmw_ret_t nros_rmw_qos_incompatibility_mask (rmw_qos_profile_t offered, rmw_qos_profile_t requested, rmw_qos_compatibility_type_t *compatibility, uint32_t *clash_mask)
 
rmw_ret_t rmw_compare_gids_equal (const rmw_gid_t *gid1, const rmw_gid_t *gid2, bool *result)
 
rmw_ret_t rmw_qos_profile_check_compatible (rmw_qos_profile_t publisher_profile, rmw_qos_profile_t subscription_profile, rmw_qos_compatibility_type_t *compatibility, char *reason, size_t reason_size)
 

Detailed Description

Typed entity structs for the nros RMW C surface.

Same shape as upstream rmw.h's rmw_publisher_t / rmw_subscription_t family: visible metadata + a void * data tail (named backend_data here). No generic-handle typedef.

Lifetime rule. All const char * string fields are borrowed pointers — the storage pointing at them is owned by the caller (the runtime) and must outlive the entity. Backends never free or reallocate these strings; they hold them as-is for the entity's lifetime.

ABI commitment. These structs are part of the public ABI. Adding or reordering fields is a major version bump. Backends compile against this header and consumers compile against backend libraries — both sides must agree on the layout.

Forward-compat reserved bytes. Each entity carries an explicit _reserved[N] byte array sized to fill the natural alignment slot before backend_data. New fields up to N bytes can be added later without changing the struct's overall size or any field's offset after backend_data. Backends and runtime must zero the reserved bytes; the runtime relies on them being zero on read.

No-alloc + no-std preserved. No struct here owns heap-allocated storage. All metadata is either inline POD or a borrowed pointer.

Macro Definition Documentation

◆ NROS_RMW_DURABILITY_SYSTEM_DEFAULT

#define NROS_RMW_DURABILITY_SYSTEM_DEFAULT   0

Durability policy values for rmw_qos_profile_t::durability.

◆ NROS_RMW_DURABILITY_TRANSIENT_LOCAL

#define NROS_RMW_DURABILITY_TRANSIENT_LOCAL   1

◆ NROS_RMW_DURABILITY_UNKNOWN

#define NROS_RMW_DURABILITY_UNKNOWN   3

◆ NROS_RMW_DURABILITY_VOLATILE

#define NROS_RMW_DURABILITY_VOLATILE   2

◆ NROS_RMW_DURATION_INFINITE_MS

#define NROS_RMW_DURATION_INFINITE_MS   UINT32_MAX

Explicit infinite spelling for the u32-ms duration fields (phase-301, issue 0241). Semantically identical to 0 (no check) but lets a caller distinguish "I mean infinite" from "I left it unset".

◆ NROS_RMW_HISTORY_KEEP_ALL

#define NROS_RMW_HISTORY_KEEP_ALL   2

◆ NROS_RMW_HISTORY_KEEP_LAST

#define NROS_RMW_HISTORY_KEEP_LAST   1

◆ NROS_RMW_HISTORY_SYSTEM_DEFAULT

#define NROS_RMW_HISTORY_SYSTEM_DEFAULT   0

History policy values for rmw_qos_profile_t::history.

◆ NROS_RMW_HISTORY_UNKNOWN

#define NROS_RMW_HISTORY_UNKNOWN   3

◆ NROS_RMW_QOS_PROFILE_DEFAULT

#define NROS_RMW_QOS_PROFILE_DEFAULT
Value:
.liveliness_kind = NROS_RMW_LIVELINESS_AUTOMATIC, \
.depth = 10, \
._reserved0 = 0, \
.deadline_ms = 0, \
.lifespan_ms = 0, \
.liveliness_lease_ms = 0, \
.avoid_ros_namespace_conventions = 0, \
._reserved1 = {0, 0, 0}, \
})
#define NROS_RMW_DURABILITY_VOLATILE
Definition rmw_entity.h:80
@ NROS_RMW_LIVELINESS_AUTOMATIC
Definition rmw_entity.h:268
#define NROS_RMW_HISTORY_KEEP_LAST
Definition rmw_entity.h:85
#define NROS_RMW_RELIABILITY_RELIABLE
Definition rmw_entity.h:71
Definition rmw_entity.h:318

rmw_qos_profile_default-equivalent: reliable + volatile + keep-last(10), automatic liveliness, no deadline / lifespan.

◆ NROS_RMW_QOS_PROFILE_PARAMETERS

#define NROS_RMW_QOS_PROFILE_PARAMETERS
Value:
.liveliness_kind = NROS_RMW_LIVELINESS_AUTOMATIC, \
.depth = 1000, \
._reserved0 = 0, \
.deadline_ms = 0, \
.lifespan_ms = 0, \
.liveliness_lease_ms = 0, \
.avoid_ros_namespace_conventions = 0, \
._reserved1 = {0, 0, 0}, \
})

rmw_qos_profile_parameters-equivalent: reliable + volatile + keep-last(1000).

◆ NROS_RMW_QOS_PROFILE_SENSOR_DATA

#define NROS_RMW_QOS_PROFILE_SENSOR_DATA
Value:
.liveliness_kind = NROS_RMW_LIVELINESS_AUTOMATIC, \
.depth = 5, \
._reserved0 = 0, \
.deadline_ms = 0, \
.lifespan_ms = 0, \
.liveliness_lease_ms = 0, \
.avoid_ros_namespace_conventions = 0, \
._reserved1 = {0, 0, 0}, \
})
#define NROS_RMW_RELIABILITY_BEST_EFFORT
Definition rmw_entity.h:72

rmw_qos_profile_sensor_data-equivalent: best-effort + volatile + keep-last(5).

◆ NROS_RMW_QOS_PROFILE_SERVICES_DEFAULT

#define NROS_RMW_QOS_PROFILE_SERVICES_DEFAULT   NROS_RMW_QOS_PROFILE_DEFAULT

rmw_qos_profile_services_default-equivalent: reliable + volatile + keep-last(10).

◆ NROS_RMW_QOS_PROFILE_SYSTEM_DEFAULT

#define NROS_RMW_QOS_PROFILE_SYSTEM_DEFAULT
Value:
.liveliness_kind = NROS_RMW_LIVELINESS_SYSTEM_DEFAULT, \
.depth = 0, \
._reserved0 = 0, \
.deadline_ms = 0, \
.lifespan_ms = 0, \
.liveliness_lease_ms = 0, \
.avoid_ros_namespace_conventions = 0, \
._reserved1 = {0, 0, 0}, \
})
@ NROS_RMW_LIVELINESS_SYSTEM_DEFAULT
Definition rmw_entity.h:266
#define NROS_RMW_DURABILITY_SYSTEM_DEFAULT
Definition rmw_entity.h:78
#define NROS_RMW_HISTORY_SYSTEM_DEFAULT
Definition rmw_entity.h:84
#define NROS_RMW_RELIABILITY_SYSTEM_DEFAULT
Definition rmw_entity.h:70

rmw_qos_profile_system_default-equivalent: every field is the sentinel.

issue 0829. This aliased NROS_RMW_QOS_PROFILE_DEFAULT until 2026-09-03, which made SYSTEM_DEFAULT a byte-for-byte synonym for a concrete RELIABLE / VOLATILE / KEEP_LAST(10) profile — i.e. the constant said nothing of its own. Upstream's rmw_qos_profile_system_default names no concrete policy either; it is all sentinel, and the RMW resolves it. The two reference RMWs resolve the SAME sentinel differently — rmw_cyclonedds_cpp's create_readwrite_qos gives KEEP_LAST, 1, while rmw_zenoh_cpp's QoS::QoS() gives RMW_ZENOH_DEFAULT_HISTORY_DEPTH, which is 42 — so no number baked here could be right.

NOT AN ABI BREAK: no struct layout moved and no policy value was renumbered. What changed is the BYTES this macro expands to, so a caller that recompiles against this header and uses this constant now sends sentinels where it used to send depth 10. That is the intended fix, and nothing in this repository used the macro. Every field being zero also means this is what a memset of rmw_qos_profile_t gives, so the ABI stops having two answers for the same bytes.

Which concrete values a sentinel becomes is the BACKEND's answer, applied at its create entry: cyclonedds resolves to RELIABLE / VOLATILE / KEEP_LAST(1), mirroring rmw_cyclonedds_cpp; xrce resolves the three policies the same way and leaves the depth for the Agent; zenoh resolves the depth to the ring the shim actually enforces.

◆ NROS_RMW_RELIABILITY_BEST_EFFORT

#define NROS_RMW_RELIABILITY_BEST_EFFORT   2

◆ NROS_RMW_RELIABILITY_RELIABLE

#define NROS_RMW_RELIABILITY_RELIABLE   1

◆ NROS_RMW_RELIABILITY_SYSTEM_DEFAULT

#define NROS_RMW_RELIABILITY_SYSTEM_DEFAULT   0

Reliability policy values for rmw_qos_profile_t::reliability.

◆ NROS_RMW_RELIABILITY_UNKNOWN

#define NROS_RMW_RELIABILITY_UNKNOWN   3

The backend could not determine this policy. See the note on rmw_qos_profile_t about partial answers.

◆ RMW_GID_STORAGE_SIZE

#define RMW_GID_STORAGE_SIZE   24u

Storage size of a GID, in bytes. Upstream's RMW_GID_STORAGE_SIZE.

◆ RMW_INET_ADDRSTRLEN

#define RMW_INET_ADDRSTRLEN   48

Upstream's value, kept exactly: it sizes a field that crosses the ABI, and upstream took it from linux/inet.h for the same reason.

◆ RMW_MESSAGE_INFO_SEQUENCE_NUMBER_UNSUPPORTED

#define RMW_MESSAGE_INFO_SEQUENCE_NUMBER_UNSUPPORTED   UINT64_MAX

Sentinel for a sequence number the backend does not populate. Upstream's RMW_MESSAGE_INFO_SEQUENCE_NUMBER_UNSUPPORTED.

◆ RMW_SESSION_MAX_PROPERTIES

#define RMW_SESSION_MAX_PROPERTIES   16

Upper bound on rmw_session_options_t::property_count.

The seam marshals the properties through a stack array, so it needs a bound; 16 is chosen to clear the largest configuration anyone can actually state at once (zenoh-pico defines 23 run-time keys, but mode and connect arrive as dedicated create_session arguments and the 13 TLS keys split into a listen-side and a connect-side set — a full mTLS client is ~10). A caller that exceeds it is REFUSED, never truncated.

Typedef Documentation

◆ rmw_content_filter_visit_fn

typedef void(* rmw_content_filter_visit_fn) (void *ctx, const char *expression, const char *const *parameters, size_t parameter_count)

Visit a subscription's content filter. Return value ignored: there is exactly one filter per subscription, so this is a callback only to avoid handing back an allocated rmw_subscription_content_filter_options_t.

expression and every parameters[i] are BORROWED for the call. A subscription with no filter is reported as expression == NULL, which is what upstream's empty options struct means.

◆ rmw_network_flow_endpoint_visit_fn

typedef bool(* rmw_network_flow_endpoint_visit_fn) (void *ctx, const rmw_network_flow_endpoint_t *endpoint)

Visit one network flow endpoint. Return false to stop.

Upstream fills an ALLOCATING rmw_network_flow_endpoint_array_t through an rcutils_allocator_t *. There is no allocator at this seam and the flow count is a property of the OS's routing, not of anything the caller can size in advance — so it streams, exactly like the graph slots.

◆ rmw_time_point_value_t

typedef int64_t rmw_time_point_value_t

Nanoseconds since a clock's epoch — upstream's rmw_time_point_value_t.

Enumeration Type Documentation

◆ nros_rmw_qos_clash_t

Which policies clashed, as a bitmask. A nano-ros extension: upstream reports the reason only as prose, which a target cannot act on.

Enumerator
NROS_RMW_QOS_CLASH_NONE 
NROS_RMW_QOS_CLASH_RELIABILITY 
NROS_RMW_QOS_CLASH_DURABILITY 
NROS_RMW_QOS_CLASH_DEADLINE 
NROS_RMW_QOS_CLASH_LIVELINESS_KIND 
NROS_RMW_QOS_CLASH_LIVELINESS_LEASE 

◆ rmw_endpoint_type_t

Which end of a topic an endpoint is — upstream rmw_endpoint_type_t.

Enumerator
RMW_ENDPOINT_INVALID 
RMW_ENDPOINT_PUBLISHER 
RMW_ENDPOINT_SUBSCRIPTION 

◆ rmw_feature_t

Upstream rmw_feature_t — an optional piece of CONTENT a backend may or may not populate. Upstream defines exactly these two, both about whether message-info sequence numbers are real. Values mirror upstream's.

Enumerator
RMW_FEATURE_MESSAGE_INFO_PUBLICATION_SEQUENCE_NUMBER 
RMW_FEATURE_MESSAGE_INFO_RECEPTION_SEQUENCE_NUMBER 

◆ rmw_internet_protocol_t

Internet protocol of a network flow — upstream rmw_internet_protocol_t.

Enumerator
RMW_INTERNET_PROTOCOL_UNKNOWN 
RMW_INTERNET_PROTOCOL_IPV4 
RMW_INTERNET_PROTOCOL_IPV6 
RMW_INTERNET_PROTOCOL_COUNT 

◆ rmw_liveliness_kind_t

Liveliness kind values for rmw_qos_profile_t::liveliness_kind.

Upstream's numbering (W5/B2). MANUAL_BY_NODE and MANUAL_BY_TOPIC were SWAPPED here until 2026-08-24 — 2 meant BY_TOPIC to us and BY_NODE to upstream — which the cyclonedds backend then translated into a real DDS liveliness kind a ROS peer matches on.

Enumerator
NROS_RMW_LIVELINESS_SYSTEM_DEFAULT 

Let the middleware choose. Spelled NONE before W5/B2 and used the same way: nothing is asserted and nothing is tracked. Upstream has no separate NONE, so the two collapse onto value 0.

NROS_RMW_LIVELINESS_AUTOMATIC 

Backend's keepalive task asserts liveliness automatically.

NROS_RMW_LIVELINESS_MANUAL_BY_NODE 

Application calls assert_liveliness() at the node level.

NROS_RMW_LIVELINESS_MANUAL_BY_TOPIC 

Application calls assert_liveliness() per topic explicitly.

NROS_RMW_LIVELINESS_UNKNOWN 

The backend could not determine this policy.

◆ rmw_log_severity_t

Log severity — upstream rmw_log_severity_t, values included.

The values are rcutils' ladder (DEBUG 10, INFO 20, …), not a dense 0..N, so they are written out rather than renumbered: a caller that has an rcutils severity in hand can pass it straight through.

There is no TRACE. nros_log::Severity has one, and it maps to DEBUG crossing this seam — losing a distinction upstream never had is better than inventing a value a ROS-side caller cannot produce.

Enumerator
RMW_LOG_SEVERITY_UNSET 
RMW_LOG_SEVERITY_DEBUG 
RMW_LOG_SEVERITY_INFO 
RMW_LOG_SEVERITY_WARN 
RMW_LOG_SEVERITY_ERROR 
RMW_LOG_SEVERITY_FATAL 

◆ rmw_qos_compatibility_type_t

Verdict of a QoS compatibility check. Upstream rmw_qos_compatibility_type_t, values included.

WARNING means "compatible as far as could be checked, but at least one policy on one side is `*_UNKNOWN`" — the backend could not read it back. Reachable since W5/B2 gave the policies an UNKNOWN encoding; it was defined and unreachable before that, so the value could not be reused for anything else in the meantime.

A definite clash OUTRANKS an unknown: if the policies that COULD be compared are already incompatible the verdict is ERROR, because softening it to a warning would hide something the caller can act on.

Enumerator
RMW_QOS_COMPATIBILITY_OK 
RMW_QOS_COMPATIBILITY_WARNING 
RMW_QOS_COMPATIBILITY_ERROR 

◆ rmw_transport_protocol_t

Transport protocol of a network flow — upstream rmw_transport_protocol_t, values included.

Enumerator
RMW_TRANSPORT_PROTOCOL_UNKNOWN 
RMW_TRANSPORT_PROTOCOL_UDP 
RMW_TRANSPORT_PROTOCOL_TCP 
RMW_TRANSPORT_PROTOCOL_COUNT 

Function Documentation

◆ nros_rmw_qos_incompatibility_mask()

rmw_ret_t nros_rmw_qos_incompatibility_mask ( rmw_qos_profile_t  offered,
rmw_qos_profile_t  requested,
rmw_qos_compatibility_type_t compatibility,
uint32_t *  clash_mask 
)

Which policies of offered (a publisher's) and requested (a subscription's) are incompatible, as a bitmask — no strings, so an image that only needs the verdict never links the reason table.

Argument order is upstream's: publisher profile first.

Writes *compatibility and *clash_mask on NROS_RMW_RET_OK; NROS_RMW_RET_INVALID_ARGUMENT if either out-parameter is NULL.

◆ rmw_compare_gids_equal()

rmw_ret_t rmw_compare_gids_equal ( const rmw_gid_t gid1,
const rmw_gid_t gid2,
bool *  result 
)

Upstream rmw_compare_gids_equal. Exact parity.

Equal means the same implementation_identifier AND the same 24 bytes. Gids from different backends are never equal — which matters more here than upstream, because nros_rmw_cffi_register_named admits several backends in one image.

Comparison is over the WHOLE array, so a producer must zero-pad; see rmw_gid_t.

◆ rmw_qos_profile_check_compatible()

rmw_ret_t rmw_qos_profile_check_compatible ( rmw_qos_profile_t  publisher_profile,
rmw_qos_profile_t  subscription_profile,
rmw_qos_compatibility_type_t compatibility,
char *  reason,
size_t  reason_size 
)

Upstream rmw_qos_profile_check_compatible. Exact parity.

reason may be NULL with reason_size 0 — the create-time path, which wants the verdict and nothing else.

The reason is SELECTED, never FORMATTED: each clash bit maps to one static const char[] and they are appended by a bounded copy. Upstream's implementations use snprintf, which would drag the printf engine into images that deliberately excluded it.

Truncation is NOT failure: the buffer is always NUL-terminated and the verdict is still written. Returning BUFFER_TOO_SMALL would make a small-buffer caller lose the load-bearing half of the answer.