orouter_serial/host/
codec.rs

1use heapless::Vec;
2
3const MAX_BLE_FRAME_LENGTH: usize = 128; // BLE can only process this
4pub const MAX_USB_FRAME_LENGTH: usize = 256; // USB can only process this
5///
6/// cannot run calculation in const declaration
7/// calculation is min(1, MAX_MESSAGE_LENGTH_HEX_ENCODED % MAX_SERIAL_FRAME_LENGTH);
8/// which is min(1, 520 % 128) = min(1, 8) = 1
9const MAX_BLE_FRAMES_COUNT_REMAINDER: usize = 1;
10
11/// cannot run calculation in const declaration
12/// calculation is min(1, MAX_MESSAGE_LENGTH_HEX_ENCODED % MAX_SERIAL_FRAME_LENGTH);
13/// which is min(1, 260 % 256) = min(1, 1) = 1
14///
15const MAX_USB_FRAMES_COUNT_REMAINDER: usize = 1;
16
17pub const MAX_USB_FRAMES_COUNT: usize =
18    super::MAX_MESSAGE_LENGTH / MAX_USB_FRAME_LENGTH + MAX_USB_FRAMES_COUNT_REMAINDER;
19
20pub const MAX_BLE_FRAMES_COUNT: usize =
21    MAX_MESSAGE_LENGTH_HEX_ENCODED / MAX_BLE_FRAME_LENGTH + MAX_BLE_FRAMES_COUNT_REMAINDER;
22
23pub const MAX_MESSAGE_LENGTH_HEX_ENCODED: usize = 2 * super::MAX_MESSAGE_LENGTH; // hex encoding - each byte = 2 chars
24
25const MAX_BGX13_MESSAGE_LENGTH: usize = 32;
26const MAX_BGX13_FRAMES_COUNT: usize = 9;
27
28const MAX_BT4502_MESSAGE_LENGTH: usize = 240;
29const MAX_BT4502_FRAMES_COUNT: usize = 3;
30
31type UsbSerialFrameVec = Vec<u8, MAX_USB_FRAME_LENGTH>;
32type BleSerialFrameVec = Vec<u8, MAX_BLE_FRAME_LENGTH>;
33type Bgx13SerialFrameVec = Vec<u8, MAX_BGX13_MESSAGE_LENGTH>;
34type Bt4502SerialFrameVec = Vec<u8, MAX_BT4502_MESSAGE_LENGTH>;
35
36pub trait WireCodec {
37    const MESSAGE_DELIMITER: Option<char>;
38    type Frames;
39    type IncomingFrame: IntoIterator<Item = u8> + AsRef<[u8]>;
40
41    fn get_frames(data: &[u8]) -> Result<Self::Frames, CodecError>;
42    fn decode_frame(data: &[u8]) -> Result<(Self::IncomingFrame, usize), CodecError>;
43}
44
45#[derive(PartialEq)]
46#[cfg_attr(feature = "std", derive(Debug))]
47pub enum CodecError {
48    FrameCreateError,
49    DecodeError,
50    MalformedHex(base16::DecodeError),
51}
52
53impl From<base16::DecodeError> for CodecError {
54    fn from(e: base16::DecodeError) -> CodecError {
55        CodecError::MalformedHex(e)
56    }
57}
58
59pub struct Rn4870Codec {}
60
61impl WireCodec for Rn4870Codec {
62    const MESSAGE_DELIMITER: Option<char> = Some('%');
63    type Frames = Vec<BleSerialFrameVec, MAX_BLE_FRAMES_COUNT>;
64    type IncomingFrame = BleSerialFrameVec;
65
66    fn get_frames(data: &[u8]) -> Result<Self::Frames, CodecError> {
67        let mut hex_result = Vec::<u8, MAX_MESSAGE_LENGTH_HEX_ENCODED>::new();
68        hex_result
69            .resize_default(data.len() * 2)
70            .map_err(|_| CodecError::FrameCreateError)?;
71        base16::encode_config_slice(&data, base16::EncodeLower, &mut hex_result);
72
73        // wrap each chunk in a delimiter char
74        let mut frames = Vec::<BleSerialFrameVec, MAX_BLE_FRAMES_COUNT>::new();
75        for chunk in hex_result.chunks(MAX_BLE_FRAME_LENGTH - 2) {
76            let mut frame = BleSerialFrameVec::new();
77            if let Some(delim) = Self::MESSAGE_DELIMITER {
78                frame
79                    .push(delim as u8)
80                    .map_err(|_| CodecError::FrameCreateError)?;
81            };
82            frame
83                .extend_from_slice(&chunk)
84                .map_err(|_| CodecError::FrameCreateError)?;
85            if let Some(delim) = Self::MESSAGE_DELIMITER {
86                frame
87                    .push(delim as u8)
88                    .map_err(|_| CodecError::FrameCreateError)?;
89            };
90            frames
91                .push(frame)
92                .map_err(|_| CodecError::FrameCreateError)?
93        }
94        Ok(frames)
95    }
96
97    fn decode_frame(data: &[u8]) -> Result<(Self::IncomingFrame, usize), CodecError> {
98        let mut decoded = Vec::<u8, 64>::new();
99        decoded
100            .resize_default(64)
101            .map_err(|_| CodecError::DecodeError)?;
102        match base16::decode_slice(&data, &mut decoded) {
103            Ok(decoded_len) => {
104                let result = Vec::from_slice(&decoded[0..decoded_len])
105                    .map_err(|_| CodecError::DecodeError)?;
106                Ok((result, decoded_len))
107            }
108            Err(e) => Err(CodecError::MalformedHex(e)),
109        }
110    }
111}
112
113pub struct UsbCodec {}
114
115impl UsbCodec {
116    pub fn get_frames_iter(data: &[u8]) -> impl Iterator<Item = &[u8]> {
117        data.chunks(MAX_USB_FRAME_LENGTH)
118    }
119}
120
121impl WireCodec for UsbCodec {
122    type Frames = Vec<UsbSerialFrameVec, MAX_USB_FRAMES_COUNT>;
123    type IncomingFrame = UsbSerialFrameVec;
124    const MESSAGE_DELIMITER: Option<char> = None;
125
126    fn get_frames(data: &[u8]) -> Result<Self::Frames, CodecError> {
127        let mut frames = Vec::<UsbSerialFrameVec, MAX_USB_FRAMES_COUNT>::new();
128        for chunk in data.chunks(MAX_USB_FRAME_LENGTH) {
129            frames
130                .push(
131                    UsbSerialFrameVec::from_slice(&chunk)
132                        .map_err(|_| CodecError::FrameCreateError)?,
133                )
134                .map_err(|_| CodecError::FrameCreateError)?
135        }
136        Ok(frames)
137    }
138
139    fn decode_frame(data: &[u8]) -> Result<(Self::IncomingFrame, usize), CodecError> {
140        let mut decoded = UsbSerialFrameVec::new();
141        decoded
142            .extend_from_slice(data)
143            .map_err(|_| CodecError::DecodeError)?;
144        Ok((decoded, data.len()))
145    }
146}
147
148pub struct Bgx13Codec {}
149
150impl WireCodec for Bgx13Codec {
151    type Frames = Vec<Bgx13SerialFrameVec, MAX_BGX13_FRAMES_COUNT>;
152    type IncomingFrame = Bgx13SerialFrameVec;
153    const MESSAGE_DELIMITER: Option<char> = None;
154
155    fn get_frames(data: &[u8]) -> Result<Self::Frames, CodecError> {
156        let mut frames = Vec::<Bgx13SerialFrameVec, MAX_BGX13_FRAMES_COUNT>::new();
157        for chunk in data.chunks(MAX_BGX13_MESSAGE_LENGTH) {
158            frames
159                .push(
160                    Bgx13SerialFrameVec::from_slice(&chunk)
161                        .map_err(|_| CodecError::FrameCreateError)?,
162                )
163                .map_err(|_| CodecError::FrameCreateError)?
164        }
165        Ok(frames)
166    }
167    fn decode_frame(data: &[u8]) -> Result<(Self::IncomingFrame, usize), CodecError> {
168        let mut decoded = Bgx13SerialFrameVec::new();
169        decoded
170            .extend_from_slice(data)
171            .map_err(|_| CodecError::DecodeError)?;
172        Ok((decoded, data.len()))
173    }
174}
175
176pub struct Bt4502Codec {}
177
178impl Bt4502Codec {
179    pub fn get_frames_iter(data: &[u8]) -> impl Iterator<Item = &[u8]> {
180        data.chunks(MAX_USB_FRAME_LENGTH)
181    }
182}
183
184impl WireCodec for Bt4502Codec {
185    type Frames = Vec<Bt4502SerialFrameVec, MAX_BT4502_FRAMES_COUNT>;
186    type IncomingFrame = Bt4502SerialFrameVec;
187    const MESSAGE_DELIMITER: Option<char> = None;
188
189    fn get_frames(data: &[u8]) -> Result<Self::Frames, CodecError> {
190        let mut frames = Vec::<Bt4502SerialFrameVec, MAX_BT4502_FRAMES_COUNT>::new();
191        for chunk in data.chunks(MAX_BT4502_MESSAGE_LENGTH) {
192            match chunk[0..4] {
193                [b'T', b'T', b'M', b':'] => {
194                    frames
195                        .push(
196                            Bt4502SerialFrameVec::from_slice(&chunk[0..2])
197                                .map_err(|_| CodecError::FrameCreateError)?,
198                        )
199                        .map_err(|_| CodecError::FrameCreateError)?;
200                    frames
201                        .push(
202                            Bt4502SerialFrameVec::from_slice(&chunk[2..])
203                                .map_err(|_| CodecError::FrameCreateError)?,
204                        )
205                        .map_err(|_| CodecError::FrameCreateError)?;
206                }
207                _ => frames
208                    .push(
209                        Bt4502SerialFrameVec::from_slice(&chunk)
210                            .map_err(|_| CodecError::FrameCreateError)?,
211                    )
212                    .map_err(|_| CodecError::FrameCreateError)?,
213            };
214        }
215        Ok(frames)
216    }
217
218    fn decode_frame(data: &[u8]) -> Result<(Self::IncomingFrame, usize), CodecError> {
219        let mut decoded = Bt4502SerialFrameVec::new();
220        decoded
221            .extend_from_slice(data)
222            .map_err(|_| CodecError::DecodeError)?;
223        Ok((decoded, data.len()))
224    }
225}
226
227#[cfg(test)]
228mod tests {
229    use super::*;
230    #[test]
231    fn test_max_usb_frames() {
232        let encoded = &[
233            0xaa, 0xd6, 0xbb, 0x28, 0x44, 0xf8, 0x47, 0xfd, 0xf7, 0xd8, 0x25, 0xfe, 0x74, 0x07,
234            0xd6, 0x39, 0x1a, 0xce, 0xcd, 0xa2, 0xfb, 0xbf, 0xa1, 0xe0, 0x26, 0x60, 0x49, 0x7b,
235            0x84, 0x97, 0x5b, 0x75, 0x5d, 0xd8, 0xe7, 0x3e, 0xd6, 0x25, 0x90, 0x5a, 0x21, 0x03,
236            0x77, 0x68, 0xcf, 0xf2, 0xff, 0x5c, 0xe3, 0x5c, 0x77, 0x59, 0x6e, 0x59, 0x0c, 0xcc,
237            0x23, 0x44, 0x1e, 0xe4, 0x78, 0x4d, 0xe7, 0x97, 0x13, 0x4d, 0xe9, 0x2e, 0xc0, 0x8b,
238            0xb0, 0x46, 0xd2, 0x3a, 0x27, 0x3a, 0xd5, 0x2f, 0xdb, 0x96, 0x29, 0x92, 0x2f, 0x5e,
239            0x79, 0x9f, 0x6f, 0x66, 0x6b, 0x6d, 0xd7, 0xa9, 0x7f, 0x0f, 0xae, 0x64, 0x75, 0x80,
240            0x2b, 0xca, 0xba, 0xd7, 0xf6, 0x8c, 0x1c, 0xcf, 0xe9, 0x67, 0xb6, 0xdb, 0x1a, 0x27,
241            0x10, 0x3a, 0xf3, 0xa4, 0x1d, 0x00, 0xb2, 0x6d, 0x1e, 0x48, 0x59, 0xaf, 0x28, 0x1a,
242            0x43, 0x3d, 0xe9, 0x9e, 0xe6, 0xc5, 0x06, 0xdd, 0x63, 0x9a, 0x1c, 0x72, 0xb9, 0x3f,
243            0x76, 0x96, 0x63, 0xf4, 0x8a, 0x5b, 0x7b, 0x3a, 0xb2, 0xd8, 0x9f, 0x90, 0x98, 0xfc,
244            0x49, 0x71, 0x1d, 0x79, 0xae, 0x88, 0x74, 0x1a, 0xe7, 0xdf, 0x43, 0x04, 0x66, 0xd3,
245            0xe5, 0x24, 0x92, 0xec, 0xde, 0xe4, 0x15, 0x4b, 0x4d, 0xbe, 0x09, 0x02, 0x13, 0x41,
246            0x2a, 0xcf, 0x38, 0xe8, 0x01, 0x91, 0xb5, 0x1b, 0xa8, 0xc5, 0xcd, 0xbb, 0xa8, 0x3a,
247            0xaa, 0xd0, 0x80, 0xf7, 0x80, 0xee, 0x64, 0xde, 0xa8, 0xe7, 0xa4, 0xd0, 0x47, 0x05,
248            0xdc, 0x50, 0xf6, 0x33, 0x40, 0xe8, 0x90, 0xaa, 0x7a, 0xe5, 0x71, 0x32, 0x1a, 0x2a,
249            0xfd, 0xc7, 0x4b, 0x3d, 0x85, 0xb2, 0x0d, 0x58, 0x09, 0xdb, 0xaf, 0x70, 0x31, 0x22,
250            0xf1, 0x1d, 0x92, 0x81, 0x19, 0x44, 0x92, 0xe5, 0x8d, 0xb5, 0xad, 0x64, 0x24, 0x7b,
251            0xf4, 0x3b, 0xf8,
252        ];
253        let msg = super::super::Message::SendData {
254            data: Vec::<u8, 255>::from_slice(&encoded[..]).unwrap(),
255        };
256
257        let frames = msg.as_frames::<UsbCodec>().unwrap();
258
259        assert_eq!(frames.len(), 2);
260
261        let result = &frames[0];
262        let last_frame = &frames.last().unwrap();
263        assert_eq!(result.len(), MAX_USB_FRAME_LENGTH);
264        for b in &result[0..result.len() - 2] {
265            assert_ne!(0x00, *b);
266        }
267        assert_eq!(Some(&0x00), last_frame.last());
268    }
269    #[test]
270    fn test_bt4502() {
271        let frames = Bt4502Codec::get_frames(&mut [0x01, 0x02, 0x03, 0x04]).unwrap();
272        assert_eq!(frames.len(), 1);
273    }
274    #[test]
275    fn test_bt4502_split() {
276        let frames = Bt4502Codec::get_frames(&mut [b'T', b'T', b'M', b':']).unwrap();
277        assert_eq!(frames[0].len(), 2);
278        assert_eq!(frames[1].len(), 2);
279        assert_eq!(frames.len(), 2);
280    }
281}