1use crate::{Packet, PacketKind};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
9#[repr(u32)]
10pub enum Command {
11 BinInfo = 0x0001,
12 Info = 0x0002,
13 ResetIntoApp = 0x0003,
14 ResetIntoBootloader = 0x0004,
15 StartFlash = 0x0005,
16 WriteFlashPage = 0x0006,
17 ChecksumPages = 0x0007,
18 ReadWords = 0x0008,
19 WriteWords = 0x0009,
20 Dmesg = 0x0010,
21 Other(u32),
22}
23
24impl From<u32> for Command {
25 fn from(value: u32) -> Self {
26 match value {
27 0x0001 => Self::BinInfo,
28 0x0002 => Self::Info,
29 0x0003 => Self::ResetIntoApp,
30 0x0004 => Self::ResetIntoBootloader,
31 0x0005 => Self::StartFlash,
32 0x0006 => Self::WriteFlashPage,
33 0x0007 => Self::ReadWords,
34 0x0008 => Self::WriteWords,
35 0x0010 => Self::Dmesg,
36 _ => Self::Other(value),
37 }
38 }
39}
40
41impl Into<u32> for Command {
42 fn into(self) -> u32 {
43 match self {
44 Self::BinInfo => 0x0001,
45 Self::Info => 0x0002,
46 Self::ResetIntoApp => 0x0003,
47 Self::ResetIntoBootloader => 0x0004,
48 Self::StartFlash => 0x0005,
49 Self::WriteFlashPage => 0x0006,
50 Self::ChecksumPages => 0x0007,
51 Self::ReadWords => 0x0008,
52 Self::WriteWords => 0x0009,
53 Self::Dmesg => 0x0010,
54 Self::Other(value) => value,
55 }
56 }
57}
58
59#[derive(Debug)]
61#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
62pub struct Request<'a>(&'a [u8]);
63
64impl<'a> Request<'a> {
65 pub const HEADER_LEN: usize = 8;
66
67 pub fn new(buf: &'a mut [u8], command: Command, tag: u16, data: &[u8]) -> Self {
71 assert!(buf.len() == (data.len() + Self::HEADER_LEN));
73
74 let cmd: u32 = command.into();
76 buf[0..4].copy_from_slice(&cmd.to_le_bytes());
77
78 buf[4..6].copy_from_slice(&tag.to_le_bytes());
80
81 buf[8..].copy_from_slice(data);
83
84 Self(buf)
85 }
86
87 pub fn from_bytes(buf: &'a [u8]) -> Self {
89 assert!(buf.len() >= Self::HEADER_LEN);
90 Self(buf)
91 }
92
93 pub fn len(&self) -> usize {
95 self.0.len() - Self::HEADER_LEN
96 }
97
98 pub fn command(&self) -> Command {
100 let bytes = &self.0[0..4];
101 Command::from(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
102 }
103
104 pub fn tag(&self) -> u16 {
106 let bytes = &self.0[4..6];
107 u16::from_le_bytes([bytes[0], bytes[1]])
108 }
109
110 pub fn data(&self) -> &[u8] {
112 &self.0[8..]
113 }
114
115 pub fn into_packet_iter(&self) -> RequestPacketIter {
117 RequestPacketIter {
118 request: self,
119 chunk: 0,
120 }
121 }
122}
123
124#[derive(Debug)]
129#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
130pub struct RequestPacketIter<'a> {
131 request: &'a Request<'a>,
132 chunk: usize,
133}
134
135impl<'a> RequestPacketIter<'a> {
136 pub fn next<'b>(&mut self, buf: &'b mut [u8]) -> Option<Packet<'b>> {
138 let chunks = self.request.0.chunks(Packet::MAX_LEN);
139
140 let chunk = match self.request.0.chunks(Packet::MAX_LEN).nth(self.chunk) {
141 Some(c) => c,
142 None => return None,
143 };
144
145 let kind = if chunks.count() - 1 == self.chunk {
146 PacketKind::CommandFinal
147 } else {
148 PacketKind::CommandInner
149 };
150
151 self.chunk += 1;
153
154 Some(Packet::new(buf, kind, chunk))
155 }
156}
157
158#[derive(Debug, Clone, Copy, PartialEq, Eq)]
160#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
161#[repr(u32)]
162pub enum Status {
163 Sucess = 0x00,
165 Unknown = 0x01,
167 Error = 0x02,
169 Other(u8),
171}
172
173impl From<u8> for Status {
174 fn from(value: u8) -> Self {
175 match value {
176 0x00 => Self::Sucess,
177 0x01 => Self::Unknown,
178 0x02 => Self::Error,
179 _ => Self::Other(value),
180 }
181 }
182}
183
184impl Into<u8> for Status {
185 fn into(self) -> u8 {
186 match self {
187 Self::Sucess => 0x00,
188 Self::Unknown => 0x01,
189 Self::Error => 0x02,
190 Self::Other(value) => value,
191 }
192 }
193}
194
195#[derive(Debug)]
197#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
198pub struct Response<'a>(&'a [u8]);
199
200impl<'a> Response<'a> {
201 pub const HEADER_LEN: usize = 4;
202
203 pub fn new(buf: &'a mut [u8], tag: u16, status: Status, status_info: u8, data: &[u8]) -> Self {
207 assert!(buf.len() == data.len() + Self::HEADER_LEN);
209
210 buf[0..2].copy_from_slice(&tag.to_le_bytes());
211 buf[2] = status.into();
212 buf[3] = status_info;
213 buf[Self::HEADER_LEN..].copy_from_slice(data);
214
215 Self(buf)
216 }
217
218 pub fn from_bytes(buf: &'a [u8]) -> Self {
220 assert!(buf.len() >= Self::HEADER_LEN);
221 Self(buf)
222 }
223
224 pub fn tag(&self) -> u16 {
226 let bytes = &self.0[0..2];
227 u16::from_le_bytes([bytes[0], bytes[1]])
228 }
229
230 pub fn status(&self) -> Status {
232 Status::from(self.0[2])
233 }
234
235 pub fn status_info(&self) -> u8 {
237 self.0[3]
238 }
239
240 pub fn data(&self) -> &[u8] {
242 &self.0[Self::HEADER_LEN..]
243 }
244}
245
246#[cfg(test)]
247mod tests {
248 use super::*;
249
250 #[test]
251 fn test_command() {
252 let command = Command::from(u32::MAX);
253 assert_eq!(command, Command::Other(u32::MAX));
254
255 let value = 123456;
256 let input = Command::from(value);
257 let output: u32 = input.into();
258 assert_eq!(value, output);
259 }
260
261 #[test]
262 fn test_request() {
263 let mut buf = [0; 256];
264 let data = [0x55; 256 - Request::HEADER_LEN];
265 let request = Request::new(&mut buf, Command::Info, 0x123, &data);
266
267 let mut packet_iter = request.into_packet_iter();
268
269 let mut iter_count = 0;
270 let mut byte_count = 0;
271
272 loop {
273 let mut buf = [0; 64];
274 match packet_iter.next(&mut buf) {
275 Some(packet) => {
276 byte_count += packet.data().len();
277 iter_count += 1;
278
279 println!("{:?}", packet.kind());
280 }
281 None => break,
282 }
283 }
284
285 assert_eq!(iter_count, 5);
286 assert_eq!(byte_count, 256);
287 }
288}