diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-06-25 21:15:23 +0200 |
|---|---|---|
| committer | Ulf Lilleengen <[email protected]> | 2024-08-21 12:44:07 +0200 |
| commit | 11652ff5c7b139fd14ae270659181c65e59515dc (patch) | |
| tree | 3b687fab17c92f9512590e5acbc8cf7600e6f133 | |
| parent | 160e1c38ceab0ae8876c2bf5f12438edd4d9b018 (diff) | |
don't crash if tx buffers fill up.
| -rw-r--r-- | embassy-net-nrf91/src/lib.rs | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/embassy-net-nrf91/src/lib.rs b/embassy-net-nrf91/src/lib.rs index 62ade6dd3..70ad176da 100644 --- a/embassy-net-nrf91/src/lib.rs +++ b/embassy-net-nrf91/src/lib.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![doc = include_str!("../README.md")] | 2 | #![doc = include_str!("../README.md")] |
| 3 | #![warn(missing_docs)] | 3 | #![warn(missing_docs)] |
| 4 | #![deny(unused_must_use)] | ||
| 4 | 5 | ||
| 5 | // must be first | 6 | // must be first |
| 6 | mod fmt; | 7 | mod fmt; |
| @@ -244,6 +245,10 @@ struct PendingRequest { | |||
| 244 | waker: Waker, | 245 | waker: Waker, |
| 245 | } | 246 | } |
| 246 | 247 | ||
| 248 | #[derive(Copy, Clone, PartialEq, Eq)] | ||
| 249 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 250 | struct NoFreeBufs; | ||
| 251 | |||
| 247 | struct StateInner { | 252 | struct StateInner { |
| 248 | init: bool, | 253 | init: bool, |
| 249 | init_waker: WakerRegistration, | 254 | init_waker: WakerRegistration, |
| @@ -450,13 +455,13 @@ impl StateInner { | |||
| 450 | return None; | 455 | return None; |
| 451 | } | 456 | } |
| 452 | 457 | ||
| 453 | fn send_message(&mut self, msg: &mut Message, data: &[u8]) { | 458 | fn send_message(&mut self, msg: &mut Message, data: &[u8]) -> Result<(), NoFreeBufs> { |
| 454 | if data.is_empty() { | 459 | if data.is_empty() { |
| 455 | msg.data = ptr::null_mut(); | 460 | msg.data = ptr::null_mut(); |
| 456 | msg.data_len = 0; | 461 | msg.data_len = 0; |
| 457 | } else { | 462 | } else { |
| 458 | assert!(data.len() <= TX_BUF_SIZE); | 463 | assert!(data.len() <= TX_BUF_SIZE); |
| 459 | let buf_idx = self.find_free_tx_buf().unwrap(); // TODO handle out of bufs | 464 | let buf_idx = self.find_free_tx_buf().ok_or(NoFreeBufs)?; |
| 460 | let buf = unsafe { addr_of_mut!((*self.cb).tx_bufs[buf_idx]) } as *mut u8; | 465 | let buf = unsafe { addr_of_mut!((*self.cb).tx_bufs[buf_idx]) } as *mut u8; |
| 461 | unsafe { copy_nonoverlapping(data.as_ptr(), buf, data.len()) } | 466 | unsafe { copy_nonoverlapping(data.as_ptr(), buf, data.len()) } |
| 462 | msg.data = buf; | 467 | msg.data = buf; |
| @@ -467,10 +472,10 @@ impl StateInner { | |||
| 467 | } | 472 | } |
| 468 | 473 | ||
| 469 | // TODO free data buf if send_message_raw fails. | 474 | // TODO free data buf if send_message_raw fails. |
| 470 | self.send_message_raw(msg); | 475 | self.send_message_raw(msg) |
| 471 | } | 476 | } |
| 472 | 477 | ||
| 473 | fn send_message_raw(&mut self, msg: &Message) { | 478 | fn send_message_raw(&mut self, msg: &Message) -> Result<(), NoFreeBufs> { |
| 474 | let (ch, ipc_ch) = match msg.channel { | 479 | let (ch, ipc_ch) = match msg.channel { |
| 475 | 1 => (0, 1), // control | 480 | 1 => (0, 1), // control |
| 476 | 2 => (1, 3), // data | 481 | 2 => (1, 3), // data |
| @@ -478,7 +483,7 @@ impl StateInner { | |||
| 478 | }; | 483 | }; |
| 479 | 484 | ||
| 480 | // allocate a msg. | 485 | // allocate a msg. |
| 481 | let idx = self.find_free_message(ch).unwrap(); // TODO handle list full | 486 | let idx = self.find_free_message(ch).ok_or(NoFreeBufs)?; |
| 482 | 487 | ||
| 483 | debug!("tx seq {} msg: {:?}", self.tx_seq_no, msg); | 488 | debug!("tx seq {} msg: {:?}", self.tx_seq_no, msg); |
| 484 | 489 | ||
| @@ -491,6 +496,7 @@ impl StateInner { | |||
| 491 | 496 | ||
| 492 | let ipc = unsafe { &*pac::IPC_NS::ptr() }; | 497 | let ipc = unsafe { &*pac::IPC_NS::ptr() }; |
| 493 | ipc.tasks_send[ipc_ch].write(|w| unsafe { w.bits(1) }); | 498 | ipc.tasks_send[ipc_ch].write(|w| unsafe { w.bits(1) }); |
| 499 | Ok(()) | ||
| 494 | } | 500 | } |
| 495 | 501 | ||
| 496 | fn handle_control(&mut self, msg: &Message) { | 502 | fn handle_control(&mut self, msg: &Message) { |
| @@ -626,7 +632,7 @@ impl StateInner { | |||
| 626 | free_msg.data = msg.data; | 632 | free_msg.data = msg.data; |
| 627 | free_msg.data_len = msg.data_len; | 633 | free_msg.data_len = msg.data_len; |
| 628 | 634 | ||
| 629 | self.send_message_raw(&free_msg); | 635 | unwrap!(self.send_message_raw(&free_msg)); |
| 630 | } | 636 | } |
| 631 | } | 637 | } |
| 632 | 638 | ||
| @@ -702,7 +708,7 @@ impl<'a> Control<'a> { | |||
| 702 | } | 708 | } |
| 703 | 709 | ||
| 704 | msg.param[0..4].copy_from_slice(&req_serial.to_le_bytes()); | 710 | msg.param[0..4].copy_from_slice(&req_serial.to_le_bytes()); |
| 705 | state.send_message(msg, req_data); | 711 | unwrap!(state.send_message(msg, req_data)); |
| 706 | 712 | ||
| 707 | // Setup the pending request state. | 713 | // Setup the pending request state. |
| 708 | let (req_slot_idx, req_slot) = state | 714 | let (req_slot_idx, req_slot) = state |
| @@ -838,7 +844,9 @@ impl<'a, TW: embedded_io::Write> Runner<'a, TW> { | |||
| 838 | msg.id = 0x7006_0004; // IP send | 844 | msg.id = 0x7006_0004; // IP send |
| 839 | msg.param_len = 12; | 845 | msg.param_len = 12; |
| 840 | msg.param[4..8].copy_from_slice(&fd.to_le_bytes()); | 846 | msg.param[4..8].copy_from_slice(&fd.to_le_bytes()); |
| 841 | state.send_message(&mut msg, buf); | 847 | if let Err(e) = state.send_message(&mut msg, buf) { |
| 848 | warn!("tx failed: {:?}", e); | ||
| 849 | } | ||
| 842 | self.ch.tx_done(); | 850 | self.ch.tx_done(); |
| 843 | } | 851 | } |
| 844 | 852 | ||
