use anyhow::{anyhow, Result};
use embedded_svc::wifi::{AuthMethod, ClientConfiguration, Configuration};
use esp_idf_svc::wifi::{BlockingWifi, EspWifi};
pub struct Config {
ssid: &'static str,
password: &'static str,
auth: AuthMethod,
}
impl Config {
fn new(ssid: &'static str, password: &'static str, auth: AuthMethod) -> Self {
Self {
ssid,
password,
auth,
}
}
#[must_use]
pub fn ssid(&self) -> &str {
self.ssid
}
#[must_use]
pub fn password(&self) -> &str {
self.password
}
#[must_use]
pub fn auth(&self) -> AuthMethod {
self.auth
}
pub fn from_env() -> Result<Self> {
let ssid = option_env!("WIFI_SSID")
.ok_or_else(|| anyhow!("WIFI_SSID environment variable not set"))?;
let password = option_env!("WIFI_PASSWORD")
.ok_or_else(|| anyhow!("WIFI_PASSWORD environment variable not set"))?;
Ok(Self::new(ssid, password, AuthMethod::WPA2Personal))
}
}
pub struct Connection<'a> {
handler: BlockingWifi<EspWifi<'a>>,
}
impl<'a> Connection<'a> {
pub fn new(handler: BlockingWifi<EspWifi<'a>>, config: &Config) -> Result<Self> {
let configuration: Configuration =
Configuration::Client(ClientConfiguration {
auth_method: config.auth(),
ssid: config
.ssid()
.try_into()
.map_err(|()| anyhow!("Failed to convert SSID"))?,
password: config
.password()
.try_into()
.map_err(|()| anyhow!("Failed to convert password"))?,
..Default::default()
});
let mut handler = handler;
handler.set_configuration(&configuration)?;
handler.start()?;
handler.connect()?;
handler.wait_netif_up()?;
Ok(Self { handler })
}
pub fn is_on(&self) -> Result<bool> {
Ok(self.handler.is_connected()?)
}
}