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
160#[cfg(test)]
161mod tests {
162 use super::*;
163
164 #[test]
165 fn escape_fend() {
166 assert_eq!(escape(&[FEND]), vec![FESC, TFEND]);
167 assert_eq!(escape(&[0xC0]), vec![0xDB, 0xDC]);
168 }
169
170 #[test]
171 fn escape_fesc() {
172 assert_eq!(escape(&[FESC]), vec![FESC, TFESC]);
173 assert_eq!(escape(&[0xDB]), vec![0xDB, 0xDD]);
174 }
175
176 #[test]
177 fn escape_passthrough() {
178 let data = b"hello world";
179 assert_eq!(escape(data), data.to_vec());
180 }
181
182 #[test]
183 fn unescape_roundtrip() {
184 let data: Vec<u8> = (0..=255).collect();
186 let escaped = escape(&data);
187 let recovered = unescape(&escaped);
188 assert_eq!(recovered, data);
189 }
190
191 #[test]
192 fn frame_data() {
193 let data = b"test";
194 let framed = frame(data);
195 assert_eq!(framed[0], FEND);
196 assert_eq!(framed[1], CMD_DATA);
197 assert_eq!(*framed.last().unwrap(), FEND);
198 let middle = &framed[2..framed.len() - 1];
200 assert_eq!(middle, &escape(data)[..]);
201 }
202
203 #[test]
204 fn decoder_single_frame() {
205 let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
206 let framed = frame(&data);
207
208 let mut decoder = Decoder::new();
209 let events = decoder.feed(&framed);
210 assert_eq!(events.len(), 1);
211 assert_eq!(events[0], KissEvent::DataFrame(data));
212 }
213
214 #[test]
215 fn decoder_ready_event() {
216 let ready_frame = vec![FEND, CMD_READY, 0x01, FEND];
218
219 let mut decoder = Decoder::new();
220 let events = decoder.feed(&ready_frame);
221 assert_eq!(events.len(), 1);
222 assert_eq!(events[0], KissEvent::Ready);
223 }
224
225 #[test]
226 fn decoder_fragmented() {
227 let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
228 let framed = frame(&data);
229
230 let mut decoder = Decoder::new();
231
232 let mut all_events = Vec::new();
234 for &byte in &framed {
235 all_events.extend(decoder.feed(&[byte]));
236 }
237
238 assert_eq!(all_events.len(), 1);
239 assert_eq!(all_events[0], KissEvent::DataFrame(data));
240 }
241}