Skip to main content

msrt_ffi/
event.rs

1//! C-compatible poll and receive events.
2
3use msrt::endpoint::{EndpointPoll, ReceiveReport};
4use msrt::error::{Error, ErrorKind};
5
6use crate::constants::{
7    MAX_EVENT_BYTES, MSRT_POLL_IDLE, MSRT_POLL_MESSAGE, MSRT_POLL_SEND_FAILED, MSRT_POLL_TRANSMIT,
8    MSRT_RECEIVE_ACK, MSRT_RECEIVE_CORRUPTED, MSRT_RECEIVE_DUPLICATE, MSRT_RECEIVE_ERROR,
9    MSRT_RECEIVE_INCOMPLETE, MSRT_RECEIVE_NOISE, MSRT_RECEIVE_PACKET, MSRT_RECEIVE_PING,
10    MSRT_RECEIVE_PONG,
11};
12
13/// C-compatible poll event.
14#[repr(C)]
15#[derive(Clone, Copy, Debug)]
16pub struct MsrtPollEvent {
17    /// Event kind: one of `MSRT_POLL_*`.
18    pub kind: u32,
19    /// Number of valid bytes in `bytes`.
20    pub len: usize,
21    /// Event byte storage for transmit bytes or received messages.
22    pub bytes: [u8; MAX_EVENT_BYTES],
23    /// Send attempt count for transmit events.
24    pub attempts: u8,
25    /// Packet type from MSRT for message or send-failed events.
26    pub packet_type: u8,
27    /// Message identifier for message or send-failed events.
28    pub message_id: u32,
29    /// Failure reason for send-failed events.
30    pub failure_reason: u32,
31}
32
33/// C-compatible receive report.
34#[repr(C)]
35#[derive(Clone, Copy, Debug)]
36pub struct MsrtReceiveEvent {
37    /// Receive kind: one of `MSRT_RECEIVE_*`.
38    pub kind: u32,
39    /// Packet index, skipped byte count, needed byte count, or error kind.
40    pub value: usize,
41}
42
43impl MsrtPollEvent {
44    /// Creates an idle C poll event.
45    pub(crate) const fn idle() -> Self {
46        Self {
47            kind: MSRT_POLL_IDLE,
48            len: 0,
49            bytes: [0; MAX_EVENT_BYTES],
50            attempts: 0,
51            packet_type: 0,
52            message_id: 0,
53            failure_reason: 0,
54        }
55    }
56}
57
58/// Converts an MSRT receive report into a C receive event.
59pub(crate) fn receive_event(report: ReceiveReport) -> MsrtReceiveEvent {
60    match report {
61        ReceiveReport::Packet { packet_index } => MsrtReceiveEvent {
62            kind: MSRT_RECEIVE_PACKET,
63            value: usize::from(packet_index.get()),
64        },
65        ReceiveReport::Duplicate { packet_index } => MsrtReceiveEvent {
66            kind: MSRT_RECEIVE_DUPLICATE,
67            value: usize::from(packet_index.get()),
68        },
69        ReceiveReport::Ack { packet_index } => MsrtReceiveEvent {
70            kind: MSRT_RECEIVE_ACK,
71            value: usize::from(packet_index.get()),
72        },
73        ReceiveReport::Ping => MsrtReceiveEvent {
74            kind: MSRT_RECEIVE_PING,
75            value: 0,
76        },
77        ReceiveReport::Pong => MsrtReceiveEvent {
78            kind: MSRT_RECEIVE_PONG,
79            value: 0,
80        },
81        ReceiveReport::Noise { skipped } => MsrtReceiveEvent {
82            kind: MSRT_RECEIVE_NOISE,
83            value: skipped,
84        },
85        ReceiveReport::Corrupted => MsrtReceiveEvent {
86            kind: MSRT_RECEIVE_CORRUPTED,
87            value: 0,
88        },
89        ReceiveReport::Incomplete { needed } => MsrtReceiveEvent {
90            kind: MSRT_RECEIVE_INCOMPLETE,
91            value: needed.unwrap_or(0),
92        },
93        ReceiveReport::Error(error) => MsrtReceiveEvent {
94            kind: MSRT_RECEIVE_ERROR,
95            value: error_kind(error),
96        },
97    }
98}
99
100/// Converts an MSRT endpoint poll into a C poll event.
101pub(crate) fn poll_event(poll: EndpointPoll<'_>) -> MsrtPollEvent {
102    let mut event = MsrtPollEvent::idle();
103    match poll {
104        EndpointPoll::Transmit { bytes, attempts } => {
105            event.kind = MSRT_POLL_TRANSMIT;
106            copy_bytes(&mut event, bytes);
107            event.attempts = attempts;
108        }
109        EndpointPoll::Message(message) => {
110            event.kind = MSRT_POLL_MESSAGE;
111            copy_bytes(&mut event, message.as_bytes());
112            event.packet_type = message.packet_type.code();
113            event.message_id = message.message_id.get();
114        }
115        EndpointPoll::SendFailed(failed) => {
116            event.kind = MSRT_POLL_SEND_FAILED;
117            event.packet_type = failed.packet_type.code();
118            event.message_id = failed.message_id.get();
119            event.failure_reason = 1;
120        }
121        EndpointPoll::Idle => {}
122    }
123
124    event
125}
126
127fn copy_bytes(event: &mut MsrtPollEvent, bytes: &[u8]) {
128    let len = bytes.len().min(event.bytes.len());
129    event.bytes[..len].copy_from_slice(&bytes[..len]);
130    event.len = len;
131}
132
133fn error_kind(error: Error) -> usize {
134    match error.kind() {
135        ErrorKind::Malformed => 1,
136        ErrorKind::BufferTooSmall => 2,
137        ErrorKind::Packet => 3,
138        ErrorKind::Reliability => 4,
139        ErrorKind::Channel => 5,
140        ErrorKind::Engine => 6,
141        ErrorKind::Unsupported => 7,
142    }
143}