From 28b419d65ede6ff29c79dbcaa27145f1c3458a57 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 16 Jul 2023 15:09:30 -0500 Subject: [PATCH] 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 c2bdc7e1..67f207d5 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 436b9ac9..c7e9be84 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 d29257f8..e0376a7f 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 d30ed2f1..d9bf4c90 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 f8c8ba28..86413ea0 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 b0eb9106..7cb401d8 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 2fc15dc9..d64a5ef8 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();