diff options
Diffstat (limited to 'embassy-stm32-wpan/src/mac')
| -rw-r--r-- | embassy-stm32-wpan/src/mac/commands.rs | 478 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/consts.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/control.rs | 95 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/driver.rs | 120 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/event.rs | 153 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/indications.rs | 265 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/macros.rs | 32 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/mod.rs | 21 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/opcodes.rs | 92 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/responses.rs | 273 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/runner.rs | 109 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/typedefs.rs | 381 |
12 files changed, 0 insertions, 2023 deletions
diff --git a/embassy-stm32-wpan/src/mac/commands.rs b/embassy-stm32-wpan/src/mac/commands.rs deleted file mode 100644 index 82b9d2772..000000000 --- a/embassy-stm32-wpan/src/mac/commands.rs +++ /dev/null | |||
| @@ -1,478 +0,0 @@ | |||
| 1 | #![allow(unused)] | ||
| 2 | |||
| 3 | use core::{mem, slice}; | ||
| 4 | |||
| 5 | use super::opcodes::OpcodeM4ToM0; | ||
| 6 | use super::typedefs::{ | ||
| 7 | AddressMode, Capabilities, DisassociationReason, GtsCharacteristics, KeyIdMode, MacAddress, MacChannel, MacStatus, | ||
| 8 | PanId, PibId, ScanType, SecurityLevel, | ||
| 9 | }; | ||
| 10 | |||
| 11 | pub trait MacCommand: Sized { | ||
| 12 | const OPCODE: OpcodeM4ToM0; | ||
| 13 | |||
| 14 | fn payload<'a>(&'a self) -> &'a [u8] { | ||
| 15 | unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of::<Self>()) } | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | /// MLME ASSOCIATE Request used to request an association | ||
| 20 | #[repr(C)] | ||
| 21 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 22 | pub struct AssociateRequest { | ||
| 23 | /// the logical channel on which to attempt association | ||
| 24 | pub channel_number: MacChannel, | ||
| 25 | /// the channel page on which to attempt association | ||
| 26 | pub channel_page: u8, | ||
| 27 | /// coordinator addressing mode | ||
| 28 | pub coord_addr_mode: AddressMode, | ||
| 29 | /// operational capabilities of the associating device | ||
| 30 | pub capability_information: Capabilities, | ||
| 31 | /// the identifier of the PAN with which to associate | ||
| 32 | pub coord_pan_id: PanId, | ||
| 33 | /// the security level to be used | ||
| 34 | pub security_level: SecurityLevel, | ||
| 35 | /// the mode used to identify the key to be used | ||
| 36 | pub key_id_mode: KeyIdMode, | ||
| 37 | /// the originator of the key to be used | ||
| 38 | pub key_source: [u8; 8], | ||
| 39 | /// Coordinator address | ||
| 40 | pub coord_address: MacAddress, | ||
| 41 | /// the index of the key to be used | ||
| 42 | pub key_index: u8, | ||
| 43 | } | ||
| 44 | |||
| 45 | impl MacCommand for AssociateRequest { | ||
| 46 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; | ||
| 47 | } | ||
| 48 | |||
| 49 | /// MLME DISASSOCIATE Request sed to request a disassociation | ||
| 50 | #[repr(C)] | ||
| 51 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 52 | pub struct DisassociateRequest { | ||
| 53 | /// device addressing mode used | ||
| 54 | pub device_addr_mode: AddressMode, | ||
| 55 | /// the identifier of the PAN of the device | ||
| 56 | pub device_pan_id: PanId, | ||
| 57 | /// the reason for the disassociation | ||
| 58 | pub disassociation_reason: DisassociationReason, | ||
| 59 | /// device address | ||
| 60 | pub device_address: MacAddress, | ||
| 61 | /// `true` if the disassociation notification command is to be sent indirectly | ||
| 62 | pub tx_indirect: bool, | ||
| 63 | /// the security level to be used | ||
| 64 | pub security_level: SecurityLevel, | ||
| 65 | /// the mode to be used to indetify the key to be used | ||
| 66 | pub key_id_mode: KeyIdMode, | ||
| 67 | /// the index of the key to be used | ||
| 68 | pub key_index: u8, | ||
| 69 | /// the originator of the key to be used | ||
| 70 | pub key_source: [u8; 8], | ||
| 71 | } | ||
| 72 | |||
| 73 | impl MacCommand for DisassociateRequest { | ||
| 74 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq; | ||
| 75 | } | ||
| 76 | |||
| 77 | /// MLME GET Request used to request a PIB value | ||
| 78 | #[repr(C)] | ||
| 79 | #[derive(Default)] | ||
| 80 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 81 | pub struct GetRequest { | ||
| 82 | /// the name of the PIB attribute to read | ||
| 83 | pub pib_attribute: PibId, | ||
| 84 | |||
| 85 | /// byte stuffing to keep 32 bit alignment | ||
| 86 | pub a_stuffing: [u8; 3], | ||
| 87 | } | ||
| 88 | |||
| 89 | impl MacCommand for GetRequest { | ||
| 90 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; | ||
| 91 | } | ||
| 92 | |||
| 93 | /// MLME GTS Request used to request and maintain GTSs | ||
| 94 | #[repr(C)] | ||
| 95 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 96 | pub struct GtsRequest { | ||
| 97 | /// the characteristics of the GTS | ||
| 98 | pub characteristics: GtsCharacteristics, | ||
| 99 | /// the security level to be used | ||
| 100 | pub security_level: SecurityLevel, | ||
| 101 | /// the mode used to identify the key to be used | ||
| 102 | pub key_id_mode: KeyIdMode, | ||
| 103 | /// the index of the key to be used | ||
| 104 | pub key_index: u8, | ||
| 105 | /// the originator of the key to be used | ||
| 106 | pub key_source: [u8; 8], | ||
| 107 | } | ||
| 108 | |||
| 109 | impl MacCommand for GtsRequest { | ||
| 110 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; | ||
| 111 | } | ||
| 112 | |||
| 113 | #[repr(C)] | ||
| 114 | #[derive(Default)] | ||
| 115 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 116 | pub struct ResetRequest { | ||
| 117 | /// MAC PIB attributes are set to their default values or not during reset | ||
| 118 | pub set_default_pib: bool, | ||
| 119 | /// byte stuffing to keep 32 bit alignment | ||
| 120 | pub a_stuffing: [u8; 3], | ||
| 121 | } | ||
| 122 | |||
| 123 | impl MacCommand for ResetRequest { | ||
| 124 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; | ||
| 125 | } | ||
| 126 | |||
| 127 | /// MLME RX ENABLE Request used to request that the receiver is either enabled | ||
| 128 | /// for a finite period of time or disabled | ||
| 129 | #[repr(C)] | ||
| 130 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 131 | pub struct RxEnableRequest { | ||
| 132 | /// the request operation can be deferred or not | ||
| 133 | pub defer_permit: bool, | ||
| 134 | /// configure the transceiver to RX with ranging for a value of | ||
| 135 | /// RANGING_ON or to not enable ranging for RANGING_OFF | ||
| 136 | pub ranging_rx_control: u8, | ||
| 137 | /// byte stuffing to keep 32 bit alignment | ||
| 138 | pub a_stuffing: [u8; 2], | ||
| 139 | /// number of symbols measured before the receiver is to be enabled or disabled | ||
| 140 | pub rx_on_time: [u8; 4], | ||
| 141 | /// number of symbols for which the receiver is to be enabled | ||
| 142 | pub rx_on_duration: [u8; 4], | ||
| 143 | } | ||
| 144 | |||
| 145 | impl MacCommand for RxEnableRequest { | ||
| 146 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeRxEnableReq; | ||
| 147 | } | ||
| 148 | |||
| 149 | /// MLME SCAN Request used to initiate a channel scan over a given list of channels | ||
| 150 | #[repr(C)] | ||
| 151 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 152 | pub struct ScanRequest { | ||
| 153 | /// the type of scan to be performed | ||
| 154 | pub scan_type: ScanType, | ||
| 155 | /// the time spent on scanning each channel | ||
| 156 | pub scan_duration: u8, | ||
| 157 | /// channel page on which to perform the scan | ||
| 158 | pub channel_page: u8, | ||
| 159 | /// security level to be used | ||
| 160 | pub security_level: SecurityLevel, | ||
| 161 | /// indicate which channels are to be scanned | ||
| 162 | pub scan_channels: [u8; 4], | ||
| 163 | /// originator the key to be used | ||
| 164 | pub key_source: [u8; 8], | ||
| 165 | /// mode used to identify the key to be used | ||
| 166 | pub key_id_mode: KeyIdMode, | ||
| 167 | /// index of the key to be used | ||
| 168 | pub key_index: u8, | ||
| 169 | /// byte stuffing to keep 32 bit alignment | ||
| 170 | pub a_stuffing: [u8; 2], | ||
| 171 | } | ||
| 172 | |||
| 173 | impl MacCommand for ScanRequest { | ||
| 174 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeScanReq; | ||
| 175 | } | ||
| 176 | |||
| 177 | /// MLME SET Request used to attempt to write the given value to the indicated PIB attribute | ||
| 178 | #[repr(C)] | ||
| 179 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 180 | pub struct SetRequest { | ||
| 181 | /// the pointer to the value of the PIB attribute to set | ||
| 182 | pub pib_attribute_ptr: *const u8, | ||
| 183 | /// the name of the PIB attribute to set | ||
| 184 | pub pib_attribute: PibId, | ||
| 185 | } | ||
| 186 | |||
| 187 | impl MacCommand for SetRequest { | ||
| 188 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; | ||
| 189 | } | ||
| 190 | |||
| 191 | /// MLME START Request used by the FFDs to intiate a new PAN or to begin using a new superframe | ||
| 192 | /// configuration | ||
| 193 | #[repr(C)] | ||
| 194 | #[derive(Default)] | ||
| 195 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 196 | pub struct StartRequest { | ||
| 197 | /// PAN indentifier to used by the device | ||
| 198 | pub pan_id: PanId, | ||
| 199 | /// logical channel on which to begin | ||
| 200 | pub channel_number: MacChannel, | ||
| 201 | /// channel page on which to begin | ||
| 202 | pub channel_page: u8, | ||
| 203 | /// time at which to begin transmitting beacons | ||
| 204 | pub start_time: [u8; 4], | ||
| 205 | /// indicated how often the beacon is to be transmitted | ||
| 206 | pub beacon_order: u8, | ||
| 207 | /// length of the active portion of the superframe | ||
| 208 | pub superframe_order: u8, | ||
| 209 | /// indicated wheter the device is a PAN coordinator or not | ||
| 210 | pub pan_coordinator: bool, | ||
| 211 | /// indicates if the receiver of the beaconing device is disabled or not | ||
| 212 | pub battery_life_extension: bool, | ||
| 213 | /// indicated if the coordinator realignment command is to be trasmitted | ||
| 214 | pub coord_realignment: u8, | ||
| 215 | /// indicated if the coordinator realignment command is to be trasmitted | ||
| 216 | pub coord_realign_security_level: SecurityLevel, | ||
| 217 | /// index of the key to be used | ||
| 218 | pub coord_realign_key_id_index: u8, | ||
| 219 | /// originator of the key to be used | ||
| 220 | pub coord_realign_key_source: [u8; 8], | ||
| 221 | /// security level to be used for beacon frames | ||
| 222 | pub beacon_security_level: SecurityLevel, | ||
| 223 | /// mode used to identify the key to be used | ||
| 224 | pub beacon_key_id_mode: KeyIdMode, | ||
| 225 | /// index of the key to be used | ||
| 226 | pub beacon_key_index: u8, | ||
| 227 | /// originator of the key to be used | ||
| 228 | pub beacon_key_source: [u8; 8], | ||
| 229 | } | ||
| 230 | |||
| 231 | impl MacCommand for StartRequest { | ||
| 232 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq; | ||
| 233 | } | ||
| 234 | |||
| 235 | /// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if | ||
| 236 | /// specified, tracking its beacons | ||
| 237 | #[repr(C)] | ||
| 238 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 239 | pub struct SyncRequest { | ||
| 240 | /// the channel number on which to attempt coordinator synchronization | ||
| 241 | pub channel_number: MacChannel, | ||
| 242 | /// the channel page on which to attempt coordinator synchronization | ||
| 243 | pub channel_page: u8, | ||
| 244 | /// `true` if the MLME is to synchronize with the next beacon and attempts | ||
| 245 | /// to track all future beacons. | ||
| 246 | /// | ||
| 247 | /// `false` if the MLME is to synchronize with only the next beacon | ||
| 248 | pub track_beacon: bool, | ||
| 249 | /// byte stuffing to keep 32 bit alignment | ||
| 250 | pub a_stuffing: [u8; 1], | ||
| 251 | } | ||
| 252 | |||
| 253 | impl MacCommand for SyncRequest { | ||
| 254 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq; | ||
| 255 | } | ||
| 256 | |||
| 257 | /// MLME POLL Request propmts the device to request data from the coordinator | ||
| 258 | #[repr(C)] | ||
| 259 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 260 | pub struct PollRequest { | ||
| 261 | /// addressing mode of the coordinator | ||
| 262 | pub coord_addr_mode: AddressMode, | ||
| 263 | /// security level to be used | ||
| 264 | pub security_level: SecurityLevel, | ||
| 265 | /// mode used to identify the key to be used | ||
| 266 | pub key_id_mode: KeyIdMode, | ||
| 267 | /// index of the key to be used | ||
| 268 | pub key_index: u8, | ||
| 269 | /// coordinator address | ||
| 270 | pub coord_address: MacAddress, | ||
| 271 | /// originator of the key to be used | ||
| 272 | pub key_source: [u8; 8], | ||
| 273 | /// PAN identifier of the coordinator | ||
| 274 | pub coord_pan_id: PanId, | ||
| 275 | /// byte stuffing to keep 32 bit alignment | ||
| 276 | pub a_stuffing: [u8; 2], | ||
| 277 | } | ||
| 278 | |||
| 279 | impl MacCommand for PollRequest { | ||
| 280 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq; | ||
| 281 | } | ||
| 282 | |||
| 283 | /// MLME DPS Request allows the next higher layer to request that the PHY utilize a | ||
| 284 | /// given pair of preamble codes for a single use pending expiration of the DPSIndexDuration | ||
| 285 | #[repr(C)] | ||
| 286 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 287 | pub struct DpsRequest { | ||
| 288 | /// the index value for the transmitter | ||
| 289 | tx_dps_index: u8, | ||
| 290 | /// the index value of the receiver | ||
| 291 | rx_dps_index: u8, | ||
| 292 | /// the number of symbols for which the transmitter and receiver will utilize the | ||
| 293 | /// respective DPS indices | ||
| 294 | dps_index_duration: u8, | ||
| 295 | /// byte stuffing to keep 32 bit alignment | ||
| 296 | pub a_stuffing: [u8; 1], | ||
| 297 | } | ||
| 298 | |||
| 299 | impl MacCommand for DpsRequest { | ||
| 300 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq; | ||
| 301 | } | ||
| 302 | |||
| 303 | /// MLME SOUNDING request primitive which is used by the next higher layer to request that | ||
| 304 | /// the PHY respond with channel sounding information | ||
| 305 | #[repr(C)] | ||
| 306 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 307 | pub struct SoundingRequest { | ||
| 308 | /// byte stuffing to keep 32 bit alignment | ||
| 309 | pub a_stuffing: [u8; 4], | ||
| 310 | } | ||
| 311 | |||
| 312 | impl MacCommand for SoundingRequest { | ||
| 313 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq; | ||
| 314 | } | ||
| 315 | |||
| 316 | /// MLME CALIBRATE request primitive which used to obtain the results of a ranging | ||
| 317 | /// calibration request from an RDEV | ||
| 318 | #[repr(C)] | ||
| 319 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 320 | pub struct CalibrateRequest { | ||
| 321 | /// byte stuffing to keep 32 bit alignment | ||
| 322 | pub a_stuffing: [u8; 4], | ||
| 323 | } | ||
| 324 | |||
| 325 | impl MacCommand for CalibrateRequest { | ||
| 326 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq; | ||
| 327 | } | ||
| 328 | |||
| 329 | /// MCPS DATA Request used for MAC data related requests from the application | ||
| 330 | #[repr(C)] | ||
| 331 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 332 | pub struct DataRequest { | ||
| 333 | /// the handle assocated with the MSDU to be transmitted | ||
| 334 | pub msdu_ptr: *const u8, | ||
| 335 | /// source addressing mode used | ||
| 336 | pub src_addr_mode: AddressMode, | ||
| 337 | /// destination addressing mode used | ||
| 338 | pub dst_addr_mode: AddressMode, | ||
| 339 | /// destination PAN Id | ||
| 340 | pub dst_pan_id: PanId, | ||
| 341 | /// destination address | ||
| 342 | pub dst_address: MacAddress, | ||
| 343 | /// the number of octets contained in the MSDU | ||
| 344 | pub msdu_length: u8, | ||
| 345 | /// the handle assocated with the MSDU to be transmitted | ||
| 346 | pub msdu_handle: u8, | ||
| 347 | /// the ACK transmittion options for the MSDU | ||
| 348 | pub ack_tx: u8, | ||
| 349 | /// `true` if a GTS is to be used for transmission | ||
| 350 | /// | ||
| 351 | /// `false` indicates that the CAP will be used | ||
| 352 | pub gts_tx: bool, | ||
| 353 | /// the pending bit transmission options for the MSDU | ||
| 354 | pub indirect_tx: u8, | ||
| 355 | /// the security level to be used | ||
| 356 | pub security_level: SecurityLevel, | ||
| 357 | /// the mode used to indentify the key to be used | ||
| 358 | pub key_id_mode: KeyIdMode, | ||
| 359 | /// the index of the key to be used | ||
| 360 | pub key_index: u8, | ||
| 361 | /// the originator of the key to be used | ||
| 362 | pub key_source: [u8; 8], | ||
| 363 | /// 2011 - the pulse repitition value | ||
| 364 | pub uwbprf: u8, | ||
| 365 | /// 2011 - the ranging configuration | ||
| 366 | pub ranging: u8, | ||
| 367 | /// 2011 - the preamble symbol repititions | ||
| 368 | pub uwb_preamble_symbol_repetitions: u8, | ||
| 369 | /// 2011 - indicates the data rate | ||
| 370 | pub datrate: u8, | ||
| 371 | } | ||
| 372 | |||
| 373 | impl DataRequest { | ||
| 374 | pub fn set_buffer<'a>(&'a mut self, buf: &'a [u8]) -> &'a mut Self { | ||
| 375 | self.msdu_ptr = buf as *const _ as *const u8; | ||
| 376 | self.msdu_length = buf.len() as u8; | ||
| 377 | |||
| 378 | self | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 382 | impl Default for DataRequest { | ||
| 383 | fn default() -> Self { | ||
| 384 | Self { | ||
| 385 | msdu_ptr: 0 as *const u8, | ||
| 386 | src_addr_mode: AddressMode::NoAddress, | ||
| 387 | dst_addr_mode: AddressMode::NoAddress, | ||
| 388 | dst_pan_id: PanId([0, 0]), | ||
| 389 | dst_address: MacAddress { short: [0, 0] }, | ||
| 390 | msdu_length: 0, | ||
| 391 | msdu_handle: 0, | ||
| 392 | ack_tx: 0, | ||
| 393 | gts_tx: false, | ||
| 394 | indirect_tx: 0, | ||
| 395 | security_level: SecurityLevel::Unsecure, | ||
| 396 | key_id_mode: KeyIdMode::Implicite, | ||
| 397 | key_index: 0, | ||
| 398 | key_source: [0u8; 8], | ||
| 399 | uwbprf: 0, | ||
| 400 | ranging: 0, | ||
| 401 | uwb_preamble_symbol_repetitions: 0, | ||
| 402 | datrate: 0, | ||
| 403 | } | ||
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | impl MacCommand for DataRequest { | ||
| 408 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq; | ||
| 409 | } | ||
| 410 | |||
| 411 | /// for MCPS PURGE Request used to purge an MSDU from the transaction queue | ||
| 412 | #[repr(C)] | ||
| 413 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 414 | pub struct PurgeRequest { | ||
| 415 | /// the handle associated with the MSDU to be purged from the transaction | ||
| 416 | /// queue | ||
| 417 | pub msdu_handle: u8, | ||
| 418 | /// byte stuffing to keep 32 bit alignment | ||
| 419 | pub a_stuffing: [u8; 3], | ||
| 420 | } | ||
| 421 | |||
| 422 | impl MacCommand for PurgeRequest { | ||
| 423 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq; | ||
| 424 | } | ||
| 425 | |||
| 426 | /// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication | ||
| 427 | #[repr(C)] | ||
| 428 | #[derive(Default)] | ||
| 429 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 430 | pub struct AssociateResponse { | ||
| 431 | /// extended address of the device requesting association | ||
| 432 | pub device_address: [u8; 8], | ||
| 433 | /// 16-bitshort device address allocated by the coordinator on successful | ||
| 434 | /// association | ||
| 435 | pub assoc_short_address: [u8; 2], | ||
| 436 | /// status of the association attempt | ||
| 437 | pub status: MacStatus, | ||
| 438 | /// security level to be used | ||
| 439 | pub security_level: SecurityLevel, | ||
| 440 | /// the originator of the key to be used | ||
| 441 | pub key_source: [u8; 8], | ||
| 442 | /// the mode used to identify the key to be used | ||
| 443 | pub key_id_mode: KeyIdMode, | ||
| 444 | /// the index of the key to be used | ||
| 445 | pub key_index: u8, | ||
| 446 | /// byte stuffing to keep 32 bit alignment | ||
| 447 | pub a_stuffing: [u8; 2], | ||
| 448 | } | ||
| 449 | |||
| 450 | impl MacCommand for AssociateResponse { | ||
| 451 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes; | ||
| 452 | } | ||
| 453 | |||
| 454 | /// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication | ||
| 455 | #[repr(C)] | ||
| 456 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 457 | pub struct OrphanResponse { | ||
| 458 | /// extended address of the orphaned device | ||
| 459 | pub orphan_address: [u8; 8], | ||
| 460 | /// short address allocated to the orphaned device | ||
| 461 | pub short_address: [u8; 2], | ||
| 462 | /// if the orphaned device is associated with coordinator or not | ||
| 463 | pub associated_member: bool, | ||
| 464 | /// security level to be used | ||
| 465 | pub security_level: SecurityLevel, | ||
| 466 | /// the originator of the key to be used | ||
| 467 | pub key_source: [u8; 8], | ||
| 468 | /// the mode used to identify the key to be used | ||
| 469 | pub key_id_mode: KeyIdMode, | ||
| 470 | /// the index of the key to be used | ||
| 471 | pub key_index: u8, | ||
| 472 | /// byte stuffing to keep 32 bit alignment | ||
| 473 | pub a_stuffing: [u8; 2], | ||
| 474 | } | ||
| 475 | |||
| 476 | impl MacCommand for OrphanResponse { | ||
| 477 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes; | ||
| 478 | } | ||
diff --git a/embassy-stm32-wpan/src/mac/consts.rs b/embassy-stm32-wpan/src/mac/consts.rs deleted file mode 100644 index 56903d980..000000000 --- a/embassy-stm32-wpan/src/mac/consts.rs +++ /dev/null | |||
| @@ -1,4 +0,0 @@ | |||
| 1 | pub const MAX_PAN_DESC_SUPPORTED: usize = 6; | ||
| 2 | pub const MAX_SOUNDING_LIST_SUPPORTED: usize = 6; | ||
| 3 | pub const MAX_PENDING_ADDRESS: usize = 7; | ||
| 4 | pub const MAX_ED_SCAN_RESULTS_SUPPORTED: usize = 16; | ||
diff --git a/embassy-stm32-wpan/src/mac/control.rs b/embassy-stm32-wpan/src/mac/control.rs deleted file mode 100644 index e8d2f9f7b..000000000 --- a/embassy-stm32-wpan/src/mac/control.rs +++ /dev/null | |||
| @@ -1,95 +0,0 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | use core::task; | ||
| 3 | use core::task::Poll; | ||
| 4 | |||
| 5 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 6 | use embassy_sync::mutex::MutexGuard; | ||
| 7 | use embassy_sync::signal::Signal; | ||
| 8 | use futures_util::FutureExt; | ||
| 9 | |||
| 10 | use super::commands::MacCommand; | ||
| 11 | use super::event::MacEvent; | ||
| 12 | use super::typedefs::MacError; | ||
| 13 | use crate::mac::runner::Runner; | ||
| 14 | |||
| 15 | pub struct Control<'a> { | ||
| 16 | runner: &'a Runner<'a>, | ||
| 17 | } | ||
| 18 | |||
| 19 | impl<'a> Control<'a> { | ||
| 20 | pub(crate) fn new(runner: &'a Runner<'a>) -> Self { | ||
| 21 | Self { runner: runner } | ||
| 22 | } | ||
| 23 | |||
| 24 | pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError> | ||
| 25 | where | ||
| 26 | T: MacCommand, | ||
| 27 | { | ||
| 28 | let _wm = self.runner.write_mutex.lock().await; | ||
| 29 | |||
| 30 | self.runner.mac_subsystem.send_command(cmd).await | ||
| 31 | } | ||
| 32 | |||
| 33 | pub async fn send_command_and_get_response<T>(&self, cmd: &T) -> Result<EventToken<'a>, MacError> | ||
| 34 | where | ||
| 35 | T: MacCommand, | ||
| 36 | { | ||
| 37 | let rm = self.runner.read_mutex.lock().await; | ||
| 38 | let _wm = self.runner.write_mutex.lock().await; | ||
| 39 | let token = EventToken::new(self.runner, rm); | ||
| 40 | |||
| 41 | self.runner.mac_subsystem.send_command(cmd).await?; | ||
| 42 | |||
| 43 | Ok(token) | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | pub struct EventToken<'a> { | ||
| 48 | runner: &'a Runner<'a>, | ||
| 49 | _mutex_guard: MutexGuard<'a, CriticalSectionRawMutex, ()>, | ||
| 50 | } | ||
| 51 | |||
| 52 | impl<'a> EventToken<'a> { | ||
| 53 | pub(crate) fn new(runner: &'a Runner<'a>, mutex_guard: MutexGuard<'a, CriticalSectionRawMutex, ()>) -> Self { | ||
| 54 | // Enable event receiving | ||
| 55 | runner.rx_event_channel.lock(|s| { | ||
| 56 | *s.borrow_mut() = Some(Signal::new()); | ||
| 57 | }); | ||
| 58 | |||
| 59 | Self { | ||
| 60 | runner: runner, | ||
| 61 | _mutex_guard: mutex_guard, | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | impl<'a> Future for EventToken<'a> { | ||
| 67 | type Output = MacEvent<'a>; | ||
| 68 | |||
| 69 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> { | ||
| 70 | self.get_mut().runner.rx_event_channel.lock(|s| { | ||
| 71 | let signal = s.borrow_mut(); | ||
| 72 | let signal = match &*signal { | ||
| 73 | Some(s) => s, | ||
| 74 | _ => unreachable!(), | ||
| 75 | }; | ||
| 76 | |||
| 77 | let result = match signal.wait().poll_unpin(cx) { | ||
| 78 | Poll::Ready(mac_event) => Poll::Ready(mac_event), | ||
| 79 | Poll::Pending => Poll::Pending, | ||
| 80 | }; | ||
| 81 | |||
| 82 | result | ||
| 83 | }) | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | impl<'a> Drop for EventToken<'a> { | ||
| 88 | fn drop(&mut self) { | ||
| 89 | // Disable event receiving | ||
| 90 | // This will also drop the contained event, if it exists, and will free up receiving the next event | ||
| 91 | self.runner.rx_event_channel.lock(|s| { | ||
| 92 | *s.borrow_mut() = None; | ||
| 93 | }); | ||
| 94 | } | ||
| 95 | } | ||
diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs deleted file mode 100644 index 41cca09e3..000000000 --- a/embassy-stm32-wpan/src/mac/driver.rs +++ /dev/null | |||
| @@ -1,120 +0,0 @@ | |||
| 1 | #![deny(unused_must_use)] | ||
| 2 | |||
| 3 | use core::task::Context; | ||
| 4 | |||
| 5 | use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; | ||
| 6 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 7 | use embassy_sync::channel::Channel; | ||
| 8 | |||
| 9 | use crate::mac::event::MacEvent; | ||
| 10 | use crate::mac::runner::Runner; | ||
| 11 | use crate::mac::MTU; | ||
| 12 | |||
| 13 | pub struct Driver<'d> { | ||
| 14 | runner: &'d Runner<'d>, | ||
| 15 | } | ||
| 16 | |||
| 17 | impl<'d> Driver<'d> { | ||
| 18 | pub(crate) fn new(runner: &'d Runner<'d>) -> Self { | ||
| 19 | Self { runner: runner } | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | impl<'d> embassy_net_driver::Driver for Driver<'d> { | ||
| 24 | // type RxToken<'a> = RxToken<'a, 'd> where Self: 'a; | ||
| 25 | // type TxToken<'a> = TxToken<'a, 'd> where Self: 'a; | ||
| 26 | type RxToken<'a> | ||
| 27 | = RxToken<'d> | ||
| 28 | where | ||
| 29 | Self: 'a; | ||
| 30 | type TxToken<'a> | ||
| 31 | = TxToken<'d> | ||
| 32 | where | ||
| 33 | Self: 'a; | ||
| 34 | |||
| 35 | fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { | ||
| 36 | if self.runner.rx_channel.poll_ready_to_receive(cx).is_ready() | ||
| 37 | && self.runner.tx_buf_channel.poll_ready_to_receive(cx).is_ready() | ||
| 38 | { | ||
| 39 | Some(( | ||
| 40 | RxToken { | ||
| 41 | rx: &self.runner.rx_channel, | ||
| 42 | }, | ||
| 43 | TxToken { | ||
| 44 | tx: &self.runner.tx_channel, | ||
| 45 | tx_buf: &self.runner.tx_buf_channel, | ||
| 46 | }, | ||
| 47 | )) | ||
| 48 | } else { | ||
| 49 | None | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> { | ||
| 54 | if self.runner.tx_buf_channel.poll_ready_to_receive(cx).is_ready() { | ||
| 55 | Some(TxToken { | ||
| 56 | tx: &self.runner.tx_channel, | ||
| 57 | tx_buf: &self.runner.tx_buf_channel, | ||
| 58 | }) | ||
| 59 | } else { | ||
| 60 | None | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | fn capabilities(&self) -> Capabilities { | ||
| 65 | let mut caps = Capabilities::default(); | ||
| 66 | caps.max_transmission_unit = MTU; | ||
| 67 | // caps.max_burst_size = Some(self.tx.len()); | ||
| 68 | caps | ||
| 69 | } | ||
| 70 | |||
| 71 | fn link_state(&mut self, _cx: &mut Context) -> LinkState { | ||
| 72 | LinkState::Down | ||
| 73 | } | ||
| 74 | |||
| 75 | fn hardware_address(&self) -> HardwareAddress { | ||
| 76 | // self.mac_addr | ||
| 77 | HardwareAddress::Ieee802154([0; 8]) | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | pub struct RxToken<'d> { | ||
| 82 | rx: &'d Channel<CriticalSectionRawMutex, MacEvent<'d>, 1>, | ||
| 83 | } | ||
| 84 | |||
| 85 | impl<'d> embassy_net_driver::RxToken for RxToken<'d> { | ||
| 86 | fn consume<R, F>(self, f: F) -> R | ||
| 87 | where | ||
| 88 | F: FnOnce(&mut [u8]) -> R, | ||
| 89 | { | ||
| 90 | // Only valid data events should be put into the queue | ||
| 91 | |||
| 92 | let data_event = match self.rx.try_receive().unwrap() { | ||
| 93 | MacEvent::McpsDataInd(data_event) => data_event, | ||
| 94 | _ => unreachable!(), | ||
| 95 | }; | ||
| 96 | |||
| 97 | f(&mut data_event.payload()) | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | pub struct TxToken<'d> { | ||
| 102 | tx: &'d Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), 5>, | ||
| 103 | tx_buf: &'d Channel<CriticalSectionRawMutex, &'d mut [u8; MTU], 5>, | ||
| 104 | } | ||
| 105 | |||
| 106 | impl<'d> embassy_net_driver::TxToken for TxToken<'d> { | ||
| 107 | fn consume<R, F>(self, len: usize, f: F) -> R | ||
| 108 | where | ||
| 109 | F: FnOnce(&mut [u8]) -> R, | ||
| 110 | { | ||
| 111 | // Only valid tx buffers should be put into the queue | ||
| 112 | let buf = self.tx_buf.try_receive().unwrap(); | ||
| 113 | let r = f(&mut buf[..len]); | ||
| 114 | |||
| 115 | // The tx channel should always be of equal capacity to the tx_buf channel | ||
| 116 | self.tx.try_send((buf, len)).unwrap(); | ||
| 117 | |||
| 118 | r | ||
| 119 | } | ||
| 120 | } | ||
diff --git a/embassy-stm32-wpan/src/mac/event.rs b/embassy-stm32-wpan/src/mac/event.rs deleted file mode 100644 index 9ca4f5a2a..000000000 --- a/embassy-stm32-wpan/src/mac/event.rs +++ /dev/null | |||
| @@ -1,153 +0,0 @@ | |||
| 1 | use core::{mem, ptr}; | ||
| 2 | |||
| 3 | use super::indications::{ | ||
| 4 | AssociateIndication, BeaconNotifyIndication, CommStatusIndication, DataIndication, DisassociateIndication, | ||
| 5 | DpsIndication, GtsIndication, OrphanIndication, PollIndication, SyncLossIndication, | ||
| 6 | }; | ||
| 7 | use super::responses::{ | ||
| 8 | AssociateConfirm, CalibrateConfirm, DataConfirm, DisassociateConfirm, DpsConfirm, GetConfirm, GtsConfirm, | ||
| 9 | PollConfirm, PurgeConfirm, ResetConfirm, RxEnableConfirm, ScanConfirm, SetConfirm, SoundingConfirm, StartConfirm, | ||
| 10 | }; | ||
| 11 | use crate::evt::{EvtBox, MemoryManager}; | ||
| 12 | use crate::mac::opcodes::OpcodeM0ToM4; | ||
| 13 | use crate::sub::mac::{self, Mac}; | ||
| 14 | |||
| 15 | pub(crate) trait ParseableMacEvent: Sized { | ||
| 16 | fn from_buffer<'a>(buf: &'a [u8]) -> Result<&'a Self, ()> { | ||
| 17 | if buf.len() < mem::size_of::<Self>() { | ||
| 18 | Err(()) | ||
| 19 | } else { | ||
| 20 | Ok(unsafe { &*(buf as *const _ as *const Self) }) | ||
| 21 | } | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 26 | #[derive(Debug)] | ||
| 27 | pub enum MacEvent<'a> { | ||
| 28 | MlmeAssociateCnf(&'a AssociateConfirm), | ||
| 29 | MlmeDisassociateCnf(&'a DisassociateConfirm), | ||
| 30 | MlmeGetCnf(&'a GetConfirm), | ||
| 31 | MlmeGtsCnf(&'a GtsConfirm), | ||
| 32 | MlmeResetCnf(&'a ResetConfirm), | ||
| 33 | MlmeRxEnableCnf(&'a RxEnableConfirm), | ||
| 34 | MlmeScanCnf(&'a ScanConfirm), | ||
| 35 | MlmeSetCnf(&'a SetConfirm), | ||
| 36 | MlmeStartCnf(&'a StartConfirm), | ||
| 37 | MlmePollCnf(&'a PollConfirm), | ||
| 38 | MlmeDpsCnf(&'a DpsConfirm), | ||
| 39 | MlmeSoundingCnf(&'a SoundingConfirm), | ||
| 40 | MlmeCalibrateCnf(&'a CalibrateConfirm), | ||
| 41 | McpsDataCnf(&'a DataConfirm), | ||
| 42 | McpsPurgeCnf(&'a PurgeConfirm), | ||
| 43 | MlmeAssociateInd(&'a AssociateIndication), | ||
| 44 | MlmeDisassociateInd(&'a DisassociateIndication), | ||
| 45 | MlmeBeaconNotifyInd(&'a BeaconNotifyIndication), | ||
| 46 | MlmeCommStatusInd(&'a CommStatusIndication), | ||
| 47 | MlmeGtsInd(&'a GtsIndication), | ||
| 48 | MlmeOrphanInd(&'a OrphanIndication), | ||
| 49 | MlmeSyncLossInd(&'a SyncLossIndication), | ||
| 50 | MlmeDpsInd(&'a DpsIndication), | ||
| 51 | McpsDataInd(&'a DataIndication), | ||
| 52 | MlmePollInd(&'a PollIndication), | ||
| 53 | } | ||
| 54 | |||
| 55 | impl<'a> MacEvent<'a> { | ||
| 56 | pub(crate) fn new(event_box: EvtBox<Mac>) -> Result<Self, ()> { | ||
| 57 | let payload = event_box.payload(); | ||
| 58 | let opcode = u16::from_le_bytes(payload[0..2].try_into().unwrap()); | ||
| 59 | |||
| 60 | let opcode = OpcodeM0ToM4::try_from(opcode)?; | ||
| 61 | let buf = &payload[2..]; | ||
| 62 | |||
| 63 | // To avoid re-parsing the opcode, we store the result of the parse | ||
| 64 | // this requires use of unsafe because rust cannot assume that a reference will become | ||
| 65 | // invalid when the underlying result is moved. However, because we refer to a "heap" | ||
| 66 | // allocation, the underlying reference will not move until the struct is dropped. | ||
| 67 | |||
| 68 | let mac_event = match opcode { | ||
| 69 | OpcodeM0ToM4::MlmeAssociateCnf => { | ||
| 70 | MacEvent::MlmeAssociateCnf(unsafe { &*(AssociateConfirm::from_buffer(buf)? as *const _) }) | ||
| 71 | } | ||
| 72 | OpcodeM0ToM4::MlmeDisassociateCnf => { | ||
| 73 | MacEvent::MlmeDisassociateCnf(unsafe { &*(DisassociateConfirm::from_buffer(buf)? as *const _) }) | ||
| 74 | } | ||
| 75 | OpcodeM0ToM4::MlmeGetCnf => MacEvent::MlmeGetCnf(unsafe { &*(GetConfirm::from_buffer(buf)? as *const _) }), | ||
| 76 | OpcodeM0ToM4::MlmeGtsCnf => MacEvent::MlmeGtsCnf(unsafe { &*(GtsConfirm::from_buffer(buf)? as *const _) }), | ||
| 77 | OpcodeM0ToM4::MlmeResetCnf => { | ||
| 78 | MacEvent::MlmeResetCnf(unsafe { &*(ResetConfirm::from_buffer(buf)? as *const _) }) | ||
| 79 | } | ||
| 80 | OpcodeM0ToM4::MlmeRxEnableCnf => { | ||
| 81 | MacEvent::MlmeRxEnableCnf(unsafe { &*(RxEnableConfirm::from_buffer(buf)? as *const _) }) | ||
| 82 | } | ||
| 83 | OpcodeM0ToM4::MlmeScanCnf => { | ||
| 84 | MacEvent::MlmeScanCnf(unsafe { &*(ScanConfirm::from_buffer(buf)? as *const _) }) | ||
| 85 | } | ||
| 86 | OpcodeM0ToM4::MlmeSetCnf => MacEvent::MlmeSetCnf(unsafe { &*(SetConfirm::from_buffer(buf)? as *const _) }), | ||
| 87 | OpcodeM0ToM4::MlmeStartCnf => { | ||
| 88 | MacEvent::MlmeStartCnf(unsafe { &*(StartConfirm::from_buffer(buf)? as *const _) }) | ||
| 89 | } | ||
| 90 | OpcodeM0ToM4::MlmePollCnf => { | ||
| 91 | MacEvent::MlmePollCnf(unsafe { &*(PollConfirm::from_buffer(buf)? as *const _) }) | ||
| 92 | } | ||
| 93 | OpcodeM0ToM4::MlmeDpsCnf => MacEvent::MlmeDpsCnf(unsafe { &*(DpsConfirm::from_buffer(buf)? as *const _) }), | ||
| 94 | OpcodeM0ToM4::MlmeSoundingCnf => { | ||
| 95 | MacEvent::MlmeSoundingCnf(unsafe { &*(SoundingConfirm::from_buffer(buf)? as *const _) }) | ||
| 96 | } | ||
| 97 | OpcodeM0ToM4::MlmeCalibrateCnf => { | ||
| 98 | MacEvent::MlmeCalibrateCnf(unsafe { &*(CalibrateConfirm::from_buffer(buf)? as *const _) }) | ||
| 99 | } | ||
| 100 | OpcodeM0ToM4::McpsDataCnf => { | ||
| 101 | MacEvent::McpsDataCnf(unsafe { &*(DataConfirm::from_buffer(buf)? as *const _) }) | ||
| 102 | } | ||
| 103 | OpcodeM0ToM4::McpsPurgeCnf => { | ||
| 104 | MacEvent::McpsPurgeCnf(unsafe { &*(PurgeConfirm::from_buffer(buf)? as *const _) }) | ||
| 105 | } | ||
| 106 | OpcodeM0ToM4::MlmeAssociateInd => { | ||
| 107 | MacEvent::MlmeAssociateInd(unsafe { &*(AssociateIndication::from_buffer(buf)? as *const _) }) | ||
| 108 | } | ||
| 109 | OpcodeM0ToM4::MlmeDisassociateInd => { | ||
| 110 | MacEvent::MlmeDisassociateInd(unsafe { &*(DisassociateIndication::from_buffer(buf)? as *const _) }) | ||
| 111 | } | ||
| 112 | OpcodeM0ToM4::MlmeBeaconNotifyInd => { | ||
| 113 | MacEvent::MlmeBeaconNotifyInd(unsafe { &*(BeaconNotifyIndication::from_buffer(buf)? as *const _) }) | ||
| 114 | } | ||
| 115 | OpcodeM0ToM4::MlmeCommStatusInd => { | ||
| 116 | MacEvent::MlmeCommStatusInd(unsafe { &*(CommStatusIndication::from_buffer(buf)? as *const _) }) | ||
| 117 | } | ||
| 118 | OpcodeM0ToM4::MlmeGtsInd => { | ||
| 119 | MacEvent::MlmeGtsInd(unsafe { &*(GtsIndication::from_buffer(buf)? as *const _) }) | ||
| 120 | } | ||
| 121 | OpcodeM0ToM4::MlmeOrphanInd => { | ||
| 122 | MacEvent::MlmeOrphanInd(unsafe { &*(OrphanIndication::from_buffer(buf)? as *const _) }) | ||
| 123 | } | ||
| 124 | OpcodeM0ToM4::MlmeSyncLossInd => { | ||
| 125 | MacEvent::MlmeSyncLossInd(unsafe { &*(SyncLossIndication::from_buffer(buf)? as *const _) }) | ||
| 126 | } | ||
| 127 | OpcodeM0ToM4::MlmeDpsInd => { | ||
| 128 | MacEvent::MlmeDpsInd(unsafe { &*(DpsIndication::from_buffer(buf)? as *const _) }) | ||
| 129 | } | ||
| 130 | OpcodeM0ToM4::McpsDataInd => { | ||
| 131 | MacEvent::McpsDataInd(unsafe { &*(DataIndication::from_buffer(buf)? as *const _) }) | ||
| 132 | } | ||
| 133 | OpcodeM0ToM4::MlmePollInd => { | ||
| 134 | MacEvent::MlmePollInd(unsafe { &*(PollIndication::from_buffer(buf)? as *const _) }) | ||
| 135 | } | ||
| 136 | }; | ||
| 137 | |||
| 138 | // Forget the event box so that drop isn't called | ||
| 139 | // We want to handle the lifetime ourselves | ||
| 140 | |||
| 141 | mem::forget(event_box); | ||
| 142 | |||
| 143 | Ok(mac_event) | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | unsafe impl<'a> Send for MacEvent<'a> {} | ||
| 148 | |||
| 149 | impl<'a> Drop for MacEvent<'a> { | ||
| 150 | fn drop(&mut self) { | ||
| 151 | unsafe { mac::Mac::drop_event_packet(ptr::null_mut()) }; | ||
| 152 | } | ||
| 153 | } | ||
diff --git a/embassy-stm32-wpan/src/mac/indications.rs b/embassy-stm32-wpan/src/mac/indications.rs deleted file mode 100644 index c0b86d745..000000000 --- a/embassy-stm32-wpan/src/mac/indications.rs +++ /dev/null | |||
| @@ -1,265 +0,0 @@ | |||
| 1 | use core::slice; | ||
| 2 | |||
| 3 | use super::consts::MAX_PENDING_ADDRESS; | ||
| 4 | use super::event::ParseableMacEvent; | ||
| 5 | use super::typedefs::{ | ||
| 6 | AddressMode, Capabilities, DisassociationReason, KeyIdMode, MacAddress, MacChannel, MacStatus, PanDescriptor, | ||
| 7 | PanId, SecurityLevel, | ||
| 8 | }; | ||
| 9 | |||
| 10 | /// MLME ASSOCIATE Indication which will be used by the MAC | ||
| 11 | /// to indicate the reception of an association request command | ||
| 12 | #[repr(C)] | ||
| 13 | #[derive(Debug)] | ||
| 14 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 15 | pub struct AssociateIndication { | ||
| 16 | /// Extended address of the device requesting association | ||
| 17 | pub device_address: [u8; 8], | ||
| 18 | /// Operational capabilities of the device requesting association | ||
| 19 | pub capability_information: Capabilities, | ||
| 20 | /// Security level purportedly used by the received MAC command frame | ||
| 21 | pub security_level: SecurityLevel, | ||
| 22 | /// The mode used to identify the key used by the originator of frame | ||
| 23 | pub key_id_mode: KeyIdMode, | ||
| 24 | /// Index of the key used by the originator of the received frame | ||
| 25 | pub key_index: u8, | ||
| 26 | /// The originator of the key used by the originator of the received frame | ||
| 27 | pub key_source: [u8; 8], | ||
| 28 | } | ||
| 29 | |||
| 30 | impl ParseableMacEvent for AssociateIndication {} | ||
| 31 | |||
| 32 | /// MLME DISASSOCIATE indication which will be used to send | ||
| 33 | /// disassociation indication to the application. | ||
| 34 | #[repr(C)] | ||
| 35 | #[derive(Debug)] | ||
| 36 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 37 | pub struct DisassociateIndication { | ||
| 38 | /// Extended address of the device requesting association | ||
| 39 | pub device_address: [u8; 8], | ||
| 40 | /// The reason for the disassociation | ||
| 41 | pub disassociation_reason: DisassociationReason, | ||
| 42 | /// The security level to be used | ||
| 43 | pub security_level: SecurityLevel, | ||
| 44 | /// The mode used to identify the key to be used | ||
| 45 | pub key_id_mode: KeyIdMode, | ||
| 46 | /// The index of the key to be used | ||
| 47 | pub key_index: u8, | ||
| 48 | /// The originator of the key to be used | ||
| 49 | pub key_source: [u8; 8], | ||
| 50 | } | ||
| 51 | |||
| 52 | impl ParseableMacEvent for DisassociateIndication {} | ||
| 53 | |||
| 54 | /// MLME BEACON NOTIIFY Indication which is used to send parameters contained | ||
| 55 | /// within a beacon frame received by the MAC to the application | ||
| 56 | #[repr(C)] | ||
| 57 | #[derive(Debug)] | ||
| 58 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 59 | pub struct BeaconNotifyIndication { | ||
| 60 | /// he set of octets comprising the beacon payload to be transferred | ||
| 61 | /// from the MAC sublayer entity to the next higher layer | ||
| 62 | pub sdu_ptr: *const u8, | ||
| 63 | /// The PAN Descriptor for the received beacon | ||
| 64 | pub pan_descriptor: PanDescriptor, | ||
| 65 | /// The list of addresses of the devices | ||
| 66 | pub addr_list: [MacAddress; MAX_PENDING_ADDRESS], | ||
| 67 | /// Beacon Sequence Number | ||
| 68 | pub bsn: u8, | ||
| 69 | /// The beacon pending address specification | ||
| 70 | pub pend_addr_spec: u8, | ||
| 71 | /// Number of octets contained in the beacon payload of the beacon frame | ||
| 72 | pub sdu_length: u8, | ||
| 73 | } | ||
| 74 | |||
| 75 | impl ParseableMacEvent for BeaconNotifyIndication {} | ||
| 76 | |||
| 77 | /// MLME COMM STATUS Indication which is used by the MAC to indicate a communications status | ||
| 78 | #[repr(C)] | ||
| 79 | #[derive(Debug)] | ||
| 80 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 81 | pub struct CommStatusIndication { | ||
| 82 | /// The 16-bit PAN identifier of the device from which the frame | ||
| 83 | /// was received or to which the frame was being sent | ||
| 84 | pub pan_id: PanId, | ||
| 85 | /// Source addressing mode | ||
| 86 | pub src_addr_mode: AddressMode, | ||
| 87 | /// Destination addressing mode | ||
| 88 | pub dst_addr_mode: AddressMode, | ||
| 89 | /// Source address | ||
| 90 | pub src_address: MacAddress, | ||
| 91 | /// Destination address | ||
| 92 | pub dst_address: MacAddress, | ||
| 93 | /// The communications status | ||
| 94 | pub status: MacStatus, | ||
| 95 | /// Security level to be used | ||
| 96 | pub security_level: SecurityLevel, | ||
| 97 | /// Mode used to identify the key to be used | ||
| 98 | pub key_id_mode: KeyIdMode, | ||
| 99 | /// Index of the key to be used | ||
| 100 | pub key_index: u8, | ||
| 101 | /// Originator of the key to be used | ||
| 102 | pub key_source: [u8; 8], | ||
| 103 | } | ||
| 104 | |||
| 105 | impl ParseableMacEvent for CommStatusIndication {} | ||
| 106 | |||
| 107 | /// MLME GTS Indication indicates that a GTS has been allocated or that a | ||
| 108 | /// previously allocated GTS has been deallocated | ||
| 109 | #[repr(C)] | ||
| 110 | #[derive(Debug)] | ||
| 111 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 112 | pub struct GtsIndication { | ||
| 113 | /// The short address of the device that has been allocated or deallocated a GTS | ||
| 114 | pub device_address: [u8; 2], | ||
| 115 | /// The characteristics of the GTS | ||
| 116 | pub gts_characteristics: u8, | ||
| 117 | /// Security level to be used | ||
| 118 | pub security_level: SecurityLevel, | ||
| 119 | /// Mode used to identify the key to be used | ||
| 120 | pub key_id_mode: KeyIdMode, | ||
| 121 | /// Index of the key to be used | ||
| 122 | pub key_index: u8, | ||
| 123 | /// byte stuffing to keep 32 bit alignment | ||
| 124 | a_stuffing: [u8; 2], | ||
| 125 | /// Originator of the key to be used | ||
| 126 | pub key_source: [u8; 8], | ||
| 127 | } | ||
| 128 | |||
| 129 | impl ParseableMacEvent for GtsIndication {} | ||
| 130 | |||
| 131 | /// MLME ORPHAN Indication which is used by the coordinator to notify the | ||
| 132 | /// application of the presence of an orphaned device | ||
| 133 | #[repr(C)] | ||
| 134 | #[derive(Debug)] | ||
| 135 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 136 | pub struct OrphanIndication { | ||
| 137 | /// Extended address of the orphaned device | ||
| 138 | pub orphan_address: [u8; 8], | ||
| 139 | /// Originator of the key used by the originator of the received frame | ||
| 140 | pub key_source: [u8; 8], | ||
| 141 | /// Security level purportedly used by the received MAC command frame | ||
| 142 | pub security_level: SecurityLevel, | ||
| 143 | /// Mode used to identify the key used by originator of received frame | ||
| 144 | pub key_id_mode: KeyIdMode, | ||
| 145 | /// Index of the key used by the originator of the received frame | ||
| 146 | pub key_index: u8, | ||
| 147 | /// byte stuffing to keep 32 bit alignment | ||
| 148 | a_stuffing: [u8; 1], | ||
| 149 | } | ||
| 150 | |||
| 151 | impl ParseableMacEvent for OrphanIndication {} | ||
| 152 | |||
| 153 | /// MLME SYNC LOSS Indication which is used by the MAC to indicate the loss | ||
| 154 | /// of synchronization with the coordinator | ||
| 155 | #[repr(C)] | ||
| 156 | #[derive(Debug)] | ||
| 157 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 158 | pub struct SyncLossIndication { | ||
| 159 | /// The PAN identifier with which the device lost synchronization or to which it was realigned | ||
| 160 | pub pan_id: PanId, | ||
| 161 | /// The reason that synchronization was lost | ||
| 162 | pub loss_reason: u8, | ||
| 163 | /// The logical channel on which the device lost synchronization or to whi | ||
| 164 | pub channel_number: MacChannel, | ||
| 165 | /// The channel page on which the device lost synchronization or to which | ||
| 166 | pub channel_page: u8, | ||
| 167 | /// The security level used by the received MAC frame | ||
| 168 | pub security_level: SecurityLevel, | ||
| 169 | /// Mode used to identify the key used by originator of received frame | ||
| 170 | pub key_id_mode: KeyIdMode, | ||
| 171 | /// Index of the key used by the originator of the received frame | ||
| 172 | pub key_index: u8, | ||
| 173 | /// Originator of the key used by the originator of the received frame | ||
| 174 | pub key_source: [u8; 8], | ||
| 175 | } | ||
| 176 | |||
| 177 | impl ParseableMacEvent for SyncLossIndication {} | ||
| 178 | |||
| 179 | /// MLME DPS Indication which indicates the expiration of the DPSIndexDuration | ||
| 180 | /// and the resetting of the DPS values in the PHY | ||
| 181 | #[repr(C)] | ||
| 182 | #[derive(Debug)] | ||
| 183 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 184 | pub struct DpsIndication { | ||
| 185 | /// byte stuffing to keep 32 bit alignment | ||
| 186 | a_stuffing: [u8; 4], | ||
| 187 | } | ||
| 188 | |||
| 189 | impl ParseableMacEvent for DpsIndication {} | ||
| 190 | |||
| 191 | #[repr(C)] | ||
| 192 | #[derive(Debug)] | ||
| 193 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 194 | pub struct DataIndication { | ||
| 195 | /// Pointer to the set of octets forming the MSDU being indicated | ||
| 196 | pub msdu_ptr: *const u8, | ||
| 197 | /// Source addressing mode used | ||
| 198 | pub src_addr_mode: AddressMode, | ||
| 199 | /// Source PAN ID | ||
| 200 | pub src_pan_id: PanId, | ||
| 201 | /// Source address | ||
| 202 | pub src_address: MacAddress, | ||
| 203 | /// Destination addressing mode used | ||
| 204 | pub dst_addr_mode: AddressMode, | ||
| 205 | /// Destination PAN ID | ||
| 206 | pub dst_pan_id: PanId, | ||
| 207 | /// Destination address | ||
| 208 | pub dst_address: MacAddress, | ||
| 209 | /// The number of octets contained in the MSDU being indicated | ||
| 210 | pub msdu_length: u8, | ||
| 211 | /// QI value measured during reception of the MPDU | ||
| 212 | pub mpdu_link_quality: u8, | ||
| 213 | /// The data sequence number of the received data frame | ||
| 214 | pub dsn: u8, | ||
| 215 | /// The time, in symbols, at which the data were received | ||
| 216 | pub time_stamp: [u8; 4], | ||
| 217 | /// The security level purportedly used by the received data frame | ||
| 218 | security_level: SecurityLevel, | ||
| 219 | /// Mode used to identify the key used by originator of received frame | ||
| 220 | key_id_mode: KeyIdMode, | ||
| 221 | /// The originator of the key | ||
| 222 | pub key_source: [u8; 8], | ||
| 223 | /// The index of the key | ||
| 224 | pub key_index: u8, | ||
| 225 | /// he pulse repetition value of the received PPDU | ||
| 226 | pub uwbprf: u8, | ||
| 227 | /// The preamble symbol repetitions of the UWB PHY frame | ||
| 228 | pub uwn_preamble_symbol_repetitions: u8, | ||
| 229 | /// Indicates the data rate | ||
| 230 | pub datrate: u8, | ||
| 231 | /// time units corresponding to an RMARKER at the antenna at the end of a ranging exchange, | ||
| 232 | pub ranging_received: u8, | ||
| 233 | pub ranging_counter_start: u32, | ||
| 234 | pub ranging_counter_stop: u32, | ||
| 235 | /// ime units in a message exchange over which the tracking offset was measured | ||
| 236 | pub ranging_tracking_interval: u32, | ||
| 237 | /// time units slipped or advanced by the radio tracking system | ||
| 238 | pub ranging_offset: u32, | ||
| 239 | /// The FoM characterizing the ranging measurement | ||
| 240 | pub ranging_fom: u8, | ||
| 241 | /// The Received Signal Strength Indicator measured | ||
| 242 | pub rssi: u8, | ||
| 243 | } | ||
| 244 | |||
| 245 | impl ParseableMacEvent for DataIndication {} | ||
| 246 | |||
| 247 | impl DataIndication { | ||
| 248 | pub fn payload<'a>(&'a self) -> &'a mut [u8] { | ||
| 249 | unsafe { slice::from_raw_parts_mut(self.msdu_ptr as *mut _, self.msdu_length as usize) } | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | /// MLME POLL Indication which will be used for indicating the Data Request | ||
| 254 | /// reception to upper layer as defined in Zigbee r22 - D.8.2 | ||
| 255 | #[repr(C)] | ||
| 256 | #[derive(Debug)] | ||
| 257 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 258 | pub struct PollIndication { | ||
| 259 | /// addressing mode used | ||
| 260 | pub addr_mode: AddressMode, | ||
| 261 | /// Poll requester address | ||
| 262 | pub request_address: MacAddress, | ||
| 263 | } | ||
| 264 | |||
| 265 | impl ParseableMacEvent for PollIndication {} | ||
diff --git a/embassy-stm32-wpan/src/mac/macros.rs b/embassy-stm32-wpan/src/mac/macros.rs deleted file mode 100644 index 1a988a779..000000000 --- a/embassy-stm32-wpan/src/mac/macros.rs +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | #[macro_export] | ||
| 2 | macro_rules! numeric_enum { | ||
| 3 | (#[repr($repr:ident)] | ||
| 4 | $(#$attrs:tt)* $vis:vis enum $name:ident { | ||
| 5 | $($(#$enum_attrs:tt)* $enum:ident = $constant:expr),* $(,)? | ||
| 6 | } ) => { | ||
| 7 | #[repr($repr)] | ||
| 8 | $(#$attrs)* | ||
| 9 | $vis enum $name { | ||
| 10 | $($(#$enum_attrs)* $enum = $constant),* | ||
| 11 | } | ||
| 12 | |||
| 13 | impl ::core::convert::TryFrom<$repr> for $name { | ||
| 14 | type Error = (); | ||
| 15 | |||
| 16 | fn try_from(value: $repr) -> ::core::result::Result<Self, ()> { | ||
| 17 | match value { | ||
| 18 | $($constant => Ok( $name :: $enum ),)* | ||
| 19 | _ => Err(()) | ||
| 20 | } | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | impl ::core::convert::From<$name> for $repr { | ||
| 25 | fn from(value: $name) -> $repr { | ||
| 26 | match value { | ||
| 27 | $($name :: $enum => $constant,)* | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
diff --git a/embassy-stm32-wpan/src/mac/mod.rs b/embassy-stm32-wpan/src/mac/mod.rs deleted file mode 100644 index c847a5cca..000000000 --- a/embassy-stm32-wpan/src/mac/mod.rs +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | pub mod commands; | ||
| 2 | mod consts; | ||
| 3 | pub mod control; | ||
| 4 | mod driver; | ||
| 5 | pub mod event; | ||
| 6 | pub mod indications; | ||
| 7 | mod macros; | ||
| 8 | mod opcodes; | ||
| 9 | pub mod responses; | ||
| 10 | pub mod runner; | ||
| 11 | pub mod typedefs; | ||
| 12 | |||
| 13 | pub use crate::mac::control::Control; | ||
| 14 | use crate::mac::driver::Driver; | ||
| 15 | pub use crate::mac::runner::Runner; | ||
| 16 | |||
| 17 | const MTU: usize = 127; | ||
| 18 | |||
| 19 | pub async fn new<'a>(runner: &'a Runner<'a>) -> (Control<'a>, Driver<'a>) { | ||
| 20 | (Control::new(runner), Driver::new(runner)) | ||
| 21 | } | ||
diff --git a/embassy-stm32-wpan/src/mac/opcodes.rs b/embassy-stm32-wpan/src/mac/opcodes.rs deleted file mode 100644 index fd7011873..000000000 --- a/embassy-stm32-wpan/src/mac/opcodes.rs +++ /dev/null | |||
| @@ -1,92 +0,0 @@ | |||
| 1 | const ST_VENDOR_OGF: u16 = 0x3F; | ||
| 2 | const MAC_802_15_4_CMD_OPCODE_OFFSET: u16 = 0x280; | ||
| 3 | |||
| 4 | const fn opcode(ocf: u16) -> isize { | ||
| 5 | ((ST_VENDOR_OGF << 9) | (MAC_802_15_4_CMD_OPCODE_OFFSET + ocf)) as isize | ||
| 6 | } | ||
| 7 | |||
| 8 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 9 | pub enum OpcodeM4ToM0 { | ||
| 10 | MlmeAssociateReq = opcode(0x00), | ||
| 11 | MlmeAssociateRes = opcode(0x01), | ||
| 12 | MlmeDisassociateReq = opcode(0x02), | ||
| 13 | MlmeGetReq = opcode(0x03), | ||
| 14 | MlmeGtsReq = opcode(0x04), | ||
| 15 | MlmeOrphanRes = opcode(0x05), | ||
| 16 | MlmeResetReq = opcode(0x06), | ||
| 17 | MlmeRxEnableReq = opcode(0x07), | ||
| 18 | MlmeScanReq = opcode(0x08), | ||
| 19 | MlmeSetReq = opcode(0x09), | ||
| 20 | MlmeStartReq = opcode(0x0A), | ||
| 21 | MlmeSyncReq = opcode(0x0B), | ||
| 22 | MlmePollReq = opcode(0x0C), | ||
| 23 | MlmeDpsReq = opcode(0x0D), | ||
| 24 | MlmeSoundingReq = opcode(0x0E), | ||
| 25 | MlmeCalibrateReq = opcode(0x0F), | ||
| 26 | McpsDataReq = opcode(0x10), | ||
| 27 | McpsPurgeReq = opcode(0x11), | ||
| 28 | } | ||
| 29 | |||
| 30 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 31 | pub enum OpcodeM0ToM4 { | ||
| 32 | MlmeAssociateCnf = 0x00, | ||
| 33 | MlmeDisassociateCnf, | ||
| 34 | MlmeGetCnf, | ||
| 35 | MlmeGtsCnf, | ||
| 36 | MlmeResetCnf, | ||
| 37 | MlmeRxEnableCnf, | ||
| 38 | MlmeScanCnf, | ||
| 39 | MlmeSetCnf, | ||
| 40 | MlmeStartCnf, | ||
| 41 | MlmePollCnf, | ||
| 42 | MlmeDpsCnf, | ||
| 43 | MlmeSoundingCnf, | ||
| 44 | MlmeCalibrateCnf, | ||
| 45 | McpsDataCnf, | ||
| 46 | McpsPurgeCnf, | ||
| 47 | MlmeAssociateInd, | ||
| 48 | MlmeDisassociateInd, | ||
| 49 | MlmeBeaconNotifyInd, | ||
| 50 | MlmeCommStatusInd, | ||
| 51 | MlmeGtsInd, | ||
| 52 | MlmeOrphanInd, | ||
| 53 | MlmeSyncLossInd, | ||
| 54 | MlmeDpsInd, | ||
| 55 | McpsDataInd, | ||
| 56 | MlmePollInd, | ||
| 57 | } | ||
| 58 | |||
| 59 | impl TryFrom<u16> for OpcodeM0ToM4 { | ||
| 60 | type Error = (); | ||
| 61 | |||
| 62 | fn try_from(value: u16) -> Result<Self, Self::Error> { | ||
| 63 | match value { | ||
| 64 | 0 => Ok(Self::MlmeAssociateCnf), | ||
| 65 | 1 => Ok(Self::MlmeDisassociateCnf), | ||
| 66 | 2 => Ok(Self::MlmeGetCnf), | ||
| 67 | 3 => Ok(Self::MlmeGtsCnf), | ||
| 68 | 4 => Ok(Self::MlmeResetCnf), | ||
| 69 | 5 => Ok(Self::MlmeRxEnableCnf), | ||
| 70 | 6 => Ok(Self::MlmeScanCnf), | ||
| 71 | 7 => Ok(Self::MlmeSetCnf), | ||
| 72 | 8 => Ok(Self::MlmeStartCnf), | ||
| 73 | 9 => Ok(Self::MlmePollCnf), | ||
| 74 | 10 => Ok(Self::MlmeDpsCnf), | ||
| 75 | 11 => Ok(Self::MlmeSoundingCnf), | ||
| 76 | 12 => Ok(Self::MlmeCalibrateCnf), | ||
| 77 | 13 => Ok(Self::McpsDataCnf), | ||
| 78 | 14 => Ok(Self::McpsPurgeCnf), | ||
| 79 | 15 => Ok(Self::MlmeAssociateInd), | ||
| 80 | 16 => Ok(Self::MlmeDisassociateInd), | ||
| 81 | 17 => Ok(Self::MlmeBeaconNotifyInd), | ||
| 82 | 18 => Ok(Self::MlmeCommStatusInd), | ||
| 83 | 19 => Ok(Self::MlmeGtsInd), | ||
| 84 | 20 => Ok(Self::MlmeOrphanInd), | ||
| 85 | 21 => Ok(Self::MlmeSyncLossInd), | ||
| 86 | 22 => Ok(Self::MlmeDpsInd), | ||
| 87 | 23 => Ok(Self::McpsDataInd), | ||
| 88 | 24 => Ok(Self::MlmePollInd), | ||
| 89 | _ => Err(()), | ||
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
diff --git a/embassy-stm32-wpan/src/mac/responses.rs b/embassy-stm32-wpan/src/mac/responses.rs deleted file mode 100644 index 544fdaae8..000000000 --- a/embassy-stm32-wpan/src/mac/responses.rs +++ /dev/null | |||
| @@ -1,273 +0,0 @@ | |||
| 1 | use super::consts::{MAX_ED_SCAN_RESULTS_SUPPORTED, MAX_PAN_DESC_SUPPORTED, MAX_SOUNDING_LIST_SUPPORTED}; | ||
| 2 | use super::event::ParseableMacEvent; | ||
| 3 | use super::typedefs::{ | ||
| 4 | AddressMode, AssociationStatus, KeyIdMode, MacAddress, MacStatus, PanDescriptor, PanId, PibId, ScanType, | ||
| 5 | SecurityLevel, | ||
| 6 | }; | ||
| 7 | |||
| 8 | /// MLME ASSOCIATE Confirm used to inform of the initiating device whether | ||
| 9 | /// its request to associate was successful or unsuccessful | ||
| 10 | #[repr(C)] | ||
| 11 | #[derive(Debug)] | ||
| 12 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 13 | pub struct AssociateConfirm { | ||
| 14 | /// short address allocated by the coordinator on successful association | ||
| 15 | pub assoc_short_address: [u8; 2], | ||
| 16 | /// status of the association request | ||
| 17 | pub status: AssociationStatus, | ||
| 18 | /// security level to be used | ||
| 19 | pub security_level: SecurityLevel, | ||
| 20 | /// the originator of the key to be used | ||
| 21 | pub key_source: [u8; 8], | ||
| 22 | /// the mode used to identify the key to be used | ||
| 23 | pub key_id_mode: KeyIdMode, | ||
| 24 | /// the index of the key to be used | ||
| 25 | pub key_index: u8, | ||
| 26 | /// byte stuffing to keep 32 bit alignment | ||
| 27 | a_stuffing: [u8; 2], | ||
| 28 | } | ||
| 29 | |||
| 30 | impl ParseableMacEvent for AssociateConfirm {} | ||
| 31 | |||
| 32 | /// MLME DISASSOCIATE Confirm used to send disassociation Confirmation to the application. | ||
| 33 | #[repr(C)] | ||
| 34 | #[derive(Debug)] | ||
| 35 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 36 | pub struct DisassociateConfirm { | ||
| 37 | /// status of the disassociation attempt | ||
| 38 | pub status: MacStatus, | ||
| 39 | /// device addressing mode used | ||
| 40 | pub device_addr_mode: AddressMode, | ||
| 41 | /// the identifier of the PAN of the device | ||
| 42 | pub device_pan_id: PanId, | ||
| 43 | /// device address | ||
| 44 | pub device_address: MacAddress, | ||
| 45 | } | ||
| 46 | |||
| 47 | impl ParseableMacEvent for DisassociateConfirm {} | ||
| 48 | |||
| 49 | /// MLME GET Confirm which requests information about a given PIB attribute | ||
| 50 | #[repr(C)] | ||
| 51 | #[derive(Debug)] | ||
| 52 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 53 | pub struct GetConfirm { | ||
| 54 | /// The pointer to the value of the PIB attribute attempted to read | ||
| 55 | pub pib_attribute_value_ptr: *const u8, | ||
| 56 | /// Status of the GET attempt | ||
| 57 | pub status: MacStatus, | ||
| 58 | /// The name of the PIB attribute attempted to read | ||
| 59 | pub pib_attribute: PibId, | ||
| 60 | /// The lenght of the PIB attribute Value return | ||
| 61 | pub pib_attribute_value_len: u8, | ||
| 62 | /// byte stuffing to keep 32 bit alignment | ||
| 63 | a_stuffing: [u8; 1], | ||
| 64 | } | ||
| 65 | |||
| 66 | impl ParseableMacEvent for GetConfirm {} | ||
| 67 | |||
| 68 | /// MLME GTS Confirm which eports the results of a request to allocate a new GTS | ||
| 69 | /// or to deallocate an existing GTS | ||
| 70 | #[repr(C)] | ||
| 71 | #[derive(Debug)] | ||
| 72 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 73 | pub struct GtsConfirm { | ||
| 74 | /// The characteristics of the GTS | ||
| 75 | pub gts_characteristics: u8, | ||
| 76 | /// The status of the GTS reques | ||
| 77 | pub status: MacStatus, | ||
| 78 | /// byte stuffing to keep 32 bit alignment | ||
| 79 | a_stuffing: [u8; 2], | ||
| 80 | } | ||
| 81 | |||
| 82 | impl ParseableMacEvent for GtsConfirm {} | ||
| 83 | |||
| 84 | /// MLME RESET Confirm which is used to report the results of the reset operation | ||
| 85 | #[repr(C)] | ||
| 86 | #[derive(Debug)] | ||
| 87 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 88 | pub struct ResetConfirm { | ||
| 89 | /// The result of the reset operation | ||
| 90 | pub status: MacStatus, | ||
| 91 | /// byte stuffing to keep 32 bit alignment | ||
| 92 | a_stuffing: [u8; 3], | ||
| 93 | } | ||
| 94 | |||
| 95 | impl ParseableMacEvent for ResetConfirm {} | ||
| 96 | |||
| 97 | /// MLME RX ENABLE Confirm which is used to report the results of the attempt | ||
| 98 | /// to enable or disable the receiver | ||
| 99 | #[repr(C)] | ||
| 100 | #[derive(Debug)] | ||
| 101 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 102 | pub struct RxEnableConfirm { | ||
| 103 | /// Result of the request to enable or disable the receiver | ||
| 104 | pub status: MacStatus, | ||
| 105 | /// byte stuffing to keep 32 bit alignment | ||
| 106 | a_stuffing: [u8; 3], | ||
| 107 | } | ||
| 108 | |||
| 109 | impl ParseableMacEvent for RxEnableConfirm {} | ||
| 110 | |||
| 111 | /// MLME SCAN Confirm which is used to report the result of the channel scan request | ||
| 112 | #[repr(C)] | ||
| 113 | #[derive(Debug)] | ||
| 114 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 115 | pub struct ScanConfirm { | ||
| 116 | /// Status of the scan request | ||
| 117 | pub status: MacStatus, | ||
| 118 | /// The type of scan performed | ||
| 119 | pub scan_type: ScanType, | ||
| 120 | /// Channel page on which the scan was performed | ||
| 121 | pub channel_page: u8, | ||
| 122 | /// Channels given in the request which were not scanned | ||
| 123 | pub unscanned_channels: [u8; 4], | ||
| 124 | /// Number of elements returned in the appropriate result lists | ||
| 125 | pub result_list_size: u8, | ||
| 126 | /// List of energy measurements | ||
| 127 | pub energy_detect_list: [u8; MAX_ED_SCAN_RESULTS_SUPPORTED], | ||
| 128 | /// List of PAN descriptors | ||
| 129 | pub pan_descriptor_list: [PanDescriptor; MAX_PAN_DESC_SUPPORTED], | ||
| 130 | /// Categorization of energy detected in channel | ||
| 131 | pub detected_category: u8, | ||
| 132 | /// For UWB PHYs, the list of energy measurements taken | ||
| 133 | pub uwb_energy_detect_list: [u8; MAX_ED_SCAN_RESULTS_SUPPORTED], | ||
| 134 | } | ||
| 135 | |||
| 136 | impl ParseableMacEvent for ScanConfirm {} | ||
| 137 | |||
| 138 | /// MLME SET Confirm which reports the result of an attempt to write a value to a PIB attribute | ||
| 139 | #[repr(C)] | ||
| 140 | #[derive(Debug)] | ||
| 141 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 142 | pub struct SetConfirm { | ||
| 143 | /// The result of the set operation | ||
| 144 | pub status: MacStatus, | ||
| 145 | /// The name of the PIB attribute that was written | ||
| 146 | pub pin_attribute: PibId, | ||
| 147 | /// byte stuffing to keep 32 bit alignment | ||
| 148 | a_stuffing: [u8; 2], | ||
| 149 | } | ||
| 150 | |||
| 151 | impl ParseableMacEvent for SetConfirm {} | ||
| 152 | |||
| 153 | /// MLME START Confirm which is used to report the results of the attempt to | ||
| 154 | /// start using a new superframe configuration | ||
| 155 | #[repr(C)] | ||
| 156 | #[derive(Debug)] | ||
| 157 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 158 | pub struct StartConfirm { | ||
| 159 | /// Result of the attempt to start using an updated superframe configuration | ||
| 160 | pub status: MacStatus, | ||
| 161 | /// byte stuffing to keep 32 bit alignment | ||
| 162 | a_stuffing: [u8; 3], | ||
| 163 | } | ||
| 164 | |||
| 165 | impl ParseableMacEvent for StartConfirm {} | ||
| 166 | |||
| 167 | /// MLME POLL Confirm which is used to report the result of a request to poll the coordinator for data | ||
| 168 | #[repr(C)] | ||
| 169 | #[derive(Debug)] | ||
| 170 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 171 | pub struct PollConfirm { | ||
| 172 | /// The status of the data request | ||
| 173 | pub status: MacStatus, | ||
| 174 | /// byte stuffing to keep 32 bit alignment | ||
| 175 | a_stuffing: [u8; 3], | ||
| 176 | } | ||
| 177 | |||
| 178 | impl ParseableMacEvent for PollConfirm {} | ||
| 179 | |||
| 180 | /// MLME DPS Confirm which reports the results of the attempt to enable or disable the DPS | ||
| 181 | #[repr(C)] | ||
| 182 | #[derive(Debug)] | ||
| 183 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 184 | pub struct DpsConfirm { | ||
| 185 | /// The status of the DPS request | ||
| 186 | pub status: MacStatus, | ||
| 187 | /// byte stuffing to keep 32 bit alignment | ||
| 188 | a_stuffing: [u8; 3], | ||
| 189 | } | ||
| 190 | |||
| 191 | impl ParseableMacEvent for DpsConfirm {} | ||
| 192 | |||
| 193 | /// MLME SOUNDING Confirm which reports the result of a request to the PHY to provide | ||
| 194 | /// channel sounding information | ||
| 195 | #[repr(C)] | ||
| 196 | #[derive(Debug)] | ||
| 197 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 198 | pub struct SoundingConfirm { | ||
| 199 | /// Results of the sounding measurement | ||
| 200 | pub sounding_list: [u8; MAX_SOUNDING_LIST_SUPPORTED], | ||
| 201 | |||
| 202 | status: u8, | ||
| 203 | } | ||
| 204 | |||
| 205 | impl ParseableMacEvent for SoundingConfirm {} | ||
| 206 | |||
| 207 | /// MLME CALIBRATE Confirm which reports the result of a request to the PHY | ||
| 208 | /// to provide internal propagation path information | ||
| 209 | #[repr(C)] | ||
| 210 | #[derive(Debug)] | ||
| 211 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 212 | pub struct CalibrateConfirm { | ||
| 213 | /// The status of the attempt to return sounding data | ||
| 214 | pub status: MacStatus, | ||
| 215 | /// byte stuffing to keep 32 bit alignment | ||
| 216 | a_stuffing: [u8; 3], | ||
| 217 | /// A count of the propagation time from the ranging counter | ||
| 218 | /// to the transmit antenna | ||
| 219 | pub cal_tx_rmaker_offset: u32, | ||
| 220 | /// A count of the propagation time from the receive antenna | ||
| 221 | /// to the ranging counter | ||
| 222 | pub cal_rx_rmaker_offset: u32, | ||
| 223 | } | ||
| 224 | |||
| 225 | impl ParseableMacEvent for CalibrateConfirm {} | ||
| 226 | |||
| 227 | /// MCPS DATA Confirm which will be used for reporting the results of | ||
| 228 | /// MAC data related requests from the application | ||
| 229 | #[repr(C)] | ||
| 230 | #[derive(Debug)] | ||
| 231 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 232 | pub struct DataConfirm { | ||
| 233 | /// The handle associated with the MSDU being confirmed | ||
| 234 | pub msdu_handle: u8, | ||
| 235 | /// The time, in symbols, at which the data were transmitted | ||
| 236 | pub time_stamp: [u8; 4], | ||
| 237 | /// ranging status | ||
| 238 | pub ranging_received: u8, | ||
| 239 | /// The status of the last MSDU transmission | ||
| 240 | pub status: MacStatus, | ||
| 241 | /// time units corresponding to an RMARKER at the antenna at | ||
| 242 | /// the beginning of a ranging exchange | ||
| 243 | pub ranging_counter_start: u32, | ||
| 244 | /// time units corresponding to an RMARKER at the antenna | ||
| 245 | /// at the end of a ranging exchange | ||
| 246 | pub ranging_counter_stop: u32, | ||
| 247 | /// time units in a message exchange over which the tracking offset was measured | ||
| 248 | pub ranging_tracking_interval: u32, | ||
| 249 | /// time units slipped or advanced by the radio tracking system | ||
| 250 | pub ranging_offset: u32, | ||
| 251 | /// The FoM characterizing the ranging measurement | ||
| 252 | pub ranging_fom: u8, | ||
| 253 | /// byte stuffing to keep 32 bit alignment | ||
| 254 | a_stuffing: [u8; 3], | ||
| 255 | } | ||
| 256 | |||
| 257 | impl ParseableMacEvent for DataConfirm {} | ||
| 258 | |||
| 259 | /// MCPS PURGE Confirm which will be used by the MAC to notify the application of | ||
| 260 | /// the status of its request to purge an MSDU from the transaction queue | ||
| 261 | #[repr(C)] | ||
| 262 | #[derive(Debug)] | ||
| 263 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 264 | pub struct PurgeConfirm { | ||
| 265 | /// Handle associated with the MSDU requested to be purged from the transaction queue | ||
| 266 | pub msdu_handle: u8, | ||
| 267 | /// The status of the request | ||
| 268 | pub status: MacStatus, | ||
| 269 | /// byte stuffing to keep 32 bit alignment | ||
| 270 | a_stuffing: [u8; 2], | ||
| 271 | } | ||
| 272 | |||
| 273 | impl ParseableMacEvent for PurgeConfirm {} | ||
diff --git a/embassy-stm32-wpan/src/mac/runner.rs b/embassy-stm32-wpan/src/mac/runner.rs deleted file mode 100644 index d3099b6b7..000000000 --- a/embassy-stm32-wpan/src/mac/runner.rs +++ /dev/null | |||
| @@ -1,109 +0,0 @@ | |||
| 1 | use core::cell::RefCell; | ||
| 2 | |||
| 3 | use embassy_futures::join; | ||
| 4 | use embassy_sync::blocking_mutex; | ||
| 5 | use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; | ||
| 6 | use embassy_sync::channel::Channel; | ||
| 7 | use embassy_sync::mutex::Mutex; | ||
| 8 | use embassy_sync::signal::Signal; | ||
| 9 | |||
| 10 | use crate::mac::commands::DataRequest; | ||
| 11 | use crate::mac::event::MacEvent; | ||
| 12 | use crate::mac::typedefs::{AddressMode, MacAddress, PanId, SecurityLevel}; | ||
| 13 | use crate::mac::MTU; | ||
| 14 | use crate::sub::mac::Mac; | ||
| 15 | |||
| 16 | type ZeroCopyPubSub<M, T> = blocking_mutex::Mutex<M, RefCell<Option<Signal<NoopRawMutex, T>>>>; | ||
| 17 | |||
| 18 | pub struct Runner<'a> { | ||
| 19 | pub(crate) mac_subsystem: Mac, | ||
| 20 | // rx event backpressure is already provided through the MacEvent drop mechanism | ||
| 21 | // therefore, we don't need to worry about overwriting events | ||
| 22 | pub(crate) rx_event_channel: ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>, | ||
| 23 | pub(crate) read_mutex: Mutex<CriticalSectionRawMutex, ()>, | ||
| 24 | pub(crate) write_mutex: Mutex<CriticalSectionRawMutex, ()>, | ||
| 25 | pub(crate) rx_channel: Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>, | ||
| 26 | pub(crate) tx_channel: Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), 5>, | ||
| 27 | pub(crate) tx_buf_channel: Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], 5>, | ||
| 28 | } | ||
| 29 | |||
| 30 | impl<'a> Runner<'a> { | ||
| 31 | pub fn new(mac: Mac, tx_buf_queue: [&'a mut [u8; MTU]; 5]) -> Self { | ||
| 32 | let this = Self { | ||
| 33 | mac_subsystem: mac, | ||
| 34 | rx_event_channel: blocking_mutex::Mutex::new(RefCell::new(None)), | ||
| 35 | read_mutex: Mutex::new(()), | ||
| 36 | write_mutex: Mutex::new(()), | ||
| 37 | rx_channel: Channel::new(), | ||
| 38 | tx_channel: Channel::new(), | ||
| 39 | tx_buf_channel: Channel::new(), | ||
| 40 | }; | ||
| 41 | |||
| 42 | for buf in tx_buf_queue { | ||
| 43 | this.tx_buf_channel.try_send(buf).unwrap(); | ||
| 44 | } | ||
| 45 | |||
| 46 | this | ||
| 47 | } | ||
| 48 | |||
| 49 | pub async fn run(&'a self) -> ! { | ||
| 50 | join::join( | ||
| 51 | async { | ||
| 52 | loop { | ||
| 53 | if let Ok(mac_event) = self.mac_subsystem.read().await { | ||
| 54 | match mac_event { | ||
| 55 | MacEvent::McpsDataInd(_) => { | ||
| 56 | self.rx_channel.send(mac_event).await; | ||
| 57 | } | ||
| 58 | _ => { | ||
| 59 | self.rx_event_channel.lock(|s| { | ||
| 60 | match &*s.borrow() { | ||
| 61 | Some(signal) => { | ||
| 62 | signal.signal(mac_event); | ||
| 63 | } | ||
| 64 | None => {} | ||
| 65 | }; | ||
| 66 | }); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } | ||
| 70 | } | ||
| 71 | }, | ||
| 72 | async { | ||
| 73 | let mut msdu_handle = 0x02; | ||
| 74 | |||
| 75 | loop { | ||
| 76 | let (buf, len) = self.tx_channel.receive().await; | ||
| 77 | let _wm = self.write_mutex.lock().await; | ||
| 78 | |||
| 79 | // The mutex should be dropped on the next loop iteration | ||
| 80 | self.mac_subsystem | ||
| 81 | .send_command( | ||
| 82 | DataRequest { | ||
| 83 | src_addr_mode: AddressMode::Short, | ||
| 84 | dst_addr_mode: AddressMode::Short, | ||
| 85 | dst_pan_id: PanId([0x1A, 0xAA]), | ||
| 86 | dst_address: MacAddress::BROADCAST, | ||
| 87 | msdu_handle: msdu_handle, | ||
| 88 | ack_tx: 0x00, | ||
| 89 | gts_tx: false, | ||
| 90 | security_level: SecurityLevel::Unsecure, | ||
| 91 | ..Default::default() | ||
| 92 | } | ||
| 93 | .set_buffer(&buf[..len]), | ||
| 94 | ) | ||
| 95 | .await | ||
| 96 | .unwrap(); | ||
| 97 | |||
| 98 | msdu_handle = msdu_handle.wrapping_add(1); | ||
| 99 | |||
| 100 | // The tx channel should always be of equal capacity to the tx_buf channel | ||
| 101 | self.tx_buf_channel.try_send(buf).unwrap(); | ||
| 102 | } | ||
| 103 | }, | ||
| 104 | ) | ||
| 105 | .await; | ||
| 106 | |||
| 107 | loop {} | ||
| 108 | } | ||
| 109 | } | ||
diff --git a/embassy-stm32-wpan/src/mac/typedefs.rs b/embassy-stm32-wpan/src/mac/typedefs.rs deleted file mode 100644 index 0552b8ea1..000000000 --- a/embassy-stm32-wpan/src/mac/typedefs.rs +++ /dev/null | |||
| @@ -1,381 +0,0 @@ | |||
| 1 | use core::fmt::Debug; | ||
| 2 | |||
| 3 | use crate::numeric_enum; | ||
| 4 | |||
| 5 | #[derive(Debug)] | ||
| 6 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 7 | pub enum MacError { | ||
| 8 | Error = 0x01, | ||
| 9 | NotImplemented = 0x02, | ||
| 10 | NotSupported = 0x03, | ||
| 11 | HardwareNotSupported = 0x04, | ||
| 12 | Undefined = 0x05, | ||
| 13 | } | ||
| 14 | |||
| 15 | impl From<u8> for MacError { | ||
| 16 | fn from(value: u8) -> Self { | ||
| 17 | match value { | ||
| 18 | 0x01 => Self::Error, | ||
| 19 | 0x02 => Self::NotImplemented, | ||
| 20 | 0x03 => Self::NotSupported, | ||
| 21 | 0x04 => Self::HardwareNotSupported, | ||
| 22 | 0x05 => Self::Undefined, | ||
| 23 | _ => Self::Undefined, | ||
| 24 | } | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | numeric_enum! { | ||
| 29 | #[repr(u8)] | ||
| 30 | #[derive(Debug, Default)] | ||
| 31 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 32 | pub enum MacStatus { | ||
| 33 | #[default] | ||
| 34 | Success = 0x00, | ||
| 35 | Failure = 0xFF | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | numeric_enum! { | ||
| 40 | #[repr(u8)] | ||
| 41 | /// this enum contains all the MAC PIB Ids | ||
| 42 | #[derive(Default, Debug)] | ||
| 43 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 44 | pub enum PibId { | ||
| 45 | // PHY | ||
| 46 | #[default] | ||
| 47 | CurrentChannel = 0x00, | ||
| 48 | ChannelsSupported = 0x01, | ||
| 49 | TransmitPower = 0x02, | ||
| 50 | CCAMode = 0x03, | ||
| 51 | CurrentPage = 0x04, | ||
| 52 | MaxFrameDuration = 0x05, | ||
| 53 | SHRDuration = 0x06, | ||
| 54 | SymbolsPerOctet = 0x07, | ||
| 55 | |||
| 56 | // MAC | ||
| 57 | AckWaitDuration = 0x40, | ||
| 58 | AssociationPermit = 0x41, | ||
| 59 | AutoRequest = 0x42, | ||
| 60 | BeaconPayload = 0x45, | ||
| 61 | BeaconPayloadLength = 0x46, | ||
| 62 | BeaconOrder = 0x47, | ||
| 63 | Bsn = 0x49, | ||
| 64 | CoordExtendedAdddress = 0x4A, | ||
| 65 | CoordShortAddress = 0x4B, | ||
| 66 | Dsn = 0x4C, | ||
| 67 | MaxFrameTotalWaitTime = 0x58, | ||
| 68 | MaxFrameRetries = 0x59, | ||
| 69 | PanId = 0x50, | ||
| 70 | ResponseWaitTime = 0x5A, | ||
| 71 | RxOnWhenIdle = 0x52, | ||
| 72 | SecurityEnabled = 0x5D, | ||
| 73 | ShortAddress = 0x53, | ||
| 74 | SuperframeOrder = 0x54, | ||
| 75 | TimestampSupported = 0x5C, | ||
| 76 | TransactionPersistenceTime = 0x55, | ||
| 77 | MaxBe = 0x57, | ||
| 78 | LifsPeriod = 0x5E, | ||
| 79 | SifsPeriod = 0x5F, | ||
| 80 | MaxCsmaBackoffs = 0x4E, | ||
| 81 | MinBe = 0x4F, | ||
| 82 | PanCoordinator = 0x10, | ||
| 83 | AssocPanCoordinator = 0x11, | ||
| 84 | ExtendedAddress = 0x6F, | ||
| 85 | AclEntryDescriptor = 0x70, | ||
| 86 | AclEntryDescriptorSize = 0x71, | ||
| 87 | DefaultSecurity = 0x72, | ||
| 88 | DefaultSecurityMaterialLength = 0x73, | ||
| 89 | DefaultSecurityMaterial = 0x74, | ||
| 90 | DefaultSecuritySuite = 0x75, | ||
| 91 | SecurityMode = 0x76, | ||
| 92 | CurrentAclEntries = 0x80, | ||
| 93 | DefaultSecurityExtendedAddress = 0x81, | ||
| 94 | AssociatedPanCoordinator = 0x56, | ||
| 95 | PromiscuousMode = 0x51, | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | numeric_enum! { | ||
| 100 | #[repr(u8)] | ||
| 101 | #[derive(Default, Clone, Copy, Debug)] | ||
| 102 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 103 | pub enum AddressMode { | ||
| 104 | #[default] | ||
| 105 | NoAddress = 0x00, | ||
| 106 | Reserved = 0x01, | ||
| 107 | Short = 0x02, | ||
| 108 | Extended = 0x03, | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | #[derive(Clone, Copy)] | ||
| 113 | pub union MacAddress { | ||
| 114 | pub short: [u8; 2], | ||
| 115 | pub extended: [u8; 8], | ||
| 116 | } | ||
| 117 | |||
| 118 | impl Debug for MacAddress { | ||
| 119 | fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| 120 | unsafe { | ||
| 121 | write!( | ||
| 122 | fmt, | ||
| 123 | "MacAddress {{ short: {:?}, extended: {:?} }}", | ||
| 124 | self.short, self.extended | ||
| 125 | ) | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | #[cfg(feature = "defmt")] | ||
| 131 | impl defmt::Format for MacAddress { | ||
| 132 | fn format(&self, fmt: defmt::Formatter) { | ||
| 133 | unsafe { | ||
| 134 | defmt::write!( | ||
| 135 | fmt, | ||
| 136 | "MacAddress {{ short: {}, extended: {} }}", | ||
| 137 | self.short, | ||
| 138 | self.extended | ||
| 139 | ) | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | impl Default for MacAddress { | ||
| 145 | fn default() -> Self { | ||
| 146 | Self { short: [0, 0] } | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | impl MacAddress { | ||
| 151 | pub const BROADCAST: Self = Self { short: [0xFF, 0xFF] }; | ||
| 152 | } | ||
| 153 | |||
| 154 | impl TryFrom<&[u8]> for MacAddress { | ||
| 155 | type Error = (); | ||
| 156 | |||
| 157 | fn try_from(buf: &[u8]) -> Result<Self, Self::Error> { | ||
| 158 | const SIZE: usize = 8; | ||
| 159 | if buf.len() < SIZE { | ||
| 160 | return Err(()); | ||
| 161 | } | ||
| 162 | |||
| 163 | Ok(Self { | ||
| 164 | extended: [buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]], | ||
| 165 | }) | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 170 | pub struct GtsCharacteristics { | ||
| 171 | pub fields: u8, | ||
| 172 | } | ||
| 173 | |||
| 174 | /// MAC PAN Descriptor which contains the network details of the device from | ||
| 175 | /// which the beacon is received | ||
| 176 | #[derive(Default, Clone, Copy, Debug)] | ||
| 177 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 178 | pub struct PanDescriptor { | ||
| 179 | /// PAN identifier of the coordinator | ||
| 180 | pub coord_pan_id: PanId, | ||
| 181 | /// Coordinator addressing mode | ||
| 182 | pub coord_addr_mode: AddressMode, | ||
| 183 | /// The current logical channel occupied by the network | ||
| 184 | pub logical_channel: MacChannel, | ||
| 185 | /// Coordinator address | ||
| 186 | pub coord_addr: MacAddress, | ||
| 187 | /// The current channel page occupied by the network | ||
| 188 | pub channel_page: u8, | ||
| 189 | /// PAN coordinator is accepting GTS requests or not | ||
| 190 | pub gts_permit: bool, | ||
| 191 | /// Superframe specification as specified in the received beacon frame | ||
| 192 | pub superframe_spec: [u8; 2], | ||
| 193 | /// The time at which the beacon frame was received, in symbols | ||
| 194 | pub time_stamp: [u8; 4], | ||
| 195 | /// The LQI at which the network beacon was received | ||
| 196 | pub link_quality: u8, | ||
| 197 | /// Security level purportedly used by the received beacon frame | ||
| 198 | pub security_level: u8, | ||
| 199 | } | ||
| 200 | |||
| 201 | impl TryFrom<&[u8]> for PanDescriptor { | ||
| 202 | type Error = (); | ||
| 203 | |||
| 204 | fn try_from(buf: &[u8]) -> Result<Self, Self::Error> { | ||
| 205 | const SIZE: usize = 22; | ||
| 206 | if buf.len() < SIZE { | ||
| 207 | return Err(()); | ||
| 208 | } | ||
| 209 | |||
| 210 | let coord_addr_mode = AddressMode::try_from(buf[2])?; | ||
| 211 | let coord_addr = match coord_addr_mode { | ||
| 212 | AddressMode::NoAddress => MacAddress { short: [0, 0] }, | ||
| 213 | AddressMode::Reserved => MacAddress { short: [0, 0] }, | ||
| 214 | AddressMode::Short => MacAddress { | ||
| 215 | short: [buf[4], buf[5]], | ||
| 216 | }, | ||
| 217 | AddressMode::Extended => MacAddress { | ||
| 218 | extended: [buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]], | ||
| 219 | }, | ||
| 220 | }; | ||
| 221 | |||
| 222 | Ok(Self { | ||
| 223 | coord_pan_id: PanId([buf[0], buf[1]]), | ||
| 224 | coord_addr_mode, | ||
| 225 | logical_channel: MacChannel::try_from(buf[3])?, | ||
| 226 | coord_addr, | ||
| 227 | channel_page: buf[12], | ||
| 228 | gts_permit: buf[13] != 0, | ||
| 229 | superframe_spec: [buf[14], buf[15]], | ||
| 230 | time_stamp: [buf[16], buf[17], buf[18], buf[19]], | ||
| 231 | link_quality: buf[20], | ||
| 232 | security_level: buf[21], | ||
| 233 | // 2 byte stuffing | ||
| 234 | }) | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | numeric_enum! { | ||
| 239 | #[repr(u8)] | ||
| 240 | #[derive(Default, Clone, Copy, Debug)] | ||
| 241 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 242 | /// Building wireless applications with STM32WB series MCUs - Application note 13.10.3 | ||
| 243 | pub enum MacChannel { | ||
| 244 | Channel11 = 0x0B, | ||
| 245 | Channel12 = 0x0C, | ||
| 246 | Channel13 = 0x0D, | ||
| 247 | Channel14 = 0x0E, | ||
| 248 | Channel15 = 0x0F, | ||
| 249 | #[default] | ||
| 250 | Channel16 = 0x10, | ||
| 251 | Channel17 = 0x11, | ||
| 252 | Channel18 = 0x12, | ||
| 253 | Channel19 = 0x13, | ||
| 254 | Channel20 = 0x14, | ||
| 255 | Channel21 = 0x15, | ||
| 256 | Channel22 = 0x16, | ||
| 257 | Channel23 = 0x17, | ||
| 258 | Channel24 = 0x18, | ||
| 259 | Channel25 = 0x19, | ||
| 260 | Channel26 = 0x1A, | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | #[cfg(not(feature = "defmt"))] | ||
| 265 | bitflags::bitflags! { | ||
| 266 | pub struct Capabilities: u8 { | ||
| 267 | /// 1 if the device is capabaleof becoming a PAN coordinator | ||
| 268 | const IS_COORDINATOR_CAPABLE = 0b00000001; | ||
| 269 | /// 1 if the device is an FFD, 0 if it is an RFD | ||
| 270 | const IS_FFD = 0b00000010; | ||
| 271 | /// 1 if the device is receiving power from mains, 0 if it is battery-powered | ||
| 272 | const IS_MAINS_POWERED = 0b00000100; | ||
| 273 | /// 1 if the device does not disable its receiver to conserver power during idle periods | ||
| 274 | const RECEIVER_ON_WHEN_IDLE = 0b00001000; | ||
| 275 | // 0b00010000 reserved | ||
| 276 | // 0b00100000 reserved | ||
| 277 | /// 1 if the device is capable of sending and receiving secured MAC frames | ||
| 278 | const IS_SECURE = 0b01000000; | ||
| 279 | /// 1 if the device wishes the coordinator to allocate a short address as a result of the association | ||
| 280 | const ALLOCATE_ADDRESS = 0b10000000; | ||
| 281 | } | ||
| 282 | } | ||
| 283 | |||
| 284 | #[cfg(feature = "defmt")] | ||
| 285 | defmt::bitflags! { | ||
| 286 | pub struct Capabilities: u8 { | ||
| 287 | /// 1 if the device is capabaleof becoming a PAN coordinator | ||
| 288 | const IS_COORDINATOR_CAPABLE = 0b00000001; | ||
| 289 | /// 1 if the device is an FFD, 0 if it is an RFD | ||
| 290 | const IS_FFD = 0b00000010; | ||
| 291 | /// 1 if the device is receiving power from mains, 0 if it is battery-powered | ||
| 292 | const IS_MAINS_POWERED = 0b00000100; | ||
| 293 | /// 1 if the device does not disable its receiver to conserver power during idle periods | ||
| 294 | const RECEIVER_ON_WHEN_IDLE = 0b00001000; | ||
| 295 | // 0b00010000 reserved | ||
| 296 | // 0b00100000 reserved | ||
| 297 | /// 1 if the device is capable of sending and receiving secured MAC frames | ||
| 298 | const IS_SECURE = 0b01000000; | ||
| 299 | /// 1 if the device wishes the coordinator to allocate a short address as a result of the association | ||
| 300 | const ALLOCATE_ADDRESS = 0b10000000; | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | numeric_enum! { | ||
| 305 | #[repr(u8)] | ||
| 306 | #[derive(Default, Clone, Copy, Debug)] | ||
| 307 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 308 | pub enum KeyIdMode { | ||
| 309 | #[default] | ||
| 310 | /// the key is determined implicitly from the originator and recipient(s) of the frame | ||
| 311 | Implicite = 0x00, | ||
| 312 | /// the key is determined explicitly using a 1 bytes key source and a 1 byte key index | ||
| 313 | Explicite1Byte = 0x01, | ||
| 314 | /// the key is determined explicitly using a 4 bytes key source and a 1 byte key index | ||
| 315 | Explicite4Byte = 0x02, | ||
| 316 | /// the key is determined explicitly using a 8 bytes key source and a 1 byte key index | ||
| 317 | Explicite8Byte = 0x03, | ||
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | numeric_enum! { | ||
| 322 | #[repr(u8)] | ||
| 323 | #[derive(Debug)] | ||
| 324 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 325 | pub enum AssociationStatus { | ||
| 326 | /// Association successful | ||
| 327 | Success = 0x00, | ||
| 328 | /// PAN at capacity | ||
| 329 | PanAtCapacity = 0x01, | ||
| 330 | /// PAN access denied | ||
| 331 | PanAccessDenied = 0x02 | ||
| 332 | } | ||
| 333 | } | ||
| 334 | |||
| 335 | numeric_enum! { | ||
| 336 | #[repr(u8)] | ||
| 337 | #[derive(Clone, Copy, Debug)] | ||
| 338 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 339 | pub enum DisassociationReason { | ||
| 340 | /// The coordinator wishes the device to leave the PAN. | ||
| 341 | CoordRequested = 0x01, | ||
| 342 | /// The device wishes to leave the PAN. | ||
| 343 | DeviceRequested = 0x02, | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | numeric_enum! { | ||
| 348 | #[repr(u8)] | ||
| 349 | #[derive(Default, Clone, Copy, Debug)] | ||
| 350 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 351 | pub enum SecurityLevel { | ||
| 352 | /// MAC Unsecured Mode Security | ||
| 353 | #[default] | ||
| 354 | Unsecure = 0x00, | ||
| 355 | /// MAC ACL Mode Security | ||
| 356 | AclMode = 0x01, | ||
| 357 | /// MAC Secured Mode Security | ||
| 358 | Secured = 0x02, | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | numeric_enum! { | ||
| 363 | #[repr(u8)] | ||
| 364 | #[derive(Debug)] | ||
| 365 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 366 | pub enum ScanType { | ||
| 367 | EdScan = 0x00, | ||
| 368 | Active = 0x01, | ||
| 369 | Passive = 0x02, | ||
| 370 | Orphan = 0x03 | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | /// newtype for Pan Id | ||
| 375 | #[derive(Default, Clone, Copy, Debug)] | ||
| 376 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 377 | pub struct PanId(pub [u8; 2]); | ||
| 378 | |||
| 379 | impl PanId { | ||
| 380 | pub const BROADCAST: Self = Self([0xFF, 0xFF]); | ||
| 381 | } | ||
