zerodds-endpoint-ada 1.0 — Spec Coverage
Source: docs/specs/zerodds-endpoint-ada-1.0.md — ZeroDDS Ada endpoint SDK
spec (DDS-XRCE 1.0 §8.3/§8.4.10/§8.4.11 + reliable-endpoint-1.0); complements
the codegen coverage zerodds-xcdr2-ada.
Implementation:
endpoints/ada/— the Ada endpoint SDK (Stage-1, ADR 0013:Interfaces.Cbindings over the C89 wire corezdw, plus the idiomaticDeep_Readinglayer):src/zdw.ads(wire-core FFI),src/deep_reading.{ads,adb}(codec,Frame/Deframe,Mailbox,Reader_Task),src/reliable.{ads,adb}(reliable state machine + async-decoupled writer),test/{example_sync,example_async,example_reliable}.adb.crates/endpoint-e2e/tests/ada.rs— the live ping-pong E2E against the shared Rust XRCE peer.
§1 XRCE Framing
§1 Endpoint SDK (wire-core binding)
Spec: §1 – “body — the XCDR2-encoded sample, bound via
endpoints/ada/src/zdw.ads (package Zdw, Interfaces.C FFI over the C89 wire
core), byte-identical to the zerodds-cdr reference.”
Repo: endpoints/ada/src/zdw.ads (thin FFI over the C89 wire core,
Put_*/Get_*), deep_reading.{ads,adb} (codec, Frame/Deframe, Mailbox
protected object, Reader_Task).
Tests: endpoints/ada/test/test_byte_identity.adb::Test_Byte_Identity — the marks "negative: a body past Max_Frame refused",
"negative: the largest body still frames" and "ALL OK" against
golden_le.bin/golden_be.bin; driven by
crates/endpoint-e2e/tests/ada.rs::ada_endpoint_sync.
Status: done
§1 WRITE_DATA framing (8-byte header + body)
Spec: §1 – “A WRITE_DATA sample is framed as an 8-byte header + body:
[session][stream][seq_lo][seq_hi][0x07][flags][len_lo][len_hi][body...].
session=0x80, stream=0x01 (best-effort) on the sync/async path,
stream_id >= 128 on the reliable path. Deep_Reading.Frame/Deframe MUST
build resp. parse this frame for the best-effort stream;
Reliable.Write_Frame for the reliable stream.”
Repo: Deep_Reading.Frame / Deframe (best-effort stream 0x01);
Reliable.Write_Frame (reliable stream 0x80) in endpoints/ada/src/reliable.adb.
Tests: endpoints/ada/test/test_udp_loopback.adb — mark
"UDP loopback round-trip ok";
endpoints/ada/test/test_byte_identity.adb::Test_Byte_Identity for the frame octets; the ping-pong and reliable E2E from §2/§3/§4.
Status: done
§2 sync Client
§2 Deep_Reading.Mailbox + example_sync.adb
Spec: §2 – “A blocking receive path over the idiomatic Ada concurrency
primitive: the protected object Deep_Reading.Mailbox. MUST:
Mailbox.Deliver(Frame); Mailbox.Receive(Frame) / Mailbox.Try_Receive(Frame, Success) — the integrator owns the poll/wait loop.”
Repo: Deep_Reading.Mailbox (protected FIFO transport, Deliver/Receive);
example example_sync.adb.
Tests: (Linux) ada_endpoint_sync (crates/endpoint-e2e/tests/ada.rs, Ada
app built via gprbuild over the C89 wire core) — together with
ada_endpoint_async (§3) 2/2 passed.
Status: done
§3 async Reader/Writer
§3 Reader_Task + example_async.adb
Spec: §3 – “A background reader as its own Ada task (Reader_Task) — no
async runtime beyond task/protected object. MUST: Reader_Task drains the
transport, decodes every WRITE_DATA body, deposits it via Mailbox.Deliver; the
calling task blocks on Mailbox.Receive.”
Repo: Reader_Task (background drain, deposits decoded bodies via
Mailbox.Deliver); example example_async.adb (main task blocks on
Inbox.Receive).
Tests: (Linux) ada_endpoint_async (crates/endpoint-e2e/tests/ada.rs,
Ada app built via gprbuild over the C89 wire core) — together with
ada_endpoint_sync (§2) 2/2 passed.
Status: done
§4 reliable Stream
§4 State machine (sender + receiver)
Spec: §4 – “Ada implements the canonical contract (reliable-endpoint-1.0
§3) in endpoints/ada/src/reliable.{ads,adb}: sender —
Submit/Pending_Heartbeat/Recv_Acknack/Get_In_Flight; receiver —
Recv_Data/Drain_Next/Pending_Acknack/Reset.”
Repo: endpoints/ada/src/reliable.{ads,adb}.
Tests: (Linux) test_reliable_unit — monotonic seq, window-full, heartbeat
first/silence/empty, acknack-clear (+full-clear), reorder, duplicate-drop,
buffer-full, pending-acknack bitmap, reset → ALL OK.
Status: done
§4 Wire (byte-golden HEARTBEAT/ACKNACK)
Spec: §4 – “Wire codec — Heartbeat_Frame/Acknack_Frame + the
corresponding Parse_* functions; byte-identical to
golden_heartbeat_le.bin/golden_acknack_le.bin.”
Repo: Reliable.Heartbeat_Frame / Acknack_Frame / Parse_*.
Tests: (Linux) test_reliable_unit asserts Heartbeat_Frame(1,3) ==
golden_heartbeat_le.bin and Acknack_Frame(1,0) == golden_acknack_le.bin →
byte-identical.
Status: done
§4 Async-decoupled writer + loss recovery
Spec: §4 – “Reliable.Send_Ring — a protected ring
(Enqueue/Dequeue/Close) as the async-decoupled writer: the producer only
ever performs a wait-free Enqueue, no syscall; a dedicated drain task
(example_reliable.adb, GNAT.Sockets) owns the socket and the sender state
and performs all the I/O (send, heartbeat, ACKNACK-driven retransmit).”
Repo: Reliable.Send_Ring (protected Enqueue/Dequeue/Close) +
example_reliable.adb (drain task via GNAT.Sockets).
Tests: (Linux)
- ada_reliable_loss_recovery — peer drops every 3rd datagram; app retransmits
on ACKNACK; all 12 samples delivered gap-free in order.
- ada_reliable_baseline — lossless; 12/12.
- Latency micro-bench: producer Enqueue→return 87 ns vs inline
frame+sendto 7338 ns (~84×).
Status: done
Audit-Status
7 done / 0 partial / 0 open / 0 blocked / 0 n/a (informative).
Test-run (Linux, verified): cargo test -p zerodds-endpoint-e2e --test ada
2/2 (ping-pong); --test ada_reliable 3/3 (unit+golden, loss recovery, baseline);
latency bench decoupled 87 ns / inline 7338 ns.
Open items: none.
zerodds-endpoint-ada 1.0 — Spec-Coverage
Quelle: docs/specs/zerodds-endpoint-ada-1.0.md — ZeroDDS Ada-Endpoint-SDK-Spec
(DDS-XRCE 1.0 §8.3/§8.4.10/§8.4.11 + reliable-endpoint-1.0); ergänzt die
Codegen-Coverage zerodds-xcdr2-ada.
Implementation:
endpoints/ada/— das Ada-Endpoint-SDK (Stage-1, ADR 0013:Interfaces.C- Bindings über den C89-Wire-Corezdw, plus die idiomatischeDeep_Reading- Schicht):src/zdw.ads(Wire-Core-FFI),src/deep_reading.{ads,adb}(Codec,Frame/Deframe,Mailbox,Reader_Task),src/reliable.{ads,adb}(reliable State-Machine + async-entkoppelter Writer),test/{example_sync,example_async,example_reliable}.adb.crates/endpoint-e2e/tests/ada.rs— das Live-Ping-Pong-E2E gegen den geteilten Rust-XRCE-Peer.
§1 XRCE-Framing
§1 Endpoint-SDK (Wire-Core-Bindung)
Spec: §1 – “body — das XCDR2-kodierte Sample, gebunden über
endpoints/ada/src/zdw.ads (Package Zdw, Interfaces.C-FFI über den
C89-Wire-Core), byte-identisch zur zerodds-cdr-Referenz.”
Repo: endpoints/ada/src/zdw.ads (dünnes FFI über den C89-Wire-Core,
Put_*/Get_*), deep_reading.{ads,adb} (Codec, Frame/Deframe, Mailbox
protected object, Reader_Task).
Tests: endpoints/ada/test/test_byte_identity.adb::Test_Byte_Identity — die
Marken "negative: a body past Max_Frame refused",
"negative: the largest body still frames" und "ALL OK" gegen
golden_le.bin/golden_be.bin; gefahren über
crates/endpoint-e2e/tests/ada.rs::ada_endpoint_sync.
Status: done
§1 WRITE_DATA-Framing (8-Byte-Header + Body)
Spec: §1 – “Ein WRITE_DATA-Sample wird als 8-Byte-Header + Body gerahmt:
[session][stream][seq_lo][seq_hi][0x07][flags][len_lo][len_hi][body...].
session=0x80, stream=0x01 (best-effort) auf dem Sync/Async-Pfad,
stream_id ≥ 128 auf dem reliable Pfad. Deep_Reading.Frame/Deframe MÜSSEN
diesen Rahmen für den best-effort Stream bauen bzw. parsen; Reliable.Write_Frame
für den reliable Stream.”
Repo: Deep_Reading.Frame / Deframe (best-effort Stream 0x01);
Reliable.Write_Frame (reliable Stream 0x80) in endpoints/ada/src/reliable.adb.
Tests: endpoints/ada/test/test_udp_loopback.adb — Marke
"UDP loopback round-trip ok";
endpoints/ada/test/test_byte_identity.adb::Test_Byte_Identity für die
Rahmen-Oktette; das Ping-Pong- und reliable-E2E aus §2/§3/§4.
Status: done
§2 sync Client
§2 Deep_Reading.Mailbox + example_sync.adb
Spec: §2 – “Ein blockierender Empfangspfad über das idiomatische
Ada-Concurrency-Primitiv: das protected object Deep_Reading.Mailbox. MUSS:
Mailbox.Deliver(Frame); Mailbox.Receive(Frame) / Mailbox.Try_Receive(Frame, Success) — der Integrator besitzt den Poll-/Wait-Loop.”
Repo: Deep_Reading.Mailbox (protected FIFO-Transport, Deliver/Receive);
Beispiel example_sync.adb.
Tests: (Linux) ada_endpoint_sync (crates/endpoint-e2e/tests/ada.rs,
Ada-App via gprbuild über den C89-Wire-Core gebaut) — gemeinsam mit
ada_endpoint_async (§3) 2/2 passed.
Status: done
§3 async Reader/Writer
§3 Reader_Task + example_async.adb
Spec: §3 – “Ein Hintergrund-Reader als eigener Ada-Task (Reader_Task) —
kein Async-Runtime jenseits von task/protected object. MUSS: Reader_Task
drained den Transport, dekodiert jeden WRITE_DATA-Body, legt ihn per
Mailbox.Deliver ab; der aufrufende Task blockiert auf Mailbox.Receive.”
Repo: Reader_Task (Hintergrund-Drain, legt dekodierte Bodies per
Mailbox.Deliver ab); Beispiel example_async.adb (Haupt-Task blockiert auf
Inbox.Receive).
Tests: (Linux) ada_endpoint_async (crates/endpoint-e2e/tests/ada.rs,
Ada-App via gprbuild über den C89-Wire-Core gebaut) — gemeinsam mit
ada_endpoint_sync (§2) 2/2 passed.
Status: done
§4 reliable Stream
§4 State-Machine (Sender + Receiver)
Spec: §4 – “Ada implementiert den kanonischen Vertrag
(reliable-endpoint-1.0 §3) in endpoints/ada/src/reliable.{ads,adb}: Sender —
Submit/Pending_Heartbeat/Recv_Acknack/Get_In_Flight; Receiver —
Recv_Data/Drain_Next/Pending_Acknack/Reset.”
Repo: endpoints/ada/src/reliable.{ads,adb}.
Tests: (Linux) test_reliable_unit — monotone seq, window-full, heartbeat
first/silence/empty, acknack-clear (+full-clear), reorder, duplicate-drop,
buffer-full, pending-acknack-Bitmap, reset → ALL OK.
Status: done
§4 Wire (byte-golden HEARTBEAT/ACKNACK)
Spec: §4 – “Wire-Codec — Heartbeat_Frame/Acknack_Frame + die zugehörigen
Parse_*-Funktionen; byte-identisch zu golden_heartbeat_le.bin/
golden_acknack_le.bin.”
Repo: Reliable.Heartbeat_Frame / Acknack_Frame / Parse_*.
Tests: (Linux) test_reliable_unit assertet Heartbeat_Frame(1,3) ==
golden_heartbeat_le.bin und Acknack_Frame(1,0) == golden_acknack_le.bin →
byte-identisch.
Status: done
§4 Async-entkoppelter Writer + Loss-Recovery
Spec: §4 – “Reliable.Send_Ring — ein protected Ring
(Enqueue/Dequeue/Close) als async-entkoppelter Writer: der Producer macht
nur ein wait-freies Enqueue, kein Syscall; ein dedizierter Drain-Task
(example_reliable.adb, GNAT.Sockets) besitzt Socket und Sender-State und
macht die gesamte I/O (Send, Heartbeat, ACKNACK-getriebenes Retransmit).”
Repo: Reliable.Send_Ring (protected Enqueue/Dequeue/Close) +
example_reliable.adb (Drain-Task via GNAT.Sockets).
Tests: (Linux)
- ada_reliable_loss_recovery — Peer dropt jedes 3. Datagramm; App retransmittet
auf ACKNACK; alle 12 Samples lückenlos in-order geliefert.
- ada_reliable_baseline — lossless; 12/12.
- Latenz-Micro-Bench: Producer Enqueue→return 87 ns vs. inline
frame+sendto 7338 ns (~84×).
Status: done
Audit-Status
7 done / 0 partial / 0 open / 0 blocked / 0 n/a (informative).
Test-Lauf: Linux, verifiziert — cargo test -p zerodds-endpoint-e2e --test ada
2/2 (Ping-Pong); --test ada_reliable 3/3 (Unit+Golden, Loss-Recovery, Baseline);
Latenz-Bench decoupled 87 ns / inline 7338 ns.
Offene Punkte: keine.