1use bytes::{Buf, BufMut, BytesMut};
4use crate::error::{S101Error, Result};
5use super::constants::*;
6use super::frame::{S101Frame, S101Message, EmberFlags};
7use super::crc;
8
9#[derive(Debug, Default)]
11pub struct S101Decoder {
12 buffer: BytesMut,
13 in_frame: bool,
14 escape_next: bool,
15}
16
17impl S101Decoder {
18 pub fn new() -> Self {
20 S101Decoder {
21 buffer: BytesMut::new(),
22 in_frame: false,
23 escape_next: false,
24 }
25 }
26
27 pub fn feed(&mut self, data: &[u8]) {
29 for &byte in data {
30 self.process_byte(byte);
31 }
32 }
33
34 fn process_byte(&mut self, byte: u8) {
36 if self.escape_next {
37 self.buffer.put_u8(byte ^ ESCAPE_XOR);
38 self.escape_next = false;
39 } else if byte == BOF {
40 self.buffer.clear();
42 self.in_frame = true;
43 } else if byte == EOF {
44 if self.in_frame && !self.buffer.is_empty() {
45 self.in_frame = false;
47 }
48 } else if byte == ESCAPE_BYTE && self.in_frame {
49 self.escape_next = true;
50 } else if self.in_frame {
51 self.buffer.put_u8(byte);
52 }
53 }
54
55 pub fn decode_frame(&mut self) -> Result<Option<S101Frame>> {
57 if self.buffer.is_empty() || self.in_frame {
58 return Ok(None);
59 }
60
61 if self.buffer.len() < 5 {
63 self.buffer.clear();
65 return Err(S101Error::IncompleteFrame.into());
66 }
67
68 if !crc::verify_crc(&self.buffer) {
69 let len = self.buffer.len();
70 let received = u16::from_be_bytes([self.buffer[len - 2], self.buffer[len - 1]]);
71 let calculated = crc::calculate_crc(&self.buffer[..len - 2]);
72 self.buffer.clear();
73 return Err(S101Error::CrcMismatch {
74 expected: calculated,
75 actual: received,
76 }.into());
77 }
78
79 let payload_len = self.buffer.len() - 2;
81 self.buffer.truncate(payload_len);
82
83 let data = self.buffer.split();
85
86 if data.len() < 3 {
87 return Err(S101Error::IncompleteFrame.into());
88 }
89
90 let slot = data[0];
91 let message_type = super::frame::MessageType::try_from(data[1])?;
92 let command = super::frame::Command::try_from(data[2])?;
93
94 let payload = match command {
96 super::frame::Command::KeepAliveRequest | super::frame::Command::KeepAliveResponse => {
97 vec![]
99 }
100 super::frame::Command::Ember => {
101 if data.len() < 7 {
103 return Err(S101Error::IncompleteFrame.into());
104 }
105 let app_bytes_count = data[6] as usize;
106 let payload_start = 7 + app_bytes_count;
107 if payload_start > data.len() {
108 return Err(S101Error::IncompleteFrame.into());
109 }
110 data[payload_start..].to_vec()
111 }
112 };
113
114 Ok(Some(S101Frame {
115 slot,
116 message_type,
117 command,
118 payload,
119 }))
120 }
121
122 pub fn decode_message(&mut self) -> Result<Option<S101Message>> {
124 if let Some(frame) = self.decode_frame()? {
125 Ok(Some(frame.to_message()))
126 } else {
127 Ok(None)
128 }
129 }
130}
131
132#[derive(Debug, Default)]
134pub struct S101Encoder;
135
136impl S101Encoder {
137 pub fn new() -> Self {
139 S101Encoder
140 }
141
142 pub fn encode_ember_packet(payload: &[u8]) -> Vec<u8> {
144 let frame = S101Frame::ember_data(payload.to_vec());
145 frame.encode()
146 }
147
148 pub fn encode_keepalive_request() -> Vec<u8> {
150 S101Frame::keepalive_request().encode()
151 }
152
153 pub fn encode_keepalive_response() -> Vec<u8> {
155 S101Frame::keepalive_response().encode()
156 }
157
158 pub fn encode_message(message: &S101Message) -> Vec<u8> {
160 match message {
161 S101Message::EmberData { payload, .. } => {
162 Self::encode_ember_packet(payload)
163 }
164 S101Message::KeepAliveRequest => Self::encode_keepalive_request(),
165 S101Message::KeepAliveResponse => Self::encode_keepalive_response(),
166 }
167 }
168
169 fn encode_with_framing(data: &[u8]) -> Vec<u8> {
171 let mut output = Vec::with_capacity(data.len() * 2 + 4);
172 output.push(BOF);
173
174 for &byte in data {
175 if byte == BOF || byte == EOF || byte == ESCAPE_BYTE {
177 output.push(ESCAPE_BYTE);
178 output.push(byte ^ ESCAPE_XOR);
179 } else {
180 output.push(byte);
181 }
182 }
183
184 output.push(EOF);
185 output
186 }
187}
188
189pub struct S101Codec {
191 pub decoder: S101Decoder,
193 pub encoder: S101Encoder,
195}
196
197impl S101Codec {
198 pub fn new() -> Self {
200 S101Codec {
201 decoder: S101Decoder::new(),
202 encoder: S101Encoder::new(),
203 }
204 }
205
206 pub fn feed(&mut self, data: &[u8]) {
208 self.decoder.feed(data);
209 }
210
211 pub fn decode_frame(&mut self) -> Result<Option<S101Frame>> {
213 self.decoder.decode_frame()
214 }
215
216 pub fn encode_ember_packet(&self, payload: &[u8]) -> Vec<u8> {
218 S101Encoder::encode_ember_packet(payload)
219 }
220}
221
222impl Default for S101Codec {
223 fn default() -> Self {
224 Self::new()
225 }
226}
227
228#[cfg(test)]
229mod tests {
230 use super::*;
231
232 #[test]
233 fn test_decoder_basic() {
234 let mut decoder = S101Decoder::new();
235
236 let frame = S101Frame::ember_data(vec![0x01, 0x02, 0x03]);
238 let encoded = frame.encode();
239
240 decoder.feed(&encoded);
241 let decoded = decoder.decode_frame().unwrap().unwrap();
242
243 assert_eq!(decoded.payload, vec![0x01, 0x02, 0x03]);
244 }
245
246 #[test]
247 fn test_decoder_streaming() {
248 let mut decoder = S101Decoder::new();
249
250 let frame = S101Frame::ember_data(vec![0xAA, 0xBB, 0xCC]);
251 let encoded = frame.encode();
252
253 for &byte in &encoded {
255 decoder.feed(&[byte]);
256 }
257
258 let decoded = decoder.decode_frame().unwrap().unwrap();
259 assert_eq!(decoded.payload, vec![0xAA, 0xBB, 0xCC]);
260 }
261
262 #[test]
263 fn test_keepalive_roundtrip() {
264 let mut decoder = S101Decoder::new();
265
266 let encoded = S101Encoder::encode_keepalive_request();
267 decoder.feed(&encoded);
268
269 let message = decoder.decode_message().unwrap().unwrap();
270 assert!(message.is_keepalive_request());
271 }
272}