wpan/mac: use slice view to avoid copy

This commit is contained in:
xoviat 2023-07-16 12:41:57 -05:00
parent c7ec45a004
commit e95a7dc555
6 changed files with 77 additions and 63 deletions

View File

@ -1,15 +1,16 @@
use core::{mem, slice};
use super::opcodes::OpcodeM4ToM0; use super::opcodes::OpcodeM4ToM0;
use super::typedefs::{ use super::typedefs::{
AddressMode, Capabilities, DisassociationReason, GtsCharacteristics, KeyIdMode, MacAddress, MacChannel, MacStatus, AddressMode, Capabilities, DisassociationReason, GtsCharacteristics, KeyIdMode, MacAddress, MacChannel, MacStatus,
PanId, PibId, ScanType, SecurityLevel, PanId, PibId, ScanType, SecurityLevel,
}; };
pub trait MacCommand { pub trait MacCommand: Sized {
const OPCODE: OpcodeM4ToM0; const OPCODE: OpcodeM4ToM0;
const SIZE: usize;
fn copy_into_slice(&self, buf: &mut [u8]) { fn payload<'a>(&'a self) -> &'a [u8] {
unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, Self::SIZE) }; unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of::<Self>()) }
} }
} }
@ -41,7 +42,6 @@ pub struct AssociateRequest {
impl MacCommand for AssociateRequest { impl MacCommand for AssociateRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq;
const SIZE: usize = 25;
} }
/// MLME DISASSOCIATE Request sed to request a disassociation /// MLME DISASSOCIATE Request sed to request a disassociation
@ -70,20 +70,22 @@ pub struct DisassociateRequest {
impl MacCommand for DisassociateRequest { impl MacCommand for DisassociateRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq;
const SIZE: usize = 24;
} }
/// MLME GET Request used to request a PIB value /// MLME GET Request used to request a PIB value
#[repr(C)] #[repr(C)]
#[derive(Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GetRequest { pub struct GetRequest {
/// the name of the PIB attribute to read /// the name of the PIB attribute to read
pub pib_attribute: PibId, pub pib_attribute: PibId,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 3],
} }
impl MacCommand for GetRequest { impl MacCommand for GetRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq;
const SIZE: usize = 4;
} }
/// MLME GTS Request used to request and maintain GTSs /// MLME GTS Request used to request and maintain GTSs
@ -104,19 +106,20 @@ pub struct GtsRequest {
impl MacCommand for GtsRequest { impl MacCommand for GtsRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq;
const SIZE: usize = 12;
} }
#[repr(C)] #[repr(C)]
#[derive(Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ResetRequest { pub struct ResetRequest {
/// MAC PIB attributes are set to their default values or not during reset /// MAC PIB attributes are set to their default values or not during reset
pub set_default_pib: bool, pub set_default_pib: bool,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 3],
} }
impl MacCommand for ResetRequest { impl MacCommand for ResetRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq;
const SIZE: usize = 4;
} }
/// MLME RX ENABLE Request used to request that the receiver is either enabled /// 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 /// configure the transceiver to RX with ranging for a value of
/// RANGING_ON or to not enable ranging for RANGING_OFF /// RANGING_ON or to not enable ranging for RANGING_OFF
pub ranging_rx_control: u8, 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 /// number of symbols measured before the receiver is to be enabled or disabled
pub rx_on_time: [u8; 4], pub rx_on_time: [u8; 4],
/// number of symbols for which the receiver is to be enabled /// number of symbols for which the receiver is to be enabled
@ -137,19 +142,6 @@ pub struct RxEnableRequest {
impl MacCommand for RxEnableRequest { impl MacCommand for RxEnableRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeRxEnableReq; 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 /// 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, pub key_id_mode: KeyIdMode,
/// index of the key to be used /// index of the key to be used
pub key_index: u8, pub key_index: u8,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 2],
} }
impl MacCommand for ScanRequest { impl MacCommand for ScanRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeScanReq; 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 /// 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 { impl MacCommand for SetRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; 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 /// MLME START Request used by the FFDs to intiate a new PAN or to begin using a new superframe
/// configuration /// configuration
#[derive(Default)]
#[repr(C)] #[repr(C)]
#[derive(Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct StartRequest { pub struct StartRequest {
/// PAN indentifier to used by the device /// PAN indentifier to used by the device
@ -236,7 +228,6 @@ pub struct StartRequest {
impl MacCommand for StartRequest { impl MacCommand for StartRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq;
const SIZE: usize = 35;
} }
/// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if /// 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 /// `false` if the MLME is to synchronize with only the next beacon
pub track_beacon: bool, pub track_beacon: bool,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 1],
} }
impl MacCommand for SyncRequest { impl MacCommand for SyncRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq;
const SIZE: usize = 4;
} }
/// MLME POLL Request propmts the device to request data from the coordinator /// MLME POLL Request propmts the device to request data from the coordinator
@ -278,11 +270,12 @@ pub struct PollRequest {
pub key_source: [u8; 8], pub key_source: [u8; 8],
/// PAN identifier of the coordinator /// PAN identifier of the coordinator
pub coord_pan_id: PanId, pub coord_pan_id: PanId,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 2],
} }
impl MacCommand for PollRequest { impl MacCommand for PollRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq;
const SIZE: usize = 24;
} }
/// MLME DPS Request allows the next higher layer to request that the PHY utilize a /// 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 /// the number of symbols for which the transmitter and receiver will utilize the
/// respective DPS indices /// respective DPS indices
dps_index_duration: u8, dps_index_duration: u8,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 1],
} }
impl MacCommand for DpsRequest { impl MacCommand for DpsRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq;
const SIZE: usize = 4;
} }
/// MLME SOUNDING request primitive which is used by the next higher layer to request that /// MLME SOUNDING request primitive which is used by the next higher layer to request that
/// the PHY respond with channel sounding information /// the PHY respond with channel sounding information
#[repr(C)] #[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[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 { impl MacCommand for SoundingRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq;
const SIZE: usize = 4;
} }
/// MLME CALIBRATE request primitive which used to obtain the results of a ranging /// MLME CALIBRATE request primitive which used to obtain the results of a ranging
/// calibration request from an RDEV /// calibration request from an RDEV
#[repr(C)] #[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[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 { impl MacCommand for CalibrateRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq;
const SIZE: usize = 4;
} }
/// MCPS DATA Request used for MAC data related requests from the application /// MCPS DATA Request used for MAC data related requests from the application
@ -370,6 +368,15 @@ pub struct DataRequest {
pub datrate: u8, 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 { impl Default for DataRequest {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -397,7 +404,6 @@ impl Default for DataRequest {
impl MacCommand for DataRequest { impl MacCommand for DataRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq;
const SIZE: usize = 40;
} }
/// for MCPS PURGE Request used to purge an MSDU from the transaction queue /// 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 /// the handle associated with the MSDU to be purged from the transaction
/// queue /// queue
pub msdu_handle: u8, pub msdu_handle: u8,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 3],
} }
impl MacCommand for PurgeRequest { impl MacCommand for PurgeRequest {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq;
const SIZE: usize = 4;
} }
/// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication /// 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, pub key_id_mode: KeyIdMode,
/// the index of the key to be used /// the index of the key to be used
pub key_index: u8, pub key_index: u8,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 2],
} }
impl MacCommand for AssociateResponse { impl MacCommand for AssociateResponse {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes;
const SIZE: usize = 24;
} }
/// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication /// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication
@ -459,9 +467,10 @@ pub struct OrphanResponse {
pub key_id_mode: KeyIdMode, pub key_id_mode: KeyIdMode,
/// the index of the key to be used /// the index of the key to be used
pub key_index: u8, pub key_index: u8,
/// byte stuffing to keep 32 bit alignment
pub a_stuffing: [u8; 2],
} }
impl MacCommand for OrphanResponse { impl MacCommand for OrphanResponse {
const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes; const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes;
const SIZE: usize = 24;
} }

