rework wifi controller share
This commit is contained in:
		@@ -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<Interfaces<'static>>,
 | 
			
		||||
    pub controller: Option<WifiController<'static>>,
 | 
			
		||||
    pub controller: Arc<Mutex<CriticalSectionRawMutex, WifiController<'static>>>,
 | 
			
		||||
 | 
			
		||||
    //only filled, if a useable mqtt client with working roundtrip could be established
 | 
			
		||||
    pub(crate) mqtt_client: Option<MqttClient<'a>>,
 | 
			
		||||
@@ -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<Vec<AccessPointInfo>> {
 | 
			
		||||
        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<AccessPointInfo> {
 | 
			
		||||
        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<DateTime<Utc>> {
 | 
			
		||||
@@ -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<Mutex<CriticalSectionRawMutex, WifiController<'static>>>,
 | 
			
		||||
    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]
 | 
			
		||||
 
 | 
			
		||||
@@ -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<FlashStorage>,
 | 
			
		||||
            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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[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<Option<std::string::String>, 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<T, const N: usize>(
 | 
			
		||||
    _request: &mut Connection<'_, T, N>,
 | 
			
		||||
) -> Result<Option<String>, 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<String> = 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<T, const N: usize>(
 | 
			
		||||
    _request: &mut Connection<'_, T, N>,
 | 
			
		||||
) -> Result<Option<String>, anyhow::Error> {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user