/* lumen-core C ABI — see crates/lumen-core/src/abi.rs */ #ifndef LUMEN_CORE_H #define LUMEN_CORE_H #pragma once /* Generated by cbindgen from lumen-core. Do not edit by hand. */ #include #include #include #include // Bump on any breaking change to the [C ABI](crate::abi). Mirrors // `lumen_abi_version()` and is checked by clients before use. #define ABI_VERSION 1 // 16-byte AEAD authentication tag appended by GCM. #define TAG_LEN 16 // Wire tag distinguishing an input datagram from a video packet. #define INPUT_MAGIC 200 // Fixed serialized size of an [`InputEvent`] on the wire (tag + fields). #define INPUT_WIRE_LEN (((((1 + 1) + 4) + 4) + 4) + 4) // Identifies a lumen video packet (vs. an input datagram, see [`crate::input`]). #define LUMEN_MAGIC 201 #define FLAG_PIC 1 #define FLAG_EOF 2 #define FLAG_SOF 4 // Largest UDP datagram the core will send or accept. `Config::validate` bounds // `shard_payload` so `HEADER_LEN + shard_payload + CRYPTO_OVERHEAD ≤ MAX_DATAGRAM_BYTES`. #define MAX_DATAGRAM_BYTES 2048 // Stable C ABI status codes. `Ok` is 0; all errors are negative so callers can // test `rc < 0`. Do not renumber existing variants — only append. enum LumenStatus #if defined(__cplusplus) || __STDC_VERSION__ >= 202311L : int32_t #endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L { LUMEN_STATUS_OK = 0, LUMEN_STATUS_INVALID_ARG = -1, LUMEN_STATUS_FEC = -2, LUMEN_STATUS_CRYPTO = -3, LUMEN_STATUS_BAD_PACKET = -4, LUMEN_STATUS_NO_FRAME = -5, LUMEN_STATUS_UNSUPPORTED = -6, LUMEN_STATUS_IO = -7, LUMEN_STATUS_NULL_POINTER = -8, LUMEN_STATUS_TIMEOUT = -9, LUMEN_STATUS_CLOSED = -10, LUMEN_STATUS_PANIC = -99, }; #ifndef __cplusplus #if __STDC_VERSION__ >= 202311L typedef enum LumenStatus LumenStatus; #else typedef int32_t LumenStatus; #endif // __STDC_VERSION__ >= 202311L #endif // __cplusplus // Kinds of input event. `#[repr(u8)]` so it crosses the C ABI as a byte tag. enum LumenInputKind #if defined(__cplusplus) || __STDC_VERSION__ >= 202311L : uint8_t #endif // defined(__cplusplus) || __STDC_VERSION__ >= 202311L { LUMEN_INPUT_KIND_KEY_DOWN = 0, LUMEN_INPUT_KIND_KEY_UP = 1, // Relative motion: `x`/`y` carry `dx`/`dy`. LUMEN_INPUT_KIND_MOUSE_MOVE = 2, // Absolute motion: `x`/`y` carry pixel coordinates. LUMEN_INPUT_KIND_MOUSE_MOVE_ABS = 3, LUMEN_INPUT_KIND_MOUSE_BUTTON_DOWN = 4, LUMEN_INPUT_KIND_MOUSE_BUTTON_UP = 5, // `x` carries the (signed) scroll delta. LUMEN_INPUT_KIND_MOUSE_SCROLL = 6, LUMEN_INPUT_KIND_GAMEPAD_BUTTON = 7, // `code` = axis id, `x` = axis value. LUMEN_INPUT_KIND_GAMEPAD_AXIS = 8, }; #ifndef __cplusplus #if __STDC_VERSION__ >= 202311L typedef enum LumenInputKind LumenInputKind; #else typedef uint8_t LumenInputKind; #endif // __STDC_VERSION__ >= 202311L #endif // __cplusplus #if defined(LUMEN_FEATURE_QUIC) // Opaque handle to a live `lumen/1` connection (QUIC control plane + UDP data plane, all // pumped on internal threads). typedef struct LumenConnection LumenConnection; #endif // Opaque session handle. Pointer-only from C. typedef struct LumenSession LumenSession; // Forward-compatible session configuration. The caller MUST set `struct_size` to // `sizeof(LumenConfig)`; the core uses it to detect ABI skew. typedef struct { uint32_t struct_size; // 0 = host, 1 = client. uint32_t role; // 1 = P1 (GameStream-compatible), 2 = P2 (`lumen/1`). uint32_t phase; // 0 = GF(2⁸), 1 = GF(2¹⁶). uint32_t fec_scheme; uint32_t fec_percent; uint32_t max_data_per_block; uint32_t shard_payload; // Non-zero enables AES-128-GCM. uint32_t encrypt; uint8_t key[16]; uint8_t salt[4]; // Test hook for the loopback transport; 0 in production. uint32_t loopback_drop_period; // Largest encoded access unit the receiver will accept (bounds reassembler memory). uint64_t max_frame_bytes; } LumenConfig; // A reassembled access unit. `data`/`len` borrow session-owned memory valid until the // next `lumen_client_poll_frame`/`lumen_session_free` on the same session. typedef struct { const uint8_t *data; uintptr_t len; uint32_t frame_index; uint64_t pts_ns; uint32_t flags; } LumenFrame; // A single input event. `#[repr(C)]` — shared verbatim with the C ABI as // `LumenInputEvent`. typedef struct { LumenInputKind kind; uint8_t _pad[3]; // keycode / button id / axis id, depending on `kind`. uint32_t code; // x / dx / abs-x / axis-value / scroll-delta, depending on `kind`. int32_t x; // y / dy / abs-y, depending on `kind`. int32_t y; // modifier bitmask or gamepad index. uint32_t flags; } LumenInputEvent; // Snapshot of session counters. typedef struct { uint64_t frames_submitted; uint64_t frames_completed; uint64_t frames_dropped; uint64_t packets_sent; uint64_t packets_received; uint64_t packets_dropped; uint64_t fec_recovered_shards; uint64_t bytes_sent; uint64_t bytes_received; } LumenStats; #ifdef __cplusplus extern "C" { #endif // __cplusplus // Current ABI version. Mismatch with [`crate::ABI_VERSION`] means incompatible core. uint32_t lumen_abi_version(void); // Create a session over a real UDP transport (`local`/`peer` are `host:port` strings). // Returns NULL on error. // // # Safety // `cfg`, `local`, `peer` must be valid pointers; the strings must be NUL-terminated. LumenSession *lumen_session_new(const LumenConfig *cfg, const char *local, const char *peer); // Create a connected host+client session pair sharing an in-process loopback // transport. Test/dev only — exercises the full FEC + framing path without a network. // // # Safety // All four pointers must be valid; the two out-params receive owned handles. LumenStatus lumen_test_loopback_pair(const LumenConfig *host_cfg, const LumenConfig *client_cfg, LumenSession **out_host, LumenSession **out_client); // Free a session handle. Safe to call with NULL. // // # Safety // `s` must be a handle from `lumen_session_new`/`lumen_test_loopback_pair`, freed once. void lumen_session_free(LumenSession *s); // Host: FEC-protect, packetize, seal and send one encoded access unit. // // # Safety // `s` is a valid host handle; `data` points to `len` readable bytes (or `len == 0`). LumenStatus lumen_host_submit_frame(LumenSession *s, const uint8_t *data, uintptr_t len, uint64_t pts_ns, uint32_t flags); // Client: poll for the next reassembled access unit. Returns [`LumenStatus::NoFrame`] // when nothing is ready yet. On `Ok`, `*out` borrows session memory until the next poll. // // # Safety // `s` is a valid client handle; `out` points to a writable `LumenFrame`. LumenStatus lumen_client_poll_frame(LumenSession *s, LumenFrame *out); // Client: serialize and send one input event to the host. // // # Safety // `s` is a valid client handle; `ev` points to a valid [`InputEvent`]. LumenStatus lumen_send_input(LumenSession *s, const LumenInputEvent *ev); // Register the host-side input callback (pass a NULL fn pointer to clear). The callback // fires from within [`lumen_host_poll_input`], on the calling thread. // // # Safety // `s` is a valid host handle; `user` is passed back verbatim to `cb`. LumenStatus lumen_set_input_callback(LumenSession *s, void (*cb)(const LumenInputEvent *event, void *user), void *user); // Host: drain all pending input events, invoking the registered callback for each. // Returns the count dispatched (≥ 0), or a negative [`LumenStatus`] on error. // // # Safety // `s` is a valid host handle. int32_t lumen_host_poll_input(LumenSession *s); // Copy session counters into `*out`. // // # Safety // `s` is a valid handle; `out` points to a writable `LumenStats`. LumenStatus lumen_get_stats(LumenSession *s, LumenStats *out); #if defined(LUMEN_FEATURE_QUIC) // Connect to a `lumen/1` host and start a session at `width`x`height`@`refresh_hz`. // Blocks up to `timeout_ms` for the handshake. Returns NULL on failure. // // # Safety // `host` is a NUL-terminated UTF-8 string (IP or hostname resolvable by the platform). LumenConnection *lumen_connect(const char *host, uint16_t port, uint32_t width, uint32_t height, uint32_t refresh_hz, uint32_t timeout_ms); #endif #if defined(LUMEN_FEATURE_QUIC) // Pull the next reassembled access unit, waiting up to `timeout_ms`. Returns // [`LumenStatus::NoFrame`] on timeout and [`LumenStatus::Closed`] once the session ended. // On `Ok`, `*out` borrows connection memory **until the next call** on this handle. // // # Safety // `c` is a valid connection handle used from a single thread; `out` is writable. LumenStatus lumen_connection_next_au(LumenConnection *c, LumenFrame *out, uint32_t timeout_ms); #endif #if defined(LUMEN_FEATURE_QUIC) // Send one input event to the host as a QUIC datagram (non-blocking enqueue). // // # Safety // `c` is a valid connection handle; `ev` points to a valid [`InputEvent`]. LumenStatus lumen_connection_send_input(LumenConnection *c, const LumenInputEvent *ev); #endif #if defined(LUMEN_FEATURE_QUIC) // The host-confirmed session mode (from the Welcome). Safe any time after connect. // // # Safety // `c` is a valid connection handle; out pointers are writable (NULLs are skipped). LumenStatus lumen_connection_mode(const LumenConnection *c, uint32_t *width, uint32_t *height, uint32_t *refresh_hz); #endif #if defined(LUMEN_FEATURE_QUIC) // Close the connection and free the handle (joins the internal threads). NULL is a no-op. // // # Safety // `c` was returned by [`lumen_connect`] and is not used after this call. void lumen_connection_close(LumenConnection *c); #endif #ifdef __cplusplus } // extern "C" #endif // __cplusplus #endif /* LUMEN_CORE_H */