feat(wifi): implement a mutex for the wifi_controller and add it to the WifiService state
This commit is contained in:
+41
-33
@@ -1,27 +1,34 @@
|
||||
use defmt::{error, info};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::select::{Either, select};
|
||||
use embassy_net::{Runner, Stack};
|
||||
use embassy_sync::signal::Signal;
|
||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, rpc_service::RpcService};
|
||||
use embassy_sync::{
|
||||
blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, rpc_service::RpcService,
|
||||
};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_hal::peripherals::WIFI;
|
||||
use esp_radio::wifi::sta::StationConfig;
|
||||
use esp_radio::wifi::{ControllerConfig, Interface, WifiController};
|
||||
use esp_radio::wifi::{ControllerConfig, Interface, WifiController, WifiError};
|
||||
|
||||
pub static WIFI_SERVICE: RpcService<CriticalSectionRawMutex, WifiService, 64> = RpcService::new();
|
||||
|
||||
pub struct WifiService {
|
||||
pub net_stack: Stack<'static>
|
||||
pub net_stack: Stack<'static>,
|
||||
wifi_controller: &'static Mutex<CriticalSectionRawMutex, WifiController<'static>>,
|
||||
}
|
||||
|
||||
impl WifiService {
|
||||
pub async fn set_station_config(config: esp_radio::wifi::Config) {
|
||||
WIFI_HANDLER_RPC.signal(config);
|
||||
pub async fn set_station_config(
|
||||
&self,
|
||||
config: esp_radio::wifi::Config,
|
||||
) -> Result<(), WifiError> {
|
||||
let mut controller = self.wifi_controller.lock().await;
|
||||
controller.set_config(&config)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_dhcp_config(&self, config: embassy_net::DhcpConfig) {
|
||||
self.net_stack.set_config_v4(embassy_net::ConfigV4::Dhcp(config));
|
||||
pub fn set_dhcp_config(&self, config: embassy_net::DhcpConfig) {
|
||||
self.net_stack
|
||||
.set_config_v4(embassy_net::ConfigV4::Dhcp(config));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,53 +58,54 @@ pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
|
||||
seed,
|
||||
);
|
||||
|
||||
spawner.spawn(net_task(net_runner).unwrap());
|
||||
spawner.spawn(wifi_handler(wifi_controller).unwrap());
|
||||
let service = WifiService {
|
||||
net_stack: net_stack,
|
||||
wifi_controller: crate::mk_static!(Mutex<CriticalSectionRawMutex, WifiController<'static>>, Mutex::new(wifi_controller)),
|
||||
};
|
||||
|
||||
spawner.spawn(net_handler(net_runner).unwrap());
|
||||
spawner.spawn(connection_handler(service.wifi_controller).unwrap());
|
||||
spawner.spawn(handler(service).unwrap());
|
||||
spawner.spawn(ip_logger(net_stack).unwrap());
|
||||
spawner.spawn(handler(net_stack).unwrap());
|
||||
|
||||
net_stack
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn handler(net_stack: Stack<'static>) {
|
||||
WIFI_SERVICE.run(&mut WifiService {net_stack: net_stack}).await;
|
||||
async fn handler(mut service: WifiService) -> ! {
|
||||
WIFI_SERVICE.run(&mut service).await
|
||||
}
|
||||
|
||||
static WIFI_HANDLER_RPC: Signal<CriticalSectionRawMutex, esp_radio::wifi::Config> = Signal::new();
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn wifi_handler(mut controller: WifiController<'static>) {
|
||||
let connection = async |controller: &mut WifiController<'static>| {
|
||||
async fn connection_handler(
|
||||
controller: &'static Mutex<CriticalSectionRawMutex, WifiController<'static>>,
|
||||
) -> ! {
|
||||
loop {
|
||||
info!("Connecting to WiFi...");
|
||||
|
||||
match controller.connect_async().await {
|
||||
match controller.lock().await.connect_async().await {
|
||||
Ok(info) => {
|
||||
info!("Wifi connected to {:?}", info);
|
||||
|
||||
// wait until we're no longer connected
|
||||
let info = controller.wait_for_disconnect_async().await.ok();
|
||||
info!("Disconnected: {:?}", info);
|
||||
// TODO: reimplement the wait for disconnect
|
||||
// let info = controller
|
||||
// .lock()
|
||||
// .await
|
||||
// .wait_for_disconnect_async()
|
||||
// .await
|
||||
// .ok();
|
||||
// info!("Disconnected: {:?}", info);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to connect to wifi: {:?}", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loop {
|
||||
if let Either::First(req) =
|
||||
select(WIFI_HANDLER_RPC.wait(), connection(&mut controller)).await
|
||||
{
|
||||
if let Some(err) = controller.set_config(&req).err() {
|
||||
error!("Wifi controller failed to set a new config: {:?}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn ip_logger(net_stack: Stack<'static>) {
|
||||
async fn ip_logger(net_stack: Stack<'static>) -> ! {
|
||||
loop {
|
||||
info!("Getting IP address...");
|
||||
net_stack.wait_config_up().await;
|
||||
@@ -120,6 +128,6 @@ async fn ip_logger(net_stack: Stack<'static>) {
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn net_task(mut runner: Runner<'static, Interface<'static>>) {
|
||||
async fn net_handler(mut runner: Runner<'static, Interface<'static>>) -> ! {
|
||||
runner.run().await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user