ross_protocol/
packet.rs

1use alloc::vec;
2use alloc::vec::Vec;
3
4use crate::frame::{Frame, FrameId};
5
6#[derive(Debug, PartialEq, Clone)]
7pub struct Packet {
8    /// If this flag is set, the packet is considered to be an error packet
9    pub is_error: bool,
10    /// Transmitting device's address
11    pub device_address: u16,
12    /// Packet data
13    pub data: Vec<u8>,
14}
15
16impl Packet {
17    pub fn to_frames(&self) -> Vec<Frame> {
18        if self.data.len() <= 8 {
19            let mut data = [0; 8];
20
21            for i in 0..self.data.len() {
22                data[i] = self.data[i];
23            }
24
25            return vec![Frame {
26                not_error_flag: !self.is_error,
27                start_frame_flag: true,
28                multi_frame_flag: false,
29                frame_id: FrameId::LastFrameId(0),
30                device_address: self.device_address,
31                data_len: self.data.len() as u8,
32                data,
33            }];
34        }
35
36        let frame_count = (self.data.len() - 1) / 7 + 1;
37        let mut frames = vec![];
38
39        for i in 0..frame_count {
40            let data_len = if i == frame_count - 1 {
41                if self.data.len() % 7 == 0 {
42                    8
43                } else {
44                    self.data.len() % 7 + 1
45                }
46            } else {
47                8
48            };
49
50            let mut data = [0u8; 8];
51
52            if i == 0 {
53                data[0] = ((frame_count - 1) & 0xff) as u8;
54            } else {
55                data[0] = (i & 0xff) as u8;
56            }
57
58            for j in 0..(data_len - 1) {
59                data[j + 1] = self.data[i * 7 + j];
60            }
61
62            frames.push(Frame {
63                not_error_flag: !self.is_error,
64                start_frame_flag: i == 0,
65                multi_frame_flag: true,
66                frame_id: if i == 0 {
67                    FrameId::LastFrameId(frame_count as u16 - 1)
68                } else {
69                    FrameId::CurrentFrameId(i as u16)
70                },
71                device_address: self.device_address,
72                data_len: data_len as u8,
73                data,
74            });
75        }
76
77        return frames;
78    }
79}
80
81#[derive(Debug, PartialEq)]
82pub enum PacketBuilderError {
83    /// Frame supplied was not the next frame in the sequence+
84    OutOfOrder,
85    /// Expected a multi frame packet but a single frame packet was given
86    SingleFramePacket,
87    /// Expected less frames to be in the packet+
88    TooManyFrames,
89    /// Expected an error frame but a data frame was given or the other way around+
90    WrongFrameType,
91    /// The frame given was transmitted by a different device than the previous frames+
92    DeviceAddressMismatch,
93    /// Expected more frames+
94    MissingFrames,
95}
96
97#[derive(Debug, PartialEq)]
98pub struct PacketBuilder {
99    is_error: bool,
100    expected_frame_count: u16,
101    device_address: u16,
102    frames: Vec<Frame>,
103}
104
105impl PacketBuilder {
106    pub fn expected_frame_count(&self) -> u16 {
107        self.expected_frame_count
108    }
109
110    pub fn frame_count(&self) -> u16 {
111        self.frames.len() as u16
112    }
113
114    pub fn frames_left(&self) -> u16 {
115        self.expected_frame_count() - self.frame_count()
116    }
117
118    pub fn new(frame: Frame) -> Result<Self, PacketBuilderError> {
119        if !frame.start_frame_flag {
120            return Err(PacketBuilderError::OutOfOrder);
121        }
122
123        let expected_frame_count = if let FrameId::LastFrameId(last_frame_id) = frame.frame_id {
124            last_frame_id + 1
125        } else {
126            return Err(PacketBuilderError::OutOfOrder);
127        };
128
129        Ok(PacketBuilder {
130            is_error: !frame.not_error_flag,
131            expected_frame_count,
132            device_address: frame.device_address,
133            frames: vec![frame],
134        })
135    }
136
137    pub fn add_frame(&mut self, frame: Frame) -> Result<(), PacketBuilderError> {
138        if !frame.not_error_flag != self.is_error {
139            return Err(PacketBuilderError::WrongFrameType);
140        }
141
142        if frame.device_address != self.device_address {
143            return Err(PacketBuilderError::DeviceAddressMismatch);
144        }
145
146        if frame.start_frame_flag {
147            return Err(PacketBuilderError::OutOfOrder);
148        }
149
150        if !frame.multi_frame_flag {
151            return Err(PacketBuilderError::SingleFramePacket);
152        }
153
154        if let FrameId::CurrentFrameId(frame_id) = frame.frame_id {
155            if frame_id != self.frames.len() as u16 {
156                return Err(PacketBuilderError::OutOfOrder);
157            }
158
159            if frame_id >= self.expected_frame_count {
160                return Err(PacketBuilderError::TooManyFrames);
161            }
162        } else {
163            return Err(PacketBuilderError::OutOfOrder);
164        }
165
166        self.frames.push(frame);
167
168        Ok(())
169    }
170
171    pub fn build(&self) -> Result<Packet, PacketBuilderError> {
172        if self.frames.len() != self.expected_frame_count as usize {
173            return Err(PacketBuilderError::MissingFrames);
174        }
175
176        let mut data = vec![];
177
178        for frame in self.frames.iter() {
179            let start_index = if frame.multi_frame_flag { 1 } else { 0 };
180
181            for i in start_index..frame.data_len {
182                data.push(frame.data[i as usize]);
183            }
184        }
185
186        Ok(Packet {
187            is_error: self.is_error,
188            device_address: self.device_address,
189            data,
190        })
191    }
192}
193
194#[cfg(test)]
195mod tests {
196    use super::*;
197
198    const FRAME_DATA: [u8; 8] = [0x01; 8];
199    const SINGLE_FRAME_PACKET: Frame = Frame {
200        not_error_flag: true,
201        start_frame_flag: true,
202        multi_frame_flag: false,
203        frame_id: FrameId::LastFrameId(0x00),
204        device_address: 0x0101,
205        data_len: 8,
206        data: FRAME_DATA,
207    };
208
209    const MULTI_FRAME_PACKET_DATA: [u8; 14] = [0x01; 14];
210    const MULTI_FRAME_PACKET1: Frame = Frame {
211        not_error_flag: true,
212        start_frame_flag: true,
213        multi_frame_flag: true,
214        frame_id: FrameId::LastFrameId(0x01),
215        device_address: 0x0101,
216        data_len: 8,
217        data: FRAME_DATA,
218    };
219    const MULTI_FRAME_PACKET2: Frame = Frame {
220        not_error_flag: true,
221        start_frame_flag: false,
222        multi_frame_flag: true,
223        frame_id: FrameId::CurrentFrameId(0x01),
224        device_address: 0x0101,
225        data_len: 8,
226        data: FRAME_DATA,
227    };
228
229    #[test]
230    fn to_frames_test() {
231        let packet = Packet {
232            is_error: !MULTI_FRAME_PACKET1.not_error_flag,
233            device_address: MULTI_FRAME_PACKET1.device_address,
234            data: [0x01; 14].to_vec(),
235        };
236
237        let frames = packet.to_frames();
238
239        assert_eq!(frames.len(), 2);
240        assert_eq!(frames[0], MULTI_FRAME_PACKET1);
241        assert_eq!(frames[1], MULTI_FRAME_PACKET2);
242    }
243
244    #[test]
245    fn new_test() {
246        let packet_builder = PacketBuilder::new(SINGLE_FRAME_PACKET).unwrap();
247        let packet = packet_builder.build().unwrap();
248
249        assert_eq!(packet.is_error, !SINGLE_FRAME_PACKET.not_error_flag);
250        assert_eq!(packet.device_address, SINGLE_FRAME_PACKET.device_address);
251        assert_eq!(packet.data, FRAME_DATA);
252    }
253
254    #[test]
255    #[should_panic]
256    fn new_out_of_order_test() {
257        PacketBuilder::new(MULTI_FRAME_PACKET2).unwrap();
258    }
259
260    #[test]
261    fn add_frame_test() {
262        let mut packet_builder = PacketBuilder::new(MULTI_FRAME_PACKET1).unwrap();
263        packet_builder.add_frame(MULTI_FRAME_PACKET2).unwrap();
264        let packet = packet_builder.build().unwrap();
265
266        assert_eq!(packet.is_error, !MULTI_FRAME_PACKET1.not_error_flag);
267        assert_eq!(packet.device_address, MULTI_FRAME_PACKET1.device_address);
268        assert_eq!(packet.data, MULTI_FRAME_PACKET_DATA);
269    }
270
271    #[test]
272    #[should_panic]
273    fn add_frame_wrong_frame_type_test() {
274        let mut error_frame = MULTI_FRAME_PACKET2;
275        error_frame.not_error_flag = false;
276
277        let mut packet_builder = PacketBuilder::new(MULTI_FRAME_PACKET1).unwrap();
278        packet_builder.add_frame(error_frame).unwrap();
279    }
280
281    #[test]
282    #[should_panic]
283    fn add_frame_device_address_mismatch_rwar() {
284        let mut wrong_device_frame = MULTI_FRAME_PACKET2;
285        wrong_device_frame.device_address = 0xffff;
286
287        let mut packet_builder = PacketBuilder::new(MULTI_FRAME_PACKET1).unwrap();
288        packet_builder.add_frame(wrong_device_frame).unwrap();
289    }
290
291    #[test]
292    #[should_panic]
293    fn add_frame_single_frame_packet_test() {
294        let mut packet_builder = PacketBuilder::new(MULTI_FRAME_PACKET1).unwrap();
295        packet_builder.add_frame(SINGLE_FRAME_PACKET).unwrap();
296    }
297
298    #[test]
299    #[should_panic]
300    fn add_frame_too_many_frames_test() {
301        let extra_frame = Frame {
302            not_error_flag: true,
303            start_frame_flag: false,
304            multi_frame_flag: true,
305            frame_id: FrameId::CurrentFrameId(0x02),
306            device_address: 0x0101,
307            data_len: 8,
308            data: FRAME_DATA,
309        };
310
311        let mut packet_builder = PacketBuilder::new(MULTI_FRAME_PACKET1).unwrap();
312        packet_builder.add_frame(MULTI_FRAME_PACKET2).unwrap();
313        packet_builder.add_frame(extra_frame).unwrap();
314    }
315
316    #[test]
317    #[should_panic]
318    fn build_missing_frames_test() {
319        let packet_builder = PacketBuilder::new(MULTI_FRAME_PACKET1).unwrap();
320        packet_builder.build().unwrap();
321    }
322}