diff options
| author | kbleeke <[email protected]> | 2023-03-31 14:18:39 +0200 |
|---|---|---|
| committer | kbleeke <[email protected]> | 2023-04-03 12:50:52 +0200 |
| commit | 76ebebd0c5b58d230391be4d1989f68f1cc3d5b5 (patch) | |
| tree | dbdc4170d858fd00664bf6a01007d22d46db3ed1 /src/runner.rs | |
| parent | e6e5685f7c75c3f5f5475e64101de90e6999b79c (diff) | |
parse data from device in-place
Diffstat (limited to 'src/runner.rs')
| -rw-r--r-- | src/runner.rs | 67 |
1 files changed, 12 insertions, 55 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) => { |
