feat: support connect wifi. Closed #2.
This commit is contained in:
parent
5234fe20b5
commit
7ef35692c9
@ -32,3 +32,4 @@ build-std = ["std", "panic_abort"]
|
|||||||
#ESP_IDF_VERSION = { value = "branch:release/v4.4" }
|
#ESP_IDF_VERSION = { value = "branch:release/v4.4" }
|
||||||
# Enables the esp-idf-sys "native" build feature (`cargo build --features native`) to build against ESP-IDF master (mainline)
|
# Enables the esp-idf-sys "native" build feature (`cargo build --features native`) to build against ESP-IDF master (mainline)
|
||||||
ESP_IDF_VERSION = { value = "master" }
|
ESP_IDF_VERSION = { value = "master" }
|
||||||
|
|
||||||
|
@ -20,8 +20,10 @@ anyhow = {version = "1.0.57", features = ["backtrace"]}
|
|||||||
embedded-graphics = "0.7.1"
|
embedded-graphics = "0.7.1"
|
||||||
embedded-hal = "1.0.0-alpha.8"
|
embedded-hal = "1.0.0-alpha.8"
|
||||||
embedded-hal-0-2 = {package = "embedded-hal", version = "0.2.7", features = ["unproven"]}
|
embedded-hal-0-2 = {package = "embedded-hal", version = "0.2.7", features = ["unproven"]}
|
||||||
|
embedded-svc = "0.21.3"
|
||||||
env_logger = "0.9.0"
|
env_logger = "0.9.0"
|
||||||
esp-idf-hal = { git = "https://github.com/esp-rs/esp-idf-hal", branch="master" }
|
esp-idf-hal = { git = "https://github.com/esp-rs/esp-idf-hal", branch="master" }
|
||||||
|
esp-idf-svc = { git = "https://github.com/IvanLi-CN/esp-idf-svc", branch="master" }
|
||||||
esp-idf-sys = {version = "0.31.5", features = ["binstart"]}
|
esp-idf-sys = {version = "0.31.5", features = ["binstart"]}
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
retry = "1.3.1"
|
retry = "1.3.1"
|
||||||
|
@ -3,11 +3,14 @@ use esp_idf_sys as _;
|
|||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use std::{thread, time::Duration, sync::mpsc, env};
|
use std::{thread, time::Duration, sync::mpsc, env};
|
||||||
|
|
||||||
|
use crate::wifi::WiFi;
|
||||||
|
|
||||||
mod beep;
|
mod beep;
|
||||||
mod blink;
|
mod blink;
|
||||||
mod dc_out_controller;
|
mod dc_out_controller;
|
||||||
mod manager;
|
mod manager;
|
||||||
mod screen;
|
mod screen;
|
||||||
|
mod wifi;
|
||||||
fn main() {
|
fn main() {
|
||||||
env::set_var("DEFMT_LOG", "trace");
|
env::set_var("DEFMT_LOG", "trace");
|
||||||
env::set_var("RUST_LOG", "trace");
|
env::set_var("RUST_LOG", "trace");
|
||||||
@ -71,6 +74,9 @@ fn main() {
|
|||||||
battery_pin.into_analog_atten_11db().expect("Failed to set GPIO2 as analog input"),
|
battery_pin.into_analog_atten_11db().expect("Failed to set GPIO2 as analog input"),
|
||||||
tx,
|
tx,
|
||||||
).expect("Failed to create manager");
|
).expect("Failed to create manager");
|
||||||
|
|
||||||
|
let wifi = WiFi::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match manager.handling_once() {
|
match manager.handling_once() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
|
117
src/wifi.rs
Normal file
117
src/wifi.rs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
|
use anyhow::{
|
||||||
|
bail,
|
||||||
|
Result, Ok,
|
||||||
|
};
|
||||||
|
use esp_idf_svc::ping::EspPing;
|
||||||
|
use esp_idf_svc::{
|
||||||
|
netif::EspNetifStack, nvs::EspDefaultNvs, sysloop::EspSysLoopStack, wifi::EspWifi
|
||||||
|
};
|
||||||
|
use embedded_svc::{wifi::*, ipv4};
|
||||||
|
use embedded_svc::ping::Ping;
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
pub struct WiFi {
|
||||||
|
wifi: Box<EspWifi>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WiFi {
|
||||||
|
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 mut wifi = Self::wifi(
|
||||||
|
netif_stack.clone(),
|
||||||
|
sys_loop_stack.clone(),
|
||||||
|
default_nvs.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Self { wifi })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wifi(
|
||||||
|
netif_stack: Arc<EspNetifStack>,
|
||||||
|
sys_loop_stack: Arc<EspSysLoopStack>,
|
||||||
|
default_nvs: Arc<EspDefaultNvs>,
|
||||||
|
) -> Result<Box<EspWifi>> {
|
||||||
|
const SSID: &str = "Ivan Li";
|
||||||
|
const PASSWORD: &str = "ivanli.cc";
|
||||||
|
let mut wifi = Box::new(EspWifi::new(netif_stack, sys_loop_stack, default_nvs)?);
|
||||||
|
|
||||||
|
info!("Wifi created, about to scan");
|
||||||
|
|
||||||
|
let ap_infos = wifi.scan()?;
|
||||||
|
|
||||||
|
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::Mixed(
|
||||||
|
ClientConfiguration {
|
||||||
|
ssid: SSID.into(),
|
||||||
|
password: PASSWORD.into(),
|
||||||
|
channel,
|
||||||
|
..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();
|
||||||
|
|
||||||
|
if let Status(
|
||||||
|
ClientStatus::Started(ClientConnectionStatus::Connected(ClientIpStatus::Done(
|
||||||
|
ip_settings,
|
||||||
|
))),
|
||||||
|
ApStatus::Started(ApIpStatus::Done),
|
||||||
|
) = status
|
||||||
|
{
|
||||||
|
info!("Wifi connected");
|
||||||
|
|
||||||
|
Self::ping(&ip_settings)?;
|
||||||
|
} else {
|
||||||
|
bail!("Unexpected Wifi status: {:?}", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(wifi)
|
||||||
|
}
|
||||||
|
|
||||||
|
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(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user