feat: Extended the Scan API

This commit is contained in:
umgefahren 2024-01-19 23:49:49 +01:00 committed by Dario Nieuwenhuis
parent a2eb46e9e4
commit 6ca43030db
4 changed files with 89 additions and 14 deletions

View File

@ -10,7 +10,7 @@ repository = "https://github.com/embassy-rs/embassy"
documentation = "https://docs.embassy.dev/cyw43"
[features]
defmt = ["dep:defmt"]
defmt = ["dep:defmt", "heapless/defmt-03"]
log = ["dep:log"]
# Fetch console logs from the WiFi firmware and forward them to `log` or `defmt`.
@ -32,6 +32,8 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
num_enum = { version = "0.5.7", default-features = false }
heapless = "0.8.0"
[package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/cyw43-v$VERSION/cyw43/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/cyw43/src/"

View File

@ -3,7 +3,7 @@ use core::iter::zip;
use embassy_net_driver_channel as ch;
use embassy_net_driver_channel::driver::{HardwareAddress, LinkState};
use embassy_time::Timer;
use embassy_time::{Duration, Timer};
use crate::consts::*;
use crate::events::{Event, EventSubscriber, Events};
@ -35,6 +35,45 @@ pub struct Control<'a> {
ioctl_state: &'a IoctlState,
}
#[derive(Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ScanType {
Active {
/// Period of time to wait on each channel when active scanning.
dwell_time: Option<Duration>,
},
Passive {
/// Period of time to wait on each channel when passive scanning.
dwell_time: Option<Duration>,
},
}
#[derive(Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ScanOptions {
pub ssid: Option<heapless::String<32>>,
/// If set to `None`, all APs will be returned. If set to `Some`, only APs
/// with the specified BSSID will be returned.
pub bssid: Option<[u8; 6]>,
/// Number of probes to send on each channel.
pub nprobes: Option<u16>,
/// Time to spend waiting on the home channel.
pub home_time: Option<Duration>,
pub scan_type: ScanType,
}
impl Default for ScanOptions {
fn default() -> Self {
Self {
ssid: None,
bssid: None,
nprobes: None,
home_time: None,
scan_type: ScanType::Passive { dwell_time: None },
}
}
}
impl<'a> Control<'a> {
pub(crate) fn new(state_ch: ch::StateRunner<'a>, event_sub: &'a Events, ioctl_state: &'a IoctlState) -> Self {
Self {
@ -471,22 +510,56 @@ impl<'a> Control<'a> {
/// # Note
/// Device events are currently implemented using a bounded queue.
/// To not miss any events, you should make sure to always await the stream.
pub async fn scan(&mut self) -> Scanner<'_> {
pub async fn scan(&mut self, scan_opts: ScanOptions) -> Scanner<'_> {
const SCANTYPE_ACTIVE: u8 = 0;
const SCANTYPE_PASSIVE: u8 = 1;
let mut active_time = !0;
let mut passive_time = !0;
let scan_type = match scan_opts.scan_type {
ScanType::Active { dwell_time: None } => SCANTYPE_ACTIVE,
ScanType::Active {
dwell_time: Some(dwell_time),
} => {
active_time = dwell_time.as_millis() as u32;
if active_time == !0 {
active_time = !0 - 1;
}
SCANTYPE_ACTIVE
}
ScanType::Passive { dwell_time: None } => SCANTYPE_PASSIVE,
ScanType::Passive {
dwell_time: Some(dwell_time),
} => {
passive_time = dwell_time.as_millis() as u32;
if passive_time == !0 {
passive_time = !0 - 1;
}
SCANTYPE_PASSIVE
}
};
let scan_params = ScanParams {
version: 1,
action: 1,
sync_id: 1,
ssid_len: 0,
ssid: [0; 32],
bssid: [0xff; 6],
ssid_len: scan_opts.ssid.as_ref().map(|e| e.as_bytes().len() as u32).unwrap_or(0),
ssid: scan_opts
.ssid
.map(|e| {
let mut ssid = [0; 32];
ssid[..e.as_bytes().len()].copy_from_slice(e.as_bytes());
ssid
})
.unwrap_or([0; 32]),
bssid: scan_opts.bssid.unwrap_or([0xff; 6]),
bss_type: 2,
scan_type: SCANTYPE_PASSIVE,
nprobes: !0,
active_time: !0,
passive_time: !0,
home_time: !0,
scan_type,
nprobes: scan_opts.nprobes.unwrap_or(!0).into(),
active_time,
passive_time,
home_time: scan_opts.home_time.map(|e| e.as_millis() as u32).unwrap_or(!0),
channel_num: 0,
channel_list: [0; 1],
};

View File

@ -311,13 +311,13 @@ pub struct Status {
pub status: u32,
}
#[derive(Clone, Copy)]
#[derive(Copy, Clone)]
pub enum Payload {
None,
BssInfo(BssInfo),
}
#[derive(Clone, Copy)]
#[derive(Copy, Clone)]
pub struct Message {
pub header: Status,

View File

@ -65,7 +65,7 @@ async fn main(spawner: Spawner) {
.set_power_management(cyw43::PowerManagementMode::PowerSave)
.await;
let mut scanner = control.scan().await;
let mut scanner = control.scan(Default::default()).await;
while let Some(bss) = scanner.next().await {
if let Ok(ssid_str) = str::from_utf8(&bss.ssid) {
info!("scanned {} == {:x}", ssid_str, bss.bssid);