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(
123 core::mem::take(&mut self.buffer),
124 ));
125 }
126 } else if byte == FEND {
127 self.in_frame = true;
129 self.command = CMD_UNKNOWN;
130 self.buffer.clear();
131 self.escape = false;
132 } else if self.in_frame {
133 if self.buffer.is_empty() && self.command == CMD_UNKNOWN {
134 self.command = byte & 0x0F;
136 } else if self.command == CMD_DATA {
137 if byte == FESC {
138 self.escape = true;
139 } else if self.escape {
140 match byte {
141 TFEND => self.buffer.push(FEND),
142 TFESC => self.buffer.push(FESC),
143 _ => self.buffer.push(byte),
144 }
145 self.escape = false;
146 } else {
147 self.buffer.push(byte);
148 }
149 } else if self.command == CMD_READY {
150 events.push(KissEvent::Ready);
151 self.command = CMD_UNKNOWN;
153 self.in_frame = false;
154 }
155 }
156 }
157
158 events
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165
166 #[test]
167 fn escape_fend() {
168 assert_eq!(escape(&[FEND]), vec![FESC, TFEND]);
169 assert_eq!(escape(&[0xC0]), vec![0xDB, 0xDC]);
170 }
171
172 #[test]
173 fn escape_fesc() {
174 assert_eq!(escape(&[FESC]), vec![FESC, TFESC]);
175 assert_eq!(escape(&[0xDB]), vec![0xDB, 0xDD]);
176 }
177
178 #[test]
179 fn escape_passthrough() {
180 let data = b"hello world";
181 assert_eq!(escape(data), data.to_vec());
182 }
183
184 #[test]
185 fn unescape_roundtrip() {
186 let data: Vec<u8> = (0..=255).collect();
188 let escaped = escape(&data);
189 let recovered = unescape(&escaped);
190 assert_eq!(recovered, data);
191 }
192
193 #[test]
194 fn frame_data() {
195 let data = b"test";
196 let framed = frame(data);
197 assert_eq!(framed[0], FEND);
198 assert_eq!(framed[1], CMD_DATA);
199 assert_eq!(*framed.last().unwrap(), FEND);
200 let middle = &framed[2..framed.len() - 1];
202 assert_eq!(middle, &escape(data)[..]);
203 }
204
205 #[test]
206 fn decoder_single_frame() {
207 let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
208 let framed = frame(&data);
209
210 let mut decoder = Decoder::new();
211 let events = decoder.feed(&framed);
212 assert_eq!(events.len(), 1);
213 assert_eq!(events[0], KissEvent::DataFrame(data));
214 }
215
216 #[test]
217 fn decoder_ready_event() {
218 let ready_frame = vec![FEND, CMD_READY, 0x01, FEND];
220
221 let mut decoder = Decoder::new();
222 let events = decoder.feed(&ready_frame);
223 assert_eq!(events.len(), 1);
224 assert_eq!(events[0], KissEvent::Ready);
225 }
226
227 #[test]
228 fn decoder_fragmented() {
229 let data = vec![0x01, 0x02, 0x03, 0x04, 0x05];
230 let framed = frame(&data);
231
232 let mut decoder = Decoder::new();
233
234 let mut all_events = Vec::new();
236 for &byte in &framed {
237 all_events.extend(decoder.feed(&[byte]));
238 }
239
240 assert_eq!(all_events.len(), 1);
241 assert_eq!(all_events[0], KissEvent::DataFrame(data));
242 }
243}