zerodds-rtps
Writer/Reader State-Machines, RTPS-Submessages, Wire-Format-Encoding.
Teil von ZeroDDS. Safety-Klasse SAFE —
forbid(unsafe_code), no_std + alloc.
DDSI-RTPS 2.5 — voll spec-konform (K3b-Audit abgeschlossen 2026-04-28: 121 done / 0 partial / 0 open / 3 n/a).
Quick Start (E2E mit UDP)
use Ipv4Addr;
use BestEffortReader;
use BestEffortWriter;
use ;
use Transport;
use UdpTransport;
let prefix = from_bytes;
let writer_id = user_writer_with_key;
let reader_id = user_reader_with_key;
let writer_xport = bind_v4?;
let reader_xport = bind_v4?;
let dest = reader_xport.local_locator;
let mut writer = new;
let reader = new;
let datagram = writer.write?;
writer_xport.send?;
let received = reader_xport.recv?;
let samples = reader.recv_datagram?;
assert_eq!;
# Ok::
Module
| Modul | Zweck |
|---|---|
error |
WireError-Varianten |
wire_types |
Guid, EntityId, SequenceNumber, Locator, ProtocolVersion, VendorId |
header |
RtpsHeader (20B) + RTPS_MAGIC |
submessage_header |
SubmessageHeader (4B) + SubmessageId-Enum |
submessages |
DATA, DATA_FRAG, HEARTBEAT, HEARTBEAT_FRAG, ACKNACK, NACK_FRAG, GAP, INFO_TS, INFO_SRC, INFO_DST, INFO_REPLY + SequenceNumberSet |
datagram |
encode/decode RTPS-Messages, ParsedSubmessage-Iteration |
writer |
BestEffortWriter (1:1, stateless) |
reader |
BestEffortReader (1:1, mit Wildcard-Match) |
history_cache |
Geordnete CacheChange-Ablage (BTreeMap) + atomare Stats + LockFreeReadHistoryCache |
reader_proxy / writer_proxy |
Per-Endpoint State |
reliable_writer / reliable_reader |
Reliable State-Machines, tick-getrieben |
reliable_stateless_writer |
Stateless-Writer-Variante fuer SPDP |
fragment_assembler |
Reader-seitige Reassembly mit DoS-Caps |
participant_security_info |
PID 0x1005 (DDS-Security 1.2 §7.4.1.6) |
message_builder |
OutboundDatagram-Aggregation pro Send-Tick |
Reliable-Quickstart
use Duration;
use ;
let mut w = new;
let dgs = w.write?;
for dg in dgs
loop
Lock-Free Read-Path & Per-Slot Mutex
Das History-Cache-Modul ist in drei Schichten lock-free aufgebaut:
- Atomic Stats —
HistoryCacheStatsmitAtomicUsize/AtomicI64fürlen/evicted/max_sn/min_sn. Monitoring-Threads pollen viacache.stats() -> Arc<HistoryCacheStats>ohne den Writer-Lock zu nehmen. - Per-Endpoint-Mutex —
dcps::user_writers/user_readersnutzenRwLock<BTreeMap<EntityId, Arc<Mutex<Slot>>>>: pro Writer/Reader ein eigener Mutex statt globalem Lock. - RCU-Snapshot —
LockFreeReadHistoryCachemit&self- Mutationen viazerodds_foundation::rcu::RcuCell(Copy-on-Write Arc-swap). Reader-Snapshots leben unabhängig vom Cache-Lock.
Wire-Format-Konformitaet
DDSI-RTPS 2.5 §8.3 — voll umgesetzt:
- RTPS-Header (§8.3.3): 20 Byte, Magic + Version + VendorId + GuidPrefix
- Submessage-Header (§8.3.4): 4 Byte, ID + Flags + OctetsToNextHeader
- DATA / DATA_FRAG / GAP / HEARTBEAT / HEARTBEAT_FRAG / ACKNACK / NACK_FRAG / INFO_TS / INFO_SRC / INFO_DST / INFO_REPLY
- Cross-Vendor-Wire-Compat byte-identisch gegen Cyclone DDS,
FastDDS, RTI Connext, OpenSplice (siehe
docs/interop/).
Cross-Vendor-Compatibility
- RTPS 2.1 mit 0x80-Submessage (Cyclone/FastDDS-Legacy) —
HeaderExtension wird nur ab Version 2.5 geparst, davor als
Vendor-Specific behandelt. Regression-Test
rtps_2_1_treats_0x80_as_vendor_specific_not_header_extension. fragments_in_submessage > 1(RTI-Bundling) — Decoder akzeptiert; Encoder emittiert 1 Fragment pro Submessage.- HEARTBEAT_FRAG — Decoder bereit, Encoder nicht aktiv (regulaere HEARTBEATs reichen dem Reader).
Tests
E2E-Tests in tests/reliable_e2e.rs decken In-Order-Delivery
mit 0%/10%/30% simuliertem Packet-Loss + 10-kB-Fragmentation
ab.
Documentation
Fuer einen Hot-Path-Trace siehe Documentation Trail Station 02 → data-flow.