//! Provisioning mode: SoftAP + captive DNS + HTTP config form.
//!
//! Blocks until the user submits a usable config, then reboots into normal
//! operation.
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use anyhow::Result;
use esp_idf_svc::eventloop::EspSystemEventLoop;
use esp_idf_svc::hal::delay::FreeRtos;
use esp_idf_svc::hal::modem::WifiModemPeripheral;
use esp_idf_svc::hal::reset;
use crate::config::PortalConfig;
use crate::dns;
use crate::portal::{self, Pages};
use crate::store::ConfigStore;
use crate::wifi::{self, AP_IP};
/// Stack for the captive-DNS thread. It handles one 512-byte datagram at a
/// time and allocates only the reply vector.
const DNS_STACK: usize = 4096;
/// How long to let the confirmation page flush before resetting.
const FLUSH_DELAY_MS: u32 = 1500;
/// How often to check whether a config has landed.
const POLL_MS: u32 = 200;
/// Run provisioning until a config is saved, then reboot. Never returns
/// normally; the `Ok` variant exists only so callers can use `?`.
pub fn run<C, M>(
modem: M,
sysloop: EspSystemEventLoop,
store: ConfigStore,
ssid: &str,
pages: Pages,
) -> Result<()>
where
C: PortalConfig,
M: WifiModemPeripheral + 'static,
{
// Keep the AP handle alive for the duration of provisioning.
let _ap = wifi::start_ap(modem, sysloop, store.partition().clone(), ssid)?;
std::thread::Builder::new()
.stack_size(DNS_STACK)
.spawn(move || dns::serve(AP_IP))?;
let saved = Arc::new(AtomicBool::new(false));
// Keep the server alive; dropping it would unregister the handlers.
let _server = portal::start::<C>(store, saved.clone(), pages)?;
log::info!("provisioning ready: join '{ssid}', config opens automatically");
loop {
if saved.load(Ordering::SeqCst) {
log::info!("config saved; rebooting into normal operation");
FreeRtos::delay_ms(FLUSH_DELAY_MS);
reset::restart();
}
FreeRtos::delay_ms(POLL_MS);
}
}
neiam
/neiam-portal
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
2.0 KiB · text
History
65cab78