1use core::fmt::Debug;
2
3use crc::{Crc, CRC_16_IBM_SDLC};
4use labrador_ldpc::decoder::DecodeFrom;
5
6use crate::{
7 buffer::{Buffer, BufferOverflow},
8 error::{CommentError, DecodeError, DigipeatError, EncodeError, PacketRouteAppendError},
9 identity::Identity,
10 interleaver, ldpc, utf8,
11 whisker::{
12 Arbitrary, Comment, Destination, Gps, Identification, NodeInfo, PastHop, Route, RouteHop,
13 Timestamp, ValidatedWhiskerIter, Whisker, WhiskerIter, COMMENT_TYPE,
14 },
15 whitener,
16};
17
18const X25: Crc<u16> = Crc::<u16>::new(&CRC_16_IBM_SDLC);
19
20macro_rules! uniq_whisker {
21 ($t:meta) => {
22 ::paste::paste! {
23 pub fn [<$t:snake:lower>](&self) -> Option<$t> {
24 self.iter().find_map(|w| match w {
25 Whisker::$t(x) => Some(x),
26 _ => None,
27 })
28 }
29
30 pub fn [<add_ $t:snake:lower>](&mut self, w: $t) -> Result<(), EncodeError> {
31 if self.[<$t:snake:lower>]().is_some() {
32 return Err(EncodeError::DuplicateData);
33 }
34
35 try_lock(&mut self.buf, |data| {
36 let mut buf = [0; 256];
37 let out = w.encode(&mut buf).unwrap();
39
40 data.try_push(crate::whisker::[<$t:snake:upper _TYPE>]).ok().ok_or(EncodeError::CatsOverflow)?;
41 data.try_extend_from_slice(out).ok().ok_or(EncodeError::CatsOverflow)?;
42
43 Ok(())
44 })?;
45
46 Ok(())
47 }
48
49 pub fn [<clear_ $t:snake:lower>](&mut self) {
50 self.clear_by_type(crate::whisker::[<$t:snake:upper _TYPE>], false);
51 }
52 }
53 };
54}
55
56macro_rules! poly_whisker {
57 ($t: meta) => {
58 ::paste::paste! {
59 pub fn [<$t:lower _iter>](&self) -> core::iter::FilterMap<ValidatedWhiskerIter<'_>, fn(Whisker) -> Option<$t>> {
60 fn filt(w: Whisker) -> Option<$t> {
61 match w {
62 Whisker::$t(x) => Some(x),
63 _ => None
64 }
65 }
66
67 self.iter().filter_map(filt)
68 }
69
70 pub fn [<add_ $t:lower>](&mut self, w: $t) -> Result<(), EncodeError> {
71 try_lock(&mut self.buf, |data| {
72 let mut buf = [0; 256];
73 let out = w.encode(&mut buf).unwrap();
75
76 data.try_push(crate::whisker::[<$t:upper _TYPE>]).ok().ok_or(EncodeError::CatsOverflow)?;
77 data.try_extend_from_slice(out).ok().ok_or(EncodeError::CatsOverflow)?;
78
79 Ok(())
80 })?;
81
82 Ok(())
83 }
84
85 pub fn [<clear_ $t:lower>](&mut self) {
86 self.clear_by_type(crate::whisker::[<$t:upper _TYPE>], true);
87 }
88 }
89 };
90}
91
92pub struct Packet<'a, const N: usize> {
95 buf: Buffer<'a, N>,
96}
97
98impl<'a, const N: usize> Packet<'a, N> {
99 pub fn new(buf: &'a mut [u8; N]) -> Self {
100 Self { buf: buf.into() }
101 }
102
103 pub fn clone_backing<'b>(&self, buf: &'b mut [u8; N]) -> Packet<'b, N> {
104 Packet {
105 buf: self.buf.clone_backing(buf),
106 }
107 }
108
109 pub fn decode(buf: Buffer<'a, N>) -> Result<Self, DecodeError> {
112 assert!(N <= 8191);
113
114 for w in WhiskerIter::new(&buf) {
116 w?;
117 }
118
119 let comment_iter = WhiskerIter::new(&buf)
120 .filter_map(|w| match w.unwrap() {
121 Whisker::Comment(c) => Some(c.internal_data().clone()),
122 _ => None,
123 })
124 .flatten();
125
126 if !utf8::validate(comment_iter) {
127 return Err(DecodeError::InvalidComment);
128 }
129
130 Ok(Self { buf })
131 }
132
133 pub fn encode(&self) -> &[u8] {
134 &self.buf
135 }
136
137 pub fn semi_encode(mut self) -> Result<Buffer<'a, N>, (EncodeError, Self)> {
139 let crc = X25.checksum(&self.buf).to_le_bytes();
140
141 let res: Result<(), BufferOverflow> = try_lock(&mut self.buf, |data| {
142 data.try_push(crc[0])?;
143 data.try_push(crc[1])?;
144
145 Ok(())
146 });
147
148 match res {
149 Ok(()) => Ok(self.buf),
150 Err(_) => Err((EncodeError::CatsOverflow, self)),
151 }
152 }
153
154 pub fn semi_decode(mut buf: Buffer<'a, N>) -> Result<Self, DecodeError> {
158 let crc1 = buf.pop().ok_or(DecodeError::UnexpectedEndOfInput)?;
159 let crc0 = buf.pop().ok_or(DecodeError::UnexpectedEndOfInput)?;
160 let crc_expected = u16::from_le_bytes([crc0, crc1]);
161 let crc_actual = X25.checksum(&buf);
162
163 if crc_expected != crc_actual {
164 return Err(DecodeError::CrcMismatch);
165 }
166
167 Self::decode(buf)
168 }
169
170 pub fn fully_encode<const M: usize>(self, out: &mut Buffer<M>) -> Result<(), EncodeError> {
173 let mut data = self.semi_encode().map_err(|(err, _)| err)?;
174 whitener::whiten(&mut data);
175 ldpc::encode(&mut data)?;
176
177 out.try_extend_from_slice(&u16::try_from(data.len()).unwrap().to_le_bytes())
179 .map_err(|_| EncodeError::CatsOverflow)?;
180 interleaver::interleave(&data, out)?;
181
182 Ok(())
183 }
184
185 pub fn fully_decode(data: &[u8], buf: &'a mut [u8; N]) -> Result<Self, DecodeError> {
190 let mut buf = Buffer::new_empty(buf);
191 interleaver::uninterleave(data, &mut buf).map_err(|_| DecodeError::Overflow)?;
192 ldpc::decode(&mut buf).ok_or(DecodeError::LdpcError)?;
193 whitener::whiten(&mut buf);
194
195 Self::semi_decode(buf)
196 }
197
198 pub fn fully_decode_soft<const M: usize, T: DecodeFrom>(
201 data: &mut [T],
202 buf: &'a mut [u8; N],
203 ) -> Result<Self, DecodeError> {
204 let mut out = [T::zero(); M];
205 let mut out = Buffer::new_empty(&mut out);
206 interleaver::uninterleave_soft(data, &mut out).map_err(|_| DecodeError::Overflow)?;
207 let mut buf = Buffer::new_empty(buf);
208 ldpc::decode_soft(&mut out, &mut buf).ok_or(DecodeError::LdpcError)?;
209 whitener::whiten(&mut buf);
210
211 Self::semi_decode(buf)
212 }
213
214 pub fn iter(&self) -> ValidatedWhiskerIter<'_> {
215 ValidatedWhiskerIter::new(&self.buf)
216 }
217
218 uniq_whisker!(Identification);
219 uniq_whisker!(Timestamp);
220 uniq_whisker!(Gps);
221 uniq_whisker!(Route);
222 uniq_whisker!(NodeInfo);
223 poly_whisker!(Destination);
224 poly_whisker!(Arbitrary);
225
226 pub fn comment<'b>(&self, buf: &'b mut [u8]) -> Result<&'b str, CommentError> {
227 let iter = self.iter().filter_map(|w| match w {
228 Whisker::Comment(c) => Some(c),
229 _ => None,
230 });
231
232 let mut i = 0;
233 let mut has_comment = false;
234 for c in iter {
235 has_comment = true;
236 let data = c.internal_data();
237 buf.get_mut(i..(i + data.len()))
238 .ok_or(CommentError::BufferOverflow)?
239 .copy_from_slice(data);
240
241 i += data.len();
242 }
243
244 if !has_comment {
245 return Err(CommentError::NoComment);
246 }
247
248 Ok(core::str::from_utf8(&buf[0..i]).unwrap())
250 }
251
252 pub fn add_comment(&mut self, comment: &str) -> Result<(), EncodeError> {
253 if self.iter().any(|w| matches!(w, Whisker::Comment(_))) {
254 return Err(EncodeError::DuplicateData);
256 }
257
258 try_lock(&mut self.buf, |data| {
259 let mut comment = comment.as_bytes();
260
261 while comment.len() > 255 {
262 let c = Comment::new(&comment[0..255]).unwrap();
263 let mut buf = [0; 256];
264 let out = c.encode(&mut buf).unwrap();
265
266 data.try_push(COMMENT_TYPE)
267 .map_err(|_| EncodeError::CatsOverflow)?;
268 data.try_extend_from_slice(out)
269 .map_err(|_| EncodeError::CatsOverflow)?;
270
271 comment = &comment[255..];
272 }
273
274 let c = Comment::new(comment).unwrap();
275 let mut buf = [0; 256];
276 let out = c.encode(&mut buf).unwrap();
277
278 data.try_push(COMMENT_TYPE)
279 .map_err(|_| EncodeError::CatsOverflow)?;
280 data.try_extend_from_slice(out)
281 .map_err(|_| EncodeError::CatsOverflow)?;
282
283 Ok(())
284 })?;
285
286 Ok(())
287 }
288
289 pub fn clear_comment(&mut self) {
290 self.clear_by_type(COMMENT_TYPE, true);
291 }
292
293 pub fn should_digipeat(&self, identity: Identity) -> Result<(), DigipeatError> {
296 let route = match self.route() {
297 Some(x) => x,
298 None => {
299 return Err(DigipeatError::NoRoute);
300 }
301 };
302
303 if let Some(ident) = self.identification() {
304 if &ident.callsign == identity.callsign() && ident.ssid == identity.ssid() {
305 return Err(DigipeatError::Us);
306 }
307 }
308
309 let max_hops: usize = route.max_hops.into();
310 let cur_hops = route
311 .iter()
312 .filter(|r| match r {
313 RouteHop::Internet => false,
314 RouteHop::Past(_) => true,
315 RouteHop::Future(_) => false,
316 })
317 .count();
318
319 if max_hops <= cur_hops {
320 return Err(DigipeatError::MaxHops);
321 }
322
323 let already_digipeated = route.iter().any(|r| match r {
324 RouteHop::Internet => false,
325 RouteHop::Past(past_hop) => past_hop.identity() == identity,
326 RouteHop::Future(_) => false,
327 });
328
329 if already_digipeated {
330 return Err(DigipeatError::AlreadyDigipeated);
331 }
332
333 let next_node = route.iter().find_map(|r| match r {
334 RouteHop::Future(x) => Some(x),
335 _ => None,
336 });
337
338 match next_node {
339 Some(ident) if ident != identity => Err(DigipeatError::SetDestiny),
340 _ => Ok(()),
341 }
342 }
343
344 pub fn append_to_route(
346 &mut self,
347 callsign: &str,
348 ssid: u8,
349 rssi: Option<f64>,
350 ) -> Result<(), PacketRouteAppendError> {
351 let mut route = self.route().ok_or(PacketRouteAppendError::NoRouteWhisker)?;
352 route
353 .append_hop(PastHop::new(Identity::new(callsign, ssid), rssi))
354 .map_err(|error| PacketRouteAppendError::Route { error })?;
355 self.clear_route();
356
357 self.add_route(route)
358 .map_err(|_| PacketRouteAppendError::PacketOverflow)?;
359
360 Ok(())
361 }
362
363 fn clear_by_type(&mut self, whisker_type: u8, all: bool) {
364 let mut i = 0;
365 while i < self.buf.len() {
366 let t = self.buf[i];
367 let step = usize::from(self.buf[i + 1]) + 2;
368
369 if t == whisker_type {
370 self.buf.drain(i, i + step);
371
372 if !all {
373 return;
374 }
375 } else {
376 i += step;
377 }
378 }
379 }
380}
381
382impl<const N: usize> Debug for Packet<'_, N> {
383 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
384 f.debug_list()
385 .entries(ValidatedWhiskerIter::new(&self.buf))
386 .finish()
387 }
388}
389
390fn try_lock<'a, const N: usize, T, E, F: Fn(&mut Buffer<'a, N>) -> Result<T, E>>(
393 buf: &mut Buffer<'a, N>,
394 f: F,
395) -> Result<T, E> {
396 let len = buf.len();
397
398 match f(buf) {
399 Ok(x) => Ok(x),
400 Err(e) => {
401 buf.truncate(len);
402
403 Err(e)
404 }
405 }
406}
407
408#[cfg(test)]
409mod tests {
410 use super::*;
411 use crate::whisker::NodeInfoBuilder;
412 use crate::{soft_bit::FromHardBit, whisker::AckData};
413 use arrayvec::ArrayString;
414 use bitvec::{order::Msb0, view::BitView};
415
416 #[test]
417 fn dest() {
418 let d1 = Destination::new("CALL1", 23, Some(AckData::new(7, false))).unwrap();
419 let d2 = Destination::new("CALL2", 2, Some(AckData::new(23, true))).unwrap();
420
421 let mut buf = [0; 1024];
422 let mut packet: Packet<1024> = Packet::new(&mut buf);
423 packet.add_destination(d1.clone()).unwrap();
424 packet.add_destination(d2.clone()).unwrap();
425
426 let mut dests = packet.destination_iter();
427 assert_eq!(d1, dests.next().unwrap());
428 assert_eq!(d2, dests.next().unwrap());
429 assert_eq!(None, dests.next());
430 }
431
432 #[test]
433 fn route_clear() {
434 let mut buf = [0; 1024];
435 let mut p: Packet<1024> = Packet::new(&mut buf);
436 p.add_identification(Identification::new("call", 43, 123).unwrap())
437 .unwrap();
438 let mut r = Route::new(8);
439 r.push_internet().unwrap();
440 p.add_route(r).unwrap();
441 p.add_comment("This is a comment").unwrap();
442
443 p.clear_route();
444
445 assert_eq!(
446 Identification::new("call", 43, 123).unwrap(),
447 p.identification().unwrap()
448 );
449 assert_eq!(None, p.route());
450 let mut buf = [0; 32];
451 assert_eq!("This is a comment", p.comment(&mut buf).unwrap());
452 }
453
454 #[test]
455 fn semi_e2e() {
456 let comment = "Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.";
457
458 let mut buf = [0; 2048];
459 let mut packet = Packet::new(&mut buf);
460 packet
461 .add_identification(Identification {
462 icon: 123,
463 callsign: ArrayString::from("ABCXYZ_LONG_CALL").unwrap(),
464 ssid: 43,
465 })
466 .unwrap();
467
468 packet.add_comment(comment).unwrap();
469
470 let res = packet.add_identification(Identification {
471 icon: 456,
472 callsign: ArrayString::from("NOPE").unwrap(),
473 ssid: 0,
474 });
475 assert!(matches!(res, Err(EncodeError::DuplicateData)));
476
477 let semi = packet.semi_encode().unwrap();
478
479 let packet2 = Packet::semi_decode(semi).unwrap();
480 assert_eq!(
481 Identification {
482 icon: 123,
483 callsign: ArrayString::from("ABCXYZ_LONG_CALL").unwrap(),
484 ssid: 43,
485 },
486 packet2.identification().unwrap()
487 );
488
489 let mut buf = [0; 1024];
490 assert_eq!(comment, packet2.comment(&mut buf).unwrap());
491 }
492
493 #[test]
494 fn full_e2e() {
495 let comment = "Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.";
496
497 let mut buf = [0; 4096];
498 let mut packet = Packet::new(&mut buf);
499 packet
500 .add_identification(Identification {
501 icon: 123,
502 callsign: ArrayString::from("ABCXYZ_LONG_CALL").unwrap(),
503 ssid: 43,
504 })
505 .unwrap();
506
507 packet.add_comment(comment).unwrap();
508
509 let res = packet.add_identification(Identification {
510 icon: 456,
511 callsign: ArrayString::from("NOPE").unwrap(),
512 ssid: 0,
513 });
514 assert!(matches!(res, Err(EncodeError::DuplicateData)));
515
516 let mut buf2 = [0; 4096];
517 let mut fully = Buffer::new_empty(&mut buf2);
518 packet.fully_encode(&mut fully).unwrap();
519
520 fully[40] ^= 0x55;
521 fully[844] ^= 0x7B;
522
523 let mut buf3 = [0; 8191];
525 let packet2: Packet<8191> = Packet::fully_decode(&fully[2..], &mut buf3).unwrap();
526 assert_eq!(
527 Identification {
528 icon: 123,
529 callsign: ArrayString::from("ABCXYZ_LONG_CALL").unwrap(),
530 ssid: 43,
531 },
532 packet2.identification().unwrap()
533 );
534
535 let mut buf = [0; 1024];
536 assert_eq!(comment, packet2.comment(&mut buf).unwrap());
537 }
538
539 #[test]
540 fn full_e2e_soft_decode() {
541 let comment = "Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.Hello world! This is a comment. It's long so that it needs to be split across more than one whisker.";
542
543 let mut buf = [0; 4096];
544 let mut packet = Packet::new(&mut buf);
545 packet
546 .add_identification(Identification {
547 icon: 123,
548 callsign: ArrayString::from("ABCXYZ_LONG_CALL").unwrap(),
549 ssid: 43,
550 })
551 .unwrap();
552
553 packet.add_comment(comment).unwrap();
554
555 let res = packet.add_identification(Identification {
556 icon: 456,
557 callsign: ArrayString::from("NOPE").unwrap(),
558 ssid: 0,
559 });
560 assert!(matches!(res, Err(EncodeError::DuplicateData)));
561
562 let mut buf2 = [0; 4096];
563 let mut fully = Buffer::new_empty(&mut buf2);
564 packet.fully_encode(&mut fully).unwrap();
565
566 fully[40] ^= 0x55;
567 fully[844] ^= 0x7B;
568
569 let mut soft = [0.0; 8191 * 8];
570 let mut soft = Buffer::new_empty(&mut soft);
571 for b in fully.view_bits::<Msb0>().iter() {
572 soft.push(f32::from_hard_bit(*b));
573 }
574 let soft = &mut soft[16..];
575
576 let mut buf3 = [0; 8191];
577 let packet2: Packet<8191> =
579 Packet::fully_decode_soft::<{ 8191 * 8 }, _>(soft, &mut buf3).unwrap();
580 assert_eq!(
581 Identification {
582 icon: 123,
583 callsign: ArrayString::from("ABCXYZ_LONG_CALL").unwrap(),
584 ssid: 43,
585 },
586 packet2.identification().unwrap()
587 );
588
589 let mut buf = [0; 1024];
590 assert_eq!(comment, packet2.comment(&mut buf).unwrap());
591 }
592
593 #[test]
594 fn node_info_e2e() {
595 let mut buf = [0; 4096];
596 let mut packet = Packet::new(&mut buf);
597 packet
598 .add_node_info(
599 NodeInfoBuilder::default()
600 .hardware_id(0xBEEF)
601 .software_id(0xBC)
602 .uptime(2304)
603 .antenna_height(5)
604 .antenna_gain(3.0)
605 .tx_power(30.0)
606 .voltage(12.6)
607 .xcvr_temperature(-15)
608 .battery_charge(65.0)
609 .build(),
610 )
611 .unwrap();
612
613 let mut buf2 = [0; 4096];
614 let mut encoded = Buffer::new_empty(&mut buf2);
615 packet.fully_encode(&mut encoded).unwrap();
616
617 let mut buf3 = [0; 4096];
618 let packet2 = Packet::fully_decode(&encoded[2..], &mut buf3).unwrap();
619
620 let node_info = packet2.node_info().unwrap();
621 assert_eq!(0xBEEF, node_info.hardware_id().unwrap());
622 assert_eq!(0xBC, node_info.software_id().unwrap());
623 assert_eq!(2304, node_info.uptime().unwrap());
624 assert_eq!(5, node_info.antenna_height().unwrap());
625 assert_eq!(3.0, node_info.antenna_gain().unwrap());
626 assert_eq!(30.0, node_info.tx_power().unwrap());
627 assert_eq!(12.6, node_info.voltage().unwrap());
628 assert_eq!(-15, node_info.xcvr_temperature().unwrap());
629 assert_eq!(64.70588235294117, node_info.battery_charge().unwrap());
630 }
631
632 #[test]
633 fn node_info_e2e_some_unpopulated() {
634 let mut buf = [0; 4096];
635 let mut packet = Packet::new(&mut buf);
636 packet
637 .add_node_info(
638 NodeInfoBuilder::default()
639 .software_id(0xBC)
640 .uptime(2304)
641 .antenna_gain(3.0)
642 .voltage(12.6)
643 .xcvr_temperature(-15)
644 .build(),
645 )
646 .unwrap();
647
648 let mut buf2 = [0; 4096];
649 let mut encoded = Buffer::new_empty(&mut buf2);
650 packet.fully_encode(&mut encoded).unwrap();
651
652 let mut buf3 = [0; 4096];
653 let packet2 = Packet::fully_decode(&encoded[2..], &mut buf3).unwrap();
654
655 let node_info = packet2.node_info().unwrap();
656 assert_eq!(None, node_info.hardware_id());
657 assert_eq!(0xBC, node_info.software_id().unwrap());
658 assert_eq!(2304, node_info.uptime().unwrap());
659 assert_eq!(None, node_info.antenna_height());
660 assert_eq!(3.0, node_info.antenna_gain().unwrap());
661 assert_eq!(None, node_info.tx_power());
662 assert_eq!(12.6, node_info.voltage().unwrap());
663 assert_eq!(-15, node_info.xcvr_temperature().unwrap());
664 assert_eq!(None, node_info.battery_charge());
665 }
666
667 #[test]
668 fn fully_decode_fuzz_tests() {
669 let data = [
670 112, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 74, 0, 0, 0, 0, 41, 0,
671 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 114, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
672 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
673 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
674 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
675 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255,
676 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
677 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 10, 112, 0, 0, 0, 0, 0, 0, 2, 1, 0,
678 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 74, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39,
679 114, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
680 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
681 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
682 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
683 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
684 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 118, 118, 118, 118, 118, 118, 118,
685 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 0, 118, 118, 118, 118, 118, 118, 118, 118,
686 118, 118, 118, 145, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
687 59, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
688 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
689 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
690 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
691 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
692 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
693 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7,
694 0, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
695 118, 118, 118, 118, 118, 118, 118, 118, 59, 118, 118, 118, 118, 118, 118, 118, 118,
696 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
697 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
698 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
699 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
700 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
701 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
702 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0,
703 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
704 0, 0, 0, 0, 228, 0, 0, 0, 64, 0, 65, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 7, 0, 118, 118, 118,
705 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
706 118, 118, 1, 0, 0, 10, 118, 118, 118, 118, 118, 118, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0,
707 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
708 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 64,
709 0, 65, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 7, 0, 118, 118, 118, 118, 118, 118, 118, 118, 118,
710 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 1, 0, 0, 10, 118, 118,
711 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
712 118, 118, 118, 118, 118, 118, 118, 118, 118, 1, 2, 118, 118, 118, 118, 118, 118, 118,
713 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
714 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
715 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
716 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 0, 0, 118, 118, 118, 118,
717 118, 118, 118, 118, 118, 118, 118, 0, 0, 0, 0, 96, 96,
718 ];
719
720 let mut buf = [0; 1024];
721 let _ = Packet::<1024>::fully_decode(&data, &mut buf);
722 }
723
724 #[test]
725 fn semi_decode_fuzz_tests() {
726 let cases = [
727 &[
728 42, 64, 64, 64, 229, 40, 64, 64, 0, 0, 173, 173, 173, 173, 173, 173, 173, 173, 64,
729 64, 0, 0, 173, 187, 187, 187, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
730 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 187, 187,
731 187, 101, 157, 138, 74, 101, 157, 138, 74, 0, 0, 0, 0, 1, 126, 255, 255, 255, 187,
732 187, 187, 187, 187, 187, 187, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
733 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 187, 101, 157, 138, 74, 101,
734 157, 138, 106, 0, 0, 0, 0, 1, 126, 255, 255, 255, 0, 212, 0, 0, 0, 0, 1, 187, 187,
735 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
736 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 173, 187, 187, 187, 101,
737 157, 138, 74, 101, 157, 138, 74, 0, 0, 0, 0, 1, 126, 255, 255, 255, 0, 212, 0, 0,
738 0, 0, 1, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
739 187, 187, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 157, 138, 74, 0, 0, 0,
740 0, 1, 126, 255, 255, 255, 0, 212, 0, 0, 0, 0, 1, 187, 187, 187, 187, 187, 187, 187,
741 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
742 187, 187, 187, 187, 187, 187, 173, 187, 187, 64, 187, 101, 157, 138, 74, 101, 157,
743 50, 138, 74, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
744 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
745 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
746 255, 255, 255, 255, 255, 1, 126, 255, 255, 255, 0, 212, 0, 0, 0, 0, 1, 187, 187,
747 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
748 187, 187, 187, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
749 173, 173, 173, 173, 173, 173, 64, 64, 0, 0, 173, 173, 173, 173, 173, 173, 173, 173,
750 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
751 173, 187, 187, 187, 101, 157, 138, 74, 101, 157, 138, 74, 0, 0, 0, 0, 1, 126, 255,
752 255, 255, 0, 212, 0, 0, 0, 0, 1, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
753 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
754 187, 187, 187, 173, 187, 187, 187, 101, 157, 138, 74, 101, 157, 138, 74, 0, 0, 0,
755 0, 1, 126, 255, 255, 255, 0, 212, 0, 0, 0, 0, 1, 187, 187, 0, 0, 192, 192, 0, 187,
756 187, 187, 187, 187, 187, 187, 187, 187, 187, 173, 173, 173, 173, 173, 173, 173,
757 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
758 173, 64, 64, 0, 0, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
759 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 187, 187, 187, 101,
760 157, 138, 74, 101, 157, 138, 74, 0, 0, 0, 0, 1, 126, 255, 255, 255, 0, 212, 0, 0,
761 0, 0, 1, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
762 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
763 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
764 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 126,
765 ][..],
766 &[
767 48, 5, 4, 255, 5, 5, 5, 5, 5, 5, 5, 37, 5, 7, 5, 5, 35, 5, 5, 5, 5, 4, 5, 7, 5, 5,
768 5, 5, 5, 5, 5, 5, 11, 126, 3, 101, 5, 3, 3, 96, 192, 128, 192, 192,
769 ][..],
770 ];
771
772 for data in cases {
773 let mut buf = [0; 1024];
774 let mut buf = Buffer::new_empty(&mut buf);
775 buf.extend(data);
776 let _ = Packet::<1024>::semi_decode(buf);
777 }
778 }
779
780 #[test]
781 fn decode_fuzz_tests() {
782 let cases = [&[4, 0, 0, 0][..], &[4, 5, 0, 0, 0, 10, 255, 255, 0, 0][..]];
783
784 for data in cases {
785 let mut buf = [0; 1024];
786 let mut buf = Buffer::new_empty(&mut buf);
787 buf.extend(data);
788 let _ = Packet::<1024>::decode(buf);
789 }
790 }
791
792 #[test]
793 fn fully_decode_soft_fuzz_tests() {
794 let cases = [
796 &mut [
797 -39, -39, -39, -118, -58, -58, -58, -58, -89, -39, -118, -58, -58, -58, 34, 34, 34,
798 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -58, -58,
799 127, 81, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
800 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -86, 127, 127, 127, 127, 127,
801 127, 127, 127, 127, 127, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -58, -58, 127,
802 81, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 34, 34, 34, 34, 34, 34, 34,
803 34, 34, 34, 34, -58, -58, 127, 81, 127, 127, 127, 127, 127, 127, 127, 127, 127,
804 127, 127, 127, 127, 127, 127, -128, -128, -128, -128, -128, -128, -128, -128, -128,
805 -128, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -128, -128,
806 ][..],
807 &mut [
808 -73, -73, -73, -73, -75, -76, -73, -73, -73, -73, -73, -73, -73, -73, 73, 72, 72,
809 72, 72, 72, 72, 62, -73, -118, 120, 127, 127, 121, 127, 112, 127, 127,
810 ],
811 ];
812
813 for data in cases {
814 let mut buf = [0; 1024];
815 let _ = Packet::<1024>::fully_decode_soft::<8192, i8>(data, &mut buf);
816 }
817 }
818}