Skip to main content

adamo_sys/
lib.rs

1//! Raw FFI bindings to the Adamo SDK.
2//!
3//! This crate is a thin, `unsafe` interface — prefer the safe wrappers in
4//! [`adamo`](https://docs.rs/adamo) for normal use.
5//!
6//! All declarations match the C header generated by `cbindgen` for the
7//! `adamo-c` crate (`include/adamo/adamo.h`). Keep them in sync.
8
9#![allow(non_camel_case_types)]
10#![allow(clippy::missing_safety_doc)]
11
12use std::os::raw::{c_char, c_int, c_void};
13
14pub type adamo_protocol_t = u32;
15pub const ADAMO_PROTOCOL_UDP: adamo_protocol_t = 0;
16pub const ADAMO_PROTOCOL_QUIC: adamo_protocol_t = 1;
17pub const ADAMO_PROTOCOL_TCP: adamo_protocol_t = 2;
18
19pub type adamo_regime_t = u32;
20pub const ADAMO_REGIME_STABLE: adamo_regime_t = 0;
21pub const ADAMO_REGIME_DEGRADING: adamo_regime_t = 1;
22pub const ADAMO_REGIME_VOLATILE: adamo_regime_t = 2;
23pub const ADAMO_REGIME_RECOVERING: adamo_regime_t = 3;
24
25// Opaque handles. Zero-sized placeholders — callers only ever see pointers
26// to them. `PhantomData<*mut ()>` keeps them `!Send + !Sync` by default;
27// the safe wrapper re-asserts thread-safety where the C API documents it.
28#[repr(C)]
29pub struct adamo_session_t {
30    _priv: [u8; 0],
31    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
32}
33#[repr(C)]
34pub struct adamo_publisher_t {
35    _priv: [u8; 0],
36    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
37}
38#[repr(C)]
39pub struct adamo_subscriber_t {
40    _priv: [u8; 0],
41    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
42}
43#[repr(C)]
44pub struct adamo_cb_sub_t {
45    _priv: [u8; 0],
46    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
47}
48#[repr(C)]
49pub struct adamo_liveliness_token_t {
50    _priv: [u8; 0],
51    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
52}
53#[repr(C)]
54pub struct adamo_liveliness_sub_t {
55    _priv: [u8; 0],
56    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
57}
58#[repr(C)]
59pub struct adamo_robot_t {
60    _priv: [u8; 0],
61    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
62}
63#[repr(C)]
64pub struct adamo_video_track_t {
65    _priv: [u8; 0],
66    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
67}
68
69#[repr(C)]
70pub struct adamo_sample_t {
71    pub key: *mut c_char,
72    pub payload: *mut u8,
73    pub payload_len: usize,
74    pub is_delete: i32,
75    pub timestamp_us: u64,
76}
77
78#[repr(C)]
79pub struct adamo_latency_stats_t {
80    pub regime: adamo_regime_t,
81    pub jitter_hint_ms: f32,
82    pub garch_sigma_ms: f32,
83    pub target_bitrate_kbps: u32,
84    pub loss_rate: f32,
85    pub queuing_delay_ms: f32,
86    pub timestamp_ms: u64,
87}
88
89pub type adamo_sample_cb_t =
90    Option<unsafe extern "C" fn(sample: *const adamo_sample_t, user: *mut c_void)>;
91pub type adamo_liveliness_cb_t =
92    Option<unsafe extern "C" fn(key: *const c_char, alive: c_int, user: *mut c_void)>;
93
94// docs.rs builds can't link libadamo; stub the extern block out there so
95// rustdoc still succeeds.
96#[cfg(not(docsrs))]
97unsafe extern "C" {
98    pub fn adamo_last_error() -> *const c_char;
99
100    pub fn adamo_sample_free(sample: *mut adamo_sample_t);
101
102    pub fn adamo_open(api_key: *const c_char, protocol: adamo_protocol_t) -> *mut adamo_session_t;
103    pub fn adamo_open_default(api_key: *const c_char) -> *mut adamo_session_t;
104    pub fn adamo_session_free(sess: *mut adamo_session_t);
105    pub fn adamo_session_org(sess: *const adamo_session_t) -> *const c_char;
106    pub fn adamo_session_org_len(sess: *const adamo_session_t) -> usize;
107
108    pub fn adamo_put(
109        sess: *const adamo_session_t,
110        key: *const c_char,
111        payload: *const u8,
112        payload_len: usize,
113        priority: u8,
114        express: i32,
115    ) -> i32;
116
117    pub fn adamo_publisher(
118        sess: *const adamo_session_t,
119        key: *const c_char,
120        priority: u8,
121        express: i32,
122        reliable: i32,
123    ) -> *mut adamo_publisher_t;
124    pub fn adamo_publisher_put(
125        pub_: *const adamo_publisher_t,
126        payload: *const u8,
127        payload_len: usize,
128    ) -> i32;
129    pub fn adamo_publisher_free(pub_: *mut adamo_publisher_t);
130
131    pub fn adamo_subscribe(
132        sess: *const adamo_session_t,
133        key: *const c_char,
134    ) -> *mut adamo_subscriber_t;
135    pub fn adamo_sub_recv(
136        sub: *const adamo_subscriber_t,
137        timeout_ms: u64,
138    ) -> *mut adamo_sample_t;
139    pub fn adamo_sub_try_recv(sub: *const adamo_subscriber_t) -> *mut adamo_sample_t;
140    pub fn adamo_sub_free(sub: *mut adamo_subscriber_t);
141
142    pub fn adamo_subscribe_cb(
143        sess: *const adamo_session_t,
144        key: *const c_char,
145        cb: adamo_sample_cb_t,
146        user: *mut c_void,
147    ) -> *mut adamo_cb_sub_t;
148    pub fn adamo_cb_sub_free(sub: *mut adamo_cb_sub_t);
149
150    pub fn adamo_get(
151        sess: *const adamo_session_t,
152        key: *const c_char,
153        timeout_ms: u64,
154        count_out: *mut usize,
155    ) -> *mut *mut adamo_sample_t;
156    pub fn adamo_get_replies_free(replies: *mut *mut adamo_sample_t, count: usize);
157
158    pub fn adamo_liveliness_declare(
159        sess: *const adamo_session_t,
160        token_key: *const c_char,
161    ) -> *mut adamo_liveliness_token_t;
162    pub fn adamo_liveliness_token_free(tok: *mut adamo_liveliness_token_t);
163    pub fn adamo_liveliness_get(
164        sess: *const adamo_session_t,
165        pattern: *const c_char,
166        count_out: *mut usize,
167    ) -> *mut *mut c_char;
168    pub fn adamo_liveliness_tokens_free(tokens: *mut *mut c_char, count: usize);
169    pub fn adamo_liveliness_subscribe(
170        sess: *const adamo_session_t,
171        pattern: *const c_char,
172        history: c_int,
173        cb: adamo_liveliness_cb_t,
174        user: *mut c_void,
175    ) -> *mut adamo_liveliness_sub_t;
176    pub fn adamo_liveliness_sub_free(sub: *mut adamo_liveliness_sub_t);
177
178    pub fn adamo_robot_new(
179        api_key: *const c_char,
180        name: *const c_char,
181        protocol: adamo_protocol_t,
182    ) -> *mut adamo_robot_t;
183    pub fn adamo_robot_new_default(
184        api_key: *const c_char,
185        name: *const c_char,
186    ) -> *mut adamo_robot_t;
187    pub fn adamo_robot_video(
188        robot: *mut adamo_robot_t,
189        name: *const c_char,
190        width: u32,
191        height: u32,
192        pixel_format: *const c_char,
193        fps: u32,
194        bitrate_kbps: u32,
195        stereo: bool,
196    ) -> *mut adamo_video_track_t;
197    pub fn adamo_robot_video_with_options(
198        robot: *mut adamo_robot_t,
199        name: *const c_char,
200        width: u32,
201        height: u32,
202        pixel_format: *const c_char,
203        fps: u32,
204        bitrate_kbps: u32,
205        stereo: bool,
206        encoder: *const c_char,
207        hw_pipeline: bool,
208    ) -> *mut adamo_video_track_t;
209    pub fn adamo_robot_attach_video_v4l2(
210        robot: *mut adamo_robot_t,
211        name: *const c_char,
212        device: *const c_char,
213        width: u32,
214        height: u32,
215        fps: u32,
216        bitrate_kbps: u32,
217        stereo: bool,
218    ) -> i32;
219    pub fn adamo_robot_attach_video_gst(
220        robot: *mut adamo_robot_t,
221        name: *const c_char,
222        pipeline: *const c_char,
223        width: u32,
224        height: u32,
225        fps: u32,
226        bitrate_kbps: u32,
227        stereo: bool,
228    ) -> i32;
229    pub fn adamo_robot_attach_video_shm(
230        robot: *mut adamo_robot_t,
231        name: *const c_char,
232        service: *const c_char,
233        width: u32,
234        height: u32,
235        pixel_format: *const c_char,
236        fps: u32,
237        bitrate_kbps: u32,
238        stereo: bool,
239    ) -> i32;
240    pub fn adamo_video_track_send(
241        track: *mut adamo_video_track_t,
242        payload: *const u8,
243        payload_len: usize,
244    ) -> i32;
245    pub fn adamo_video_track_free(track: *mut adamo_video_track_t);
246    pub fn adamo_robot_run(robot: *mut adamo_robot_t) -> i32;
247    pub fn adamo_robot_free(robot: *mut adamo_robot_t);
248
249    pub fn adamo_detect_encoder() -> *const c_char;
250
251    pub fn adamo_fabric_now_us() -> u64;
252    pub fn adamo_fabric_synced() -> i32;
253    pub fn adamo_relay_rtt_us(sess: *const adamo_session_t, out_us: *mut u64) -> i32;
254
255    pub fn adamo_parse_heartbeat(
256        payload: *const u8,
257        payload_len: usize,
258        out: *mut adamo_latency_stats_t,
259    ) -> i32;
260    pub fn adamo_heartbeat_topic(
261        robot: *const c_char,
262        out: *mut c_char,
263        out_cap: usize,
264    ) -> isize;
265    pub fn adamo_ping_topic(
266        robot: *const c_char,
267        out: *mut c_char,
268        out_cap: usize,
269    ) -> isize;
270    pub fn adamo_pong_topic(
271        robot: *const c_char,
272        out: *mut c_char,
273        out_cap: usize,
274    ) -> isize;
275    pub fn adamo_measure_rtt(
276        sess: *const adamo_session_t,
277        robot: *const c_char,
278        timeout_ms: u64,
279        out_us: *mut u64,
280    ) -> i32;
281}
282
283// Silence `unused_imports` if someone pulls in the crate without calling
284// anything (e.g. docs builds).
285#[doc(hidden)]
286pub const _IMPORTS: (Option<c_int>, Option<*mut c_void>) = (None, None);