More cleanup in esp-radio (#4040)

* More cleanup in `esp-radio`

* misc

* address reviews

* docs update

* fmt
This commit is contained in:
Kirill Mikhailov 2025-09-04 16:03:19 +02:00 committed by GitHub
parent d9f6d7d73e
commit 38fd991ff7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 122 additions and 141 deletions

View File

@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- common traits for `Protocol`, `Country`, (#4017) - common traits for `Protocol`, `Country`, (#4017)
- `BuilderLite` pattern to `AccessPointConfig`, `ClientConfig` (#4017) - `BuilderLite` pattern to `AccessPointConfig`, `ClientConfig` (#4017)
- lifetime to `Sniffer` (#4017) - lifetime to `Sniffer` (#4017)
- `dtim_period` parameter for `PowerSaveMode` (#4040)
### Changed ### Changed
@ -38,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `RxControlInfo` hidden behind `esp-now` feature (#4017) - `RxControlInfo` hidden behind `esp-now` feature (#4017)
- `set_configuration()` to `set_config() (#4017) - `set_configuration()` to `set_config() (#4017)
- `WifiState` split into `WifiStaState` and `WifiApState` (#4046) - `WifiState` split into `WifiStaState` and `WifiApState` (#4046)
- `Mixed` has been renamed to `ApSta` in `Config` and `Capability` (#4040)
### Fixed ### Fixed
@ -51,6 +53,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `EnumSetType` from `Protocol`, `Country` enums (#4017) - `EnumSetType` from `Protocol`, `Country` enums (#4017)
- `AtomicWifiState` and `WifiDeviceMode` are not available anymore (#4029) - `AtomicWifiState` and `WifiDeviceMode` are not available anymore (#4029)
- `wifi_state()` and `WifiState` are not available anymore (#4046) - `wifi_state()` and `WifiState` are not available anymore (#4046)
- `config` module (#4040)
## [v0.15.0] - 2025-07-16 ## [v0.15.0] - 2025-07-16

View File

@ -96,4 +96,30 @@ Same for `set_configuration()` to `set_config()`:
```diff ```diff
- if esp_radio::wifi::wifi_state() == WifiState::StaConnected { ... } - if esp_radio::wifi::wifi_state() == WifiState::StaConnected { ... }
+ if esp_radio::wifi::sta_state() == WifiStaState::Connected { ... } + if esp_radio::wifi::sta_state() == WifiStaState::Connected { ... }
```
## `Mixed` mode has been renamed to `ApSta`
```diff
- let client_config = Config::Mixed(
- ClientConfig::default()
- .with_ssid("ssid".into())
- .with_password("password".into()),
- AccessPointConfig::default().with_ssid("esp-radio".into()),
- );
+ let client_config = Config::ApSta(
+ ClientConfig::default()
+ .with_ssid("ssid".into())
+ .with_password("password".into()),
+ AccessPointConfig::default().with_ssid("esp-radio".into()),
+ );
```
## `PowerSaveMode` is moved to `wifi` module
```diff
controller
- .set_power_saving(esp_radio::config::PowerSaveMode::None)
+ .set_power_saving(esp_radio::wifi::PowerSaveMode::None)
.unwrap();
``` ```

View File

@ -14,7 +14,6 @@ use esp_wifi_sys::{c_types::c_char, include::malloc};
use super::{OSI_FUNCS_TIME_BLOCKING, malloc::free}; use super::{OSI_FUNCS_TIME_BLOCKING, malloc::free};
use crate::{ use crate::{
CONFIG,
ESP_RADIO_LOCK, ESP_RADIO_LOCK,
binary::c_types::{c_int, c_void}, binary::c_types::{c_int, c_void},
memory_fence::memory_fence, memory_fence::memory_fence,

View File

@ -1,44 +0,0 @@
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// Tunable parameters for the Wi-Fi driver
#[allow(unused)] // currently there are no ble tunables
pub(crate) struct Config {
pub(crate) rx_queue_size: usize,
pub(crate) tx_queue_size: usize,
pub(crate) static_rx_buf_num: usize,
pub(crate) dynamic_rx_buf_num: usize,
pub(crate) static_tx_buf_num: usize,
pub(crate) dynamic_tx_buf_num: usize,
pub(crate) ampdu_rx_enable: bool,
pub(crate) ampdu_tx_enable: bool,
pub(crate) amsdu_tx_enable: bool,
pub(crate) rx_ba_win: usize,
pub(crate) max_burst_size: usize,
pub(crate) country_code: &'static str,
pub(crate) country_code_operating_class: u8,
pub(crate) mtu: usize,
pub(crate) listen_interval: u16,
pub(crate) beacon_timeout: u16,
pub(crate) ap_beacon_timeout: u16,
pub(crate) failure_retry_cnt: u8,
pub(crate) scan_method: u32,
}
#[non_exhaustive]
#[derive(Default)]
pub enum PowerSaveMode {
#[default]
None,
Minimum,
Maximum,
}
impl From<PowerSaveMode> for esp_wifi_sys::include::wifi_ps_type_t {
fn from(s: PowerSaveMode) -> Self {
match s {
PowerSaveMode::None => esp_wifi_sys::include::wifi_ps_type_t_WIFI_PS_NONE,
PowerSaveMode::Minimum => esp_wifi_sys::include::wifi_ps_type_t_WIFI_PS_MIN_MODEM,
PowerSaveMode::Maximum => esp_wifi_sys::include::wifi_ps_type_t_WIFI_PS_MAX_MODEM,
}
}
}

View File

@ -53,9 +53,10 @@
//! You can get inspiration from the [ESP-IDF examples](https://github.com/espressif/esp-idf/tree/release/v5.3/examples/wifi/iperf) //! You can get inspiration from the [ESP-IDF examples](https://github.com/espressif/esp-idf/tree/release/v5.3/examples/wifi/iperf)
//! //!
//! Please note that the configuration keys are usually named slightly different and not all configuration keys apply. //! Please note that the configuration keys are usually named slightly different and not all configuration keys apply.
//! #![cfg_attr(
//! By default the power-saving mode is [PowerSaveMode::None](crate::config::PowerSaveMode::None) and `ESP_RADIO_PHY_ENABLE_USB` is enabled by default. feature = "wifi",
//! doc = "By default the power-saving mode is [PowerSaveMode::None](crate::wifi::PowerSaveMode::None) and `ESP_RADIO_PHY_ENABLE_USB` is enabled by default."
)]
//! In addition pay attention to these configuration keys: //! In addition pay attention to these configuration keys:
//! - `ESP_RADIO_RX_QUEUE_SIZE` //! - `ESP_RADIO_RX_QUEUE_SIZE`
//! - `ESP_RADIO_TX_QUEUE_SIZE` //! - `ESP_RADIO_TX_QUEUE_SIZE`
@ -113,7 +114,6 @@ use core::marker::PhantomData;
use common_adapter::chip_specific::phy_mem_init; use common_adapter::chip_specific::phy_mem_init;
pub use common_adapter::{phy_calibration_data, set_phy_calibration_data}; pub use common_adapter::{phy_calibration_data, set_phy_calibration_data};
use esp_config::*;
use esp_hal::{self as hal}; use esp_hal::{self as hal};
use esp_radio_preempt_driver as preempt; use esp_radio_preempt_driver as preempt;
use esp_sync::RawMutex; use esp_sync::RawMutex;
@ -175,7 +175,6 @@ unstable_module! {
#[cfg(feature = "ieee802154")] #[cfg(feature = "ieee802154")]
pub mod ieee802154; pub mod ieee802154;
} }
pub mod config;
pub(crate) mod common_adapter; pub(crate) mod common_adapter;
@ -203,31 +202,6 @@ const _: () = {
}; };
}; };
pub(crate) const CONFIG: config::Config = config::Config {
rx_queue_size: esp_config_int!(usize, "ESP_RADIO_CONFIG_RX_QUEUE_SIZE"),
tx_queue_size: esp_config_int!(usize, "ESP_RADIO_CONFIG_TX_QUEUE_SIZE"),
static_rx_buf_num: esp_config_int!(usize, "ESP_RADIO_CONFIG_STATIC_RX_BUF_NUM"),
dynamic_rx_buf_num: esp_config_int!(usize, "ESP_RADIO_CONFIG_DYNAMIC_RX_BUF_NUM"),
static_tx_buf_num: esp_config_int!(usize, "ESP_RADIO_CONFIG_STATIC_TX_BUF_NUM"),
dynamic_tx_buf_num: esp_config_int!(usize, "ESP_RADIO_CONFIG_DYNAMIC_TX_BUF_NUM"),
ampdu_rx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMPDU_RX_ENABLE"),
ampdu_tx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMPDU_TX_ENABLE"),
amsdu_tx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMSDU_TX_ENABLE"),
rx_ba_win: esp_config_int!(usize, "ESP_RADIO_CONFIG_RX_BA_WIN"),
max_burst_size: esp_config_int!(usize, "ESP_RADIO_CONFIG_MAX_BURST_SIZE"),
country_code: esp_config_str!("ESP_RADIO_CONFIG_COUNTRY_CODE"),
country_code_operating_class: esp_config_int!(
u8,
"ESP_RADIO_CONFIG_COUNTRY_CODE_OPERATING_CLASS"
),
mtu: esp_config_int!(usize, "ESP_RADIO_CONFIG_MTU"),
listen_interval: esp_config_int!(u16, "ESP_RADIO_CONFIG_LISTEN_INTERVAL"),
beacon_timeout: esp_config_int!(u16, "ESP_RADIO_CONFIG_BEACON_TIMEOUT"),
ap_beacon_timeout: esp_config_int!(u16, "ESP_RADIO_CONFIG_AP_BEACON_TIMEOUT"),
failure_retry_cnt: esp_config_int!(u8, "ESP_RADIO_CONFIG_FAILURE_RETRY_CNT"),
scan_method: esp_config_int!(u32, "ESP_RADIO_CONFIG_SCAN_METHOD"),
};
#[derive(Debug, PartialEq, PartialOrd)] #[derive(Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// Controller for the ESP Radio driver. /// Controller for the ESP Radio driver.
@ -279,7 +253,6 @@ pub fn init<'d>() -> Result<Controller<'d>, InitializationError> {
return Err(InitializationError::WrongClockConfig); return Err(InitializationError::WrongClockConfig);
} }
info!("esp-radio configuration {:?}", crate::CONFIG);
crate::common_adapter::chip_specific::enable_wifi_power_domain(); crate::common_adapter::chip_specific::enable_wifi_power_domain();
phy_mem_init(); phy_mem_init();

View File

@ -1,3 +1,4 @@
use esp_config::{esp_config_bool, esp_config_int};
use esp_wifi_sys::include::{ use esp_wifi_sys::include::{
ESP_WIFI_OS_ADAPTER_MAGIC, ESP_WIFI_OS_ADAPTER_MAGIC,
ESP_WIFI_OS_ADAPTER_VERSION, ESP_WIFI_OS_ADAPTER_VERSION,
@ -257,21 +258,21 @@ pub(super) static mut G_CONFIG: wifi_init_config_t = wifi_init_config_t {
sha256_vector: None, sha256_vector: None,
crc32: None, crc32: None,
}, },
static_rx_buf_num: crate::CONFIG.static_rx_buf_num as i32, static_rx_buf_num: esp_config_int!(i32, "ESP_RADIO_CONFIG_RX_QUEUE_SIZE"),
dynamic_rx_buf_num: crate::CONFIG.dynamic_rx_buf_num as i32, dynamic_rx_buf_num: esp_config_int!(i32, "ESP_RADIO_CONFIG_DYNAMIC_RX_BUF_NUM"),
tx_buf_type: esp_wifi_sys::include::CONFIG_ESP_WIFI_TX_BUFFER_TYPE as i32, tx_buf_type: esp_wifi_sys::include::CONFIG_ESP_WIFI_TX_BUFFER_TYPE as i32,
static_tx_buf_num: crate::CONFIG.static_tx_buf_num as i32, static_tx_buf_num: esp_config_int!(i32, "ESP_RADIO_CONFIG_STATIC_TX_BUF_NUM"),
dynamic_tx_buf_num: crate::CONFIG.dynamic_tx_buf_num as i32, dynamic_tx_buf_num: esp_config_int!(i32, "ESP_RADIO_CONFIG_DYNAMIC_TX_BUF_NUM"),
rx_mgmt_buf_type: esp_wifi_sys::include::CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF as i32, rx_mgmt_buf_type: esp_wifi_sys::include::CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF as i32,
rx_mgmt_buf_num: esp_wifi_sys::include::CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF as i32, rx_mgmt_buf_num: esp_wifi_sys::include::CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF as i32,
cache_tx_buf_num: esp_wifi_sys::include::WIFI_CACHE_TX_BUFFER_NUM as i32, cache_tx_buf_num: esp_wifi_sys::include::WIFI_CACHE_TX_BUFFER_NUM as i32,
csi_enable: cfg!(feature = "csi") as i32, csi_enable: cfg!(feature = "csi") as i32,
ampdu_rx_enable: crate::CONFIG.ampdu_rx_enable as i32, ampdu_rx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMPDU_RX_ENABLE") as i32,
ampdu_tx_enable: crate::CONFIG.ampdu_tx_enable as i32, ampdu_tx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMPDU_TX_ENABLE") as i32,
amsdu_tx_enable: crate::CONFIG.amsdu_tx_enable as i32, amsdu_tx_enable: esp_config_bool!("ESP_RADIO_CONFIG_AMSDU_TX_ENABLE") as i32,
nvs_enable: 0, nvs_enable: 0,
nano_enable: 0, nano_enable: 0,
rx_ba_win: crate::CONFIG.rx_ba_win as i32, rx_ba_win: esp_config_int!(i32, "ESP_RADIO_CONFIG_RX_BA_WIN"),
wifi_task_core_id: 0, wifi_task_core_id: 0,
beacon_max_len: esp_wifi_sys::include::WIFI_SOFTAP_BEACON_MAX_LEN as i32, beacon_max_len: esp_wifi_sys::include::WIFI_SOFTAP_BEACON_MAX_LEN as i32,
mgmt_sbuf_num: esp_wifi_sys::include::WIFI_MGMT_SBUF_NUM as i32, mgmt_sbuf_num: esp_wifi_sys::include::WIFI_MGMT_SBUF_NUM as i32,

View File

@ -18,6 +18,7 @@ use core::{
}; };
use enumset::{EnumSet, EnumSetType}; use enumset::{EnumSet, EnumSetType};
use esp_config::{esp_config_int, esp_config_str};
use esp_hal::asynch::AtomicWaker; use esp_hal::asynch::AtomicWaker;
use esp_sync::NonReentrantMutex; use esp_sync::NonReentrantMutex;
#[cfg(all(any(feature = "sniffer", feature = "esp-now"), feature = "unstable"))] #[cfg(all(any(feature = "sniffer", feature = "esp-now"), feature = "unstable"))]
@ -75,13 +76,12 @@ pub use state::*;
use crate::{ use crate::{
Controller, Controller,
common_adapter::*, common_adapter::*,
config::PowerSaveMode,
esp_wifi_result, esp_wifi_result,
hal::ram, hal::ram,
wifi::private::PacketBuffer, wifi::private::PacketBuffer,
}; };
const MTU: usize = crate::CONFIG.mtu; const MTU: usize = esp_config_int!(usize, "ESP_RADIO_CONFIG_MTU");
#[cfg(all(feature = "csi", esp32c6))] #[cfg(all(feature = "csi", esp32c6))]
use crate::binary::include::wifi_csi_acquire_config_t; use crate::binary::include::wifi_csi_acquire_config_t;
@ -212,10 +212,9 @@ pub enum Protocol {
} }
/// Secondary Wi-Fi channels. /// Secondary Wi-Fi channels.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd)] #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Default)]
pub enum SecondaryChannel { pub enum SecondaryChannel {
// TODO: Need to extend that for 5GHz // TODO: Need to extend that for 5GHz
/// No secondary channel (default). /// No secondary channel (default).
@ -305,7 +304,6 @@ pub struct AccessPointInfo {
/// Configuration for a Wi-Fi access point. /// Configuration for a Wi-Fi access point.
#[derive(BuilderLite, Clone, Eq, PartialEq)] #[derive(BuilderLite, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[non_exhaustive]
pub struct AccessPointConfig { pub struct AccessPointConfig {
/// The SSID of the access point. /// The SSID of the access point.
#[builder_lite(reference)] #[builder_lite(reference)]
@ -332,6 +330,8 @@ pub struct AccessPointConfig {
/// The maximum number of connections allowed on the access point. /// The maximum number of connections allowed on the access point.
max_connections: u16, max_connections: u16,
/// Dtim period of the access point (Range: 1 ~ 10).
dtim_period: u8,
} }
impl AccessPointConfig { impl AccessPointConfig {
@ -344,6 +344,10 @@ impl AccessPointConfig {
return Err(WifiError::InvalidArguments); return Err(WifiError::InvalidArguments);
} }
if !(1..=10).contains(&self.dtim_period) {
return Err(WifiError::InvalidArguments);
}
Ok(()) Ok(())
} }
} }
@ -359,6 +363,7 @@ impl Default for AccessPointConfig {
auth_method: AuthMethod::None, auth_method: AuthMethod::None,
password: String::new(), password: String::new(),
max_connections: 255, max_connections: 255,
dtim_period: 2,
} }
} }
} }
@ -425,7 +430,6 @@ impl defmt::Format for AccessPointConfig {
/// Client configuration for a Wi-Fi connection. /// Client configuration for a Wi-Fi connection.
#[derive(BuilderLite, Clone, Default, Eq, PartialEq)] #[derive(BuilderLite, Clone, Default, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[non_exhaustive]
pub struct ClientConfig { pub struct ClientConfig {
/// The SSID of the Wi-Fi network. /// The SSID of the Wi-Fi network.
#[builder_lite(reference)] #[builder_lite(reference)]
@ -434,7 +438,6 @@ pub struct ClientConfig {
/// The BSSID (MAC address) of the client. /// The BSSID (MAC address) of the client.
bssid: Option<[u8; 6]>, bssid: Option<[u8; 6]>,
// pub protocol: Protocol,
/// The authentication method for the Wi-Fi connection. /// The authentication method for the Wi-Fi connection.
auth_method: AuthMethod, auth_method: AuthMethod,
@ -733,7 +736,7 @@ pub enum Capability {
/// The device can operate in both client and access point modes /// The device can operate in both client and access point modes
/// simultaneously. /// simultaneously.
Mixed, ApSta,
} }
/// Configuration of Wi-Fi operation mode. /// Configuration of Wi-Fi operation mode.
@ -754,7 +757,7 @@ pub enum Config {
AccessPoint(AccessPointConfig), AccessPoint(AccessPointConfig),
/// Simultaneous client and access point configuration. /// Simultaneous client and access point configuration.
Mixed(ClientConfig, AccessPointConfig), ApSta(ClientConfig, AccessPointConfig),
/// EAP client configuration for enterprise Wi-Fi. /// EAP client configuration for enterprise Wi-Fi.
#[cfg(feature = "wifi-eap")] #[cfg(feature = "wifi-eap")]
@ -770,7 +773,7 @@ impl Config {
Config::AccessPoint(access_point_configuration) => { Config::AccessPoint(access_point_configuration) => {
access_point_configuration.validate() access_point_configuration.validate()
} }
Config::Mixed(client_configuration, access_point_configuration) => { Config::ApSta(client_configuration, access_point_configuration) => {
client_configuration.validate()?; client_configuration.validate()?;
access_point_configuration.validate() access_point_configuration.validate()
} }
@ -783,7 +786,7 @@ impl Config {
pub fn as_client_conf_ref(&self) -> Option<&ClientConfig> { pub fn as_client_conf_ref(&self) -> Option<&ClientConfig> {
match self { match self {
Self::Client(client_conf) => Some(client_conf), Self::Client(client_conf) => Some(client_conf),
Self::Mixed(client_conf, _) => Some(client_conf), Self::ApSta(client_conf, _) => Some(client_conf),
_ => None, _ => None,
} }
} }
@ -792,7 +795,7 @@ impl Config {
pub fn as_ap_conf_ref(&self) -> Option<&AccessPointConfig> { pub fn as_ap_conf_ref(&self) -> Option<&AccessPointConfig> {
match self { match self {
Self::AccessPoint(ap_conf) => Some(ap_conf), Self::AccessPoint(ap_conf) => Some(ap_conf),
Self::Mixed(_, ap_conf) => Some(ap_conf), Self::ApSta(_, ap_conf) => Some(ap_conf),
_ => None, _ => None,
} }
} }
@ -802,10 +805,10 @@ impl Config {
pub fn as_client_conf_mut(&mut self) -> &mut ClientConfig { pub fn as_client_conf_mut(&mut self) -> &mut ClientConfig {
match self { match self {
Self::Client(client_conf) => client_conf, Self::Client(client_conf) => client_conf,
Self::Mixed(_, _) => { Self::ApSta(_, _) => {
let prev = mem::replace(self, Self::None); let prev = mem::replace(self, Self::None);
match prev { match prev {
Self::Mixed(client_conf, _) => { Self::ApSta(client_conf, _) => {
*self = Self::Client(client_conf); *self = Self::Client(client_conf);
self.as_client_conf_mut() self.as_client_conf_mut()
} }
@ -824,10 +827,10 @@ impl Config {
pub fn as_ap_conf_mut(&mut self) -> &mut AccessPointConfig { pub fn as_ap_conf_mut(&mut self) -> &mut AccessPointConfig {
match self { match self {
Self::AccessPoint(ap_conf) => ap_conf, Self::AccessPoint(ap_conf) => ap_conf,
Self::Mixed(_, _) => { Self::ApSta(_, _) => {
let prev = mem::replace(self, Self::None); let prev = mem::replace(self, Self::None);
match prev { match prev {
Self::Mixed(_, ap_conf) => { Self::ApSta(_, ap_conf) => {
*self = Self::AccessPoint(ap_conf); *self = Self::AccessPoint(ap_conf);
self.as_ap_conf_mut() self.as_ap_conf_mut()
} }
@ -845,12 +848,12 @@ impl Config {
/// and `AccessPointConfig`. /// and `AccessPointConfig`.
pub fn as_mixed_conf_mut(&mut self) -> (&mut ClientConfig, &mut AccessPointConfig) { pub fn as_mixed_conf_mut(&mut self) -> (&mut ClientConfig, &mut AccessPointConfig) {
match self { match self {
Self::Mixed(client_conf, ap_conf) => (client_conf, ap_conf), Self::ApSta(client_conf, ap_conf) => (client_conf, ap_conf),
Self::AccessPoint(_) => { Self::AccessPoint(_) => {
let prev = mem::replace(self, Self::None); let prev = mem::replace(self, Self::None);
match prev { match prev {
Self::AccessPoint(ap_conf) => { Self::AccessPoint(ap_conf) => {
*self = Self::Mixed(Default::default(), ap_conf); *self = Self::ApSta(Default::default(), ap_conf);
self.as_mixed_conf_mut() self.as_mixed_conf_mut()
} }
_ => unreachable!(), _ => unreachable!(),
@ -860,14 +863,14 @@ impl Config {
let prev = mem::replace(self, Self::None); let prev = mem::replace(self, Self::None);
match prev { match prev {
Self::Client(client_conf) => { Self::Client(client_conf) => {
*self = Self::Mixed(client_conf, Default::default()); *self = Self::ApSta(client_conf, Default::default());
self.as_mixed_conf_mut() self.as_mixed_conf_mut()
} }
_ => unreachable!(), _ => unreachable!(),
} }
} }
_ => { _ => {
*self = Self::Mixed(Default::default(), Default::default()); *self = Self::ApSta(Default::default(), Default::default());
self.as_mixed_conf_mut() self.as_mixed_conf_mut()
} }
} }
@ -958,7 +961,7 @@ impl TryFrom<&Config> for WifiMode {
Config::None => return Err(WifiError::UnknownWifiMode), Config::None => return Err(WifiError::UnknownWifiMode),
Config::AccessPoint(_) => Self::Ap, Config::AccessPoint(_) => Self::Ap,
Config::Client(_) => Self::Sta, Config::Client(_) => Self::Sta,
Config::Mixed(_, _) => Self::ApSta, Config::ApSta(_, _) => Self::ApSta,
#[cfg(feature = "wifi-eap")] #[cfg(feature = "wifi-eap")]
Config::EapClient(_) => Self::Sta, Config::EapClient(_) => Self::Sta,
}; };
@ -1179,8 +1182,8 @@ impl CsiConfig {
} }
} }
const RX_QUEUE_SIZE: usize = crate::CONFIG.rx_queue_size; const RX_QUEUE_SIZE: usize = esp_config_int!(usize, "ESP_RADIO_CONFIG_RX_QUEUE_SIZE");
const TX_QUEUE_SIZE: usize = crate::CONFIG.tx_queue_size; const TX_QUEUE_SIZE: usize = esp_config_int!(usize, "ESP_RADIO_CONFIG_TX_QUEUE_SIZE");
pub(crate) static DATA_QUEUE_RX_AP: NonReentrantMutex<VecDeque<PacketBuffer>> = pub(crate) static DATA_QUEUE_RX_AP: NonReentrantMutex<VecDeque<PacketBuffer>> =
NonReentrantMutex::new(VecDeque::new()); NonReentrantMutex::new(VecDeque::new());
@ -1599,13 +1602,13 @@ pub(crate) fn wifi_start() -> Result<(), WifiError> {
if mode.is_ap() { if mode.is_ap() {
esp_wifi_result!(include::esp_wifi_set_inactive_time( esp_wifi_result!(include::esp_wifi_set_inactive_time(
wifi_interface_t_WIFI_IF_AP, wifi_interface_t_WIFI_IF_AP,
crate::CONFIG.ap_beacon_timeout esp_config_int!(u16, "ESP_RADIO_CONFIG_AP_BEACON_TIMEOUT")
))?; ))?;
} }
if mode.is_sta() { if mode.is_sta() {
esp_wifi_result!(include::esp_wifi_set_inactive_time( esp_wifi_result!(include::esp_wifi_set_inactive_time(
wifi_interface_t_WIFI_IF_STA, wifi_interface_t_WIFI_IF_STA,
crate::CONFIG.beacon_timeout esp_config_int!(u16, "ESP_RADIO_CONFIG_BEACON_TIMEOUT")
))?; ))?;
}; };
} }
@ -1678,25 +1681,25 @@ pub struct ScanConfig<'a> {
/// If [`None`] is passed, all SSIDs will be returned. /// If [`None`] is passed, all SSIDs will be returned.
/// If [`Some`] is passed, only the APs matching the given SSID will be /// If [`Some`] is passed, only the APs matching the given SSID will be
/// returned. /// returned.
pub ssid: Option<&'a str>, ssid: Option<&'a str>,
/// BSSID to filter for. /// BSSID to filter for.
/// If [`None`] is passed, all BSSIDs will be returned. /// If [`None`] is passed, all BSSIDs will be returned.
/// If [`Some`] is passed, only the APs matching the given BSSID will be /// If [`Some`] is passed, only the APs matching the given BSSID will be
/// returned. /// returned.
pub bssid: Option<[u8; 6]>, bssid: Option<[u8; 6]>,
/// Channel to filter for. /// Channel to filter for.
/// If [`None`] is passed, all channels will be returned. /// If [`None`] is passed, all channels will be returned.
/// If [`Some`] is passed, only the APs on the given channel will be /// If [`Some`] is passed, only the APs on the given channel will be
/// returned. /// returned.
pub channel: Option<u8>, channel: Option<u8>,
/// Whether to show hidden networks. /// Whether to show hidden networks.
pub show_hidden: bool, show_hidden: bool,
/// Scan type, active or passive. /// Scan type, active or passive.
pub scan_type: ScanTypeConfig, scan_type: ScanTypeConfig,
/// The maximum number of networks to return when scanning. /// The maximum number of networks to return when scanning.
/// If [`None`] is passed, all networks will be returned. /// If [`None`] is passed, all networks will be returned.
/// If [`Some`] is passed, the specified number of networks will be returned. /// If [`Some`] is passed, the specified number of networks will be returned.
pub max: Option<usize>, max: Option<usize>,
} }
pub(crate) fn wifi_start_scan( pub(crate) fn wifi_start_scan(
@ -2254,10 +2257,10 @@ impl Device for WifiDevice<'_> {
fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities { fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities {
let mut caps = DeviceCapabilities::default(); let mut caps = DeviceCapabilities::default();
caps.max_transmission_unit = MTU; caps.max_transmission_unit = MTU;
caps.max_burst_size = if crate::CONFIG.max_burst_size == 0 { caps.max_burst_size = if esp_config_int!(usize, "ESP_RADIO_CONFIG_MAX_BURST_SIZE") == 0 {
None None
} else { } else {
Some(crate::CONFIG.max_burst_size) Some(esp_config_int!(usize, "ESP_RADIO_CONFIG_MAX_BURST_SIZE"))
}; };
caps caps
} }
@ -2388,7 +2391,7 @@ fn apply_ap_config(config: &AccessPointConfig) -> Result<(), WifiError> {
}, },
sae_pwe_h2e: 0, sae_pwe_h2e: 0,
csa_count: 3, csa_count: 3,
dtim_period: 2, dtim_period: config.dtim_period,
}, },
}; };
@ -2410,11 +2413,11 @@ fn apply_sta_config(config: &ClientConfig) -> Result<(), WifiError> {
sta: wifi_sta_config_t { sta: wifi_sta_config_t {
ssid: [0; 32], ssid: [0; 32],
password: [0; 64], password: [0; 64],
scan_method: crate::CONFIG.scan_method, scan_method: esp_config_int!(u32, "ESP_RADIO_CONFIG_SCAN_METHOD"),
bssid_set: config.bssid.is_some(), bssid_set: config.bssid.is_some(),
bssid: config.bssid.unwrap_or_default(), bssid: config.bssid.unwrap_or_default(),
channel: config.channel.unwrap_or(0), channel: config.channel.unwrap_or(0),
listen_interval: crate::CONFIG.listen_interval, listen_interval: esp_config_int!(u16, "ESP_RADIO_CONFIG_LISTEN_INTERVAL"),
sort_method: wifi_sort_method_t_WIFI_CONNECT_AP_BY_SIGNAL, sort_method: wifi_sort_method_t_WIFI_CONNECT_AP_BY_SIGNAL,
threshold: wifi_scan_threshold_t { threshold: wifi_scan_threshold_t {
rssi: -99, rssi: -99,
@ -2427,7 +2430,7 @@ fn apply_sta_config(config: &ClientConfig) -> Result<(), WifiError> {
sae_pwe_h2e: 3, sae_pwe_h2e: 3,
_bitfield_align_1: [0; 0], _bitfield_align_1: [0; 0],
_bitfield_1: __BindgenBitfieldUnit::new([0; 4]), _bitfield_1: __BindgenBitfieldUnit::new([0; 4]),
failure_retry_cnt: crate::CONFIG.failure_retry_cnt, failure_retry_cnt: esp_config_int!(u8, "ESP_RADIO_CONFIG_FAILURE_RETRY_CNT"),
_bitfield_align_2: [0; 0], _bitfield_align_2: [0; 0],
_bitfield_2: __BindgenBitfieldUnit::new([0; 4]), _bitfield_2: __BindgenBitfieldUnit::new([0; 4]),
sae_pk_mode: 0, // ?? sae_pk_mode: 0, // ??
@ -2453,11 +2456,11 @@ fn apply_sta_eap_config(config: &EapClientConfig) -> Result<(), WifiError> {
sta: wifi_sta_config_t { sta: wifi_sta_config_t {
ssid: [0; 32], ssid: [0; 32],
password: [0; 64], password: [0; 64],
scan_method: crate::CONFIG.scan_method, scan_method: esp_config_int!(u32, "ESP_RADIO_CONFIG_SCAN_METHOD"),
bssid_set: config.bssid.is_some(), bssid_set: config.bssid.is_some(),
bssid: config.bssid.unwrap_or_default(), bssid: config.bssid.unwrap_or_default(),
channel: config.channel.unwrap_or(0), channel: config.channel.unwrap_or(0),
listen_interval: crate::CONFIG.listen_interval, listen_interval: esp_config_int!(u16, "ESP_RADIO_CONFIG_LISTEN_INTERVAL"),
sort_method: wifi_sort_method_t_WIFI_CONNECT_AP_BY_SIGNAL, sort_method: wifi_sort_method_t_WIFI_CONNECT_AP_BY_SIGNAL,
threshold: wifi_scan_threshold_t { threshold: wifi_scan_threshold_t {
rssi: -99, rssi: -99,
@ -2470,7 +2473,7 @@ fn apply_sta_eap_config(config: &EapClientConfig) -> Result<(), WifiError> {
sae_pwe_h2e: 3, sae_pwe_h2e: 3,
_bitfield_align_1: [0; 0], _bitfield_align_1: [0; 0],
_bitfield_1: __BindgenBitfieldUnit::new([0; 4]), _bitfield_1: __BindgenBitfieldUnit::new([0; 4]),
failure_retry_cnt: crate::CONFIG.failure_retry_cnt, failure_retry_cnt: esp_config_int!(u8, "ESP_RADIO_CONFIG_FAILURE_RETRY_CNT"),
_bitfield_align_2: [0; 0], _bitfield_align_2: [0; 0],
_bitfield_2: __BindgenBitfieldUnit::new([0; 4]), _bitfield_2: __BindgenBitfieldUnit::new([0; 4]),
sae_pk_mode: 0, // ?? sae_pk_mode: 0, // ??
@ -2675,10 +2678,11 @@ pub(crate) mod embassy {
fn capabilities(&self) -> Capabilities { fn capabilities(&self) -> Capabilities {
let mut caps = Capabilities::default(); let mut caps = Capabilities::default();
caps.max_transmission_unit = MTU; caps.max_transmission_unit = MTU;
caps.max_burst_size = if crate::CONFIG.max_burst_size == 0 { caps.max_burst_size = if esp_config_int!(usize, "ESP_RADIO_CONFIG_MAX_BURST_SIZE") == 0
{
None None
} else { } else {
Some(crate::CONFIG.max_burst_size) Some(esp_config_int!(usize, "ESP_RADIO_CONFIG_MAX_BURST_SIZE"))
}; };
caps caps
} }
@ -2689,8 +2693,28 @@ pub(crate) mod embassy {
} }
} }
/// Power saving mode settings for the modem.
#[non_exhaustive]
#[derive(Default)]
pub enum PowerSaveMode {
/// No power saving.
#[default]
None,
/// Minimum power save mode. In this mode, station wakes up to receive beacon every DTIM period.
Minimum,
/// Maximum power save mode. In this mode, interval to receive beacons is determined by the
/// `ESP_RADIO_CONFIG_LISTEN_INTERVAL` config option.
Maximum,
}
pub(crate) fn apply_power_saving(ps: PowerSaveMode) -> Result<(), WifiError> { pub(crate) fn apply_power_saving(ps: PowerSaveMode) -> Result<(), WifiError> {
esp_wifi_result!(unsafe { esp_wifi_sys::include::esp_wifi_set_ps(ps.into()) })?; esp_wifi_result!(unsafe {
esp_wifi_sys::include::esp_wifi_set_ps(match ps {
PowerSaveMode::None => esp_wifi_sys::include::wifi_ps_type_t_WIFI_PS_NONE,
PowerSaveMode::Minimum => esp_wifi_sys::include::wifi_ps_type_t_WIFI_PS_MIN_MODEM,
PowerSaveMode::Maximum => esp_wifi_sys::include::wifi_ps_type_t_WIFI_PS_MAX_MODEM,
})
})?;
Ok(()) Ok(())
} }
@ -2743,10 +2767,9 @@ pub fn new<'d>(
crate::wifi::wifi_init()?; crate::wifi::wifi_init()?;
let mut cntry_code = [0u8; 3]; let mut cntry_code = [0u8; 3];
cntry_code[..crate::CONFIG.country_code.len()] cntry_code[..esp_config_str!("ESP_RADIO_CONFIG_COUNTRY_CODE").len()]
.copy_from_slice(crate::CONFIG.country_code.as_bytes()); .copy_from_slice(esp_config_str!("ESP_RADIO_CONFIG_COUNTRY_CODE").as_bytes());
cntry_code[2] = crate::CONFIG.country_code_operating_class; cntry_code[2] = esp_config_int!(u8, "ESP_RADIO_CONFIG_COUNTRY_CODE_OPERATING_CLASS");
unsafe { unsafe {
let country = wifi_country_t { let country = wifi_country_t {
cc: cntry_code, cc: cntry_code,
@ -2959,7 +2982,7 @@ impl WifiController<'_> {
/// Get the supported capabilities of the controller. /// Get the supported capabilities of the controller.
pub fn capabilities(&self) -> Result<EnumSet<crate::wifi::Capability>, WifiError> { pub fn capabilities(&self) -> Result<EnumSet<crate::wifi::Capability>, WifiError> {
let caps = let caps =
enumset::enum_set! { Capability::Client | Capability::AccessPoint | Capability::Mixed }; enumset::enum_set! { Capability::Client | Capability::AccessPoint | Capability::ApSta };
Ok(caps) Ok(caps)
} }
@ -2980,7 +3003,7 @@ impl WifiController<'_> {
Config::None => wifi_mode_t_WIFI_MODE_NULL, Config::None => wifi_mode_t_WIFI_MODE_NULL,
Config::Client(_) => wifi_mode_t_WIFI_MODE_STA, Config::Client(_) => wifi_mode_t_WIFI_MODE_STA,
Config::AccessPoint(_) => wifi_mode_t_WIFI_MODE_AP, Config::AccessPoint(_) => wifi_mode_t_WIFI_MODE_AP,
Config::Mixed(_, _) => wifi_mode_t_WIFI_MODE_APSTA, Config::ApSta(_, _) => wifi_mode_t_WIFI_MODE_APSTA,
#[cfg(feature = "wifi-eap")] #[cfg(feature = "wifi-eap")]
Config::EapClient(_) => wifi_mode_t_WIFI_MODE_STA, Config::EapClient(_) => wifi_mode_t_WIFI_MODE_STA,
}; };
@ -2991,7 +3014,7 @@ impl WifiController<'_> {
Config::None => Ok::<(), WifiError>(()), Config::None => Ok::<(), WifiError>(()),
Config::Client(config) => apply_sta_config(config), Config::Client(config) => apply_sta_config(config),
Config::AccessPoint(config) => apply_ap_config(config), Config::AccessPoint(config) => apply_ap_config(config),
Config::Mixed(sta_config, ap_config) => { Config::ApSta(sta_config, ap_config) => {
apply_ap_config(ap_config).and_then(|()| apply_sta_config(sta_config)) apply_ap_config(ap_config).and_then(|()| apply_sta_config(sta_config))
} }
#[cfg(feature = "wifi-eap")] #[cfg(feature = "wifi-eap")]

View File

@ -71,7 +71,7 @@ fn main() -> ! {
sta_socket_set.add(smoltcp::socket::dhcpv4::Socket::new()); sta_socket_set.add(smoltcp::socket::dhcpv4::Socket::new());
let sta_stack = Stack::new(sta_interface, sta_device, sta_socket_set, now, rng.random()); let sta_stack = Stack::new(sta_interface, sta_device, sta_socket_set, now, rng.random());
let client_config = Config::Mixed( let client_config = Config::ApSta(
ClientConfig::default() ClientConfig::default()
.with_ssid(SSID.into()) .with_ssid(SSID.into())
.with_password(PASSWORD.into()), .with_password(PASSWORD.into()),

View File

@ -105,7 +105,7 @@ fn main() -> ! {
let iface = create_interface(&mut device); let iface = create_interface(&mut device);
controller controller
.set_power_saving(esp_radio::config::PowerSaveMode::None) .set_power_saving(esp_radio::wifi::PowerSaveMode::None)
.unwrap(); .unwrap();
let mut socket_set_entries: [SocketStorage; 3] = Default::default(); let mut socket_set_entries: [SocketStorage; 3] = Default::default();

View File

@ -69,7 +69,7 @@ fn main() -> ! {
let stack = Stack::new(iface, device, socket_set, now, rng.random()); let stack = Stack::new(iface, device, socket_set, now, rng.random());
controller controller
.set_power_saving(esp_radio::config::PowerSaveMode::None) .set_power_saving(esp_radio::wifi::PowerSaveMode::None)
.unwrap(); .unwrap();
let client_config = Config::Client( let client_config = Config::Client(

View File

@ -118,7 +118,7 @@ async fn main(spawner: Spawner) -> ! {
seed, seed,
); );
let client_config = Config::Mixed( let client_config = Config::ApSta(
ClientConfig::default() ClientConfig::default()
.with_ssid(SSID.into()) .with_ssid(SSID.into())
.with_password(PASSWORD.into()), .with_password(PASSWORD.into()),

View File

@ -51,7 +51,7 @@ fn main() -> ! {
let iface = create_interface(&mut device); let iface = create_interface(&mut device);
controller controller
.set_power_saving(esp_radio::config::PowerSaveMode::None) .set_power_saving(esp_radio::wifi::PowerSaveMode::None)
.unwrap(); .unwrap();
let mut socket_set_entries: [SocketStorage; 3] = Default::default(); let mut socket_set_entries: [SocketStorage; 3] = Default::default();

View File

@ -86,7 +86,7 @@ async fn main(spawner: Spawner) -> ! {
let wifi_interface = interfaces.sta; let wifi_interface = interfaces.sta;
controller controller
.set_power_saving(esp_radio::config::PowerSaveMode::None) .set_power_saving(esp_radio::wifi::PowerSaveMode::None)
.unwrap(); .unwrap();
cfg_if::cfg_if! { cfg_if::cfg_if! {

View File

@ -73,7 +73,7 @@ fn main() -> ! {
let iface = create_interface(&mut device); let iface = create_interface(&mut device);
controller controller
.set_power_saving(esp_radio::config::PowerSaveMode::None) .set_power_saving(esp_radio::wifi::PowerSaveMode::None)
.unwrap(); .unwrap();
let mut socket_set_entries: [SocketStorage; 3] = Default::default(); let mut socket_set_entries: [SocketStorage; 3] = Default::default();