diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-04-30 15:05:16 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-04-30 15:05:16 +0000 |
| commit | 5659269c8fb2f7d03d4a903e4ad48c8268668f0a (patch) | |
| tree | e35e59f37d50791029c2f88b3014b409ea802d39 /src/control.rs | |
| parent | c19de2984751ba6fa2972ee66cfa2a6310d5f0c1 (diff) | |
| parent | 76b967a966677e570cc0a2942ed3ccd29b2d1017 (diff) | |
Merge pull request #70 from kbleeke/wifi-scanning-ioctl
Wifi scanning ioctl
Diffstat (limited to 'src/control.rs')
| -rw-r--r-- | src/control.rs | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/src/control.rs b/src/control.rs index 0c06009b9..934bade23 100644 --- a/src/control.rs +++ b/src/control.rs | |||
| @@ -6,11 +6,11 @@ use embassy_time::{Duration, Timer}; | |||
| 6 | 6 | ||
| 7 | pub use crate::bus::SpiBusCyw43; | 7 | pub use crate::bus::SpiBusCyw43; |
| 8 | use crate::consts::*; | 8 | use crate::consts::*; |
| 9 | use crate::events::{Event, Events}; | 9 | use crate::events::{Event, EventSubscriber, Events}; |
| 10 | use crate::fmt::Bytes; | 10 | use crate::fmt::Bytes; |
| 11 | use crate::ioctl::{IoctlState, IoctlType}; | 11 | use crate::ioctl::{IoctlState, IoctlType}; |
| 12 | use crate::structs::*; | 12 | use crate::structs::*; |
| 13 | use crate::{countries, PowerManagementMode}; | 13 | use crate::{countries, events, PowerManagementMode}; |
| 14 | 14 | ||
| 15 | pub struct Control<'a> { | 15 | pub struct Control<'a> { |
| 16 | state_ch: ch::StateRunner<'a>, | 16 | state_ch: ch::StateRunner<'a>, |
| @@ -245,9 +245,13 @@ impl<'a> Control<'a> { | |||
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | async fn set_iovar(&mut self, name: &str, val: &[u8]) { | 247 | async fn set_iovar(&mut self, name: &str, val: &[u8]) { |
| 248 | self.set_iovar_v::<64>(name, val).await | ||
| 249 | } | ||
| 250 | |||
| 251 | async fn set_iovar_v<const BUFSIZE: usize>(&mut self, name: &str, val: &[u8]) { | ||
| 248 | info!("set {} = {:02x}", name, Bytes(val)); | 252 | info!("set {} = {:02x}", name, Bytes(val)); |
| 249 | 253 | ||
| 250 | let mut buf = [0; 64]; | 254 | let mut buf = [0; BUFSIZE]; |
| 251 | buf[..name.len()].copy_from_slice(name.as_bytes()); | 255 | buf[..name.len()].copy_from_slice(name.as_bytes()); |
| 252 | buf[name.len()] = 0; | 256 | buf[name.len()] = 0; |
| 253 | buf[name.len() + 1..][..val.len()].copy_from_slice(val); | 257 | buf[name.len() + 1..][..val.len()].copy_from_slice(val); |
| @@ -304,4 +308,69 @@ impl<'a> Control<'a> { | |||
| 304 | 308 | ||
| 305 | resp_len | 309 | resp_len |
| 306 | } | 310 | } |
| 311 | |||
| 312 | /// Start a wifi scan | ||
| 313 | /// | ||
| 314 | /// Returns a `Stream` of networks found by the device | ||
| 315 | /// | ||
| 316 | /// # Note | ||
| 317 | /// Device events are currently implemented using a bounded queue. | ||
| 318 | /// To not miss any events, you should make sure to always await the stream. | ||
| 319 | pub async fn scan(&mut self) -> Scanner<'_> { | ||
| 320 | const SCANTYPE_PASSIVE: u8 = 1; | ||
| 321 | |||
| 322 | let scan_params = ScanParams { | ||
| 323 | version: 1, | ||
| 324 | action: 1, | ||
| 325 | sync_id: 1, | ||
| 326 | ssid_len: 0, | ||
| 327 | ssid: [0; 32], | ||
| 328 | bssid: [0xff; 6], | ||
| 329 | bss_type: 2, | ||
| 330 | scan_type: SCANTYPE_PASSIVE, | ||
| 331 | nprobes: !0, | ||
| 332 | active_time: !0, | ||
| 333 | passive_time: !0, | ||
| 334 | home_time: !0, | ||
| 335 | channel_num: 0, | ||
| 336 | channel_list: [0; 1], | ||
| 337 | }; | ||
| 338 | |||
| 339 | self.events.mask.enable(&[Event::ESCAN_RESULT]); | ||
| 340 | let subscriber = self.events.queue.subscriber().unwrap(); | ||
| 341 | self.set_iovar_v::<256>("escan", &scan_params.to_bytes()).await; | ||
| 342 | |||
| 343 | Scanner { | ||
| 344 | subscriber, | ||
| 345 | events: &self.events, | ||
| 346 | } | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | pub struct Scanner<'a> { | ||
| 351 | subscriber: EventSubscriber<'a>, | ||
| 352 | events: &'a Events, | ||
| 353 | } | ||
| 354 | |||
| 355 | impl Scanner<'_> { | ||
| 356 | /// wait for the next found network | ||
| 357 | pub async fn next(&mut self) -> Option<BssInfo> { | ||
| 358 | let event = self.subscriber.next_message_pure().await; | ||
| 359 | if event.header.status != EStatus::PARTIAL { | ||
| 360 | self.events.mask.disable_all(); | ||
| 361 | return None; | ||
| 362 | } | ||
| 363 | |||
| 364 | if let events::Payload::BssInfo(bss) = event.payload { | ||
| 365 | Some(bss) | ||
| 366 | } else { | ||
| 367 | None | ||
| 368 | } | ||
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 372 | impl Drop for Scanner<'_> { | ||
| 373 | fn drop(&mut self) { | ||
| 374 | self.events.mask.disable_all(); | ||
| 375 | } | ||
| 307 | } | 376 | } |
