sbus_rs/parser/
blocking.rs1use crate::{error::SbusError, packet::SbusPacket, parser::SBUS_FRAME_LENGTH, Parser};
2use embedded_io::Read;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6pub struct Blocking {}
7impl super::Mode for Blocking {}
8impl super::Sealed for Blocking {}
9
10impl<R: Read> Parser<R, Blocking> {
11 pub fn new(reader: R) -> Self {
12 Self {
13 reader,
14 _mode: Default::default(),
15 }
16 }
17
18 pub fn read_frame(&mut self) -> Result<SbusPacket, SbusError> {
25 let mut buffer = [0u8; SBUS_FRAME_LENGTH];
26 self.reader
27 .read_exact(&mut buffer)
28 .map_err(|_| SbusError::ReadError)?;
29
30 SbusPacket::from_array(&buffer)
31 }
32}
33
34pub type SbusParser<R> = Parser<R, Blocking>;
35
36#[cfg(test)]
37mod tests {
38 use crate::{SbusError, SbusParser, CHANNEL_MAX};
39 use embedded_io_adapters::std::FromStd;
40 use std::io::Cursor;
41
42 const TEST_PACKET: [u8; 25] = [
43 0x0F, (1024 & 0x07FF) as u8,
45 (((1024 & 0x07FF) >> 8) | ((1024 & 0x07FF) << 3)) as u8,
46 (((1024 & 0x07FF) >> 5) | ((1024 & 0x07FF) << 6)) as u8,
47 ((1024 & 0x07FF) >> 2) as u8,
48 (((1024 & 0x07FF) >> 10) | ((1024 & 0x07FF) << 1)) as u8,
49 (((1024 & 0x07FF) >> 7) | ((1024 & 0x07FF) << 4)) as u8,
50 ((1024 & 0x07FF) >> 4) as u8,
51 ((1024 & 0x07FF) << 2) as u8,
52 (((1024 & 0x07FF) >> 8) | ((1024 & 0x07FF) << 5)) as u8,
53 ((1024 & 0x07FF) >> 1) as u8,
54 (((1024 & 0x07FF) >> 9) | ((1024 & 0x07FF) << 6)) as u8,
55 ((1024 & 0x07FF) >> 3) as u8,
56 (((1024 & 0x07FF) >> 10) | ((1024 & 0x07FF) << 1)) as u8,
57 (((1024 & 0x07FF) >> 7) | ((1024 & 0x07FF) << 4)) as u8,
58 ((1024 & 0x07FF) >> 4) as u8,
59 ((1024 & 0x07FF) << 2) as u8,
60 (((1024 & 0x07FF) >> 8) | ((1024 & 0x07FF) << 5)) as u8,
61 ((1024 & 0x07FF) >> 1) as u8,
62 (((1024 & 0x07FF) >> 9) | ((1024 & 0x07FF) << 6)) as u8,
63 ((1024 & 0x07FF) >> 3) as u8,
64 (((1024 & 0x07FF) >> 10) | ((1024 & 0x07FF) << 1)) as u8,
65 (((1024 & 0x07FF) >> 7) | ((1024 & 0x07FF) << 4)) as u8,
66 0x00, 0x00, ];
69
70 #[test]
71 fn test_valid_sbus_frame() {
72 let data = [
74 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
83 let cursor = Cursor::new(data);
84 let mut parser = SbusParser::new(FromStd::new(cursor));
85
86 let packet = parser.read_frame().expect("Should be a valid frame");
87
88 assert_eq!(packet.channels[0], 0);
89 assert_eq!(packet.channels[15], 0);
90 assert!(!packet.flags.d1);
91 assert!(!packet.flags.d2);
92 assert!(!packet.flags.frame_lost);
93 assert!(!packet.flags.failsafe);
94 }
95
96 #[test]
97 fn test_invalid_header() {
98 let mut data = TEST_PACKET;
100 data[0] = 0x00; let cursor = Cursor::new(data);
103 let mut parser = SbusParser::new(FromStd::new(cursor));
104
105 let result = parser.read_frame();
106 assert!(matches!(result, Err(SbusError::InvalidHeader(0x00))));
107 }
108
109 #[test]
110 fn test_invalid_footer() {
111 let mut data = TEST_PACKET;
112 data[24] = 0xFF; let cursor = Cursor::new(data);
115 let mut parser = SbusParser::new(FromStd::new(cursor));
116
117 let result = parser.read_frame();
118 assert!(matches!(result, Err(SbusError::InvalidFooter(0xFF))));
119 }
120
121 #[test]
122 fn test_flag_bytes() {
123 let mut data = TEST_PACKET;
124 data[23] = 0b00001111; let cursor = Cursor::new(data);
127 let mut parser = SbusParser::new(FromStd::new(cursor));
128
129 let result = parser.read_frame();
130 assert!(result.is_ok());
131 let packet = result.unwrap();
132 assert!(packet.flags.d1);
133 assert!(packet.flags.d2);
134 assert!(packet.flags.frame_lost);
135 assert!(packet.flags.failsafe);
136 }
137
138 #[test]
139 fn test_partial_frame() {
140 let data = &TEST_PACKET[..20]; let cursor = Cursor::new(data);
143 let mut parser = SbusParser::new(FromStd::new(cursor));
144
145 let result = parser.read_frame();
146 assert!(matches!(result, Err(SbusError::ReadError)));
147 }
148
149 #[test]
150 fn test_channel_decoding() {
151 let mut data = [0u8; 25];
152 data[0] = 0x0F; data[1] = 0;
155 data[2] = 0;
156 data[2] |= (CHANNEL_MAX << 3) as u8; data[3] = ((CHANNEL_MAX >> 5) & 0xFF) as u8; data[4] = ((CHANNEL_MAX >> 5) & 0x07) as u8; data[24] = 0x00; let cursor = Cursor::new(data);
163 let mut parser = SbusParser::new(FromStd::new(cursor));
164
165 let result = parser.read_frame();
166 assert!(result.is_ok());
167 let packet = result.unwrap();
168 assert_eq!(packet.channels[0], 0); assert_eq!(packet.channels[1], CHANNEL_MAX); }
171}