📟 pmme-device: BT_NIMBLE support for wifi provisioning
This commit is contained in:
parent
9d5b9366d5
commit
4e07dbb461
@ -19,8 +19,7 @@ opt-level = "z"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
experimental = ["esp-idf-svc/experimental"]
|
||||||
# experimental = ["esp-idf-svc/experimental"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
@ -28,7 +27,6 @@ esp-idf-svc = { version = "0.51", features = ["critical-section", "embassy-time-
|
|||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
embedded-graphics = "0.8.1"
|
embedded-graphics = "0.8.1"
|
||||||
ssd1306 = "0.10.0"
|
ssd1306 = "0.10.0"
|
||||||
# esp-idf-hal = { version = "0.45.2", features = ["std"] }
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
embuild = "0.33"
|
embuild = "0.33"
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
# Rust often needs a bit of an extra main task stack size compared to C (the default is 3K)
|
# Rust often needs a bit of an extra main task stack size compared to C (the default is 3K)
|
||||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000
|
||||||
|
# CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
# CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="./partitions.csv"
|
||||||
|
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
CONFIG_WIFI_PROV_SCHEME_BLE=y
|
||||||
|
# CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
||||||
|
# CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
||||||
|
|
||||||
# Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default).
|
# Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default).
|
||||||
# This allows to use 1 ms granularity for thread sleeps (10 ms by default).
|
# This allows to use 1 ms granularity for thread sleeps (10 ms by default).
|
||||||
|
@ -1,13 +1,23 @@
|
|||||||
use crate::Pms7003Data;
|
use crate::Pms7003Data;
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use log::info;
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use log::info;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use embedded_graphics::{Drawable, image::{Image, ImageRaw}, mono_font::{ascii::FONT_10X20, MonoTextStyle}, pixelcolor::BinaryColor, prelude::Point, text::Text};
|
|
||||||
use embedded_graphics::draw_target::DrawTarget;
|
use embedded_graphics::draw_target::DrawTarget;
|
||||||
|
use embedded_graphics::{
|
||||||
|
image::{Image, ImageRaw},
|
||||||
|
mono_font::{ascii::FONT_10X20, MonoTextStyle},
|
||||||
|
pixelcolor::BinaryColor,
|
||||||
|
prelude::Point,
|
||||||
|
text::Text,
|
||||||
|
Drawable,
|
||||||
|
};
|
||||||
use esp_idf_svc::hal::{delay::FreeRtos, i2c::I2cDriver};
|
use esp_idf_svc::hal::{delay::FreeRtos, i2c::I2cDriver};
|
||||||
use ssd1306::{mode::DisplayConfig, prelude::DisplayRotation, size::DisplaySize128x64, I2CDisplayInterface, Ssd1306};
|
use ssd1306::{
|
||||||
|
mode::DisplayConfig, prelude::DisplayRotation, size::DisplaySize128x64, I2CDisplayInterface,
|
||||||
|
Ssd1306,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn oled_task(pm_data: Arc<Mutex<Pms7003Data>>, i2c: I2cDriver) -> Result<()> {
|
pub fn oled_task(pm_data: Arc<Mutex<Pms7003Data>>, i2c: I2cDriver) -> Result<()> {
|
||||||
info!("Staring OLED Task");
|
info!("Staring OLED Task");
|
||||||
@ -41,9 +51,7 @@ pub fn oled_task(pm_data: Arc<Mutex<Pms7003Data>>, i2c: I2cDriver) -> Result<()>
|
|||||||
.map_err(|e| anyhow!("Could not draw text! {:?}", e))?;
|
.map_err(|e| anyhow!("Could not draw text! {:?}", e))?;
|
||||||
display
|
display
|
||||||
.flush()
|
.flush()
|
||||||
.map_err(|e| {
|
.map_err(|e| anyhow!("Could not flush display! {:?}", e))?;
|
||||||
anyhow!("Could not flush display! {:?}", e)
|
|
||||||
})?;
|
|
||||||
FreeRtos::delay_ms(500);
|
FreeRtos::delay_ms(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
pub mod wifi;
|
|
||||||
pub mod sensors;
|
|
||||||
pub mod display;
|
pub mod display;
|
||||||
|
pub mod sensors;
|
||||||
|
pub mod wifi;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Pms7003Data {
|
pub struct Pms7003Data {
|
||||||
|
@ -1,15 +1,23 @@
|
|||||||
use std::{sync::{Arc, Mutex}, thread};
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use std::{
|
||||||
use esp_idf_svc::hal::{
|
sync::{Arc, Mutex},
|
||||||
gpio,
|
thread,
|
||||||
i2c::{I2cConfig, I2cDriver},
|
|
||||||
peripherals::Peripherals,
|
|
||||||
prelude::FromValueType,
|
|
||||||
uart::{config, UartDriver},
|
|
||||||
units::Hertz,
|
|
||||||
};
|
};
|
||||||
use pmme_device::{display::oled_task, sensors::pm_sensor_task, Pms7003Data};
|
|
||||||
|
use esp_idf_svc::{
|
||||||
|
eventloop::EspSystemEventLoop,
|
||||||
|
hal::{
|
||||||
|
gpio,
|
||||||
|
i2c::{I2cConfig, I2cDriver},
|
||||||
|
peripherals::Peripherals,
|
||||||
|
prelude::FromValueType,
|
||||||
|
uart::{self, UartDriver},
|
||||||
|
units::Hertz,
|
||||||
|
},
|
||||||
|
log::EspLogger,
|
||||||
|
nvs::EspDefaultNvsPartition,
|
||||||
|
};
|
||||||
|
use pmme_device::{display::oled_task, sensors::sensors_task, wifi::wifi_task, Pms7003Data};
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
// It is necessary to call this function once. Otherwise some patches to the runtime
|
// It is necessary to call this function once. Otherwise some patches to the runtime
|
||||||
@ -17,9 +25,8 @@ fn main() -> Result<()> {
|
|||||||
esp_idf_svc::sys::link_patches();
|
esp_idf_svc::sys::link_patches();
|
||||||
|
|
||||||
// Initialize NVS
|
// Initialize NVS
|
||||||
// esp_idf_hal::nvs::EspDefaultNvsPartition::take()
|
EspLogger::initialize_default();
|
||||||
// .context("Could not take NVS partition")?;
|
let nvs = EspDefaultNvsPartition::take()?;
|
||||||
esp_idf_svc::log::EspLogger::initialize_default();
|
|
||||||
|
|
||||||
let peripherals = Peripherals::take()?;
|
let peripherals = Peripherals::take()?;
|
||||||
let i2c = peripherals.i2c0;
|
let i2c = peripherals.i2c0;
|
||||||
@ -32,7 +39,7 @@ fn main() -> Result<()> {
|
|||||||
let tx = peripherals.pins.gpio17;
|
let tx = peripherals.pins.gpio17;
|
||||||
let rx = peripherals.pins.gpio16;
|
let rx = peripherals.pins.gpio16;
|
||||||
|
|
||||||
let config = config::Config::new().baudrate(Hertz(9600));
|
let config = uart::config::Config::new().baudrate(Hertz(9600));
|
||||||
let uart = UartDriver::new(
|
let uart = UartDriver::new(
|
||||||
peripherals.uart2,
|
peripherals.uart2,
|
||||||
tx,
|
tx,
|
||||||
@ -42,19 +49,28 @@ fn main() -> Result<()> {
|
|||||||
&config,
|
&config,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let pm_data = Arc::new(Mutex::new(Pms7003Data::default()));
|
let sysloop = EspSystemEventLoop::take()?;
|
||||||
|
let modem = peripherals.modem;
|
||||||
|
|
||||||
let pm_data1 = Arc::clone(&pm_data);
|
let pm_data = Arc::new(Mutex::new(Pms7003Data::default()));
|
||||||
let pm_data2 = Arc::clone(&pm_data);
|
let oled_arc = Arc::clone(&pm_data);
|
||||||
|
let sensors_arc = Arc::clone(&pm_data);
|
||||||
|
// let wifi_arc = Arc::clone(&pm_data);
|
||||||
|
|
||||||
let handles = vec![
|
let handles = vec![
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
if let Err(e) = oled_task(pm_data1, i2c) {
|
if let Err(e) = oled_task(oled_arc, i2c) {
|
||||||
log::error!("OLED Task Error: {:?}", e);
|
log::error!("OLED Task Error: {:?}", e);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
if let Err(e) = pm_sensor_task(pm_data2, &uart) {
|
if let Err(e) = sensors_task(sensors_arc, &uart) {
|
||||||
|
log::error!("PM Sensor Task Error: {:?}", e);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
thread::spawn(move || {
|
||||||
|
// if let Err(e) = wifi_task(wifi_arc, &uart) {
|
||||||
|
if let Err(e) = wifi_task(modem, sysloop, nvs) {
|
||||||
log::error!("PM Sensor Task Error: {:?}", e);
|
log::error!("PM Sensor Task Error: {:?}", e);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
use crate::Pms7003Data;
|
use crate::Pms7003Data;
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use log::{info, warn};
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use log::{info, warn};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use esp_idf_svc::hal::{delay::{FreeRtos, BLOCK}, uart::UartDriver};
|
use esp_idf_svc::hal::{
|
||||||
|
delay::{FreeRtos, BLOCK},
|
||||||
|
uart::UartDriver,
|
||||||
|
};
|
||||||
|
|
||||||
// u16::from_be_bytes is too verbose
|
// u16::from_be_bytes is too verbose
|
||||||
fn get_u16(buf: &[u8]) -> u16 {
|
fn get_u16(buf: &[u8]) -> u16 {
|
||||||
@ -45,7 +48,7 @@ fn send_pms7003_command(uart: &UartDriver, cmd: u8, datah: u8, datal: u8) -> Res
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pm_sensor_task(pm_data: Arc<Mutex<Pms7003Data>>, uart: &UartDriver) -> Result<()> {
|
pub fn sensors_task(pm_data: Arc<Mutex<Pms7003Data>>, uart: &UartDriver) -> Result<()> {
|
||||||
info!("Staring UART PM Sensor Task");
|
info!("Staring UART PM Sensor Task");
|
||||||
|
|
||||||
send_pms7003_command(uart, 0xE1, 0x00, 0x00)?;
|
send_pms7003_command(uart, 0xE1, 0x00, 0x00)?;
|
||||||
|
@ -1,79 +1,192 @@
|
|||||||
|
use anyhow::Result;
|
||||||
use log::info;
|
use log::info;
|
||||||
use anyhow::bail;
|
|
||||||
|
|
||||||
use esp_idf_svc::{
|
use esp_idf_svc::{
|
||||||
eventloop::EspSystemEventLoop,
|
eventloop::EspSystemEventLoop,
|
||||||
hal::peripheral,
|
hal::peripheral,
|
||||||
wifi::{AuthMethod, BlockingWifi, ClientConfiguration, Configuration, EspWifi},
|
nvs::EspDefaultNvsPartition,
|
||||||
|
sys::{
|
||||||
|
esp, esp_err_t, wifi_prov_event_handler_t, wifi_prov_mgr_config_t, wifi_prov_mgr_deinit, wifi_prov_mgr_init, wifi_prov_mgr_is_provisioned, wifi_prov_mgr_start_provisioning, wifi_prov_mgr_stop_provisioning, wifi_prov_mgr_wait, wifi_prov_scheme_ble, wifi_prov_security_WIFI_PROV_SECURITY_1, wifi_prov_security_t, EspError
|
||||||
|
},
|
||||||
|
wifi::{BlockingWifi, ClientConfiguration, Configuration, EspWifi},
|
||||||
};
|
};
|
||||||
|
use std::ffi::c_void;
|
||||||
|
use std::ffi::CString;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
pub fn wifi(
|
pub struct WifiProvisioning;
|
||||||
ssid: &str,
|
|
||||||
pass: &str,
|
impl WifiProvisioning {
|
||||||
|
pub fn new() -> Result<Self, EspError> {
|
||||||
|
unsafe {
|
||||||
|
// Updated struct initialization
|
||||||
|
let config = wifi_prov_mgr_config_t {
|
||||||
|
scheme: wifi_prov_scheme_ble, // ble provisioning
|
||||||
|
scheme_event_handler: wifi_prov_event_handler_t {
|
||||||
|
event_cb: None, // No custom callback
|
||||||
|
user_data: ptr::null_mut(),
|
||||||
|
},
|
||||||
|
app_event_handler: wifi_prov_event_handler_t {
|
||||||
|
event_cb: None, // No custom callback
|
||||||
|
user_data: ptr::null_mut(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
esp!(wifi_prov_mgr_init(config))?;
|
||||||
|
}
|
||||||
|
Ok(WifiProvisioning)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_provisioning(
|
||||||
|
&self,
|
||||||
|
security: wifi_prov_security_t,
|
||||||
|
pop: &str,
|
||||||
|
service_name: &str,
|
||||||
|
service_key: Option<&str>,
|
||||||
|
) -> Result<(), EspError> {
|
||||||
|
let pop = CString::new(pop).unwrap();
|
||||||
|
let service_name = CString::new(service_name).unwrap();
|
||||||
|
let service_key = service_key.map(|key| CString::new(key).unwrap());
|
||||||
|
let pop_ptr: *const c_void = pop.as_ptr() as *const c_void;
|
||||||
|
unsafe {
|
||||||
|
esp!(wifi_prov_mgr_start_provisioning(
|
||||||
|
security,
|
||||||
|
pop_ptr,
|
||||||
|
service_name.as_ptr(),
|
||||||
|
service_key.map_or(ptr::null(), |k| k.as_ptr()),
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wait(&self) {
|
||||||
|
unsafe {
|
||||||
|
wifi_prov_mgr_wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_provisioned(&self) -> Result<bool, EspError> {
|
||||||
|
let mut provisioned: bool = false;
|
||||||
|
let result: esp_err_t = unsafe { wifi_prov_mgr_is_provisioned(&mut provisioned) };
|
||||||
|
if result == 0 {
|
||||||
|
Ok(provisioned)
|
||||||
|
} else {
|
||||||
|
Err(EspError::from(result).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop(&self) {
|
||||||
|
unsafe {
|
||||||
|
wifi_prov_mgr_stop_provisioning();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for WifiProvisioning {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
wifi_prov_mgr_deinit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wifi_task(
|
||||||
modem: impl peripheral::Peripheral<P = esp_idf_svc::hal::modem::Modem> + 'static,
|
modem: impl peripheral::Peripheral<P = esp_idf_svc::hal::modem::Modem> + 'static,
|
||||||
sysloop: EspSystemEventLoop,
|
sysloop: EspSystemEventLoop,
|
||||||
) -> anyhow::Result<Box<EspWifi<'static>>> {
|
nvs: EspDefaultNvsPartition,
|
||||||
let mut auth_method = AuthMethod::WPA2Personal;
|
) -> Result<()> {
|
||||||
if ssid.is_empty() {
|
info!("Provisioning device!");
|
||||||
bail!("Missing WiFi name")
|
return Ok(());
|
||||||
}
|
let wifi = EspWifi::new(modem, sysloop.clone(), Some(nvs))?;
|
||||||
if pass.is_empty() {
|
let mut wifi = BlockingWifi::wrap(wifi, sysloop)?;
|
||||||
auth_method = AuthMethod::None;
|
let prov = WifiProvisioning::new()?;
|
||||||
info!("Wifi password is empty");
|
if !prov.is_provisioned()? {
|
||||||
}
|
let wifi_configuration: Configuration = Configuration::Client(ClientConfiguration {
|
||||||
let mut esp_wifi = EspWifi::new(modem, sysloop.clone(), None)?;
|
..Default::default()
|
||||||
|
});
|
||||||
|
wifi.set_configuration(&wifi_configuration)?;
|
||||||
|
wifi.start()?;
|
||||||
|
prov.start_provisioning(
|
||||||
|
wifi_prov_security_WIFI_PROV_SECURITY_1,
|
||||||
|
"abcd1234", // Proof of Possession (POP)
|
||||||
|
"PROV_ESP32", // Service Name
|
||||||
|
None, // No Service Key
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut wifi = BlockingWifi::wrap(&mut esp_wifi, sysloop)?;
|
println!("Waiting for Wi-Fi provisioning...");
|
||||||
|
prov.wait();
|
||||||
|
|
||||||
wifi.set_configuration(&Configuration::Client(ClientConfiguration::default()))?;
|
println!("Provisioning completed. Stopping...");
|
||||||
|
prov.stop();
|
||||||
info!("Starting wifi...");
|
|
||||||
|
|
||||||
wifi.start()?;
|
|
||||||
|
|
||||||
info!("Scanning...");
|
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
info!(
|
wifi.start()?;
|
||||||
"Configured access point {} not found during scanning, will go with unknown channel",
|
wifi.connect()?;
|
||||||
ssid
|
}
|
||||||
);
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
wifi.set_configuration(&Configuration::Client(ClientConfiguration {
|
|
||||||
ssid: ssid
|
|
||||||
.try_into()
|
|
||||||
.expect("Could not parse the given SSID into WiFi config"),
|
|
||||||
password: pass
|
|
||||||
.try_into()
|
|
||||||
.expect("Could not parse the given password into WiFi config"),
|
|
||||||
channel,
|
|
||||||
auth_method,
|
|
||||||
..Default::default()
|
|
||||||
}))?;
|
|
||||||
|
|
||||||
info!("Connecting wifi...");
|
|
||||||
|
|
||||||
wifi.connect()?;
|
|
||||||
|
|
||||||
info!("Waiting for DHCP lease...");
|
|
||||||
|
|
||||||
wifi.wait_netif_up()?;
|
wifi.wait_netif_up()?;
|
||||||
|
|
||||||
let ip_info = wifi.wifi().sta_netif().get_ip_info()?;
|
let ip_info = wifi.wifi().sta_netif().get_ip_info()?;
|
||||||
|
println!("Wifi DHCP info: {:?}", ip_info);
|
||||||
|
|
||||||
info!("Wifi DHCP info: {:?}", ip_info);
|
// let mut auth_method = AuthMethod::WPA2Personal;
|
||||||
|
// if ssid.is_empty() {
|
||||||
|
// bail!("Missing WiFi name")
|
||||||
|
// }
|
||||||
|
// if pass.is_empty() {
|
||||||
|
// auth_method = AuthMethod::None;
|
||||||
|
// info!("Wifi password is empty");
|
||||||
|
// }
|
||||||
|
// let mut esp_wifi = EspWifi::new(modem, sysloop.clone(), None)?;
|
||||||
|
|
||||||
Ok(Box::new(esp_wifi))
|
// let mut wifi = BlockingWifi::wrap(&mut esp_wifi, sysloop)?;
|
||||||
|
|
||||||
|
// wifi.set_configuration(&Configuration::Client(ClientConfiguration::default()))?;
|
||||||
|
|
||||||
|
// info!("Starting wifi...");
|
||||||
|
|
||||||
|
// wifi.start()?;
|
||||||
|
|
||||||
|
// info!("Scanning...");
|
||||||
|
|
||||||
|
// 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::Client(ClientConfiguration {
|
||||||
|
// ssid: ssid
|
||||||
|
// .try_into()
|
||||||
|
// .expect("Could not parse the given SSID into WiFi config"),
|
||||||
|
// password: pass
|
||||||
|
// .try_into()
|
||||||
|
// .expect("Could not parse the given password into WiFi config"),
|
||||||
|
// channel,
|
||||||
|
// auth_method,
|
||||||
|
// ..Default::default()
|
||||||
|
// }))?;
|
||||||
|
|
||||||
|
// info!("Connecting wifi...");
|
||||||
|
|
||||||
|
// wifi.connect()?;
|
||||||
|
|
||||||
|
// info!("Waiting for DHCP lease...");
|
||||||
|
|
||||||
|
// wifi.wait_netif_up()?;
|
||||||
|
|
||||||
|
// let ip_info = wifi.wifi().sta_netif().get_ip_info()?;
|
||||||
|
|
||||||
|
// info!("Wifi DHCP info: {:?}", ip_info);
|
||||||
|
|
||||||
|
// Ok(Box::new(esp_wifi))
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user