use own wifi implementation to connect to wifi. store credentials in flash. no wifi connection yet
This commit is contained in:
+130
-53
@@ -1,67 +1,144 @@
|
||||
use crate::navigation::navigation::Mutex;
|
||||
use crate::peripherals::storage::Nvs;
|
||||
use alloc::sync::Arc;
|
||||
use embassy_executor::Spawner;
|
||||
|
||||
use crate::Mutex;
|
||||
use crate::alloc::string::ToString;
|
||||
use crate::Signal;
|
||||
use crate::navigation::outputs::Outputs;
|
||||
use crate::peripherals::Peripherals;
|
||||
#[cfg(not(feature = "wokwi"))]
|
||||
pub async fn setup_wifi(
|
||||
wifi: esp_hal::peripherals::WIFI<'static>,
|
||||
nvs: Arc<Mutex<Nvs>>,
|
||||
spawner: &Spawner,
|
||||
) {
|
||||
let espnvs = esp_hal_wifimanager::Nvs::new_from_nvs(nvs, 0, 0);
|
||||
use crate::peripherals::storage::wifistore::WifiStore;
|
||||
use crate::peripherals::storage::wifistore::WifiStoreError;
|
||||
use alloc::string::String;
|
||||
use core::error::Error;
|
||||
use core::fmt::Display;
|
||||
use esp_radio::wifi::WifiController;
|
||||
use esp_radio::*;
|
||||
|
||||
let mut wm_settings = esp_hal_wifimanager::WmSettings::default();
|
||||
|
||||
wm_settings.ssid.clear();
|
||||
_ = core::fmt::write(
|
||||
&mut wm_settings.ssid,
|
||||
format_args!("CreatureDex-{:X}", esp_hal_wifimanager::get_efuse_mac()),
|
||||
);
|
||||
|
||||
wm_settings.wifi_conn_timeout = 30000;
|
||||
wm_settings.esp_reset_timeout = Some(300000); // 5min
|
||||
|
||||
let wifi_res =
|
||||
esp_hal_wifimanager::init_wm(wm_settings, spawner, Some(&espnvs), wifi, None).await;
|
||||
|
||||
log::info!("wifi_res: {wifi_res:?}");
|
||||
#[derive(Debug)]
|
||||
pub struct WifiCredentials {
|
||||
pub ssid: String,
|
||||
pub pass: String,
|
||||
}
|
||||
|
||||
#[cfg(feature = "wokwi")]
|
||||
pub async fn setup_wifi(
|
||||
wifi: esp_hal::peripherals::WIFI<'static>,
|
||||
nvs: Arc<Mutex<Nvs>>,
|
||||
spawner: &Spawner,
|
||||
) {
|
||||
log::info!("Wokwi mode active: pre-seeding WiFi Manager with Wokwi credentials");
|
||||
pub static WIFI_CREDENTIALS: Signal<WifiCredentials> = Signal::new();
|
||||
|
||||
use esp_nvs::Key;
|
||||
const WIFIMANAGER_NAMESPACE: Key = Key::from_str("wifimanager");
|
||||
const WIFIMANAGER_NVS_KEY: Key = Key::from_str("WIFI_SETUP");
|
||||
|
||||
if let Err(e) = nvs.lock().await.set(
|
||||
&WIFIMANAGER_NAMESPACE,
|
||||
&WIFIMANAGER_NVS_KEY,
|
||||
"{\"ssid\":\"Wokwi-GUEST\",\"psk\":\"\",\"data\":{}}",
|
||||
) {
|
||||
log::error!("Failed to store Wokwi WiFi config in NVS: {e:?}");
|
||||
return;
|
||||
#[derive(Debug)]
|
||||
pub struct Wifi {
|
||||
pub controller: WifiController<'static>,
|
||||
pub interfaces: wifi::Interfaces<'static>,
|
||||
pub credentials: WifiCredentials,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum WifiError {
|
||||
Store(WifiStoreError),
|
||||
Radio(esp_radio::wifi::WifiError),
|
||||
NoCredentialsStored,
|
||||
}
|
||||
|
||||
impl Error for WifiError {}
|
||||
|
||||
impl Display for WifiError {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
WifiError::Store(e) => e.fmt(f),
|
||||
WifiError::Radio(e) => e.fmt(f),
|
||||
WifiError::NoCredentialsStored => write!(f, "No WiFi credentials stored in flash"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WifiStoreError> for WifiError {
|
||||
fn from(error: WifiStoreError) -> WifiError {
|
||||
WifiError::Store(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<esp_radio::wifi::WifiError> for WifiError {
|
||||
fn from(error: esp_radio::wifi::WifiError) -> WifiError {
|
||||
WifiError::Radio(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl Wifi {
|
||||
pub fn new(
|
||||
wifi: esp_hal::peripherals::WIFI<'static>,
|
||||
credentials: WifiCredentials
|
||||
) -> Result<Self, WifiError> {
|
||||
let wifi = wifi::new(wifi, Default::default())?;
|
||||
|
||||
Ok(Self {
|
||||
controller: wifi.0,
|
||||
interfaces: wifi.1,
|
||||
credentials
|
||||
})
|
||||
}
|
||||
|
||||
// Preload connection data so init_wm can connect immediately without AP setup.
|
||||
let nvs = esp_hal_wifimanager::Nvs::new_from_nvs(nvs, 0, 0);
|
||||
pub async fn initialize_credentials(
|
||||
wifi_store: &WifiStore,
|
||||
) -> Result<WifiCredentials, WifiError> {
|
||||
let stored_credentials = wifi_store.load_credentials().await?;
|
||||
let ssid = option_env!("WIFI_SSID").map_or(stored_credentials.ssid, |v| v.to_string());
|
||||
let pass = option_env!("WIFI_PASS").map_or(stored_credentials.pass, |v| v.to_string());
|
||||
|
||||
let mut wm_settings = esp_hal_wifimanager::WmSettings::default();
|
||||
log::info!("initial wifi credentials:\nssid:{ssid}, pass:{pass}");
|
||||
Ok(WifiCredentials {ssid, pass})
|
||||
}
|
||||
|
||||
// Wokwi simulation uses a default open network called "Wokwi-GUEST"
|
||||
wm_settings.ssid.clear();
|
||||
_ = core::fmt::write(&mut wm_settings.ssid, format_args!("Wokwi-GUEST"));
|
||||
#[cfg(feature = "wokwi")]
|
||||
pub async fn setup(
|
||||
wifi: esp_hal::peripherals::WIFI<'static>,
|
||||
nvs: Arc<Mutex<Nvs>>,
|
||||
spawner: &Spawner,
|
||||
) {
|
||||
log::info!("Wokwi mode active: pre-seeding WiFi Manager with Wokwi credentials");
|
||||
|
||||
wm_settings.wifi_conn_timeout = 30000;
|
||||
const WIFIMANAGER_NAMESPACE: Key = Key::from_str("wifimanager");
|
||||
const WIFIMANAGER_NVS_KEY: Key = Key::from_str("WIFI_SETUP");
|
||||
|
||||
// Initialize Wi-Fi connection through WiFi Manager using the pre-seeded NVS data.
|
||||
let wifi_res = esp_hal_wifimanager::init_wm(wm_settings, spawner, Some(&nvs), wifi, None).await;
|
||||
if let Err(e) = nvs.lock().await.set(
|
||||
&WIFIMANAGER_NAMESPACE,
|
||||
&WIFIMANAGER_NVS_KEY,
|
||||
"{\"ssid\":\"Wokwi-GUEST\",\"psk\":\"\",\"data\":{}}",
|
||||
) {
|
||||
log::error!("Failed to store Wokwi WiFi config in NVS: {e:?}");
|
||||
return;
|
||||
}
|
||||
|
||||
log::info!("Wokwi wifi_res: {wifi_res:?}");
|
||||
// Preload connection data so init_wm can connect immediately without AP setup.
|
||||
let nvs = esp_hal_wifimanager::Nvs::new_from_nvs(nvs, 0, 0);
|
||||
|
||||
let mut wm_settings = esp_hal_wifimanager::WmSettings::default();
|
||||
|
||||
// Wokwi simulation uses a default open network called "Wokwi-GUEST"
|
||||
wm_settings.ssid.clear();
|
||||
_ = core::fmt::write(&mut wm_settings.ssid, format_args!("Wokwi-GUEST"));
|
||||
|
||||
wm_settings.wifi_conn_timeout = 30000;
|
||||
|
||||
// Initialize Wi-Fi connection through WiFi Manager using the pre-seeded NVS data.
|
||||
let wifi_res =
|
||||
esp_hal_wifimanager::init_wm(wm_settings, spawner, Some(&nvs), wifi, None).await;
|
||||
|
||||
log::info!("Wokwi wifi_res: {wifi_res:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn wait_for_wifi_credentials(_outputs: &'static Mutex<Outputs>, peripherals: &'static Peripherals) {
|
||||
|
||||
loop {
|
||||
log::info!("Waiting for new WiFi credentials");
|
||||
let credentials = WIFI_CREDENTIALS.wait().await;
|
||||
|
||||
log::info!("Received new WiFi credentials:\nssid: {}, pass: {}", credentials.ssid, credentials.pass);
|
||||
if let Err(err) = peripherals.store.lock().await.wifi_store.save_credentials(&credentials).await {
|
||||
log::error!("Error storing credentials: {err}");
|
||||
continue;
|
||||
}
|
||||
|
||||
log::info!("Saved new WiFi credentials. Restarting WiFi");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user