1pub const FEND: u8 = 0xC0;
6pub const FESC: u8 = 0xDB;
7pub const TFEND: u8 = 0xDC;
8pub const TFESC: u8 = 0xDD;
9
10pub const CMD_DATA: u8 = 0x00;
11pub const CMD_TXDELAY: u8 = 0x01;
12pub const CMD_P: u8 = 0x02;
13pub const CMD_SLOTTIME: u8 = 0x03;
14pub const CMD_TXTAIL: u8 = 0x04;
15pub const CMD_FULLDUPLEX: u8 = 0x05;
16pub const CMD_SETHARDWARE: u8 = 0x06;
17pub const CMD_READY: u8 = 0x0F;
18pub const CMD_RETURN: u8 = 0xFF;
19pub const CMD_UNKNOWN: u8 = 0xFE;
20
21pub fn escape(data: &[u8]) -> Vec<u8> {
24 let mut out = Vec::with_capacity(data.len());
25 for &b in data {
26 match b {
27 FESC => {
28 out.push(FESC);
29 out.push(TFESC);
30 }
31 FEND => {
32 out.push(FESC);
33 out.push(TFEND);
34 }
35 _ => out.push(b),
36 }
37 }
38 out
39}
40
41pub fn unescape(data: &[u8]) -> Vec<u8> {
43 let mut out = Vec::with_capacity(data.len());
44 let mut esc = false;
45 for &b in data {
46 if esc {
47 match b {
48 TFEND => out.push(FEND),
49 TFESC => out.push(FESC),
50 _ => out.push(b), }
52 esc = false;
53 } else if b == FESC {
54 esc = true;
55 } else {
56 out.push(b);
57 }
58 }
59 out
60}
61
62pub fn frame(data: &[u8]) -> Vec<u8> {
64 let escaped = escape(data);
65 let mut out = Vec::with_capacity(escaped.len() + 3);
66 out.push(FEND);
67 out.push(CMD_DATA);
68 out.extend_from_slice(&escaped);
69 out.push(FEND);
70 out
71}
72
73pub fn command_frame(cmd: u8, value: &[u8]) -> Vec<u8> {
75 let escaped = escape(value);
76 let mut out = Vec::with_capacity(escaped.len() + 3);
77 out.push(FEND);
78 out.push(cmd);
79 out.extend_from_slice(&escaped);
80 out.push(FEND);
81 out
82}
83
84#[derive(Debug, Clone, PartialEq)]
86pub enum KissEvent {
87 DataFrame(Vec<u8>),
89 Ready,
91}
92
93pub struct Decoder {
97 in_frame: bool,
98 escape: bool,
99 command: u8,
100 buffer: Vec<u8>,
101}
102
103impl Decoder {
104 pub fn new() -> Self {
105 Decoder {
106 in_frame: false,
107 escape: false,
108 command: CMD_UNKNOWN,
109 buffer: Vec::new(),
110 }
111 }
112
113 pub fn feed(&mut self, bytes: &[u8]) -> Vec<KissEvent> {
115 let mut events = Vec::new();
116
117 for &byte in bytes {
118 if self.in_frame && byte == FEND && self.command == CMD_DATA {
119 self.in_frame = false;
121 if !self.buffer.is_empty() {
122 events.push(KissEvent::DataFrame(core::mem::take(&mut self.buffer)));
123 }
124 } else if byte == FEND {
125 self.in_frame = true;
127 self.command = CMD_UNKNOWN;
128 self.buffer.clear();
129 self.escape = false;
130 } else if self.in_frame {
131 if self.buffer.is_empty() && self.command == CMD_UNKNOWN {
132 self.command = byte & 0x0F;
134 } else if self.command == CMD_DATA {
135 if byte == FESC {
136 self.escape = true;
137 } else if self.escape {
138 match byte {
139 TFEND => self.buffer.push(FEND),
140 TFESC => self.buffer.push(FESC),
141 _ => self.buffer.push(byte),
142 }
143 self.escape = false;
144 } else {
145 self.buffer.push(byte);
146 }
147 } else if self.command == CMD_READY {
148 events.push(KissEvent::Ready);
149 self.command = CMD_UNKNOWN;
151 self.in_frame = false;
152 }
153 }
154 }
155
156 events
157 }
158}
159
160impl Default for Decoder {
161 fn default() -> Self {
162 Self::new()
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169
170 #[test]
171 fn escape_fend() {
172 assert_eq!(escape(&[FEND]), vec![FESC, TFEND]);
173 assert_eq!(escape(&[0xC0]), vec![0xDB, 0xDC]);
174 }
175
176 #[test]
177 fn escape_fesc() {
178 assert_eq!(escape(&[FESC]), vec![FESC, TFESC]);
179 assert_eq!(escape(&[0xDB]), vec![0xDB, 0xDD]);
180 }
181
182 #[test]
183 fn escape_passthrough() {
184 let data = b"hello world";
185 assert_eq!(escape(data), data.to_vec());
186 }
187
188 #[test]
189 fn unescape_roundtrip() {
190 let data: Vec<u8> = (0..=255).collect();
192 let escaped = escape(&data);
193 let recovered = unescape(&escaped);
194 assert_eq!(recovered, data);
195 }
196
197 #[test]
198 fn frame_data() {
199 let data = b"test";
200 let framed = frame(data);
201 assert_eq!(framed[0], FEND);
202 assert_eq!(framed[1], CMD_DATA);
203 assert_eq!(*framed.last().unwrap(), FEND);
204 let middle = &framed[2..framed.len() - 1];
206 assert_eq!(middle, &escape(data)[..]);
207 }
208
209 #[test]
210 fn decoder_single_frame() {
211 let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
212 let framed = frame(&data);
213
214 let mut decoder = Decoder::new();
215 let events = decoder.feed(&framed);
216 assert_eq!(events.len(), 1);
217 assert_eq!(events[0], KissEvent::DataFrame(data));
218 }
219
220 #[test]
221 fn decoder_ready_event() {
222 let ready_frame = vec![FEND, CMD_READY, 0x01, FEND];
224
225 let mut decoder = Decoder::new();
226 let events = decoder.feed(&ready_frame);
227 assert_eq!(events.len(), 1);
228 assert_eq!(events[0], KissEvent::Ready);
229 }
230
231 #[test]
232 fn decoder_fragmented() {
233 let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
234 let framed = frame(&data);
235
236 let mut decoder = Decoder::new();
237
238 let mut all_events = Vec::new();
240 for &byte in &framed {
241 all_events.extend(decoder.feed(&[byte]));
242 }
243
244 assert_eq!(all_events.len(), 1);
245 assert_eq!(all_events[0], KissEvent::DataFrame(data));
246 }
247}