remote_id/codec/
mod.rs

1use crate::MAX_ID_BYTE_SIZE;
2
3pub mod decode;
4pub mod encode;
5
6#[repr(u8)]
7#[derive(Debug, Copy, Clone)]
8enum MessageType {
9    BasicId = 0,
10    Location = 1,
11    Auth = 2,
12    Selfid = 3,
13    System = 4,
14    OperatorId = 5,
15    MessagePack = 0xF,
16
17    Invalid,
18}
19
20impl From<u8> for MessageType {
21    fn from(value: u8) -> Self {
22        match value {
23            0 => MessageType::BasicId,
24            1 => MessageType::Location,
25            2 => MessageType::Auth,
26            3 => MessageType::Selfid,
27            4 => MessageType::System,
28            5 => MessageType::OperatorId,
29            0xF => MessageType::MessagePack,
30
31            _ => MessageType::Invalid,
32        }
33    }
34}
35
36pub fn copy_to_id(slice: &[u8]) -> [u8; 20] {
37    let mut buffer = [0u8; MAX_ID_BYTE_SIZE];
38    let max = if slice.len() <= MAX_ID_BYTE_SIZE {
39        slice.len()
40    } else {
41        MAX_ID_BYTE_SIZE
42    };
43    buffer[0..max].copy_from_slice(&slice[0..max]);
44    buffer
45}
46
47#[macro_export]
48macro_rules! bitmask {
49    ($lo:literal, $hi:literal) => {{
50        let mut pattern = 1;
51
52        for _ in 0..($hi - $lo) {
53            pattern = (pattern << 1) + 1;
54        }
55
56        for _ in 0..$lo {
57            pattern <<= 1;
58        }
59
60        pattern
61    }};
62}
63
64/// Return a subslice or an array of the given bytes:
65/// get_bytes!(buf, OFFSET, LEN)
66/// ```ignore
67/// assert_eq!([2, 3], get_bytes!(&[1, 2, 3], 1, 2))
68/// ```  
69#[macro_export]
70macro_rules! get_bytes {
71    ($buf:expr, $off:expr, 1) => {{
72        $buf[$off]
73    }};
74
75    ($buf:expr, $off:expr, 2) => {{
76        [$buf[$off], $buf[$off + 1]]
77    }};
78
79    ($buf:expr, $off:expr, 3) => {{
80        [$buf[$off], $buf[$off + 1], $buf[$off + 2]]
81    }};
82
83    ($buf:expr, $off:expr, 4) => {{
84        [$buf[$off], $buf[$off + 1], $buf[$off + 2], $buf[$off + 3]]
85    }};
86
87    ($buf:expr, $off:expr, $len:expr) => {{
88        &$buf[$off..($off + $len)]
89    }};
90}
91
92/// Return the given bits from a value
93/// ```ignore
94/// assert_eq!(get_bits!(0b1111, 2..0), 7)
95/// ```  
96#[macro_export]
97macro_rules! get_bits {
98    ($num:expr, $hi:literal..$lo:literal) => {{
99        let p = $crate::bitmask!($lo, $hi);
100        ($num & p) >> $lo
101    }};
102}
103
104#[macro_export]
105macro_rules! put_bits {
106    ($num:expr, $hi:literal..$lo:literal) => {{
107        let p = $crate::bitmask!($lo, $hi);
108        ($num & p) >> $lo
109    }};
110}
111
112#[cfg(test)]
113mod test {
114    use chrono::{SubsecRound, Utc};
115
116    use crate::{
117        codec::{copy_to_id, decode, encode},
118        data::{
119            basic_id::BasicId, location::Location, operator_id::OperatorId, system::System,
120            RemoteIDMessage,
121        },
122    };
123
124    #[test]
125    fn test_get_bits_trivial() {
126        assert_eq!(get_bits!(0b0000, 1..0), 0);
127        assert_eq!(get_bits!(0b0000, 2..0), 0);
128        assert_eq!(get_bits!(0b0000, 3..0), 0);
129        assert_eq!(get_bits!(0b0000, 4..0), 0);
130    }
131
132    #[test]
133    fn test_get_bits_all_ones() {
134        assert_eq!(get_bits!(0b1111, 0..0), 1);
135        assert_eq!(get_bits!(0b1111, 1..0), 3);
136        assert_eq!(get_bits!(0b1111, 2..0), 7);
137        assert_eq!(get_bits!(0b1111, 3..0), 15);
138
139        assert_eq!(get_bits!(0b1111, 1..1), 1);
140        assert_eq!(get_bits!(0b1111, 2..1), 3);
141        assert_eq!(get_bits!(0b1111, 3..1), 7);
142
143        assert_eq!(get_bits!(0b1111, 2..2), 1);
144        assert_eq!(get_bits!(0b1111, 3..2), 3);
145
146        assert_eq!(get_bits!(0b1111_1111, 3..3), 1);
147        assert_eq!(get_bits!(0b1111_1111, 4..3), 3);
148        assert_eq!(get_bits!(0b1111_1111, 5..3), 7);
149
150        assert_eq!(get_bits!(0b1111_1111, 7..7), 1);
151        assert_eq!(get_bits!(0b1111_1111, 8..8), 0);
152        assert_eq!(get_bits!(0b1111_1111, 9..8), 0);
153    }
154
155    #[test]
156    fn test_get_bits_x() {
157        let n = 0b0001_1100;
158        assert_eq!(get_bits!(n, 4..2), (n & 0b0001_1100) >> 2);
159
160        let n = 34;
161        assert_eq!(get_bits!(n, 7..3), (n & 0b1111_1000) >> 3);
162    }
163
164    #[test]
165    fn test_bitmask_from_0() {
166        assert_eq!(bitmask!(0, 0), 1);
167        assert_eq!(bitmask!(0, 1), 3);
168        assert_eq!(bitmask!(0, 2), 7);
169        assert_eq!(bitmask!(0, 3), 15);
170        assert_eq!(bitmask!(0, 4), 31);
171        assert_eq!(bitmask!(0, 5), 63);
172        assert_eq!(bitmask!(0, 6), 127);
173        assert_eq!(bitmask!(0, 7), 255);
174    }
175
176    #[test]
177    fn test_bitmask_one_bit() {
178        assert_eq!(bitmask!(1, 1), 2);
179        assert_eq!(bitmask!(2, 2), 4);
180        assert_eq!(bitmask!(3, 3), 8);
181        assert_eq!(bitmask!(4, 4), 16);
182        assert_eq!(bitmask!(5, 5), 32);
183    }
184
185    #[test]
186    fn test_bitmask_two_bits() {
187        assert_eq!(bitmask!(1, 2), 6);
188        assert_eq!(bitmask!(2, 3), 12);
189        assert_eq!(bitmask!(3, 4), 24);
190        assert_eq!(bitmask!(4, 5), 48);
191    }
192
193    #[test]
194    fn test_bitmask_three_bits() {
195        assert_eq!(bitmask!(1, 3), 14);
196        assert_eq!(bitmask!(2, 4), 28);
197        assert_eq!(bitmask!(3, 5), 56);
198        assert_eq!(bitmask!(4, 6), 112);
199    }
200
201    extern crate std;
202    #[test]
203    fn test_bitmask_xxx() {
204        let p = bitmask!(0, 3);
205        std::dbg!(p);
206    }
207
208    #[test]
209    fn test_recode_basic_id() {
210        let basic_id = RemoteIDMessage::BasicID(BasicId {
211            id_type: crate::data::basic_id::IdType::None,
212            ua_type: crate::data::basic_id::UAType::Aeroplane,
213            uas_id: copy_to_id("1\0".as_bytes()),
214        });
215
216        let mut buf = [0u8; 22];
217        encode::to_message_buffer(&basic_id, &mut buf);
218        let msg = decode::from_message_buffer(&buf).unwrap();
219        std::dbg!(&msg);
220        assert_eq!(basic_id, msg);
221    }
222
223    #[test]
224    fn test_recode_location() {
225        let location = RemoteIDMessage::Location(Location {
226            operational_status: crate::data::location::OperationalStatus::Undeclared,
227            height_type: crate::data::location::HeightType::AboveGroundLevel,
228            speed: 4.0,
229            vertical_speed: 2.0,
230            pressure_altitude: 3.0,
231            geodetic_altitude: 4.0,
232            track_direction: 5,
233            horizontal_accuracy: crate::data::location::HorizontalAccuracy::LessThan_10_NM,
234            vertical_accuracy: crate::data::location::VerticalAccuracy::LessThan_10_m,
235            latidute: 6.0,
236            longitude: 7.0,
237            height: 8.0,
238            baro_altitude_accuracy: crate::data::location::VerticalAccuracy::LessThan_10_m,
239            speed_accuracy: crate::data::location::SpeedAccuracy::LessThan_10_mps,
240            timestamp: 9.0,
241            timestamp_accuracy: None,
242        });
243
244        let mut buf = [0u8; 25];
245        encode::to_message_buffer(&location, &mut buf);
246
247        let msg = decode::from_message_buffer(&buf).unwrap();
248        std::dbg!(&msg);
249        assert_eq!(location, msg);
250    }
251
252    #[test]
253    fn test_recode_operator_id() {
254        let location = RemoteIDMessage::OperatorId(OperatorId {
255            id_type: crate::data::operator_id::OperatorIdType::Unknown(99),
256            operator_id: copy_to_id("1\0".as_bytes()),
257        });
258
259        let mut buf = [0u8; 25];
260        encode::to_message_buffer(&location, &mut buf);
261        let msg = decode::from_message_buffer(&buf).unwrap();
262
263        assert_eq!(location, msg);
264    }
265
266    #[test]
267    fn test_recode_system() {
268        let location = RemoteIDMessage::System(System {
269            classification_type: crate::data::system::ClassificationType::EuropeanUnion,
270            operator_location_type: crate::data::system::OperatorLocationType::Fixed,
271            operator_latidute: 10.0,
272            operator_longitude: 10.0,
273            area_count: 11,
274            area_radius: 1230.0,
275            area_ceiling: 1234.0,
276            area_floor: 1234.0,
277            ua_classification: crate::data::system::UaClassification {
278                category: crate::data::system::UaCategory::Certified,
279                class: crate::data::system::UaClass::Class0,
280            },
281            operator_altitude: 123.0,
282            timestamp: Utc::now().trunc_subsecs(0),
283        });
284
285        let mut buf = [0u8; 25];
286        encode::to_message_buffer(&location, &mut buf);
287        let msg = decode::from_message_buffer(&buf).unwrap();
288
289        assert_eq!(location, msg);
290    }
291}