aboutsummaryrefslogtreecommitdiff
path: root/src
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
parente6e5685f7c75c3f5f5475e64101de90e6999b79c (diff)
parse data from device in-place
Diffstat (limited to 'src')
-rw-r--r--src/runner.rs67
-rw-r--r--src/structs.rs149
2 files changed, 154 insertions, 62 deletions
diff --git a/src/runner.rs b/src/runner.rs
index deb45f9f4..f0f6fceeb 100644
--- a/src/runner.rs
+++ b/src/runner.rs
@@ -328,45 +328,23 @@ where
328 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT; 328 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT;
329 self.bus.wlan_read(buf, len).await; 329 self.bus.wlan_read(buf, len).await;
330 trace!("rx {:02x}", Bytes(&slice8_mut(buf)[..(len as usize).min(48)])); 330 trace!("rx {:02x}", Bytes(&slice8_mut(buf)[..(len as usize).min(48)]));
331 self.rx(&slice8_mut(buf)[..len as usize]); 331 self.rx(&mut slice8_mut(buf)[..len as usize]);
332 } else { 332 } else {
333 break; 333 break;
334 } 334 }
335 } 335 }
336 } 336 }
337 337
338 fn rx(&mut self, packet: &[u8]) { 338 fn rx(&mut self, packet: &mut [u8]) {
339 if packet.len() < SdpcmHeader::SIZE { 339 let Some((sdpcm_header, payload)) = SdpcmHeader::parse(packet) else { return };
340 warn!("packet too short, len={}", packet.len());
341 return;
342 }
343
344 let sdpcm_header = SdpcmHeader::from_bytes(packet[..SdpcmHeader::SIZE].try_into().unwrap());
345 trace!("rx {:?}", sdpcm_header);
346 if sdpcm_header.len != !sdpcm_header.len_inv {
347 warn!("len inv mismatch");
348 return;
349 }
350 if sdpcm_header.len as usize != packet.len() {
351 // TODO: is this guaranteed??
352 warn!("len from header doesn't match len from spi");
353 return;
354 }
355 340
356 self.update_credit(&sdpcm_header); 341 self.update_credit(&sdpcm_header);
357 342
358 let channel = sdpcm_header.channel_and_flags & 0x0f; 343 let channel = sdpcm_header.channel_and_flags & 0x0f;
359 344
360 let payload = &packet[sdpcm_header.header_length as _..];
361
362 match channel { 345 match channel {
363 CHANNEL_TYPE_CONTROL => { 346 CHANNEL_TYPE_CONTROL => {
364 if payload.len() < CdcHeader::SIZE { 347 let Some((cdc_header, response)) = CdcHeader::parse(payload) else { return; };
365 warn!("payload too short, len={}", payload.len());
366 return;
367 }
368
369 let cdc_header = CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap());
370 trace!(" {:?}", cdc_header); 348 trace!(" {:?}", cdc_header);
371 349
372 if cdc_header.id == self.ioctl_id { 350 if cdc_header.id == self.ioctl_id {
@@ -375,28 +353,21 @@ where
375 panic!("IOCTL error {}", cdc_header.status as i32); 353 panic!("IOCTL error {}", cdc_header.status as i32);
376 } 354 }
377 355
378 let resp_len = cdc_header.len as usize;
379 let response = &payload[CdcHeader::SIZE..][..resp_len];
380 info!("IOCTL Response: {:02x}", Bytes(response)); 356 info!("IOCTL Response: {:02x}", Bytes(response));
381 357
382 self.ioctl_state.ioctl_done(response); 358 self.ioctl_state.ioctl_done(response);
383 } 359 }
384 } 360 }
385 CHANNEL_TYPE_EVENT => { 361 CHANNEL_TYPE_EVENT => {
386 let bcd_header = BcdHeader::from_bytes(&payload[..BcdHeader::SIZE].try_into().unwrap()); 362 let Some((_, bcd_packet)) = BcdHeader::parse(payload) else {
387 trace!(" {:?}", bcd_header);
388
389 let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize;
390
391 if packet_start + EventPacket::SIZE > payload.len() {
392 warn!("BCD event, incomplete header"); 363 warn!("BCD event, incomplete header");
393 return; 364 return;
394 } 365 };
395 let bcd_packet = &payload[packet_start..];
396 trace!(" {:02x}", Bytes(&bcd_packet[..(bcd_packet.len() as usize).min(36)]));
397 366
398 let mut event_packet = EventPacket::from_bytes(&bcd_packet[..EventPacket::SIZE].try_into().unwrap()); 367 let Some((event_packet, evt_data)) = EventPacket::parse(bcd_packet) else {
399 event_packet.byteswap(); 368 warn!("BCD event, incomplete data");
369 return;
370 };
400 371
401 const ETH_P_LINK_CTL: u16 = 0x886c; // HPNA, wlan link local tunnel, according to linux if_ether.h 372 const ETH_P_LINK_CTL: u16 = 0x886c; // HPNA, wlan link local tunnel, according to linux if_ether.h
402 if event_packet.eth.ether_type != ETH_P_LINK_CTL { 373 if event_packet.eth.ether_type != ETH_P_LINK_CTL {
@@ -427,13 +398,7 @@ where
427 return; 398 return;
428 } 399 }
429 400
430 if event_packet.msg.datalen as usize >= (bcd_packet.len() - EventMessage::SIZE) {
431 warn!("BCD event, incomplete data");
432 return;
433 }
434
435 let evt_type = events::Event::from(event_packet.msg.event_type as u8); 401 let evt_type = events::Event::from(event_packet.msg.event_type as u8);
436 let evt_data = &bcd_packet[EventMessage::SIZE..][..event_packet.msg.datalen as usize];
437 debug!( 402 debug!(
438 "=== EVENT {:?}: {:?} {:02x}", 403 "=== EVENT {:?}: {:?} {:02x}",
439 evt_type, 404 evt_type,
@@ -449,16 +414,8 @@ where
449 } 414 }
450 } 415 }
451 CHANNEL_TYPE_DATA => { 416 CHANNEL_TYPE_DATA => {
452 let bcd_header = BcdHeader::from_bytes(&payload[..BcdHeader::SIZE].try_into().unwrap()); 417 let Some((_, packet)) = BcdHeader::parse(payload) else { return };
453 trace!(" {:?}", bcd_header); 418 trace!("rx pkt {:02x}", Bytes(&packet[..packet.len().min(48)]));
454
455 let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize;
456 if packet_start > payload.len() {
457 warn!("packet start out of range.");
458 return;
459 }
460 let packet = &payload[packet_start..];
461 trace!("rx pkt {:02x}", Bytes(&packet[..(packet.len() as usize).min(48)]));
462 419
463 match self.ch.try_rx_buf() { 420 match self.ch.try_rx_buf() {
464 Some(buf) => { 421 Some(buf) => {
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();