diff --git a/rust/src/hal/esp.rs b/rust/src/hal/esp.rs index 86b6676..f1872f2 100644 --- a/rust/src/hal/esp.rs +++ b/rust/src/hal/esp.rs @@ -7,6 +7,7 @@ use chrono::{DateTime, Utc}; use serde::Serialize; use alloc::string::ToString; +use alloc::sync::Arc; use alloc::{format, string::String, vec::Vec}; use core::marker::PhantomData; use core::net::{IpAddr, Ipv4Addr}; @@ -14,7 +15,11 @@ use core::str::FromStr; use embassy_executor::{SendSpawner, Spawner}; use embassy_net::tcp::TcpSocket; use embassy_net::{IpListenEndpoint, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4}; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::mutex::Mutex; use embassy_time::{Duration, Instant, Timer}; +use embedded_storage::nor_flash::ReadNorFlash; +use embedded_storage::Storage; use esp_bootloader_esp_idf::ota::{Ota, OtaImageState, Slot}; use esp_bootloader_esp_idf::partitions::{Error, FlashRegion, PartitionEntry, PartitionTable}; use esp_hal::gpio::Input; @@ -23,8 +28,8 @@ use esp_hal::rtc_cntl::sleep::RtcSleepConfig; use esp_println::{print, println}; use esp_storage::FlashStorage; use esp_wifi::wifi::{ - AccessPointConfiguration, Configuration, Interfaces, WifiController, WifiDevice, WifiEvent, - WifiState, + AccessPointConfiguration, AccessPointInfo, Configuration, Interfaces, ScanConfig, + WifiController, WifiDevice, WifiEvent, WifiState, }; use log::{info, warn}; @@ -67,7 +72,7 @@ pub struct Esp<'a> { pub rng: Rng, //first starter (ap or sta will take these) pub interfaces: Option>, - pub controller: Option>, + pub controller: Arc>>, //only filled, if a useable mqtt client with working roundtrip could be established pub(crate) mqtt_client: Option>, @@ -76,7 +81,7 @@ pub struct Esp<'a> { pub(crate) wall_clock_offset: u64, pub ota: Ota<'static, FlashStorage>, - pub ota_next: &'static PartitionEntry<'static>, + pub ota_next: &'static mut FlashRegion<'static, FlashStorage>, } pub struct IpInfo { @@ -85,8 +90,6 @@ pub struct IpInfo { gateway: IpAddr, } -struct AccessPointInfo {} - macro_rules! mk_static { ($t:ty,$val:expr) => {{ static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); @@ -151,8 +154,7 @@ impl Esp<'_> { } pub async fn flash_ota(&mut self) -> anyhow::Result<()> { - let mut storage_ota_next = FlashStorage::new(); - let ota_next = self.ota_next.as_embedded_storage(&mut storage_ota_next); + let capacity = self.ota_next.capacity(); bail!("not implemented") } @@ -162,17 +164,14 @@ impl Esp<'_> { DateTime::from_timestamp_millis(wall_clock as i64).unwrap() } - pub(crate) async fn wifi_scan(&mut self) -> anyhow::Result> { - bail!("todo"); - // self.wifi_driver.start_scan( - // &ScanConfig { - // scan_type: ScanType::Passive(Duration::from_secs(5)), - // show_hidden: false, - // ..Default::default() - // }, - // true, - // )?; - // anyhow::Ok(self.wifi_driver.get_scan_result()?) + pub(crate) async fn wifi_scan(&mut self) -> Vec { + info!("start wifi scan"); + let mut lock = self.controller.try_lock().unwrap(); + info!("start wifi scan lock"); + let scan_config = ScanConfig::default(); + let rv = lock.scan_with_config_sync(scan_config).unwrap(); + info!("end wifi scan lock"); + return rv; } pub(crate) fn last_pump_time(&self, plant: usize) -> Option> { @@ -244,8 +243,9 @@ impl Esp<'_> { ); let stack = mk_static!(Stack, stack); - let controller = self.controller.take().unwrap(); - spawner.spawn(connection(controller, ssid)).ok(); + spawner + .spawn(connection(self.controller.clone(), ssid)) + .ok(); spawner.spawn(net_task(runner)).ok(); spawner.spawn(run_dhcp(stack.clone(), gw_ip_addr_str)).ok(); @@ -809,29 +809,27 @@ async fn run_dhcp(stack: Stack<'static>, gw_ip_addr: &'static str) { } #[embassy_executor::task] -async fn connection(mut controller: WifiController<'static>, ssid: String) { +async fn connection( + controller: Arc>>, + ssid: String, +) { println!("start connection task"); - println!("Device capabilities: {:?}", controller.capabilities()); - loop { - match esp_wifi::wifi::wifi_state() { - WifiState::ApStarted => { - // wait until we're no longer connected - controller.wait_for_event(WifiEvent::ApStop).await; - Timer::after(Duration::from_millis(5000)).await - } - _ => {} - } - if !matches!(controller.is_started(), core::result::Result::Ok(true)) { - let client_config = Configuration::AccessPoint(AccessPointConfiguration { - ssid: ssid.clone(), - ..Default::default() - }); - controller.set_configuration(&client_config).unwrap(); - println!("Starting wifi"); - controller.start_async().await.unwrap(); - println!("Wifi started!"); - } - } + println!( + "Device capabilities: {:?}", + controller.lock().await.capabilities() + ); + let client_config = Configuration::AccessPoint(AccessPointConfiguration { + ssid: ssid.clone(), + ..Default::default() + }); + controller + .lock() + .await + .set_configuration(&client_config) + .unwrap(); + println!("Starting wifi"); + controller.lock().await.start_async().await.unwrap(); + println!("Wifi started!"); } #[embassy_executor::task] diff --git a/rust/src/hal/mod.rs b/rust/src/hal/mod.rs index ea11e11..5457626 100644 --- a/rust/src/hal/mod.rs +++ b/rust/src/hal/mod.rs @@ -21,6 +21,7 @@ use crate::{ }; use alloc::boxed::Box; use alloc::format; +use alloc::sync::Arc; use anyhow::{Ok, Result}; use async_trait::async_trait; use embassy_executor::Spawner; @@ -273,10 +274,15 @@ impl PlantHal { }; let ota_next = mk_static!(PartitionEntry, ota_partition); + let storage_ota_next = mk_static!(FlashStorage, FlashStorage::new()); + let ota_next = mk_static!( + FlashRegion, + ota_next.as_embedded_storage(storage_ota_next) + ); let mut esp = Esp { rng, - controller: Some(controller), + controller: Arc::new(Mutex::new(controller)), interfaces: Some(interfaces), boot_button, mqtt_client: None, diff --git a/rust/src/webserver/mod.rs b/rust/src/webserver/mod.rs index 8d30871..1a0d85a 100644 --- a/rust/src/webserver/mod.rs +++ b/rust/src/webserver/mod.rs @@ -21,8 +21,8 @@ use log::info; use serde::{Deserialize, Serialize}; #[derive(Serialize, Debug)] -struct SSIDList<'a> { - ssids: Vec<&'a String>, +struct SSIDList { + ssids: Vec, } #[derive(Serialize, Debug)] @@ -369,6 +369,7 @@ impl Handler for HttpHandler { "/files" => Some(list_files(conn).await), "/log_localization" => Some(get_log_localization_config(conn).await), "/log" => Some(get_log(conn).await), + "/wifiscan" => Some(wifi_scan(conn).await), _ => None, }; match json { @@ -377,7 +378,17 @@ impl Handler for HttpHandler { } } }, - Method::Options | Method::Delete | Method::Head | Method::Post | Method::Put => None, + Method::Post => { + let json = match path { + "/wifiscan" => Some(wifi_scan(conn).await), + _ => None, + }; + match json { + None => None, + Some(json) => Some(handle_json(conn, json).await?), + } + } + Method::Options | Method::Delete | Method::Head | Method::Put => None, _ => None, }; let code = match status { @@ -406,6 +417,33 @@ impl Handler for HttpHandler { // reboot_now_for_reboot.store(true, std::sync::atomic::Ordering::Relaxed); // anyhow::Ok(()) +// fn wifi_scan( +// _request: &mut Request<&mut EspHttpConnection>, +// ) -> Result, anyhow::Error> { +// let mut board = BOARD_ACCESS.lock().unwrap(); +// let scan_result = board.board_hal.get_esp().wifi_scan()?; +// let mut ssids: Vec<&String<32>> = Vec::new(); +// scan_result.iter().for_each(|s| ssids.push(&s.ssid)); +// let ssid_json = serde_json::to_string(&SSIDList { ssids })?; +// log::info!("Sending ssid list {}", &ssid_json); +// anyhow::Ok(Some(ssid_json)) +// } + +async fn wifi_scan( + _request: &mut Connection<'_, T, N>, +) -> Result, anyhow::Error> { + let mut board = BOARD_ACCESS.get().await.lock().await; + info!("start wifi scan"); + let scan_result = board.board_hal.get_esp().wifi_scan().await; + let mut ssids: Vec = Vec::new(); + scan_result + .iter() + .for_each(|s| ssids.push(s.ssid.to_string())); + let ssid_json = serde_json::to_string(&SSIDList { ssids })?; + info!("Sending ssid list {}", &ssid_json); + anyhow::Ok(Some(ssid_json)) +} + async fn get_log( _request: &mut Connection<'_, T, N>, ) -> Result, anyhow::Error> {