feat: use the embedded-rpc library for the wifi service
This commit is contained in:
+72
-62
@@ -1,11 +1,10 @@
|
||||
use defmt::{error, info};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::select::Either::First;
|
||||
use embassy_futures::select::select;
|
||||
use embassy_futures::select::{Either, select};
|
||||
use embassy_net::{Runner, Stack};
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::{channel::Channel};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embedded_rpc::{RequestDroppedError, RpcService};
|
||||
use esp_hal::peripherals::WIFI;
|
||||
use esp_radio::wifi::sta::StationConfig;
|
||||
use esp_radio::wifi::{ControllerConfig, Interface, WifiController};
|
||||
@@ -16,14 +15,16 @@ pub enum WifiCommand {
|
||||
}
|
||||
|
||||
impl WifiCommand {
|
||||
pub async fn set_station_config(config: esp_radio::wifi::Config) {
|
||||
WIFI_CH
|
||||
.send(WifiCommand::SetStationConfig(config))
|
||||
.await;
|
||||
pub async fn set_station_config(
|
||||
config: esp_radio::wifi::Config,
|
||||
) -> Result<(), RequestDroppedError> {
|
||||
WIFI_SERVICE
|
||||
.request(WifiCommand::SetStationConfig(config))
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
pub static WIFI_CH: Channel<CriticalSectionRawMutex, WifiCommand, 4> = Channel::new();
|
||||
pub static WIFI_SERVICE: RpcService<CriticalSectionRawMutex, WifiCommand, ()> = RpcService::new();
|
||||
|
||||
pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
|
||||
let wifi_config = esp_radio::wifi::Config::Station(StationConfig::default());
|
||||
@@ -52,78 +53,87 @@ pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> {
|
||||
);
|
||||
|
||||
spawner.spawn(net_task(net_runner).unwrap());
|
||||
spawner.spawn(handler(wifi_controller, net_stack).unwrap());
|
||||
spawner.spawn(wifi_handler(wifi_controller).unwrap());
|
||||
spawner.spawn(ip_logger(net_stack).unwrap());
|
||||
spawner.spawn(handler(net_stack).unwrap());
|
||||
|
||||
net_stack
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn handler(mut controller: WifiController<'static>, net_stack: Stack<'static>) {
|
||||
let receiver = WIFI_CH.receiver();
|
||||
async fn handler(net_stack: Stack<'static>) {
|
||||
loop {
|
||||
match select(receiver.receive(), connection(&mut controller, net_stack)).await {
|
||||
First(WifiCommand::SetStationConfig(config)) => {
|
||||
if controller.set_config(&config).is_err() {
|
||||
error!("Set WiFi config failed: {:?}", config);
|
||||
};
|
||||
let (req, served) = WIFI_SERVICE.serve().await;
|
||||
|
||||
match req {
|
||||
WifiCommand::SetStationConfig(config) => {
|
||||
if WIFI_HANDLER_RPC.request(config).await.is_err() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
First(WifiCommand::SetDhcpConfig(dhcp_config)) => {
|
||||
WifiCommand::SetDhcpConfig(dhcp_config) => {
|
||||
net_stack.set_config_v4(embassy_net::ConfigV4::Dhcp(dhcp_config));
|
||||
}
|
||||
embassy_futures::select::Either::Second(_) => {
|
||||
unreachable!("connection function should be infinite loop")
|
||||
}
|
||||
|
||||
served.respond(());
|
||||
}
|
||||
}
|
||||
|
||||
static WIFI_HANDLER_RPC: RpcService<CriticalSectionRawMutex, esp_radio::wifi::Config, ()> =
|
||||
RpcService::new();
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn wifi_handler(mut controller: WifiController<'static>) {
|
||||
let connection = async |controller: &mut WifiController<'static>| {
|
||||
info!("Connecting to WiFi...");
|
||||
|
||||
match controller.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);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to connect to wifi: {:?}", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loop {
|
||||
if let Either::First((req, served)) =
|
||||
select(WIFI_HANDLER_RPC.serve(), connection(&mut controller)).await
|
||||
{
|
||||
if controller.set_config(&req).is_ok() {
|
||||
served.respond(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn connection(controller: &mut WifiController<'static>, net_stack: Stack<'static>) {
|
||||
info!("start connection task");
|
||||
#[embassy_executor::task]
|
||||
async fn ip_logger(net_stack: Stack<'static>) {
|
||||
loop {
|
||||
info!("Getting IP address...");
|
||||
net_stack.wait_config_up().await;
|
||||
|
||||
select(
|
||||
async {
|
||||
loop {
|
||||
info!("Connecting to WiFi...");
|
||||
match net_stack.config_v4() {
|
||||
Some(info) => {
|
||||
info!("Got IP: {:?}", info);
|
||||
|
||||
match controller.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);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to connect to wifi: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
Timer::after(Duration::from_millis(5000)).await
|
||||
// wait until we're no longer connected
|
||||
net_stack.wait_config_down().await;
|
||||
info!("Address no longer configured");
|
||||
}
|
||||
},
|
||||
async {
|
||||
loop {
|
||||
info!("Getting IP address...");
|
||||
net_stack.wait_config_up().await;
|
||||
|
||||
match net_stack.config_v4() {
|
||||
Some(info) => {
|
||||
info!("Got IP: {:?}", info);
|
||||
|
||||
// wait until we're no longer connected
|
||||
net_stack.wait_config_down().await;
|
||||
info!("Address no longer configured");
|
||||
}
|
||||
None => {
|
||||
error!("Failed to configure an address");
|
||||
}
|
||||
}
|
||||
|
||||
Timer::after(Duration::from_millis(5000)).await
|
||||
None => {
|
||||
error!("Failed to configure an address");
|
||||
}
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
Timer::after(Duration::from_millis(5000)).await
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
|
||||
Reference in New Issue
Block a user