aboutsummaryrefslogtreecommitdiff
path: root/src/structs.rs
diff options
context:
space:
mode:
authorkbleeke <[email protected]>2023-03-31 14:18:39 +0200
committerkbleeke <[email protected]>2023-04-03 12:50:52 +0200
commit76ebebd0c5b58d230391be4d1989f68f1cc3d5b5 (patch)
treedbdc4170d858fd00664bf6a01007d22d46db3ed1 /src/structs.rs
parente6e5685f7c75c3f5f5475e64101de90e6999b79c (diff)
parse data from device in-place
Diffstat (limited to 'src/structs.rs')
-rw-r--r--src/structs.rs149
1 files changed, 142 insertions, 7 deletions
diff --git a/src/structs.rs b/src/structs.rs
index e16808f30..6d5d31b06 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -1,4 +1,5 @@
1use crate::events::Event; 1use crate::events::Event;
2use crate::fmt::Bytes;
2 3
3macro_rules! impl_bytes { 4macro_rules! impl_bytes {
4 ($t:ident) => { 5 ($t:ident) => {
@@ -11,8 +12,28 @@ macro_rules! impl_bytes {
11 } 12 }
12 13
13 #[allow(unused)] 14 #[allow(unused)]
14 pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> Self { 15 pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> &Self {
15 unsafe { core::mem::transmute(*bytes) } 16 let alignment = core::mem::align_of::<Self>();
17 assert_eq!(
18 bytes.as_ptr().align_offset(alignment),
19 0,
20 "{} is not aligned",
21 core::any::type_name::<Self>()
22 );
23 unsafe { core::mem::transmute(bytes) }
24 }
25
26 #[allow(unused)]
27 pub fn from_bytes_mut(bytes: &mut [u8; Self::SIZE]) -> &mut Self {
28 let alignment = core::mem::align_of::<Self>();
29 assert_eq!(
30 bytes.as_ptr().align_offset(alignment),
31 0,
32 "{} is not aligned",
33 core::any::type_name::<Self>()
34 );
35
36 unsafe { core::mem::transmute(bytes) }
16 } 37 }
17 } 38 }
18 }; 39 };
@@ -67,9 +88,35 @@ pub struct SdpcmHeader {
67} 88}
68impl_bytes!(SdpcmHeader); 89impl_bytes!(SdpcmHeader);
69 90
91impl SdpcmHeader {
92 pub fn parse(packet: &mut [u8]) -> Option<(&mut Self, &mut [u8])> {
93 let packet_len = packet.len();
94 if packet_len < Self::SIZE {
95 warn!("packet too short, len={}", packet.len());
96 return None;
97 }
98 let (sdpcm_header, sdpcm_packet) = packet.split_at_mut(Self::SIZE);
99 let sdpcm_header = Self::from_bytes_mut(sdpcm_header.try_into().unwrap());
100 trace!("rx {:?}", sdpcm_header);
101
102 if sdpcm_header.len != !sdpcm_header.len_inv {
103 warn!("len inv mismatch");
104 return None;
105 }
106
107 if sdpcm_header.len as usize != packet_len {
108 warn!("len from header doesn't match len from spi");
109 return None;
110 }
111
112 let sdpcm_packet = &mut sdpcm_packet[(sdpcm_header.header_length as usize - Self::SIZE)..];
113 Some((sdpcm_header, sdpcm_packet))
114 }
115}
116
70#[derive(Debug, Clone, Copy)] 117#[derive(Debug, Clone, Copy)]
71#[cfg_attr(feature = "defmt", derive(defmt::Format))] 118// #[cfg_attr(feature = "defmt", derive(defmt::Format))]
72#[repr(C)] 119#[repr(C, packed(2))]
73pub struct CdcHeader { 120pub struct CdcHeader {
74 pub cmd: u32, 121 pub cmd: u32,
75 pub len: u32, 122 pub len: u32,
@@ -79,6 +126,21 @@ pub struct CdcHeader {
79} 126}
80impl_bytes!(CdcHeader); 127impl_bytes!(CdcHeader);
81 128
129impl CdcHeader {
130 pub fn parse(packet: &mut [u8]) -> Option<(&mut Self, &mut [u8])> {
131 if packet.len() < Self::SIZE {
132 warn!("payload too short, len={}", packet.len());
133 return None;
134 }
135
136 let (cdc_header, payload) = packet.split_at_mut(Self::SIZE);
137 let cdc_header = Self::from_bytes_mut(cdc_header.try_into().unwrap());
138
139 let payload = &mut payload[..cdc_header.len as usize];
140 Some((cdc_header, payload))
141 }
142}
143
82pub const BDC_VERSION: u8 = 2; 144pub const BDC_VERSION: u8 = 2;
83pub const BDC_VERSION_SHIFT: u8 = 4; 145pub const BDC_VERSION_SHIFT: u8 = 4;
84 146
@@ -95,6 +157,25 @@ pub struct BcdHeader {
95} 157}
96impl_bytes!(BcdHeader); 158impl_bytes!(BcdHeader);
97 159
160impl BcdHeader {
161 pub fn parse(packet: &mut [u8]) -> Option<(&mut Self, &mut [u8])> {
162 if packet.len() < Self::SIZE {
163 return None;
164 }
165
166 let (bcd_header, bcd_packet) = packet.split_at_mut(Self::SIZE);
167 let bcd_header = Self::from_bytes_mut(bcd_header.try_into().unwrap());
168 trace!(" {:?}", bcd_header);
169
170 let packet_start = 4 * bcd_header.data_offset as usize;
171
172 let bcd_packet = bcd_packet.get_mut(packet_start..)?;
173 trace!(" {:02x}", Bytes(&bcd_packet[..bcd_packet.len().min(36)]));
174
175 Some((bcd_header, bcd_packet))
176 }
177}
178
98#[derive(Clone, Copy)] 179#[derive(Clone, Copy)]
99#[cfg_attr(feature = "defmt", derive(defmt::Format))] 180#[cfg_attr(feature = "defmt", derive(defmt::Format))]
100#[repr(C)] 181#[repr(C)]
@@ -130,8 +211,8 @@ impl EventHeader {
130} 211}
131 212
132#[derive(Debug, Clone, Copy)] 213#[derive(Debug, Clone, Copy)]
133#[cfg_attr(feature = "defmt", derive(defmt::Format))] 214// #[cfg_attr(feature = "defmt", derive(defmt::Format))]
134#[repr(C)] 215#[repr(C, packed(2))]
135pub struct EventMessage { 216pub struct EventMessage {
136 /// version 217 /// version
137 pub version: u16, 218 pub version: u16,
@@ -158,6 +239,45 @@ pub struct EventMessage {
158} 239}
159impl_bytes!(EventMessage); 240impl_bytes!(EventMessage);
160 241
242#[cfg(feature = "defmt")]
243impl defmt::Format for EventMessage {
244 fn format(&self, fmt: defmt::Formatter) {
245 let event_type = self.event_type;
246 let status = self.status;
247 let reason = self.reason;
248 let auth_type = self.auth_type;
249 let datalen = self.datalen;
250
251 defmt::write!(
252 fmt,
253 "EventMessage {{ \
254 version: {=u16}, \
255 flags: {=u16}, \
256 event_type: {=u32}, \
257 status: {=u32}, \
258 reason: {=u32}, \
259 auth_type: {=u32}, \
260 datalen: {=u32}, \
261 addr: {=[u8; 6]:x}, \
262 ifname: {=[u8; 16]:x}, \
263 ifidx: {=u8}, \
264 bsscfgidx: {=u8}, \
265 }} ",
266 self.version,
267 self.flags,
268 event_type,
269 status,
270 reason,
271 auth_type,
272 datalen,
273 self.addr,
274 self.ifname,
275 self.ifidx,
276 self.bsscfgidx
277 );
278 }
279}
280
161impl EventMessage { 281impl EventMessage {
162 pub fn byteswap(&mut self) { 282 pub fn byteswap(&mut self) {
163 self.version = self.version.to_be(); 283 self.version = self.version.to_be();
@@ -172,7 +292,7 @@ impl EventMessage {
172 292
173#[derive(Clone, Copy)] 293#[derive(Clone, Copy)]
174#[cfg_attr(feature = "defmt", derive(defmt::Format))] 294#[cfg_attr(feature = "defmt", derive(defmt::Format))]
175#[repr(C)] 295#[repr(C, packed(2))]
176pub struct EventPacket { 296pub struct EventPacket {
177 pub eth: EthernetHeader, 297 pub eth: EthernetHeader,
178 pub hdr: EventHeader, 298 pub hdr: EventHeader,
@@ -181,6 +301,21 @@ pub struct EventPacket {
181impl_bytes!(EventPacket); 301impl_bytes!(EventPacket);
182 302
183impl EventPacket { 303impl EventPacket {
304 pub fn parse(packet: &mut [u8]) -> Option<(&mut Self, &mut [u8])> {
305 if packet.len() < Self::SIZE {
306 return None;
307 }
308
309 let (event_header, event_packet) = packet.split_at_mut(Self::SIZE);
310 let event_header = Self::from_bytes_mut(event_header.try_into().unwrap());
311 // warn!("event_header {:x}", event_header as *const _);
312 event_header.byteswap();
313
314 let event_packet = event_packet.get_mut(..event_header.msg.datalen as usize)?;
315
316 Some((event_header, event_packet))
317 }
318
184 pub fn byteswap(&mut self) { 319 pub fn byteswap(&mut self) {
185 self.eth.byteswap(); 320 self.eth.byteswap();
186 self.hdr.byteswap(); 321 self.hdr.byteswap();