diff --git a/rust/src/hal/esp.rs b/rust/src/hal/esp.rs index 97219c3..177901e 100644 --- a/rust/src/hal/esp.rs +++ b/rust/src/hal/esp.rs @@ -347,104 +347,6 @@ impl Esp<'_> { } } - pub(crate) async fn wifi( - &mut self, - network_config: &NetworkConfig, - spawner: Spawner, - ) -> FatResult> { - esp_radio::wifi_set_log_verbose(); - let ssid = match &network_config.ssid { - Some(ssid) => { - if ssid.is_empty() { - bail!("Wifi ssid was empty") - } - ssid.to_string() - } - None => { - bail!("Wifi ssid was empty") - } - }; - info!("attempting to connect wifi {ssid}"); - let password = match network_config.password { - Some(ref password) => password.to_string(), - None => "".to_string(), - }; - let max_wait = network_config.max_wait; - - let device = self - .interface_sta - .take() - .context("STA interface already taken")?; - let config = embassy_net::Config::dhcpv4(DhcpConfig::default()); - - let seed = (self.rng.random() as u64) << 32 | self.rng.random() as u64; - - // Init network stack - let (stack, runner) = embassy_net::new( - device, - config, - mk_static!(StackResources<8>, StackResources::<8>::new()), - seed, - ); - let stack = mk_static!(Stack, stack); - - let auth_method = if password.is_empty() { - AuthenticationMethod::None - } else { - AuthenticationMethod::Wpa2Personal - }; - let client_config = StationConfig::default() - .with_ssid(ssid) - .with_auth_method(auth_method) - .with_scan_method(esp_radio::wifi::sta::ScanMethod::AllChannels) - .with_listen_interval(10) - .with_beacon_timeout(10) - .with_failure_retry_cnt(3) - .with_password(password); - - self.controller - .lock() - .await - .set_config(&Config::Station(client_config))?; - spawner.spawn(net_task(runner)?); - self.controller - .lock() - .await - .connect_async() - .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) - .await - .context("Timeout waiting for wifi sta connected")??; - - let res = async { - while !stack.is_link_up() { - Timer::after(Duration::from_millis(500)).await; - } - Ok::<(), FatError>(()) - } - .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) - .await; - - if res.is_err() { - bail!("Timeout waiting for wifi link up") - } - - let res = async { - while !stack.is_config_up() { - Timer::after(Duration::from_millis(100)).await - } - Ok::<(), FatError>(()) - } - .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) - .await; - - if res.is_err() { - bail!("Timeout waiting for wifi config up") - } - - info!("Connected WIFI, dhcp: {:?}", stack.config_v4()); - Ok(*stack) - } - pub fn deep_sleep_ms(&mut self, duration_in_ms: u64) -> ! { // Mark the current OTA image as valid if we reached here while in pending verify. if let Ok(cur) = self.ota.current_ota_state() { diff --git a/rust/src/main.rs b/rust/src/main.rs index 8a1d2e3..46196c2 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -754,7 +754,16 @@ async fn try_connect_wifi_sntp_mqtt( spawner: Spawner, ) -> network::NetworkMode { let nw_conf = &board.board_hal.get_config().network.clone(); - match board.board_hal.get_esp().wifi(nw_conf, spawner).await { + let esp = board.board_hal.get_esp(); + let device = match esp.interface_sta.take() { + Some(d) => d, + None => { + info!("Offline mode due to STA interface already taken"); + board.board_hal.general_fault(true).await; + return network::NetworkMode::OFFLINE; + } + }; + match network::wifi(nw_conf, device, &esp.controller, &mut esp.rng, spawner).await { Ok(stack) => { stack_store.replace(stack); diff --git a/rust/src/network.rs b/rust/src/network.rs index 4b1311a..848eae8 100644 --- a/rust/src/network.rs +++ b/rust/src/network.rs @@ -1,13 +1,14 @@ use crate::bail; +use crate::config::NetworkConfig; use crate::fat_error::{ContextExt, FatError, FatResult}; -use alloc::string::String; +use alloc::string::{String, ToString}; use alloc::sync::Arc; use chrono::{DateTime, Utc}; use core::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4}; use embassy_executor::Spawner; use embassy_net::dns::DnsQueryType; use embassy_net::udp::{PacketMetadata, UdpSocket}; -use embassy_net::{Runner, Stack, StackResources, StaticConfigV4}; +use embassy_net::{DhcpConfig, Runner, Stack, StackResources, StaticConfigV4}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::mutex::Mutex; use embassy_time::{Duration, Timer, WithTimeout}; @@ -20,7 +21,8 @@ use edge_nal_embassy::{Udp, UdpBuffers}; use esp_hal::rng::Rng; use esp_println::println; use esp_radio::wifi::ap::AccessPointConfig; -use esp_radio::wifi::{Config, Interface}; +use esp_radio::wifi::sta::StationConfig; +use esp_radio::wifi::{AuthenticationMethod, Config, Interface}; use log::{info, warn, error}; use serde::Serialize; use sntpc::{NtpContext, NtpTimestampGenerator, NtpUdpSocket, get_time}; @@ -251,3 +253,98 @@ pub async fn wifi_ap( Ok(*stack) } + +pub async fn wifi( + network_config: &NetworkConfig, + interface_sta: Interface<'static>, + controller: &Arc>>, + rng: &mut Rng, + spawner: Spawner, +) -> FatResult> { + esp_radio::wifi_set_log_verbose(); + let ssid = match &network_config.ssid { + Some(ssid) => { + if ssid.is_empty() { + bail!("Wifi ssid was empty") + } + ssid.as_str().to_string() + } + None => { + bail!("Wifi ssid was empty") + } + }; + info!("attempting to connect wifi {ssid}"); + let password = match network_config.password { + Some(ref password) => password.as_str().to_string(), + None => "".to_string(), + }; + let max_wait = network_config.max_wait; + + let config = embassy_net::Config::dhcpv4(DhcpConfig::default()); + + let seed = (rng.random() as u64) << 32 | rng.random() as u64; + + let (stack, runner) = embassy_net::new( + interface_sta, + config, + mk_static!(StackResources<8>, StackResources::<8>::new()), + seed, + ); + let stack = mk_static!(Stack, stack); + + let auth_method = if password.is_empty() { + AuthenticationMethod::None + } else { + AuthenticationMethod::Wpa2Personal + }; + let client_config = StationConfig::default() + .with_ssid(ssid) + .with_auth_method(auth_method) + .with_scan_method(esp_radio::wifi::sta::ScanMethod::AllChannels) + .with_listen_interval(10) + .with_beacon_timeout(10) + .with_failure_retry_cnt(3) + .with_password(password); + + controller + .lock() + .await + .set_config(&Config::Station(client_config))?; + spawner.spawn(net_task(runner)?); + controller + .lock() + .await + .connect_async() + .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) + .await + .context("Timeout waiting for wifi sta connected")??; + + let res = async { + while !stack.is_link_up() { + Timer::after(Duration::from_millis(500)).await; + } + Ok::<(), FatError>(()) + } + .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) + .await; + + if res.is_err() { + bail!("Timeout waiting for wifi link up") + } + + let res = async { + while !stack.is_config_up() { + Timer::after(Duration::from_millis(100)).await + } + Ok::<(), FatError>(()) + } + .with_timeout(Duration::from_millis(max_wait as u64 * 1000)) + .await; + + if res.is_err() { + bail!("Timeout waiting for wifi config up") + } + + info!("Connected WIFI, dhcp: {:?}", stack.config_v4()); + Ok(*stack) +}