mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-10-30 05:40:55 +00:00
wpan/mac: use slice view to avoid copy
This commit is contained in:
parent
c7ec45a004
commit
e95a7dc555
@ -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::<Self>()) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user