View File

@ -37,9 +37,11 @@ numeric_enum! {
numeric_enum! { numeric_enum! {
#[repr(u8)] #[repr(u8)]
/// this enum contains all the MAC PIB Ids /// this enum contains all the MAC PIB Ids
#[derive(Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum PibId { pub enum PibId {
// PHY // PHY
#[default]
CurrentChannel = 0x00, CurrentChannel = 0x00,
ChannelsSupported = 0x01, ChannelsSupported = 0x01,
TransmitPower = 0x02, TransmitPower = 0x02,

View File

@ -85,12 +85,7 @@ impl Mac {
where where
T: MacCommand, T: MacCommand,
{ {
let mut payload = [0u8; MAX_PACKET_SIZE]; let response = self.tl_write_and_get_response(T::OPCODE as u16, cmd.payload()).await;
cmd.copy_into_slice(&mut payload);
let response = self
.tl_write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE])
.await;
if response == 0x00 { if response == 0x00 {
Ok(()) Ok(())
@ -107,8 +102,6 @@ impl Mac {
} }
} }
const MAX_PACKET_SIZE: usize = 255;
impl evt::MemoryManager for Mac { impl evt::MemoryManager for Mac {
/// SAFETY: passing a pointer to something other than a managed event packet is UB /// SAFETY: passing a pointer to something other than a managed event packet is UB
unsafe fn drop_event_packet(_: *mut EvtPacket) { unsafe fn drop_event_packet(_: *mut EvtPacket) {

View File

@ -67,7 +67,10 @@ async fn main(spawner: Spawner) {
info!("resetting"); info!("resetting");
mbox.mac_subsystem mbox.mac_subsystem
.send_command(&ResetRequest { set_default_pib: true }) .send_command(&ResetRequest {
set_default_pib: true,
..Default::default()
})
.await .await
.unwrap(); .unwrap();
let evt = mbox.mac_subsystem.read().await; let evt = mbox.mac_subsystem.read().await;

View File

@ -69,7 +69,10 @@ async fn main(spawner: Spawner) {
info!("resetting"); info!("resetting");
mbox.mac_subsystem mbox.mac_subsystem
.send_command(&ResetRequest { set_default_pib: true }) .send_command(&ResetRequest {
set_default_pib: true,
..Default::default()
})
.await .await
.unwrap(); .unwrap();
let evt = mbox.mac_subsystem.read().await; let evt = mbox.mac_subsystem.read().await;
@ -91,6 +94,7 @@ async fn main(spawner: Spawner) {
mbox.mac_subsystem mbox.mac_subsystem
.send_command(&GetRequest { .send_command(&GetRequest {
pib_attribute: PibId::ExtendedAddress, pib_attribute: PibId::ExtendedAddress,
..Default::default()
}) })
.await .await
.unwrap(); .unwrap();
@ -141,23 +145,22 @@ async fn main(spawner: Spawner) {
info!("{:#x}", evt); info!("{:#x}", evt);
info!("sending data"); info!("sending data");
let mut data_buffer = [0u8; 256];
let data = b"Hello from embassy!"; let data = b"Hello from embassy!";
data_buffer[..data.len()].copy_from_slice(data);
mbox.mac_subsystem mbox.mac_subsystem
.send_command(&DataRequest { .send_command(
src_addr_mode: AddressMode::Short, DataRequest {
dst_addr_mode: AddressMode::Short, src_addr_mode: AddressMode::Short,
dst_pan_id: PanId([0x1A, 0xAA]), dst_addr_mode: AddressMode::Short,
dst_address: MacAddress::BROADCAST, dst_pan_id: PanId([0x1A, 0xAA]),
msdu_handle: 0x02, dst_address: MacAddress::BROADCAST,
ack_tx: 0x00, msdu_handle: 0x02,
gts_tx: false, ack_tx: 0x00,
msdu_ptr: &data_buffer as *const _ as *const u8, gts_tx: false,
msdu_length: data.len() as u8, security_level: SecurityLevel::Unsecure,
security_level: SecurityLevel::Unsecure, ..Default::default()
..Default::default() }
}) .set_buffer(data),
)
.await .await
.unwrap(); .unwrap();
let evt = mbox.mac_subsystem.read().await; let evt = mbox.mac_subsystem.read().await;

View File

@ -49,7 +49,10 @@ async fn main(spawner: Spawner) {
info!("resetting"); info!("resetting");
mbox.mac_subsystem mbox.mac_subsystem
.send_command(&ResetRequest { set_default_pib: true }) .send_command(&ResetRequest {
set_default_pib: true,
..Default::default()
})
.await .await
.unwrap(); .unwrap();
let evt = mbox.mac_subsystem.read().await; let evt = mbox.mac_subsystem.read().await;
@ -71,6 +74,7 @@ async fn main(spawner: Spawner) {
mbox.mac_subsystem mbox.mac_subsystem
.send_command(&GetRequest { .send_command(&GetRequest {
pib_attribute: PibId::ExtendedAddress, pib_attribute: PibId::ExtendedAddress,
..Default::default()
}) })
.await .await
.unwrap(); .unwrap();