aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgoueslati <[email protected]>2023-07-12 15:06:56 +0100
committergoueslati <[email protected]>2023-07-12 15:06:56 +0100
commitd5a4457b5e3a95a12f249315fb1d9b6a577307f2 (patch)
tree6f0b4c98653ce287b483a14dc2a031b2ee6de638
parentfbddfcbfb7f732db593eecd5383742d9ce7308e7 (diff)
parsing MAC structs
-rw-r--r--embassy-stm32-wpan/Cargo.toml7
-rw-r--r--embassy-stm32-wpan/src/sub/mac/commands.rs55
-rw-r--r--embassy-stm32-wpan/src/sub/mac/event.rs94
-rw-r--r--embassy-stm32-wpan/src/sub/mac/helpers.rs7
-rw-r--r--embassy-stm32-wpan/src/sub/mac/indications.rs295
-rw-r--r--embassy-stm32-wpan/src/sub/mac/macros.rs32
-rw-r--r--embassy-stm32-wpan/src/sub/mac/mod.rs63
-rw-r--r--embassy-stm32-wpan/src/sub/mac/opcodes.rs63
-rw-r--r--embassy-stm32-wpan/src/sub/mac/responses.rs302
-rw-r--r--embassy-stm32-wpan/src/sub/mac/typedefs.rs357
-rw-r--r--examples/stm32wb/src/bin/mac_ffd.rs101
-rw-r--r--examples/stm32wb/src/bin/mac_rfd.rs14
12 files changed, 1107 insertions, 283 deletions
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml
index 4b5dcdd29..1325faed9 100644
--- a/embassy-stm32-wpan/Cargo.toml
+++ b/embassy-stm32-wpan/Cargo.toml
@@ -26,13 +26,14 @@ aligned = "0.4.1"
26bit_field = "0.10.2" 26bit_field = "0.10.2"
27stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } 27stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] }
28stm32wb-hci = { version = "0.1.2", features = ["version-5-0"], optional = true } 28stm32wb-hci = { version = "0.1.2", features = ["version-5-0"], optional = true }
29bitflags = { version = "2.3.3", optional = true }
29 30
30[features] 31[features]
31default = ["stm32wb55rg", "mac", "ble"] 32default = ["stm32wb55rg", "mac", "ble", "defmt"]
32defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"] 33defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"]
33 34
34ble = ["dep:stm32wb-hci"] 35ble = ["dep:stm32wb-hci"]
35mac = [] 36mac = ["dep:bitflags"]
36 37
37stm32wb10cc = [ "embassy-stm32/stm32wb10cc" ] 38stm32wb10cc = [ "embassy-stm32/stm32wb10cc" ]
38stm32wb15cc = [ "embassy-stm32/stm32wb15cc" ] 39stm32wb15cc = [ "embassy-stm32/stm32wb15cc" ]
@@ -49,4 +50,4 @@ stm32wb55rg = [ "embassy-stm32/stm32wb55rg" ]
49stm32wb55vc = [ "embassy-stm32/stm32wb55vc" ] 50stm32wb55vc = [ "embassy-stm32/stm32wb55vc" ]
50stm32wb55ve = [ "embassy-stm32/stm32wb55ve" ] 51stm32wb55ve = [ "embassy-stm32/stm32wb55ve" ]
51stm32wb55vg = [ "embassy-stm32/stm32wb55vg" ] 52stm32wb55vg = [ "embassy-stm32/stm32wb55vg" ]
52stm32wb55vy = [ "embassy-stm32/stm32wb55vy" ] \ No newline at end of file 53stm32wb55vy = [ "embassy-stm32/stm32wb55vy" ]
diff --git a/embassy-stm32-wpan/src/sub/mac/commands.rs b/embassy-stm32-wpan/src/sub/mac/commands.rs
index 4965a46eb..d8a4e3ee1 100644
--- a/embassy-stm32-wpan/src/sub/mac/commands.rs
+++ b/embassy-stm32-wpan/src/sub/mac/commands.rs
@@ -1,5 +1,8 @@
1use super::opcodes::OpcodeM4ToM0; 1use super::opcodes::OpcodeM4ToM0;
2use super::typedefs::{AddressMode, GtsCharacteristics, MacAddress, PibId}; 2use super::typedefs::{
3 AddressMode, Capabilities, DisassociationReason, GtsCharacteristics, KeyIdMode, MacAddress, MacChannel, PibId,
4 ScanType, SecurityLevel,
5};
3 6
4pub trait MacCommand { 7pub trait MacCommand {
5 const OPCODE: OpcodeM4ToM0; 8 const OPCODE: OpcodeM4ToM0;
@@ -14,19 +17,19 @@ pub trait MacCommand {
14#[repr(C)] 17#[repr(C)]
15pub struct AssociateRequest { 18pub struct AssociateRequest {
16 /// the logical channel on which to attempt association 19 /// the logical channel on which to attempt association
17 pub channel_number: u8, 20 pub channel_number: MacChannel,
18 /// the channel page on which to attempt association 21 /// the channel page on which to attempt association
19 pub channel_page: u8, 22 pub channel_page: u8,
20 /// coordinator addressing mode 23 /// coordinator addressing mode
21 pub coord_addr_mode: AddressMode, 24 pub coord_addr_mode: AddressMode,
22 /// operational capabilities of the associating device 25 /// operational capabilities of the associating device
23 pub capability_information: u8, 26 pub capability_information: Capabilities,
24 /// the identifier of the PAN with which to associate 27 /// the identifier of the PAN with which to associate
25 pub coord_pan_id: [u8; 2], 28 pub coord_pan_id: [u8; 2],
26 /// the security level to be used 29 /// the security level to be used
27 pub security_level: u8, 30 pub security_level: SecurityLevel,
28 /// the mode used to identify the key to be used 31 /// the mode used to identify the key to be used
29 pub key_id_mode: u8, 32 pub key_id_mode: KeyIdMode,
30 /// the originator of the key to be used 33 /// the originator of the key to be used
31 pub key_source: [u8; 8], 34 pub key_source: [u8; 8],
32 /// Coordinator address 35 /// Coordinator address
@@ -48,15 +51,15 @@ pub struct DisassociateRequest {
48 /// the identifier of the PAN of the device 51 /// the identifier of the PAN of the device
49 pub device_pan_id: [u8; 2], 52 pub device_pan_id: [u8; 2],
50 /// the reason for the disassociation 53 /// the reason for the disassociation
51 pub disassociate_reason: u8, 54 pub disassociation_reason: DisassociationReason,
52 /// device address 55 /// device address
53 pub device_address: MacAddress, 56 pub device_address: MacAddress,
54 /// `true` if the disassociation notification command is to be sent indirectly 57 /// `true` if the disassociation notification command is to be sent indirectly
55 pub tx_indirect: bool, 58 pub tx_indirect: bool,
56 /// the security level to be used 59 /// the security level to be used
57 pub security_level: u8, 60 pub security_level: SecurityLevel,
58 /// the mode to be used to indetify the key to be used 61 /// the mode to be used to indetify the key to be used
59 pub key_id_mode: u8, 62 pub key_id_mode: KeyIdMode,
60 /// the index of the key to be used 63 /// the index of the key to be used
61 pub key_index: u8, 64 pub key_index: u8,
62 /// the originator of the key to be used 65 /// the originator of the key to be used
@@ -86,9 +89,9 @@ pub struct GtsRequest {
86 /// the characteristics of the GTS 89 /// the characteristics of the GTS
87 pub characteristics: GtsCharacteristics, 90 pub characteristics: GtsCharacteristics,
88 /// the security level to be used 91 /// the security level to be used
89 pub security_level: u8, 92 pub security_level: SecurityLevel,
90 /// the mode used to identify the key to be used 93 /// the mode used to identify the key to be used
91 pub key_id_mode: u8, 94 pub key_id_mode: KeyIdMode,
92 /// the index of the key to be used 95 /// the index of the key to be used
93 pub key_index: u8, 96 pub key_index: u8,
94 /// the originator of the key to be used 97 /// the originator of the key to be used
@@ -147,19 +150,19 @@ impl MacCommand for RxEnableRequest {
147#[repr(C)] 150#[repr(C)]
148pub struct ScanRequest { 151pub struct ScanRequest {
149 /// the type of scan to be performed 152 /// the type of scan to be performed
150 pub scan_type: u8, 153 pub scan_type: ScanType,
151 /// the time spent on scanning each channel 154 /// the time spent on scanning each channel
152 pub scan_duration: u8, 155 pub scan_duration: u8,
153 /// channel page on which to perform the scan 156 /// channel page on which to perform the scan
154 pub channel_page: u8, 157 pub channel_page: u8,
155 /// security level to be used 158 /// security level to be used
156 pub security_level: u8, 159 pub security_level: SecurityLevel,
157 /// indicate which channels are to be scanned 160 /// indicate which channels are to be scanned
158 pub scan_channels: [u8; 4], 161 pub scan_channels: [u8; 4],
159 /// originator the key to be used 162 /// originator the key to be used
160 pub key_source: [u8; 8], 163 pub key_source: [u8; 8],
161 /// mode used to identify the key to be used 164 /// mode used to identify the key to be used
162 pub key_id_mode: u8, 165 pub key_id_mode: KeyIdMode,
163 /// index of the key to be used 166 /// index of the key to be used
164 pub key_index: u8, 167 pub key_index: u8,
165} 168}
@@ -191,7 +194,7 @@ pub struct StartRequest {
191 /// PAN indentifier to used by the device 194 /// PAN indentifier to used by the device
192 pub pan_id: [u8; 2], 195 pub pan_id: [u8; 2],
193 /// logical channel on which to begin 196 /// logical channel on which to begin
194 pub channel_number: u8, 197 pub channel_number: MacChannel,
195 /// channel page on which to begin 198 /// channel page on which to begin
196 pub channel_page: u8, 199 pub channel_page: u8,
197 /// time at which to begin transmitting beacons 200 /// time at which to begin transmitting beacons
@@ -207,15 +210,15 @@ pub struct StartRequest {
207 /// indicated if the coordinator realignment command is to be trasmitted 210 /// indicated if the coordinator realignment command is to be trasmitted
208 pub coord_realignment: u8, 211 pub coord_realignment: u8,
209 /// indicated if the coordinator realignment command is to be trasmitted 212 /// indicated if the coordinator realignment command is to be trasmitted
210 pub coord_realign_security_level: u8, 213 pub coord_realign_security_level: SecurityLevel,
211 /// index of the key to be used 214 /// index of the key to be used
212 pub coord_realign_key_id_index: u8, 215 pub coord_realign_key_id_index: u8,
213 /// originator of the key to be used 216 /// originator of the key to be used
214 pub coord_realign_key_source: [u8; 8], 217 pub coord_realign_key_source: [u8; 8],
215 /// security level to be used for beacon frames 218 /// security level to be used for beacon frames
216 pub beacon_security_level: u8, 219 pub beacon_security_level: SecurityLevel,
217 /// mode used to identify the key to be used 220 /// mode used to identify the key to be used
218 pub beacon_key_id_mode: u8, 221 pub beacon_key_id_mode: KeyIdMode,
219 /// index of the key to be used 222 /// index of the key to be used
220 pub beacon_key_index: u8, 223 pub beacon_key_index: u8,
221 /// originator of the key to be used 224 /// originator of the key to be used
@@ -232,7 +235,7 @@ impl MacCommand for StartRequest {
232#[repr(C)] 235#[repr(C)]
233pub struct SyncRequest { 236pub struct SyncRequest {
234 /// the channel number on which to attempt coordinator synchronization 237 /// the channel number on which to attempt coordinator synchronization
235 pub channel_number: u8, 238 pub channel_number: MacChannel,
236 /// the channel page on which to attempt coordinator synchronization 239 /// the channel page on which to attempt coordinator synchronization
237 pub channel_page: u8, 240 pub channel_page: u8,
238 /// `true` if the MLME is to synchronize with the next beacon and attempts 241 /// `true` if the MLME is to synchronize with the next beacon and attempts
@@ -253,9 +256,9 @@ pub struct PollRequest {
253 /// addressing mode of the coordinator 256 /// addressing mode of the coordinator
254 pub coord_addr_mode: AddressMode, 257 pub coord_addr_mode: AddressMode,
255 /// security level to be used 258 /// security level to be used
256 pub security_level: u8, 259 pub security_level: SecurityLevel,
257 /// mode used to identify the key to be used 260 /// mode used to identify the key to be used
258 pub key_id_mode: u8, 261 pub key_id_mode: KeyIdMode,
259 /// index of the key to be used 262 /// index of the key to be used
260 pub key_index: u8, 263 pub key_index: u8,
261 /// coordinator address 264 /// coordinator address
@@ -335,9 +338,9 @@ pub struct DataRequest {
335 /// the pending bit transmission options for the MSDU 338 /// the pending bit transmission options for the MSDU
336 pub indirect_tx: u8, 339 pub indirect_tx: u8,
337 /// the security level to be used 340 /// the security level to be used
338 pub security_level: u8, 341 pub security_level: SecurityLevel,
339 /// the mode used to indentify the key to be used 342 /// the mode used to indentify the key to be used
340 pub key_id_mode: u8, 343 pub key_id_mode: KeyIdMode,
341 /// the index of the key to be used 344 /// the index of the key to be used
342 pub key_index: u8, 345 pub key_index: u8,
343 /// the originator of the key to be used 346 /// the originator of the key to be used
@@ -381,11 +384,11 @@ pub struct AssociateResponse {
381 /// status of the association attempt 384 /// status of the association attempt
382 pub status: u8, 385 pub status: u8,
383 /// security level to be used 386 /// security level to be used
384 pub security_level: u8, 387 pub security_level: SecurityLevel,
385 /// the originator of the key to be used 388 /// the originator of the key to be used
386 pub key_source: [u8; 8], 389 pub key_source: [u8; 8],
387 /// the mode used to identify the key to be used 390 /// the mode used to identify the key to be used
388 pub key_id_mode: u8, 391 pub key_id_mode: KeyIdMode,
389 /// the index of the key to be used 392 /// the index of the key to be used
390 pub key_index: u8, 393 pub key_index: u8,
391} 394}
@@ -405,11 +408,11 @@ pub struct OrphanResponse {
405 /// if the orphaned device is associated with coordinator or not 408 /// if the orphaned device is associated with coordinator or not
406 pub associated_member: bool, 409 pub associated_member: bool,
407 /// security level to be used 410 /// security level to be used
408 pub security_level: u8, 411 pub security_level: SecurityLevel,
409 /// the originator of the key to be used 412 /// the originator of the key to be used
410 pub key_source: [u8; 8], 413 pub key_source: [u8; 8],
411 /// the mode used to identify the key to be used 414 /// the mode used to identify the key to be used
412 pub key_id_mode: u8, 415 pub key_id_mode: KeyIdMode,
413 /// the index of the key to be used 416 /// the index of the key to be used
414 pub key_index: u8, 417 pub key_index: u8,
415} 418}
diff --git a/embassy-stm32-wpan/src/sub/mac/event.rs b/embassy-stm32-wpan/src/sub/mac/event.rs
new file mode 100644
index 000000000..aaf965565
--- /dev/null
+++ b/embassy-stm32-wpan/src/sub/mac/event.rs
@@ -0,0 +1,94 @@
1use super::helpers::to_u16;
2use super::indications::{
3 AssociateIndication, BeaconNotifyIndication, CommStatusIndication, DataIndication, DisassociateIndication,
4 DpsIndication, GtsIndication, OrphanIndication, PollIndication, SyncLossIndication,
5};
6use super::responses::{
7 AssociateConfirm, CalibrateConfirm, DataConfirm, DisassociateConfirm, DpsConfirm, GetConfirm, GtsConfirm,
8 PollConfirm, PurgeConfirm, ResetConfirm, RxEnableConfirm, ScanConfirm, SetConfirm, SoundingConfirm, StartConfirm,
9};
10use crate::sub::mac::opcodes::OpcodeM0ToM4;
11
12pub trait ParseableMacEvent {
13 const SIZE: usize;
14
15 fn validate(buf: &[u8]) -> Result<(), ()> {
16 if buf.len() < Self::SIZE {
17 return Err(());
18 }
19
20 Ok(())
21 }
22
23 fn try_parse(buf: &[u8]) -> Result<Self, ()>
24 where
25 Self: Sized;
26}
27
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub enum MacEvent {
30 MlmeAssociateCnf(AssociateConfirm),
31 MlmeDisassociateCnf(DisassociateConfirm),
32 MlmeGetCnf(GetConfirm),
33 MlmeGtsCnf(GtsConfirm),
34 MlmeResetCnf(ResetConfirm),
35 MlmeRxEnableCnf(RxEnableConfirm),
36 MlmeScanCnf(ScanConfirm),
37 MlmeSetCnf(SetConfirm),
38 MlmeStartCnf(StartConfirm),
39 MlmePollCnf(PollConfirm),
40 MlmeDpsCnf(DpsConfirm),
41 MlmeSoundingCnf(SoundingConfirm),
42 MlmeCalibrateCnf(CalibrateConfirm),
43 McpsDataCnf(DataConfirm),
44 McpsPurgeCnf(PurgeConfirm),
45 MlmeAssociateInd(AssociateIndication),
46 MlmeDisassociateInd(DisassociateIndication),
47 MlmeBeaconNotifyInd(BeaconNotifyIndication),
48 MlmeCommStatusInd(CommStatusIndication),
49 MlmeGtsInd(GtsIndication),
50 MlmeOrphanInd(OrphanIndication),
51 MlmeSyncLossInd(SyncLossIndication),
52 MlmeDpsInd(DpsIndication),
53 McpsDataInd(DataIndication),
54 MlmePollInd(PollIndication),
55}
56
57impl TryFrom<&[u8]> for MacEvent {
58 type Error = ();
59
60 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
61 let opcode = to_u16(&value[0..2]);
62 let opcode = OpcodeM0ToM4::try_from(opcode)?;
63
64 let buf = &value[2..];
65
66 match opcode {
67 OpcodeM0ToM4::MlmeAssociateCnf => Ok(Self::MlmeAssociateCnf(AssociateConfirm::try_parse(buf)?)),
68 OpcodeM0ToM4::MlmeDisassociateCnf => Ok(Self::MlmeDisassociateCnf(DisassociateConfirm::try_parse(buf)?)),
69 OpcodeM0ToM4::MlmeGetCnf => Ok(Self::MlmeGetCnf(GetConfirm::try_parse(buf)?)),
70 OpcodeM0ToM4::MlmeGtsCnf => Ok(Self::MlmeGtsCnf(GtsConfirm::try_parse(buf)?)),
71 OpcodeM0ToM4::MlmeResetCnf => Ok(Self::MlmeResetCnf(ResetConfirm::try_parse(buf)?)),
72 OpcodeM0ToM4::MlmeRxEnableCnf => Ok(Self::MlmeRxEnableCnf(RxEnableConfirm::try_parse(buf)?)),
73 OpcodeM0ToM4::MlmeScanCnf => Ok(Self::MlmeScanCnf(ScanConfirm::try_parse(buf)?)),
74 OpcodeM0ToM4::MlmeSetCnf => Ok(Self::MlmeSetCnf(SetConfirm::try_parse(buf)?)),
75 OpcodeM0ToM4::MlmeStartCnf => Ok(Self::MlmeStartCnf(StartConfirm::try_parse(buf)?)),
76 OpcodeM0ToM4::MlmePollCnf => Ok(Self::MlmePollCnf(PollConfirm::try_parse(buf)?)),
77 OpcodeM0ToM4::MlmeDpsCnf => Ok(Self::MlmeDpsCnf(DpsConfirm::try_parse(buf)?)),
78 OpcodeM0ToM4::MlmeSoundingCnf => Ok(Self::MlmeSoundingCnf(SoundingConfirm::try_parse(buf)?)),
79 OpcodeM0ToM4::MlmeCalibrateCnf => Ok(Self::MlmeCalibrateCnf(CalibrateConfirm::try_parse(buf)?)),
80 OpcodeM0ToM4::McpsDataCnf => Ok(Self::McpsDataCnf(DataConfirm::try_parse(buf)?)),
81 OpcodeM0ToM4::McpsPurgeCnf => Ok(Self::McpsPurgeCnf(PurgeConfirm::try_parse(buf)?)),
82 OpcodeM0ToM4::MlmeAssociateInd => Ok(Self::MlmeAssociateInd(AssociateIndication::try_parse(buf)?)),
83 OpcodeM0ToM4::MlmeDisassociateInd => Ok(Self::MlmeDisassociateInd(DisassociateIndication::try_parse(buf)?)),
84 OpcodeM0ToM4::MlmeBeaconNotifyInd => Ok(Self::MlmeBeaconNotifyInd(BeaconNotifyIndication::try_parse(buf)?)),
85 OpcodeM0ToM4::MlmeCommStatusInd => Ok(Self::MlmeCommStatusInd(CommStatusIndication::try_parse(buf)?)),
86 OpcodeM0ToM4::MlmeGtsInd => Ok(Self::MlmeGtsInd(GtsIndication::try_parse(buf)?)),
87 OpcodeM0ToM4::MlmeOrphanInd => Ok(Self::MlmeOrphanInd(OrphanIndication::try_parse(buf)?)),
88 OpcodeM0ToM4::MlmeSyncLossInd => Ok(Self::MlmeSyncLossInd(SyncLossIndication::try_parse(buf)?)),
89 OpcodeM0ToM4::MlmeDpsInd => Ok(Self::MlmeDpsInd(DpsIndication::try_parse(buf)?)),
90 OpcodeM0ToM4::McpsDataInd => Ok(Self::McpsDataInd(DataIndication::try_parse(buf)?)),
91 OpcodeM0ToM4::MlmePollInd => Ok(Self::MlmePollInd(PollIndication::try_parse(buf)?)),
92 }
93 }
94}
diff --git a/embassy-stm32-wpan/src/sub/mac/helpers.rs b/embassy-stm32-wpan/src/sub/mac/helpers.rs
new file mode 100644
index 000000000..5a5bf8a85
--- /dev/null
+++ b/embassy-stm32-wpan/src/sub/mac/helpers.rs
@@ -0,0 +1,7 @@
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/sub/mac/indications.rs b/embassy-stm32-wpan/src/sub/mac/indications.rs
index ebca16f72..dc5ae4c44 100644
--- a/embassy-stm32-wpan/src/sub/mac/indications.rs
+++ b/embassy-stm32-wpan/src/sub/mac/indications.rs
@@ -1,45 +1,84 @@
1use super::consts::MAX_PENDING_ADDRESS; 1use super::consts::MAX_PENDING_ADDRESS;
2use super::typedefs::{AddressMode, MacAddress, PanDescriptor}; 2use super::event::ParseableMacEvent;
3use super::helpers::to_u32;
4use super::typedefs::{
5 AddressMode, Capabilities, DisassociationReason, KeyIdMode, MacAddress, MacChannel, MacStatus, PanDescriptor,
6 SecurityLevel,
7};
3 8
4/// MLME ASSOCIATE Indication which will be used by the MAC 9/// MLME ASSOCIATE Indication which will be used by the MAC
5/// to indicate the reception of an association request command 10/// to indicate the reception of an association request command
6#[repr(C)] 11#[cfg_attr(feature = "defmt", derive(defmt::Format))]
7pub struct AssociateIndication { 12pub struct AssociateIndication {
8 /// Extended address of the device requesting association 13 /// Extended address of the device requesting association
9 pub device_address: [u8; 8], 14 pub device_address: [u8; 8],
10 /// Operational capabilities of the device requesting association 15 /// Operational capabilities of the device requesting association
11 pub capability_information: u8, 16 pub capability_information: Capabilities,
12 /// Security level purportedly used by the received MAC command frame 17 /// Security level purportedly used by the received MAC command frame
13 pub security_level: u8, 18 pub security_level: SecurityLevel,
14 /// The mode used to identify the key used by the originator of frame 19 /// The mode used to identify the key used by the originator of frame
15 pub key_id_mode: u8, 20 pub key_id_mode: KeyIdMode,
16 /// Index of the key used by the originator of the received frame 21 /// Index of the key used by the originator of the received frame
17 pub key_index: u8, 22 pub key_index: u8,
18 /// The originator of the key used by the originator of the received frame 23 /// The originator of the key used by the originator of the received frame
19 pub key_source: [u8; 8], 24 pub key_source: [u8; 8],
20} 25}
21 26
27impl 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
22/// MLME DISASSOCIATE indication which will be used to send 44/// MLME DISASSOCIATE indication which will be used to send
23/// disassociation indication to the application. 45/// disassociation indication to the application.
24#[repr(C)] 46#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25pub struct DisassociateIndication { 47pub struct DisassociateIndication {
26 /// Extended address of the device requesting association 48 /// Extended address of the device requesting association
27 pub device_address: [u8; 8], 49 pub device_address: [u8; 8],
28 /// The reason for the disassociation 50 /// The reason for the disassociation
29 pub disassociate_reason: u8, 51 pub disassociation_reason: DisassociationReason,
30 /// The security level to be used 52 /// The security level to be used
31 pub security_level: u8, 53 pub security_level: SecurityLevel,
32 /// The mode used to identify the key to be used 54 /// The mode used to identify the key to be used
33 pub key_id_mode: u8, 55 pub key_id_mode: KeyIdMode,
34 /// The index of the key to be used 56 /// The index of the key to be used
35 pub key_index: u8, 57 pub key_index: u8,
36 /// The originator of the key to be used 58 /// The originator of the key to be used
37 pub key_source: [u8; 8], 59 pub key_source: [u8; 8],
38} 60}
39 61
62impl 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
40/// MLME BEACON NOTIIFY Indication which is used to send parameters contained 79/// MLME BEACON NOTIIFY Indication which is used to send parameters contained
41/// within a beacon frame received by the MAC to the application 80/// within a beacon frame received by the MAC to the application
42#[repr(C)] 81#[cfg_attr(feature = "defmt", derive(defmt::Format))]
43pub struct BeaconNotifyIndication { 82pub struct BeaconNotifyIndication {
44 /// he set of octets comprising the beacon payload to be transferred 83 /// he set of octets comprising the beacon payload to be transferred
45 /// from the MAC sublayer entity to the next higher layer 84 /// from the MAC sublayer entity to the next higher layer
@@ -56,8 +95,18 @@ pub struct BeaconNotifyIndication {
56 pub sdu_length: u8, 95 pub sdu_length: u8,
57} 96}
58 97
98impl ParseableMacEvent for BeaconNotifyIndication {
99 const SIZE: usize = 12;
100
101 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
102 Self::validate(buf)?;
103
104 todo!()
105 }
106}
107
59/// MLME COMM STATUS Indication which is used by the MAC to indicate a communications status 108/// MLME COMM STATUS Indication which is used by the MAC to indicate a communications status
60#[repr(C)] 109#[cfg_attr(feature = "defmt", derive(defmt::Format))]
61pub struct CommStatusIndication { 110pub struct CommStatusIndication {
62 /// The 16-bit PAN identifier of the device from which the frame 111 /// The 16-bit PAN identifier of the device from which the frame
63 /// was received or to which the frame was being sent 112 /// was received or to which the frame was being sent
@@ -71,83 +120,190 @@ pub struct CommStatusIndication {
71 /// Destination address 120 /// Destination address
72 pub dst_address: MacAddress, 121 pub dst_address: MacAddress,
73 /// The communications status 122 /// The communications status
74 pub status: u8, 123 pub status: MacStatus,
75 /// Security level to be used 124 /// Security level to be used
76 pub security_level: u8, 125 pub security_level: SecurityLevel,
77 /// Mode used to identify the key to be used 126 /// Mode used to identify the key to be used
78 pub key_id_mode: u8, 127 pub key_id_mode: KeyIdMode,
79 /// Index of the key to be used 128 /// Index of the key to be used
80 pub key_index: u8, 129 pub key_index: u8,
81 /// Originator of the key to be used 130 /// Originator of the key to be used
82 pub key_source: [u8; 8], 131 pub key_source: [u8; 8],
83} 132}
84 133
134impl ParseableMacEvent for CommStatusIndication {
135 const SIZE: usize = 32;
136
137 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
138 Self::validate(buf)?;
139
140 let src_addr_mode = AddressMode::try_from(buf[2])?;
141 let dst_addr_mode = AddressMode::try_from(buf[3])?;
142
143 let src_address = match src_addr_mode {
144 AddressMode::NoAddress => MacAddress::Short([0, 0]),
145 AddressMode::Reserved => MacAddress::Short([0, 0]),
146 AddressMode::Short => MacAddress::Short([buf[4], buf[5]]),
147 AddressMode::Extended => {
148 MacAddress::Extended([buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]])
149 }
150 };
151
152 let dst_address = match dst_addr_mode {
153 AddressMode::NoAddress => MacAddress::Short([0, 0]),
154 AddressMode::Reserved => MacAddress::Short([0, 0]),
155 AddressMode::Short => MacAddress::Short([buf[12], buf[13]]),
156 AddressMode::Extended => {
157 MacAddress::Extended([buf[12], buf[13], buf[14], buf[15], buf[16], buf[17], buf[18], buf[19]])
158 }
159 };
160
161 Ok(Self {
162 pan_id: [buf[0], buf[1]],
163 src_addr_mode,
164 dst_addr_mode,
165 src_address,
166 dst_address,
167 status: MacStatus::try_from(buf[20])?,
168 security_level: SecurityLevel::try_from(buf[21])?,
169 key_id_mode: KeyIdMode::try_from(buf[22])?,
170 key_index: buf[23],
171 key_source: [buf[24], buf[25], buf[26], buf[27], buf[28], buf[29], buf[30], buf[31]],
172 })
173 }
174}
175
85/// MLME GTS Indication indicates that a GTS has been allocated or that a 176/// MLME GTS Indication indicates that a GTS has been allocated or that a
86/// previously allocated GTS has been deallocated 177/// previously allocated GTS has been deallocated
87#[repr(C)] 178#[cfg_attr(feature = "defmt", derive(defmt::Format))]
88pub struct GtsIndication { 179pub struct GtsIndication {
89 /// The short address of the device that has been allocated or deallocated a GTS 180 /// The short address of the device that has been allocated or deallocated a GTS
90 pub device_address: [u8; 2], 181 pub device_address: [u8; 2],
91 /// The characteristics of the GTS 182 /// The characteristics of the GTS
92 pub gts_characteristics: u8, 183 pub gts_characteristics: u8,
93 /// Security level to be used 184 /// Security level to be used
94 pub security_level: u8, 185 pub security_level: SecurityLevel,
95 /// Mode used to identify the key to be used 186 /// Mode used to identify the key to be used
96 pub key_id_mode: u8, 187 pub key_id_mode: KeyIdMode,
97 /// Index of the key to be used 188 /// Index of the key to be used
98 pub key_index: u8, 189 pub key_index: u8,
99 /// Originator of the key to be used 190 /// Originator of the key to be used
100 pub key_source: [u8; 8], 191 pub key_source: [u8; 8],
101} 192}
102 193
194impl ParseableMacEvent for GtsIndication {
195 const SIZE: usize = 16;
196
197 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
198 Self::validate(buf)?;
199
200 Ok(Self {
201 device_address: [buf[0], buf[1]],
202 gts_characteristics: buf[2],
203 security_level: SecurityLevel::try_from(buf[3])?,
204 key_id_mode: KeyIdMode::try_from(buf[4])?,
205 key_index: buf[5],
206 // 2 byte stuffing
207 key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]],
208 })
209 }
210}
211
103/// MLME ORPHAN Indication which is used by the coordinator to notify the 212/// MLME ORPHAN Indication which is used by the coordinator to notify the
104/// application of the presence of an orphaned device 213/// application of the presence of an orphaned device
105#[repr(C)] 214#[cfg_attr(feature = "defmt", derive(defmt::Format))]
106pub struct OrphanIndication { 215pub struct OrphanIndication {
107 /// Extended address of the orphaned device 216 /// Extended address of the orphaned device
108 pub orphan_address: [u8; 8], 217 pub orphan_address: [u8; 8],
109 /// Originator of the key used by the originator of the received frame 218 /// Originator of the key used by the originator of the received frame
110 pub key_source: [u8; 8], 219 pub key_source: [u8; 8],
111 /// Security level purportedly used by the received MAC command frame 220 /// Security level purportedly used by the received MAC command frame
112 pub security_level: u8, 221 pub security_level: SecurityLevel,
113 /// Mode used to identify the key used by originator of received frame 222 /// Mode used to identify the key used by originator of received frame
114 pub key_id_mode: u8, 223 pub key_id_mode: KeyIdMode,
115 /// Index of the key used by the originator of the received frame 224 /// Index of the key used by the originator of the received frame
116 pub key_index: u8, 225 pub key_index: u8,
117} 226}
118 227
228impl ParseableMacEvent for OrphanIndication {
229 const SIZE: usize = 20;
230
231 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
232 Self::validate(buf)?;
233
234 Ok(Self {
235 orphan_address: [buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]],
236 key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]],
237 security_level: SecurityLevel::try_from(buf[16])?,
238 key_id_mode: KeyIdMode::try_from(buf[17])?,
239 key_index: buf[18],
240 // 1 byte stuffing
241 })
242 }
243}
244
119/// MLME SYNC LOSS Indication which is used by the MAC to indicate the loss 245/// MLME SYNC LOSS Indication which is used by the MAC to indicate the loss
120/// of synchronization with the coordinator 246/// of synchronization with the coordinator
121#[repr(C)] 247#[cfg_attr(feature = "defmt", derive(defmt::Format))]
122pub struct SyncLossIndication { 248pub struct SyncLossIndication {
123 /// The PAN identifier with which the device lost synchronization or to which it was realigned 249 /// The PAN identifier with which the device lost synchronization or to which it was realigned
124 pub pan_id: [u8; 2], 250 pub pan_id: [u8; 2],
125 /// The reason that synchronization was lost 251 /// The reason that synchronization was lost
126 pub loss_reason: u8, 252 pub loss_reason: u8,
127 /// The logical channel on which the device lost synchronization or to whi 253 /// The logical channel on which the device lost synchronization or to whi
128 pub channel_number: u8, 254 pub channel_number: MacChannel,
129 /// The channel page on which the device lost synchronization or to which 255 /// The channel page on which the device lost synchronization or to which
130 pub channel_page: u8, 256 pub channel_page: u8,
131 /// The security level used by the received MAC frame 257 /// The security level used by the received MAC frame
132 pub security_level: u8, 258 pub security_level: SecurityLevel,
133 /// Mode used to identify the key used by originator of received frame 259 /// Mode used to identify the key used by originator of received frame
134 pub key_id_mode: u8, 260 pub key_id_mode: KeyIdMode,
135 /// Index of the key used by the originator of the received frame 261 /// Index of the key used by the originator of the received frame
136 pub key_index: u8, 262 pub key_index: u8,
137 /// Originator of the key used by the originator of the received frame 263 /// Originator of the key used by the originator of the received frame
138 pub key_source: [u8; 8], 264 pub key_source: [u8; 8],
139} 265}
140 266
267impl ParseableMacEvent for SyncLossIndication {
268 const SIZE: usize = 16;
269
270 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
271 Self::validate(buf)?;
272
273 Ok(Self {
274 pan_id: [buf[0], buf[1]],
275 loss_reason: buf[2],
276 channel_number: MacChannel::try_from(buf[3])?,
277 channel_page: buf[4],
278 security_level: SecurityLevel::try_from(buf[5])?,
279 key_id_mode: KeyIdMode::try_from(buf[6])?,
280 key_index: buf[7],
281 key_source: [buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]],
282 })
283 }
284}
285
141/// MLME DPS Indication which indicates the expiration of the DPSIndexDuration 286/// MLME DPS Indication which indicates the expiration of the DPSIndexDuration
142/// and the resetting of the DPS values in the PHY 287/// and the resetting of the DPS values in the PHY
288#[cfg_attr(feature = "defmt", derive(defmt::Format))]
143pub struct DpsIndication; 289pub struct DpsIndication;
144 290
145#[repr(C)] 291impl ParseableMacEvent for DpsIndication {
292 const SIZE: usize = 4;
293
294 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
295 Self::validate(buf)?;
296
297 Ok(Self)
298 }
299}
300
301#[cfg_attr(feature = "defmt", derive(defmt::Format))]
146pub struct DataIndication { 302pub struct DataIndication {
147 /// Pointer to the set of octets forming the MSDU being indicated 303 /// Pointer to the set of octets forming the MSDU being indicated
148 pub msdu_ptr: *const u8, 304 pub msdu_ptr: *const u8,
149 /// Source addressing mode used 305 /// Source addressing mode used
150 pub src_addr_mode: u8, 306 pub src_addr_mode: AddressMode,
151 /// Source PAN ID 307 /// Source PAN ID
152 pub src_pan_id: [u8; 2], 308 pub src_pan_id: [u8; 2],
153 /// Source address 309 /// Source address
@@ -167,9 +323,9 @@ pub struct DataIndication {
167 /// The time, in symbols, at which the data were received 323 /// The time, in symbols, at which the data were received
168 pub time_stamp: [u8; 4], 324 pub time_stamp: [u8; 4],
169 /// The security level purportedly used by the received data frame 325 /// The security level purportedly used by the received data frame
170 pub security_level: u8, 326 pub security_level: SecurityLevel,
171 /// Mode used to identify the key used by originator of received frame 327 /// Mode used to identify the key used by originator of received frame
172 pub key_id_mode: u8, 328 pub key_id_mode: KeyIdMode,
173 /// The originator of the key 329 /// The originator of the key
174 pub key_source: [u8; 8], 330 pub key_source: [u8; 8],
175 /// The index of the key 331 /// The index of the key
@@ -194,12 +350,91 @@ pub struct DataIndication {
194 pub rssi: u8, 350 pub rssi: u8,
195} 351}
196 352
353impl ParseableMacEvent for DataIndication {
354 const SIZE: usize = 72;
355
356 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
357 Self::validate(buf)?;
358
359 let src_addr_mode = AddressMode::try_from(buf[4])?;
360 let src_address = match src_addr_mode {
361 AddressMode::NoAddress => MacAddress::Short([0, 0]),
362 AddressMode::Reserved => MacAddress::Short([0, 0]),
363 AddressMode::Short => MacAddress::Short([buf[7], buf[8]]),
364 AddressMode::Extended => {
365 MacAddress::Extended([buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14]])
366 }
367 };
368
369 let dst_addr_mode = AddressMode::try_from(buf[15])?;
370 let dst_address = match dst_addr_mode {
371 AddressMode::NoAddress => MacAddress::Short([0, 0]),
372 AddressMode::Reserved => MacAddress::Short([0, 0]),
373 AddressMode::Short => MacAddress::Short([buf[18], buf[19]]),
374 AddressMode::Extended => {
375 MacAddress::Extended([buf[18], buf[19], buf[20], buf[21], buf[22], buf[23], buf[24], buf[25]])
376 }
377 };
378
379 Ok(Self {
380 msdu_ptr: to_u32(&buf[0..4]) as *const u8,
381 src_addr_mode,
382 src_pan_id: [buf[5], buf[6]],
383 src_address,
384 dst_addr_mode,
385 dst_pan_id: [buf[16], buf[17]],
386 dst_address,
387 msdu_length: buf[26],
388 mpdu_link_quality: buf[27],
389 dsn: buf[28],
390 time_stamp: [buf[29], buf[30], buf[31], buf[32]],
391 security_level: SecurityLevel::try_from(buf[33])?,
392 key_id_mode: KeyIdMode::try_from(buf[34])?,
393 key_source: [buf[35], buf[36], buf[37], buf[38], buf[39], buf[40], buf[41], buf[42]],
394 key_index: buf[43],
395 uwbprf: buf[44],
396 uwn_preamble_symbol_repetitions: buf[45],
397 datrate: buf[46],
398 ranging_received: buf[47],
399 ranging_counter_start: to_u32(&buf[58..52]),
400 ranging_counter_stop: to_u32(&buf[52..56]),
401 ranging_tracking_interval: to_u32(&buf[56..60]),
402 ranging_offset: to_u32(&buf[60..64]),
403 ranging_fom: buf[65],
404 rssi: buf[66],
405 })
406 }
407}
408
197/// MLME POLL Indication which will be used for indicating the Data Request 409/// MLME POLL Indication which will be used for indicating the Data Request
198/// reception to upper layer as defined in Zigbee r22 - D.8.2 410/// reception to upper layer as defined in Zigbee r22 - D.8.2
199#[repr(C)] 411#[cfg_attr(feature = "defmt", derive(defmt::Format))]
200pub struct PollIndication { 412pub struct PollIndication {
201 /// addressing mode used 413 /// addressing mode used
202 pub addr_mode: u8, 414 pub addr_mode: AddressMode,
203 /// Poll requester address 415 /// Poll requester address
204 pub request_address: MacAddress, 416 pub request_address: MacAddress,
205} 417}
418
419impl ParseableMacEvent for PollIndication {
420 const SIZE: usize = 9;
421
422 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
423 Self::validate(buf)?;
424
425 let addr_mode = AddressMode::try_from(buf[0])?;
426 let request_address = match addr_mode {
427 AddressMode::NoAddress => MacAddress::Short([0, 0]),
428 AddressMode::Reserved => MacAddress::Short([0, 0]),
429 AddressMode::Short => MacAddress::Short([buf[1], buf[2]]),
430 AddressMode::Extended => {
431 MacAddress::Extended([buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]])
432 }
433 };
434
435 Ok(Self {
436 addr_mode,
437 request_address,
438 })
439 }
440}
diff --git a/embassy-stm32-wpan/src/sub/mac/macros.rs b/embassy-stm32-wpan/src/sub/mac/macros.rs
new file mode 100644
index 000000000..1a988a779
--- /dev/null
+++ b/embassy-stm32-wpan/src/sub/mac/macros.rs
@@ -0,0 +1,32 @@
1#[macro_export]
2macro_rules! numeric_enum {
3 (#[repr($repr:ident)]
4 $(#$attrs:tt)* $vis:vis enum $name:ident {
5 $($(#$enum_attrs:tt)* $enum:ident = $constant:expr),* $(,)?
6 } ) => {
7 #[repr($repr)]
8 $(#$attrs)*
9 $vis enum $name {
10 $($(#$enum_attrs)* $enum = $constant),*
11 }
12
13 impl ::core::convert::TryFrom<$repr> for $name {
14 type Error = ();
15
16 fn try_from(value: $repr) -> ::core::result::Result<Self, ()> {
17 match value {
18 $($constant => Ok( $name :: $enum ),)*
19 _ => Err(())
20 }
21 }
22 }
23
24 impl ::core::convert::From<$name> for $repr {
25 fn from(value: $name) -> $repr {
26 match value {
27 $($name :: $enum => $constant,)*
28 }
29 }
30 }
31 }
32}
diff --git a/embassy-stm32-wpan/src/sub/mac/mod.rs b/embassy-stm32-wpan/src/sub/mac/mod.rs
index 756d7d5b1..0524f135a 100644
--- a/embassy-stm32-wpan/src/sub/mac/mod.rs
+++ b/embassy-stm32-wpan/src/sub/mac/mod.rs
@@ -9,7 +9,8 @@ use embassy_stm32::ipcc::Ipcc;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use self::commands::MacCommand; 11use self::commands::MacCommand;
12use self::typedefs::MacStatus; 12use self::event::MacEvent;
13use self::typedefs::MacError;
13use crate::cmd::CmdPacket; 14use crate::cmd::CmdPacket;
14use crate::consts::TlPacketType; 15use crate::consts::TlPacketType;
15use crate::evt::{EvtBox, EvtPacket}; 16use crate::evt::{EvtBox, EvtPacket};
@@ -18,7 +19,10 @@ use crate::{channels, evt};
18 19
19pub mod commands; 20pub mod commands;
20mod consts; 21mod consts;
22pub mod event;
23mod helpers;
21pub mod indications; 24pub mod indications;
25mod macros;
22mod opcodes; 26mod opcodes;
23pub mod responses; 27pub mod responses;
24pub mod typedefs; 28pub mod typedefs;
@@ -38,7 +42,7 @@ impl Mac {
38 /// `HW_IPCC_MAC_802_15_4_EvtNot` 42 /// `HW_IPCC_MAC_802_15_4_EvtNot`
39 /// 43 ///
40 /// This function will stall if the previous `EvtBox` has not been dropped 44 /// This function will stall if the previous `EvtBox` has not been dropped
41 pub async fn read(&self) -> EvtBox<Self> { 45 pub async fn tl_read(&self) -> EvtBox<Self> {
42 // Wait for the last event box to be dropped 46 // Wait for the last event box to be dropped
43 poll_fn(|cx| { 47 poll_fn(|cx| {
44 MAC_WAKER.register(cx.waker()); 48 MAC_WAKER.register(cx.waker());
@@ -62,33 +66,20 @@ impl Mac {
62 } 66 }
63 67
64 /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` 68 /// `HW_IPCC_MAC_802_15_4_CmdEvtNot`
65 pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { 69 pub async fn tl_write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 {
66 self.write(opcode, payload).await; 70 self.tl_write(opcode, payload).await;
67 Ipcc::flush(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL).await; 71 Ipcc::flush(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL).await;
68 72
69 unsafe { 73 unsafe {
70 let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; 74 let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket;
71 let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; 75 let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8;
72 76
73 let evt_serial = (MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket)
74 .read_volatile()
75 .evt_serial;
76 let kind = (evt_serial).kind;
77 let evt_code = evt_serial.evt.evt_code;
78 let payload_len = evt_serial.evt.payload_len;
79 let payload = evt_serial.evt.payload;
80
81 debug!(
82 "evt kind {} evt_code {} len {} payload {}",
83 kind, evt_code, payload_len, payload
84 );
85
86 ptr::read_volatile(p_mac_rsp_evt) 77 ptr::read_volatile(p_mac_rsp_evt)
87 } 78 }
88 } 79 }
89 80
90 /// `TL_MAC_802_15_4_SendCmd` 81 /// `TL_MAC_802_15_4_SendCmd`
91 pub async fn write(&self, opcode: u16, payload: &[u8]) { 82 pub async fn tl_write(&self, opcode: u16, payload: &[u8]) {
92 Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { 83 Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe {
93 CmdPacket::write_into( 84 CmdPacket::write_into(
94 MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), 85 MAC_802_15_4_CMD_BUFFER.as_mut_ptr(),
@@ -98,37 +89,31 @@ impl Mac {
98 ); 89 );
99 }) 90 })
100 .await; 91 .await;
101
102 unsafe {
103 let typ = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.ty;
104 let cmd_code = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.cmd.cmd_code;
105 let payload_len = MAC_802_15_4_CMD_BUFFER
106 .as_ptr()
107 .read_volatile()
108 .cmdserial
109 .cmd
110 .payload_len;
111 let payload = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.cmd.payload;
112
113 debug!(
114 "serial type {} cmd_code {} len {} payload {}",
115 typ, cmd_code, payload_len, payload
116 );
117 }
118 } 92 }
119 93
120 pub async fn send_command<T>(&self, cmd: T) -> Result<MacStatus, ()> 94 pub async fn send_command<T>(&self, cmd: T) -> Result<(), MacError>
121 where 95 where
122 T: MacCommand, 96 T: MacCommand,
123 { 97 {
124 let mut payload = [0u8; MAX_PACKET_SIZE]; 98 let mut payload = [0u8; MAX_PACKET_SIZE];
125 cmd.copy_into_slice(&mut payload); 99 cmd.copy_into_slice(&mut payload);
126 100
127 debug!("sending {:#x}", payload[..T::SIZE]); 101 let response = self
102 .tl_write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE])
103 .await;
104
105 if response == 0x00 {
106 Ok(())
107 } else {
108 Err(MacError::from(response))
109 }
110 }
128 111
129 let response = self.write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]).await; 112 pub async fn read(&self) -> Result<MacEvent, ()> {
113 let evt_box = self.tl_read().await;
114 let payload = evt_box.payload();
130 115
131 MacStatus::try_from(response) 116 MacEvent::try_from(payload)
132 } 117 }
133} 118}
134 119
diff --git a/embassy-stm32-wpan/src/sub/mac/opcodes.rs b/embassy-stm32-wpan/src/sub/mac/opcodes.rs
index 511b78157..c9a07d6af 100644
--- a/embassy-stm32-wpan/src/sub/mac/opcodes.rs
+++ b/embassy-stm32-wpan/src/sub/mac/opcodes.rs
@@ -25,3 +25,66 @@ pub enum OpcodeM4ToM0 {
25 McpsDataReq = opcode(0x10), 25 McpsDataReq = opcode(0x10),
26 McpsPurgeReq = opcode(0x11), 26 McpsPurgeReq = opcode(0x11),
27} 27}
28
29pub enum OpcodeM0ToM4 {
30 MlmeAssociateCnf = 0x00,
31 MlmeDisassociateCnf,
32 MlmeGetCnf,
33 MlmeGtsCnf,
34 MlmeResetCnf,
35 MlmeRxEnableCnf,
36 MlmeScanCnf,
37 MlmeSetCnf,
38 MlmeStartCnf,
39 MlmePollCnf,
40 MlmeDpsCnf,
41 MlmeSoundingCnf,
42 MlmeCalibrateCnf,
43 McpsDataCnf,
44 McpsPurgeCnf,
45 MlmeAssociateInd,
46 MlmeDisassociateInd,
47 MlmeBeaconNotifyInd,
48 MlmeCommStatusInd,
49 MlmeGtsInd,
50 MlmeOrphanInd,
51 MlmeSyncLossInd,
52 MlmeDpsInd,
53 McpsDataInd,
54 MlmePollInd,
55}
56
57impl TryFrom<u16> for OpcodeM0ToM4 {
58 type Error = ();
59
60 fn try_from(value: u16) -> Result<Self, Self::Error> {
61 match value {
62 0 => Ok(Self::MlmeAssociateCnf),
63 1 => Ok(Self::MlmeDisassociateCnf),
64 2 => Ok(Self::MlmeGetCnf),
65 3 => Ok(Self::MlmeGtsCnf),
66 4 => Ok(Self::MlmeResetCnf),
67 5 => Ok(Self::MlmeRxEnableCnf),
68 6 => Ok(Self::MlmeScanCnf),
69 7 => Ok(Self::MlmeSetCnf),
70 8 => Ok(Self::MlmeStartCnf),
71 9 => Ok(Self::MlmePollCnf),
72 10 => Ok(Self::MlmeDpsCnf),
73 11 => Ok(Self::MlmeSoundingCnf),
74 12 => Ok(Self::MlmeCalibrateCnf),
75 13 => Ok(Self::McpsDataCnf),
76 14 => Ok(Self::McpsPurgeCnf),
77 15 => Ok(Self::MlmeAssociateInd),
78 16 => Ok(Self::MlmeDisassociateInd),
79 17 => Ok(Self::MlmeBeaconNotifyInd),
80 18 => Ok(Self::MlmeCommStatusInd),
81 19 => Ok(Self::MlmeGtsInd),
82 20 => Ok(Self::MlmeOrphanInd),
83 21 => Ok(Self::MlmeSyncLossInd),
84 22 => Ok(Self::MlmeDpsInd),
85 23 => Ok(Self::McpsDataInd),
86 24 => Ok(Self::MlmePollInd),
87 _ => Err(()),
88 }
89 }
90}
diff --git a/embassy-stm32-wpan/src/sub/mac/responses.rs b/embassy-stm32-wpan/src/sub/mac/responses.rs
index 8c30a1823..ce2ca2fb2 100644
--- a/embassy-stm32-wpan/src/sub/mac/responses.rs
+++ b/embassy-stm32-wpan/src/sub/mac/responses.rs
@@ -1,35 +1,50 @@
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::typedefs::{AddressMode, MacAddress, PanDescriptor}; 2use super::event::ParseableMacEvent;
3 3use super::helpers::to_u32;
4pub trait MacResponse { 4use super::typedefs::{
5 const SIZE: usize; 5 AddressMode, AssociationStatus, KeyIdMode, MacAddress, MacStatus, PanDescriptor, PibId, ScanType, SecurityLevel,
6 6};
7 fn parse(buf: &[u8]) -> Self;
8}
9 7
10/// MLME ASSOCIATE Confirm used to inform of the initiating device whether 8/// MLME ASSOCIATE Confirm used to inform of the initiating device whether
11/// its request to associate was successful or unsuccessful 9/// its request to associate was successful or unsuccessful
12#[repr(C)] 10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
13pub struct AssociateConfirm { 11pub struct AssociateConfirm {
14 /// short address allocated by the coordinator on successful association 12 /// short address allocated by the coordinator on successful association
15 pub assoc_short_address: [u8; 2], 13 pub assoc_short_address: [u8; 2],
16 /// status of the association request 14 /// status of the association request
17 pub status: u8, 15 pub status: AssociationStatus,
18 /// security level to be used 16 /// security level to be used
19 pub security_level: u8, 17 pub security_level: SecurityLevel,
20 /// the originator of the key to be used 18 /// the originator of the key to be used
21 pub key_source: [u8; 8], 19 pub key_source: [u8; 8],
22 /// the mode used to identify the key to be used 20 /// the mode used to identify the key to be used
23 pub key_id_mode: u8, 21 pub key_id_mode: KeyIdMode,
24 /// the index of the key to be used 22 /// the index of the key to be used
25 pub key_index: u8, 23 pub key_index: u8,
26} 24}
27 25
26impl ParseableMacEvent for AssociateConfirm {
27 const SIZE: usize = 16;
28
29 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
30 Self::validate(buf)?;
31
32 Ok(Self {
33 assoc_short_address: [buf[0], buf[1]],
34 status: AssociationStatus::try_from(buf[2])?,
35 security_level: SecurityLevel::try_from(buf[3])?,
36 key_source: [buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]],
37 key_id_mode: KeyIdMode::try_from(buf[12])?,
38 key_index: buf[13],
39 })
40 }
41}
42
28/// MLME DISASSOCIATE Confirm used to send disassociation Confirmation to the application. 43/// MLME DISASSOCIATE Confirm used to send disassociation Confirmation to the application.
29#[repr(C)] 44#[cfg_attr(feature = "defmt", derive(defmt::Format))]
30pub struct DisassociateConfirm { 45pub struct DisassociateConfirm {
31 /// status of the disassociation attempt 46 /// status of the disassociation attempt
32 pub status: u8, 47 pub status: MacStatus,
33 /// device addressing mode used 48 /// device addressing mode used
34 pub device_addr_mode: AddressMode, 49 pub device_addr_mode: AddressMode,
35 /// the identifier of the PAN of the device 50 /// the identifier of the PAN of the device
@@ -38,51 +53,130 @@ pub struct DisassociateConfirm {
38 pub device_address: MacAddress, 53 pub device_address: MacAddress,
39} 54}
40 55
56impl ParseableMacEvent for DisassociateConfirm {
57 const SIZE: usize = 12;
58
59 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
60 Self::validate(buf)?;
61
62 let device_addr_mode = AddressMode::try_from(buf[1])?;
63 let device_address = match device_addr_mode {
64 AddressMode::NoAddress => MacAddress::Short([0, 0]),
65 AddressMode::Reserved => MacAddress::Short([0, 0]),
66 AddressMode::Short => MacAddress::Short([buf[4], buf[5]]),
67 AddressMode::Extended => {
68 MacAddress::Extended([buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]])
69 }
70 };
71
72 Ok(Self {
73 status: MacStatus::try_from(buf[0])?,
74 device_addr_mode,
75 device_pan_id: [buf[2], buf[3]],
76 device_address,
77 })
78 }
79}
80
41/// MLME GET Confirm which requests information about a given PIB attribute 81/// MLME GET Confirm which requests information about a given PIB attribute
42#[repr(C)] 82#[cfg_attr(feature = "defmt", derive(defmt::Format))]
43pub struct GetConfirm { 83pub struct GetConfirm {
44 /// The pointer to the value of the PIB attribute attempted to read 84 /// The pointer to the value of the PIB attribute attempted to read
45 pub pib_attribute_value_ptr: *const u8, 85 pub pib_attribute_value_ptr: *const u8,
46 /// Status of the GET attempt 86 /// Status of the GET attempt
47 pub status: u8, 87 pub status: MacStatus,
48 /// The name of the PIB attribute attempted to read 88 /// The name of the PIB attribute attempted to read
49 pub pib_attribute: u8, 89 pub pib_attribute: PibId,
50 /// The lenght of the PIB attribute Value return 90 /// The lenght of the PIB attribute Value return
51 pub pib_attribute_value_len: u8, 91 pub pib_attribute_value_len: u8,
52} 92}
53 93
94impl ParseableMacEvent for GetConfirm {
95 const SIZE: usize = 8;
96
97 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
98 Self::validate(buf)?;
99
100 let address = to_u32(&buf[0..4]);
101
102 Ok(Self {
103 pib_attribute_value_ptr: address as *const u8,
104 status: MacStatus::try_from(buf[4])?,
105 pib_attribute: PibId::try_from(buf[5])?,
106 pib_attribute_value_len: buf[6],
107 })
108 }
109}
110
54/// MLME GTS Confirm which eports the results of a request to allocate a new GTS 111/// MLME GTS Confirm which eports the results of a request to allocate a new GTS
55/// or to deallocate an existing GTS 112/// or to deallocate an existing GTS
56#[repr(C)] 113#[cfg_attr(feature = "defmt", derive(defmt::Format))]
57pub struct GtsConfirm { 114pub struct GtsConfirm {
58 /// The characteristics of the GTS 115 /// The characteristics of the GTS
59 pub gts_characteristics: u8, 116 pub gts_characteristics: u8,
60 /// The status of the GTS reques 117 /// The status of the GTS reques
61 pub status: u8, 118 pub status: MacStatus,
119}
120
121impl ParseableMacEvent for GtsConfirm {
122 const SIZE: usize = 4;
123
124 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
125 Self::validate(buf)?;
126
127 Ok(Self {
128 gts_characteristics: buf[0],
129 status: MacStatus::try_from(buf[1])?,
130 })
131 }
62} 132}
63 133
64/// MLME RESET Confirm which is used to report the results of the reset operation 134/// MLME RESET Confirm which is used to report the results of the reset operation
65#[repr(C)] 135#[cfg_attr(feature = "defmt", derive(defmt::Format))]
66pub struct ResetConfirm { 136pub struct ResetConfirm {
67 /// The result of the reset operation 137 /// The result of the reset operation
68 status: u8, 138 status: MacStatus,
139}
140
141impl ParseableMacEvent for ResetConfirm {
142 const SIZE: usize = 4;
143
144 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
145 Self::validate(buf)?;
146
147 Ok(Self {
148 status: MacStatus::try_from(buf[0])?,
149 })
150 }
69} 151}
70 152
71/// MLME RX ENABLE Confirm which is used to report the results of the attempt 153/// MLME RX ENABLE Confirm which is used to report the results of the attempt
72/// to enable or disable the receiver 154/// to enable or disable the receiver
73#[repr(C)] 155#[cfg_attr(feature = "defmt", derive(defmt::Format))]
74pub struct RxEnableConfirm { 156pub struct RxEnableConfirm {
75 /// Result of the request to enable or disable the receiver 157 /// Result of the request to enable or disable the receiver
76 status: u8, 158 status: MacStatus,
159}
160
161impl ParseableMacEvent for RxEnableConfirm {
162 const SIZE: usize = 4;
163
164 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
165 Self::validate(buf)?;
166
167 Ok(Self {
168 status: MacStatus::try_from(buf[0])?,
169 })
170 }
77} 171}
78 172
79/// MLME SCAN Confirm which is used to report the result of the channel scan request 173/// MLME SCAN Confirm which is used to report the result of the channel scan request
80#[repr(C)] 174#[cfg_attr(feature = "defmt", derive(defmt::Format))]
81pub struct ScanConfirm { 175pub struct ScanConfirm {
82 /// Status of the scan request 176 /// Status of the scan request
83 pub status: u8, 177 pub status: MacStatus,
84 /// The type of scan performed 178 /// The type of scan performed
85 pub scan_type: u8, 179 pub scan_type: ScanType,
86 /// Channel page on which the scan was performed 180 /// Channel page on which the scan was performed
87 pub channel_page: u8, 181 pub channel_page: u8,
88 /// Channels given in the request which were not scanned 182 /// Channels given in the request which were not scanned
@@ -99,44 +193,124 @@ pub struct ScanConfirm {
99 pub uwb_energy_detect_list: [u8; MAX_ED_SCAN_RESULTS_SUPPORTED], 193 pub uwb_energy_detect_list: [u8; MAX_ED_SCAN_RESULTS_SUPPORTED],
100} 194}
101 195
196impl ParseableMacEvent for ScanConfirm {
197 const SIZE: usize = 9;
198
199 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
200 Self::validate(buf)?;
201
202 todo!()
203 }
204}
205
102/// MLME SET Confirm which reports the result of an attempt to write a value to a PIB attribute 206/// MLME SET Confirm which reports the result of an attempt to write a value to a PIB attribute
103#[repr(C)] 207#[cfg_attr(feature = "defmt", derive(defmt::Format))]
104pub struct SetConfirm { 208pub struct SetConfirm {
105 /// The result of the set operation 209 /// The result of the set operation
106 pub status: u8, 210 pub status: MacStatus,
107 /// The name of the PIB attribute that was written 211 /// The name of the PIB attribute that was written
108 pub pin_attribute: u8, 212 pub pin_attribute: PibId,
213}
214
215impl ParseableMacEvent for SetConfirm {
216 const SIZE: usize = 4;
217
218 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
219 Self::validate(buf)?;
220
221 Ok(Self {
222 status: MacStatus::try_from(buf[0])?,
223 pin_attribute: PibId::try_from(buf[1])?,
224 })
225 }
109} 226}
110 227
111/// MLME START Confirm which is used to report the results of the attempt to 228/// MLME START Confirm which is used to report the results of the attempt to
112/// start using a new superframe configuration 229/// start using a new superframe configuration
113#[repr(C)] 230#[cfg_attr(feature = "defmt", derive(defmt::Format))]
114pub struct StartConfirm { 231pub struct StartConfirm {
115 /// Result of the attempt to start using an updated superframe configuration 232 /// Result of the attempt to start using an updated superframe configuration
116 pub status: u8, 233 pub status: MacStatus,
234}
235
236impl ParseableMacEvent for StartConfirm {
237 const SIZE: usize = 4;
238
239 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
240 Self::validate(buf)?;
241 debug!("{:#x}", buf);
242
243 Ok(Self {
244 status: MacStatus::try_from(buf[0])?,
245 })
246 }
117} 247}
118 248
119/// MLME POLL Confirm which is used to report the result of a request to poll the coordinator for data 249/// MLME POLL Confirm which is used to report the result of a request to poll the coordinator for data
120#[repr(C)] 250#[cfg_attr(feature = "defmt", derive(defmt::Format))]
121pub struct PollConfirm { 251pub struct PollConfirm {
122 /// The status of the data request 252 /// The status of the data request
123 pub status: u8, 253 pub status: MacStatus,
254}
255
256impl ParseableMacEvent for PollConfirm {
257 const SIZE: usize = 4;
258
259 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
260 Self::validate(buf)?;
261
262 Ok(Self {
263 status: MacStatus::try_from(buf[0])?,
264 })
265 }
266}
267
268/// MLME DPS Confirm which reports the results of the attempt to enable or disable the DPS
269#[cfg_attr(feature = "defmt", derive(defmt::Format))]
270pub struct DpsConfirm {
271 /// The status of the DPS request
272 pub status: MacStatus,
273}
274
275impl ParseableMacEvent for DpsConfirm {
276 const SIZE: usize = 4;
277
278 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
279 Self::validate(buf)?;
280
281 Ok(Self {
282 status: MacStatus::try_from(buf[0])?,
283 })
284 }
124} 285}
125 286
126/// MLME SOUNDING Confirm which reports the result of a request to the PHY to provide 287/// MLME SOUNDING Confirm which reports the result of a request to the PHY to provide
127/// channel sounding information 288/// channel sounding information
128#[repr(C)] 289#[cfg_attr(feature = "defmt", derive(defmt::Format))]
129pub struct SoundingConfirm { 290pub struct SoundingConfirm {
130 /// Results of the sounding measurement 291 /// Results of the sounding measurement
131 sounding_list: [u8; MAX_SOUNDING_LIST_SUPPORTED], 292 sounding_list: [u8; MAX_SOUNDING_LIST_SUPPORTED],
132} 293}
133 294
295impl ParseableMacEvent for SoundingConfirm {
296 const SIZE: usize = 1;
297
298 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
299 Self::validate(buf)?;
300
301 let mut sounding_list = [0u8; MAX_SOUNDING_LIST_SUPPORTED];
302 sounding_list[..buf.len()].copy_from_slice(buf);
303
304 Ok(Self { sounding_list })
305 }
306}
307
134/// MLME CALIBRATE Confirm which reports the result of a request to the PHY 308/// MLME CALIBRATE Confirm which reports the result of a request to the PHY
135/// to provide internal propagation path information 309/// to provide internal propagation path information
136#[repr(C)] 310#[cfg_attr(feature = "defmt", derive(defmt::Format))]
137pub struct CalibrateConfirm { 311pub struct CalibrateConfirm {
138 /// The status of the attempt to return sounding data 312 /// The status of the attempt to return sounding data
139 pub status: u8, 313 pub status: MacStatus,
140 /// A count of the propagation time from the ranging counter 314 /// A count of the propagation time from the ranging counter
141 /// to the transmit antenna 315 /// to the transmit antenna
142 pub cal_tx_rmaker_offset: u32, 316 pub cal_tx_rmaker_offset: u32,
@@ -145,18 +319,33 @@ pub struct CalibrateConfirm {
145 pub cal_rx_rmaker_offset: u32, 319 pub cal_rx_rmaker_offset: u32,
146} 320}
147 321
322impl ParseableMacEvent for CalibrateConfirm {
323 const SIZE: usize = 12;
324
325 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
326 Self::validate(buf)?;
327
328 Ok(Self {
329 status: MacStatus::try_from(buf[0])?,
330 // 3 byte stuffing
331 cal_tx_rmaker_offset: to_u32(&buf[4..8]),
332 cal_rx_rmaker_offset: to_u32(&buf[8..12]),
333 })
334 }
335}
336
148/// MCPS DATA Confirm which will be used for reporting the results of 337/// MCPS DATA Confirm which will be used for reporting the results of
149/// MAC data related requests from the application 338/// MAC data related requests from the application
150#[repr(C)] 339#[cfg_attr(feature = "defmt", derive(defmt::Format))]
151pub struct DataConfirm { 340pub struct DataConfirm {
152 /// The handle associated with the MSDU being confirmed 341 /// The handle associated with the MSDU being confirmed
153 pub msdu_handle: u8, 342 pub msdu_handle: u8,
154 /// The time, in symbols, at which the data were transmitted 343 /// The time, in symbols, at which the data were transmitted
155 pub a_time_stamp: [u8; 4], 344 pub time_stamp: [u8; 4],
156 /// ranging status 345 /// ranging status
157 pub ranging_received: u8, 346 pub ranging_received: u8,
158 /// The status of the last MSDU transmission 347 /// The status of the last MSDU transmission
159 pub status: u8, 348 pub status: MacStatus,
160 /// time units corresponding to an RMARKER at the antenna at 349 /// time units corresponding to an RMARKER at the antenna at
161 /// the beginning of a ranging exchange 350 /// the beginning of a ranging exchange
162 pub ranging_counter_start: u32, 351 pub ranging_counter_start: u32,
@@ -171,12 +360,45 @@ pub struct DataConfirm {
171 pub ranging_fom: u8, 360 pub ranging_fom: u8,
172} 361}
173 362
363impl ParseableMacEvent for DataConfirm {
364 const SIZE: usize = 28;
365
366 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
367 Self::validate(buf)?;
368
369 Ok(Self {
370 msdu_handle: buf[0],
371 time_stamp: [buf[1], buf[2], buf[3], buf[4]],
372 ranging_received: buf[5],
373 status: MacStatus::try_from(buf[6])?,
374 ranging_counter_start: to_u32(&buf[7..11]),
375 ranging_counter_stop: to_u32(&buf[11..15]),
376 ranging_tracking_interval: to_u32(&buf[15..19]),
377 ranging_offset: to_u32(&buf[19..23]),
378 ranging_fom: buf[24],
379 })
380 }
381}
382
174/// MCPS PURGE Confirm which will be used by the MAC to notify the application of 383/// MCPS PURGE Confirm which will be used by the MAC to notify the application of
175/// the status of its request to purge an MSDU from the transaction queue 384/// the status of its request to purge an MSDU from the transaction queue
176#[repr(C)] 385#[cfg_attr(feature = "defmt", derive(defmt::Format))]
177pub struct PurgeConfirm { 386pub struct PurgeConfirm {
178 /// Handle associated with the MSDU requested to be purged from the transaction queue 387 /// Handle associated with the MSDU requested to be purged from the transaction queue
179 pub msdu_handle: u8, 388 pub msdu_handle: u8,
180 /// The status of the request 389 /// The status of the request
181 pub status: u8, 390 pub status: MacStatus,
391}
392
393impl ParseableMacEvent for PurgeConfirm {
394 const SIZE: usize = 4;
395
396 fn try_parse(buf: &[u8]) -> Result<Self, ()> {
397 Self::validate(buf)?;
398
399 Ok(Self {
400 msdu_handle: buf[0],
401 status: MacStatus::try_from(buf[1])?,
402 })
403 }
182} 404}
diff --git a/embassy-stm32-wpan/src/sub/mac/typedefs.rs b/embassy-stm32-wpan/src/sub/mac/typedefs.rs
index 7f0dd75c0..fe79b3a79 100644
--- a/embassy-stm32-wpan/src/sub/mac/typedefs.rs
+++ b/embassy-stm32-wpan/src/sub/mac/typedefs.rs
@@ -1,6 +1,8 @@
1use crate::numeric_enum;
2
3#[derive(Debug)]
1#[cfg_attr(feature = "defmt", derive(defmt::Format))] 4#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2pub enum MacStatus { 5pub enum MacError {
3 Success = 0x00,
4 Error = 0x01, 6 Error = 0x01,
5 NotImplemented = 0x02, 7 NotImplemented = 0x02,
6 NotSupported = 0x03, 8 NotSupported = 0x03,
@@ -8,88 +10,115 @@ pub enum MacStatus {
8 Undefined = 0x05, 10 Undefined = 0x05,
9} 11}
10 12
11impl TryFrom<u8> for MacStatus { 13impl From<u8> for MacError {
12 type Error = (); 14 fn from(value: u8) -> Self {
13
14 fn try_from(value: u8) -> Result<Self, <MacStatus as TryFrom<u8>>::Error> {
15 match value { 15 match value {
16 0x00 => Ok(Self::Success), 16 0x01 => Self::Error,
17 0x01 => Ok(Self::Error), 17 0x02 => Self::NotImplemented,
18 0x02 => Ok(Self::NotImplemented), 18 0x03 => Self::NotSupported,
19 0x03 => Ok(Self::NotSupported), 19 0x04 => Self::HardwareNotSupported,
20 0x04 => Ok(Self::HardwareNotSupported), 20 0x05 => Self::Undefined,
21 0x05 => Ok(Self::Undefined), 21 _ => Self::Undefined,
22 _ => Err(()),
23 } 22 }
24 } 23 }
25} 24}
26 25
27/// this enum contains all the MAC PIB Ids 26numeric_enum! {
28#[cfg_attr(feature = "defmt", derive(defmt::Format))] 27 #[repr(u8)]
29pub enum PibId { 28 #[derive(Debug)]
30 // PHY 29 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
31 CurrentChannel = 0x00, 30 pub enum MacStatus {
32 ChannelsSupported = 0x01, 31 Success = 0x00,
33 TransmitPower = 0x02, 32 Error = 0x01,
34 CCAMode = 0x03, 33 NotImplemented = 0x02,
35 CurrentPage = 0x04, 34 NotSupported = 0x03,
36 MaxFrameDuration = 0x05, 35 HardwareNotSupported = 0x04,
37 SHRDuration = 0x06, 36 Undefined = 0x05,
38 SymbolsPerOctet = 0x07, 37 }
39 38}
40 // MAC 39
41 AckWaitDuration = 0x40, 40numeric_enum! {
42 AssociationPermit = 0x41, 41 #[repr(u8)]
43 AutoRequest = 0x42, 42 /// this enum contains all the MAC PIB Ids
44 BeaconPayload = 0x45, 43 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
45 BeaconPayloadLength = 0x46, 44 pub enum PibId {
46 BeaconOrder = 0x47, 45 // PHY
47 Bsn = 0x49, 46 CurrentChannel = 0x00,
48 CoordExtendedAdddress = 0x4A, 47 ChannelsSupported = 0x01,
49 CoordShortAddress = 0x4B, 48 TransmitPower = 0x02,
50 Dsn = 0x4C, 49 CCAMode = 0x03,
51 MaxFrameTotalWaitTime = 0x58, 50 CurrentPage = 0x04,
52 MaxFrameRetries = 0x59, 51 MaxFrameDuration = 0x05,
53 PanId = 0x50, 52 SHRDuration = 0x06,
54 ResponseWaitTime = 0x5A, 53 SymbolsPerOctet = 0x07,
55 RxOnWhenIdle = 0x52, 54
56 SecurityEnabled = 0x5D, 55 // MAC
57 ShortAddress = 0x53, 56 AckWaitDuration = 0x40,
58 SuperframeOrder = 0x54, 57 AssociationPermit = 0x41,
59 TimestampSupported = 0x5C, 58 AutoRequest = 0x42,
60 TransactionPersistenceTime = 0x55, 59 BeaconPayload = 0x45,
61 MaxBe = 0x57, 60 BeaconPayloadLength = 0x46,
62 LifsPeriod = 0x5E, 61 BeaconOrder = 0x47,
63 SifsPeriod = 0x5F, 62 Bsn = 0x49,
64 MaxCsmaBackoffs = 0x4E, 63 CoordExtendedAdddress = 0x4A,
65 MinBe = 0x4F, 64 CoordShortAddress = 0x4B,
66 PanCoordinator = 0x10, 65 Dsn = 0x4C,
67 AssocPanCoordinator = 0x11, 66 MaxFrameTotalWaitTime = 0x58,
68 ExtendedAddress = 0x6F, 67 MaxFrameRetries = 0x59,
69 AclEntryDescriptor = 0x70, 68 PanId = 0x50,
70 AclEntryDescriptorSize = 0x71, 69 ResponseWaitTime = 0x5A,
71 DefaultSecurity = 0x72, 70 RxOnWhenIdle = 0x52,
72 DefaultSecurityMaterialLength = 0x73, 71 SecurityEnabled = 0x5D,
73 DefaultSecurityMaterial = 0x74, 72 ShortAddress = 0x53,
74 DefaultSecuritySuite = 0x75, 73 SuperframeOrder = 0x54,
75 SecurityMode = 0x76, 74 TimestampSupported = 0x5C,
76 CurrentAclEntries = 0x80, 75 TransactionPersistenceTime = 0x55,
77 DefaultSecurityExtendedAddress = 0x81, 76 MaxBe = 0x57,
78 AssociatedPanCoordinator = 0x56, 77 LifsPeriod = 0x5E,
79 PromiscuousMode = 0x51, 78 SifsPeriod = 0x5F,
79 MaxCsmaBackoffs = 0x4E,
80 MinBe = 0x4F,
81 PanCoordinator = 0x10,
82 AssocPanCoordinator = 0x11,
83 ExtendedAddress = 0x6F,
84 AclEntryDescriptor = 0x70,
85 AclEntryDescriptorSize = 0x71,
86 DefaultSecurity = 0x72,
87 DefaultSecurityMaterialLength = 0x73,
88 DefaultSecurityMaterial = 0x74,
89 DefaultSecuritySuite = 0x75,
90 SecurityMode = 0x76,
91 CurrentAclEntries = 0x80,
92 DefaultSecurityExtendedAddress = 0x81,
93 AssociatedPanCoordinator = 0x56,
94 PromiscuousMode = 0x51,
95 }
96}
97
98numeric_enum! {
99 #[repr(u8)]
100 #[derive(Default, Clone, Copy)]
101 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
102 pub enum AddressMode {
103 #[default]
104 NoAddress = 0x00,
105 Reserved = 0x01,
106 Short = 0x02,
107 Extended = 0x03,
108}
80} 109}
81 110
111#[derive(Clone, Copy)]
82#[cfg_attr(feature = "defmt", derive(defmt::Format))] 112#[cfg_attr(feature = "defmt", derive(defmt::Format))]
83pub enum AddressMode { 113pub enum MacAddress {
84 NoAddress = 0x00, 114 Short([u8; 2]),
85 Reserved = 0x01, 115 Extended([u8; 8]),
86 Short = 0x02,
87 Extended = 0x03,
88} 116}
89 117
90pub union MacAddress { 118impl Default for MacAddress {
91 pub short: [u8; 2], 119 fn default() -> Self {
92 pub extended: [u8; 8], 120 Self::Short([0, 0])
121 }
93} 122}
94 123
95pub struct GtsCharacteristics { 124pub struct GtsCharacteristics {
@@ -98,13 +127,15 @@ pub struct GtsCharacteristics {
98 127
99/// MAC PAN Descriptor which contains the network details of the device from 128/// MAC PAN Descriptor which contains the network details of the device from
100/// which the beacon is received 129/// which the beacon is received
130#[derive(Default, Clone, Copy)]
131#[cfg_attr(feature = "defmt", derive(defmt::Format))]
101pub struct PanDescriptor { 132pub struct PanDescriptor {
102 /// PAN identifier of the coordinator 133 /// PAN identifier of the coordinator
103 pub a_coord_pan_id: [u8; 2], 134 pub coord_pan_id: [u8; 2],
104 /// Coordinator addressing mode 135 /// Coordinator addressing mode
105 pub coord_addr_mode: AddressMode, 136 pub coord_addr_mode: AddressMode,
106 /// The current logical channel occupied by the network 137 /// The current logical channel occupied by the network
107 pub logical_channel: u8, 138 pub logical_channel: MacChannel,
108 /// Coordinator address 139 /// Coordinator address
109 pub coord_addr: MacAddress, 140 pub coord_addr: MacAddress,
110 /// The current channel page occupied by the network 141 /// The current channel page occupied by the network
@@ -112,13 +143,179 @@ pub struct PanDescriptor {
112 /// PAN coordinator is accepting GTS requests or not 143 /// PAN coordinator is accepting GTS requests or not
113 pub gts_permit: bool, 144 pub gts_permit: bool,
114 /// Superframe specification as specified in the received beacon frame 145 /// Superframe specification as specified in the received beacon frame
115 pub a_superframe_spec: [u8; 2], 146 pub superframe_spec: [u8; 2],
116 /// The time at which the beacon frame was received, in symbols 147 /// The time at which the beacon frame was received, in symbols
117 pub a_time_stamp: [u8; 4], 148 pub time_stamp: [u8; 4],
118 /// The LQI at which the network beacon was received 149 /// The LQI at which the network beacon was received
119 pub link_quality: u8, 150 pub link_quality: u8,
120 /// Security level purportedly used by the received beacon frame 151 /// Security level purportedly used by the received beacon frame
121 pub security_level: u8, 152 pub security_level: u8,
122 /// Byte Stuffing to keep 32 bit alignment 153}
123 pub a_stuffing: [u8; 2], 154
155impl TryFrom<&[u8]> for PanDescriptor {
156 type Error = ();
157
158 fn try_from(buf: &[u8]) -> Result<Self, Self::Error> {
159 const SIZE: usize = 24;
160 if buf.len() < SIZE {
161 return Err(());
162 }
163
164 let coord_addr_mode = AddressMode::try_from(buf[2])?;
165 let coord_addr = match coord_addr_mode {
166 AddressMode::NoAddress => MacAddress::Short([0, 0]),
167 AddressMode::Reserved => MacAddress::Short([0, 0]),
168 AddressMode::Short => MacAddress::Short([buf[4], buf[5]]),
169 AddressMode::Extended => {
170 MacAddress::Extended([buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]])
171 }
172 };
173
174 Ok(Self {
175 coord_pan_id: [buf[0], buf[1]],
176 coord_addr_mode,
177 logical_channel: MacChannel::try_from(buf[3])?,
178 coord_addr,
179 channel_page: buf[12],
180 gts_permit: buf[13] != 0,
181 superframe_spec: [buf[14], buf[15]],
182 time_stamp: [buf[16], buf[17], buf[18], buf[19]],
183 link_quality: buf[20],
184 security_level: buf[21],
185 // 2 byte stuffing
186 })
187 }
188}
189
190numeric_enum! {
191 #[repr(u8)]
192 #[derive(Default, Clone, Copy)]
193 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
194 /// Building wireless applications with STM32WB series MCUs - Application note 13.10.3
195 pub enum MacChannel {
196 Channel11 = 0x0B,
197 Channel12 = 0x0C,
198 Channel13 = 0x0D,
199 Channel14 = 0x0E,
200 Channel15 = 0x0F,
201 #[default]
202 Channel16 = 0x10,
203 Channel17 = 0x11,
204 Channel18 = 0x12,
205 Channel19 = 0x13,
206 Channel20 = 0x14,
207 Channel21 = 0x15,
208 Channel22 = 0x16,
209 Channel23 = 0x17,
210 Channel24 = 0x18,
211 Channel25 = 0x19,
212 Channel26 = 0x1A,
213 }
214}
215
216#[cfg(not(feature = "defmt"))]
217bitflags::bitflags! {
218 pub struct Capabilities: u8 {
219 /// 1 if the device is capabaleof becoming a PAN coordinator
220 const IS_COORDINATOR_CAPABLE = 0b00000001;
221 /// 1 if the device is an FFD, 0 if it is an RFD
222 const IS_FFD = 0b00000010;
223 /// 1 if the device is receiving power from mains, 0 if it is battery-powered
224 const IS_MAINS_POWERED = 0b00000100;
225 /// 1 if the device does not disable its receiver to conserver power during idle periods
226 const RECEIVER_ON_WHEN_IDLE = 0b00001000;
227 // 0b00010000 reserved
228 // 0b00100000 reserved
229 /// 1 if the device is capable of sending and receiving secured MAC frames
230 const IS_SECURE = 0b01000000;
231 /// 1 if the device wishes the coordinator to allocate a short address as a result of the association
232 const ALLOCATE_ADDRESS = 0b10000000;
233 }
234}
235
236#[cfg(feature = "defmt")]
237defmt::bitflags! {
238 pub struct Capabilities: u8 {
239 /// 1 if the device is capabaleof becoming a PAN coordinator
240 const IS_COORDINATOR_CAPABLE = 0b00000001;
241 /// 1 if the device is an FFD, 0 if it is an RFD
242 const IS_FFD = 0b00000010;
243 /// 1 if the device is receiving power from mains, 0 if it is battery-powered
244 const IS_MAINS_POWERED = 0b00000100;
245 /// 1 if the device does not disable its receiver to conserver power during idle periods
246 const RECEIVER_ON_WHEN_IDLE = 0b00001000;
247 // 0b00010000 reserved
248 // 0b00100000 reserved
249 /// 1 if the device is capable of sending and receiving secured MAC frames
250 const IS_SECURE = 0b01000000;
251 /// 1 if the device wishes the coordinator to allocate a short address as a result of the association
252 const ALLOCATE_ADDRESS = 0b10000000;
253 }
254}
255
256numeric_enum! {
257 #[repr(u8)]
258 #[derive(Default)]
259 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
260 pub enum KeyIdMode {
261 #[default]
262 /// the key is determined implicitly from the originator and recipient(s) of the frame
263 Implicite = 0x00,
264 /// the key is determined explicitly using a 1 bytes key source and a 1 byte key index
265 Explicite1Byte = 0x01,
266 /// the key is determined explicitly using a 4 bytes key source and a 1 byte key index
267 Explicite4Byte = 0x02,
268 /// the key is determined explicitly using a 8 bytes key source and a 1 byte key index
269 Explicite8Byte = 0x03,
270 }
271}
272
273numeric_enum! {
274 #[repr(u8)]
275 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
276 pub enum AssociationStatus {
277 /// Association successful
278 Success = 0x00,
279 /// PAN at capacity
280 PanAtCapacity = 0x01,
281 /// PAN access denied
282 PanAccessDenied = 0x02
283 }
284}
285
286numeric_enum! {
287 #[repr(u8)]
288 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
289 pub enum DisassociationReason {
290 /// The coordinator wishes the device to leave the PAN.
291 CoordRequested = 0x01,
292 /// The device wishes to leave the PAN.
293 DeviceRequested = 0x02,
294 }
295}
296
297numeric_enum! {
298 #[repr(u8)]
299 #[derive(Default)]
300 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
301 pub enum SecurityLevel {
302 /// MAC Unsecured Mode Security
303 #[default]
304 Unsecure = 0x00,
305 /// MAC ACL Mode Security
306 AclMode = 0x01,
307 /// MAC Secured Mode Security
308 Secured = 0x02,
309 }
310}
311
312numeric_enum! {
313 #[repr(u8)]
314 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
315 pub enum ScanType {
316 EdScan = 0x00,
317 Active = 0x01,
318 Passive = 0x02,
319 Orphan = 0x03
320 }
124} 321}
diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs
index 4100d1ac5..18b29362b 100644
--- a/examples/stm32wb/src/bin/mac_ffd.rs
+++ b/examples/stm32wb/src/bin/mac_ffd.rs
@@ -7,7 +7,7 @@ use embassy_executor::Spawner;
7use embassy_stm32::bind_interrupts; 7use embassy_stm32::bind_interrupts;
8use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 8use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
9use embassy_stm32_wpan::sub::mac::commands::{ResetRequest, SetRequest, StartRequest}; 9use embassy_stm32_wpan::sub::mac::commands::{ResetRequest, SetRequest, StartRequest};
10use embassy_stm32_wpan::sub::mac::typedefs::PibId; 10use embassy_stm32_wpan::sub::mac::typedefs::{MacChannel, PibId};
11use embassy_stm32_wpan::sub::mm; 11use embassy_stm32_wpan::sub::mm;
12use embassy_stm32_wpan::TlMbox; 12use embassy_stm32_wpan::TlMbox;
13use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
@@ -65,109 +65,92 @@ async fn main(spawner: Spawner) {
65 info!("initialized mac: {}", result); 65 info!("initialized mac: {}", result);
66 66
67 info!("resetting"); 67 info!("resetting");
68 let response = mbox 68 mbox.mac_subsystem
69 .mac_subsystem
70 .send_command(ResetRequest { set_default_pib: true }) 69 .send_command(ResetRequest { set_default_pib: true })
71 .await; 70 .await
72 info!("{}", response); 71 .unwrap();
72 let evt = mbox.mac_subsystem.read().await;
73 defmt::info!("{:#x}", evt);
73 74
74 info!("setting extended address"); 75 info!("setting extended address");
75 let extended_address: u64 = 0xACDE480000000001; 76 let extended_address: u64 = 0xACDE480000000001;
76 let response = mbox 77 mbox.mac_subsystem
77 .mac_subsystem
78 .send_command(SetRequest { 78 .send_command(SetRequest {
79 pib_attribute_ptr: &extended_address as *const _ as *const u8, 79 pib_attribute_ptr: &extended_address as *const _ as *const u8,
80 pib_attribute: PibId::ExtendedAddress, 80 pib_attribute: PibId::ExtendedAddress,
81 }) 81 })
82 .await; 82 .await
83 info!("{}", response); 83 .unwrap();
84 let evt = mbox.mac_subsystem.read().await;
85 defmt::info!("{:#x}", evt);
84 86
85 info!("setting short address"); 87 info!("setting short address");
86 let short_address: u16 = 0x1122; 88 let short_address: u16 = 0x1122;
87 let response = mbox 89 mbox.mac_subsystem
88 .mac_subsystem
89 .send_command(SetRequest { 90 .send_command(SetRequest {
90 pib_attribute_ptr: &short_address as *const _ as *const u8, 91 pib_attribute_ptr: &short_address as *const _ as *const u8,
91 pib_attribute: PibId::ShortAddress, 92 pib_attribute: PibId::ShortAddress,
92 }) 93 })
93 .await; 94 .await
94 info!("{}", response); 95 .unwrap();
96 let evt = mbox.mac_subsystem.read().await;
97 defmt::info!("{:#x}", evt);
95 98
96 info!("setting association permit"); 99 info!("setting association permit");
97 let association_permit: bool = true; 100 let association_permit: bool = true;
98 let response = mbox 101 mbox.mac_subsystem
99 .mac_subsystem
100 .send_command(SetRequest { 102 .send_command(SetRequest {
101 pib_attribute_ptr: &association_permit as *const _ as *const u8, 103 pib_attribute_ptr: &association_permit as *const _ as *const u8,
102 pib_attribute: PibId::AssociationPermit, 104 pib_attribute: PibId::AssociationPermit,
103 }) 105 })
104 .await; 106 .await
105 info!("{}", response); 107 .unwrap();
108 let evt = mbox.mac_subsystem.read().await;
109 defmt::info!("{:#x}", evt);
106 110
107 info!("setting TX power"); 111 info!("setting TX power");
108 let transmit_power: i8 = 2; 112 let transmit_power: i8 = 2;
109 let response = mbox 113 mbox.mac_subsystem
110 .mac_subsystem
111 .send_command(SetRequest { 114 .send_command(SetRequest {
112 pib_attribute_ptr: &transmit_power as *const _ as *const u8, 115 pib_attribute_ptr: &transmit_power as *const _ as *const u8,
113 pib_attribute: PibId::TransmitPower, 116 pib_attribute: PibId::TransmitPower,
114 }) 117 })
115 .await; 118 .await
116 info!("{}", response); 119 .unwrap();
120 let evt = mbox.mac_subsystem.read().await;
121 defmt::info!("{:#x}", evt);
117 122
118 info!("starting FFD device"); 123 info!("starting FFD device");
119 let response = mbox 124 mbox.mac_subsystem
120 .mac_subsystem
121 .send_command(StartRequest { 125 .send_command(StartRequest {
122 channel_number: 16, 126 channel_number: MacChannel::Channel16,
123 beacon_order: 0x0F, 127 beacon_order: 0x0F,
124 superframe_order: 0x0F, 128 superframe_order: 0x0F,
125 pan_coordinator: true, 129 pan_coordinator: true,
126 battery_life_extension: false, 130 battery_life_extension: false,
127 ..Default::default() 131 ..Default::default()
128 }) 132 })
129 .await; 133 .await
130 info!("{}", response); 134 .unwrap();
135 let evt = mbox.mac_subsystem.read().await;
136 defmt::info!("{:#x}", evt);
131 137
132 info!("setting RX on when idle"); 138 info!("setting RX on when idle");
133 let rx_on_while_idle: bool = true; 139 let rx_on_while_idle: bool = true;
134 let response = mbox 140 mbox.mac_subsystem
135 .mac_subsystem
136 .send_command(SetRequest { 141 .send_command(SetRequest {
137 pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8, 142 pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8,
138 pib_attribute: PibId::RxOnWhenIdle, 143 pib_attribute: PibId::RxOnWhenIdle,
139 }) 144 })
140 .await; 145 .await
141 info!("{}", response); 146 .unwrap();
142 147 let evt = mbox.mac_subsystem.read().await;
143 // info!("association request"); 148 defmt::info!("{:#x}", evt);
144 // mbox.mac_subsystem 149
145 // .send_command(AssociateRequest { 150 loop {
146 // channel_number: 16, 151 let evt = mbox.mac_subsystem.read().await;
147 // channel_page: 0, 152 defmt::info!("{:#x}", evt);
148 // coord_addr_mode: 2, 153 }
149 // coord_address: MacAddress { short: [0x22, 0x11] },
150 // capability_information: 0x80,
151 // coord_pan_id: [0xAA, 0x1A],
152 // security_level: 0,
153
154 // key_id_mode: 0,
155 // key_index: 0,
156 // key_source: [0; 8],
157 // })
158 // .await;
159 // info!("reading");
160 // let result = mbox.mac_subsystem.read().await;
161 // info!("{}", result.payload());
162
163 //
164 // info!("starting ble...");
165 // mbox.ble_subsystem.t_write(0x0c, &[]).await;
166 //
167 // info!("waiting for ble...");
168 // let ble_event = mbox.ble_subsystem.tl_read().await;
169 //
170 // info!("ble event: {}", ble_event.payload());
171 154
172 info!("Test OK"); 155 info!("Test OK");
173 cortex_m::asm::bkpt(); 156 cortex_m::asm::bkpt();
diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs
index 938fe754f..8042a3704 100644
--- a/examples/stm32wb/src/bin/mac_rfd.rs
+++ b/examples/stm32wb/src/bin/mac_rfd.rs
@@ -7,7 +7,9 @@ use embassy_executor::Spawner;
7use embassy_stm32::bind_interrupts; 7use embassy_stm32::bind_interrupts;
8use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 8use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
9use embassy_stm32_wpan::sub::mac::commands::{AssociateRequest, ResetRequest, SetRequest, StartRequest}; 9use embassy_stm32_wpan::sub::mac::commands::{AssociateRequest, ResetRequest, SetRequest, StartRequest};
10use embassy_stm32_wpan::sub::mac::typedefs::{AddressMode, MacAddress, PibId}; 10use embassy_stm32_wpan::sub::mac::typedefs::{
11 AddressMode, Capabilities, KeyIdMode, MacAddress, MacChannel, PibId, SecurityLevel,
12};
11use embassy_stm32_wpan::sub::mm; 13use embassy_stm32_wpan::sub::mm;
12use embassy_stm32_wpan::TlMbox; 14use embassy_stm32_wpan::TlMbox;
13use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
@@ -86,14 +88,14 @@ async fn main(spawner: Spawner) {
86 let response = mbox 88 let response = mbox
87 .mac_subsystem 89 .mac_subsystem
88 .send_command(AssociateRequest { 90 .send_command(AssociateRequest {
89 channel_number: 16, 91 channel_number: MacChannel::Channel16,
90 channel_page: 0, 92 channel_page: 0,
91 coord_addr_mode: AddressMode::Short, 93 coord_addr_mode: AddressMode::Short,
92 coord_address: MacAddress { short: [0x22, 0x11] }, 94 coord_address: MacAddress::Short([0x22, 0x11]),
93 capability_information: 0x80, 95 capability_information: Capabilities::ALLOCATE_ADDRESS,
94 coord_pan_id: [0xAA, 0x1A], 96 coord_pan_id: [0xAA, 0x1A],
95 security_level: 0x00, 97 security_level: SecurityLevel::Unsecure,
96 key_id_mode: 0, 98 key_id_mode: KeyIdMode::Implicite,
97 key_source: [0; 8], 99 key_source: [0; 8],
98 key_index: 0, 100 key_index: 0,
99 }) 101 })