|
5 | 5 | pub mod event; |
6 | 6 | mod internal; |
7 | 7 | pub(crate) mod os_adapter; |
| 8 | +mod scan; |
8 | 9 | pub(crate) mod state; |
9 | | -use alloc::{collections::vec_deque::VecDeque, string::String}; |
10 | | -use core::{ |
11 | | - fmt::Debug, |
12 | | - marker::PhantomData, |
13 | | - mem::MaybeUninit, |
14 | | - ptr::addr_of, |
15 | | - task::Poll, |
16 | | - time::Duration, |
17 | | -}; |
| 10 | +use alloc::{collections::vec_deque::VecDeque, string::String, vec::Vec}; |
| 11 | +use core::{fmt::Debug, marker::PhantomData, ptr::addr_of, task::Poll, time::Duration}; |
18 | 12 |
|
19 | 13 | use enumset::{EnumSet, EnumSetType}; |
20 | 14 | use esp_config::esp_config_int; |
@@ -84,7 +78,10 @@ use crate::{ |
84 | 78 | wifi_scan_channel_bitmap_t, |
85 | 79 | }, |
86 | 80 | }, |
87 | | - wifi::private::PacketBuffer, |
| 81 | + wifi::{ |
| 82 | + private::PacketBuffer, |
| 83 | + scan::{FreeApListOnDrop, ScanResults}, |
| 84 | + }, |
88 | 85 | }; |
89 | 86 |
|
90 | 87 | const MTU: usize = esp_config_int!(usize, "ESP_RADIO_CONFIG_WIFI_MTU"); |
@@ -1779,7 +1776,7 @@ pub(crate) fn wifi_start_scan( |
1779 | 1776 | }; |
1780 | 1777 |
|
1781 | 1778 | let mut ssid_buf = ssid.map(|m| { |
1782 | | - let mut buf = alloc::vec::Vec::from_iter(m.bytes()); |
| 1779 | + let mut buf = Vec::from_iter(m.bytes()); |
1783 | 1780 | buf.push(b'\0'); |
1784 | 1781 | buf |
1785 | 1782 | }); |
@@ -1978,33 +1975,6 @@ impl WifiDevice<'_> { |
1978 | 1975 | } |
1979 | 1976 | } |
1980 | 1977 |
|
1981 | | -fn convert_ap_info(record: &include::wifi_ap_record_t) -> AccessPointInfo { |
1982 | | - let str_len = record |
1983 | | - .ssid |
1984 | | - .iter() |
1985 | | - .position(|&c| c == 0) |
1986 | | - .unwrap_or(record.ssid.len()); |
1987 | | - let ssid_ref = unsafe { core::str::from_utf8_unchecked(&record.ssid[..str_len]) }; |
1988 | | - |
1989 | | - let mut ssid = String::new(); |
1990 | | - ssid.push_str(ssid_ref); |
1991 | | - |
1992 | | - AccessPointInfo { |
1993 | | - ssid, |
1994 | | - bssid: record.bssid, |
1995 | | - channel: record.primary, |
1996 | | - secondary_channel: match record.second { |
1997 | | - include::wifi_second_chan_t_WIFI_SECOND_CHAN_NONE => SecondaryChannel::None, |
1998 | | - include::wifi_second_chan_t_WIFI_SECOND_CHAN_ABOVE => SecondaryChannel::Above, |
1999 | | - include::wifi_second_chan_t_WIFI_SECOND_CHAN_BELOW => SecondaryChannel::Below, |
2000 | | - _ => panic!(), |
2001 | | - }, |
2002 | | - signal_strength: record.rssi, |
2003 | | - auth_method: Some(AuthMethod::from_raw(record.authmode)), |
2004 | | - country: Country::try_from_c(&record.country), |
2005 | | - } |
2006 | | -} |
2007 | | - |
2008 | 1978 | /// The radio metadata header of the received packet, which is the common header |
2009 | 1979 | /// at the beginning of all RX callback buffers in promiscuous mode. |
2010 | 1980 | #[cfg(not(esp32c6))] |
@@ -2564,21 +2534,6 @@ pub(crate) fn apply_power_saving(ps: PowerSaveMode) -> Result<(), WifiError> { |
2564 | 2534 | Ok(()) |
2565 | 2535 | } |
2566 | 2536 |
|
2567 | | -struct FreeApListOnDrop; |
2568 | | -impl FreeApListOnDrop { |
2569 | | - pub fn defuse(self) { |
2570 | | - core::mem::forget(self); |
2571 | | - } |
2572 | | -} |
2573 | | - |
2574 | | -impl Drop for FreeApListOnDrop { |
2575 | | - fn drop(&mut self) { |
2576 | | - unsafe { |
2577 | | - include::esp_wifi_clear_ap_list(); |
2578 | | - } |
2579 | | - } |
2580 | | -} |
2581 | | - |
2582 | 2537 | /// Represents the Wi-Fi controller and its associated interfaces. |
2583 | 2538 | #[non_exhaustive] |
2584 | 2539 | pub struct Interfaces<'d> { |
@@ -3049,33 +3004,17 @@ impl WifiController<'_> { |
3049 | 3004 | pub fn scan_with_config( |
3050 | 3005 | &mut self, |
3051 | 3006 | config: ScanConfig<'_>, |
3052 | | - ) -> Result<alloc::vec::Vec<AccessPointInfo>, WifiError> { |
| 3007 | + ) -> Result<Vec<AccessPointInfo>, WifiError> { |
3053 | 3008 | esp_wifi_result!(crate::wifi::wifi_start_scan(true, config))?; |
3054 | 3009 | self.scan_results(config.max.unwrap_or(usize::MAX)) |
3055 | 3010 | } |
3056 | 3011 |
|
3057 | | - fn scan_results(&mut self, max: usize) -> Result<alloc::vec::Vec<AccessPointInfo>, WifiError> { |
3058 | | - let mut scanned = alloc::vec::Vec::<AccessPointInfo>::new(); |
3059 | | - let mut bss_total: u16 = max as u16; |
3060 | | - |
3061 | | - // Prevents memory leak on error |
3062 | | - let guard = FreeApListOnDrop; |
3063 | | - |
3064 | | - unsafe { esp_wifi_result!(include::esp_wifi_scan_get_ap_num(&mut bss_total))? }; |
3065 | | - |
3066 | | - guard.defuse(); |
3067 | | - |
3068 | | - let mut record: MaybeUninit<include::wifi_ap_record_t> = MaybeUninit::uninit(); |
3069 | | - for _ in 0..usize::min(bss_total as usize, max) { |
3070 | | - unsafe { esp_wifi_result!(include::esp_wifi_scan_get_ap_record(record.as_mut_ptr()))? }; |
3071 | | - let record = unsafe { MaybeUninit::assume_init_ref(&record) }; |
3072 | | - let ap_info = convert_ap_info(record); |
3073 | | - scanned.push(ap_info); |
3074 | | - } |
3075 | | - |
3076 | | - unsafe { esp_wifi_result!(include::esp_wifi_clear_ap_list())? }; |
| 3012 | + fn scan_results_iter(&mut self) -> Result<ScanResults<'_>, WifiError> { |
| 3013 | + ScanResults::new(self) |
| 3014 | + } |
3077 | 3015 |
|
3078 | | - Ok(scanned) |
| 3016 | + fn scan_results(&mut self, max: usize) -> Result<Vec<AccessPointInfo>, WifiError> { |
| 3017 | + Ok(self.scan_results_iter()?.take(max).collect::<Vec<_>>()) |
3079 | 3018 | } |
3080 | 3019 |
|
3081 | 3020 | /// Starts the Wi-Fi controller. |
@@ -3282,14 +3221,13 @@ impl WifiController<'_> { |
3282 | 3221 | pub async fn scan_with_config_async( |
3283 | 3222 | &mut self, |
3284 | 3223 | config: ScanConfig<'_>, |
3285 | | - ) -> Result<alloc::vec::Vec<AccessPointInfo>, WifiError> { |
| 3224 | + ) -> Result<Vec<AccessPointInfo>, WifiError> { |
3286 | 3225 | Self::clear_events(WifiEvent::ScanDone); |
3287 | 3226 | esp_wifi_result!(wifi_start_scan(false, config))?; |
3288 | 3227 |
|
3289 | | - // Prevents memory leak if `scan_n`'s future is dropped. |
| 3228 | + // Prevents memory leak if `scan_with_config_async`'s future is dropped. |
3290 | 3229 | let guard = FreeApListOnDrop; |
3291 | 3230 | WifiEventFuture::new(WifiEvent::ScanDone).await; |
3292 | | - |
3293 | 3231 | guard.defuse(); |
3294 | 3232 |
|
3295 | 3233 | let result = self.scan_results(config.max.unwrap_or(usize::MAX))?; |
|
0 commit comments