Skip to main content

msrt_ffi/
config.rs

1//! C-compatible endpoint configuration.
2
3use msrt::endpoint::{EngineConfig, IntegrityConfig, MessageId};
4
5use crate::constants::{
6    MSRT_INTEGRITY_CRC16, MSRT_INTEGRITY_CRC32, MSRT_INTEGRITY_CRC64,
7    MSRT_INTEGRITY_SIP_TAG_DEFAULT, MSRT_INTEGRITY_SIP_TAG_KEY, MSRT_ROLE_CLIENT,
8};
9
10/// C-compatible endpoint configuration.
11#[repr(C)]
12#[derive(Clone, Copy, Debug)]
13pub struct MsrtConfig {
14    /// Endpoint role: `MSRT_ROLE_CLIENT` or `MSRT_ROLE_PASSIVE`.
15    pub role: u32,
16    /// First message identifier used by the endpoint.
17    pub initial_message_id: u32,
18    /// Maximum message fragment bytes written into one packet. Zero uses the MSRT default.
19    pub fragment_bytes: usize,
20    /// Maximum retransmission attempts. Zero uses the MSRT default.
21    pub max_retransmit_attempts: u8,
22    /// Retransmission timeout in milliseconds. Zero uses the MSRT default.
23    pub retransmit_timeout_ms: u64,
24    /// Reassembly timeout in milliseconds. Zero uses the MSRT default.
25    pub reassembly_timeout_ms: u64,
26    /// Integrity backend.
27    pub integrity: u32,
28    /// Key used when `integrity` is `MSRT_INTEGRITY_SIP_TAG_KEY`.
29    pub aead_key: [u8; 16],
30}
31
32impl Default for MsrtConfig {
33    fn default() -> Self {
34        let config = EngineConfig::default();
35        Self {
36            role: MSRT_ROLE_CLIENT,
37            initial_message_id: 0,
38            fragment_bytes: config.fragment_bytes,
39            max_retransmit_attempts: config.max_retransmit_attempts,
40            retransmit_timeout_ms: config.retransmit_timeout_ms,
41            reassembly_timeout_ms: config.reassembly_timeout_ms,
42            integrity: MSRT_INTEGRITY_CRC16,
43            aead_key: [0; 16],
44        }
45    }
46}
47
48impl MsrtConfig {
49    /// Converts C configuration into MSRT engine configuration.
50    pub(crate) fn engine_config(self) -> Result<EngineConfig, ()> {
51        let mut config = EngineConfig::default();
52        config.initial_message_id = MessageId::new(self.initial_message_id);
53        if self.fragment_bytes != 0 {
54            config.fragment_bytes = self.fragment_bytes;
55        }
56        if self.max_retransmit_attempts != 0 {
57            config.max_retransmit_attempts = self.max_retransmit_attempts;
58        }
59        if self.retransmit_timeout_ms != 0 {
60            config.retransmit_timeout_ms = self.retransmit_timeout_ms;
61        }
62        if self.reassembly_timeout_ms != 0 {
63            config.reassembly_timeout_ms = self.reassembly_timeout_ms;
64        }
65        config.integrity = match self.integrity {
66            0 | MSRT_INTEGRITY_CRC16 => IntegrityConfig::crc16(),
67            MSRT_INTEGRITY_CRC32 => IntegrityConfig::crc32(),
68            MSRT_INTEGRITY_CRC64 => IntegrityConfig::crc64(),
69            MSRT_INTEGRITY_SIP_TAG_DEFAULT => IntegrityConfig::sip_tag(),
70            MSRT_INTEGRITY_SIP_TAG_KEY => IntegrityConfig::sip_tag_with_key(self.aead_key),
71            _ => return Err(()),
72        };
73
74        Ok(config)
75    }
76}