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