Skip to main content

msrt_ffi/
lib.rs

1#![doc = "C ABI bindings for MSRT."]
2#![cfg_attr(not(feature = "std"), no_std)]
3#![warn(missing_docs)]
4#![allow(clippy::std_instead_of_core)]
5
6#[cfg(not(feature = "std"))]
7use core::panic::PanicInfo;
8
9mod abi;
10mod config;
11mod constants;
12mod endpoint;
13mod event;
14mod ptr;
15
16pub use config::MsrtConfig;
17pub use constants::*;
18pub use endpoint::{MsrtEndpoint, MsrtEndpointStorage};
19pub use event::{MsrtPollEvent, MsrtReceiveEvent};
20
21#[cfg(not(feature = "std"))]
22#[panic_handler]
23fn panic(_info: &PanicInfo<'_>) -> ! {
24    loop {}
25}
26
27#[cfg(test)]
28mod tests {
29    use core::mem::{align_of, size_of};
30    use core::ptr;
31
32    use super::*;
33    use crate::abi::{
34        msrt_endpoint_connect, msrt_endpoint_deinit, msrt_endpoint_free, msrt_endpoint_new,
35        msrt_endpoint_poll, msrt_endpoint_receive, msrt_endpoint_state,
36    };
37    use crate::endpoint::{endpoint_from_storage, free_storage_endpoint};
38
39    #[test]
40    fn endpoint_storage_layout_is_large_enough() {
41        assert!(size_of::<MsrtEndpoint>() <= ENDPOINT_STORAGE_BYTES);
42        assert!(align_of::<MsrtEndpoint>() <= align_of::<MsrtEndpointStorage>());
43    }
44
45    #[test]
46    fn client_passive_exchange_over_ffi() {
47        unsafe {
48            let (client_storage, client) = endpoint_from_storage(ptr::null());
49
50            let mut passive_config = MsrtConfig::default();
51            passive_config.role = MSRT_ROLE_PASSIVE;
52            let (passive_storage, passive) = endpoint_from_storage(&passive_config);
53
54            assert_eq!(msrt_endpoint_connect(client, 1), MSRT_STATUS_OK);
55
56            let mut event = MsrtPollEvent {
57                kind: MSRT_POLL_IDLE,
58                len: 0,
59                bytes: [0; MAX_EVENT_BYTES],
60                attempts: 0,
61                packet_type: 0,
62                message_id: 0,
63                failure_reason: 0,
64            };
65            assert_eq!(msrt_endpoint_poll(client, 1, &mut event), MSRT_STATUS_OK);
66            assert_eq!(event.kind, MSRT_POLL_TRANSMIT);
67
68            let mut receive = MsrtReceiveEvent {
69                kind: MSRT_RECEIVE_NONE,
70                value: 0,
71            };
72            assert_eq!(
73                msrt_endpoint_receive(passive, 2, event.bytes.as_ptr(), event.len, &mut receive),
74                MSRT_STATUS_OK
75            );
76
77            assert_eq!(msrt_endpoint_poll(passive, 2, &mut event), MSRT_STATUS_OK);
78            assert_eq!(event.kind, MSRT_POLL_TRANSMIT);
79
80            assert_eq!(
81                msrt_endpoint_receive(client, 3, event.bytes.as_ptr(), event.len, &mut receive),
82                MSRT_STATUS_OK
83            );
84            assert_eq!(msrt_endpoint_state(client), MSRT_PEER_CONNECTED);
85
86            free_storage_endpoint(client_storage, client);
87            free_storage_endpoint(passive_storage, passive);
88        }
89    }
90
91    #[test]
92    fn init_and_deinit_symbols_accept_storage_endpoint() {
93        unsafe {
94            let (storage, endpoint) = endpoint_from_storage(ptr::null());
95            assert_eq!(msrt_endpoint_deinit(endpoint), MSRT_STATUS_OK);
96            drop(Box::from_raw(storage));
97        }
98    }
99
100    #[test]
101    fn heap_endpoint_api_is_available_with_std() {
102        unsafe {
103            let endpoint = msrt_endpoint_new(ptr::null());
104            assert!(!endpoint.is_null());
105            msrt_endpoint_free(endpoint);
106        }
107    }
108}