From e95a7dc555f367534d3b8bc7a9b6f2d361b0d951 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 12:41:57 -0500 Subject: [PATCH 1/7] wpan/mac: use slice view to avoid copy --- embassy-stm32-wpan/src/mac/commands.rs | 83 ++++++++++++++------------ embassy-stm32-wpan/src/mac/typedefs.rs | 2 + embassy-stm32-wpan/src/sub/mac.rs | 9 +-- examples/stm32wb/src/bin/mac_ffd.rs | 5 +- examples/stm32wb/src/bin/mac_rfd.rs | 35 ++++++----- tests/stm32/src/bin/wpan_mac.rs | 6 +- 6 files changed, 77 insertions(+), 63 deletions(-) diff --git a/embassy-stm32-wpan/src/mac/commands.rs b/embassy-stm32-wpan/src/mac/commands.rs index 8cfa0a054..8acae24bb 100644 --- a/embassy-stm32-wpan/src/mac/commands.rs +++ b/embassy-stm32-wpan/src/mac/commands.rs @@ -1,15 +1,16 @@ +use core::{mem, slice}; + use super::opcodes::OpcodeM4ToM0; use super::typedefs::{ AddressMode, Capabilities, DisassociationReason, GtsCharacteristics, KeyIdMode, MacAddress, MacChannel, MacStatus, PanId, PibId, ScanType, SecurityLevel, }; -pub trait MacCommand { +pub trait MacCommand: Sized { const OPCODE: OpcodeM4ToM0; - const SIZE: usize; - fn copy_into_slice(&self, buf: &mut [u8]) { - unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, Self::SIZE) }; + fn payload<'a>(&'a self) -> &'a [u8] { + unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of::()) } } } @@ -41,7 +42,6 @@ pub struct AssociateRequest { impl MacCommand for AssociateRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; - const SIZE: usize = 25; } /// MLME DISASSOCIATE Request sed to request a disassociation @@ -70,20 +70,22 @@ pub struct DisassociateRequest { impl MacCommand for DisassociateRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq; - const SIZE: usize = 24; } /// MLME GET Request used to request a PIB value #[repr(C)] +#[derive(Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct GetRequest { /// the name of the PIB attribute to read pub pib_attribute: PibId, + + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 3], } impl MacCommand for GetRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; - const SIZE: usize = 4; } /// MLME GTS Request used to request and maintain GTSs @@ -104,19 +106,20 @@ pub struct GtsRequest { impl MacCommand for GtsRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; - const SIZE: usize = 12; } #[repr(C)] +#[derive(Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ResetRequest { /// MAC PIB attributes are set to their default values or not during reset pub set_default_pib: bool, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 3], } impl MacCommand for ResetRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; - const SIZE: usize = 4; } /// MLME RX ENABLE Request used to request that the receiver is either enabled @@ -129,6 +132,8 @@ pub struct RxEnableRequest { /// configure the transceiver to RX with ranging for a value of /// RANGING_ON or to not enable ranging for RANGING_OFF pub ranging_rx_control: u8, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 2], /// number of symbols measured before the receiver is to be enabled or disabled pub rx_on_time: [u8; 4], /// number of symbols for which the receiver is to be enabled @@ -137,19 +142,6 @@ pub struct RxEnableRequest { impl MacCommand for RxEnableRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeRxEnableReq; - const SIZE: usize = 12; - - fn copy_into_slice(&self, buf: &mut [u8]) { - buf[0] = self.defer_permit as u8; - buf[1] = self.ranging_rx_control as u8; - - // stuffing to keep 32bit alignment - buf[2] = 0; - buf[3] = 0; - - buf[4..8].copy_from_slice(&self.rx_on_time); - buf[8..12].copy_from_slice(&self.rx_on_duration); - } } /// MLME SCAN Request used to initiate a channel scan over a given list of channels @@ -172,11 +164,12 @@ pub struct ScanRequest { pub key_id_mode: KeyIdMode, /// index of the key to be used pub key_index: u8, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 2], } impl MacCommand for ScanRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeScanReq; - const SIZE: usize = 20; } /// MLME SET Request used to attempt to write the given value to the indicated PIB attribute @@ -191,13 +184,12 @@ pub struct SetRequest { impl MacCommand for SetRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; - const SIZE: usize = 8; } /// MLME START Request used by the FFDs to intiate a new PAN or to begin using a new superframe /// configuration -#[derive(Default)] #[repr(C)] +#[derive(Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct StartRequest { /// PAN indentifier to used by the device @@ -236,7 +228,6 @@ pub struct StartRequest { impl MacCommand for StartRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq; - const SIZE: usize = 35; } /// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if @@ -253,11 +244,12 @@ pub struct SyncRequest { /// /// `false` if the MLME is to synchronize with only the next beacon pub track_beacon: bool, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 1], } impl MacCommand for SyncRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq; - const SIZE: usize = 4; } /// MLME POLL Request propmts the device to request data from the coordinator @@ -278,11 +270,12 @@ pub struct PollRequest { pub key_source: [u8; 8], /// PAN identifier of the coordinator pub coord_pan_id: PanId, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 2], } impl MacCommand for PollRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq; - const SIZE: usize = 24; } /// MLME DPS Request allows the next higher layer to request that the PHY utilize a @@ -297,33 +290,38 @@ pub struct DpsRequest { /// the number of symbols for which the transmitter and receiver will utilize the /// respective DPS indices dps_index_duration: u8, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 1], } impl MacCommand for DpsRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq; - const SIZE: usize = 4; } /// MLME SOUNDING request primitive which is used by the next higher layer to request that /// the PHY respond with channel sounding information #[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct SoundingRequest; +pub struct SoundingRequest { + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 4], +} impl MacCommand for SoundingRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq; - const SIZE: usize = 4; } /// MLME CALIBRATE request primitive which used to obtain the results of a ranging /// calibration request from an RDEV #[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct CalibrateRequest; +pub struct CalibrateRequest { + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 4], +} impl MacCommand for CalibrateRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq; - const SIZE: usize = 4; } /// MCPS DATA Request used for MAC data related requests from the application @@ -370,6 +368,15 @@ pub struct DataRequest { pub datrate: u8, } +impl DataRequest { + pub fn set_buffer<'a>(&'a mut self, buf: &'a [u8]) -> &mut Self { + self.msdu_ptr = &buf as *const _ as *const u8; + self.msdu_length = buf.len() as u8; + + self + } +} + impl Default for DataRequest { fn default() -> Self { Self { @@ -397,7 +404,6 @@ impl Default for DataRequest { impl MacCommand for DataRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq; - const SIZE: usize = 40; } /// for MCPS PURGE Request used to purge an MSDU from the transaction queue @@ -407,11 +413,12 @@ pub struct PurgeRequest { /// the handle associated with the MSDU to be purged from the transaction /// queue pub msdu_handle: u8, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 3], } impl MacCommand for PurgeRequest { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq; - const SIZE: usize = 4; } /// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication @@ -434,11 +441,12 @@ pub struct AssociateResponse { pub key_id_mode: KeyIdMode, /// the index of the key to be used pub key_index: u8, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 2], } impl MacCommand for AssociateResponse { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes; - const SIZE: usize = 24; } /// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication @@ -459,9 +467,10 @@ pub struct OrphanResponse { pub key_id_mode: KeyIdMode, /// the index of the key to be used pub key_index: u8, + /// byte stuffing to keep 32 bit alignment + pub a_stuffing: [u8; 2], } impl MacCommand for OrphanResponse { const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes; - const SIZE: usize = 24; } diff --git a/embassy-stm32-wpan/src/mac/typedefs.rs b/embassy-stm32-wpan/src/mac/typedefs.rs index 30c7731b2..98c67c86b 100644 --- a/embassy-stm32-wpan/src/mac/typedefs.rs +++ b/embassy-stm32-wpan/src/mac/typedefs.rs @@ -37,9 +37,11 @@ numeric_enum! { numeric_enum! { #[repr(u8)] /// this enum contains all the MAC PIB Ids + #[derive(Default)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum PibId { // PHY + #[default] CurrentChannel = 0x00, ChannelsSupported = 0x01, TransmitPower = 0x02, diff --git a/embassy-stm32-wpan/src/sub/mac.rs b/embassy-stm32-wpan/src/sub/mac.rs index 4893cb47b..d30ed2f11 100644 --- a/embassy-stm32-wpan/src/sub/mac.rs +++ b/embassy-stm32-wpan/src/sub/mac.rs @@ -85,12 +85,7 @@ impl Mac { where T: MacCommand, { - let mut payload = [0u8; MAX_PACKET_SIZE]; - cmd.copy_into_slice(&mut payload); - - let response = self - .tl_write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]) - .await; + let response = self.tl_write_and_get_response(T::OPCODE as u16, cmd.payload()).await; if response == 0x00 { Ok(()) @@ -107,8 +102,6 @@ impl Mac { } } -const MAX_PACKET_SIZE: usize = 255; - impl evt::MemoryManager for Mac { /// SAFETY: passing a pointer to something other than a managed event packet is UB unsafe fn drop_event_packet(_: *mut EvtPacket) { diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs index e4d81997e..f8c8ba288 100644 --- a/examples/stm32wb/src/bin/mac_ffd.rs +++ b/examples/stm32wb/src/bin/mac_ffd.rs @@ -67,7 +67,10 @@ async fn main(spawner: Spawner) { info!("resetting"); mbox.mac_subsystem - .send_command(&ResetRequest { set_default_pib: true }) + .send_command(&ResetRequest { + set_default_pib: true, + ..Default::default() + }) .await .unwrap(); let evt = mbox.mac_subsystem.read().await; diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs index b2dac72cc..b0eb91061 100644 --- a/examples/stm32wb/src/bin/mac_rfd.rs +++ b/examples/stm32wb/src/bin/mac_rfd.rs @@ -69,7 +69,10 @@ async fn main(spawner: Spawner) { info!("resetting"); mbox.mac_subsystem - .send_command(&ResetRequest { set_default_pib: true }) + .send_command(&ResetRequest { + set_default_pib: true, + ..Default::default() + }) .await .unwrap(); let evt = mbox.mac_subsystem.read().await; @@ -91,6 +94,7 @@ async fn main(spawner: Spawner) { mbox.mac_subsystem .send_command(&GetRequest { pib_attribute: PibId::ExtendedAddress, + ..Default::default() }) .await .unwrap(); @@ -141,23 +145,22 @@ async fn main(spawner: Spawner) { info!("{:#x}", evt); info!("sending data"); - let mut data_buffer = [0u8; 256]; let data = b"Hello from embassy!"; - data_buffer[..data.len()].copy_from_slice(data); mbox.mac_subsystem - .send_command(&DataRequest { - src_addr_mode: AddressMode::Short, - dst_addr_mode: AddressMode::Short, - dst_pan_id: PanId([0x1A, 0xAA]), - dst_address: MacAddress::BROADCAST, - msdu_handle: 0x02, - ack_tx: 0x00, - gts_tx: false, - msdu_ptr: &data_buffer as *const _ as *const u8, - msdu_length: data.len() as u8, - security_level: SecurityLevel::Unsecure, - ..Default::default() - }) + .send_command( + DataRequest { + src_addr_mode: AddressMode::Short, + dst_addr_mode: AddressMode::Short, + dst_pan_id: PanId([0x1A, 0xAA]), + dst_address: MacAddress::BROADCAST, + msdu_handle: 0x02, + ack_tx: 0x00, + gts_tx: false, + security_level: SecurityLevel::Unsecure, + ..Default::default() + } + .set_buffer(data), + ) .await .unwrap(); let evt = mbox.mac_subsystem.read().await; diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs index cfa0aca3b..2fc15dc9d 100644 --- a/tests/stm32/src/bin/wpan_mac.rs +++ b/tests/stm32/src/bin/wpan_mac.rs @@ -49,7 +49,10 @@ async fn main(spawner: Spawner) { info!("resetting"); mbox.mac_subsystem - .send_command(&ResetRequest { set_default_pib: true }) + .send_command(&ResetRequest { + set_default_pib: true, + ..Default::default() + }) .await .unwrap(); let evt = mbox.mac_subsystem.read().await; @@ -71,6 +74,7 @@ async fn main(spawner: Spawner) { mbox.mac_subsystem .send_command(&GetRequest { pib_attribute: PibId::ExtendedAddress, + ..Default::default() }) .await .unwrap(); From 7c465465c1a97234c3fbeb18154bfd7f79ab07f2 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 13:59:15 -0500 Subject: [PATCH 2/7] wpan: use builtin conversion methods --- embassy-stm32-wpan/src/mac/event.rs | 4 ++-- embassy-stm32-wpan/src/mac/helpers.rs | 7 ------- embassy-stm32-wpan/src/mac/indications.rs | 13 ++++++------- embassy-stm32-wpan/src/mac/mod.rs | 1 - embassy-stm32-wpan/src/mac/responses.rs | 15 +++++++-------- 5 files changed, 15 insertions(+), 25 deletions(-) delete mode 100644 embassy-stm32-wpan/src/mac/helpers.rs diff --git a/embassy-stm32-wpan/src/mac/event.rs b/embassy-stm32-wpan/src/mac/event.rs index dfce21fea..c2bdc7e11 100644 --- a/embassy-stm32-wpan/src/mac/event.rs +++ b/embassy-stm32-wpan/src/mac/event.rs @@ -1,4 +1,3 @@ -use super::helpers::to_u16; use super::indications::{ AssociateIndication, BeaconNotifyIndication, CommStatusIndication, DataIndication, DisassociateIndication, DpsIndication, GtsIndication, OrphanIndication, PollIndication, SyncLossIndication, @@ -58,7 +57,8 @@ impl TryFrom<&[u8]> for MacEvent { type Error = (); fn try_from(value: &[u8]) -> Result { - let opcode = to_u16(&value[0..2]); + let opcode = u16::from_le_bytes(value[0..2].try_into().unwrap()); + let opcode = OpcodeM0ToM4::try_from(opcode)?; let buf = &value[2..]; diff --git a/embassy-stm32-wpan/src/mac/helpers.rs b/embassy-stm32-wpan/src/mac/helpers.rs deleted file mode 100644 index 5a5bf8a85..000000000 --- a/embassy-stm32-wpan/src/mac/helpers.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub fn to_u16(buf: &[u8]) -> u16 { - ((buf[1] as u16) << 8) | buf[0] as u16 -} - -pub fn to_u32(buf: &[u8]) -> u32 { - ((buf[0] as u32) << 0) + ((buf[1] as u32) << 8) + ((buf[2] as u32) << 16) + ((buf[3] as u32) << 24) -} diff --git a/embassy-stm32-wpan/src/mac/indications.rs b/embassy-stm32-wpan/src/mac/indications.rs index 6df4aa23a..436b9ac9c 100644 --- a/embassy-stm32-wpan/src/mac/indications.rs +++ b/embassy-stm32-wpan/src/mac/indications.rs @@ -1,6 +1,5 @@ use super::consts::MAX_PENDING_ADDRESS; use super::event::ParseableMacEvent; -use super::helpers::to_u32; use super::typedefs::{ AddressMode, Capabilities, DisassociationReason, KeyIdMode, MacAddress, MacChannel, MacStatus, PanDescriptor, PanId, SecurityLevel, @@ -114,7 +113,7 @@ impl ParseableMacEvent for BeaconNotifyIndication { ]; Ok(Self { - sdu_ptr: to_u32(&buf[0..4]) as *const u8, + sdu_ptr: u32::from_le_bytes(buf[0..4].try_into().unwrap()) as *const u8, pan_descriptor: PanDescriptor::try_from(&buf[4..26])?, addr_list, bsn: buf[82], @@ -405,7 +404,7 @@ impl ParseableMacEvent for DataIndication { }; Ok(Self { - msdu_ptr: to_u32(&buf[0..4]) as *const u8, + msdu_ptr: u32::from_le_bytes(buf[0..4].try_into().unwrap()) as *const u8, src_addr_mode, src_pan_id: PanId([buf[5], buf[6]]), src_address, @@ -424,10 +423,10 @@ impl ParseableMacEvent for DataIndication { uwn_preamble_symbol_repetitions: buf[45], datrate: buf[46], ranging_received: buf[47], - ranging_counter_start: to_u32(&buf[48..52]), - ranging_counter_stop: to_u32(&buf[52..56]), - ranging_tracking_interval: to_u32(&buf[56..60]), - ranging_offset: to_u32(&buf[60..64]), + ranging_counter_start: u32::from_le_bytes(buf[48..52].try_into().unwrap()), + ranging_counter_stop: u32::from_le_bytes(buf[52..56].try_into().unwrap()), + ranging_tracking_interval: u32::from_le_bytes(buf[56..60].try_into().unwrap()), + ranging_offset: u32::from_le_bytes(buf[60..64].try_into().unwrap()), ranging_fom: buf[65], rssi: buf[66], }) diff --git a/embassy-stm32-wpan/src/mac/mod.rs b/embassy-stm32-wpan/src/mac/mod.rs index 1af8fe6ba..8d5edad6b 100644 --- a/embassy-stm32-wpan/src/mac/mod.rs +++ b/embassy-stm32-wpan/src/mac/mod.rs @@ -1,7 +1,6 @@ pub mod commands; mod consts; pub mod event; -mod helpers; pub mod indications; mod macros; mod opcodes; diff --git a/embassy-stm32-wpan/src/mac/responses.rs b/embassy-stm32-wpan/src/mac/responses.rs index 2f6f5bf58..d29257f84 100644 --- a/embassy-stm32-wpan/src/mac/responses.rs +++ b/embassy-stm32-wpan/src/mac/responses.rs @@ -1,6 +1,5 @@ use super::consts::{MAX_ED_SCAN_RESULTS_SUPPORTED, MAX_PAN_DESC_SUPPORTED, MAX_SOUNDING_LIST_SUPPORTED}; use super::event::ParseableMacEvent; -use super::helpers::to_u32; use super::typedefs::{ AddressMode, AssociationStatus, KeyIdMode, MacAddress, MacStatus, PanDescriptor, PanId, PibId, ScanType, SecurityLevel, @@ -100,7 +99,7 @@ impl ParseableMacEvent for GetConfirm { fn try_parse(buf: &[u8]) -> Result { Self::validate(buf)?; - let address = to_u32(&buf[0..4]); + let address = u32::from_le_bytes(buf[0..4].try_into().unwrap()); Ok(Self { pib_attribute_value_ptr: address as *const u8, @@ -357,8 +356,8 @@ impl ParseableMacEvent for CalibrateConfirm { Ok(Self { status: MacStatus::try_from(buf[0])?, // 3 byte stuffing - cal_tx_rmaker_offset: to_u32(&buf[4..8]), - cal_rx_rmaker_offset: to_u32(&buf[8..12]), + cal_tx_rmaker_offset: u32::from_le_bytes(buf[4..8].try_into().unwrap()), + cal_rx_rmaker_offset: u32::from_le_bytes(buf[8..12].try_into().unwrap()), }) } } @@ -400,10 +399,10 @@ impl ParseableMacEvent for DataConfirm { time_stamp: [buf[1], buf[2], buf[3], buf[4]], ranging_received: buf[5], status: MacStatus::try_from(buf[6])?, - ranging_counter_start: to_u32(&buf[7..11]), - ranging_counter_stop: to_u32(&buf[11..15]), - ranging_tracking_interval: to_u32(&buf[15..19]), - ranging_offset: to_u32(&buf[19..23]), + ranging_counter_start: u32::from_le_bytes(buf[7..11].try_into().unwrap()), + ranging_counter_stop: u32::from_le_bytes(buf[11..15].try_into().unwrap()), + ranging_tracking_interval: u32::from_le_bytes(buf[15..19].try_into().unwrap()), + ranging_offset: u32::from_le_bytes(buf[19..23].try_into().unwrap()), ranging_fom: buf[24], }) } From 28b419d65ede6ff29c79dbcaa27145f1c3458a57 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 15:09:30 -0500 Subject: [PATCH 3/7] wpan/mac: use lifetimes to control events --- embassy-stm32-wpan/src/mac/event.rs | 169 ++++++++------ embassy-stm32-wpan/src/mac/indications.rs | 269 ++------------------- embassy-stm32-wpan/src/mac/responses.rs | 271 ++++------------------ embassy-stm32-wpan/src/sub/mac.rs | 9 +- examples/stm32wb/src/bin/mac_ffd.rs | 46 ++-- examples/stm32wb/src/bin/mac_rfd.rs | 55 +++-- tests/stm32/src/bin/wpan_mac.rs | 32 ++- 7 files changed, 243 insertions(+), 608 deletions(-) diff --git a/embassy-stm32-wpan/src/mac/event.rs b/embassy-stm32-wpan/src/mac/event.rs index c2bdc7e11..67f207d57 100644 --- a/embassy-stm32-wpan/src/mac/event.rs +++ b/embassy-stm32-wpan/src/mac/event.rs @@ -1,3 +1,5 @@ +use core::mem; + use super::indications::{ AssociateIndication, BeaconNotifyIndication, CommStatusIndication, DataIndication, DisassociateIndication, DpsIndication, GtsIndication, OrphanIndication, PollIndication, SyncLossIndication, @@ -6,89 +8,110 @@ use super::responses::{ AssociateConfirm, CalibrateConfirm, DataConfirm, DisassociateConfirm, DpsConfirm, GetConfirm, GtsConfirm, PollConfirm, PurgeConfirm, ResetConfirm, RxEnableConfirm, ScanConfirm, SetConfirm, SoundingConfirm, StartConfirm, }; +use crate::evt::EvtBox; use crate::mac::opcodes::OpcodeM0ToM4; +use crate::sub::mac::Mac; -pub trait ParseableMacEvent { - const SIZE: usize; - - fn validate(buf: &[u8]) -> Result<(), ()> { - if buf.len() < Self::SIZE { - return Err(()); +pub(crate) trait ParseableMacEvent: Sized { + fn from_buffer<'a>(buf: &'a [u8]) -> Result<&'a Self, ()> { + if buf.len() < mem::size_of::() { + Err(()) + } else { + Ok(unsafe { &*(buf as *const _ as *const Self) }) } + } +} - Ok(()) +pub struct Event { + event_box: EvtBox, +} + +impl Event { + pub(crate) fn new(event_box: EvtBox) -> Self { + Self { event_box } } - fn try_parse(buf: &[u8]) -> Result - where - Self: Sized; -} - -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub enum MacEvent { - MlmeAssociateCnf(AssociateConfirm), - MlmeDisassociateCnf(DisassociateConfirm), - MlmeGetCnf(GetConfirm), - MlmeGtsCnf(GtsConfirm), - MlmeResetCnf(ResetConfirm), - MlmeRxEnableCnf(RxEnableConfirm), - MlmeScanCnf(ScanConfirm), - MlmeSetCnf(SetConfirm), - MlmeStartCnf(StartConfirm), - MlmePollCnf(PollConfirm), - MlmeDpsCnf(DpsConfirm), - MlmeSoundingCnf(SoundingConfirm), - MlmeCalibrateCnf(CalibrateConfirm), - McpsDataCnf(DataConfirm), - McpsPurgeCnf(PurgeConfirm), - MlmeAssociateInd(AssociateIndication), - MlmeDisassociateInd(DisassociateIndication), - MlmeBeaconNotifyInd(BeaconNotifyIndication), - MlmeCommStatusInd(CommStatusIndication), - MlmeGtsInd(GtsIndication), - MlmeOrphanInd(OrphanIndication), - MlmeSyncLossInd(SyncLossIndication), - MlmeDpsInd(DpsIndication), - McpsDataInd(DataIndication), - MlmePollInd(PollIndication), -} - -impl TryFrom<&[u8]> for MacEvent { - type Error = (); - - fn try_from(value: &[u8]) -> Result { - let opcode = u16::from_le_bytes(value[0..2].try_into().unwrap()); + pub fn mac_event<'a>(&'a self) -> Result, ()> { + let payload = self.event_box.payload(); + let opcode = u16::from_le_bytes(payload[0..2].try_into().unwrap()); let opcode = OpcodeM0ToM4::try_from(opcode)?; - let buf = &value[2..]; - match opcode { - OpcodeM0ToM4::MlmeAssociateCnf => Ok(Self::MlmeAssociateCnf(AssociateConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeDisassociateCnf => Ok(Self::MlmeDisassociateCnf(DisassociateConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeGetCnf => Ok(Self::MlmeGetCnf(GetConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeGtsCnf => Ok(Self::MlmeGtsCnf(GtsConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeResetCnf => Ok(Self::MlmeResetCnf(ResetConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeRxEnableCnf => Ok(Self::MlmeRxEnableCnf(RxEnableConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeScanCnf => Ok(Self::MlmeScanCnf(ScanConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeSetCnf => Ok(Self::MlmeSetCnf(SetConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeStartCnf => Ok(Self::MlmeStartCnf(StartConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmePollCnf => Ok(Self::MlmePollCnf(PollConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeDpsCnf => Ok(Self::MlmeDpsCnf(DpsConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeSoundingCnf => Ok(Self::MlmeSoundingCnf(SoundingConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeCalibrateCnf => Ok(Self::MlmeCalibrateCnf(CalibrateConfirm::try_parse(buf)?)), - OpcodeM0ToM4::McpsDataCnf => Ok(Self::McpsDataCnf(DataConfirm::try_parse(buf)?)), - OpcodeM0ToM4::McpsPurgeCnf => Ok(Self::McpsPurgeCnf(PurgeConfirm::try_parse(buf)?)), - OpcodeM0ToM4::MlmeAssociateInd => Ok(Self::MlmeAssociateInd(AssociateIndication::try_parse(buf)?)), - OpcodeM0ToM4::MlmeDisassociateInd => Ok(Self::MlmeDisassociateInd(DisassociateIndication::try_parse(buf)?)), - OpcodeM0ToM4::MlmeBeaconNotifyInd => Ok(Self::MlmeBeaconNotifyInd(BeaconNotifyIndication::try_parse(buf)?)), - OpcodeM0ToM4::MlmeCommStatusInd => Ok(Self::MlmeCommStatusInd(CommStatusIndication::try_parse(buf)?)), - OpcodeM0ToM4::MlmeGtsInd => Ok(Self::MlmeGtsInd(GtsIndication::try_parse(buf)?)), - OpcodeM0ToM4::MlmeOrphanInd => Ok(Self::MlmeOrphanInd(OrphanIndication::try_parse(buf)?)), - OpcodeM0ToM4::MlmeSyncLossInd => Ok(Self::MlmeSyncLossInd(SyncLossIndication::try_parse(buf)?)), - OpcodeM0ToM4::MlmeDpsInd => Ok(Self::MlmeDpsInd(DpsIndication::try_parse(buf)?)), - OpcodeM0ToM4::McpsDataInd => Ok(Self::McpsDataInd(DataIndication::try_parse(buf)?)), - OpcodeM0ToM4::MlmePollInd => Ok(Self::MlmePollInd(PollIndication::try_parse(buf)?)), + OpcodeM0ToM4::MlmeAssociateCnf => Ok(MacEvent::MlmeAssociateCnf(AssociateConfirm::from_buffer( + &payload[2..], + )?)), + OpcodeM0ToM4::MlmeDisassociateCnf => Ok(MacEvent::MlmeDisassociateCnf(DisassociateConfirm::from_buffer( + &payload[2..], + )?)), + OpcodeM0ToM4::MlmeGetCnf => Ok(MacEvent::MlmeGetCnf(GetConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeGtsCnf => Ok(MacEvent::MlmeGtsCnf(GtsConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeResetCnf => Ok(MacEvent::MlmeResetCnf(ResetConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeRxEnableCnf => { + Ok(MacEvent::MlmeRxEnableCnf(RxEnableConfirm::from_buffer(&payload[2..])?)) + } + OpcodeM0ToM4::MlmeScanCnf => Ok(MacEvent::MlmeScanCnf(ScanConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeSetCnf => Ok(MacEvent::MlmeSetCnf(SetConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeStartCnf => Ok(MacEvent::MlmeStartCnf(StartConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmePollCnf => Ok(MacEvent::MlmePollCnf(PollConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeDpsCnf => Ok(MacEvent::MlmeDpsCnf(DpsConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeSoundingCnf => { + Ok(MacEvent::MlmeSoundingCnf(SoundingConfirm::from_buffer(&payload[2..])?)) + } + OpcodeM0ToM4::MlmeCalibrateCnf => Ok(MacEvent::MlmeCalibrateCnf(CalibrateConfirm::from_buffer( + &payload[2..], + )?)), + OpcodeM0ToM4::McpsDataCnf => Ok(MacEvent::McpsDataCnf(DataConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::McpsPurgeCnf => Ok(MacEvent::McpsPurgeCnf(PurgeConfirm::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeAssociateInd => Ok(MacEvent::MlmeAssociateInd(AssociateIndication::from_buffer( + &payload[2..], + )?)), + OpcodeM0ToM4::MlmeDisassociateInd => Ok(MacEvent::MlmeDisassociateInd( + DisassociateIndication::from_buffer(&payload[2..])?, + )), + OpcodeM0ToM4::MlmeBeaconNotifyInd => Ok(MacEvent::MlmeBeaconNotifyInd( + BeaconNotifyIndication::from_buffer(&payload[2..])?, + )), + OpcodeM0ToM4::MlmeCommStatusInd => Ok(MacEvent::MlmeCommStatusInd(CommStatusIndication::from_buffer( + &payload[2..], + )?)), + OpcodeM0ToM4::MlmeGtsInd => Ok(MacEvent::MlmeGtsInd(GtsIndication::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeOrphanInd => Ok(MacEvent::MlmeOrphanInd(OrphanIndication::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeSyncLossInd => Ok(MacEvent::MlmeSyncLossInd(SyncLossIndication::from_buffer( + &payload[2..], + )?)), + OpcodeM0ToM4::MlmeDpsInd => Ok(MacEvent::MlmeDpsInd(DpsIndication::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::McpsDataInd => Ok(MacEvent::McpsDataInd(DataIndication::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmePollInd => Ok(MacEvent::MlmePollInd(PollIndication::from_buffer(&payload[2..])?)), } } } + +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum MacEvent<'a> { + MlmeAssociateCnf(&'a AssociateConfirm), + MlmeDisassociateCnf(&'a DisassociateConfirm), + MlmeGetCnf(&'a GetConfirm), + MlmeGtsCnf(&'a GtsConfirm), + MlmeResetCnf(&'a ResetConfirm), + MlmeRxEnableCnf(&'a RxEnableConfirm), + MlmeScanCnf(&'a ScanConfirm), + MlmeSetCnf(&'a SetConfirm), + MlmeStartCnf(&'a StartConfirm), + MlmePollCnf(&'a PollConfirm), + MlmeDpsCnf(&'a DpsConfirm), + MlmeSoundingCnf(&'a SoundingConfirm), + MlmeCalibrateCnf(&'a CalibrateConfirm), + McpsDataCnf(&'a DataConfirm), + McpsPurgeCnf(&'a PurgeConfirm), + MlmeAssociateInd(&'a AssociateIndication), + MlmeDisassociateInd(&'a DisassociateIndication), + MlmeBeaconNotifyInd(&'a BeaconNotifyIndication), + MlmeCommStatusInd(&'a CommStatusIndication), + MlmeGtsInd(&'a GtsIndication), + MlmeOrphanInd(&'a OrphanIndication), + MlmeSyncLossInd(&'a SyncLossIndication), + MlmeDpsInd(&'a DpsIndication), + McpsDataInd(&'a DataIndication), + MlmePollInd(&'a PollIndication), +} diff --git a/embassy-stm32-wpan/src/mac/indications.rs b/embassy-stm32-wpan/src/mac/indications.rs index 436b9ac9c..c7e9be84a 100644 --- a/embassy-stm32-wpan/src/mac/indications.rs +++ b/embassy-stm32-wpan/src/mac/indications.rs @@ -23,22 +23,7 @@ pub struct AssociateIndication { pub key_source: [u8; 8], } -impl ParseableMacEvent for AssociateIndication { - const SIZE: usize = 20; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - device_address: [buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]], - capability_information: Capabilities::from_bits(buf[8]).ok_or(())?, - security_level: SecurityLevel::try_from(buf[9])?, - key_id_mode: KeyIdMode::try_from(buf[10])?, - key_index: buf[11], - key_source: [buf[12], buf[13], buf[14], buf[15], buf[16], buf[17], buf[18], buf[19]], - }) - } -} +impl ParseableMacEvent for AssociateIndication {} /// MLME DISASSOCIATE indication which will be used to send /// disassociation indication to the application. @@ -58,22 +43,7 @@ pub struct DisassociateIndication { pub key_source: [u8; 8], } -impl ParseableMacEvent for DisassociateIndication { - const SIZE: usize = 20; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - device_address: [buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]], - disassociation_reason: DisassociationReason::try_from(buf[8])?, - security_level: SecurityLevel::try_from(buf[9])?, - key_id_mode: KeyIdMode::try_from(buf[10])?, - key_index: buf[11], - key_source: [buf[12], buf[13], buf[14], buf[15], buf[16], buf[17], buf[18], buf[19]], - }) - } -} +impl ParseableMacEvent for DisassociateIndication {} /// MLME BEACON NOTIIFY Indication which is used to send parameters contained /// within a beacon frame received by the MAC to the application @@ -94,34 +64,7 @@ pub struct BeaconNotifyIndication { pub sdu_length: u8, } -impl ParseableMacEvent for BeaconNotifyIndication { - const SIZE: usize = 88; - - fn try_parse(buf: &[u8]) -> Result { - // TODO: this is unchecked - - Self::validate(buf)?; - - let addr_list = [ - MacAddress::try_from(&buf[26..34])?, - MacAddress::try_from(&buf[34..42])?, - MacAddress::try_from(&buf[42..50])?, - MacAddress::try_from(&buf[50..58])?, - MacAddress::try_from(&buf[58..66])?, - MacAddress::try_from(&buf[66..74])?, - MacAddress::try_from(&buf[74..82])?, - ]; - - Ok(Self { - sdu_ptr: u32::from_le_bytes(buf[0..4].try_into().unwrap()) as *const u8, - pan_descriptor: PanDescriptor::try_from(&buf[4..26])?, - addr_list, - bsn: buf[82], - pend_addr_spec: buf[83], - sdu_length: buf[83], - }) - } -} +impl ParseableMacEvent for BeaconNotifyIndication {} /// MLME COMM STATUS Indication which is used by the MAC to indicate a communications status #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -149,51 +92,7 @@ pub struct CommStatusIndication { pub key_source: [u8; 8], } -impl ParseableMacEvent for CommStatusIndication { - const SIZE: usize = 32; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - let src_addr_mode = AddressMode::try_from(buf[2])?; - let dst_addr_mode = AddressMode::try_from(buf[3])?; - - let src_address = match src_addr_mode { - AddressMode::NoAddress => MacAddress { short: [0, 0] }, - AddressMode::Reserved => MacAddress { short: [0, 0] }, - AddressMode::Short => MacAddress { - short: [buf[4], buf[5]], - }, - AddressMode::Extended => MacAddress { - extended: [buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]], - }, - }; - - let dst_address = match dst_addr_mode { - AddressMode::NoAddress => MacAddress { short: [0, 0] }, - AddressMode::Reserved => MacAddress { short: [0, 0] }, - AddressMode::Short => MacAddress { - short: [buf[12], buf[13]], - }, - AddressMode::Extended => MacAddress { - extended: [buf[12], buf[13], buf[14], buf[15], buf[16], buf[17], buf[18], buf[19]], - }, - }; - - Ok(Self { - pan_id: PanId([buf[0], buf[1]]), - src_addr_mode, - dst_addr_mode, - src_address, - dst_address, - status: MacStatus::try_from(buf[20])?, - security_level: SecurityLevel::try_from(buf[21])?, - key_id_mode: KeyIdMode::try_from(buf[22])?, - key_index: buf[23], - key_source: [buf[24], buf[25], buf[26], buf[27], buf[28], buf[29], buf[30], buf[31]], - }) - } -} +impl ParseableMacEvent for CommStatusIndication {} /// MLME GTS Indication indicates that a GTS has been allocated or that a /// previously allocated GTS has been deallocated @@ -209,27 +108,13 @@ pub struct GtsIndication { pub key_id_mode: KeyIdMode, /// Index of the key to be used pub key_index: u8, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 2], /// Originator of the key to be used pub key_source: [u8; 8], } -impl ParseableMacEvent for GtsIndication { - const SIZE: usize = 16; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - device_address: [buf[0], buf[1]], - gts_characteristics: buf[2], - security_level: SecurityLevel::try_from(buf[3])?, - key_id_mode: KeyIdMode::try_from(buf[4])?, - key_index: buf[5], - // 2 byte stuffing - key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]], - }) - } -} +impl ParseableMacEvent for GtsIndication {} /// MLME ORPHAN Indication which is used by the coordinator to notify the /// application of the presence of an orphaned device @@ -245,24 +130,11 @@ pub struct OrphanIndication { pub key_id_mode: KeyIdMode, /// Index of the key used by the originator of the received frame pub key_index: u8, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 1], } -impl ParseableMacEvent for OrphanIndication { - const SIZE: usize = 20; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - orphan_address: [buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]], - key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]], - security_level: SecurityLevel::try_from(buf[16])?, - key_id_mode: KeyIdMode::try_from(buf[17])?, - key_index: buf[18], - // 1 byte stuffing - }) - } -} +impl ParseableMacEvent for OrphanIndication {} /// MLME SYNC LOSS Indication which is used by the MAC to indicate the loss /// of synchronization with the coordinator @@ -286,42 +158,20 @@ pub struct SyncLossIndication { pub key_source: [u8; 8], } -impl ParseableMacEvent for SyncLossIndication { - const SIZE: usize = 16; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - pan_id: PanId([buf[0], buf[1]]), - loss_reason: buf[2], - channel_number: MacChannel::try_from(buf[3])?, - channel_page: buf[4], - security_level: SecurityLevel::try_from(buf[5])?, - key_id_mode: KeyIdMode::try_from(buf[6])?, - key_index: buf[7], - key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]], - }) - } -} +impl ParseableMacEvent for SyncLossIndication {} /// MLME DPS Indication which indicates the expiration of the DPSIndexDuration /// and the resetting of the DPS values in the PHY #[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct DpsIndication; - -impl ParseableMacEvent for DpsIndication { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self) - } +pub struct DpsIndication { + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 4], } +impl ParseableMacEvent for DpsIndication {} + #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[repr(C, align(8))] +#[repr(C)] pub struct DataIndication { /// Pointer to the set of octets forming the MSDU being indicated pub msdu_ptr: *const u8, @@ -373,65 +223,7 @@ pub struct DataIndication { pub rssi: u8, } -impl ParseableMacEvent for DataIndication { - const SIZE: usize = 68; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - let src_addr_mode = AddressMode::try_from(buf[4])?; - let src_address = match src_addr_mode { - AddressMode::NoAddress => MacAddress { short: [0, 0] }, - AddressMode::Reserved => MacAddress { short: [0, 0] }, - AddressMode::Short => MacAddress { - short: [buf[7], buf[8]], - }, - AddressMode::Extended => MacAddress { - extended: [buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14]], - }, - }; - - let dst_addr_mode = AddressMode::try_from(buf[15])?; - let dst_address = match dst_addr_mode { - AddressMode::NoAddress => MacAddress { short: [0, 0] }, - AddressMode::Reserved => MacAddress { short: [0, 0] }, - AddressMode::Short => MacAddress { - short: [buf[18], buf[19]], - }, - AddressMode::Extended => MacAddress { - extended: [buf[18], buf[19], buf[20], buf[21], buf[22], buf[23], buf[24], buf[25]], - }, - }; - - Ok(Self { - msdu_ptr: u32::from_le_bytes(buf[0..4].try_into().unwrap()) as *const u8, - src_addr_mode, - src_pan_id: PanId([buf[5], buf[6]]), - src_address, - dst_addr_mode, - dst_pan_id: PanId([buf[16], buf[17]]), - dst_address, - msdu_length: buf[26], - mpdu_link_quality: buf[27], - dsn: buf[28], - time_stamp: [buf[29], buf[30], buf[31], buf[32]], - security_level: SecurityLevel::try_from(buf[33]).unwrap_or(SecurityLevel::Unsecure), // TODO: this is totaly wrong, but I'm too smol brain to fix it - key_id_mode: KeyIdMode::try_from(buf[34]).unwrap_or(KeyIdMode::Implicite), // TODO: this is totaly wrong, but I'm too smol brain to fix it - key_source: [buf[35], buf[36], buf[37], buf[38], buf[39], buf[40], buf[41], buf[42]], - key_index: buf[43], - uwbprf: buf[44], - uwn_preamble_symbol_repetitions: buf[45], - datrate: buf[46], - ranging_received: buf[47], - ranging_counter_start: u32::from_le_bytes(buf[48..52].try_into().unwrap()), - ranging_counter_stop: u32::from_le_bytes(buf[52..56].try_into().unwrap()), - ranging_tracking_interval: u32::from_le_bytes(buf[56..60].try_into().unwrap()), - ranging_offset: u32::from_le_bytes(buf[60..64].try_into().unwrap()), - ranging_fom: buf[65], - rssi: buf[66], - }) - } -} +impl ParseableMacEvent for DataIndication {} /// MLME POLL Indication which will be used for indicating the Data Request /// reception to upper layer as defined in Zigbee r22 - D.8.2 @@ -443,27 +235,4 @@ pub struct PollIndication { pub request_address: MacAddress, } -impl ParseableMacEvent for PollIndication { - const SIZE: usize = 9; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - let addr_mode = AddressMode::try_from(buf[0])?; - let request_address = match addr_mode { - AddressMode::NoAddress => MacAddress { short: [0, 0] }, - AddressMode::Reserved => MacAddress { short: [0, 0] }, - AddressMode::Short => MacAddress { - short: [buf[1], buf[2]], - }, - AddressMode::Extended => MacAddress { - extended: [buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]], - }, - }; - - Ok(Self { - addr_mode, - request_address, - }) - } -} +impl ParseableMacEvent for PollIndication {} diff --git a/embassy-stm32-wpan/src/mac/responses.rs b/embassy-stm32-wpan/src/mac/responses.rs index d29257f84..e0376a7f5 100644 --- a/embassy-stm32-wpan/src/mac/responses.rs +++ b/embassy-stm32-wpan/src/mac/responses.rs @@ -21,24 +21,11 @@ pub struct AssociateConfirm { pub key_id_mode: KeyIdMode, /// the index of the key to be used pub key_index: u8, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 2], } -impl ParseableMacEvent for AssociateConfirm { - const SIZE: usize = 16; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - assoc_short_address: [buf[0], buf[1]], - status: AssociationStatus::try_from(buf[2])?, - security_level: SecurityLevel::try_from(buf[3])?, - key_source: [buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]], - key_id_mode: KeyIdMode::try_from(buf[12])?, - key_index: buf[13], - }) - } -} +impl ParseableMacEvent for AssociateConfirm {} /// MLME DISASSOCIATE Confirm used to send disassociation Confirmation to the application. #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -53,32 +40,7 @@ pub struct DisassociateConfirm { pub device_address: MacAddress, } -impl ParseableMacEvent for DisassociateConfirm { - const SIZE: usize = 12; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - let device_addr_mode = AddressMode::try_from(buf[1])?; - let device_address = match device_addr_mode { - AddressMode::NoAddress => MacAddress { short: [0, 0] }, - AddressMode::Reserved => MacAddress { short: [0, 0] }, - AddressMode::Short => MacAddress { - short: [buf[4], buf[5]], - }, - AddressMode::Extended => MacAddress { - extended: [buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]], - }, - }; - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - device_addr_mode, - device_pan_id: PanId([buf[2], buf[3]]), - device_address, - }) - } -} +impl ParseableMacEvent for DisassociateConfirm {} /// MLME GET Confirm which requests information about a given PIB attribute #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -91,24 +53,11 @@ pub struct GetConfirm { pub pib_attribute: PibId, /// The lenght of the PIB attribute Value return pub pib_attribute_value_len: u8, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 1], } -impl ParseableMacEvent for GetConfirm { - const SIZE: usize = 8; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - let address = u32::from_le_bytes(buf[0..4].try_into().unwrap()); - - Ok(Self { - pib_attribute_value_ptr: address as *const u8, - status: MacStatus::try_from(buf[4])?, - pib_attribute: PibId::try_from(buf[5])?, - pib_attribute_value_len: buf[6], - }) - } -} +impl ParseableMacEvent for GetConfirm {} /// MLME GTS Confirm which eports the results of a request to allocate a new GTS /// or to deallocate an existing GTS @@ -118,39 +67,22 @@ pub struct GtsConfirm { pub gts_characteristics: u8, /// The status of the GTS reques pub status: MacStatus, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 2], } -impl ParseableMacEvent for GtsConfirm { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - gts_characteristics: buf[0], - status: MacStatus::try_from(buf[1])?, - }) - } -} +impl ParseableMacEvent for GtsConfirm {} /// MLME RESET Confirm which is used to report the results of the reset operation #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ResetConfirm { /// The result of the reset operation status: MacStatus, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 3], } -impl ParseableMacEvent for ResetConfirm { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - }) - } -} +impl ParseableMacEvent for ResetConfirm {} /// MLME RX ENABLE Confirm which is used to report the results of the attempt /// to enable or disable the receiver @@ -158,19 +90,11 @@ impl ParseableMacEvent for ResetConfirm { pub struct RxEnableConfirm { /// Result of the request to enable or disable the receiver status: MacStatus, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 3], } -impl ParseableMacEvent for RxEnableConfirm { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - }) - } -} +impl ParseableMacEvent for RxEnableConfirm {} /// MLME SCAN Confirm which is used to report the result of the channel scan request #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -195,42 +119,7 @@ pub struct ScanConfirm { pub uwb_energy_detect_list: [u8; MAX_ED_SCAN_RESULTS_SUPPORTED], } -impl ParseableMacEvent for ScanConfirm { - const SIZE: usize = 185; - - fn try_parse(buf: &[u8]) -> Result { - // TODO: this is unchecked - - Self::validate(buf)?; - - let mut energy_detect_list = [0; MAX_ED_SCAN_RESULTS_SUPPORTED]; - energy_detect_list.copy_from_slice(&buf[8..24]); - - let pan_descriptor_list = [ - PanDescriptor::try_from(&buf[24..46])?, - PanDescriptor::try_from(&buf[46..68])?, - PanDescriptor::try_from(&buf[68..90])?, - PanDescriptor::try_from(&buf[90..102])?, - PanDescriptor::try_from(&buf[102..124])?, - PanDescriptor::try_from(&buf[124..146])?, - ]; - - let mut uwb_energy_detect_list = [0; MAX_ED_SCAN_RESULTS_SUPPORTED]; - uwb_energy_detect_list.copy_from_slice(&buf[147..163]); - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - scan_type: ScanType::try_from(buf[1])?, - channel_page: buf[2], - unscanned_channels: [buf[3], buf[4], buf[5], buf[6]], - result_list_size: buf[7], - energy_detect_list, - pan_descriptor_list, - detected_category: buf[146], - uwb_energy_detect_list, - }) - } -} +impl ParseableMacEvent for ScanConfirm {} /// MLME SET Confirm which reports the result of an attempt to write a value to a PIB attribute #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -239,20 +128,11 @@ pub struct SetConfirm { pub status: MacStatus, /// The name of the PIB attribute that was written pub pin_attribute: PibId, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 2], } -impl ParseableMacEvent for SetConfirm { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - pin_attribute: PibId::try_from(buf[1])?, - }) - } -} +impl ParseableMacEvent for SetConfirm {} /// MLME START Confirm which is used to report the results of the attempt to /// start using a new superframe configuration @@ -260,57 +140,33 @@ impl ParseableMacEvent for SetConfirm { pub struct StartConfirm { /// Result of the attempt to start using an updated superframe configuration pub status: MacStatus, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 3], } -impl ParseableMacEvent for StartConfirm { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - }) - } -} +impl ParseableMacEvent for StartConfirm {} /// MLME POLL Confirm which is used to report the result of a request to poll the coordinator for data #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct PollConfirm { /// The status of the data request pub status: MacStatus, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 3], } -impl ParseableMacEvent for PollConfirm { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - }) - } -} +impl ParseableMacEvent for PollConfirm {} /// MLME DPS Confirm which reports the results of the attempt to enable or disable the DPS #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DpsConfirm { /// The status of the DPS request pub status: MacStatus, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 3], } -impl ParseableMacEvent for DpsConfirm { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - }) - } -} +impl ParseableMacEvent for DpsConfirm {} /// MLME SOUNDING Confirm which reports the result of a request to the PHY to provide /// channel sounding information @@ -318,20 +174,11 @@ impl ParseableMacEvent for DpsConfirm { pub struct SoundingConfirm { /// Results of the sounding measurement sounding_list: [u8; MAX_SOUNDING_LIST_SUPPORTED], + + status: u8, } -impl ParseableMacEvent for SoundingConfirm { - const SIZE: usize = 1; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - let mut sounding_list = [0u8; MAX_SOUNDING_LIST_SUPPORTED]; - sounding_list[..buf.len()].copy_from_slice(buf); - - Ok(Self { sounding_list }) - } -} +impl ParseableMacEvent for SoundingConfirm {} /// MLME CALIBRATE Confirm which reports the result of a request to the PHY /// to provide internal propagation path information @@ -339,6 +186,8 @@ impl ParseableMacEvent for SoundingConfirm { pub struct CalibrateConfirm { /// The status of the attempt to return sounding data pub status: MacStatus, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 3], /// A count of the propagation time from the ranging counter /// to the transmit antenna pub cal_tx_rmaker_offset: u32, @@ -347,20 +196,7 @@ pub struct CalibrateConfirm { pub cal_rx_rmaker_offset: u32, } -impl ParseableMacEvent for CalibrateConfirm { - const SIZE: usize = 12; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - status: MacStatus::try_from(buf[0])?, - // 3 byte stuffing - cal_tx_rmaker_offset: u32::from_le_bytes(buf[4..8].try_into().unwrap()), - cal_rx_rmaker_offset: u32::from_le_bytes(buf[8..12].try_into().unwrap()), - }) - } -} +impl ParseableMacEvent for CalibrateConfirm {} /// MCPS DATA Confirm which will be used for reporting the results of /// MAC data related requests from the application @@ -386,27 +222,11 @@ pub struct DataConfirm { pub ranging_offset: u32, /// The FoM characterizing the ranging measurement pub ranging_fom: u8, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 3], } -impl ParseableMacEvent for DataConfirm { - const SIZE: usize = 28; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - msdu_handle: buf[0], - time_stamp: [buf[1], buf[2], buf[3], buf[4]], - ranging_received: buf[5], - status: MacStatus::try_from(buf[6])?, - ranging_counter_start: u32::from_le_bytes(buf[7..11].try_into().unwrap()), - ranging_counter_stop: u32::from_le_bytes(buf[11..15].try_into().unwrap()), - ranging_tracking_interval: u32::from_le_bytes(buf[15..19].try_into().unwrap()), - ranging_offset: u32::from_le_bytes(buf[19..23].try_into().unwrap()), - ranging_fom: buf[24], - }) - } -} +impl ParseableMacEvent for DataConfirm {} /// MCPS PURGE Confirm which will be used by the MAC to notify the application of /// the status of its request to purge an MSDU from the transaction queue @@ -416,17 +236,8 @@ pub struct PurgeConfirm { pub msdu_handle: u8, /// The status of the request pub status: MacStatus, + /// byte stuffing to keep 32 bit alignment + a_stuffing: [u8; 2], } -impl ParseableMacEvent for PurgeConfirm { - const SIZE: usize = 4; - - fn try_parse(buf: &[u8]) -> Result { - Self::validate(buf)?; - - Ok(Self { - msdu_handle: buf[0], - status: MacStatus::try_from(buf[1])?, - }) - } -} +impl ParseableMacEvent for PurgeConfirm {} diff --git a/embassy-stm32-wpan/src/sub/mac.rs b/embassy-stm32-wpan/src/sub/mac.rs index d30ed2f11..d9bf4c909 100644 --- a/embassy-stm32-wpan/src/sub/mac.rs +++ b/embassy-stm32-wpan/src/sub/mac.rs @@ -12,7 +12,7 @@ use crate::cmd::CmdPacket; use crate::consts::TlPacketType; use crate::evt::{EvtBox, EvtPacket}; use crate::mac::commands::MacCommand; -use crate::mac::event::MacEvent; +use crate::mac::event::Event; use crate::mac::typedefs::MacError; use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; use crate::{channels, evt}; @@ -94,11 +94,8 @@ impl Mac { } } - pub async fn read(&self) -> Result { - let evt_box = self.tl_read().await; - let payload = evt_box.payload(); - - MacEvent::try_from(payload) + pub async fn read(&self) -> Event { + Event::new(self.tl_read().await) } } diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs index f8c8ba288..86413ea0f 100644 --- a/examples/stm32wb/src/bin/mac_ffd.rs +++ b/examples/stm32wb/src/bin/mac_ffd.rs @@ -73,8 +73,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } info!("setting extended address"); let extended_address: u64 = 0xACDE480000000001; @@ -85,8 +87,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } info!("setting short address"); let short_address: u16 = 0x1122; @@ -97,8 +101,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } info!("setting association permit"); let association_permit: bool = true; @@ -109,8 +115,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } info!("setting TX power"); let transmit_power: i8 = 2; @@ -121,8 +129,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } info!("starting FFD device"); mbox.mac_subsystem @@ -137,8 +147,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } info!("setting RX on when idle"); let rx_on_while_idle: bool = true; @@ -149,14 +161,16 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } loop { let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt); + defmt::info!("{:#x}", evt.mac_event()); - if let Ok(evt) = evt { + if let Ok(evt) = evt.mac_event() { match evt { MacEvent::MlmeAssociateInd(association) => mbox .mac_subsystem diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs index b0eb91061..7cb401d89 100644 --- a/examples/stm32wb/src/bin/mac_rfd.rs +++ b/examples/stm32wb/src/bin/mac_rfd.rs @@ -75,8 +75,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } info!("setting extended address"); let extended_address: u64 = 0xACDE480000000002; @@ -87,8 +89,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + defmt::info!("{:#x}", evt.mac_event()); + } info!("getting extended address"); mbox.mac_subsystem @@ -98,14 +102,17 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); - if let Ok(MacEvent::MlmeGetCnf(evt)) = evt { - if evt.pib_attribute_value_len == 8 { - let value = unsafe { core::ptr::read_unaligned(evt.pib_attribute_value_ptr as *const u64) }; + { + let evt = mbox.mac_subsystem.read().await; + info!("{:#x}", evt.mac_event()); - info!("value {:#x}", value) + if let Ok(MacEvent::MlmeGetCnf(evt)) = evt.mac_event() { + if evt.pib_attribute_value_len == 8 { + let value = unsafe { core::ptr::read_unaligned(evt.pib_attribute_value_ptr as *const u64) }; + + info!("value {:#x}", value) + } } } @@ -124,13 +131,15 @@ async fn main(spawner: Spawner) { }; info!("{}", a); mbox.mac_subsystem.send_command(&a).await.unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + let short_addr = { + let evt = mbox.mac_subsystem.read().await; + info!("{:#x}", evt.mac_event()); - let short_addr = if let Ok(MacEvent::MlmeAssociateCnf(conf)) = evt { - conf.assoc_short_address - } else { - defmt::panic!() + if let Ok(MacEvent::MlmeAssociateCnf(conf)) = evt.mac_event() { + conf.assoc_short_address + } else { + defmt::panic!() + } }; info!("setting short address"); @@ -141,8 +150,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + info!("{:#x}", evt.mac_event()); + } info!("sending data"); let data = b"Hello from embassy!"; @@ -163,11 +174,13 @@ async fn main(spawner: Spawner) { ) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + info!("{:#x}", evt.mac_event()); + } loop { let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + info!("{:#x}", evt.mac_event()); } } diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs index 2fc15dc9d..d64a5ef81 100644 --- a/tests/stm32/src/bin/wpan_mac.rs +++ b/tests/stm32/src/bin/wpan_mac.rs @@ -55,8 +55,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + info!("{:#x}", evt.mac_event()); + } info!("setting extended address"); let extended_address: u64 = 0xACDE480000000002; @@ -67,8 +69,10 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + info!("{:#x}", evt.mac_event()); + } info!("getting extended address"); mbox.mac_subsystem @@ -78,14 +82,16 @@ async fn main(spawner: Spawner) { }) .await .unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + info!("{:#x}", evt.mac_event()); - if let Ok(MacEvent::MlmeGetCnf(evt)) = evt { - if evt.pib_attribute_value_len == 8 { - let value = unsafe { core::ptr::read_unaligned(evt.pib_attribute_value_ptr as *const u64) }; + if let Ok(MacEvent::MlmeGetCnf(evt)) = evt.mac_event() { + if evt.pib_attribute_value_len == 8 { + let value = unsafe { core::ptr::read_unaligned(evt.pib_attribute_value_ptr as *const u64) }; - info!("value {:#x}", value) + info!("value {:#x}", value) + } } } @@ -104,8 +110,10 @@ async fn main(spawner: Spawner) { }; info!("{}", a); mbox.mac_subsystem.send_command(&a).await.unwrap(); - let evt = mbox.mac_subsystem.read().await; - info!("{:#x}", evt); + { + let evt = mbox.mac_subsystem.read().await; + info!("{:#x}", evt.mac_event()); + } info!("Test OK"); cortex_m::asm::bkpt(); From a0515ca7ac9f4aebeadede7c6a2fa312b60b5d55 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 16:16:56 -0500 Subject: [PATCH 4/7] wpan: add repr(c) to mac responses --- embassy-stm32-wpan/src/mac/indications.rs | 11 ++++++++++- embassy-stm32-wpan/src/mac/responses.rs | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/embassy-stm32-wpan/src/mac/indications.rs b/embassy-stm32-wpan/src/mac/indications.rs index c7e9be84a..66819dc9d 100644 --- a/embassy-stm32-wpan/src/mac/indications.rs +++ b/embassy-stm32-wpan/src/mac/indications.rs @@ -7,6 +7,7 @@ use super::typedefs::{ /// MLME ASSOCIATE Indication which will be used by the MAC /// to indicate the reception of an association request command +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct AssociateIndication { /// Extended address of the device requesting association @@ -27,6 +28,7 @@ impl ParseableMacEvent for AssociateIndication {} /// MLME DISASSOCIATE indication which will be used to send /// disassociation indication to the application. +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DisassociateIndication { /// Extended address of the device requesting association @@ -47,6 +49,7 @@ impl ParseableMacEvent for DisassociateIndication {} /// MLME BEACON NOTIIFY Indication which is used to send parameters contained /// within a beacon frame received by the MAC to the application +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct BeaconNotifyIndication { /// he set of octets comprising the beacon payload to be transferred @@ -67,6 +70,7 @@ pub struct BeaconNotifyIndication { impl ParseableMacEvent for BeaconNotifyIndication {} /// MLME COMM STATUS Indication which is used by the MAC to indicate a communications status +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct CommStatusIndication { /// The 16-bit PAN identifier of the device from which the frame @@ -96,6 +100,7 @@ impl ParseableMacEvent for CommStatusIndication {} /// MLME GTS Indication indicates that a GTS has been allocated or that a /// previously allocated GTS has been deallocated +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct GtsIndication { /// The short address of the device that has been allocated or deallocated a GTS @@ -118,6 +123,7 @@ impl ParseableMacEvent for GtsIndication {} /// MLME ORPHAN Indication which is used by the coordinator to notify the /// application of the presence of an orphaned device +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct OrphanIndication { /// Extended address of the orphaned device @@ -138,6 +144,7 @@ impl ParseableMacEvent for OrphanIndication {} /// MLME SYNC LOSS Indication which is used by the MAC to indicate the loss /// of synchronization with the coordinator +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct SyncLossIndication { /// The PAN identifier with which the device lost synchronization or to which it was realigned @@ -162,6 +169,7 @@ impl ParseableMacEvent for SyncLossIndication {} /// MLME DPS Indication which indicates the expiration of the DPSIndexDuration /// and the resetting of the DPS values in the PHY +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DpsIndication { /// byte stuffing to keep 32 bit alignment @@ -170,8 +178,8 @@ pub struct DpsIndication { impl ParseableMacEvent for DpsIndication {} -#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(C)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DataIndication { /// Pointer to the set of octets forming the MSDU being indicated pub msdu_ptr: *const u8, @@ -227,6 +235,7 @@ impl ParseableMacEvent for DataIndication {} /// MLME POLL Indication which will be used for indicating the Data Request /// reception to upper layer as defined in Zigbee r22 - D.8.2 +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct PollIndication { /// addressing mode used diff --git a/embassy-stm32-wpan/src/mac/responses.rs b/embassy-stm32-wpan/src/mac/responses.rs index e0376a7f5..5d203084c 100644 --- a/embassy-stm32-wpan/src/mac/responses.rs +++ b/embassy-stm32-wpan/src/mac/responses.rs @@ -7,6 +7,7 @@ use super::typedefs::{ /// MLME ASSOCIATE Confirm used to inform of the initiating device whether /// its request to associate was successful or unsuccessful +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct AssociateConfirm { /// short address allocated by the coordinator on successful association @@ -28,6 +29,7 @@ pub struct AssociateConfirm { impl ParseableMacEvent for AssociateConfirm {} /// MLME DISASSOCIATE Confirm used to send disassociation Confirmation to the application. +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DisassociateConfirm { /// status of the disassociation attempt @@ -43,6 +45,7 @@ pub struct DisassociateConfirm { impl ParseableMacEvent for DisassociateConfirm {} /// MLME GET Confirm which requests information about a given PIB attribute +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct GetConfirm { /// The pointer to the value of the PIB attribute attempted to read @@ -61,6 +64,7 @@ impl ParseableMacEvent for GetConfirm {} /// MLME GTS Confirm which eports the results of a request to allocate a new GTS /// or to deallocate an existing GTS +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct GtsConfirm { /// The characteristics of the GTS @@ -74,6 +78,7 @@ pub struct GtsConfirm { impl ParseableMacEvent for GtsConfirm {} /// MLME RESET Confirm which is used to report the results of the reset operation +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ResetConfirm { /// The result of the reset operation @@ -86,6 +91,7 @@ impl ParseableMacEvent for ResetConfirm {} /// MLME RX ENABLE Confirm which is used to report the results of the attempt /// to enable or disable the receiver +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct RxEnableConfirm { /// Result of the request to enable or disable the receiver @@ -97,6 +103,7 @@ pub struct RxEnableConfirm { impl ParseableMacEvent for RxEnableConfirm {} /// MLME SCAN Confirm which is used to report the result of the channel scan request +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct ScanConfirm { /// Status of the scan request @@ -122,6 +129,7 @@ pub struct ScanConfirm { impl ParseableMacEvent for ScanConfirm {} /// MLME SET Confirm which reports the result of an attempt to write a value to a PIB attribute +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct SetConfirm { /// The result of the set operation @@ -136,6 +144,7 @@ impl ParseableMacEvent for SetConfirm {} /// MLME START Confirm which is used to report the results of the attempt to /// start using a new superframe configuration +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct StartConfirm { /// Result of the attempt to start using an updated superframe configuration @@ -147,6 +156,7 @@ pub struct StartConfirm { impl ParseableMacEvent for StartConfirm {} /// MLME POLL Confirm which is used to report the result of a request to poll the coordinator for data +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct PollConfirm { /// The status of the data request @@ -158,6 +168,7 @@ pub struct PollConfirm { impl ParseableMacEvent for PollConfirm {} /// MLME DPS Confirm which reports the results of the attempt to enable or disable the DPS +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DpsConfirm { /// The status of the DPS request @@ -170,6 +181,7 @@ impl ParseableMacEvent for DpsConfirm {} /// MLME SOUNDING Confirm which reports the result of a request to the PHY to provide /// channel sounding information +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct SoundingConfirm { /// Results of the sounding measurement @@ -182,6 +194,7 @@ impl ParseableMacEvent for SoundingConfirm {} /// MLME CALIBRATE Confirm which reports the result of a request to the PHY /// to provide internal propagation path information +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct CalibrateConfirm { /// The status of the attempt to return sounding data @@ -200,6 +213,7 @@ impl ParseableMacEvent for CalibrateConfirm {} /// MCPS DATA Confirm which will be used for reporting the results of /// MAC data related requests from the application +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct DataConfirm { /// The handle associated with the MSDU being confirmed @@ -230,6 +244,7 @@ impl ParseableMacEvent for DataConfirm {} /// MCPS PURGE Confirm which will be used by the MAC to notify the application of /// the status of its request to purge an MSDU from the transaction queue +#[repr(C)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct PurgeConfirm { /// Handle associated with the MSDU requested to be purged from the transaction queue From 34217ea797c6bbea6219bb2bc2b611a99212e14b Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 17:28:34 -0500 Subject: [PATCH 5/7] wpan: add slice data view --- embassy-stm32-wpan/src/mac/event.rs | 73 ++++++++++------------- embassy-stm32-wpan/src/mac/indications.rs | 8 +++ examples/stm32wb/src/bin/mac_ffd.rs | 22 ++++--- 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/embassy-stm32-wpan/src/mac/event.rs b/embassy-stm32-wpan/src/mac/event.rs index 67f207d57..a2bb79222 100644 --- a/embassy-stm32-wpan/src/mac/event.rs +++ b/embassy-stm32-wpan/src/mac/event.rs @@ -36,53 +36,40 @@ impl Event { let opcode = u16::from_le_bytes(payload[0..2].try_into().unwrap()); let opcode = OpcodeM0ToM4::try_from(opcode)?; + let buf = &payload[2..]; match opcode { - OpcodeM0ToM4::MlmeAssociateCnf => Ok(MacEvent::MlmeAssociateCnf(AssociateConfirm::from_buffer( - &payload[2..], - )?)), - OpcodeM0ToM4::MlmeDisassociateCnf => Ok(MacEvent::MlmeDisassociateCnf(DisassociateConfirm::from_buffer( - &payload[2..], - )?)), - OpcodeM0ToM4::MlmeGetCnf => Ok(MacEvent::MlmeGetCnf(GetConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeGtsCnf => Ok(MacEvent::MlmeGtsCnf(GtsConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeResetCnf => Ok(MacEvent::MlmeResetCnf(ResetConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeRxEnableCnf => { - Ok(MacEvent::MlmeRxEnableCnf(RxEnableConfirm::from_buffer(&payload[2..])?)) + OpcodeM0ToM4::MlmeAssociateCnf => Ok(MacEvent::MlmeAssociateCnf(AssociateConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeDisassociateCnf => { + Ok(MacEvent::MlmeDisassociateCnf(DisassociateConfirm::from_buffer(buf)?)) } - OpcodeM0ToM4::MlmeScanCnf => Ok(MacEvent::MlmeScanCnf(ScanConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeSetCnf => Ok(MacEvent::MlmeSetCnf(SetConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeStartCnf => Ok(MacEvent::MlmeStartCnf(StartConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmePollCnf => Ok(MacEvent::MlmePollCnf(PollConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeDpsCnf => Ok(MacEvent::MlmeDpsCnf(DpsConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeSoundingCnf => { - Ok(MacEvent::MlmeSoundingCnf(SoundingConfirm::from_buffer(&payload[2..])?)) + OpcodeM0ToM4::MlmeGetCnf => Ok(MacEvent::MlmeGetCnf(GetConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeGtsCnf => Ok(MacEvent::MlmeGtsCnf(GtsConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeResetCnf => Ok(MacEvent::MlmeResetCnf(ResetConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeRxEnableCnf => Ok(MacEvent::MlmeRxEnableCnf(RxEnableConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeScanCnf => Ok(MacEvent::MlmeScanCnf(ScanConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeSetCnf => Ok(MacEvent::MlmeSetCnf(SetConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeStartCnf => Ok(MacEvent::MlmeStartCnf(StartConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmePollCnf => Ok(MacEvent::MlmePollCnf(PollConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeDpsCnf => Ok(MacEvent::MlmeDpsCnf(DpsConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeSoundingCnf => Ok(MacEvent::MlmeSoundingCnf(SoundingConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeCalibrateCnf => Ok(MacEvent::MlmeCalibrateCnf(CalibrateConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::McpsDataCnf => Ok(MacEvent::McpsDataCnf(DataConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::McpsPurgeCnf => Ok(MacEvent::McpsPurgeCnf(PurgeConfirm::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeAssociateInd => Ok(MacEvent::MlmeAssociateInd(AssociateIndication::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeDisassociateInd => { + Ok(MacEvent::MlmeDisassociateInd(DisassociateIndication::from_buffer(buf)?)) } - OpcodeM0ToM4::MlmeCalibrateCnf => Ok(MacEvent::MlmeCalibrateCnf(CalibrateConfirm::from_buffer( - &payload[2..], - )?)), - OpcodeM0ToM4::McpsDataCnf => Ok(MacEvent::McpsDataCnf(DataConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::McpsPurgeCnf => Ok(MacEvent::McpsPurgeCnf(PurgeConfirm::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeAssociateInd => Ok(MacEvent::MlmeAssociateInd(AssociateIndication::from_buffer( - &payload[2..], - )?)), - OpcodeM0ToM4::MlmeDisassociateInd => Ok(MacEvent::MlmeDisassociateInd( - DisassociateIndication::from_buffer(&payload[2..])?, - )), - OpcodeM0ToM4::MlmeBeaconNotifyInd => Ok(MacEvent::MlmeBeaconNotifyInd( - BeaconNotifyIndication::from_buffer(&payload[2..])?, - )), - OpcodeM0ToM4::MlmeCommStatusInd => Ok(MacEvent::MlmeCommStatusInd(CommStatusIndication::from_buffer( - &payload[2..], - )?)), - OpcodeM0ToM4::MlmeGtsInd => Ok(MacEvent::MlmeGtsInd(GtsIndication::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeOrphanInd => Ok(MacEvent::MlmeOrphanInd(OrphanIndication::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmeSyncLossInd => Ok(MacEvent::MlmeSyncLossInd(SyncLossIndication::from_buffer( - &payload[2..], - )?)), - OpcodeM0ToM4::MlmeDpsInd => Ok(MacEvent::MlmeDpsInd(DpsIndication::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::McpsDataInd => Ok(MacEvent::McpsDataInd(DataIndication::from_buffer(&payload[2..])?)), - OpcodeM0ToM4::MlmePollInd => Ok(MacEvent::MlmePollInd(PollIndication::from_buffer(&payload[2..])?)), + OpcodeM0ToM4::MlmeBeaconNotifyInd => { + Ok(MacEvent::MlmeBeaconNotifyInd(BeaconNotifyIndication::from_buffer(buf)?)) + } + OpcodeM0ToM4::MlmeCommStatusInd => Ok(MacEvent::MlmeCommStatusInd(CommStatusIndication::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeGtsInd => Ok(MacEvent::MlmeGtsInd(GtsIndication::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeOrphanInd => Ok(MacEvent::MlmeOrphanInd(OrphanIndication::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeSyncLossInd => Ok(MacEvent::MlmeSyncLossInd(SyncLossIndication::from_buffer(buf)?)), + OpcodeM0ToM4::MlmeDpsInd => Ok(MacEvent::MlmeDpsInd(DpsIndication::from_buffer(buf)?)), + OpcodeM0ToM4::McpsDataInd => Ok(MacEvent::McpsDataInd(DataIndication::from_buffer(buf)?)), + OpcodeM0ToM4::MlmePollInd => Ok(MacEvent::MlmePollInd(PollIndication::from_buffer(buf)?)), } } } diff --git a/embassy-stm32-wpan/src/mac/indications.rs b/embassy-stm32-wpan/src/mac/indications.rs index 66819dc9d..cf795dfa0 100644 --- a/embassy-stm32-wpan/src/mac/indications.rs +++ b/embassy-stm32-wpan/src/mac/indications.rs @@ -1,3 +1,5 @@ +use core::slice; + use super::consts::MAX_PENDING_ADDRESS; use super::event::ParseableMacEvent; use super::typedefs::{ @@ -233,6 +235,12 @@ pub struct DataIndication { impl ParseableMacEvent for DataIndication {} +impl DataIndication { + pub fn payload<'a>(&'a self) -> &'a [u8] { + unsafe { slice::from_raw_parts(self.msdu_ptr as *const _ as *const u8, self.msdu_length as usize) } + } +} + /// MLME POLL Indication which will be used for indicating the Data Request /// reception to upper layer as defined in Zigbee r22 - D.8.2 #[repr(C)] diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs index 86413ea0f..bc71e29aa 100644 --- a/examples/stm32wb/src/bin/mac_ffd.rs +++ b/examples/stm32wb/src/bin/mac_ffd.rs @@ -168,9 +168,10 @@ async fn main(spawner: Spawner) { loop { let evt = mbox.mac_subsystem.read().await; - defmt::info!("{:#x}", evt.mac_event()); - if let Ok(evt) = evt.mac_event() { + defmt::info!("parsed mac event"); + defmt::info!("{:#x}", evt); + match evt { MacEvent::MlmeAssociateInd(association) => mbox .mac_subsystem @@ -184,17 +185,22 @@ async fn main(spawner: Spawner) { .await .unwrap(), MacEvent::McpsDataInd(data_ind) => { - let data_addr = data_ind.msdu_ptr; - let mut data = [0u8; 256]; - unsafe { data_addr.copy_to(&mut data as *mut _, data_ind.msdu_length as usize) } - info!("{}", data[..data_ind.msdu_length as usize]); + let payload = data_ind.payload(); + let ref_payload = b"Hello from embassy!"; + info!("{}", payload); - if &data[..data_ind.msdu_length as usize] == b"Hello from embassy!" { + if payload == ref_payload { info!("success"); + } else { + info!("ref payload: {}", ref_payload); } } - _ => {} + _ => { + defmt::info!("other mac event"); + } } + } else { + defmt::info!("failed to parse mac event"); } } } From fe1e7c4d7660163457226316ffbf30f6f3c8ddc5 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 18:07:05 -0500 Subject: [PATCH 6/7] wpan: fix datarequest --- embassy-stm32-wpan/src/mac/commands.rs | 2 +- embassy-stm32-wpan/src/mac/indications.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32-wpan/src/mac/commands.rs b/embassy-stm32-wpan/src/mac/commands.rs index 8acae24bb..8f6dcbbbc 100644 --- a/embassy-stm32-wpan/src/mac/commands.rs +++ b/embassy-stm32-wpan/src/mac/commands.rs @@ -370,7 +370,7 @@ pub struct DataRequest { impl DataRequest { pub fn set_buffer<'a>(&'a mut self, buf: &'a [u8]) -> &mut Self { - self.msdu_ptr = &buf as *const _ as *const u8; + self.msdu_ptr = buf as *const _ as *const u8; self.msdu_length = buf.len() as u8; self diff --git a/embassy-stm32-wpan/src/mac/indications.rs b/embassy-stm32-wpan/src/mac/indications.rs index cf795dfa0..98826e662 100644 --- a/embassy-stm32-wpan/src/mac/indications.rs +++ b/embassy-stm32-wpan/src/mac/indications.rs @@ -237,7 +237,7 @@ impl ParseableMacEvent for DataIndication {} impl DataIndication { pub fn payload<'a>(&'a self) -> &'a [u8] { - unsafe { slice::from_raw_parts(self.msdu_ptr as *const _ as *const u8, self.msdu_length as usize) } + unsafe { slice::from_raw_parts(self.msdu_ptr, self.msdu_length as usize) } } } From 7b34f5e866958f2ff28d7deb6888666690fe2837 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 18:54:11 -0500 Subject: [PATCH 7/7] wpan: make dataind fields private --- embassy-stm32-wpan/src/mac/indications.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32-wpan/src/mac/indications.rs b/embassy-stm32-wpan/src/mac/indications.rs index 98826e662..5445fb4af 100644 --- a/embassy-stm32-wpan/src/mac/indications.rs +++ b/embassy-stm32-wpan/src/mac/indications.rs @@ -206,9 +206,9 @@ pub struct DataIndication { /// The time, in symbols, at which the data were received pub time_stamp: [u8; 4], /// The security level purportedly used by the received data frame - pub security_level: SecurityLevel, + security_level: SecurityLevel, /// Mode used to identify the key used by originator of received frame - pub key_id_mode: KeyIdMode, + key_id_mode: KeyIdMode, /// The originator of the key pub key_source: [u8; 8], /// The index of the key