aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-07-17 16:38:46 -0500
committerxoviat <[email protected]>2023-07-17 16:38:46 -0500
commit1d2c47273db6593a53018b1643dcadb491afc3de (patch)
treeb0191bc1bb70e5401b3263b7622c248480c1a4ad
parent582006c75cdd7e9d819bcacc0f6724c05f161bee (diff)
parent6b5df4523aa1c4902f02e803450ae4b418e0e3ca (diff)
Merge branch 'master' into mac
-rw-r--r--embassy-stm32-wpan/src/mac/commands.rs83
-rw-r--r--embassy-stm32-wpan/src/mac/event.rs155
-rw-r--r--embassy-stm32-wpan/src/mac/helpers.rs7
-rw-r--r--embassy-stm32-wpan/src/mac/indications.rs285
-rw-r--r--embassy-stm32-wpan/src/mac/mod.rs1
-rw-r--r--embassy-stm32-wpan/src/mac/responses.rs287
-rw-r--r--embassy-stm32-wpan/src/mac/typedefs.rs2
-rw-r--r--embassy-stm32-wpan/src/sub/mac.rs18
-rw-r--r--examples/rp/Cargo.toml1
-rw-r--r--examples/rp/src/bin/usb_hid_keyboard.rs188
-rw-r--r--examples/stm32wb/src/bin/mac_ffd.rs69
-rw-r--r--examples/stm32wb/src/bin/mac_rfd.rs90
-rw-r--r--tests/stm32/src/bin/wpan_mac.rs38
13 files changed, 539 insertions, 685 deletions
diff --git a/embassy-stm32-wpan/src/mac/commands.rs b/embassy-stm32-wpan/src/mac/commands.rs
index 8cfa0a054..8f6dcbbbc 100644
--- a/embassy-stm32-wpan/src/mac/commands.rs
+++ b/embassy-stm32-wpan/src/mac/commands.rs
@@ -1,15 +1,16 @@
1use core::{mem, slice};
2
1use super::opcodes::OpcodeM4ToM0; 3use super::opcodes::OpcodeM4ToM0;
2use super::typedefs::{ 4use super::typedefs::{
3 AddressMode, Capabilities, DisassociationReason, GtsCharacteristics, KeyIdMode, MacAddress, MacChannel, MacStatus, 5 AddressMode, Capabilities, DisassociationReason, GtsCharacteristics, KeyIdMode, MacAddress, MacChannel, MacStatus,
4 PanId, PibId, ScanType, SecurityLevel, 6 PanId, PibId, ScanType, SecurityLevel,
5}; 7};
6 8
7pub trait MacCommand { 9pub trait MacCommand: Sized {
8 const OPCODE: OpcodeM4ToM0; 10 const OPCODE: OpcodeM4ToM0;
9 const SIZE: usize;
10 11
11 fn copy_into_slice(&self, buf: &mut [u8]) { 12 fn payload<'a>(&'a self) -> &'a [u8] {
12 unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, Self::SIZE) }; 13 unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of::<Self>()) }
13 } 14 }
14} 15}
15 16
@@ -41,7 +42,6 @@ pub struct AssociateRequest {
41 42
42impl MacCommand for AssociateRequest { 43impl MacCommand for AssociateRequest {
43 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; 44 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq;
44 const SIZE: usize = 25;
45} 45}
46 46
47/// MLME DISASSOCIATE Request sed to request a disassociation 47/// MLME DISASSOCIATE Request sed to request a disassociation
@@ -70,20 +70,22 @@ pub struct DisassociateRequest {
70 70
71impl MacCommand for DisassociateRequest { 71impl MacCommand for DisassociateRequest {
72 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq; 72 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq;
73 const SIZE: usize = 24;
74} 73}
75 74
76/// MLME GET Request used to request a PIB value 75/// MLME GET Request used to request a PIB value
77#[repr(C)] 76#[repr(C)]
77#[derive(Default)]
78#[cfg_attr(feature = "defmt", derive(defmt::Format))] 78#[cfg_attr(feature = "defmt", derive(defmt::Format))]
79pub struct GetRequest { 79pub struct GetRequest {
80 /// the name of the PIB attribute to read 80 /// the name of the PIB attribute to read
81 pub pib_attribute: PibId, 81 pub pib_attribute: PibId,
82
83 /// byte stuffing to keep 32 bit alignment
84 pub a_stuffing: [u8; 3],
82} 85}
83 86
84impl MacCommand for GetRequest { 87impl MacCommand for GetRequest {
85 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; 88 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq;
86 const SIZE: usize = 4;
87} 89}
88 90
89/// MLME GTS Request used to request and maintain GTSs 91/// MLME GTS Request used to request and maintain GTSs
@@ -104,19 +106,20 @@ pub struct GtsRequest {
104 106
105impl MacCommand for GtsRequest { 107impl MacCommand for GtsRequest {
106 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; 108 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq;
107 const SIZE: usize = 12;
108} 109}
109 110
110#[repr(C)] 111#[repr(C)]
112#[derive(Default)]
111#[cfg_attr(feature = "defmt", derive(defmt::Format))] 113#[cfg_attr(feature = "defmt", derive(defmt::Format))]
112pub struct ResetRequest { 114pub struct ResetRequest {
113 /// MAC PIB attributes are set to their default values or not during reset 115 /// MAC PIB attributes are set to their default values or not during reset
114 pub set_default_pib: bool, 116 pub set_default_pib: bool,
117 /// byte stuffing to keep 32 bit alignment
118 pub a_stuffing: [u8; 3],
115} 119}
116 120
117impl MacCommand for ResetRequest { 121impl MacCommand for ResetRequest {
118 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; 122 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq;
119 const SIZE: usize = 4;
120} 123}
121 124
122/// MLME RX ENABLE Request used to request that the receiver is either enabled 125/// MLME RX ENABLE Request used to request that the receiver is either enabled
@@ -129,6 +132,8 @@ pub struct RxEnableRequest {
129 /// configure the transceiver to RX with ranging for a value of 132 /// configure the transceiver to RX with ranging for a value of
130 /// RANGING_ON or to not enable ranging for RANGING_OFF 133 /// RANGING_ON or to not enable ranging for RANGING_OFF
131 pub ranging_rx_control: u8, 134 pub ranging_rx_control: u8,
135 /// byte stuffing to keep 32 bit alignment
136 pub a_stuffing: [u8; 2],
132 /// number of symbols measured before the receiver is to be enabled or disabled 137 /// number of symbols measured before the receiver is to be enabled or disabled
133 pub rx_on_time: [u8; 4], 138 pub rx_on_time: [u8; 4],
134 /// number of symbols for which the receiver is to be enabled 139 /// number of symbols for which the receiver is to be enabled
@@ -137,19 +142,6 @@ pub struct RxEnableRequest {
137 142
138impl MacCommand for RxEnableRequest { 143impl MacCommand for RxEnableRequest {
139 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeRxEnableReq; 144 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeRxEnableReq;
140 const SIZE: usize = 12;
141
142 fn copy_into_slice(&self, buf: &mut [u8]) {
143 buf[0] = self.defer_permit as u8;
144 buf[1] = self.ranging_rx_control as u8;
145
146 // stuffing to keep 32bit alignment
147 buf[2] = 0;
148 buf[3] = 0;
149
150 buf[4..8].copy_from_slice(&self.rx_on_time);
151 buf[8..12].copy_from_slice(&self.rx_on_duration);
152 }
153} 145}
154 146
155/// MLME SCAN Request used to initiate a channel scan over a given list of channels 147/// MLME SCAN Request used to initiate a channel scan over a given list of channels
@@ -172,11 +164,12 @@ pub struct ScanRequest {
172 pub key_id_mode: KeyIdMode, 164 pub key_id_mode: KeyIdMode,
173 /// index of the key to be used 165 /// index of the key to be used
174 pub key_index: u8, 166 pub key_index: u8,
167 /// byte stuffing to keep 32 bit alignment
168 pub a_stuffing: [u8; 2],
175} 169}
176 170
177impl MacCommand for ScanRequest { 171impl MacCommand for ScanRequest {
178 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeScanReq; 172 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeScanReq;
179 const SIZE: usize = 20;
180} 173}
181 174
182/// MLME SET Request used to attempt to write the given value to the indicated PIB attribute 175/// MLME SET Request used to attempt to write the given value to the indicated PIB attribute
@@ -191,13 +184,12 @@ pub struct SetRequest {
191 184
192impl MacCommand for SetRequest { 185impl MacCommand for SetRequest {
193 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; 186 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq;
194 const SIZE: usize = 8;
195} 187}
196 188
197/// MLME START Request used by the FFDs to intiate a new PAN or to begin using a new superframe 189/// MLME START Request used by the FFDs to intiate a new PAN or to begin using a new superframe
198/// configuration 190/// configuration
199#[derive(Default)]
200#[repr(C)] 191#[repr(C)]
192#[derive(Default)]
201#[cfg_attr(feature = "defmt", derive(defmt::Format))] 193#[cfg_attr(feature = "defmt", derive(defmt::Format))]
202pub struct StartRequest { 194pub struct StartRequest {
203 /// PAN indentifier to used by the device 195 /// PAN indentifier to used by the device
@@ -236,7 +228,6 @@ pub struct StartRequest {
236 228
237impl MacCommand for StartRequest { 229impl MacCommand for StartRequest {
238 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq; 230 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq;
239 const SIZE: usize = 35;
240} 231}
241 232
242/// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if 233/// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if
@@ -253,11 +244,12 @@ pub struct SyncRequest {
253 /// 244 ///
254 /// `false` if the MLME is to synchronize with only the next beacon 245 /// `false` if the MLME is to synchronize with only the next beacon
255 pub track_beacon: bool, 246 pub track_beacon: bool,
247 /// byte stuffing to keep 32 bit alignment
248 pub a_stuffing: [u8; 1],
256} 249}
257 250
258impl MacCommand for SyncRequest { 251impl MacCommand for SyncRequest {
259 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq; 252 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq;
260 const SIZE: usize = 4;
261} 253}
262 254
263/// MLME POLL Request propmts the device to request data from the coordinator 255/// MLME POLL Request propmts the device to request data from the coordinator
@@ -278,11 +270,12 @@ pub struct PollRequest {
278 pub key_source: [u8; 8], 270 pub key_source: [u8; 8],
279 /// PAN identifier of the coordinator 271 /// PAN identifier of the coordinator
280 pub coord_pan_id: PanId, 272 pub coord_pan_id: PanId,
273 /// byte stuffing to keep 32 bit alignment
274 pub a_stuffing: [u8; 2],
281} 275}
282 276
283impl MacCommand for PollRequest { 277impl MacCommand for PollRequest {
284 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq; 278 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq;
285 const SIZE: usize = 24;
286} 279}
287 280
288/// MLME DPS Request allows the next higher layer to request that the PHY utilize a 281/// MLME DPS Request allows the next higher layer to request that the PHY utilize a
@@ -297,33 +290,38 @@ pub struct DpsRequest {
297 /// the number of symbols for which the transmitter and receiver will utilize the 290 /// the number of symbols for which the transmitter and receiver will utilize the
298 /// respective DPS indices 291 /// respective DPS indices
299 dps_index_duration: u8, 292 dps_index_duration: u8,
293 /// byte stuffing to keep 32 bit alignment
294 pub a_stuffing: [u8; 1],
300} 295}
301 296
302impl MacCommand for DpsRequest { 297impl MacCommand for DpsRequest {
303 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq; 298 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq;
304 const SIZE: usize = 4;
305} 299}
306 300
307/// MLME SOUNDING request primitive which is used by the next higher layer to request that 301/// MLME SOUNDING request primitive which is used by the next higher layer to request that
308/// the PHY respond with channel sounding information 302/// the PHY respond with channel sounding information
309#[repr(C)] 303#[repr(C)]
310#[cfg_attr(feature = "defmt", derive(defmt::Format))] 304#[cfg_attr(feature = "defmt", derive(defmt::Format))]
311pub struct SoundingRequest; 305pub struct SoundingRequest {
306 /// byte stuffing to keep 32 bit alignment
307 pub a_stuffing: [u8; 4],
308}
312 309
313impl MacCommand for SoundingRequest { 310impl MacCommand for SoundingRequest {
314 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq; 311 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq;
315 const SIZE: usize = 4;
316} 312}
317 313
318/// MLME CALIBRATE request primitive which used to obtain the results of a ranging 314/// MLME CALIBRATE request primitive which used to obtain the results of a ranging
319/// calibration request from an RDEV 315/// calibration request from an RDEV
320#[repr(C)] 316#[repr(C)]
321#[cfg_attr(feature = "defmt", derive(defmt::Format))] 317#[cfg_attr(feature = "defmt", derive(defmt::Format))]
322pub struct CalibrateRequest; 318pub struct CalibrateRequest {
319 /// byte stuffing to keep 32 bit alignment
320 pub a_stuffing: [u8; 4],
321}
323 322
324impl MacCommand for CalibrateRequest { 323impl MacCommand for CalibrateRequest {
325 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq; 324 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq;
326 const SIZE: usize = 4;
327} 325}
328 326
329/// MCPS DATA Request used for MAC data related requests from the application 327/// MCPS DATA Request used for MAC data related requests from the application
@@ -370,6 +368,15 @@ pub struct DataRequest {
370 pub datrate: u8, 368 pub datrate: u8,
371} 369}
372 370
371impl DataRequest {
372 pub fn set_buffer<'a>(&'a mut self, buf: &'a [u8]) -> &mut Self {
373 self.msdu_ptr = buf as *const _ as *const u8;
374 self.msdu_length = buf.len() as u8;
375
376 self
377 }
378}
379
373impl Default for DataRequest { 380impl Default for DataRequest {
374 fn default() -> Self { 381 fn default() -> Self {
375 Self { 382 Self {
@@ -397,7 +404,6 @@ impl Default for DataRequest {
397 404
398impl MacCommand for DataRequest { 405impl MacCommand for DataRequest {
399 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq; 406 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq;
400 const SIZE: usize = 40;
401} 407}
402 408
403/// for MCPS PURGE Request used to purge an MSDU from the transaction queue 409/// for MCPS PURGE Request used to purge an MSDU from the transaction queue
@@ -407,11 +413,12 @@ pub struct PurgeRequest {
407 /// the handle associated with the MSDU to be purged from the transaction 413 /// the handle associated with the MSDU to be purged from the transaction
408 /// queue 414 /// queue
409 pub msdu_handle: u8, 415 pub msdu_handle: u8,
416 /// byte stuffing to keep 32 bit alignment
417 pub a_stuffing: [u8; 3],
410} 418}
411 419
412impl MacCommand for PurgeRequest { 420impl MacCommand for PurgeRequest {
413 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq; 421 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq;
414 const SIZE: usize = 4;
415} 422}
416 423
417/// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication 424/// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication
@@ -434,11 +441,12 @@ pub struct AssociateResponse {
434 pub key_id_mode: KeyIdMode, 441 pub key_id_mode: KeyIdMode,
435 /// the index of the key to be used 442 /// the index of the key to be used
436 pub key_index: u8, 443 pub key_index: u8,
444 /// byte stuffing to keep 32 bit alignment
445 pub a_stuffing: [u8; 2],
437} 446}
438 447
439impl MacCommand for AssociateResponse { 448impl MacCommand for AssociateResponse {
440 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes; 449 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes;
441 const SIZE: usize = 24;
442} 450}
443 451
444/// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication 452/// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication
@@ -459,9 +467,10 @@ pub struct OrphanResponse {
459 pub key_id_mode: KeyIdMode, 467 pub key_id_mode: KeyIdMode,
460 /// the index of the key to be used 468 /// the index of the key to be used
461 pub key_index: u8, 469 pub key_index: u8,
470 /// byte stuffing to keep 32 bit alignment
471 pub a_stuffing: [u8; 2],
462} 472}
463 473
464impl MacCommand for OrphanResponse { 474impl MacCommand for OrphanResponse {
465 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes; 475 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes;
466 const SIZE: usize = 24;
467} 476}
diff --git a/embassy-stm32-wpan/src/mac/event.rs b/embassy-stm32-wpan/src/mac/event.rs
index ea326a336..661c06ac4 100644
--- a/embassy-stm32-wpan/src/mac/event.rs
+++ b/embassy-stm32-wpan/src/mac/event.rs
@@ -4,6 +4,8 @@ use embassy_sync::blocking_mutex::raw::NoopRawMutex;
4use embassy_sync::pubsub::{PubSubChannel, Subscriber}; 4use embassy_sync::pubsub::{PubSubChannel, Subscriber};
5 5
6use super::helpers::to_u16; 6use super::helpers::to_u16;
7use core::mem;
8
7use super::indications::{ 9use super::indications::{
8 AssociateIndication, BeaconNotifyIndication, CommStatusIndication, DataIndication, DisassociateIndication, 10 AssociateIndication, BeaconNotifyIndication, CommStatusIndication, DataIndication, DisassociateIndication,
9 DpsIndication, GtsIndication, OrphanIndication, PollIndication, SyncLossIndication, 11 DpsIndication, GtsIndication, OrphanIndication, PollIndication, SyncLossIndication,
@@ -12,93 +14,102 @@ use super::responses::{
12 AssociateConfirm, CalibrateConfirm, DataConfirm, DisassociateConfirm, DpsConfirm, GetConfirm, GtsConfirm, 14 AssociateConfirm, CalibrateConfirm, DataConfirm, DisassociateConfirm, DpsConfirm, GetConfirm, GtsConfirm,
13 PollConfirm, PurgeConfirm, ResetConfirm, RxEnableConfirm, ScanConfirm, SetConfirm, SoundingConfirm, StartConfirm, 15 PollConfirm, PurgeConfirm, ResetConfirm, RxEnableConfirm, ScanConfirm, SetConfirm, SoundingConfirm, StartConfirm,
14}; 16};
17use crate::evt::EvtBox;
15use crate::mac::opcodes::OpcodeM0ToM4; 18use crate::mac::opcodes::OpcodeM0ToM4;
16 19use crate::sub::mac::Mac;
17pub trait ParseableMacEvent { 20
18 const SIZE: usize; 21pub(crate) trait ParseableMacEvent: Sized {
19 22 fn from_buffer<'a>(buf: &'a [u8]) -> Result<&'a Self, ()> {
20 fn validate(buf: &[u8]) -> Result<(), ()> { 23 if buf.len() < mem::size_of::<Self>() {
21 if buf.len() < Self::SIZE { 24 Err(())
22 return Err(()); 25 } else {
26 Ok(unsafe { &*(buf as *const _ as *const Self) })
23 } 27 }
24
25 Ok(())
26 } 28 }
27
28 fn try_parse(buf: &[u8]) -> Result<Self, ()>
29 where
30 Self: Sized;
31} 29}
32 30
33#[derive(Debug, Clone, PartialEq, Eq)] 31pub struct Event {
34#[cfg_attr(feature = "defmt", derive(defmt::Format))] 32 event_box: EvtBox<Mac>,
35pub enum MacEvent {
36 MlmeAssociateCnf(AssociateConfirm),
37 MlmeDisassociateCnf(DisassociateConfirm),
38 MlmeGetCnf(GetConfirm),
39 MlmeGtsCnf(GtsConfirm),
40 MlmeResetCnf(ResetConfirm),
41 MlmeRxEnableCnf(RxEnableConfirm),
42 MlmeScanCnf(ScanConfirm),
43 MlmeSetCnf(SetConfirm),
44 MlmeStartCnf(StartConfirm),
45 MlmePollCnf(PollConfirm),
46 MlmeDpsCnf(DpsConfirm),
47 MlmeSoundingCnf(SoundingConfirm),
48 MlmeCalibrateCnf(CalibrateConfirm),
49 McpsDataCnf(DataConfirm),
50 McpsPurgeCnf(PurgeConfirm),
51 MlmeAssociateInd(AssociateIndication),
52 MlmeDisassociateInd(DisassociateIndication),
53 MlmeBeaconNotifyInd(BeaconNotifyIndication),
54 MlmeCommStatusInd(CommStatusIndication),
55 MlmeGtsInd(GtsIndication),
56 MlmeOrphanInd(OrphanIndication),
57 MlmeSyncLossInd(SyncLossIndication),
58 MlmeDpsInd(DpsIndication),
59 McpsDataInd(DataIndication),
60 MlmePollInd(PollIndication),
61} 33}
62 34
63impl TryFrom<&[u8]> for MacEvent { 35impl Event {
64 type Error = (); 36 pub(crate) fn new(event_box: EvtBox<Mac>) -> Self {
37 Self { event_box }
38 }
65 39
66 fn try_from(value: &[u8]) -> Result<Self, Self::Error> { 40 pub fn mac_event<'a>(&'a self) -> Result<MacEvent<'a>, ()> {
67 let opcode = to_u16(&value[0..2]); 41 let payload = self.event_box.payload();
68 let opcode = OpcodeM0ToM4::try_from(opcode)?; 42 let opcode = u16::from_le_bytes(payload[0..2].try_into().unwrap());
69 43
70 let buf = &value[2..]; 44 let opcode = OpcodeM0ToM4::try_from(opcode)?;
45 let buf = &payload[2..];
71 46
72 match opcode { 47 match opcode {
73 OpcodeM0ToM4::MlmeAssociateCnf => Ok(Self::MlmeAssociateCnf(AssociateConfirm::try_parse(buf)?)), 48 OpcodeM0ToM4::MlmeAssociateCnf => Ok(MacEvent::MlmeAssociateCnf(AssociateConfirm::from_buffer(buf)?)),
74 OpcodeM0ToM4::MlmeDisassociateCnf => Ok(Self::MlmeDisassociateCnf(DisassociateConfirm::try_parse(buf)?)), 49 OpcodeM0ToM4::MlmeDisassociateCnf => {
75 OpcodeM0ToM4::MlmeGetCnf => Ok(Self::MlmeGetCnf(GetConfirm::try_parse(buf)?)), 50 Ok(MacEvent::MlmeDisassociateCnf(DisassociateConfirm::from_buffer(buf)?))
76 OpcodeM0ToM4::MlmeGtsCnf => Ok(Self::MlmeGtsCnf(GtsConfirm::try_parse(buf)?)), 51 }
77 OpcodeM0ToM4::MlmeResetCnf => Ok(Self::MlmeResetCnf(ResetConfirm::try_parse(buf)?)), 52 OpcodeM0ToM4::MlmeGetCnf => Ok(MacEvent::MlmeGetCnf(GetConfirm::from_buffer(buf)?)),
78 OpcodeM0ToM4::MlmeRxEnableCnf => Ok(Self::MlmeRxEnableCnf(RxEnableConfirm::try_parse(buf)?)), 53 OpcodeM0ToM4::MlmeGtsCnf => Ok(MacEvent::MlmeGtsCnf(GtsConfirm::from_buffer(buf)?)),
79 OpcodeM0ToM4::MlmeScanCnf => Ok(Self::MlmeScanCnf(ScanConfirm::try_parse(buf)?)), 54 OpcodeM0ToM4::MlmeResetCnf => Ok(MacEvent::MlmeResetCnf(ResetConfirm::from_buffer(buf)?)),
80 OpcodeM0ToM4::MlmeSetCnf => Ok(Self::MlmeSetCnf(SetConfirm::try_parse(buf)?)), 55 OpcodeM0ToM4::MlmeRxEnableCnf => Ok(MacEvent::MlmeRxEnableCnf(RxEnableConfirm::from_buffer(buf)?)),
81 OpcodeM0ToM4::MlmeStartCnf => Ok(Self::MlmeStartCnf(StartConfirm::try_parse(buf)?)), 56 OpcodeM0ToM4::MlmeScanCnf => Ok(MacEvent::MlmeScanCnf(ScanConfirm::from_buffer(buf)?)),
82 OpcodeM0ToM4::MlmePollCnf => Ok(Self::MlmePollCnf(PollConfirm::try_parse(buf)?)), 57 OpcodeM0ToM4::MlmeSetCnf => Ok(MacEvent::MlmeSetCnf(SetConfirm::from_buffer(buf)?)),
83 OpcodeM0ToM4::MlmeDpsCnf => Ok(Self::MlmeDpsCnf(DpsConfirm::try_parse(buf)?)), 58 OpcodeM0ToM4::MlmeStartCnf => Ok(MacEvent::MlmeStartCnf(StartConfirm::from_buffer(buf)?)),
84 OpcodeM0ToM4::MlmeSoundingCnf => Ok(Self::MlmeSoundingCnf(SoundingConfirm::try_parse(buf)?)), 59 OpcodeM0ToM4::MlmePollCnf => Ok(MacEvent::MlmePollCnf(PollConfirm::from_buffer(buf)?)),
85 OpcodeM0ToM4::MlmeCalibrateCnf => Ok(Self::MlmeCalibrateCnf(CalibrateConfirm::try_parse(buf)?)), 60 OpcodeM0ToM4::MlmeDpsCnf => Ok(MacEvent::MlmeDpsCnf(DpsConfirm::from_buffer(buf)?)),
86 OpcodeM0ToM4::McpsDataCnf => Ok(Self::McpsDataCnf(DataConfirm::try_parse(buf)?)), 61 OpcodeM0ToM4::MlmeSoundingCnf => Ok(MacEvent::MlmeSoundingCnf(SoundingConfirm::from_buffer(buf)?)),
87 OpcodeM0ToM4::McpsPurgeCnf => Ok(Self::McpsPurgeCnf(PurgeConfirm::try_parse(buf)?)), 62 OpcodeM0ToM4::MlmeCalibrateCnf => Ok(MacEvent::MlmeCalibrateCnf(CalibrateConfirm::from_buffer(buf)?)),
88 OpcodeM0ToM4::MlmeAssociateInd => Ok(Self::MlmeAssociateInd(AssociateIndication::try_parse(buf)?)), 63 OpcodeM0ToM4::McpsDataCnf => Ok(MacEvent::McpsDataCnf(DataConfirm::from_buffer(buf)?)),
89 OpcodeM0ToM4::MlmeDisassociateInd => Ok(Self::MlmeDisassociateInd(DisassociateIndication::try_parse(buf)?)), 64 OpcodeM0ToM4::McpsPurgeCnf => Ok(MacEvent::McpsPurgeCnf(PurgeConfirm::from_buffer(buf)?)),
90 OpcodeM0ToM4::MlmeBeaconNotifyInd => Ok(Self::MlmeBeaconNotifyInd(BeaconNotifyIndication::try_parse(buf)?)), 65 OpcodeM0ToM4::MlmeAssociateInd => Ok(MacEvent::MlmeAssociateInd(AssociateIndication::from_buffer(buf)?)),
91 OpcodeM0ToM4::MlmeCommStatusInd => Ok(Self::MlmeCommStatusInd(CommStatusIndication::try_parse(buf)?)), 66 OpcodeM0ToM4::MlmeDisassociateInd => {
92 OpcodeM0ToM4::MlmeGtsInd => Ok(Self::MlmeGtsInd(GtsIndication::try_parse(buf)?)), 67 Ok(MacEvent::MlmeDisassociateInd(DisassociateIndication::from_buffer(buf)?))
93 OpcodeM0ToM4::MlmeOrphanInd => Ok(Self::MlmeOrphanInd(OrphanIndication::try_parse(buf)?)), 68 }
94 OpcodeM0ToM4::MlmeSyncLossInd => Ok(Self::MlmeSyncLossInd(SyncLossIndication::try_parse(buf)?)), 69 OpcodeM0ToM4::MlmeBeaconNotifyInd => {
95 OpcodeM0ToM4::MlmeDpsInd => Ok(Self::MlmeDpsInd(DpsIndication::try_parse(buf)?)), 70 Ok(MacEvent::MlmeBeaconNotifyInd(BeaconNotifyIndication::from_buffer(buf)?))
96 OpcodeM0ToM4::McpsDataInd => Ok(Self::McpsDataInd(DataIndication::try_parse(buf)?)), 71 }
97 OpcodeM0ToM4::MlmePollInd => Ok(Self::MlmePollInd(PollIndication::try_parse(buf)?)), 72 OpcodeM0ToM4::MlmeCommStatusInd => Ok(MacEvent::MlmeCommStatusInd(CommStatusIndication::from_buffer(buf)?)),
73 OpcodeM0ToM4::MlmeGtsInd => Ok(MacEvent::MlmeGtsInd(GtsIndication::from_buffer(buf)?)),
74 OpcodeM0ToM4::MlmeOrphanInd => Ok(MacEvent::MlmeOrphanInd(OrphanIndication::from_buffer(buf)?)),
75 OpcodeM0ToM4::MlmeSyncLossInd => Ok(MacEvent::MlmeSyncLossInd(SyncLossIndication::from_buffer(buf)?)),
76 OpcodeM0ToM4::MlmeDpsInd => Ok(MacEvent::MlmeDpsInd(DpsIndication::from_buffer(buf)?)),
77 OpcodeM0ToM4::McpsDataInd => Ok(MacEvent::McpsDataInd(DataIndication::from_buffer(buf)?)),
78 OpcodeM0ToM4::MlmePollInd => Ok(MacEvent::MlmePollInd(PollIndication::from_buffer(buf)?)),
98 } 79 }
99 } 80 }
100} 81}
101 82
83#[derive(Debug, Clone, PartialEq, Eq)]
84#[cfg_attr(feature = "defmt", derive(defmt::Format))]
85pub enum MacEvent<'a> {
86 MlmeAssociateCnf(&'a AssociateConfirm),
87 MlmeDisassociateCnf(&'a DisassociateConfirm),
88 MlmeGetCnf(&'a GetConfirm),
89 MlmeGtsCnf(&'a GtsConfirm),
90 MlmeResetCnf(&'a ResetConfirm),
91 MlmeRxEnableCnf(&'a RxEnableConfirm),
92 MlmeScanCnf(&'a ScanConfirm),
93 MlmeSetCnf(&'a SetConfirm),
94 MlmeStartCnf(&'a StartConfirm),
95 MlmePollCnf(&'a PollConfirm),
96 MlmeDpsCnf(&'a DpsConfirm),
97 MlmeSoundingCnf(&'a SoundingConfirm),
98 MlmeCalibrateCnf(&'a CalibrateConfirm),
99 McpsDataCnf(&'a DataConfirm),
100 McpsPurgeCnf(&'a PurgeConfirm),
101 MlmeAssociateInd(&'a AssociateIndication),
102 MlmeDisassociateInd(&'a DisassociateIndication),
103 MlmeBeaconNotifyInd(&'a BeaconNotifyIndication),
104 MlmeCommStatusInd(&'a CommStatusIndication),
105 MlmeGtsInd(&'a GtsIndication),
106 MlmeOrphanInd(&'a OrphanIndication),
107 MlmeSyncLossInd(&'a SyncLossIndication),
108 MlmeDpsInd(&'a DpsIndication),
109 McpsDataInd(&'a DataIndication),
110 MlmePollInd(&'a PollIndication),
111}
112
102// TODO this PubSub can probably be replaced with shared memory to make it a bit more efficient. 113// TODO this PubSub can probably be replaced with shared memory to make it a bit more efficient.
103pub type EventQueue = PubSubChannel<NoopRawMutex, Message, 2, 1, 1>; 114pub type EventQueue = PubSubChannel<NoopRawMutex, Message, 2, 1, 1>;
104pub type EventSubscriber<'a> = Subscriber<'a, NoopRawMutex, Message, 2, 1, 1>; 115pub type EventSubscriber<'a> = Subscriber<'a, NoopRawMutex, Message, 2, 1, 1>;
diff --git a/embassy-stm32-wpan/src/mac/helpers.rs b/embassy-stm32-wpan/src/mac/helpers.rs
deleted file mode 100644
index 5a5bf8a85..000000000
--- a/embassy-stm32-wpan/src/mac/helpers.rs
+++ /dev/null
@@ -1,7 +0,0 @@
1pub fn to_u16(buf: &[u8]) -> u16 {
2 ((buf[1] as u16) << 8) | buf[0] as u16
3}
4
5pub fn to_u32(buf: &[u8]) -> u32 {
6 ((buf[0] as u32) << 0) + ((buf[1] as u32) << 8) + ((buf[2] as u32) << 16) + ((buf[3] as u32) << 24)
7}
diff --git a/embassy-stm32-wpan/src/mac/indications.rs b/embassy-stm32-wpan/src/mac/indications.rs
index 6df4aa23a..5445fb4af 100644
--- a/embassy-stm32-wpan/src/mac/indications.rs
+++ b/embassy-stm32-wpan/src/mac/indications.rs
@@ -1,6 +1,7 @@
1use core::slice;
2
1use super::consts::MAX_PENDING_ADDRESS; 3use super::consts::MAX_PENDING_ADDRESS;
2use super::event::ParseableMacEvent; 4use super::event::ParseableMacEvent;
3use super::helpers::to_u32;
4use super::typedefs::{ 5use super::typedefs::{
5 AddressMode, Capabilities, DisassociationReason, KeyIdMode, MacAddress, MacChannel, MacStatus, PanDescriptor, 6 AddressMode, Capabilities, DisassociationReason, KeyIdMode, MacAddress, MacChannel, MacStatus, PanDescriptor,
6 PanId, SecurityLevel, 7 PanId, SecurityLevel,
@@ -8,6 +9,7 @@ use super::typedefs::{
8 9
9/// MLME ASSOCIATE Indication which will be used by the MAC 10/// MLME ASSOCIATE Indication which will be used by the MAC
10/// to indicate the reception of an association request command 11/// to indicate the reception of an association request command
12#[repr(C)]
11#[cfg_attr(feature = "defmt", derive(defmt::Format))] 13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
12pub struct AssociateIndication { 14pub struct AssociateIndication {
13 /// Extended address of the device requesting association 15 /// Extended address of the device requesting association
@@ -24,25 +26,11 @@ pub struct AssociateIndication {
24 pub key_source: [u8; 8], 26 pub key_source: [u8; 8],
25} 27}
26 28
27impl ParseableMacEvent for AssociateIndication { 29impl ParseableMacEvent for AssociateIndication {}
28 const SIZE: usize = 20;
29
30 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
31 Self::validate(buf)?;
32
33 Ok(Self {
34 device_address: [buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]],
35 capability_information: Capabilities::from_bits(buf[8]).ok_or(())?,
36 security_level: SecurityLevel::try_from(buf[9])?,
37 key_id_mode: KeyIdMode::try_from(buf[10])?,
38 key_index: buf[11],
39 key_source: [buf[12], buf[13], buf[14], buf[15], buf[16], buf[17], buf[18], buf[19]],
40 })
41 }
42}
43 30
44/// MLME DISASSOCIATE indication which will be used to send 31/// MLME DISASSOCIATE indication which will be used to send
45/// disassociation indication to the application. 32/// disassociation indication to the application.
33#[repr(C)]
46#[cfg_attr(feature = "defmt", derive(defmt::Format))] 34#[cfg_attr(feature = "defmt", derive(defmt::Format))]
47pub struct DisassociateIndication { 35pub struct DisassociateIndication {
48 /// Extended address of the device requesting association 36 /// Extended address of the device requesting association
@@ -59,25 +47,11 @@ pub struct DisassociateIndication {
59 pub key_source: [u8; 8], 47 pub key_source: [u8; 8],
60} 48}
61 49
62impl ParseableMacEvent for DisassociateIndication { 50impl ParseableMacEvent for DisassociateIndication {}
63 const SIZE: usize = 20;
64
65 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
66 Self::validate(buf)?;
67
68 Ok(Self {
69 device_address: [buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]],
70 disassociation_reason: DisassociationReason::try_from(buf[8])?,
71 security_level: SecurityLevel::try_from(buf[9])?,
72 key_id_mode: KeyIdMode::try_from(buf[10])?,
73 key_index: buf[11],
74 key_source: [buf[12], buf[13], buf[14], buf[15], buf[16], buf[17], buf[18], buf[19]],
75 })
76 }
77}
78 51
79/// MLME BEACON NOTIIFY Indication which is used to send parameters contained 52/// MLME BEACON NOTIIFY Indication which is used to send parameters contained
80/// within a beacon frame received by the MAC to the application 53/// within a beacon frame received by the MAC to the application
54#[repr(C)]
81#[cfg_attr(feature = "defmt", derive(defmt::Format))] 55#[cfg_attr(feature = "defmt", derive(defmt::Format))]
82pub struct BeaconNotifyIndication { 56pub struct BeaconNotifyIndication {
83 /// he set of octets comprising the beacon payload to be transferred 57 /// he set of octets comprising the beacon payload to be transferred
@@ -95,36 +69,10 @@ pub struct BeaconNotifyIndication {
95 pub sdu_length: u8, 69 pub sdu_length: u8,
96} 70}
97 71
98impl ParseableMacEvent for BeaconNotifyIndication { 72impl ParseableMacEvent for BeaconNotifyIndication {}
99 const SIZE: usize = 88;
100
101 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
102 // TODO: this is unchecked
103
104 Self::validate(buf)?;
105
106 let addr_list = [
107 MacAddress::try_from(&buf[26..34])?,
108 MacAddress::try_from(&buf[34..42])?,
109 MacAddress::try_from(&buf[42..50])?,
110 MacAddress::try_from(&buf[50..58])?,
111 MacAddress::try_from(&buf[58..66])?,
112 MacAddress::try_from(&buf[66..74])?,
113 MacAddress::try_from(&buf[74..82])?,
114 ];
115
116 Ok(Self {
117 sdu_ptr: to_u32(&buf[0..4]) as *const u8,
118 pan_descriptor: PanDescriptor::try_from(&buf[4..26])?,
119 addr_list,
120 bsn: buf[82],
121 pend_addr_spec: buf[83],
122 sdu_length: buf[83],
123 })
124 }
125}
126 73
127/// MLME COMM STATUS Indication which is used by the MAC to indicate a communications status 74/// MLME COMM STATUS Indication which is used by the MAC to indicate a communications status
75#[repr(C)]
128#[cfg_attr(feature = "defmt", derive(defmt::Format))] 76#[cfg_attr(feature = "defmt", derive(defmt::Format))]
129pub struct CommStatusIndication { 77pub struct CommStatusIndication {
130 /// The 16-bit PAN identifier of the device from which the frame 78 /// The 16-bit PAN identifier of the device from which the frame
@@ -150,54 +98,11 @@ pub struct CommStatusIndication {
150 pub key_source: [u8; 8], 98 pub key_source: [u8; 8],
151} 99}
152 100
153impl ParseableMacEvent for CommStatusIndication { 101impl ParseableMacEvent for CommStatusIndication {}
154 const SIZE: usize = 32;
155
156 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
157 Self::validate(buf)?;
158
159 let src_addr_mode = AddressMode::try_from(buf[2])?;
160 let dst_addr_mode = AddressMode::try_from(buf[3])?;
161
162 let src_address = match src_addr_mode {
163 AddressMode::NoAddress => MacAddress { short: [0, 0] },
164 AddressMode::Reserved => MacAddress { short: [0, 0] },
165 AddressMode::Short => MacAddress {
166 short: [buf[4], buf[5]],
167 },
168 AddressMode::Extended => MacAddress {
169 extended: [buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]],
170 },
171 };
172
173 let dst_address = match dst_addr_mode {
174 AddressMode::NoAddress => MacAddress { short: [0, 0] },
175 AddressMode::Reserved => MacAddress { short: [0, 0] },
176 AddressMode::Short => MacAddress {
177 short: [buf[12], buf[13]],
178 },
179 AddressMode::Extended => MacAddress {
180 extended: [buf[12], buf[13], buf[14], buf[15], buf[16], buf[17], buf[18], buf[19]],
181 },
182 };
183
184 Ok(Self {
185 pan_id: PanId([buf[0], buf[1]]),
186 src_addr_mode,
187 dst_addr_mode,
188 src_address,
189 dst_address,
190 status: MacStatus::try_from(buf[20])?,
191 security_level: SecurityLevel::try_from(buf[21])?,
192 key_id_mode: KeyIdMode::try_from(buf[22])?,
193 key_index: buf[23],
194 key_source: [buf[24], buf[25], buf[26], buf[27], buf[28], buf[29], buf[30], buf[31]],
195 })
196 }
197}
198 102
199/// MLME GTS Indication indicates that a GTS has been allocated or that a 103/// MLME GTS Indication indicates that a GTS has been allocated or that a
200/// previously allocated GTS has been deallocated 104/// previously allocated GTS has been deallocated
105#[repr(C)]
201#[cfg_attr(feature = "defmt", derive(defmt::Format))] 106#[cfg_attr(feature = "defmt", derive(defmt::Format))]
202pub struct GtsIndication { 107pub struct GtsIndication {
203 /// The short address of the device that has been allocated or deallocated a GTS 108 /// The short address of the device that has been allocated or deallocated a GTS
@@ -210,30 +115,17 @@ pub struct GtsIndication {
210 pub key_id_mode: KeyIdMode, 115 pub key_id_mode: KeyIdMode,
211 /// Index of the key to be used 116 /// Index of the key to be used
212 pub key_index: u8, 117 pub key_index: u8,
118 /// byte stuffing to keep 32 bit alignment
119 a_stuffing: [u8; 2],
213 /// Originator of the key to be used 120 /// Originator of the key to be used
214 pub key_source: [u8; 8], 121 pub key_source: [u8; 8],
215} 122}
216 123
217impl ParseableMacEvent for GtsIndication { 124impl ParseableMacEvent for GtsIndication {}
218 const SIZE: usize = 16;
219
220 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
221 Self::validate(buf)?;
222
223 Ok(Self {
224 device_address: [buf[0], buf[1]],
225 gts_characteristics: buf[2],
226 security_level: SecurityLevel::try_from(buf[3])?,
227 key_id_mode: KeyIdMode::try_from(buf[4])?,
228 key_index: buf[5],
229 // 2 byte stuffing
230 key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]],
231 })
232 }
233}
234 125
235/// MLME ORPHAN Indication which is used by the coordinator to notify the 126/// MLME ORPHAN Indication which is used by the coordinator to notify the
236/// application of the presence of an orphaned device 127/// application of the presence of an orphaned device
128#[repr(C)]
237#[cfg_attr(feature = "defmt", derive(defmt::Format))] 129#[cfg_attr(feature = "defmt", derive(defmt::Format))]
238pub struct OrphanIndication { 130pub struct OrphanIndication {
239 /// Extended address of the orphaned device 131 /// Extended address of the orphaned device
@@ -246,27 +138,15 @@ pub struct OrphanIndication {
246 pub key_id_mode: KeyIdMode, 138 pub key_id_mode: KeyIdMode,
247 /// Index of the key used by the originator of the received frame 139 /// Index of the key used by the originator of the received frame
248 pub key_index: u8, 140 pub key_index: u8,
141 /// byte stuffing to keep 32 bit alignment
142 a_stuffing: [u8; 1],
249} 143}
250 144
251impl ParseableMacEvent for OrphanIndication { 145impl ParseableMacEvent for OrphanIndication {}
252 const SIZE: usize = 20;
253
254 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
255 Self::validate(buf)?;
256
257 Ok(Self {
258 orphan_address: [buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]],
259 key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]],
260 security_level: SecurityLevel::try_from(buf[16])?,
261 key_id_mode: KeyIdMode::try_from(buf[17])?,
262 key_index: buf[18],
263 // 1 byte stuffing
264 })
265 }
266}
267 146
268/// MLME SYNC LOSS Indication which is used by the MAC to indicate the loss 147/// MLME SYNC LOSS Indication which is used by the MAC to indicate the loss
269/// of synchronization with the coordinator 148/// of synchronization with the coordinator
149#[repr(C)]
270#[cfg_attr(feature = "defmt", derive(defmt::Format))] 150#[cfg_attr(feature = "defmt", derive(defmt::Format))]
271pub struct SyncLossIndication { 151pub struct SyncLossIndication {
272 /// The PAN identifier with which the device lost synchronization or to which it was realigned 152 /// The PAN identifier with which the device lost synchronization or to which it was realigned
@@ -287,42 +167,21 @@ pub struct SyncLossIndication {
287 pub key_source: [u8; 8], 167 pub key_source: [u8; 8],
288} 168}
289 169
290impl ParseableMacEvent for SyncLossIndication { 170impl ParseableMacEvent for SyncLossIndication {}
291 const SIZE: usize = 16;
292
293 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
294 Self::validate(buf)?;
295
296 Ok(Self {
297 pan_id: PanId([buf[0], buf[1]]),
298 loss_reason: buf[2],
299 channel_number: MacChannel::try_from(buf[3])?,
300 channel_page: buf[4],
301 security_level: SecurityLevel::try_from(buf[5])?,
302 key_id_mode: KeyIdMode::try_from(buf[6])?,
303 key_index: buf[7],
304 key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]],
305 })
306 }
307}
308 171
309/// MLME DPS Indication which indicates the expiration of the DPSIndexDuration 172/// MLME DPS Indication which indicates the expiration of the DPSIndexDuration
310/// and the resetting of the DPS values in the PHY 173/// and the resetting of the DPS values in the PHY
174#[repr(C)]
311#[cfg_attr(feature = "defmt", derive(defmt::Format))] 175#[cfg_attr(feature = "defmt", derive(defmt::Format))]
312pub struct DpsIndication; 176pub struct DpsIndication {
313 177 /// byte stuffing to keep 32 bit alignment
314impl ParseableMacEvent for DpsIndication { 178 a_stuffing: [u8; 4],
315 const SIZE: usize = 4;
316
317 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
318 Self::validate(buf)?;
319
320 Ok(Self)
321 }
322} 179}
323 180
181impl ParseableMacEvent for DpsIndication {}
182
183#[repr(C)]
324#[cfg_attr(feature = "defmt", derive(defmt::Format))] 184#[cfg_attr(feature = "defmt", derive(defmt::Format))]
325#[repr(C, align(8))]
326pub struct DataIndication { 185pub struct DataIndication {
327 /// Pointer to the set of octets forming the MSDU being indicated 186 /// Pointer to the set of octets forming the MSDU being indicated
328 pub msdu_ptr: *const u8, 187 pub msdu_ptr: *const u8,
@@ -347,9 +206,9 @@ pub struct DataIndication {
347 /// The time, in symbols, at which the data were received 206 /// The time, in symbols, at which the data were received
348 pub time_stamp: [u8; 4], 207 pub time_stamp: [u8; 4],
349 /// The security level purportedly used by the received data frame 208 /// The security level purportedly used by the received data frame
350 pub security_level: SecurityLevel, 209 security_level: SecurityLevel,
351 /// Mode used to identify the key used by originator of received frame 210 /// Mode used to identify the key used by originator of received frame
352 pub key_id_mode: KeyIdMode, 211 key_id_mode: KeyIdMode,
353 /// The originator of the key 212 /// The originator of the key
354 pub key_source: [u8; 8], 213 pub key_source: [u8; 8],
355 /// The index of the key 214 /// The index of the key
@@ -374,68 +233,17 @@ pub struct DataIndication {
374 pub rssi: u8, 233 pub rssi: u8,
375} 234}
376 235
377impl ParseableMacEvent for DataIndication { 236impl ParseableMacEvent for DataIndication {}
378 const SIZE: usize = 68;
379
380 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
381 Self::validate(buf)?;
382
383 let src_addr_mode = AddressMode::try_from(buf[4])?;
384 let src_address = match src_addr_mode {
385 AddressMode::NoAddress => MacAddress { short: [0, 0] },
386 AddressMode::Reserved => MacAddress { short: [0, 0] },
387 AddressMode::Short => MacAddress {
388 short: [buf[7], buf[8]],
389 },
390 AddressMode::Extended => MacAddress {
391 extended: [buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14]],
392 },
393 };
394 237
395 let dst_addr_mode = AddressMode::try_from(buf[15])?; 238impl DataIndication {
396 let dst_address = match dst_addr_mode { 239 pub fn payload<'a>(&'a self) -> &'a [u8] {
397 AddressMode::NoAddress => MacAddress { short: [0, 0] }, 240 unsafe { slice::from_raw_parts(self.msdu_ptr, self.msdu_length as usize) }
398 AddressMode::Reserved => MacAddress { short: [0, 0] },
399 AddressMode::Short => MacAddress {
400 short: [buf[18], buf[19]],
401 },
402 AddressMode::Extended => MacAddress {
403 extended: [buf[18], buf[19], buf[20], buf[21], buf[22], buf[23], buf[24], buf[25]],
404 },
405 };
406
407 Ok(Self {
408 msdu_ptr: to_u32(&buf[0..4]) as *const u8,
409 src_addr_mode,
410 src_pan_id: PanId([buf[5], buf[6]]),
411 src_address,
412 dst_addr_mode,
413 dst_pan_id: PanId([buf[16], buf[17]]),
414 dst_address,
415 msdu_length: buf[26],
416 mpdu_link_quality: buf[27],
417 dsn: buf[28],
418 time_stamp: [buf[29], buf[30], buf[31], buf[32]],
419 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
420 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
421 key_source: [buf[35], buf[36], buf[37], buf[38], buf[39], buf[40], buf[41], buf[42]],
422 key_index: buf[43],
423 uwbprf: buf[44],
424 uwn_preamble_symbol_repetitions: buf[45],
425 datrate: buf[46],
426 ranging_received: buf[47],
427 ranging_counter_start: to_u32(&buf[48..52]),
428 ranging_counter_stop: to_u32(&buf[52..56]),
429 ranging_tracking_interval: to_u32(&buf[56..60]),
430 ranging_offset: to_u32(&buf[60..64]),
431 ranging_fom: buf[65],
432 rssi: buf[66],
433 })
434 } 241 }
435} 242}
436 243
437/// MLME POLL Indication which will be used for indicating the Data Request 244/// MLME POLL Indication which will be used for indicating the Data Request
438/// reception to upper layer as defined in Zigbee r22 - D.8.2 245/// reception to upper layer as defined in Zigbee r22 - D.8.2
246#[repr(C)]
439#[cfg_attr(feature = "defmt", derive(defmt::Format))] 247#[cfg_attr(feature = "defmt", derive(defmt::Format))]
440pub struct PollIndication { 248pub struct PollIndication {
441 /// addressing mode used 249 /// addressing mode used
@@ -444,27 +252,4 @@ pub struct PollIndication {
444 pub request_address: MacAddress, 252 pub request_address: MacAddress,
445} 253}
446 254
447impl ParseableMacEvent for PollIndication { 255impl ParseableMacEvent for PollIndication {}
448 const SIZE: usize = 9;
449
450 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
451 Self::validate(buf)?;
452
453 let addr_mode = AddressMode::try_from(buf[0])?;
454 let request_address = match addr_mode {
455 AddressMode::NoAddress => MacAddress { short: [0, 0] },
456 AddressMode::Reserved => MacAddress { short: [0, 0] },
457 AddressMode::Short => MacAddress {
458 short: [buf[1], buf[2]],
459 },
460 AddressMode::Extended => MacAddress {
461 extended: [buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]],
462 },
463 };
464
465 Ok(Self {
466 addr_mode,
467 request_address,
468 })
469 }
470}
diff --git a/embassy-stm32-wpan/src/mac/mod.rs b/embassy-stm32-wpan/src/mac/mod.rs
index 67dc429e2..df03e4236 100644
--- a/embassy-stm32-wpan/src/mac/mod.rs
+++ b/embassy-stm32-wpan/src/mac/mod.rs
@@ -2,7 +2,6 @@ pub mod commands;
2mod consts; 2mod consts;
3pub mod control; 3pub mod control;
4pub mod event; 4pub mod event;
5mod helpers;
6pub mod indications; 5pub mod indications;
7mod ioctl; 6mod ioctl;
8mod macros; 7mod macros;
diff --git a/embassy-stm32-wpan/src/mac/responses.rs b/embassy-stm32-wpan/src/mac/responses.rs
index 2f6f5bf58..5d203084c 100644
--- a/embassy-stm32-wpan/src/mac/responses.rs
+++ b/embassy-stm32-wpan/src/mac/responses.rs
@@ -1,6 +1,5 @@
1use super::consts::{MAX_ED_SCAN_RESULTS_SUPPORTED, MAX_PAN_DESC_SUPPORTED, MAX_SOUNDING_LIST_SUPPORTED}; 1use super::consts::{MAX_ED_SCAN_RESULTS_SUPPORTED, MAX_PAN_DESC_SUPPORTED, MAX_SOUNDING_LIST_SUPPORTED};
2use super::event::ParseableMacEvent; 2use super::event::ParseableMacEvent;
3use super::helpers::to_u32;
4use super::typedefs::{ 3use super::typedefs::{
5 AddressMode, AssociationStatus, KeyIdMode, MacAddress, MacStatus, PanDescriptor, PanId, PibId, ScanType, 4 AddressMode, AssociationStatus, KeyIdMode, MacAddress, MacStatus, PanDescriptor, PanId, PibId, ScanType,
6 SecurityLevel, 5 SecurityLevel,
@@ -8,6 +7,7 @@ use super::typedefs::{
8 7
9/// MLME ASSOCIATE Confirm used to inform of the initiating device whether 8/// MLME ASSOCIATE Confirm used to inform of the initiating device whether
10/// its request to associate was successful or unsuccessful 9/// its request to associate was successful or unsuccessful
10#[repr(C)]
11#[cfg_attr(feature = "defmt", derive(defmt::Format))] 11#[cfg_attr(feature = "defmt", derive(defmt::Format))]
12pub struct AssociateConfirm { 12pub struct AssociateConfirm {
13 /// short address allocated by the coordinator on successful association 13 /// short address allocated by the coordinator on successful association
@@ -22,26 +22,14 @@ pub struct AssociateConfirm {
22 pub key_id_mode: KeyIdMode, 22 pub key_id_mode: KeyIdMode,
23 /// the index of the key to be used 23 /// the index of the key to be used
24 pub key_index: u8, 24 pub key_index: u8,
25 /// byte stuffing to keep 32 bit alignment
26 a_stuffing: [u8; 2],
25} 27}
26 28
27impl ParseableMacEvent for AssociateConfirm { 29impl ParseableMacEvent for AssociateConfirm {}
28 const SIZE: usize = 16;
29
30 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
31 Self::validate(buf)?;
32
33 Ok(Self {
34 assoc_short_address: [buf[0], buf[1]],
35 status: AssociationStatus::try_from(buf[2])?,
36 security_level: SecurityLevel::try_from(buf[3])?,
37 key_source: [buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]],
38 key_id_mode: KeyIdMode::try_from(buf[12])?,
39 key_index: buf[13],
40 })
41 }
42}
43 30
44/// MLME DISASSOCIATE Confirm used to send disassociation Confirmation to the application. 31/// MLME DISASSOCIATE Confirm used to send disassociation Confirmation to the application.
32#[repr(C)]
45#[cfg_attr(feature = "defmt", derive(defmt::Format))] 33#[cfg_attr(feature = "defmt", derive(defmt::Format))]
46pub struct DisassociateConfirm { 34pub struct DisassociateConfirm {
47 /// status of the disassociation attempt 35 /// status of the disassociation attempt
@@ -54,34 +42,10 @@ pub struct DisassociateConfirm {
54 pub device_address: MacAddress, 42 pub device_address: MacAddress,
55} 43}
56 44
57impl ParseableMacEvent for DisassociateConfirm { 45impl ParseableMacEvent for DisassociateConfirm {}
58 const SIZE: usize = 12;
59
60 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
61 Self::validate(buf)?;
62
63 let device_addr_mode = AddressMode::try_from(buf[1])?;
64 let device_address = match device_addr_mode {
65 AddressMode::NoAddress => MacAddress { short: [0, 0] },
66 AddressMode::Reserved => MacAddress { short: [0, 0] },
67 AddressMode::Short => MacAddress {
68 short: [buf[4], buf[5]],
69 },
70 AddressMode::Extended => MacAddress {
71 extended: [buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]],
72 },
73 };
74
75 Ok(Self {
76 status: MacStatus::try_from(buf[0])?,
77 device_addr_mode,
78 device_pan_id: PanId([buf[2], buf[3]]),
79 device_address,
80 })
81 }
82}
83 46
84/// MLME GET Confirm which requests information about a given PIB attribute 47/// MLME GET Confirm which requests information about a given PIB attribute
48#[repr(C)]
85#[cfg_attr(feature = "defmt", derive(defmt::Format))] 49#[cfg_attr(feature = "defmt", derive(defmt::Format))]
86pub struct GetConfirm { 50pub struct GetConfirm {
87 /// The pointer to the value of the PIB attribute attempted to read 51 /// The pointer to the value of the PIB attribute attempted to read
@@ -92,88 +56,54 @@ pub struct GetConfirm {
92 pub pib_attribute: PibId, 56 pub pib_attribute: PibId,
93 /// The lenght of the PIB attribute Value return 57 /// The lenght of the PIB attribute Value return
94 pub pib_attribute_value_len: u8, 58 pub pib_attribute_value_len: u8,
59 /// byte stuffing to keep 32 bit alignment
60 a_stuffing: [u8; 1],
95} 61}
96 62
97impl ParseableMacEvent for GetConfirm { 63impl ParseableMacEvent for GetConfirm {}
98 const SIZE: usize = 8;
99
100 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
101 Self::validate(buf)?;
102
103 let address = to_u32(&buf[0..4]);
104
105 Ok(Self {
106 pib_attribute_value_ptr: address as *const u8,
107 status: MacStatus::try_from(buf[4])?,
108 pib_attribute: PibId::try_from(buf[5])?,
109 pib_attribute_value_len: buf[6],
110 })
111 }
112}
113 64
114/// MLME GTS Confirm which eports the results of a request to allocate a new GTS 65/// MLME GTS Confirm which eports the results of a request to allocate a new GTS
115/// or to deallocate an existing GTS 66/// or to deallocate an existing GTS
67#[repr(C)]
116#[cfg_attr(feature = "defmt", derive(defmt::Format))] 68#[cfg_attr(feature = "defmt", derive(defmt::Format))]
117pub struct GtsConfirm { 69pub struct GtsConfirm {
118 /// The characteristics of the GTS 70 /// The characteristics of the GTS
119 pub gts_characteristics: u8, 71 pub gts_characteristics: u8,
120 /// The status of the GTS reques 72 /// The status of the GTS reques
121 pub status: MacStatus, 73 pub status: MacStatus,
74 /// byte stuffing to keep 32 bit alignment
75 a_stuffing: [u8; 2],
122} 76}
123 77
124impl ParseableMacEvent for GtsConfirm { 78impl ParseableMacEvent for GtsConfirm {}
125 const SIZE: usize = 4;
126
127 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
128 Self::validate(buf)?;
129
130 Ok(Self {
131 gts_characteristics: buf[0],
132 status: MacStatus::try_from(buf[1])?,
133 })
134 }
135}
136 79
137/// MLME RESET Confirm which is used to report the results of the reset operation 80/// MLME RESET Confirm which is used to report the results of the reset operation
81#[repr(C)]
138#[cfg_attr(feature = "defmt", derive(defmt::Format))] 82#[cfg_attr(feature = "defmt", derive(defmt::Format))]
139pub struct ResetConfirm { 83pub struct ResetConfirm {
140 /// The result of the reset operation 84 /// The result of the reset operation
141 status: MacStatus, 85 status: MacStatus,
86 /// byte stuffing to keep 32 bit alignment
87 a_stuffing: [u8; 3],
142} 88}
143 89
144impl ParseableMacEvent for ResetConfirm { 90impl ParseableMacEvent for ResetConfirm {}
145 const SIZE: usize = 4;
146
147 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
148 Self::validate(buf)?;
149
150 Ok(Self {
151 status: MacStatus::try_from(buf[0])?,
152 })
153 }
154}
155 91
156/// MLME RX ENABLE Confirm which is used to report the results of the attempt 92/// MLME RX ENABLE Confirm which is used to report the results of the attempt
157/// to enable or disable the receiver 93/// to enable or disable the receiver
94#[repr(C)]
158#[cfg_attr(feature = "defmt", derive(defmt::Format))] 95#[cfg_attr(feature = "defmt", derive(defmt::Format))]
159pub struct RxEnableConfirm { 96pub struct RxEnableConfirm {
160 /// Result of the request to enable or disable the receiver 97 /// Result of the request to enable or disable the receiver
161 status: MacStatus, 98 status: MacStatus,
99 /// byte stuffing to keep 32 bit alignment
100 a_stuffing: [u8; 3],
162} 101}
163 102
164impl ParseableMacEvent for RxEnableConfirm { 103impl ParseableMacEvent for RxEnableConfirm {}
165 const SIZE: usize = 4;
166
167 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
168 Self::validate(buf)?;
169
170 Ok(Self {
171 status: MacStatus::try_from(buf[0])?,
172 })
173 }
174}
175 104
176/// MLME SCAN Confirm which is used to report the result of the channel scan request 105/// MLME SCAN Confirm which is used to report the result of the channel scan request
106#[repr(C)]
177#[cfg_attr(feature = "defmt", derive(defmt::Format))] 107#[cfg_attr(feature = "defmt", derive(defmt::Format))]
178pub struct ScanConfirm { 108pub struct ScanConfirm {
179 /// Status of the scan request 109 /// Status of the scan request
@@ -196,150 +126,81 @@ pub struct ScanConfirm {
196 pub uwb_energy_detect_list: [u8; MAX_ED_SCAN_RESULTS_SUPPORTED], 126 pub uwb_energy_detect_list: [u8; MAX_ED_SCAN_RESULTS_SUPPORTED],
197} 127}
198 128
199impl ParseableMacEvent for ScanConfirm { 129impl ParseableMacEvent for ScanConfirm {}
200 const SIZE: usize = 185;
201
202 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
203 // TODO: this is unchecked
204
205 Self::validate(buf)?;
206
207 let mut energy_detect_list = [0; MAX_ED_SCAN_RESULTS_SUPPORTED];
208 energy_detect_list.copy_from_slice(&buf[8..24]);
209
210 let pan_descriptor_list = [
211 PanDescriptor::try_from(&buf[24..46])?,
212 PanDescriptor::try_from(&buf[46..68])?,
213 PanDescriptor::try_from(&buf[68..90])?,
214 PanDescriptor::try_from(&buf[90..102])?,
215 PanDescriptor::try_from(&buf[102..124])?,
216 PanDescriptor::try_from(&buf[124..146])?,
217 ];
218
219 let mut uwb_energy_detect_list = [0; MAX_ED_SCAN_RESULTS_SUPPORTED];
220 uwb_energy_detect_list.copy_from_slice(&buf[147..163]);
221
222 Ok(Self {
223 status: MacStatus::try_from(buf[0])?,
224 scan_type: ScanType::try_from(buf[1])?,
225 channel_page: buf[2],
226 unscanned_channels: [buf[3], buf[4], buf[5], buf[6]],
227 result_list_size: buf[7],
228 energy_detect_list,
229 pan_descriptor_list,
230 detected_category: buf[146],
231 uwb_energy_detect_list,
232 })
233 }
234}
235 130
236/// MLME SET Confirm which reports the result of an attempt to write a value to a PIB attribute 131/// MLME SET Confirm which reports the result of an attempt to write a value to a PIB attribute
132#[repr(C)]
237#[cfg_attr(feature = "defmt", derive(defmt::Format))] 133#[cfg_attr(feature = "defmt", derive(defmt::Format))]
238pub struct SetConfirm { 134pub struct SetConfirm {
239 /// The result of the set operation 135 /// The result of the set operation
240 pub status: MacStatus, 136 pub status: MacStatus,
241 /// The name of the PIB attribute that was written 137 /// The name of the PIB attribute that was written
242 pub pin_attribute: PibId, 138 pub pin_attribute: PibId,
139 /// byte stuffing to keep 32 bit alignment
140 a_stuffing: [u8; 2],
243} 141}
244 142
245impl ParseableMacEvent for SetConfirm { 143impl ParseableMacEvent for SetConfirm {}
246 const SIZE: usize = 4;
247
248 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
249 Self::validate(buf)?;
250
251 Ok(Self {
252 status: MacStatus::try_from(buf[0])?,
253 pin_attribute: PibId::try_from(buf[1])?,
254 })
255 }
256}
257 144
258/// MLME START Confirm which is used to report the results of the attempt to 145/// MLME START Confirm which is used to report the results of the attempt to
259/// start using a new superframe configuration 146/// start using a new superframe configuration
147#[repr(C)]
260#[cfg_attr(feature = "defmt", derive(defmt::Format))] 148#[cfg_attr(feature = "defmt", derive(defmt::Format))]
261pub struct StartConfirm { 149pub struct StartConfirm {
262 /// Result of the attempt to start using an updated superframe configuration 150 /// Result of the attempt to start using an updated superframe configuration
263 pub status: MacStatus, 151 pub status: MacStatus,
152 /// byte stuffing to keep 32 bit alignment
153 a_stuffing: [u8; 3],
264} 154}
265 155
266impl ParseableMacEvent for StartConfirm { 156impl ParseableMacEvent for StartConfirm {}
267 const SIZE: usize = 4;
268
269 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
270 Self::validate(buf)?;
271
272 Ok(Self {
273 status: MacStatus::try_from(buf[0])?,
274 })
275 }
276}
277 157
278/// MLME POLL Confirm which is used to report the result of a request to poll the coordinator for data 158/// MLME POLL Confirm which is used to report the result of a request to poll the coordinator for data
159#[repr(C)]
279#[cfg_attr(feature = "defmt", derive(defmt::Format))] 160#[cfg_attr(feature = "defmt", derive(defmt::Format))]
280pub struct PollConfirm { 161pub struct PollConfirm {
281 /// The status of the data request 162 /// The status of the data request
282 pub status: MacStatus, 163 pub status: MacStatus,
164 /// byte stuffing to keep 32 bit alignment
165 a_stuffing: [u8; 3],
283} 166}
284 167
285impl ParseableMacEvent for PollConfirm { 168impl ParseableMacEvent for PollConfirm {}
286 const SIZE: usize = 4;
287
288 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
289 Self::validate(buf)?;
290
291 Ok(Self {
292 status: MacStatus::try_from(buf[0])?,
293 })
294 }
295}
296 169
297/// MLME DPS Confirm which reports the results of the attempt to enable or disable the DPS 170/// MLME DPS Confirm which reports the results of the attempt to enable or disable the DPS
171#[repr(C)]
298#[cfg_attr(feature = "defmt", derive(defmt::Format))] 172#[cfg_attr(feature = "defmt", derive(defmt::Format))]
299pub struct DpsConfirm { 173pub struct DpsConfirm {
300 /// The status of the DPS request 174 /// The status of the DPS request
301 pub status: MacStatus, 175 pub status: MacStatus,
176 /// byte stuffing to keep 32 bit alignment
177 a_stuffing: [u8; 3],
302} 178}
303 179
304impl ParseableMacEvent for DpsConfirm { 180impl ParseableMacEvent for DpsConfirm {}
305 const SIZE: usize = 4;
306
307 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
308 Self::validate(buf)?;
309
310 Ok(Self {
311 status: MacStatus::try_from(buf[0])?,
312 })
313 }
314}
315 181
316/// MLME SOUNDING Confirm which reports the result of a request to the PHY to provide 182/// MLME SOUNDING Confirm which reports the result of a request to the PHY to provide
317/// channel sounding information 183/// channel sounding information
184#[repr(C)]
318#[cfg_attr(feature = "defmt", derive(defmt::Format))] 185#[cfg_attr(feature = "defmt", derive(defmt::Format))]
319pub struct SoundingConfirm { 186pub struct SoundingConfirm {
320 /// Results of the sounding measurement 187 /// Results of the sounding measurement
321 sounding_list: [u8; MAX_SOUNDING_LIST_SUPPORTED], 188 sounding_list: [u8; MAX_SOUNDING_LIST_SUPPORTED],
322}
323 189
324impl ParseableMacEvent for SoundingConfirm { 190 status: u8,
325 const SIZE: usize = 1;
326
327 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
328 Self::validate(buf)?;
329
330 let mut sounding_list = [0u8; MAX_SOUNDING_LIST_SUPPORTED];
331 sounding_list[..buf.len()].copy_from_slice(buf);
332
333 Ok(Self { sounding_list })
334 }
335} 191}
336 192
193impl ParseableMacEvent for SoundingConfirm {}
194
337/// MLME CALIBRATE Confirm which reports the result of a request to the PHY 195/// MLME CALIBRATE Confirm which reports the result of a request to the PHY
338/// to provide internal propagation path information 196/// to provide internal propagation path information
197#[repr(C)]
339#[cfg_attr(feature = "defmt", derive(defmt::Format))] 198#[cfg_attr(feature = "defmt", derive(defmt::Format))]
340pub struct CalibrateConfirm { 199pub struct CalibrateConfirm {
341 /// The status of the attempt to return sounding data 200 /// The status of the attempt to return sounding data
342 pub status: MacStatus, 201 pub status: MacStatus,
202 /// byte stuffing to keep 32 bit alignment
203 a_stuffing: [u8; 3],
343 /// A count of the propagation time from the ranging counter 204 /// A count of the propagation time from the ranging counter
344 /// to the transmit antenna 205 /// to the transmit antenna
345 pub cal_tx_rmaker_offset: u32, 206 pub cal_tx_rmaker_offset: u32,
@@ -348,23 +209,11 @@ pub struct CalibrateConfirm {
348 pub cal_rx_rmaker_offset: u32, 209 pub cal_rx_rmaker_offset: u32,
349} 210}
350 211
351impl ParseableMacEvent for CalibrateConfirm { 212impl ParseableMacEvent for CalibrateConfirm {}
352 const SIZE: usize = 12;
353
354 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
355 Self::validate(buf)?;
356
357 Ok(Self {
358 status: MacStatus::try_from(buf[0])?,
359 // 3 byte stuffing
360 cal_tx_rmaker_offset: to_u32(&buf[4..8]),
361 cal_rx_rmaker_offset: to_u32(&buf[8..12]),
362 })
363 }
364}
365 213
366/// MCPS DATA Confirm which will be used for reporting the results of 214/// MCPS DATA Confirm which will be used for reporting the results of
367/// MAC data related requests from the application 215/// MAC data related requests from the application
216#[repr(C)]
368#[cfg_attr(feature = "defmt", derive(defmt::Format))] 217#[cfg_attr(feature = "defmt", derive(defmt::Format))]
369pub struct DataConfirm { 218pub struct DataConfirm {
370 /// The handle associated with the MSDU being confirmed 219 /// The handle associated with the MSDU being confirmed
@@ -387,47 +236,23 @@ pub struct DataConfirm {
387 pub ranging_offset: u32, 236 pub ranging_offset: u32,
388 /// The FoM characterizing the ranging measurement 237 /// The FoM characterizing the ranging measurement
389 pub ranging_fom: u8, 238 pub ranging_fom: u8,
239 /// byte stuffing to keep 32 bit alignment
240 a_stuffing: [u8; 3],
390} 241}
391 242
392impl ParseableMacEvent for DataConfirm { 243impl ParseableMacEvent for DataConfirm {}
393 const SIZE: usize = 28;
394
395 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
396 Self::validate(buf)?;
397
398 Ok(Self {
399 msdu_handle: buf[0],
400 time_stamp: [buf[1], buf[2], buf[3], buf[4]],
401 ranging_received: buf[5],
402 status: MacStatus::try_from(buf[6])?,
403 ranging_counter_start: to_u32(&buf[7..11]),
404 ranging_counter_stop: to_u32(&buf[11..15]),
405 ranging_tracking_interval: to_u32(&buf[15..19]),
406 ranging_offset: to_u32(&buf[19..23]),
407 ranging_fom: buf[24],
408 })
409 }
410}
411 244
412/// MCPS PURGE Confirm which will be used by the MAC to notify the application of 245/// MCPS PURGE Confirm which will be used by the MAC to notify the application of
413/// the status of its request to purge an MSDU from the transaction queue 246/// the status of its request to purge an MSDU from the transaction queue
247#[repr(C)]
414#[cfg_attr(feature = "defmt", derive(defmt::Format))] 248#[cfg_attr(feature = "defmt", derive(defmt::Format))]
415pub struct PurgeConfirm { 249pub struct PurgeConfirm {
416 /// Handle associated with the MSDU requested to be purged from the transaction queue 250 /// Handle associated with the MSDU requested to be purged from the transaction queue
417 pub msdu_handle: u8, 251 pub msdu_handle: u8,
418 /// The status of the request 252 /// The status of the request
419 pub status: MacStatus, 253 pub status: MacStatus,
254 /// byte stuffing to keep 32 bit alignment
255 a_stuffing: [u8; 2],
420} 256}
421 257
422impl ParseableMacEvent for PurgeConfirm { 258impl ParseableMacEvent for PurgeConfirm {}
423 const SIZE: usize = 4;
424
425 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
426 Self::validate(buf)?;
427
428 Ok(Self {
429 msdu_handle: buf[0],
430 status: MacStatus::try_from(buf[1])?,
431 })
432 }
433}
diff --git a/embassy-stm32-wpan/src/mac/typedefs.rs b/embassy-stm32-wpan/src/mac/typedefs.rs
index 30c7731b2..98c67c86b 100644
--- a/embassy-stm32-wpan/src/mac/typedefs.rs
+++ b/embassy-stm32-wpan/src/mac/typedefs.rs
@@ -37,9 +37,11 @@ numeric_enum! {
37numeric_enum! { 37numeric_enum! {
38 #[repr(u8)] 38 #[repr(u8)]
39 /// this enum contains all the MAC PIB Ids 39 /// this enum contains all the MAC PIB Ids
40 #[derive(Default)]
40 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 41 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
41 pub enum PibId { 42 pub enum PibId {
42 // PHY 43 // PHY
44 #[default]
43 CurrentChannel = 0x00, 45 CurrentChannel = 0x00,
44 ChannelsSupported = 0x01, 46 ChannelsSupported = 0x01,
45 TransmitPower = 0x02, 47 TransmitPower = 0x02,
diff --git a/embassy-stm32-wpan/src/sub/mac.rs b/embassy-stm32-wpan/src/sub/mac.rs
index 4893cb47b..d9bf4c909 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;
12use crate::consts::TlPacketType; 12use crate::consts::TlPacketType;
13use crate::evt::{EvtBox, EvtPacket}; 13use crate::evt::{EvtBox, EvtPacket};
14use crate::mac::commands::MacCommand; 14use crate::mac::commands::MacCommand;
15use crate::mac::event::MacEvent; 15use crate::mac::event::Event;
16use crate::mac::typedefs::MacError; 16use crate::mac::typedefs::MacError;
17use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; 17use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER};
18use crate::{channels, evt}; 18use crate::{channels, evt};
@@ -85,12 +85,7 @@ impl Mac {
85 where 85 where
86 T: MacCommand, 86 T: MacCommand,
87 { 87 {
88 let mut payload = [0u8; MAX_PACKET_SIZE]; 88 let response = self.tl_write_and_get_response(T::OPCODE as u16, cmd.payload()).await;
89 cmd.copy_into_slice(&mut payload);
90
91 let response = self
92 .tl_write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE])
93 .await;
94 89
95 if response == 0x00 { 90 if response == 0x00 {
96 Ok(()) 91 Ok(())
@@ -99,16 +94,11 @@ impl Mac {
99 } 94 }
100 } 95 }
101 96
102 pub async fn read(&self) -> Result<MacEvent, ()> { 97 pub async fn read(&self) -> Event {
103 let evt_box = self.tl_read().await; 98 Event::new(self.tl_read().await)
104 let payload = evt_box.payload();
105
106 MacEvent::try_from(payload)
107 } 99 }
108} 100}
109 101
110const MAX_PACKET_SIZE: usize = 255;
111
112impl evt::MemoryManager for Mac { 102impl evt::MemoryManager for Mac {
113 /// SAFETY: passing a pointer to something other than a managed event packet is UB 103 /// SAFETY: passing a pointer to something other than a managed event packet is UB
114 unsafe fn drop_event_packet(_: *mut EvtPacket) { 104 unsafe fn drop_event_packet(_: *mut EvtPacket) {
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 7c5a9dfbc..c812cb3ee 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -40,6 +40,7 @@ display-interface = "0.4.1"
40byte-slice-cast = { version = "1.2.0", default-features = false } 40byte-slice-cast = { version = "1.2.0", default-features = false }
41smart-leds = "0.3.0" 41smart-leds = "0.3.0"
42heapless = "0.7.15" 42heapless = "0.7.15"
43usbd-hid = "0.6.1"
43 44
44embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } 45embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" }
45embedded-hal-async = "0.2.0-alpha.2" 46embedded-hal-async = "0.2.0-alpha.2"
diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs
new file mode 100644
index 000000000..99af1f02f
--- /dev/null
+++ b/examples/rp/src/bin/usb_hid_keyboard.rs
@@ -0,0 +1,188 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use core::sync::atomic::{AtomicBool, Ordering};
6
7use defmt::*;
8use embassy_executor::Spawner;
9use embassy_futures::join::join;
10use embassy_rp::bind_interrupts;
11use embassy_rp::gpio::{Input, Pull};
12use embassy_rp::peripherals::USB;
13use embassy_rp::usb::{Driver, InterruptHandler};
14use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State};
15use embassy_usb::control::OutResponse;
16use embassy_usb::{Builder, Config, Handler};
17use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
18use {defmt_rtt as _, panic_probe as _};
19
20bind_interrupts!(struct Irqs {
21 USBCTRL_IRQ => InterruptHandler<USB>;
22});
23
24#[embassy_executor::main]
25async fn main(_spawner: Spawner) {
26 let p = embassy_rp::init(Default::default());
27 // Create the driver, from the HAL.
28 let driver = Driver::new(p.USB, Irqs);
29
30 // Create embassy-usb Config
31 let mut config = Config::new(0xc0de, 0xcafe);
32 config.manufacturer = Some("Embassy");
33 config.product = Some("HID keyboard example");
34 config.serial_number = Some("12345678");
35 config.max_power = 100;
36 config.max_packet_size_0 = 64;
37
38 // Create embassy-usb DeviceBuilder using the driver and config.
39 // It needs some buffers for building the descriptors.
40 let mut device_descriptor = [0; 256];
41 let mut config_descriptor = [0; 256];
42 let mut bos_descriptor = [0; 256];
43 // You can also add a Microsoft OS descriptor.
44 // let mut msos_descriptor = [0; 256];
45 let mut control_buf = [0; 64];
46 let request_handler = MyRequestHandler {};
47 let mut device_handler = MyDeviceHandler::new();
48
49 let mut state = State::new();
50
51 let mut builder = Builder::new(
52 driver,
53 config,
54 &mut device_descriptor,
55 &mut config_descriptor,
56 &mut bos_descriptor,
57 // &mut msos_descriptor,
58 &mut control_buf,
59 );
60
61 builder.handler(&mut device_handler);
62
63 // Create classes on the builder.
64 let config = embassy_usb::class::hid::Config {
65 report_descriptor: KeyboardReport::desc(),
66 request_handler: Some(&request_handler),
67 poll_ms: 60,
68 max_packet_size: 64,
69 };
70 let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
71
72 // Build the builder.
73 let mut usb = builder.build();
74
75 // Run the USB device.
76 let usb_fut = usb.run();
77
78 // Set up the signal pin that will be used to trigger the keyboard.
79 let mut signal_pin = Input::new(p.PIN_16, Pull::None);
80
81 let (reader, mut writer) = hid.split();
82
83 // Do stuff with the class!
84 let in_fut = async {
85 loop {
86 info!("Waiting for HIGH on pin 16");
87 signal_pin.wait_for_high().await;
88 info!("HIGH DETECTED");
89 // Create a report with the A key pressed. (no shift modifier)
90 let report = KeyboardReport {
91 keycodes: [4, 0, 0, 0, 0, 0],
92 leds: 0,
93 modifier: 0,
94 reserved: 0,
95 };
96 // Send the report.
97 match writer.write_serialize(&report).await {
98 Ok(()) => {}
99 Err(e) => warn!("Failed to send report: {:?}", e),
100 };
101 signal_pin.wait_for_low().await;
102 info!("LOW DETECTED");
103 let report = KeyboardReport {
104 keycodes: [0, 0, 0, 0, 0, 0],
105 leds: 0,
106 modifier: 0,
107 reserved: 0,
108 };
109 match writer.write_serialize(&report).await {
110 Ok(()) => {}
111 Err(e) => warn!("Failed to send report: {:?}", e),
112 };
113 }
114 };
115
116 let out_fut = async {
117 reader.run(false, &request_handler).await;
118 };
119
120 // Run everything concurrently.
121 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
122 join(usb_fut, join(in_fut, out_fut)).await;
123}
124
125struct MyRequestHandler {}
126
127impl RequestHandler for MyRequestHandler {
128 fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> {
129 info!("Get report for {:?}", id);
130 None
131 }
132
133 fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse {
134 info!("Set report for {:?}: {=[u8]}", id, data);
135 OutResponse::Accepted
136 }
137
138 fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) {
139 info!("Set idle rate for {:?} to {:?}", id, dur);
140 }
141
142 fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> {
143 info!("Get idle rate for {:?}", id);
144 None
145 }
146}
147
148struct MyDeviceHandler {
149 configured: AtomicBool,
150}
151
152impl MyDeviceHandler {
153 fn new() -> Self {
154 MyDeviceHandler {
155 configured: AtomicBool::new(false),
156 }
157 }
158}
159
160impl Handler for MyDeviceHandler {
161 fn enabled(&mut self, enabled: bool) {
162 self.configured.store(false, Ordering::Relaxed);
163 if enabled {
164 info!("Device enabled");
165 } else {
166 info!("Device disabled");
167 }
168 }
169
170 fn reset(&mut self) {
171 self.configured.store(false, Ordering::Relaxed);
172 info!("Bus reset, the Vbus current limit is 100mA");
173 }
174
175 fn addressed(&mut self, addr: u8) {
176 self.configured.store(false, Ordering::Relaxed);
177 info!("USB address set to: {}", addr);
178 }
179
180 fn configured(&mut self, configured: bool) {
181 self.configured.store(configured, Ordering::Relaxed);
182 if configured {
183 info!("Device configured, it may now draw up to the configured current limit from Vbus.")
184 } else {
185 info!("Device is no longer configured, the Vbus current limit is 100mA.");
186 }
187 }
188}
diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs
index e4d81997e..bc71e29aa 100644
--- a/examples/stm32wb/src/bin/mac_ffd.rs
+++ b/examples/stm32wb/src/bin/mac_ffd.rs
@@ -67,11 +67,16 @@ async fn main(spawner: Spawner) {
67 67
68 info!("resetting"); 68 info!("resetting");
69 mbox.mac_subsystem 69 mbox.mac_subsystem
70 .send_command(&ResetRequest { set_default_pib: true }) 70 .send_command(&ResetRequest {
71 set_default_pib: true,
72 ..Default::default()
73 })
71 .await 74 .await
72 .unwrap(); 75 .unwrap();
73 let evt = mbox.mac_subsystem.read().await; 76 {
74 defmt::info!("{:#x}", evt); 77 let evt = mbox.mac_subsystem.read().await;
78 defmt::info!("{:#x}", evt.mac_event());
79 }
75 80
76 info!("setting extended address"); 81 info!("setting extended address");
77 let extended_address: u64 = 0xACDE480000000001; 82 let extended_address: u64 = 0xACDE480000000001;
@@ -82,8 +87,10 @@ async fn main(spawner: Spawner) {
82 }) 87 })
83 .await 88 .await
84 .unwrap(); 89 .unwrap();
85 let evt = mbox.mac_subsystem.read().await; 90 {
86 defmt::info!("{:#x}", evt); 91 let evt = mbox.mac_subsystem.read().await;
92 defmt::info!("{:#x}", evt.mac_event());
93 }
87 94
88 info!("setting short address"); 95 info!("setting short address");
89 let short_address: u16 = 0x1122; 96 let short_address: u16 = 0x1122;
@@ -94,8 +101,10 @@ async fn main(spawner: Spawner) {
94 }) 101 })
95 .await 102 .await
96 .unwrap(); 103 .unwrap();
97 let evt = mbox.mac_subsystem.read().await; 104 {
98 defmt::info!("{:#x}", evt); 105 let evt = mbox.mac_subsystem.read().await;
106 defmt::info!("{:#x}", evt.mac_event());
107 }
99 108
100 info!("setting association permit"); 109 info!("setting association permit");
101 let association_permit: bool = true; 110 let association_permit: bool = true;
@@ -106,8 +115,10 @@ async fn main(spawner: Spawner) {
106 }) 115 })
107 .await 116 .await
108 .unwrap(); 117 .unwrap();
109 let evt = mbox.mac_subsystem.read().await; 118 {
110 defmt::info!("{:#x}", evt); 119 let evt = mbox.mac_subsystem.read().await;
120 defmt::info!("{:#x}", evt.mac_event());
121 }
111 122
112 info!("setting TX power"); 123 info!("setting TX power");
113 let transmit_power: i8 = 2; 124 let transmit_power: i8 = 2;
@@ -118,8 +129,10 @@ async fn main(spawner: Spawner) {
118 }) 129 })
119 .await 130 .await
120 .unwrap(); 131 .unwrap();
121 let evt = mbox.mac_subsystem.read().await; 132 {
122 defmt::info!("{:#x}", evt); 133 let evt = mbox.mac_subsystem.read().await;
134 defmt::info!("{:#x}", evt.mac_event());
135 }
123 136
124 info!("starting FFD device"); 137 info!("starting FFD device");
125 mbox.mac_subsystem 138 mbox.mac_subsystem
@@ -134,8 +147,10 @@ async fn main(spawner: Spawner) {
134 }) 147 })
135 .await 148 .await
136 .unwrap(); 149 .unwrap();
137 let evt = mbox.mac_subsystem.read().await; 150 {
138 defmt::info!("{:#x}", evt); 151 let evt = mbox.mac_subsystem.read().await;
152 defmt::info!("{:#x}", evt.mac_event());
153 }
139 154
140 info!("setting RX on when idle"); 155 info!("setting RX on when idle");
141 let rx_on_while_idle: bool = true; 156 let rx_on_while_idle: bool = true;
@@ -146,14 +161,17 @@ async fn main(spawner: Spawner) {
146 }) 161 })
147 .await 162 .await
148 .unwrap(); 163 .unwrap();
149 let evt = mbox.mac_subsystem.read().await; 164 {
150 defmt::info!("{:#x}", evt); 165 let evt = mbox.mac_subsystem.read().await;
166 defmt::info!("{:#x}", evt.mac_event());
167 }
151 168
152 loop { 169 loop {
153 let evt = mbox.mac_subsystem.read().await; 170 let evt = mbox.mac_subsystem.read().await;
154 defmt::info!("{:#x}", evt); 171 if let Ok(evt) = evt.mac_event() {
172 defmt::info!("parsed mac event");
173 defmt::info!("{:#x}", evt);
155 174
156 if let Ok(evt) = evt {
157 match evt { 175 match evt {
158 MacEvent::MlmeAssociateInd(association) => mbox 176 MacEvent::MlmeAssociateInd(association) => mbox
159 .mac_subsystem 177 .mac_subsystem
@@ -167,17 +185,22 @@ async fn main(spawner: Spawner) {
167 .await 185 .await
168 .unwrap(), 186 .unwrap(),
169 MacEvent::McpsDataInd(data_ind) => { 187 MacEvent::McpsDataInd(data_ind) => {
170 let data_addr = data_ind.msdu_ptr; 188 let payload = data_ind.payload();
171 let mut data = [0u8; 256]; 189 let ref_payload = b"Hello from embassy!";
172 unsafe { data_addr.copy_to(&mut data as *mut _, data_ind.msdu_length as usize) } 190 info!("{}", payload);
173 info!("{}", data[..data_ind.msdu_length as usize]);
174 191
175 if &data[..data_ind.msdu_length as usize] == b"Hello from embassy!" { 192 if payload == ref_payload {
176 info!("success"); 193 info!("success");
194 } else {
195 info!("ref payload: {}", ref_payload);
177 } 196 }
178 } 197 }
179 _ => {} 198 _ => {
199 defmt::info!("other mac event");
200 }
180 } 201 }
202 } else {
203 defmt::info!("failed to parse mac event");
181 } 204 }
182 } 205 }
183} 206}
diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs
index b2dac72cc..7cb401d89 100644
--- a/examples/stm32wb/src/bin/mac_rfd.rs
+++ b/examples/stm32wb/src/bin/mac_rfd.rs
@@ -69,11 +69,16 @@ async fn main(spawner: Spawner) {
69 69
70 info!("resetting"); 70 info!("resetting");
71 mbox.mac_subsystem 71 mbox.mac_subsystem
72 .send_command(&ResetRequest { set_default_pib: true }) 72 .send_command(&ResetRequest {
73 set_default_pib: true,
74 ..Default::default()
75 })
73 .await 76 .await
74 .unwrap(); 77 .unwrap();
75 let evt = mbox.mac_subsystem.read().await; 78 {
76 info!("{:#x}", evt); 79 let evt = mbox.mac_subsystem.read().await;
80 defmt::info!("{:#x}", evt.mac_event());
81 }
77 82
78 info!("setting extended address"); 83 info!("setting extended address");
79 let extended_address: u64 = 0xACDE480000000002; 84 let extended_address: u64 = 0xACDE480000000002;
@@ -84,24 +89,30 @@ async fn main(spawner: Spawner) {
84 }) 89 })
85 .await 90 .await
86 .unwrap(); 91 .unwrap();
87 let evt = mbox.mac_subsystem.read().await; 92 {
88 info!("{:#x}", evt); 93 let evt = mbox.mac_subsystem.read().await;
94 defmt::info!("{:#x}", evt.mac_event());
95 }
89 96
90 info!("getting extended address"); 97 info!("getting extended address");
91 mbox.mac_subsystem 98 mbox.mac_subsystem
92 .send_command(&GetRequest { 99 .send_command(&GetRequest {
93 pib_attribute: PibId::ExtendedAddress, 100 pib_attribute: PibId::ExtendedAddress,
101 ..Default::default()
94 }) 102 })
95 .await 103 .await
96 .unwrap(); 104 .unwrap();
97 let evt = mbox.mac_subsystem.read().await;
98 info!("{:#x}", evt);
99 105
100 if let Ok(MacEvent::MlmeGetCnf(evt)) = evt { 106 {
101 if evt.pib_attribute_value_len == 8 { 107 let evt = mbox.mac_subsystem.read().await;
102 let value = unsafe { core::ptr::read_unaligned(evt.pib_attribute_value_ptr as *const u64) }; 108 info!("{:#x}", evt.mac_event());
109
110 if let Ok(MacEvent::MlmeGetCnf(evt)) = evt.mac_event() {
111 if evt.pib_attribute_value_len == 8 {
112 let value = unsafe { core::ptr::read_unaligned(evt.pib_attribute_value_ptr as *const u64) };
103 113
104 info!("value {:#x}", value) 114 info!("value {:#x}", value)
115 }
105 } 116 }
106 } 117 }
107 118
@@ -120,13 +131,15 @@ async fn main(spawner: Spawner) {
120 }; 131 };
121 info!("{}", a); 132 info!("{}", a);
122 mbox.mac_subsystem.send_command(&a).await.unwrap(); 133 mbox.mac_subsystem.send_command(&a).await.unwrap();
123 let evt = mbox.mac_subsystem.read().await; 134 let short_addr = {
124 info!("{:#x}", evt); 135 let evt = mbox.mac_subsystem.read().await;
136 info!("{:#x}", evt.mac_event());
125 137
126 let short_addr = if let Ok(MacEvent::MlmeAssociateCnf(conf)) = evt { 138 if let Ok(MacEvent::MlmeAssociateCnf(conf)) = evt.mac_event() {
127 conf.assoc_short_address 139 conf.assoc_short_address
128 } else { 140 } else {
129 defmt::panic!() 141 defmt::panic!()
142 }
130 }; 143 };
131 144
132 info!("setting short address"); 145 info!("setting short address");
@@ -137,34 +150,37 @@ async fn main(spawner: Spawner) {
137 }) 150 })
138 .await 151 .await
139 .unwrap(); 152 .unwrap();
140 let evt = mbox.mac_subsystem.read().await; 153 {
141 info!("{:#x}", evt); 154 let evt = mbox.mac_subsystem.read().await;
155 info!("{:#x}", evt.mac_event());
156 }
142 157
143 info!("sending data"); 158 info!("sending data");
144 let mut data_buffer = [0u8; 256];
145 let data = b"Hello from embassy!"; 159 let data = b"Hello from embassy!";
146 data_buffer[..data.len()].copy_from_slice(data);
147 mbox.mac_subsystem 160 mbox.mac_subsystem
148 .send_command(&DataRequest { 161 .send_command(
149 src_addr_mode: AddressMode::Short, 162 DataRequest {
150 dst_addr_mode: AddressMode::Short, 163 src_addr_mode: AddressMode::Short,
151 dst_pan_id: PanId([0x1A, 0xAA]), 164 dst_addr_mode: AddressMode::Short,
152 dst_address: MacAddress::BROADCAST, 165 dst_pan_id: PanId([0x1A, 0xAA]),
153 msdu_handle: 0x02, 166 dst_address: MacAddress::BROADCAST,
154 ack_tx: 0x00, 167 msdu_handle: 0x02,
155 gts_tx: false, 168 ack_tx: 0x00,
156 msdu_ptr: &data_buffer as *const _ as *const u8, 169 gts_tx: false,
157 msdu_length: data.len() as u8, 170 security_level: SecurityLevel::Unsecure,
158 security_level: SecurityLevel::Unsecure, 171 ..Default::default()
159 ..Default::default() 172 }
160 }) 173 .set_buffer(data),
174 )
161 .await 175 .await
162 .unwrap(); 176 .unwrap();
163 let evt = mbox.mac_subsystem.read().await; 177 {
164 info!("{:#x}", evt); 178 let evt = mbox.mac_subsystem.read().await;
179 info!("{:#x}", evt.mac_event());
180 }
165 181
166 loop { 182 loop {
167 let evt = mbox.mac_subsystem.read().await; 183 let evt = mbox.mac_subsystem.read().await;
168 info!("{:#x}", evt); 184 info!("{:#x}", evt.mac_event());
169 } 185 }
170} 186}
diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs
index cfa0aca3b..d64a5ef81 100644
--- a/tests/stm32/src/bin/wpan_mac.rs
+++ b/tests/stm32/src/bin/wpan_mac.rs
@@ -49,11 +49,16 @@ async fn main(spawner: Spawner) {
49 49
50 info!("resetting"); 50 info!("resetting");
51 mbox.mac_subsystem 51 mbox.mac_subsystem
52 .send_command(&ResetRequest { set_default_pib: true }) 52 .send_command(&ResetRequest {
53 set_default_pib: true,
54 ..Default::default()
55 })
53 .await 56 .await
54 .unwrap(); 57 .unwrap();
55 let evt = mbox.mac_subsystem.read().await; 58 {
56 info!("{:#x}", evt); 59 let evt = mbox.mac_subsystem.read().await;
60 info!("{:#x}", evt.mac_event());
61 }
57 62
58 info!("setting extended address"); 63 info!("setting extended address");
59 let extended_address: u64 = 0xACDE480000000002; 64 let extended_address: u64 = 0xACDE480000000002;
@@ -64,24 +69,29 @@ async fn main(spawner: Spawner) {
64 }) 69 })
65 .await 70 .await
66 .unwrap(); 71 .unwrap();
67 let evt = mbox.mac_subsystem.read().await; 72 {
68 info!("{:#x}", evt); 73 let evt = mbox.mac_subsystem.read().await;
74 info!("{:#x}", evt.mac_event());
75 }
69 76
70 info!("getting extended address"); 77 info!("getting extended address");
71 mbox.mac_subsystem 78 mbox.mac_subsystem
72 .send_command(&GetRequest { 79 .send_command(&GetRequest {
73 pib_attribute: PibId::ExtendedAddress, 80 pib_attribute: PibId::ExtendedAddress,
81 ..Default::default()
74 }) 82 })
75 .await 83 .await
76 .unwrap(); 84 .unwrap();
77 let evt = mbox.mac_subsystem.read().await; 85 {
78 info!("{:#x}", evt); 86 let evt = mbox.mac_subsystem.read().await;
87 info!("{:#x}", evt.mac_event());
79 88
80 if let Ok(MacEvent::MlmeGetCnf(evt)) = evt { 89 if let Ok(MacEvent::MlmeGetCnf(evt)) = evt.mac_event() {
81 if evt.pib_attribute_value_len == 8 { 90 if evt.pib_attribute_value_len == 8 {
82 let value = unsafe { core::ptr::read_unaligned(evt.pib_attribute_value_ptr as *const u64) }; 91 let value = unsafe { core::ptr::read_unaligned(evt.pib_attribute_value_ptr as *const u64) };
83 92
84 info!("value {:#x}", value) 93 info!("value {:#x}", value)
94 }
85 } 95 }
86 } 96 }
87 97
@@ -100,8 +110,10 @@ async fn main(spawner: Spawner) {
100 }; 110 };
101 info!("{}", a); 111 info!("{}", a);
102 mbox.mac_subsystem.send_command(&a).await.unwrap(); 112 mbox.mac_subsystem.send_command(&a).await.unwrap();
103 let evt = mbox.mac_subsystem.read().await; 113 {
104 info!("{:#x}", evt); 114 let evt = mbox.mac_subsystem.read().await;
115 info!("{:#x}", evt.mac_event());
116 }
105 117
106 info!("Test OK"); 118 info!("Test OK");
107 cortex_m::asm::bkpt(); 119 cortex_m::asm::bkpt();