Skip to main content

zerodds_xrce/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3
4//! DDS-XRCE Wire-Codec (OMG `formal/2020-11-01`).
5//!
6//! Crate `zerodds-xrce`. Safety classification: **SAFE**.
7//! Siehe `docs/architecture/02_architecture.md §3` und
8//! `docs/architecture/04_safety_by_architecture.md §2`.
9//!
10//! ## Scope (C6.2.A — Wire-Lite + UDP-Mapping)
11//!
12//! - **`MessageHeader`** (§8.3.2): SessionId/StreamId/SequenceNr +
13//!   optionalem ClientKey.
14//! - **`SubmessageHeader`** (§8.3.4): SubmessageId, Flags, Length.
15//! - **16 Submessages** (§8.3.5): CREATE_CLIENT, CREATE, GET_INFO,
16//!   DELETE, STATUS_AGENT, STATUS, INFO, WRITE_DATA, READ_DATA, DATA,
17//!   ACKNACK, HEARTBEAT, RESET, FRAGMENT, TIMESTAMP, TIMESTAMP_REPLY.
18//! - **`SerialNumber16`**: RFC-1982-Comparator (§8.3.2.3).
19//! - **`XrceUdpSender` / `recv_message`** (§11.2): UDP-Transport-
20//!   Mapping mit Default-Port-Schema `7400 + 4 * domainId + offset`.
21//!
22//! ## Scope (C6.2.B — Object-Model + Reliable-Stack)
23//!
24//! - **`ObjectId` / `ObjectKind` / `ObjectVariant`** (§7.2 + §7.7).
25//! - **`ObjectStore`** (§7.5): pro-Client `BTreeMap<ObjectId, Instance>`
26//!   mit CREATE-Reuse/Replace-Semantik.
27//! - **`ReliableStreamState`** (§8.4.10/§8.4.11): Sender + Receiver mit
28//!   HEARTBEAT-Tick und ACKNACK-Bitmap.
29//! - **`FragmentAssembler`** (§8.4.13) mit DoS-Caps + GC.
30//! - **`ReadStream`** (§8.4.14): Continuous-Read mit Rate-Limiter.
31//! - **`TransportLocator`** (§7.7.4): Small/Medium/Large/String.
32//! - **`MulticastDiscovery`** (§11.2.4) auf `239.255.0.2:7400`.
33//!
34//! ## Scope (C6.2.C — XML/File-Configuration)
35//!
36//! - **`XrceConfig`** (§7.7.3 + §9.3): Object-Hierarchy-Loader fuer
37//!   `<dds><participant>...</participant></dds>` mit Type/QoS-Profile-
38//!   Reuse via `zerodds-xml` (DDS-XML-Loader).
39//! - **`to_create_messages`**: generiert die CREATE-Submessage-Sequence
40//!   in topologischer Reihenfolge (Type → Participant → Topic →
41//!   Pub/Sub → DataWriter/DataReader) mit
42//!   `RepresentationByXmlString`-Body.
43//!
44//! ## Scope (C6.2.D — TCP/Serial-Transports + TLS/DTLS)
45//!
46//! - **`transport_tcp`** (§11.3): `XrceTcpClient`/`XrceTcpServer` mit
47//!   2-Byte-Length-Prefix-Framing.
48//! - **`transport_serial`** (Annex C): HDLC-aehnlicher Frame-Codec mit
49//!   Byte-Stuffing + CRC-16-CCITT-FALSE; Streaming-Reassembly via
50//!   `SerialFramer`. Echte Serial-IO ist nicht im Scope (kein
51//!   `serialport`-Crate-Dep).
52//! - **`transport_tls`**: Trait + Skeleton fuer TLS-on-TCP (Plug-In
53//!   spaeter).
54//! - **`transport_dtls`**: `DtlsLayer`-Trait + `DummyDtls`-Pass-Through;
55//!   echte DTLS-Lib (z.B. `webrtc-dtls`) kommt deployment-spezifisch.
56//! - `TransportLocatorTcp` + `TransportLocatorSerial` als zusaetzliche
57//!   Locator-Varianten (Discriminator 0x04/0x05).
58//!
59//! ## Bewusst nicht implementiert
60//!
61//! - Echte Serialport-IO (kein `serialport`-Crate-Dep).
62//! - Echte TLS-/DTLS-Engine (Plug-In spaeter).
63//! - ROS2-Bridge.
64//! - Live-Reload / Hot-Swap der XML-Config (Stretch).
65
66#![cfg_attr(not(feature = "std"), no_std)]
67#![forbid(unsafe_code)]
68#![warn(missing_docs)]
69
70#[cfg(feature = "alloc")]
71extern crate alloc;
72
73#[cfg(feature = "std")]
74extern crate std;
75
76pub mod encoding;
77pub mod error;
78pub mod header;
79pub mod serial_number;
80pub mod submessages;
81#[cfg(feature = "alloc")]
82pub mod transport_dtls;
83#[cfg(feature = "std")]
84pub mod transport_serial;
85#[cfg(feature = "std")]
86pub mod transport_tcp;
87#[cfg(feature = "alloc")]
88pub mod transport_tls;
89#[cfg(feature = "std")]
90pub mod transport_udp;
91
92#[cfg(feature = "alloc")]
93pub mod continuous_read;
94#[cfg(feature = "std")]
95pub mod discovery;
96#[cfg(feature = "alloc")]
97pub mod fragment;
98#[cfg(feature = "alloc")]
99pub mod object_id;
100#[cfg(feature = "alloc")]
101pub mod object_info;
102#[cfg(feature = "alloc")]
103pub mod object_kind;
104#[cfg(feature = "alloc")]
105pub mod object_repr;
106#[cfg(feature = "alloc")]
107pub mod object_store;
108#[cfg(feature = "alloc")]
109pub mod reliable;
110#[cfg(feature = "alloc")]
111pub mod transport_locator;
112#[cfg(feature = "xml-config")]
113pub mod xml_config;
114
115pub use error::XrceError;
116pub use header::{
117    CLIENT_KEY_LEN, ClientKey, MessageHeader, SESSION_ID_NONE_WITH_CLIENT_KEY,
118    SESSION_ID_NONE_WITHOUT_CLIENT_KEY, SessionId, StreamId,
119};
120pub use serial_number::SerialNumber16;
121pub use submessages::{
122    DOSC_MAX_PAYLOAD_SIZE, DOSC_MAX_SUBMESSAGES, FLAG_E_LITTLE_ENDIAN, Message, Submessage,
123    SubmessageHeader, SubmessageId,
124};
125#[cfg(feature = "std")]
126pub use transport_udp::{
127    XrceUdpSender, agent_default_port, client_default_port, recv_message, send_message,
128};
129
130#[cfg(feature = "alloc")]
131pub use continuous_read::{DeliveryControl, PendingSample, ReadStream};
132#[cfg(feature = "std")]
133pub use discovery::{MulticastDiscovery, XRCE_DISCOVERY_GROUP, XRCE_DISCOVERY_PORT};
134#[cfg(feature = "alloc")]
135pub use fragment::{
136    AssemblerKey, FragmentAssembler, MAX_FRAGMENTS_PER_STREAM, MAX_PENDING_STREAMS,
137    MAX_TOTAL_PAYLOAD,
138};
139#[cfg(feature = "alloc")]
140pub use object_id::{KIND_MASK_BIT, OBJECTID_AGENT, OBJECTID_CLIENT, OBJECTID_INVALID, ObjectId};
141#[cfg(feature = "alloc")]
142pub use object_kind::{
143    OBJK_AGENT, OBJK_APPLICATION, OBJK_CLIENT, OBJK_DATAREADER, OBJK_DATAWRITER, OBJK_DOMAIN,
144    OBJK_INVALID, OBJK_PARTICIPANT, OBJK_PUBLISHER, OBJK_QOSPROFILE, OBJK_SUBSCRIBER, OBJK_TOPIC,
145    OBJK_TYPE, ObjectKind,
146};
147#[cfg(feature = "alloc")]
148pub use object_repr::{ObjectVariant, REPR_MAX_INLINE_BYTES};
149#[cfg(feature = "alloc")]
150pub use object_store::{CreateOutcome, CreationMode, ObjectInstance, ObjectStore};
151#[cfg(feature = "alloc")]
152pub use reliable::{
153    DEFAULT_HEARTBEAT_PERIOD, RECEIVER_BUFFER_CAP, RELIABLE_MAX_PAYLOAD, ReliableConfig,
154    ReliableStreamState, SENDER_WINDOW_CAP,
155};
156#[cfg(feature = "alloc")]
157pub use transport_dtls::{DtlsError, DtlsLayer, DummyDtls};
158#[cfg(feature = "alloc")]
159pub use transport_locator::{
160    TRANSPORT_LOCATOR_SERIAL_DEVICE_MAX, TRANSPORT_LOCATOR_STRING_MAX, TransportLocator,
161    TransportLocatorLarge, TransportLocatorMedium, TransportLocatorSerial, TransportLocatorSmall,
162    TransportLocatorTcp,
163};
164#[cfg(feature = "std")]
165pub use transport_serial::{
166    ESCAPE_BYTE, FLAG_BYTE, STUFF_XOR, SerialError, SerialFramer, crc16_ccitt_false,
167    decode_frame as serial_decode_frame, decode_frame_inner as serial_decode_frame_inner,
168    encode_message as serial_encode_message, encode_payload as serial_encode_payload,
169};
170#[cfg(feature = "std")]
171pub use transport_tcp::{TCP_LENGTH_PREFIX_SIZE, XrceTcpClient, XrceTcpServer};
172#[cfg(feature = "alloc")]
173pub use transport_tls::{XrceTlsClient, XrceTlsServer, XrceTlsStream};
174#[cfg(all(feature = "std", feature = "xml-config"))]
175pub use xml_config::load_xrce_config_from_file;
176#[cfg(feature = "xml-config")]
177pub use xml_config::{
178    CreateMessage, DataReaderConfig, DataWriterConfig, InMemoryQosResolver, MAX_HIERARCHY_DEPTH,
179    MAX_TYPES_PER_FILE, ParticipantConfig, PublisherConfig, QosProfileResolver, SubscriberConfig,
180    TopicConfig, TypeConfig, XrceConfig, XrceXmlError, load_xrce_config,
181};