From e95a7dc555f367534d3b8bc7a9b6f2d361b0d951 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 12:41:57 -0500 Subject: [PATCH] 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 8cfa0a05..8acae24b 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 30c7731b..98c67c86 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 4893cb47..d30ed2f1 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 e4d81997..f8c8ba28 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 b2dac72c..b0eb9106 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 cfa0aca3..2fc15dc9 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();