118 lines
3.3 KiB
Rust
118 lines
3.3 KiB
Rust
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<EspWifi>,
|
|
auto_connect: bool,
|
|
connected: bool,
|
|
}
|
|
|
|
impl Internet {
|
|
pub fn new() -> Result<Self> {
|
|
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 Li";
|
|
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(())
|
|
}
|
|
} |