native-endpoints

ADR 0013 — Native endpoint SDKs. Conservative, no-Rust DDS-XRCE endpoints in C89 / Python / Java for constrained, legacy and big-endian platforms a full Rust stack cannot reach.

Wire

The Rust core is the reference; each endpoint SDK re-encodes the identical bytes. Every encoder is checked byte-for-byte against golden vectors from the Rust core (zerodds-cdr + zerodds-xrce), on little-endian x86-64 and on big-endian PowerPC (under qemu), with -Werror across gcc, g++ and clang. Serialization uses explicit byte shifts, so the output does not depend on host endianness.

  • XCDR2 primitives, strings, sequences; extensibility trio final / appendable (DHEADER) / mutable (EMHEADER).
  • DDS-XRCE WRITE_DATA / DATA (publish + receive), plus HEARTBEAT / ACKNACK for the reliable stream.
  • Serial framing (Annex C, RFC 1662 HDLC): byte-stuffing + CRC-16-CCITT.

Two wire backends

  • wire-fixed — IDL → generated C / Python / Java codec. No runtime type info.
  • wire-variable — reflective codec driven by a type description at runtime, for endpoints that carry many types or discover them late.

Feature levels

Two levels:

  • full — POSIX (C) or the JVM (Java) provide the transport; UDP publish and receive work out of the box.
  • hook — the wire and framing are complete; putting a frame on the link is a hook the integrator fills with the target's transport. The frame-hook (zdw_transport) is the single mandatory integration point.

Feature sets are additive: linkable libraries, extra Python imports, additional JARs.

Quickstart

C endpoint: encode a sample, frame it as XRCE WRITE_DATA, and hand the frame to the transport the integrator wired into zdw_transport.

#include "zerodds_endpoint.h"

unsigned char body[256], frame[512];
zdw_writer w;
zdw_writer_init(&w, body, sizeof body, ZDW_LE);   /* wire byte order */
zdw_put_u32(&w, 0xA1B2C3D4uL);        /* sensor id */
zdw_put_string(&w, "bay-12");         /* label     */
zdw_put_f32(&w, 3.5f);                /* value     */

/* frame the XCDR body as an XRCE WRITE_DATA (Sample) */
size_t flen = zdw_xrce_write_frame(frame, sizeof frame,
                                   ZDW_XRCE_SESSION_NOKEY,
                                   ZDW_XRCE_STREAM_BEST_EFFORT,
                                   1, body, w.len);

/* deliver through the frame-hook (here: a UDP socket) */
zdw_endpoint_send(&t, frame, flen);

Runnable C / Python / Java publishers and receivers — talking to a real zerodds-xrce hub over UDP, both directions — are in endpoints/examples and in the snippets repository.

See also

Stability

1.0.0-rc.6. Languages: C89, C++98, pure Python, Java 8 — no Rust on the endpoint. Wire format fixed by DDS-XRCE 1.0 + OMG XCDR2.

native-endpoints

ADR 0013 — Native Endpoint-SDKs. Konservative, Rust-freie DDS-XRCE-Endpoints in C89 / Python / Java für eingeschränkte, alte und Big-Endian-Plattformen, die ein voller Rust-Stack nicht erreicht.

Wire

Der Rust-Core ist die Referenz; jedes Endpoint-SDK enkodiert die identischen Bytes. Jeder Encoder wird Byte für Byte gegen Golden-Vektoren aus dem Rust-Core (zerodds-cdr + zerodds-xrce) geprüft, auf Little-Endian-x86-64 und auf Big-Endian-PowerPC (unter qemu), mit -Werror über gcc, g++ und clang. Die Serialisierung nutzt explizite Byte-Shifts, die Ausgabe hängt also nicht von der Host-Endianness ab.

  • XCDR2-Primitive, Strings, Sequenzen; Extensibility-Trias final / appendable (DHEADER) / mutable (EMHEADER).
  • DDS-XRCE WRITE_DATA / DATA (publish + receive), dazu HEARTBEAT / ACKNACK für den zuverlässigen Stream.
  • Serial-Framing (Annex C, RFC 1662 HDLC): Byte-Stuffing + CRC-16-CCITT.

Zwei Wire-Backends

  • wire-fixed — IDL → generierter C-/Python-/Java-Codec. Keine Laufzeit-Typinfo.
  • wire-variable — reflektiver Codec, zur Laufzeit über eine Typbeschreibung gesteuert, für Endpoints mit vielen oder spät entdeckten Typen.

Feature-Level

Zwei Level:

  • full — POSIX (C) oder die JVM (Java) liefern den Transport; UDP-Publish und -Receive laufen out of the box.
  • hook — Wire und Framing sind vollständig; das Auf-die-Leitung-Bringen eines Frames ist ein Hook, den der Integrator mit dem Transport seines Ziels füllt. Der Frame-Hook (zdw_transport) ist der einzige verpflichtende Integrationspunkt.

Feature-Sets sind additiv: linkbare Libraries, zusätzliche Python-Imports, weitere JARs.

Quickstart

C-Endpoint: ein Sample enkodieren, als XRCE-WRITE_DATA framen und den Frame an den Transport übergeben, den der Integrator in zdw_transport verdrahtet hat.

#include "zerodds_endpoint.h"

unsigned char body[256], frame[512];
zdw_writer w;
zdw_writer_init(&w, body, sizeof body, ZDW_LE);   /* Wire-Byte-Order */
zdw_put_u32(&w, 0xA1B2C3D4uL);        /* Sensor-ID */
zdw_put_string(&w, "bay-12");         /* Label     */
zdw_put_f32(&w, 3.5f);                /* Wert      */

/* den XCDR-Body als XRCE WRITE_DATA (Sample) framen */
size_t flen = zdw_xrce_write_frame(frame, sizeof frame,
                                   ZDW_XRCE_SESSION_NOKEY,
                                   ZDW_XRCE_STREAM_BEST_EFFORT,
                                   1, body, w.len);

/* über den Frame-Hook ausliefern (hier: ein UDP-Socket) */
zdw_endpoint_send(&t, frame, flen);

Lauffähige C-/Python-/Java-Publisher und -Receiver — gegen einen echten zerodds-xrce-Hub über UDP, in beide Richtungen — liegen in endpoints/examples und im Snippets-Repository.

Siehe auch

Stabilität

1.0.0-rc.6. Sprachen: C89, C++98, pure Python, Java 8 — kein Rust am Endpoint. Wire-Format durch DDS-XRCE 1.0 + OMG XCDR2 fixiert.