1#[cfg(test)]
4mod tests;
5
6use core::mem;
7
8use crate::{CanFrame, Error, ExtIdentifier, Identifier, SerialNumber, Status};
9use defmt::Format;
10
11const MAX_RESPONSE_LEN: usize = 6;
12const MAX_NOTIF_LEN: usize = 1 + 8 + 1 + 16 + 4 + 1; #[derive(Default, Debug)]
16pub struct ResponseBuf([u8; MAX_RESPONSE_LEN]);
17
18impl ResponseBuf {
19 pub const LEN: usize = MAX_RESPONSE_LEN;
20
21 pub const fn new() -> Self {
22 Self([0; MAX_RESPONSE_LEN])
23 }
24
25 pub fn as_slice(&self) -> &[u8] {
26 &self.0
27 }
28
29 pub fn as_slice_mut(&mut self) -> &mut [u8] {
30 &mut self.0
31 }
32}
33
34#[derive(Debug, Clone, Eq, PartialEq, Format)]
36#[non_exhaustive]
37pub enum Response {
38 Error,
40
41 Ack,
43
44 TxAck,
46
47 ExtTxAck,
49
50 Status(Status),
52
53 Version {
55 hardware_version: u8,
56 software_version: u8,
57 },
58
59 Serial(SerialNumber),
61}
62
63impl Response {
64 pub fn encode<'a>(&self, buf: &'a mut ResponseBuf) -> Result<&'a [u8], Error> {
65 let mut writer = Writer { buf: &mut buf.0 };
66 match self {
67 Response::Error => {
68 writer.write(7)?;
70 }
71 Response::Ack => writer.write(b'\r')?,
72 Response::TxAck => {
73 writer.write(b'z')?;
74 writer.write(b'\r')?;
75 }
76 Response::ExtTxAck => {
77 writer.write(b'Z')?;
78 writer.write(b'\r')?;
79 }
80 Response::Status(flags) => {
81 writer.write(b'F')?;
82 writer.write_hex_u8(flags.bits().into())?;
83 writer.write(b'\r')?;
84 }
85 Response::Version {
86 hardware_version,
87 software_version,
88 } => {
89 writer.write(b'V')?;
90 writer.write_hex_u8((*hardware_version).into())?;
91 writer.write_hex_u8((*software_version).into())?;
92 writer.write(b'\r')?;
93 }
94 Response::Serial(serial) => {
95 writer.write(b'N')?;
96 for byte in &serial.0 {
97 writer.write(*byte)?;
98 }
99 writer.write(b'\r')?;
100 }
101 }
102
103 let remaining = writer.buf.len();
104 let used = buf.0.len() - remaining;
105 Ok(&buf.0[..used])
106 }
107}
108
109#[derive(Default, Debug)]
110pub struct NotificationBuf([u8; MAX_NOTIF_LEN]);
111
112impl NotificationBuf {
113 pub const fn new() -> Self {
114 Self([0; MAX_NOTIF_LEN])
115 }
116}
117
118#[derive(Debug, Format)]
120pub enum Notification {
121 Rx {
122 identifier: Identifier,
123 frame: CanFrame,
124 },
125
126 RxExt {
127 identifier: ExtIdentifier,
128 frame: CanFrame,
129 },
130
131 RxRtr {
132 identifier: Identifier,
133 len: u8,
135 },
136
137 RxExtRtr {
138 identifier: ExtIdentifier,
139 len: u8,
141 },
142}
143
144impl Notification {
145 pub fn encode<'a>(&self, buf: &'a mut NotificationBuf) -> Result<&'a [u8], Error> {
146 let mut writer = Writer { buf: &mut buf.0 };
147 match self {
148 Notification::Rx { identifier, frame } => {
149 writer.write(b't')?;
150 writer.write_identifier(*identifier)?;
151 writer.write_frame(frame)?;
152 }
153 Notification::RxExt { identifier, frame } => {
154 writer.write(b'T')?;
155 writer.write_ext_identifier(*identifier)?;
156 writer.write_frame(frame)?;
157 }
158 Notification::RxRtr { identifier, len } => {
159 writer.write(b'r')?;
160 writer.write_identifier(*identifier)?;
161 writer.write_hex_u4(*len)?;
162 }
163 Notification::RxExtRtr { identifier, len } => {
164 writer.write(b'R')?;
165 writer.write_ext_identifier(*identifier)?;
166 writer.write_hex_u4(*len)?;
167 }
168 }
169
170 let remaining = writer.buf.len();
171 let used = buf.0.len() - remaining;
172 Ok(&buf.0[..used])
173 }
174}
175
176#[derive(Debug)]
181pub struct TimestampedNotification {
182 notif: Notification,
183 timestamp: u16,
184}
185
186impl TimestampedNotification {
187 pub fn new(notif: Notification, timestamp: u16) -> Self {
189 Self { notif, timestamp }
190 }
191
192 pub fn encode<'a>(&self, buf: &'a mut NotificationBuf) -> Result<&'a [u8], Error> {
193 let used = self.notif.encode(buf)?.len();
194 let mut writer = Writer {
195 buf: &mut buf.0[used..],
196 };
197 writer.write_hex_u16(self.timestamp)?;
198
199 let remaining = writer.buf.len();
200 let used = buf.0.len() - remaining;
201 Ok(&buf.0[..used])
202 }
203}
204
205struct Writer<'a> {
206 buf: &'a mut [u8],
207}
208
209impl<'a> Writer<'a> {
210 fn write(&mut self, byte: u8) -> Result<(), Error> {
211 let buf = mem::replace(&mut self.buf, &mut []);
212 match buf {
213 [] => Err(Error::eof()),
214 [b, rest @ ..] => {
215 *b = byte;
216 self.buf = rest;
217 Ok(())
218 }
219 }
220 }
221
222 fn write_hex_u4(&mut self, val: u8) -> Result<(), Error> {
223 self.write_hex(val.into(), 1)
224 }
225
226 fn write_hex_u8(&mut self, val: u8) -> Result<(), Error> {
227 self.write_hex(val.into(), 2)
228 }
229
230 fn write_hex_u16(&mut self, val: u16) -> Result<(), Error> {
231 self.write_hex(val.into(), 4)
232 }
233
234 fn write_identifier(&mut self, id: Identifier) -> Result<(), Error> {
235 self.write_hex(id.as_raw().into(), 3)
236 }
237
238 fn write_ext_identifier(&mut self, id: ExtIdentifier) -> Result<(), Error> {
239 self.write_hex(id.as_raw().into(), 8)
240 }
241
242 fn write_frame(&mut self, frame: &CanFrame) -> Result<(), Error> {
243 self.write_hex_u4(frame.len() as u8)?;
244 for b in frame.data() {
245 self.write_hex_u8(*b)?;
246 }
247 Ok(())
248 }
249
250 fn write_hex(&mut self, value: u32, digits: u8) -> Result<(), Error> {
251 let mut shift = digits * 4;
252
253 for _ in 0..digits {
254 shift -= 4;
255 let digit = (value >> shift) & 0xF;
256 self.write(hex(digit as u8))?;
257 }
258
259 Ok(())
260 }
261}
262
263fn hex(nibble: u8) -> u8 {
264 match nibble {
265 0..=9 => b'0' + nibble,
266 10..=15 => b'A' + nibble - 10,
267 _ => unreachable!(),
268 }
269}