esp32: wifi provisioning via AP captive portal
Replace compile-time env!() wifi/server config with NVS-based runtime provisioning. Boot checks NVS — if no config, starts AP mode (KFrame-Setup) with DNS responder + HTTP config form. WiFi failure clears config and reboots into setup mode.
This commit is contained in:
@@ -2,6 +2,7 @@ mod adapters;
|
||||
mod boot;
|
||||
mod config;
|
||||
mod hal;
|
||||
mod provisioning;
|
||||
mod tasks;
|
||||
|
||||
use std::sync::mpsc;
|
||||
@@ -10,10 +11,6 @@ use esp_idf_svc::eventloop::EspSystemEventLoop;
|
||||
use esp_idf_svc::nvs::EspDefaultNvsPartition;
|
||||
use log::info;
|
||||
|
||||
const WIFI_SSID: &str = env!("KFRAME_WIFI_SSID");
|
||||
const WIFI_PASS: &str = env!("KFRAME_WIFI_PASS");
|
||||
const SERVER_ADDR: &str = env!("KFRAME_SERVER_ADDR");
|
||||
|
||||
fn main() {
|
||||
esp_idf_svc::sys::link_patches();
|
||||
esp_idf_svc::log::EspLogger::initialize_default();
|
||||
@@ -24,7 +21,7 @@ fn main() {
|
||||
let sysloop = EspSystemEventLoop::take().unwrap();
|
||||
let nvs = EspDefaultNvsPartition::take().unwrap();
|
||||
|
||||
let display = hal::display::init(hal::display::DisplayHardware {
|
||||
let mut display = hal::display::init(hal::display::DisplayHardware {
|
||||
spi: peripherals.spi2,
|
||||
sclk: peripherals.pins.gpio18.into(),
|
||||
mosi: peripherals.pins.gpio23.into(),
|
||||
@@ -34,11 +31,46 @@ fn main() {
|
||||
});
|
||||
info!("Display ready");
|
||||
|
||||
info!("Connecting WiFi...");
|
||||
let _wifi = hal::wifi::init(peripherals.modem, sysloop, nvs, WIFI_SSID, WIFI_PASS)
|
||||
.expect("WiFi init failed");
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
tasks::network::spawn(SERVER_ADDR.into(), tx);
|
||||
tasks::render::run(config::SCREEN, display, rx);
|
||||
match provisioning::read_config(nvs.clone()) {
|
||||
Some(cfg) => run_station(peripherals.modem, sysloop, nvs, cfg, display),
|
||||
None => {
|
||||
info!("No config found, entering setup mode");
|
||||
run_setup(peripherals.modem, sysloop, nvs, &mut display);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_station(
|
||||
modem: esp_idf_hal::modem::Modem<'static>,
|
||||
sysloop: EspSystemEventLoop,
|
||||
nvs: EspDefaultNvsPartition,
|
||||
cfg: provisioning::DeviceConfig,
|
||||
display: adapters::display::Esp32DisplayAdapter,
|
||||
) {
|
||||
info!("Connecting WiFi...");
|
||||
match hal::wifi::init(modem, sysloop.clone(), nvs.clone(), &cfg.wifi_ssid, &cfg.wifi_pass) {
|
||||
Ok(_wifi) => {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
tasks::network::spawn(cfg.server_addr, tx);
|
||||
tasks::render::run(config::SCREEN, display, rx);
|
||||
}
|
||||
Err(e) => {
|
||||
info!("WiFi failed ({e}), clearing config and rebooting to setup mode");
|
||||
provisioning::clear_config(nvs);
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
unsafe { esp_idf_svc::sys::esp_restart(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_setup(
|
||||
modem: esp_idf_hal::modem::Modem<'static>,
|
||||
sysloop: EspSystemEventLoop,
|
||||
nvs: EspDefaultNvsPartition,
|
||||
display: &mut adapters::display::Esp32DisplayAdapter,
|
||||
) {
|
||||
let _wifi = hal::wifi::init_ap(modem, sysloop, nvs.clone())
|
||||
.expect("AP mode failed");
|
||||
|
||||
provisioning::portal::run_captive_portal(nvs, display);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user