bluerobotics_ping/
decoder.rs1use tracing::debug;
2
3use crate::message::{ProtocolMessage, HEADER};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, PartialEq, Clone)]
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9pub enum ParseError {
10 InvalidStartByte,
11 IncompleteData,
12 ChecksumError(ProtocolMessage),
13}
14
15#[derive(Clone, Debug)]
16pub enum DecoderState {
17 AwaitingStart1,
18 AwaitingStart2,
19 ReadingHeader,
20 ReadingPayload,
21 ReadingChecksum,
22}
23
24#[derive(Debug)]
25pub enum DecoderResult {
26 Success(ProtocolMessage),
27 InProgress(DecoderState),
28 Error(ParseError),
29}
30
31pub struct Decoder {
32 pub state: DecoderState,
33 buffer: Vec<u8>,
34 message: ProtocolMessage,
35}
36
37impl Decoder {
38 pub fn new() -> Self {
39 Self {
40 state: DecoderState::AwaitingStart1,
41 buffer: Vec::new(),
42 message: ProtocolMessage::new(),
43 }
44 }
45
46 pub fn parse_byte(&mut self, byte: u8) -> DecoderResult {
47 debug!("Parsing byte: 0x{byte:02x} ({byte})");
48 let state = &self.state;
49 match state {
50 DecoderState::AwaitingStart1 => {
51 if byte == HEADER[0] {
52 self.state = DecoderState::AwaitingStart2;
53 return DecoderResult::InProgress(self.state.clone());
54 }
55 return DecoderResult::Error(ParseError::InvalidStartByte);
56 }
57 DecoderState::AwaitingStart2 => {
58 if byte == HEADER[1] {
59 self.state = DecoderState::ReadingHeader;
60 self.buffer.clear();
61 return DecoderResult::InProgress(self.state.clone());
62 }
63 self.state = DecoderState::AwaitingStart1;
64 return DecoderResult::Error(ParseError::InvalidStartByte);
65 }
66 DecoderState::ReadingHeader => {
67 self.buffer.push(byte);
68 if self.buffer.len() == 6 {
70 self.message.payload_length =
71 u16::from_le_bytes([self.buffer[0], self.buffer[1]]);
72 self.message.message_id = u16::from_le_bytes([self.buffer[2], self.buffer[3]]);
73 self.message.src_device_id = self.buffer[4];
74 self.message.dst_device_id = self.buffer[5];
75
76 if self.message.payload_length == 0 {
77 self.state = DecoderState::ReadingChecksum
78 } else {
79 self.state = DecoderState::ReadingPayload;
80 }
81 self.buffer.clear();
82 }
83 return DecoderResult::InProgress(self.state.clone());
84 }
85 DecoderState::ReadingPayload => {
86 self.buffer.push(byte);
87 debug!(
88 "DecoderState : ReadingPayload {:?} of {:?}",
89 self.buffer.len(),
90 self.message.payload_length
91 );
92 if self.buffer.len() == self.message.payload_length as usize {
93 self.message.payload = self.buffer.clone();
94 self.state = DecoderState::ReadingChecksum;
95 self.buffer.clear();
96 }
97 return DecoderResult::InProgress(self.state.clone());
98 }
99 DecoderState::ReadingChecksum => {
100 self.buffer.push(byte);
101 if self.buffer.len() == 2 {
102 self.message.checksum = u16::from_le_bytes([self.buffer[0], self.buffer[1]]);
103 self.reset();
104 let message = self.message.clone();
105 self.message = ProtocolMessage::new();
106 if !message.has_valid_crc() {
107 return DecoderResult::Error(ParseError::ChecksumError(message));
108 }
109 return DecoderResult::Success(message);
110 }
111 return DecoderResult::InProgress(self.state.clone());
112 }
113 }
114 }
115
116 fn reset(&mut self) {
117 self.state = DecoderState::AwaitingStart1;
118 self.buffer.clear();
119 }
120}