diff options
| author | goueslati <[email protected]> | 2023-07-11 16:07:33 +0100 |
|---|---|---|
| committer | goueslati <[email protected]> | 2023-07-11 16:07:33 +0100 |
| commit | 6f4172fbc1280fdd9190ccddcf3cf6f25788c7be (patch) | |
| tree | f4503826cd87c9fb0958c966d4702d0d32d22578 /embassy-stm32-wpan/src/sub | |
| parent | 4aca7c8811b70e420280893784cdad2acbe326f9 (diff) | |
wip: added MAC commands
Diffstat (limited to 'embassy-stm32-wpan/src/sub')
| -rw-r--r-- | embassy-stm32-wpan/src/sub/mac/commands.rs | 394 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/sub/mac/mod.rs | 45 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/sub/mac/responses.rs | 0 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/sub/mac/typedefs.rs | 97 |
4 files changed, 494 insertions, 42 deletions
diff --git a/embassy-stm32-wpan/src/sub/mac/commands.rs b/embassy-stm32-wpan/src/sub/mac/commands.rs index 75a31d2fc..3c234a3ce 100644 --- a/embassy-stm32-wpan/src/sub/mac/commands.rs +++ b/embassy-stm32-wpan/src/sub/mac/commands.rs | |||
| @@ -1,13 +1,99 @@ | |||
| 1 | use bit_field::BitField; | ||
| 2 | |||
| 3 | use super::opcodes::OpcodeM4ToM0; | 1 | use super::opcodes::OpcodeM4ToM0; |
| 2 | use super::typedefs::{AddressMode, GtsCharacteristics, MacAddress, PibId}; | ||
| 4 | 3 | ||
| 5 | pub trait MacCommand { | 4 | pub trait MacCommand { |
| 6 | type Response; | ||
| 7 | const OPCODE: OpcodeM4ToM0; | 5 | const OPCODE: OpcodeM4ToM0; |
| 8 | const SIZE: usize; | 6 | const SIZE: usize; |
| 9 | 7 | ||
| 10 | fn copy_into_slice(&self, buf: &mut [u8]); | 8 | fn copy_into_slice(&self, buf: &mut [u8]) { |
| 9 | unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, 8) }; | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | /// MLME ASSOCIATE Request used to request an association | ||
| 14 | pub struct AssociateRequest { | ||
| 15 | /// the logical channel on which to attempt association | ||
| 16 | pub channel_number: u8, | ||
| 17 | /// the channel page on which to attempt association | ||
| 18 | pub channel_page: u8, | ||
| 19 | /// coordinator addressing mode | ||
| 20 | pub coord_addr_mode: AddressMode, | ||
| 21 | /// operational capabilities of the associating device | ||
| 22 | pub capability_information: u8, | ||
| 23 | /// the identifier of the PAN with which to associate | ||
| 24 | pub coord_pan_id: [u8; 2], | ||
| 25 | /// the security level to be used | ||
| 26 | pub security_level: u8, | ||
| 27 | /// the mode used to identify the key to be used | ||
| 28 | pub key_id_mode: u8, | ||
| 29 | /// the originator of the key to be used | ||
| 30 | pub key_source: [u8; 8], | ||
| 31 | /// Coordinator address | ||
| 32 | pub coord_address: MacAddress, | ||
| 33 | /// the index of the key to be used | ||
| 34 | pub key_index: u8, | ||
| 35 | } | ||
| 36 | |||
| 37 | impl MacCommand for AssociateRequest { | ||
| 38 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; | ||
| 39 | const SIZE: usize = 25; | ||
| 40 | } | ||
| 41 | |||
| 42 | /// MLME DISASSOCIATE Request sed to request a disassociation | ||
| 43 | pub struct DisassociateRequest { | ||
| 44 | /// device addressing mode used | ||
| 45 | pub device_addr_mode: AddressMode, | ||
| 46 | /// the identifier of the PAN of the device | ||
| 47 | pub device_pan_id: [u8; 2], | ||
| 48 | /// the reason for the disassociation | ||
| 49 | pub disassociate_reason: u8, | ||
| 50 | /// device address | ||
| 51 | pub device_address: MacAddress, | ||
| 52 | /// `true` if the disassociation notification command is to be sent indirectly | ||
| 53 | pub tx_indirect: bool, | ||
| 54 | /// the security level to be used | ||
| 55 | pub security_level: u8, | ||
| 56 | /// the mode to be used to indetify the key to be used | ||
| 57 | pub key_id_mode: u8, | ||
| 58 | /// the index of the key to be used | ||
| 59 | pub key_index: u8, | ||
| 60 | /// the originator of the key to be used | ||
| 61 | pub key_source: [u8; 8], | ||
| 62 | } | ||
| 63 | |||
| 64 | impl MacCommand for DisassociateRequest { | ||
| 65 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq; | ||
| 66 | const SIZE: usize = 24; | ||
| 67 | } | ||
| 68 | |||
| 69 | /// MLME GET Request used to request a PIB value | ||
| 70 | pub struct GetRequest { | ||
| 71 | /// the name of the PIB attribute to read | ||
| 72 | pub pib_attribute: PibId, | ||
| 73 | } | ||
| 74 | |||
| 75 | impl MacCommand for GetRequest { | ||
| 76 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; | ||
| 77 | const SIZE: usize = 4; | ||
| 78 | } | ||
| 79 | |||
| 80 | /// MLME GTS Request used to request and maintain GTSs | ||
| 81 | pub struct GtsRequest { | ||
| 82 | /// the characteristics of the GTS | ||
| 83 | pub characteristics: GtsCharacteristics, | ||
| 84 | /// the security level to be used | ||
| 85 | pub security_level: u8, | ||
| 86 | /// the mode used to identify the key to be used | ||
| 87 | pub key_id_mode: u8, | ||
| 88 | /// the index of the key to be used | ||
| 89 | pub key_index: u8, | ||
| 90 | /// the originator of the key to be used | ||
| 91 | pub key_source: [u8; 8], | ||
| 92 | } | ||
| 93 | |||
| 94 | impl MacCommand for GtsRequest { | ||
| 95 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; | ||
| 96 | const SIZE: usize = 12; | ||
| 11 | } | 97 | } |
| 12 | 98 | ||
| 13 | pub struct ResetRequest { | 99 | pub struct ResetRequest { |
| @@ -16,68 +102,302 @@ pub struct ResetRequest { | |||
| 16 | } | 102 | } |
| 17 | 103 | ||
| 18 | impl MacCommand for ResetRequest { | 104 | impl MacCommand for ResetRequest { |
| 19 | type Response = (); | ||
| 20 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; | 105 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; |
| 21 | const SIZE: usize = 4; | 106 | const SIZE: usize = 4; |
| 107 | } | ||
| 108 | |||
| 109 | /// MLME RX ENABLE Request used to request that the receiver is either enabled | ||
| 110 | /// for a finite period of time or disabled | ||
| 111 | pub struct RxEnableRequest { | ||
| 112 | /// the request operation can be deferred or not | ||
| 113 | pub defer_permit: bool, | ||
| 114 | /// configure the transceiver to RX with ranging for a value of | ||
| 115 | /// RANGING_ON or to not enable ranging for RANGING_OFF | ||
| 116 | pub ranging_rx_control: u8, | ||
| 117 | /// number of symbols measured before the receiver is to be enabled or disabled | ||
| 118 | pub rx_on_time: [u8; 4], | ||
| 119 | /// number of symbols for which the receiver is to be enabled | ||
| 120 | pub rx_on_duration: [u8; 4], | ||
| 121 | } | ||
| 122 | |||
| 123 | impl MacCommand for RxEnableRequest { | ||
| 124 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeRxEnableReq; | ||
| 125 | const SIZE: usize = 12; | ||
| 22 | 126 | ||
| 23 | fn copy_into_slice(&self, buf: &mut [u8]) { | 127 | fn copy_into_slice(&self, buf: &mut [u8]) { |
| 24 | buf[0] = self.set_default_pib as u8; | 128 | buf[0] = self.defer_permit as u8; |
| 129 | buf[1] = self.ranging_rx_control as u8; | ||
| 130 | |||
| 131 | // stuffing to keep 32bit alignment | ||
| 132 | buf[2] = 0; | ||
| 133 | buf[3] = 0; | ||
| 134 | |||
| 135 | buf[4..8].copy_from_slice(&self.rx_on_time); | ||
| 136 | buf[8..12].copy_from_slice(&self.rx_on_duration); | ||
| 25 | } | 137 | } |
| 26 | } | 138 | } |
| 27 | 139 | ||
| 140 | /// MLME SCAN Request used to initiate a channel scan over a given list of channels | ||
| 141 | pub struct ScanRequest { | ||
| 142 | /// the type of scan to be performed | ||
| 143 | pub scan_type: u8, | ||
| 144 | /// the time spent on scanning each channel | ||
| 145 | pub scan_duration: u8, | ||
| 146 | /// channel page on which to perform the scan | ||
| 147 | pub channel_page: u8, | ||
| 148 | /// security level to be used | ||
| 149 | pub security_level: u8, | ||
| 150 | /// indicate which channels are to be scanned | ||
| 151 | pub scan_channels: [u8; 4], | ||
| 152 | /// originator the key to be used | ||
| 153 | pub key_source: [u8; 8], | ||
| 154 | /// mode used to identify the key to be used | ||
| 155 | pub key_id_mode: u8, | ||
| 156 | /// index of the key to be used | ||
| 157 | pub key_index: u8, | ||
| 158 | } | ||
| 159 | |||
| 160 | impl MacCommand for ScanRequest { | ||
| 161 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeScanReq; | ||
| 162 | const SIZE: usize = 20; | ||
| 163 | } | ||
| 164 | |||
| 165 | /// MLME SET Request used to attempt to write the given value to the indicated PIB attribute | ||
| 28 | #[repr(C)] | 166 | #[repr(C)] |
| 29 | pub struct SetRequest { | 167 | pub struct SetRequest { |
| 168 | /// the pointer to the value of the PIB attribute to set | ||
| 30 | pub pib_attribute_ptr: *const u8, | 169 | pub pib_attribute_ptr: *const u8, |
| 31 | pub pib_attribute: u8, | 170 | /// the name of the PIB attribute to set |
| 32 | pub stuffing: [u8; 3], | 171 | pub pib_attribute: PibId, |
| 33 | } | 172 | } |
| 34 | 173 | ||
| 35 | impl MacCommand for SetRequest { | 174 | impl MacCommand for SetRequest { |
| 36 | type Response = (); | ||
| 37 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; | 175 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; |
| 38 | const SIZE: usize = 8; | 176 | const SIZE: usize = 8; |
| 177 | } | ||
| 39 | 178 | ||
| 40 | fn copy_into_slice(&self, buf: &mut [u8]) { | 179 | /// MLME START Request used by the FFDs to intiate a new PAN or to begin using a new superframe |
| 41 | let address = self.pib_attribute_ptr as usize; | 180 | /// configuration |
| 42 | 181 | #[derive(Default)] | |
| 43 | // 68 ff 2 20 6f | 182 | pub struct StartRequest { |
| 44 | 183 | /// PAN indentifier to used by the device | |
| 45 | let a = unsafe { core::slice::from_raw_parts(&self as *const _ as *const u8, Self::SIZE) }; | 184 | pub pan_id: [u8; 2], |
| 46 | debug!("{:#04x}", a); | 185 | /// logical channel on which to begin |
| 47 | 186 | pub channel_number: u8, | |
| 48 | unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, 8) }; | 187 | /// channel page on which to begin |
| 188 | pub channel_page: u8, | ||
| 189 | /// time at which to begin transmitting beacons | ||
| 190 | pub start_time: [u8; 4], | ||
| 191 | /// indicated how often the beacon is to be transmitted | ||
| 192 | pub beacon_order: u8, | ||
| 193 | /// length of the active portion of the superframe | ||
| 194 | pub superframe_order: u8, | ||
| 195 | /// indicated wheter the device is a PAN coordinator or not | ||
| 196 | pub pan_coordinator: bool, | ||
| 197 | /// indicates if the receiver of the beaconing device is disabled or not | ||
| 198 | pub battery_life_extension: bool, | ||
| 199 | /// indicated if the coordinator realignment command is to be trasmitted | ||
| 200 | pub coord_realignment: u8, | ||
| 201 | /// indicated if the coordinator realignment command is to be trasmitted | ||
| 202 | pub coord_realign_security_level: u8, | ||
| 203 | /// index of the key to be used | ||
| 204 | pub coord_realign_key_id_index: u8, | ||
| 205 | /// originator of the key to be used | ||
| 206 | pub coord_realign_key_source: [u8; 8], | ||
| 207 | /// security level to be used for beacon frames | ||
| 208 | pub beacon_security_level: u8, | ||
| 209 | /// mode used to identify the key to be used | ||
| 210 | pub beacon_key_id_mode: u8, | ||
| 211 | /// index of the key to be used | ||
| 212 | pub beacon_key_index: u8, | ||
| 213 | /// originator of the key to be used | ||
| 214 | pub beacon_key_source: [u8; 8], | ||
| 215 | } | ||
| 49 | 216 | ||
| 50 | // buf[0] = self.pib_attribute_ptr as u8; | 217 | impl MacCommand for StartRequest { |
| 51 | // buf[1] = self.pib_attribute; | 218 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq; |
| 52 | } | 219 | const SIZE: usize = 35; |
| 53 | } | 220 | } |
| 54 | 221 | ||
| 55 | pub struct AssociateRequest { | 222 | /// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if |
| 223 | /// specified, tracking its beacons | ||
| 224 | pub struct SyncRequest { | ||
| 225 | /// the channel number on which to attempt coordinator synchronization | ||
| 56 | pub channel_number: u8, | 226 | pub channel_number: u8, |
| 227 | /// the channel page on which to attempt coordinator synchronization | ||
| 57 | pub channel_page: u8, | 228 | pub channel_page: u8, |
| 58 | pub coord_addr_mode: u8, | 229 | /// `true` if the MLME is to synchronize with the next beacon and attempts |
| 59 | pub capability_information: u8, | 230 | /// to track all future beacons. |
| 60 | pub coord_pan_id: [u8; 2], | 231 | /// |
| 232 | /// `false` if the MLME is to synchronize with only the next beacon | ||
| 233 | pub track_beacon: bool, | ||
| 234 | } | ||
| 235 | |||
| 236 | impl MacCommand for SyncRequest { | ||
| 237 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq; | ||
| 238 | const SIZE: usize = 4; | ||
| 239 | } | ||
| 240 | |||
| 241 | /// MLME POLL Request propmts the device to request data from the coordinator | ||
| 242 | pub struct PollRequest { | ||
| 243 | /// addressing mode of the coordinator | ||
| 244 | pub coord_addr_mode: AddressMode, | ||
| 245 | /// security level to be used | ||
| 61 | pub security_level: u8, | 246 | pub security_level: u8, |
| 247 | /// mode used to identify the key to be used | ||
| 62 | pub key_id_mode: u8, | 248 | pub key_id_mode: u8, |
| 63 | pub key_source: [u8; 8], | 249 | /// index of the key to be used |
| 250 | pub key_index: u8, | ||
| 251 | /// coordinator address | ||
| 64 | pub coord_address: MacAddress, | 252 | pub coord_address: MacAddress, |
| 253 | /// originator of the key to be used | ||
| 254 | pub key_source: [u8; 8], | ||
| 255 | /// PAN identifier of the coordinator | ||
| 256 | pub coord_pan_id: [u8; 2], | ||
| 257 | } | ||
| 258 | |||
| 259 | impl MacCommand for PollRequest { | ||
| 260 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq; | ||
| 261 | const SIZE: usize = 24; | ||
| 262 | } | ||
| 263 | |||
| 264 | /// MLME DPS Request allows the next higher layer to request that the PHY utilize a | ||
| 265 | /// given pair of preamble codes for a single use pending expiration of the DPSIndexDuration | ||
| 266 | pub struct DpsRequest { | ||
| 267 | /// the index value for the transmitter | ||
| 268 | tx_dps_index: u8, | ||
| 269 | /// the index value of the receiver | ||
| 270 | rx_dps_index: u8, | ||
| 271 | /// the number of symbols for which the transmitter and receiver will utilize the | ||
| 272 | /// respective DPS indices | ||
| 273 | dps_index_duration: u8, | ||
| 274 | } | ||
| 275 | |||
| 276 | impl MacCommand for DpsRequest { | ||
| 277 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq; | ||
| 278 | const SIZE: usize = 4; | ||
| 279 | } | ||
| 280 | |||
| 281 | /// MLME SOUNDING request primitive which is used by the next higher layer to request that | ||
| 282 | /// the PHY respond with channel sounding information | ||
| 283 | pub struct SoundingRequest; | ||
| 284 | |||
| 285 | impl MacCommand for SoundingRequest { | ||
| 286 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq; | ||
| 287 | const SIZE: usize = 4; | ||
| 288 | } | ||
| 289 | |||
| 290 | /// MLME CALIBRATE request primitive which used to obtain the results of a ranging | ||
| 291 | /// calibration request from an RDEV | ||
| 292 | pub struct CalibrateRequest; | ||
| 293 | |||
| 294 | impl MacCommand for CalibrateRequest { | ||
| 295 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq; | ||
| 296 | const SIZE: usize = 4; | ||
| 297 | } | ||
| 298 | |||
| 299 | /// MCPS DATA Request used for MAC data related requests from the application | ||
| 300 | pub struct DataRequest { | ||
| 301 | /// the handle assocated with the MSDU to be transmitted | ||
| 302 | pub msdu_ptr: *const u8, | ||
| 303 | /// source addressing mode used | ||
| 304 | pub src_addr_mode: AddressMode, | ||
| 305 | /// destination addressing mode used | ||
| 306 | pub dst_addr_mode: AddressMode, | ||
| 307 | /// destination PAN Id | ||
| 308 | pub dst_pan_id: [u8; 2], | ||
| 309 | /// destination address | ||
| 310 | pub dst_address: MacAddress, | ||
| 311 | /// the number of octets contained in the MSDU | ||
| 312 | pub msdu_length: u8, | ||
| 313 | /// the handle assocated with the MSDU to be transmitted | ||
| 314 | pub msdu_handle: u8, | ||
| 315 | /// the ACK transmittion options for the MSDU | ||
| 316 | pub ack_tx: u8, | ||
| 317 | /// `true` if a GTS is to be used for transmission | ||
| 318 | /// | ||
| 319 | /// `false` indicates that the CAP will be used | ||
| 320 | pub gts_tx: bool, | ||
| 321 | /// the pending bit transmission options for the MSDU | ||
| 322 | pub indirect_tx: u8, | ||
| 323 | /// the security level to be used | ||
| 324 | pub security_level: u8, | ||
| 325 | /// the mode used to indentify the key to be used | ||
| 326 | pub key_id_mode: u8, | ||
| 327 | /// the index of the key to be used | ||
| 65 | pub key_index: u8, | 328 | pub key_index: u8, |
| 329 | /// the originator of the key to be used | ||
| 330 | pub key_source: [u8; 8], | ||
| 331 | /// 2011 - the pulse repitition value | ||
| 332 | pub uwbprf: u8, | ||
| 333 | /// 2011 - the ranging configuration | ||
| 334 | pub ranging: u8, | ||
| 335 | /// 2011 - the preamble symbol repititions | ||
| 336 | pub uwb_preamble_symbol_repetitions: u8, | ||
| 337 | /// 2011 - indicates the data rate | ||
| 338 | pub datrate: u8, | ||
| 66 | } | 339 | } |
| 67 | 340 | ||
| 68 | impl MacCommand for AssociateRequest { | 341 | impl MacCommand for DataRequest { |
| 69 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; | 342 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq; |
| 70 | const SIZE: usize = 25; | 343 | const SIZE: usize = 40; |
| 71 | type Response = (); | 344 | } |
| 72 | 345 | ||
| 73 | fn copy_into_slice(&self, buf: &mut [u8]) { | 346 | /// for MCPS PURGE Request used to purge an MSDU from the transaction queue |
| 74 | let a = unsafe { core::slice::from_raw_parts(&self as *const _ as *const u8, core::mem::size_of::<Self>()) }; | 347 | pub struct PurgeRequest { |
| 348 | /// the handle associated with the MSDU to be purged from the transaction | ||
| 349 | /// queue | ||
| 350 | pub msdu_handle: u8, | ||
| 351 | } | ||
| 75 | 352 | ||
| 76 | buf[..a.len()].copy_from_slice(a); | 353 | impl MacCommand for PurgeRequest { |
| 77 | } | 354 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq; |
| 355 | const SIZE: usize = 4; | ||
| 356 | } | ||
| 357 | |||
| 358 | /// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication | ||
| 359 | pub struct AssociateResponse { | ||
| 360 | /// extended address of the device requesting association | ||
| 361 | pub device_address: [u8; 8], | ||
| 362 | /// 16-bitshort device address allocated by the coordinator on successful | ||
| 363 | /// association | ||
| 364 | pub assoc_short_address: [u8; 2], | ||
| 365 | /// status of the association attempt | ||
| 366 | pub status: u8, | ||
| 367 | /// security level to be used | ||
| 368 | pub security_level: u8, | ||
| 369 | /// the originator of the key to be used | ||
| 370 | pub key_source: [u8; 8], | ||
| 371 | /// the mode used to identify the key to be used | ||
| 372 | pub key_id_mode: u8, | ||
| 373 | /// the index of the key to be used | ||
| 374 | pub key_index: u8, | ||
| 375 | } | ||
| 376 | |||
| 377 | impl MacCommand for AssociateResponse { | ||
| 378 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes; | ||
| 379 | const SIZE: usize = 24; | ||
| 380 | } | ||
| 381 | |||
| 382 | /// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication | ||
| 383 | pub struct OrphanResponse { | ||
| 384 | /// extended address of the orphaned device | ||
| 385 | pub orphan_address: [u8; 8], | ||
| 386 | /// short address allocated to the orphaned device | ||
| 387 | pub short_address: [u8; 2], | ||
| 388 | /// if the orphaned device is associated with coordinator or not | ||
| 389 | pub associated_member: bool, | ||
| 390 | /// security level to be used | ||
| 391 | pub security_level: u8, | ||
| 392 | /// the originator of the key to be used | ||
| 393 | pub key_source: [u8; 8], | ||
| 394 | /// the mode used to identify the key to be used | ||
| 395 | pub key_id_mode: u8, | ||
| 396 | /// the index of the key to be used | ||
| 397 | pub key_index: u8, | ||
| 78 | } | 398 | } |
| 79 | 399 | ||
| 80 | pub union MacAddress { | 400 | impl MacCommand for OrphanResponse { |
| 81 | pub short: [u8; 2], | 401 | const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes; |
| 82 | pub extended: [u8; 8], | 402 | const SIZE: usize = 24; |
| 83 | } | 403 | } |
diff --git a/embassy-stm32-wpan/src/sub/mac/mod.rs b/embassy-stm32-wpan/src/sub/mac/mod.rs index 83970a881..8e117d978 100644 --- a/embassy-stm32-wpan/src/sub/mac/mod.rs +++ b/embassy-stm32-wpan/src/sub/mac/mod.rs | |||
| @@ -9,14 +9,17 @@ use embassy_stm32::ipcc::Ipcc; | |||
| 9 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 10 | 10 | ||
| 11 | use self::commands::MacCommand; | 11 | use self::commands::MacCommand; |
| 12 | use self::typedefs::MacStatus; | ||
| 12 | use crate::cmd::CmdPacket; | 13 | use crate::cmd::CmdPacket; |
| 13 | use crate::consts::TlPacketType; | 14 | use crate::consts::TlPacketType; |
| 14 | use crate::evt::{EvtBox, EvtPacket}; | 15 | use crate::evt::{EvtBox, EvtPacket}; |
| 15 | use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; | 16 | use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; |
| 16 | use crate::{channels, evt}; | 17 | use crate::{channels, evt}; |
| 17 | 18 | ||
| 18 | pub mod commands; | ||
| 19 | mod opcodes; | 19 | mod opcodes; |
| 20 | pub mod commands; | ||
| 21 | pub mod responses; | ||
| 22 | pub mod typedefs; | ||
| 20 | 23 | ||
| 21 | static MAC_WAKER: AtomicWaker = AtomicWaker::new(); | 24 | static MAC_WAKER: AtomicWaker = AtomicWaker::new(); |
| 22 | static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); | 25 | static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); |
| @@ -59,12 +62,25 @@ impl Mac { | |||
| 59 | /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` | 62 | /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` |
| 60 | pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { | 63 | pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { |
| 61 | self.write(opcode, payload).await; | 64 | self.write(opcode, payload).await; |
| 62 | Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; | 65 | Ipcc::flush(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL).await; |
| 63 | 66 | ||
| 64 | unsafe { | 67 | unsafe { |
| 65 | let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; | 68 | let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; |
| 66 | let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; | 69 | let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; |
| 67 | 70 | ||
| 71 | let evt_serial = (MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket) | ||
| 72 | .read_volatile() | ||
| 73 | .evt_serial; | ||
| 74 | let kind = (evt_serial).kind; | ||
| 75 | let evt_code = evt_serial.evt.evt_code; | ||
| 76 | let payload_len = evt_serial.evt.payload_len; | ||
| 77 | let payload = evt_serial.evt.payload; | ||
| 78 | |||
| 79 | debug!( | ||
| 80 | "evt kind {} evt_code {} len {} payload {}", | ||
| 81 | kind, evt_code, payload_len, payload | ||
| 82 | ); | ||
| 83 | |||
| 68 | ptr::read_volatile(p_mac_rsp_evt) | 84 | ptr::read_volatile(p_mac_rsp_evt) |
| 69 | } | 85 | } |
| 70 | } | 86 | } |
| @@ -74,15 +90,32 @@ impl Mac { | |||
| 74 | Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { | 90 | Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { |
| 75 | CmdPacket::write_into( | 91 | CmdPacket::write_into( |
| 76 | MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), | 92 | MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), |
| 77 | TlPacketType::OtCmd, | 93 | TlPacketType::MacCmd, |
| 78 | opcode, | 94 | opcode, |
| 79 | payload, | 95 | payload, |
| 80 | ); | 96 | ); |
| 81 | }) | 97 | }) |
| 82 | .await; | 98 | .await; |
| 99 | |||
| 100 | unsafe { | ||
| 101 | let typ = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.ty; | ||
| 102 | let cmd_code = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.cmd.cmd_code; | ||
| 103 | let payload_len = MAC_802_15_4_CMD_BUFFER | ||
| 104 | .as_ptr() | ||
| 105 | .read_volatile() | ||
| 106 | .cmdserial | ||
| 107 | .cmd | ||
| 108 | .payload_len; | ||
| 109 | let payload = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.cmd.payload; | ||
| 110 | |||
| 111 | debug!( | ||
| 112 | "serial type {} cmd_code {} len {} payload {}", | ||
| 113 | typ, cmd_code, payload_len, payload | ||
| 114 | ); | ||
| 115 | } | ||
| 83 | } | 116 | } |
| 84 | 117 | ||
| 85 | pub async fn send_command<T>(&self, cmd: T) -> u8 | 118 | pub async fn send_command<T>(&self, cmd: T) -> Result<MacStatus, ()> |
| 86 | where | 119 | where |
| 87 | T: MacCommand, | 120 | T: MacCommand, |
| 88 | { | 121 | { |
| @@ -91,7 +124,9 @@ impl Mac { | |||
| 91 | 124 | ||
| 92 | debug!("sending {:#x}", payload[..T::SIZE]); | 125 | debug!("sending {:#x}", payload[..T::SIZE]); |
| 93 | 126 | ||
| 94 | self.write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]).await | 127 | let response = self.write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]).await; |
| 128 | |||
| 129 | MacStatus::try_from(response) | ||
| 95 | } | 130 | } |
| 96 | } | 131 | } |
| 97 | 132 | ||
diff --git a/embassy-stm32-wpan/src/sub/mac/responses.rs b/embassy-stm32-wpan/src/sub/mac/responses.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/embassy-stm32-wpan/src/sub/mac/responses.rs | |||
diff --git a/embassy-stm32-wpan/src/sub/mac/typedefs.rs b/embassy-stm32-wpan/src/sub/mac/typedefs.rs new file mode 100644 index 000000000..d43d6e0cf --- /dev/null +++ b/embassy-stm32-wpan/src/sub/mac/typedefs.rs | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 2 | pub enum MacStatus { | ||
| 3 | Success = 0x00, | ||
| 4 | Error = 0x01, | ||
| 5 | NotImplemented = 0x02, | ||
| 6 | NotSupported = 0x03, | ||
| 7 | HardwareNotSupported = 0x04, | ||
| 8 | Undefined = 0x05, | ||
| 9 | } | ||
| 10 | |||
| 11 | impl TryFrom<u8> for MacStatus { | ||
| 12 | type Error = (); | ||
| 13 | |||
| 14 | fn try_from(value: u8) -> Result<Self, <MacStatus as TryFrom<u8>>::Error> { | ||
| 15 | match value { | ||
| 16 | 0x00 => Ok(Self::Success), | ||
| 17 | 0x01 => Ok(Self::Error), | ||
| 18 | 0x02 => Ok(Self::NotImplemented), | ||
| 19 | 0x03 => Ok(Self::NotSupported), | ||
| 20 | 0x04 => Ok(Self::HardwareNotSupported), | ||
| 21 | 0x05 => Ok(Self::Undefined), | ||
| 22 | _ => Err(()), | ||
| 23 | } | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | /// this enum contains all the MAC PIB Ids | ||
| 28 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 29 | pub enum PibId { | ||
| 30 | // PHY | ||
| 31 | CurrentChannel = 0x00, | ||
| 32 | ChannelsSupported = 0x01, | ||
| 33 | TransmitPower = 0x02, | ||
| 34 | CCAMode = 0x03, | ||
| 35 | CurrentPage = 0x04, | ||
| 36 | MaxFrameDuration = 0x05, | ||
| 37 | SHRDuration = 0x06, | ||
| 38 | SymbolsPerOctet = 0x07, | ||
| 39 | |||
| 40 | // MAC | ||
| 41 | AckWaitDuration = 0x40, | ||
| 42 | AssociationPermit = 0x41, | ||
| 43 | AutoRequest = 0x42, | ||
| 44 | BeaconPayload = 0x45, | ||
| 45 | BeaconPayloadLength = 0x46, | ||
| 46 | BeaconOrder = 0x47, | ||
| 47 | Bsn = 0x49, | ||
| 48 | CoordExtendedAdddress = 0x4A, | ||
| 49 | CoordShortAddress = 0x4B, | ||
| 50 | Dsn = 0x4C, | ||
| 51 | MaxFrameTotalWaitTime = 0x58, | ||
| 52 | MaxFrameRetries = 0x59, | ||
| 53 | PanId = 0x50, | ||
| 54 | ResponseWaitTime = 0x5A, | ||
| 55 | RxOnWhenIdle = 0x52, | ||
| 56 | SecurityEnabled = 0x5D, | ||
| 57 | ShortAddress = 0x53, | ||
| 58 | SuperframeOrder = 0x54, | ||
| 59 | TimestampSupported = 0x5C, | ||
| 60 | TransactionPersistenceTime = 0x55, | ||
| 61 | MaxBe = 0x57, | ||
| 62 | LifsPeriod = 0x5E, | ||
| 63 | SifsPeriod = 0x5F, | ||
| 64 | MaxCsmaBackoffs = 0x4E, | ||
| 65 | MinBe = 0x4F, | ||
| 66 | PanCoordinator = 0x10, | ||
| 67 | AssocPanCoordinator = 0x11, | ||
| 68 | ExtendedAddress = 0x6F, | ||
| 69 | AclEntryDescriptor = 0x70, | ||
| 70 | AclEntryDescriptorSize = 0x71, | ||
| 71 | DefaultSecurity = 0x72, | ||
| 72 | DefaultSecurityMaterialLength = 0x73, | ||
| 73 | DefaultSecurityMaterial = 0x74, | ||
| 74 | DefaultSecuritySuite = 0x75, | ||
| 75 | SecurityMode = 0x76, | ||
| 76 | CurrentAclEntries = 0x80, | ||
| 77 | DefaultSecurityExtendedAddress = 0x81, | ||
| 78 | AssociatedPanCoordinator = 0x56, | ||
| 79 | PromiscuousMode = 0x51, | ||
| 80 | } | ||
| 81 | |||
| 82 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 83 | pub enum AddressMode { | ||
| 84 | NoAddress = 0x00, | ||
| 85 | Reserved = 0x01, | ||
| 86 | Short = 0x02, | ||
| 87 | Extended = 0x03, | ||
| 88 | } | ||
| 89 | |||
| 90 | pub union MacAddress { | ||
| 91 | pub short: [u8; 2], | ||
| 92 | pub extended: [u8; 8], | ||
| 93 | } | ||
| 94 | |||
| 95 | pub struct GtsCharacteristics { | ||
| 96 | pub fields: u8, | ||
| 97 | } | ||
