From 7d8c2fafc124ca6ea6eb070dec06dff183aa4a6f Mon Sep 17 00:00:00 2001 From: Sam Clercky Date: Wed, 20 Mar 2024 16:43:45 +0100 Subject: [PATCH 1/4] better error handling --- dot15d4/src/csma/mod.rs | 10 +++++++--- dot15d4/src/phy/driver.rs | 8 +++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/dot15d4/src/csma/mod.rs b/dot15d4/src/csma/mod.rs index 688d52f..bec2c3d 100644 --- a/dot15d4/src/csma/mod.rs +++ b/dot15d4/src/csma/mod.rs @@ -348,11 +348,15 @@ where Ok(seq_number) => sequence_number = seq_number, Err(TransmissionTaskError::InvalidIEEEFrame) => { // Invalid IEEE frame encountered - self.driver.error(driver::Error::InvalidStructure).await; + defmt::trace!("INVALID frame TX incoming buffer IEEE"); + self.driver.error(driver::Error::InvalidIEEEStructure).await; } - Err(TransmissionTaskError::InvalidDeviceFrame(_err)) => { + Err(TransmissionTaskError::InvalidDeviceFrame(err)) => { // Invalid device frame encountered - self.driver.error(driver::Error::InvalidStructure).await; + defmt::trace!("INVALID frame TX incoming buffer device: {}", err); + self.driver + .error(driver::Error::InvalidDeviceStructure) + .await; } } diff --git a/dot15d4/src/phy/driver.rs b/dot15d4/src/phy/driver.rs index 344c774..4adda31 100644 --- a/dot15d4/src/phy/driver.rs +++ b/dot15d4/src/phy/driver.rs @@ -3,9 +3,15 @@ use core::future::Future; #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[derive(Debug, PartialEq, Clone, Copy)] pub enum Error { + /// Cca failed after to many fallbacks CcaFailed, + /// Ack failed, after to many retransmissions AckFailed, - InvalidStructure, + /// The buffer did not follow the correct device structure + InvalidDeviceStructure, + /// Invalid IEEE frame + InvalidIEEEStructure, + /// Something went wrong in the radio RadioError, } From ae184aacbaf544f0a2f732df853b26278e76da4a Mon Sep 17 00:00:00 2001 From: Sam Clercky Date: Thu, 21 Mar 2024 14:31:19 +0100 Subject: [PATCH 2/4] Make channel used in CSMA configurable --- dot15d4/src/csma/mod.rs | 36 +++++++++++++++++++++++--------- dot15d4/src/csma/transmission.rs | 7 ++++++- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/dot15d4/src/csma/mod.rs b/dot15d4/src/csma/mod.rs index bec2c3d..44237fc 100644 --- a/dot15d4/src/csma/mod.rs +++ b/dot15d4/src/csma/mod.rs @@ -10,7 +10,7 @@ use user_configurable_constants::*; use crate::{ phy::{ - config::{RxConfig, TxConfig}, + config::{self, RxConfig, TxConfig}, driver::{self, Driver, FrameBuffer}, radio::{ futures::{receive, transmit}, @@ -41,17 +41,19 @@ enum TransmissionTaskError { pub struct CsmaConfig { /// All to be transmitted frames will get the ack_request flag set if they /// are unicast and a data frame - ack_unicast: bool, + pub ack_unicast: bool, /// All to be transmitted frames will get the ack_request flag set if they /// are broadcast and a data frame - ack_broadcast: bool, + pub ack_broadcast: bool, /// If false, all incoming frames will be sent up the layer stack, useful /// if making a sniffer. This does not include MAC layer control traffic. /// The default is true, meaning that frames not ment for us (non-broadcast /// or frames with a different destination address) will be filtered out. - ignore_not_for_us: bool, + pub ignore_not_for_us: bool, /// Even if there is no ack_request flag set, ack it anyway - ack_everything: bool, + pub ack_everything: bool, + /// The channel on which to transmit/receive + pub channel: config::Channel, } impl Default for CsmaConfig { @@ -61,6 +63,7 @@ impl Default for CsmaConfig { ack_broadcast: false, ignore_not_for_us: true, ack_everything: false, + channel: config::Channel::_26, } } } @@ -157,7 +160,9 @@ where receive( &mut **radio_guard.as_mut().unwrap(), &mut rx.buffer, - RxConfig::default(), + RxConfig { + channel: self.config.channel, + }, ), wants_to_transmit_signal.receive(), ) @@ -245,7 +250,10 @@ where transmit( &mut **radio_guard.as_mut().unwrap(), &mut tx_ack.buffer, - TxConfig::default(), + TxConfig { + channel: self.config.channel, + ..Default::default() + }, ) .await; } @@ -302,9 +310,14 @@ where } } - async fn wait_for_valid_ack(radio: &mut R, sequence_number: u8, ack_rx: &mut [u8; 128]) { + async fn wait_for_valid_ack( + radio: &mut R, + channel: config::Channel, + sequence_number: u8, + ack_rx: &mut [u8; 128], + ) { loop { - let result = receive(radio, ack_rx, RxConfig::default()).await; + let result = receive(radio, ack_rx, RxConfig { channel }).await; if !result { // No succesful receive, try again continue; @@ -348,12 +361,13 @@ where Ok(seq_number) => sequence_number = seq_number, Err(TransmissionTaskError::InvalidIEEEFrame) => { // Invalid IEEE frame encountered + #[cfg(feature = "defmt")] defmt::trace!("INVALID frame TX incoming buffer IEEE"); self.driver.error(driver::Error::InvalidIEEEStructure).await; } + #[allow(unused_variables)] Err(TransmissionTaskError::InvalidDeviceFrame(err)) => { // Invalid device frame encountered - defmt::trace!("INVALID frame TX incoming buffer device: {}", err); self.driver .error(driver::Error::InvalidDeviceStructure) .await; @@ -369,6 +383,7 @@ where match transmission::transmit_cca( &self.radio, &mut radio_guard, + self.config.channel, &wants_to_transmit_signal, &mut tx, &mut timer, @@ -396,6 +411,7 @@ where match select::select( Self::wait_for_valid_ack( &mut *radio_guard.unwrap(), + self.config.channel, sequence_number, &mut ack_rx.buffer, ), diff --git a/dot15d4/src/csma/transmission.rs b/dot15d4/src/csma/transmission.rs index 66fa3ce..8cdcb5d 100644 --- a/dot15d4/src/csma/transmission.rs +++ b/dot15d4/src/csma/transmission.rs @@ -4,6 +4,7 @@ use rand_core::RngCore; use super::user_configurable_constants::*; use super::utils; +use crate::phy::config; use crate::phy::config::TxConfig; use crate::phy::driver::FrameBuffer; use crate::phy::radio::futures::transmit; @@ -21,6 +22,7 @@ pub enum TransmissionError { pub async fn transmit_cca<'m, R, TIMER, Rng>( radio: &'m Mutex, radio_guard: &mut Option>, + channel: config::Channel, wants_to_transmit_signal: &Sender<'_, ()>, tx_frame: &mut FrameBuffer, timer: &mut TIMER, @@ -38,7 +40,10 @@ where transmit( &mut **radio_guard.as_mut().unwrap(), &mut tx_frame.buffer, - TxConfig::default_with_cca(), + TxConfig { + channel, + ..TxConfig::default_with_cca() + }, ) .await }; From b00848b75c3dd9d0547c8b53acf5fb9b5e73e17a Mon Sep 17 00:00:00 2001 From: Sam Clercky Date: Thu, 21 Mar 2024 15:36:28 +0100 Subject: [PATCH 3/4] fix filtering bug + contention issue --- dot15d4/src/csma/mod.rs | 2 +- dot15d4/src/csma/user_configurable_constants.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dot15d4/src/csma/mod.rs b/dot15d4/src/csma/mod.rs index 44237fc..d28075c 100644 --- a/dot15d4/src/csma/mod.rs +++ b/dot15d4/src/csma/mod.rs @@ -193,7 +193,7 @@ where // Check if package is meant for us if !Self::is_package_for_us(&self.hardware_address, &frame) - && !self.config.ignore_not_for_us + && self.config.ignore_not_for_us { // Package is not for us to handle, ignore rx.dirty = false; diff --git a/dot15d4/src/csma/user_configurable_constants.rs b/dot15d4/src/csma/user_configurable_constants.rs index 9ad7edb..173ece0 100644 --- a/dot15d4/src/csma/user_configurable_constants.rs +++ b/dot15d4/src/csma/user_configurable_constants.rs @@ -11,7 +11,7 @@ pub const MAC_MAX_BE: u16 = 8; pub const MAC_MAX_CSMA_BACKOFFS: u16 = 16; pub const MAC_UNIT_BACKOFF_DURATION: Duration = Duration::from_us((UNIT_BACKOFF_PERIOD * SYMBOL_RATE_INV_US) as i64); -pub const MAC_MAX_FRAME_RETIES: u16 = 16; // TODO: XXX +pub const MAC_MAX_FRAME_RETIES: u16 = 3; // 0-7 pub const _MAC_INTER_FRAME_TIME: Duration = Duration::from_us(1000); // TODO: XXX /// AIFS=1ms, for SUN PHY, LECIM PHY, TVWS PHY pub const ACKNOWLEDGEMENT_INTERFRAME_SPACING: Duration = Duration::from_us(1000); From 43a557f8a146210d5ce18d77329d3654618c7134 Mon Sep 17 00:00:00 2001 From: Sam Clercky Date: Thu, 21 Mar 2024 16:18:12 +0100 Subject: [PATCH 4/4] Fix tests --- dot15d4/src/csma/mod.rs | 4 ++-- dot15d4/src/phy/radio/mod.rs | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/dot15d4/src/csma/mod.rs b/dot15d4/src/csma/mod.rs index d28075c..0b7adcc 100644 --- a/dot15d4/src/csma/mod.rs +++ b/dot15d4/src/csma/mod.rs @@ -626,7 +626,7 @@ pub mod tests { let mut f = FrameBuffer::default(); let mut frame_repr = FrameBuilder::new_data(&[1, 2, 3, 4]) .set_sequence_number(sequence_number) - .set_dst_address(Address::Extended([1, 2, 3, 4, 5, 6, 7, 8])) + .set_dst_address(Address::Extended(radio.ieee802154_address())) .set_src_address(Address::Extended([1, 2, 3, 4, 9, 8, 7, 6])) .set_dst_pan_id(0xfff) .set_src_pan_id(0xfff) @@ -695,7 +695,7 @@ pub mod tests { let mut f = FrameBuffer::default(); let mut frame_repr = FrameBuilder::new_data(&[1, 2, 3, 4]) .set_sequence_number(sequence_number) - .set_dst_address(Address::Extended([1, 2, 3, 4, 5, 6, 7, 8])) + .set_dst_address(Address::Extended(radio.ieee802154_address())) .set_src_address(Address::Extended([1, 2, 3, 4, 9, 8, 7, 6])) .set_dst_pan_id(0xfff) .set_src_pan_id(0xfff) diff --git a/dot15d4/src/phy/radio/mod.rs b/dot15d4/src/phy/radio/mod.rs index f867fa4..8d1b7a9 100644 --- a/dot15d4/src/phy/radio/mod.rs +++ b/dot15d4/src/phy/radio/mod.rs @@ -169,6 +169,11 @@ pub mod tests { return; } + println!( + "New event arrived [{}]: {:?}", + inner.total_event_count, evnt + ); + inner.total_event_count += 1; if let Some(waker) = inner.assert_waker.take() { waker.wake(); @@ -218,7 +223,7 @@ pub mod tests { impl Default for TestRadio { fn default() -> Self { - Self::new([0; 8]) + Self::new([0xca; 8]) } }