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.C bindings over the C89 wire core zdw, plus the idiomatic Deep_Reading layer): 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-Core zdw, plus die idiomatische Deep_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.