electricui_embedded/
decoder.rs1use crate::sealed;
2use crate::wire::{packet, Packet};
3use err_derive::Error;
4
5#[derive(Debug, Copy, Clone, Eq, PartialEq, Error)]
6pub enum Error {
7 #[error(display = "Not enough bytes in the decoder buffer to store the frame")]
8 InsufficientBufferSize,
9
10 #[error(display = "Encountered a packet error. {}", _0)]
11 PacketError(#[error(source)] packet::Error),
12}
13
14#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
15enum State {
16 FrameOffset,
17 HeaderB0,
18 HeaderB1,
19 HeaderB2,
20 MsgId,
21 OffsetB0,
22 OffsetB1,
23 Payload,
24 CrcB0,
25 CrcB1,
26}
27
28#[derive(Debug)]
29pub struct Decoder<'buf, const N: usize> {
30 state: State,
31
32 frame_offset: u8,
33 id_bytes_read: u8,
34 data_bytes_read: u16,
35 bytes_read: usize,
36 valid_pkt_count: usize,
37 invalid_pkt_count: usize,
38
39 data_len: u16,
40 offset: bool,
41 id_len: u8,
42
43 packet_storage: &'buf mut [u8; N],
44}
45
46impl<'buf, const N: usize> Decoder<'buf, N> {
47 pub fn new(packet_storage: &'buf mut [u8; N]) -> Self {
48 sealed::greater_than_eq::<N, { Packet::<&[u8]>::BASE_PACKET_SIZE }>();
49 Self {
50 state: State::FrameOffset,
51 frame_offset: 0,
52 id_bytes_read: 0,
53 data_bytes_read: 0,
54 bytes_read: 0,
55 valid_pkt_count: 0,
56 invalid_pkt_count: 0,
57 data_len: 0,
58 offset: false,
59 id_len: 0,
60 packet_storage,
61 }
62 }
63
64 #[inline]
65 pub fn reset(&mut self) {
66 self.state = State::FrameOffset;
67 self.frame_offset = 0;
68 self.bytes_read = 0;
69 }
70
71 pub fn count(&self) -> usize {
72 self.valid_pkt_count
73 }
74
75 pub fn invalid_count(&self) -> usize {
76 self.invalid_pkt_count
77 }
78
79 pub fn decode(&mut self, mut byte: u8) -> Result<Option<Packet<&[u8]>>, Error> {
80 if byte == 0x00 {
82 self.reset();
83 return Ok(None);
84 } else if self.frame_offset > 1 {
85 self.frame_offset -= 1;
87 } else {
88 self.frame_offset = byte;
90 byte = 0x00;
91 }
92
93 match self.state {
94 State::FrameOffset => {
95 self.state = State::HeaderB0;
97 }
98 State::HeaderB0 => {
99 self.feed(byte)?;
100 self.data_len = byte as _;
101 self.state = State::HeaderB1;
102 }
103 State::HeaderB1 => {
104 self.feed(byte)?;
105 self.data_len |= ((byte as u16) << 8) & 0x0300;
106 self.offset = ((byte >> 7) & 0x01) != 0;
107 self.state = State::HeaderB2;
108 }
109 State::HeaderB2 => {
110 self.feed(byte)?;
111 self.id_len = byte & 0x0F;
112 self.id_bytes_read = 0;
113 self.state = State::MsgId;
114 }
115 State::MsgId => {
116 self.feed(byte)?;
117 self.id_bytes_read = self.id_bytes_read.saturating_add(1);
118 if self.id_bytes_read >= self.id_len {
119 if self.offset {
120 self.state = State::OffsetB0
121 } else if self.data_len > 0 {
122 self.data_bytes_read = 0;
123 self.state = State::Payload;
124 } else {
125 self.state = State::CrcB0;
126 }
127 }
128 }
129 State::OffsetB0 => {
130 self.feed(byte)?;
132 self.state = State::OffsetB1;
133 }
134 State::OffsetB1 => {
135 self.feed(byte)?;
137 self.state = State::Payload;
138 }
139 State::Payload => {
140 self.feed(byte)?;
141 self.data_bytes_read = self.data_bytes_read.saturating_add(1);
142 if self.data_bytes_read >= self.data_len {
143 self.state = State::CrcB0;
144 }
145 }
146 State::CrcB0 => {
147 self.feed(byte)?;
148 self.state = State::CrcB1;
149 }
150 State::CrcB1 => {
151 self.feed(byte)?;
152 let bytes_read = self.bytes_read;
153 self.reset();
154 match Packet::new(&self.packet_storage[..bytes_read]) {
155 Ok(p) => {
156 self.valid_pkt_count = self.valid_pkt_count.saturating_add(1);
157 return Ok(p.into());
158 }
159 Err(e) => {
160 self.invalid_pkt_count = self.invalid_pkt_count.saturating_add(1);
161 return Err(e.into());
162 }
163 }
164 }
165 }
166
167 Ok(None)
168 }
169
170 #[inline]
171 fn feed(&mut self, byte: u8) -> Result<(), Error> {
172 if self.bytes_read >= self.packet_storage.len() {
173 Err(Error::InsufficientBufferSize)
174 } else {
175 self.packet_storage[self.bytes_read] = byte;
176 self.bytes_read = self.bytes_read.saturating_add(1);
177 Ok(())
178 }
179 }
180}
181
182#[cfg(test)]
183mod tests {
184 use super::*;
185 use pretty_assertions::assert_eq;
186
187 static MSG_F32: [u8; 12 + 2] = [
190 0x00, 0x0D, 0x04, 0x2c, 0x03, 0x61, 0x62, 0x63, 0x14, 0xAE, 0x29, 0x42, 0x8B, 0x1D, ];
196
197 #[test]
198 fn basic_decoding() {
199 let mut buffer = [0_u8; 512];
200 let mut dec = Decoder::new(&mut buffer);
201
202 for _ in 0..4 {
203 for (idx, byte) in MSG_F32.iter().enumerate() {
204 let maybe_frame = dec.decode(*byte).unwrap();
205 if idx < (MSG_F32.len() - 1) {
206 assert_eq!(maybe_frame.is_some(), false);
207 } else {
208 assert_eq!(maybe_frame.is_some(), true);
209 }
210 }
211
212 assert!(dec.decode(1).unwrap().is_none());
214 assert!(dec.decode(0).unwrap().is_none());
215 assert!(dec.decode(2).unwrap().is_none());
216 }
217
218 assert_eq!(dec.count(), 4);
219 assert_eq!(dec.invalid_count(), 0);
220 }
221}