use std::{sync::Arc, time::Duration}; use anyhow::{bail, Ok, Result}; use embedded_svc::{ipv4, wifi::*}; use esp_idf_svc::ping::EspPing; use esp_idf_svc::{ netif::EspNetifStack, nvs::EspDefaultNvs, sysloop::EspSysLoopStack, wifi::EspWifi, }; use log::info; use embedded_svc::ping::Ping; pub struct Internet { wifi: Box, auto_connect: bool, connected: bool, } impl Internet { pub fn new() -> Result { let netif_stack = Arc::new(EspNetifStack::new()?); let sys_loop_stack = Arc::new(EspSysLoopStack::new()?); let default_nvs = Arc::new(EspDefaultNvs::new()?); let wifi = Box::new(EspWifi::new(netif_stack, sys_loop_stack, default_nvs)?); let mut instance = Self { wifi, auto_connect: true, connected: false }; instance.connect_ap()?; Ok(instance) } fn connect_ap( &mut self, ) -> Result<()> { const SSID: &str = "Ivan"; const PASSWORD: &str = "ivanli.cc"; info!("Wifi created, about to scan"); let wifi = self.wifi.as_mut(); // let ap_infos = wifi.scan()?; // info!("Wifi AP Count {}", ap_infos.len()); // let ours = ap_infos.into_iter().find(|a| a.ssid == SSID); // let channel = if let Some(ours) = ours { // info!( // "Found configured access point {} on channel {}", // SSID, ours.channel // ); // Some(ours.channel) // } else { // info!( // "Configured access point {} not found during scanning, will go with unknown channel", // SSID // ); // None // }; wifi.set_configuration(&Configuration::Client( ClientConfiguration { ssid: SSID.into(), password: PASSWORD.into(), channel: None, ..Default::default() }, // AccessPointConfiguration { // ssid: "aptest".into(), // channel: channel.unwrap_or(1), // ..Default::default() // }, ))?; info!("Wifi configuration set, about to get status"); wifi.wait_status_with_timeout(Duration::from_secs(20), |status| !status.is_transitional()) .map_err(|e| anyhow::anyhow!("Unexpected Wifi status: {:?}", e))?; let status = wifi.get_status(); info!("we have the wifi status"); if let Status( ClientStatus::Started(ClientConnectionStatus::Connected(ClientIpStatus::Done( ip_settings, ))), ApStatus::Stopped ) = status { info!("Wifi connected"); Self::ping(&ip_settings)?; } else { bail!("Unexpected Wifi status: {:?}", status); } Ok(()) } pub fn ping(ip_settings: &ipv4::ClientSettings) -> Result<()> { info!("About to do some pings for {:?}", ip_settings); let ping_summary = EspPing::default().ping(ip_settings.subnet.gateway, &Default::default())?; if ping_summary.transmitted != ping_summary.received { bail!( "Pinging gateway {} resulted in timeouts", ip_settings.subnet.gateway ); } info!("Pinging done"); Ok(()) } }