use core::ops::Not; use embassy_executor::Spawner; use embassy_net::{DhcpConfig, Runner, Stack, StackResources}; use embassy_time::{Duration, Timer}; use esp_hal::rng::Rng; use esp_radio::wifi::{ ClientConfig, ModeConfig, ScanConfig, WifiController, WifiDevice, WifiEvent, WifiStaState, }; use log::info; use static_cell::StaticCell; pub async fn init_wifi( wifi: esp_hal::peripherals::WIFI<'static>, spawner: &Spawner, ) -> Stack<'static> { static RADIO_INIT: StaticCell> = StaticCell::new(); let radio_init = RADIO_INIT.init(esp_radio::init().expect("Failed to initialize Wi-Fi/BLE controller")); let (wifi_controller, interfaces) = esp_radio::wifi::new(radio_init, wifi, Default::default()) .expect("Failed to initialize Wi-Fi controller"); let wifi_interface = interfaces.sta; let rng = Rng::new(); let net_seed = rng.random() as u64 | ((rng.random() as u64) << 32); let _tls_seed = rng.random() as u64 | ((rng.random() as u64) << 32); static STACK_RESOURCES: StaticCell> = StaticCell::new(); let stack_resources = STACK_RESOURCES.init(StackResources::new()); let (stack, runner) = embassy_net::new( wifi_interface, embassy_net::Config::dhcpv4(DhcpConfig::default()), stack_resources, net_seed, ); spawner.spawn(connection(wifi_controller)).ok(); spawner.spawn(net_task(runner)).ok(); stack } #[embassy_executor::task] async fn connection(mut controller: WifiController<'static>) { const SSID: &str = env!("SSID"); const PASSWORD: &str = env!("PASSWORD"); info!("start connection task"); info!("Device capabilities: {:?}", controller.capabilities()); loop { if esp_radio::wifi::sta_state() == WifiStaState::Connected { // wait until we're no longer connected controller.wait_for_event(WifiEvent::StaDisconnected).await; Timer::after(Duration::from_millis(5000)).await } if matches!(controller.is_started(), Ok(true)).not() { let client_config = ModeConfig::Client( ClientConfig::default() .with_ssid(SSID.into()) .with_password(PASSWORD.into()), ); controller.set_config(&client_config).unwrap(); info!("Starting wifi"); controller.start_async().await.unwrap(); info!("Wifi started!"); info!("Scan"); let scan_config = ScanConfig::default().with_max(10); let result = controller .scan_with_config_async(scan_config) .await .unwrap(); for ap in result { info!("{:?}", ap); } } info!("About to connect..."); match controller.connect_async().await { Ok(_) => info!("Wifi connected!"), Err(e) => { info!("Failed to connect to wifi: {:?}", e); Timer::after(Duration::from_millis(5000)).await } } } } #[embassy_executor::task] async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) { runner.run().await }