diff options
| author | xoviat <[email protected]> | 2023-07-17 16:38:46 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-07-17 16:38:46 -0500 |
| commit | 1d2c47273db6593a53018b1643dcadb491afc3de (patch) | |
| tree | b0191bc1bb70e5401b3263b7622c248480c1a4ad | |
| parent | 582006c75cdd7e9d819bcacc0f6724c05f161bee (diff) | |
| parent | 6b5df4523aa1c4902f02e803450ae4b418e0e3ca (diff) | |
Merge branch 'master' into mac
| -rw-r--r-- | embassy-stm32-wpan/src/mac/commands.rs | 83 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/event.rs | 155 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/helpers.rs | 7 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/indications.rs | 285 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/mod.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/responses.rs | 287 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/typedefs.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/sub/mac.rs | 18 | ||||
| -rw-r--r-- | examples/rp/Cargo.toml | 1 | ||||
| -rw-r--r-- | examples/rp/src/bin/usb_hid_keyboard.rs | 188 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/mac_ffd.rs | 69 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/mac_rfd.rs | 90 | ||||
| -rw-r--r-- | tests/stm32/src/bin/wpan_mac.rs | 38 |
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 @@ | |||
| 1 | use core::{mem, slice}; | ||
| 2 | |||
| 1 | use super::opcodes::OpcodeM4ToM0; | 3 | use super::opcodes::OpcodeM4ToM0; |
| 2 | use super::typedefs::{ | 4 | use 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 | ||
| 7 | pub trait MacCommand { | 9 | pub 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 | ||
| 42 | impl MacCommand for AssociateRequest { | 43 | impl 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 | ||
| 71 | impl MacCommand for DisassociateRequest { | 71 | impl 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))] |
| 79 | pub struct GetRequest { | 79 | pub 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 | ||
| 84 | impl MacCommand for GetRequest { | 87 | impl 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 | ||
| 105 | impl MacCommand for GtsRequest { | 107 | impl 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))] |
| 112 | pub struct ResetRequest { | 114 | pub 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 | ||
| 117 | impl MacCommand for ResetRequest { | 121 | impl 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 | ||
| 138 | impl MacCommand for RxEnableRequest { | 143 | impl 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 | ||
| 177 | impl MacCommand for ScanRequest { | 171 | impl 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 | ||
| 192 | impl MacCommand for SetRequest { | 185 | impl 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))] |
| 202 | pub struct StartRequest { | 194 | pub 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 | ||
| 237 | impl MacCommand for StartRequest { | 229 | impl 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 | ||
| 258 | impl MacCommand for SyncRequest { | 251 | impl 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 | ||
| 283 | impl MacCommand for PollRequest { | 277 | impl 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 | ||
| 302 | impl MacCommand for DpsRequest { | 297 | impl 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))] |
| 311 | pub struct SoundingRequest; | 305 | pub struct SoundingRequest { |
| 306 | /// byte stuffing to keep 32 bit alignment | ||
| 307 | pub a_stuffing: [u8; 4], | ||
| 308 | } | ||
| 312 | 309 | ||
| 313 | impl MacCommand for SoundingRequest { | 310 | impl 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))] |
| 322 | pub struct CalibrateRequest; | 318 | pub struct CalibrateRequest { |
| 319 | /// byte stuffing to keep 32 bit alignment | ||
| 320 | pub a_stuffing: [u8; 4], | ||
| 321 | } | ||
| 323 | 322 | ||
| 324 | impl MacCommand for CalibrateRequest { | 323 | impl 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 | ||
| 371 | impl 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 | |||
| 373 | impl Default for DataRequest { | 380 | impl 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 | ||
| 398 | impl MacCommand for DataRequest { | 405 | impl 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 | ||
| 412 | impl MacCommand for PurgeRequest { | 420 | impl 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 | ||
| 439 | impl MacCommand for AssociateResponse { | 448 | impl 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 | ||
| 464 | impl MacCommand for OrphanResponse { | 474 | impl 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; | |||
| 4 | use embassy_sync::pubsub::{PubSubChannel, Subscriber}; | 4 | use embassy_sync::pubsub::{PubSubChannel, Subscriber}; |
| 5 | 5 | ||
| 6 | use super::helpers::to_u16; | 6 | use super::helpers::to_u16; |
| 7 | use core::mem; | ||
| 8 | |||
| 7 | use super::indications::{ | 9 | use 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 | }; |
| 17 | use crate::evt::EvtBox; | ||
| 15 | use crate::mac::opcodes::OpcodeM0ToM4; | 18 | use crate::mac::opcodes::OpcodeM0ToM4; |
| 16 | 19 | use crate::sub::mac::Mac; | |
| 17 | pub trait ParseableMacEvent { | 20 | |
| 18 | const SIZE: usize; | 21 | pub(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)] | 31 | pub struct Event { |
| 34 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 32 | event_box: EvtBox<Mac>, |
| 35 | pub 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 | ||
| 63 | impl TryFrom<&[u8]> for MacEvent { | 35 | impl 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))] | ||
| 85 | pub 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. |
| 103 | pub type EventQueue = PubSubChannel<NoopRawMutex, Message, 2, 1, 1>; | 114 | pub type EventQueue = PubSubChannel<NoopRawMutex, Message, 2, 1, 1>; |
| 104 | pub type EventSubscriber<'a> = Subscriber<'a, NoopRawMutex, Message, 2, 1, 1>; | 115 | pub 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 @@ | |||
| 1 | pub fn to_u16(buf: &[u8]) -> u16 { | ||
| 2 | ((buf[1] as u16) << 8) | buf[0] as u16 | ||
| 3 | } | ||
| 4 | |||
| 5 | pub 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 @@ | |||
| 1 | use core::slice; | ||
| 2 | |||
| 1 | use super::consts::MAX_PENDING_ADDRESS; | 3 | use super::consts::MAX_PENDING_ADDRESS; |
| 2 | use super::event::ParseableMacEvent; | 4 | use super::event::ParseableMacEvent; |
| 3 | use super::helpers::to_u32; | ||
| 4 | use super::typedefs::{ | 5 | use 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))] |
| 12 | pub struct AssociateIndication { | 14 | pub 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 | ||
| 27 | impl ParseableMacEvent for AssociateIndication { | 29 | impl 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))] |
| 47 | pub struct DisassociateIndication { | 35 | pub 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 | ||
| 62 | impl ParseableMacEvent for DisassociateIndication { | 50 | impl 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))] |
| 82 | pub struct BeaconNotifyIndication { | 56 | pub 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 | ||
| 98 | impl ParseableMacEvent for BeaconNotifyIndication { | 72 | impl 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))] |
| 129 | pub struct CommStatusIndication { | 77 | pub 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 | ||
| 153 | impl ParseableMacEvent for CommStatusIndication { | 101 | impl 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))] |
| 202 | pub struct GtsIndication { | 107 | pub 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 | ||
| 217 | impl ParseableMacEvent for GtsIndication { | 124 | impl 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))] |
| 238 | pub struct OrphanIndication { | 130 | pub 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 | ||
| 251 | impl ParseableMacEvent for OrphanIndication { | 145 | impl 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))] |
| 271 | pub struct SyncLossIndication { | 151 | pub 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 | ||
| 290 | impl ParseableMacEvent for SyncLossIndication { | 170 | impl 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))] |
| 312 | pub struct DpsIndication; | 176 | pub struct DpsIndication { |
| 313 | 177 | /// byte stuffing to keep 32 bit alignment | |
| 314 | impl 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 | ||
| 181 | impl 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))] | ||
| 326 | pub struct DataIndication { | 185 | pub 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 | ||
| 377 | impl ParseableMacEvent for DataIndication { | 236 | impl 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])?; | 238 | impl 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))] |
| 440 | pub struct PollIndication { | 248 | pub 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 | ||
| 447 | impl ParseableMacEvent for PollIndication { | 255 | impl 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; | |||
| 2 | mod consts; | 2 | mod consts; |
| 3 | pub mod control; | 3 | pub mod control; |
| 4 | pub mod event; | 4 | pub mod event; |
| 5 | mod helpers; | ||
| 6 | pub mod indications; | 5 | pub mod indications; |
| 7 | mod ioctl; | 6 | mod ioctl; |
| 8 | mod macros; | 7 | mod 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 @@ | |||
| 1 | use super::consts::{MAX_ED_SCAN_RESULTS_SUPPORTED, MAX_PAN_DESC_SUPPORTED, MAX_SOUNDING_LIST_SUPPORTED}; | 1 | use super::consts::{MAX_ED_SCAN_RESULTS_SUPPORTED, MAX_PAN_DESC_SUPPORTED, MAX_SOUNDING_LIST_SUPPORTED}; |
| 2 | use super::event::ParseableMacEvent; | 2 | use super::event::ParseableMacEvent; |
| 3 | use super::helpers::to_u32; | ||
| 4 | use super::typedefs::{ | 3 | use 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))] |
| 12 | pub struct AssociateConfirm { | 12 | pub 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 | ||
| 27 | impl ParseableMacEvent for AssociateConfirm { | 29 | impl 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))] |
| 46 | pub struct DisassociateConfirm { | 34 | pub 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 | ||
| 57 | impl ParseableMacEvent for DisassociateConfirm { | 45 | impl 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))] |
| 86 | pub struct GetConfirm { | 50 | pub 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 | ||
| 97 | impl ParseableMacEvent for GetConfirm { | 63 | impl 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))] |
| 117 | pub struct GtsConfirm { | 69 | pub 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 | ||
| 124 | impl ParseableMacEvent for GtsConfirm { | 78 | impl 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))] |
| 139 | pub struct ResetConfirm { | 83 | pub 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 | ||
| 144 | impl ParseableMacEvent for ResetConfirm { | 90 | impl 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))] |
| 159 | pub struct RxEnableConfirm { | 96 | pub 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 | ||
| 164 | impl ParseableMacEvent for RxEnableConfirm { | 103 | impl 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))] |
| 178 | pub struct ScanConfirm { | 108 | pub 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 | ||
| 199 | impl ParseableMacEvent for ScanConfirm { | 129 | impl 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))] |
| 238 | pub struct SetConfirm { | 134 | pub 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 | ||
| 245 | impl ParseableMacEvent for SetConfirm { | 143 | impl 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))] |
| 261 | pub struct StartConfirm { | 149 | pub 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 | ||
| 266 | impl ParseableMacEvent for StartConfirm { | 156 | impl 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))] |
| 280 | pub struct PollConfirm { | 161 | pub 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 | ||
| 285 | impl ParseableMacEvent for PollConfirm { | 168 | impl 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))] |
| 299 | pub struct DpsConfirm { | 173 | pub 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 | ||
| 304 | impl ParseableMacEvent for DpsConfirm { | 180 | impl 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))] |
| 319 | pub struct SoundingConfirm { | 186 | pub 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 | ||
| 324 | impl 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 | ||
| 193 | impl 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))] |
| 340 | pub struct CalibrateConfirm { | 199 | pub 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 | ||
| 351 | impl ParseableMacEvent for CalibrateConfirm { | 212 | impl 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))] |
| 369 | pub struct DataConfirm { | 218 | pub 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 | ||
| 392 | impl ParseableMacEvent for DataConfirm { | 243 | impl 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))] |
| 415 | pub struct PurgeConfirm { | 249 | pub 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 | ||
| 422 | impl ParseableMacEvent for PurgeConfirm { | 258 | impl 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! { | |||
| 37 | numeric_enum! { | 37 | numeric_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; | |||
| 12 | use crate::consts::TlPacketType; | 12 | use crate::consts::TlPacketType; |
| 13 | use crate::evt::{EvtBox, EvtPacket}; | 13 | use crate::evt::{EvtBox, EvtPacket}; |
| 14 | use crate::mac::commands::MacCommand; | 14 | use crate::mac::commands::MacCommand; |
| 15 | use crate::mac::event::MacEvent; | 15 | use crate::mac::event::Event; |
| 16 | use crate::mac::typedefs::MacError; | 16 | use crate::mac::typedefs::MacError; |
| 17 | use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; | 17 | use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; |
| 18 | use crate::{channels, evt}; | 18 | use 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 | ||
| 110 | const MAX_PACKET_SIZE: usize = 255; | ||
| 111 | |||
| 112 | impl evt::MemoryManager for Mac { | 102 | impl 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" | |||
| 40 | byte-slice-cast = { version = "1.2.0", default-features = false } | 40 | byte-slice-cast = { version = "1.2.0", default-features = false } |
| 41 | smart-leds = "0.3.0" | 41 | smart-leds = "0.3.0" |
| 42 | heapless = "0.7.15" | 42 | heapless = "0.7.15" |
| 43 | usbd-hid = "0.6.1" | ||
| 43 | 44 | ||
| 44 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } | 45 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" } |
| 45 | embedded-hal-async = "0.2.0-alpha.2" | 46 | embedded-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 | |||
| 5 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 6 | |||
| 7 | use defmt::*; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_futures::join::join; | ||
| 10 | use embassy_rp::bind_interrupts; | ||
| 11 | use embassy_rp::gpio::{Input, Pull}; | ||
| 12 | use embassy_rp::peripherals::USB; | ||
| 13 | use embassy_rp::usb::{Driver, InterruptHandler}; | ||
| 14 | use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; | ||
| 15 | use embassy_usb::control::OutResponse; | ||
| 16 | use embassy_usb::{Builder, Config, Handler}; | ||
| 17 | use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor}; | ||
| 18 | use {defmt_rtt as _, panic_probe as _}; | ||
| 19 | |||
| 20 | bind_interrupts!(struct Irqs { | ||
| 21 | USBCTRL_IRQ => InterruptHandler<USB>; | ||
| 22 | }); | ||
| 23 | |||
| 24 | #[embassy_executor::main] | ||
| 25 | async 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 | |||
| 125 | struct MyRequestHandler {} | ||
| 126 | |||
| 127 | impl 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 | |||
| 148 | struct MyDeviceHandler { | ||
| 149 | configured: AtomicBool, | ||
| 150 | } | ||
| 151 | |||
| 152 | impl MyDeviceHandler { | ||
| 153 | fn new() -> Self { | ||
| 154 | MyDeviceHandler { | ||
| 155 | configured: AtomicBool::new(false), | ||
| 156 | } | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | impl 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(); |
