change MacAddress to a union instead of an enum

This commit is contained in:
goueslati 2023-07-12 16:49:37 +01:00
parent d5a4457b5e
commit eccd2ecebf
7 changed files with 168 additions and 96 deletions

View file

@ -9,12 +9,13 @@ pub trait MacCommand {
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, 8) };
unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, Self::SIZE) };
}
}
/// MLME ASSOCIATE Request used to request an association
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct AssociateRequest {
/// the logical channel on which to attempt association
pub channel_number: MacChannel,
@ -45,6 +46,7 @@ impl MacCommand for AssociateRequest {
/// MLME DISASSOCIATE Request sed to request a disassociation
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct DisassociateRequest {
/// device addressing mode used
pub device_addr_mode: AddressMode,
@ -73,6 +75,7 @@ impl MacCommand for DisassociateRequest {
/// MLME GET Request used to request a PIB value
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GetRequest {
/// the name of the PIB attribute to read
pub pib_attribute: PibId,
@ -85,6 +88,7 @@ impl MacCommand for GetRequest {
/// MLME GTS Request used to request and maintain GTSs
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GtsRequest {
/// the characteristics of the GTS
pub characteristics: GtsCharacteristics,
@ -104,6 +108,7 @@ impl MacCommand for GtsRequest {
}
#[repr(C)]
#[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,
@ -117,6 +122,7 @@ impl MacCommand for ResetRequest {
/// MLME RX ENABLE Request used to request that the receiver is either enabled
/// for a finite period of time or disabled
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct RxEnableRequest {
/// the request operation can be deferred or not
pub defer_permit: bool,
@ -148,6 +154,7 @@ impl MacCommand for RxEnableRequest {
/// MLME SCAN Request used to initiate a channel scan over a given list of channels
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ScanRequest {
/// the type of scan to be performed
pub scan_type: ScanType,
@ -174,6 +181,7 @@ impl MacCommand for ScanRequest {
/// MLME SET Request used to attempt to write the given value to the indicated PIB attribute
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct SetRequest {
/// the pointer to the value of the PIB attribute to set
pub pib_attribute_ptr: *const u8,
@ -190,6 +198,7 @@ impl MacCommand for SetRequest {
/// configuration
#[derive(Default)]
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct StartRequest {
/// PAN indentifier to used by the device
pub pan_id: [u8; 2],
@ -233,6 +242,7 @@ impl MacCommand for StartRequest {
/// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if
/// specified, tracking its beacons
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct SyncRequest {
/// the channel number on which to attempt coordinator synchronization
pub channel_number: MacChannel,
@ -252,6 +262,7 @@ impl MacCommand for SyncRequest {
/// MLME POLL Request propmts the device to request data from the coordinator
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PollRequest {
/// addressing mode of the coordinator
pub coord_addr_mode: AddressMode,
@ -277,6 +288,7 @@ impl MacCommand for PollRequest {
/// MLME DPS Request allows the next higher layer to request that the PHY utilize a
/// given pair of preamble codes for a single use pending expiration of the DPSIndexDuration
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct DpsRequest {
/// the index value for the transmitter
tx_dps_index: u8,
@ -295,6 +307,7 @@ impl MacCommand for DpsRequest {
/// 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;
impl MacCommand for SoundingRequest {
@ -305,6 +318,7 @@ impl MacCommand for SoundingRequest {
/// 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;
impl MacCommand for CalibrateRequest {
@ -314,6 +328,7 @@ impl MacCommand for CalibrateRequest {
/// MCPS DATA Request used for MAC data related requests from the application
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct DataRequest {
/// the handle assocated with the MSDU to be transmitted
pub msdu_ptr: *const u8,
@ -362,6 +377,7 @@ impl MacCommand for DataRequest {
/// for MCPS PURGE Request used to purge an MSDU from the transaction queue
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PurgeRequest {
/// the handle associated with the MSDU to be purged from the transaction
/// queue
@ -375,6 +391,7 @@ impl MacCommand for PurgeRequest {
/// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct AssociateResponse {
/// extended address of the device requesting association
pub device_address: [u8; 8],
@ -400,6 +417,7 @@ impl MacCommand for AssociateResponse {
/// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication
#[repr(C)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct OrphanResponse {
/// extended address of the orphaned device
pub orphan_address: [u8; 8],

View file

@ -141,21 +141,25 @@ impl ParseableMacEvent for CommStatusIndication {
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]])
}
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]])
}
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 {
@ -358,22 +362,26 @@ impl ParseableMacEvent for DataIndication {
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]])
}
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]])
}
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 {
@ -424,12 +432,14 @@ impl ParseableMacEvent for PollIndication {
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]])
}
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 {

View file

@ -91,13 +91,15 @@ impl Mac {
.await;
}
pub async fn send_command<T>(&self, cmd: T) -> Result<(), MacError>
pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError>
where
T: MacCommand,
{
let mut payload = [0u8; MAX_PACKET_SIZE];
cmd.copy_into_slice(&mut payload);
debug!("sending {}", &payload[..T::SIZE]);
let response = self
.tl_write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE])
.await;

View file

@ -27,6 +27,8 @@ impl ParseableMacEvent for AssociateConfirm {
const SIZE: usize = 16;
fn try_parse(buf: &[u8]) -> Result<Self, ()> {
debug!("{}", buf);
Self::validate(buf)?;
Ok(Self {
@ -61,12 +63,14 @@ impl ParseableMacEvent for DisassociateConfirm {
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]])
}
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 {
@ -238,7 +242,6 @@ impl ParseableMacEvent for StartConfirm {
fn try_parse(buf: &[u8]) -> Result<Self, ()> {
Self::validate(buf)?;
debug!("{:#x}", buf);
Ok(Self {
status: MacStatus::try_from(buf[0])?,

View file

@ -109,18 +109,32 @@ numeric_enum! {
}
#[derive(Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum MacAddress {
Short([u8; 2]),
Extended([u8; 8]),
pub union MacAddress {
pub short: [u8; 2],
pub extended: [u8; 8],
}
#[cfg(feature = "defmt")]
impl defmt::Format for MacAddress {
fn format(&self, fmt: defmt::Formatter) {
unsafe {
defmt::write!(
fmt,
"MacAddress {{ short: {}, extended: {} }}",
self.short,
self.extended
)
}
}
}
impl Default for MacAddress {
fn default() -> Self {
Self::Short([0, 0])
Self { short: [0, 0] }
}
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GtsCharacteristics {
pub fields: u8,
}
@ -163,12 +177,14 @@ impl TryFrom<&[u8]> for PanDescriptor {
let coord_addr_mode = AddressMode::try_from(buf[2])?;
let coord_addr = match coord_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]])
}
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 {
@ -255,7 +271,7 @@ defmt::bitflags! {
numeric_enum! {
#[repr(u8)]
#[derive(Default)]
#[derive(Default, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum KeyIdMode {
#[default]
@ -285,6 +301,7 @@ numeric_enum! {
numeric_enum! {
#[repr(u8)]
#[derive(Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum DisassociationReason {
/// The coordinator wishes the device to leave the PAN.
@ -296,7 +313,7 @@ numeric_enum! {
numeric_enum! {
#[repr(u8)]
#[derive(Default)]
#[derive(Default, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum SecurityLevel {
/// MAC Unsecured Mode Security

View file

@ -66,7 +66,7 @@ async fn main(spawner: Spawner) {
info!("resetting");
mbox.mac_subsystem
.send_command(ResetRequest { set_default_pib: true })
.send_command(&ResetRequest { set_default_pib: true })
.await
.unwrap();
let evt = mbox.mac_subsystem.read().await;
@ -75,7 +75,7 @@ async fn main(spawner: Spawner) {
info!("setting extended address");
let extended_address: u64 = 0xACDE480000000001;
mbox.mac_subsystem
.send_command(SetRequest {
.send_command(&SetRequest {
pib_attribute_ptr: &extended_address as *const _ as *const u8,
pib_attribute: PibId::ExtendedAddress,
})
@ -87,7 +87,7 @@ async fn main(spawner: Spawner) {
info!("setting short address");
let short_address: u16 = 0x1122;
mbox.mac_subsystem
.send_command(SetRequest {
.send_command(&SetRequest {
pib_attribute_ptr: &short_address as *const _ as *const u8,
pib_attribute: PibId::ShortAddress,
})
@ -99,7 +99,7 @@ async fn main(spawner: Spawner) {
info!("setting association permit");
let association_permit: bool = true;
mbox.mac_subsystem
.send_command(SetRequest {
.send_command(&SetRequest {
pib_attribute_ptr: &association_permit as *const _ as *const u8,
pib_attribute: PibId::AssociationPermit,
})
@ -111,7 +111,7 @@ async fn main(spawner: Spawner) {
info!("setting TX power");
let transmit_power: i8 = 2;
mbox.mac_subsystem
.send_command(SetRequest {
.send_command(&SetRequest {
pib_attribute_ptr: &transmit_power as *const _ as *const u8,
pib_attribute: PibId::TransmitPower,
})
@ -122,7 +122,8 @@ async fn main(spawner: Spawner) {
info!("starting FFD device");
mbox.mac_subsystem
.send_command(StartRequest {
.send_command(&StartRequest {
pan_id: [0xAA, 0x1A],
channel_number: MacChannel::Channel16,
beacon_order: 0x0F,
superframe_order: 0x0F,
@ -138,7 +139,7 @@ async fn main(spawner: Spawner) {
info!("setting RX on when idle");
let rx_on_while_idle: bool = true;
mbox.mac_subsystem
.send_command(SetRequest {
.send_command(&SetRequest {
pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8,
pib_attribute: PibId::RxOnWhenIdle,
})
@ -151,7 +152,4 @@ async fn main(spawner: Spawner) {
let evt = mbox.mac_subsystem.read().await;
defmt::info!("{:#x}", evt);
}
info!("Test OK");
cortex_m::asm::bkpt();
}

View file

@ -6,7 +6,8 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::bind_interrupts;
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
use embassy_stm32_wpan::sub::mac::commands::{AssociateRequest, ResetRequest, SetRequest, StartRequest};
use embassy_stm32_wpan::sub::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest};
use embassy_stm32_wpan::sub::mac::event::MacEvent;
use embassy_stm32_wpan::sub::mac::typedefs::{
AddressMode, Capabilities, KeyIdMode, MacAddress, MacChannel, PibId, SecurityLevel,
};
@ -67,52 +68,75 @@ async fn main(spawner: Spawner) {
info!("initialized mac: {}", result);
info!("resetting");
let response = mbox
.mac_subsystem
.send_command(ResetRequest { set_default_pib: true })
.await;
info!("{}", response);
mbox.mac_subsystem
.send_command(&ResetRequest { set_default_pib: true })
.await
.unwrap();
let evt = mbox.mac_subsystem.read().await;
info!("{:#x}", evt);
info!("setting extended address");
let extended_address: u64 = 0xACDE480000000002;
let response = mbox
.mac_subsystem
.send_command(SetRequest {
mbox.mac_subsystem
.send_command(&SetRequest {
pib_attribute_ptr: &extended_address as *const _ as *const u8,
pib_attribute: PibId::ExtendedAddress,
})
.await;
info!("{}", response);
.await
.unwrap();
let evt = mbox.mac_subsystem.read().await;
info!("{:#x}", evt);
info!("getting extended address");
mbox.mac_subsystem
.send_command(&GetRequest {
pib_attribute: PibId::ExtendedAddress,
})
.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) };
info!("value {:#x}", value)
}
}
info!("assocation request");
let response = mbox
.mac_subsystem
.send_command(AssociateRequest {
channel_number: MacChannel::Channel16,
channel_page: 0,
coord_addr_mode: AddressMode::Short,
coord_address: MacAddress::Short([0x22, 0x11]),
capability_information: Capabilities::ALLOCATE_ADDRESS,
coord_pan_id: [0xAA, 0x1A],
security_level: SecurityLevel::Unsecure,
key_id_mode: KeyIdMode::Implicite,
key_source: [0; 8],
key_index: 0,
})
.await;
info!("{}", response);
let a = AssociateRequest {
channel_number: MacChannel::Channel16,
channel_page: 0,
coord_addr_mode: AddressMode::Short,
coord_address: MacAddress { short: [34, 17] },
capability_information: Capabilities::ALLOCATE_ADDRESS,
coord_pan_id: [0xAA, 0x1A],
security_level: SecurityLevel::Unsecure,
key_id_mode: KeyIdMode::Implicite,
key_source: [0; 8],
key_index: 152,
};
info!("{}", a);
mbox.mac_subsystem.send_command(&a).await.unwrap();
let evt = mbox.mac_subsystem.read().await;
info!("{:#x}", evt);
info!("setting short address");
let short: u64 = 0xACDE480000000002;
let response = mbox
.mac_subsystem
.send_command(SetRequest {
mbox.mac_subsystem
.send_command(&SetRequest {
pib_attribute_ptr: &short as *const _ as *const u8,
pib_attribute: PibId::ShortAddress,
})
.await;
info!("{}", response);
.await
.unwrap();
let evt = mbox.mac_subsystem.read().await;
info!("{:#x}", evt);
info!("Test OK");
cortex_m::asm::bkpt();
loop {
let evt = mbox.mac_subsystem.read().await;
info!("{:#x}", evt);
}
}