1use alloc::vec;
2use alloc::vec::Vec;
3
4use crate::frame::{Frame, FrameId};
5
6#[derive(Debug, PartialEq, Clone)]
7pub struct Packet {
8 pub is_error: bool,
10 pub device_address: u16,
12 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 OutOfOrder,
85 SingleFramePacket,
87 TooManyFrames,
89 WrongFrameType,
91 DeviceAddressMismatch,
93 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}