diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-12-11 16:53:36 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-11 16:53:36 +0000 |
| commit | 3588023e3e04b18cf98a2a0d10756e1f236ca351 (patch) | |
| tree | 9c044943daa253e7e489ee5cc374b1de6de72b2f /cyw43 | |
| parent | 0301bdf2c09854f9f3bc864f666608cef295373b (diff) | |
| parent | 31039201e7edcba6bbf6ba8679332cf98d6d7b1f (diff) | |
Merge pull request #5020 from simonborje/improve_cyw43_join_result
Improve cyw43 join handling
Diffstat (limited to 'cyw43')
| -rw-r--r-- | cyw43/src/consts.rs | 4 | ||||
| -rw-r--r-- | cyw43/src/control.rs | 74 | ||||
| -rw-r--r-- | cyw43/src/lib.rs | 2 |
3 files changed, 51 insertions, 29 deletions
diff --git a/cyw43/src/consts.rs b/cyw43/src/consts.rs index c3f0dbfd8..e561d4794 100644 --- a/cyw43/src/consts.rs +++ b/cyw43/src/consts.rs | |||
| @@ -177,9 +177,11 @@ pub(crate) enum Security { | |||
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | #[allow(non_camel_case_types)] | 179 | #[allow(non_camel_case_types)] |
| 180 | #[derive(Copy, Clone)] | 180 | #[derive(Copy, Clone, PartialEq, num_enum::FromPrimitive)] |
| 181 | #[repr(u8)] | 181 | #[repr(u8)] |
| 182 | pub enum EStatus { | 182 | pub enum EStatus { |
| 183 | #[num_enum(default)] | ||
| 184 | Unknown = 0xFF, | ||
| 183 | /// operation was successful | 185 | /// operation was successful |
| 184 | SUCCESS = 0, | 186 | SUCCESS = 0, |
| 185 | /// operation failed | 187 | /// operation failed |
diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index 07fa1955e..240c0e728 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs | |||
| @@ -12,11 +12,16 @@ use crate::ioctl::{IoctlState, IoctlType}; | |||
| 12 | use crate::structs::*; | 12 | use crate::structs::*; |
| 13 | use crate::{PowerManagementMode, countries, events}; | 13 | use crate::{PowerManagementMode, countries, events}; |
| 14 | 14 | ||
| 15 | /// Control errors. | 15 | /// Join errors. |
| 16 | #[derive(Debug)] | 16 | #[derive(Debug)] |
| 17 | pub struct Error { | 17 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 18 | /// Status code. | 18 | pub enum JoinError { |
| 19 | pub status: u32, | 19 | /// Network not found. |
| 20 | NetworkNotFound, | ||
| 21 | /// Failure to join network. Contains the status code from the SET_SSID event. | ||
| 22 | JoinFailure(u8), | ||
| 23 | /// Authentication failure for a secure network. | ||
| 24 | AuthenticationFailure, | ||
| 20 | } | 25 | } |
| 21 | 26 | ||
| 22 | /// Multicast errors. | 27 | /// Multicast errors. |
| @@ -296,7 +301,7 @@ impl<'a> Control<'a> { | |||
| 296 | } | 301 | } |
| 297 | 302 | ||
| 298 | /// Join a network with the provided SSID using the specified options. | 303 | /// Join a network with the provided SSID using the specified options. |
| 299 | pub async fn join(&mut self, ssid: &str, options: JoinOptions<'_>) -> Result<(), Error> { | 304 | pub async fn join(&mut self, ssid: &str, options: JoinOptions<'_>) -> Result<(), JoinError> { |
| 300 | self.set_iovar_u32("ampdu_ba_wsize", 8).await; | 305 | self.set_iovar_u32("ampdu_ba_wsize", 8).await; |
| 301 | 306 | ||
| 302 | if options.auth == JoinAuth::Open { | 307 | if options.auth == JoinAuth::Open { |
| @@ -367,40 +372,55 @@ impl<'a> Control<'a> { | |||
| 367 | }; | 372 | }; |
| 368 | i.ssid[..ssid.len()].copy_from_slice(ssid.as_bytes()); | 373 | i.ssid[..ssid.len()].copy_from_slice(ssid.as_bytes()); |
| 369 | 374 | ||
| 370 | self.wait_for_join(i).await | 375 | let secure_network = options.auth != JoinAuth::Open; |
| 376 | self.wait_for_join(i, secure_network).await | ||
| 371 | } | 377 | } |
| 372 | 378 | ||
| 373 | async fn wait_for_join(&mut self, i: SsidInfo) -> Result<(), Error> { | 379 | async fn wait_for_join(&mut self, i: SsidInfo, secure_network: bool) -> Result<(), JoinError> { |
| 374 | self.events.mask.enable(&[Event::SET_SSID, Event::AUTH]); | 380 | self.events.mask.enable(&[Event::SET_SSID, Event::AUTH, Event::PSK_SUP]); |
| 375 | let mut subscriber = self.events.queue.subscriber().unwrap(); | 381 | let mut subscriber = self.events.queue.subscriber().unwrap(); |
| 376 | // the actual join operation starts here | 382 | // the actual join operation starts here |
| 377 | // we make sure to enable events before so we don't miss any | 383 | // we make sure to enable events before so we don't miss any |
| 378 | 384 | ||
| 379 | self.ioctl(IoctlType::Set, Ioctl::SetSsid, 0, &mut i.to_bytes()).await; | 385 | self.ioctl(IoctlType::Set, Ioctl::SetSsid, 0, &mut i.to_bytes()).await; |
| 380 | 386 | ||
| 381 | // to complete the join, we wait for a SET_SSID event | 387 | // To complete the join on an open network, we wait for a SET_SSID event with status SUCCESS |
| 382 | // we also save the AUTH status for the user, it may be interesting | 388 | // For secured networks, we wait for a PSK_SUP event with status 6 "UNSOLICITED" |
| 383 | let mut auth_status = 0; | 389 | let result = loop { |
| 384 | let status = loop { | ||
| 385 | let msg = subscriber.next_message_pure().await; | 390 | let msg = subscriber.next_message_pure().await; |
| 386 | if msg.header.event_type == Event::AUTH && msg.header.status != EStatus::SUCCESS { | 391 | |
| 387 | auth_status = msg.header.status; | 392 | let status = EStatus::from(msg.header.status as u8); |
| 388 | } else if msg.header.event_type == Event::SET_SSID { | 393 | match (msg.header.event_type, status, secure_network) { |
| 389 | // join operation ends with SET_SSID event | 394 | // Join operation ends with SET_SSID event for open networks |
| 390 | break msg.header.status; | 395 | (Event::SET_SSID, EStatus::SUCCESS, false) => break Ok(()), |
| 391 | } | 396 | (Event::SET_SSID, EStatus::NO_NETWORKS, _) => break Err(JoinError::NetworkNotFound), |
| 397 | (Event::SET_SSID, status, _) if status != EStatus::SUCCESS => { | ||
| 398 | break Err(JoinError::JoinFailure(status as u8)); | ||
| 399 | } | ||
| 400 | // Ignore PSK_SUP "ABORT" which is sometimes sent before successful join | ||
| 401 | (Event::PSK_SUP, EStatus::ABORT, true) => {} | ||
| 402 | // Event PSK_SUP with status 6 "UNSOLICITED" indicates success for secure networks | ||
| 403 | (Event::PSK_SUP, EStatus::UNSOLICITED, true) => break Ok(()), | ||
| 404 | // Events indicating authentication failure, possibly due to incorrect password | ||
| 405 | (Event::PSK_SUP, _, true) | (Event::AUTH, EStatus::FAIL, true) => { | ||
| 406 | break Err(JoinError::AuthenticationFailure); | ||
| 407 | } | ||
| 408 | _ => {} | ||
| 409 | }; | ||
| 392 | }; | 410 | }; |
| 393 | 411 | ||
| 394 | self.events.mask.disable_all(); | 412 | self.events.mask.disable_all(); |
| 395 | if status == EStatus::SUCCESS { | 413 | match result { |
| 396 | // successful join | 414 | Ok(()) => { |
| 397 | self.state_ch.set_link_state(LinkState::Up); | 415 | self.state_ch.set_link_state(LinkState::Up); |
| 398 | debug!("JOINED"); | 416 | debug!("JOINED"); |
| 399 | Ok(()) | 417 | } |
| 400 | } else { | 418 | Err(JoinError::JoinFailure(status)) => debug!("JOIN failed: status={}", status), |
| 401 | warn!("JOIN failed with status={} auth={}", status, auth_status); | 419 | Err(JoinError::NetworkNotFound) => debug!("JOIN failed: network not found"), |
| 402 | Err(Error { status }) | 420 | Err(JoinError::AuthenticationFailure) => debug!("JOIN failed: authentication failure"), |
| 403 | } | 421 | }; |
| 422 | |||
| 423 | result | ||
| 404 | } | 424 | } |
| 405 | 425 | ||
| 406 | /// Set GPIO pin on WiFi chip. | 426 | /// Set GPIO pin on WiFi chip. |
diff --git a/cyw43/src/lib.rs b/cyw43/src/lib.rs index 82c636346..73d2830ca 100644 --- a/cyw43/src/lib.rs +++ b/cyw43/src/lib.rs | |||
| @@ -31,7 +31,7 @@ use ioctl::IoctlState; | |||
| 31 | use crate::bus::Bus; | 31 | use crate::bus::Bus; |
| 32 | pub use crate::bus::SpiBusCyw43; | 32 | pub use crate::bus::SpiBusCyw43; |
| 33 | pub use crate::control::{ | 33 | pub use crate::control::{ |
| 34 | AddMulticastAddressError, Control, Error as ControlError, JoinAuth, JoinOptions, ScanOptions, ScanType, Scanner, | 34 | AddMulticastAddressError, Control, JoinAuth, JoinError, JoinOptions, ScanOptions, ScanType, Scanner, |
| 35 | }; | 35 | }; |
| 36 | pub use crate::runner::Runner; | 36 | pub use crate::runner::Runner; |
| 37 | pub use crate::structs::BssInfo; | 37 | pub use crate::structs::BssInfo; |
