canboat_rs/
fast_packet.rs

1use heapless::Vec;
2
3/// - In fast packet framing, the first packet contains two protocol bytes and six data bytes.
4/// - Following packets contain one protocol byte and seven data bytes.
5/// - The first byte in all frames contains a sequence counter in the high 3 bits and a frame
6/// counter in the lower 5 bits.
7/// - The second byte in the first frame contains the total number of frames that will be sent.
8#[derive(Debug)]
9pub struct FastPacket {
10    pub frame_count: u8,
11    pub sequence_count: u8,
12    pub total_number_of_frames: u8,
13    pub data: Vec<u8, 128>,
14}
15
16pub enum AddFrame {
17    Processing,
18    Complete,
19    Error,
20}
21
22impl FastPacket {
23    pub fn is_first_frame(data: &[u8]) -> bool {
24        let frame_count = FastPacket::parse_frame_count(data[0]);
25        frame_count == 0
26    }
27
28    pub fn parse_frame_count(b: u8) -> u8 {
29        b & 0b00011111
30    }
31
32    pub fn parse_sequence_count(b: u8) -> u8 {
33        b >> 5
34    }
35
36    pub fn add_frame(&mut self, data: &[u8]) -> AddFrame {
37        let first_byte: u8 = data[0];
38        let frame_count = FastPacket::parse_frame_count(first_byte);
39        if (self.frame_count + 1) == frame_count {
40            self.frame_count = frame_count;
41            self.sequence_count = FastPacket::parse_sequence_count(first_byte);
42            // Can add frame
43            let data = &data[1..8];
44            data.iter().for_each(|data| {
45                // TODO: Handle this
46                self.data.push(*data).unwrap();
47            });
48
49            if self.is_complete() {
50                return AddFrame::Complete;
51            }
52
53            return AddFrame::Processing;
54        }
55        AddFrame::Error
56    }
57
58    pub fn is_complete(&self) -> bool {
59        self.data.iter().count() >= self.total_number_of_frames.into()
60    }
61
62    pub fn new(data: &[u8]) -> Option<FastPacket> {
63        let first_byte: u8 = data[0];
64        let frame_count = FastPacket::parse_frame_count(first_byte);
65        let sequence_count = FastPacket::parse_sequence_count(first_byte);
66
67        let mut d = Vec::<u8, 128>::new();
68        data[2..8].iter().for_each(|data| {
69            d.push(*data);
70        });
71
72        if frame_count == 0 {
73            return Some(FastPacket {
74                frame_count,
75                sequence_count,
76                total_number_of_frames: data[1],
77                data: d,
78            });
79        }
80        None
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use crate::pgns::navigation_data::NavigationData;
87
88    use super::*;
89
90    #[test]
91    fn parses_fast_packet() {
92        let data = &[0b00000000, 20, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa];
93
94        let mut fp = FastPacket::new(data).unwrap();
95        let data = &[0b00100001, 20, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa];
96        fp.add_frame(data);
97        assert_eq!(fp.frame_count, 1);
98        assert_eq!(fp.sequence_count, 1);
99    }
100
101    #[test]
102    fn parses_message_correctly() {
103        let zero = &[64, 34, 136, 255, 255, 255, 255, 64];
104        let one = &[65, 255, 255, 255, 255, 255, 255, 202];
105        let two = &[66, 63, 202, 63, 255, 255, 255, 255];
106        let three = &[67, 0, 0, 0, 0, 255, 255, 255];
107        let four = &[68, 127, 255, 255, 255, 127, 255, 127];
108
109        let fp = FastPacket::new(zero);
110        assert_eq!(fp.is_some(), true);
111        let mut fp = fp.unwrap();
112        fp.add_frame(one);
113        fp.add_frame(two);
114        fp.add_frame(three);
115        fp.add_frame(four);
116        assert_eq!(fp.data.iter().count(), 34);
117        assert_eq!(fp.is_complete(), true);
118    }
119}