aboutsummaryrefslogtreecommitdiff
path: root/src/control.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/control.rs')
-rw-r--r--src/control.rs75
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
7pub use crate::bus::SpiBusCyw43; 7pub use crate::bus::SpiBusCyw43;
8use crate::consts::*; 8use crate::consts::*;
9use crate::events::{Event, Events}; 9use crate::events::{Event, EventSubscriber, Events};
10use crate::fmt::Bytes; 10use crate::fmt::Bytes;
11use crate::ioctl::{IoctlState, IoctlType}; 11use crate::ioctl::{IoctlState, IoctlType};
12use crate::structs::*; 12use crate::structs::*;
13use crate::{countries, PowerManagementMode}; 13use crate::{countries, events, PowerManagementMode};
14 14
15pub struct Control<'a> { 15pub 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
350pub struct Scanner<'a> {
351 subscriber: EventSubscriber<'a>,
352 events: &'a Events,
353}
354
355impl 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
372impl Drop for Scanner<'_> {
373 fn drop(&mut self) {
374 self.events.mask.disable_all();
375 }
307} 376}