diff --git a/Cargo.lock b/Cargo.lock index 31711e0..5a3d6a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ checksum = "c0cb6f3d4773a2107b94cbeccaa5b5f0b35a88389b5d522d13d659f64317b22d" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -69,9 +69,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.1" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" [[package]] name = "block-buffer" @@ -90,7 +90,7 @@ checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" dependencies = [ "btuuid", "defmt 1.1.1", - "embassy-sync 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "embassy-sync 0.8.0", "embedded-io 0.7.1", "embedded-io-async 0.7.0", "futures-intrusive", @@ -126,9 +126,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.4.4" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" +checksum = "f74872d07caf508b30a21f6836e7d7016a2eaf7d9ff4f48deaa58cd8a0407630" dependencies = [ "find-msvc-tools", "shlex", @@ -148,9 +148,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] name = "cipher" @@ -202,7 +202,7 @@ dependencies = [ "embassy-executor", "embassy-futures", "embassy-net", - "embassy-sync 0.8.0 (git+https://github.com/embassy-rs/embassy?branch=main)", + "embassy-sync 0.8.0", "embassy-time", "esp-alloc", "esp-backtrace", @@ -214,6 +214,7 @@ dependencies = [ "esp-storage", "heapless 0.9.3", "int-enum", + "oneshot", "picoserve", "portable-atomic", "postcard", @@ -318,7 +319,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -351,7 +352,7 @@ checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" dependencies = [ "darling_core 0.24.1", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -453,7 +454,7 @@ dependencies = [ "defmt 1.1.1", "embassy-futures", "embassy-hal-internal", - "embassy-sync 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "embassy-sync 0.8.0", "embassy-time", "embedded-hal 0.2.7", "embedded-hal 1.0.0", @@ -522,7 +523,7 @@ dependencies = [ "defmt 1.1.1", "document-features", "embassy-net-driver", - "embassy-sync 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "embassy-sync 0.8.0", "embassy-time", "embedded-io-async 0.7.0", "embedded-nal-async", @@ -583,19 +584,6 @@ dependencies = [ "heapless 0.9.3", ] -[[package]] -name = "embassy-sync" -version = "0.8.0" -source = "git+https://github.com/embassy-rs/embassy?branch=main#0b51d4cea5c02b8aa5dc0fad74be46f36b83373d" -dependencies = [ - "cfg-if", - "critical-section", - "embedded-io-async 0.7.0", - "futures-core", - "futures-sink", - "heapless 0.9.3", -] - [[package]] name = "embassy-time" version = "0.5.1" @@ -725,15 +713,15 @@ dependencies = [ [[package]] name = "embedded-storage" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" +checksum = "c815b3ed4213d85d6cfd274b871f430c0681084e28dfd4a537877f47f844ec83" [[package]] name = "embedded-storage-async" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +checksum = "69aa7787b8ba0cf4e626c95839f811d853b75e24a0f7312a1eef324fedc13b21" dependencies = [ "embedded-storage", ] @@ -838,7 +826,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e2874462a2a0faca8b6318a10b0db87d2b7cd74dded82b3dfd780c07a319038" dependencies = [ "bitfield", - "bitflags 2.13.1", + "bitflags 2.13.2", "bytemuck", "cfg-if", "critical-section", @@ -848,7 +836,7 @@ dependencies = [ "document-features", "embassy-embedded-hal", "embassy-futures", - "embassy-sync 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "embassy-sync 0.8.0", "embedded-can", "embedded-hal 1.0.0", "embedded-hal-async", @@ -910,9 +898,9 @@ checksum = "42c2ee95b945a4780796e4359e72c033aed3b45073880e8029458f538532db8a" [[package]] name = "esp-metadata-generated" -version = "0.5.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7237b66a6b13163199b9e094ea96958565a5b04d35f518ee5834dc61c044011d" +checksum = "911aadae41ec99104efa865bd0b6e486b4b735999f9b571963748a46d16495ab" [[package]] name = "esp-phy" @@ -923,7 +911,7 @@ dependencies = [ "cfg-if", "defmt 1.1.1", "document-features", - "embassy-sync 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "embassy-sync 0.8.0", "esp-config", "esp-hal", "esp-metadata-generated 0.4.0", @@ -959,7 +947,7 @@ dependencies = [ "docsplay", "document-features", "embassy-net-driver", - "embassy-sync 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "embassy-sync 0.8.0", "embedded-io 0.6.1", "embedded-io 0.7.1", "embedded-io-async 0.6.1", @@ -1020,7 +1008,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e933ff78374b763b65998b64ad671b4890ed4ba13a80deff9f53afe95ede289d" dependencies = [ "document-features", - "esp-metadata-generated 0.5.0", + "esp-metadata-generated 0.5.3", "esp32c6 0.24.0", ] @@ -1035,7 +1023,7 @@ dependencies = [ "defmt 1.1.1", "document-features", "embassy-executor", - "embassy-sync 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "embassy-sync 0.8.0", "embassy-time-driver", "embassy-time-queue-utils", "esp-alloc", @@ -1078,7 +1066,7 @@ dependencies = [ "document-features", "embassy-sync 0.6.2", "embassy-sync 0.7.2", - "embassy-sync 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "embassy-sync 0.8.0", "esp-metadata-generated 0.4.0", "riscv", "xtensa-lx", @@ -1248,9 +1236,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" +checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" [[package]] name = "fnv" @@ -1315,9 +1303,9 @@ checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" [[package]] name = "generator" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" +checksum = "54ade96dc9003043bce7c035c85a9df5a858bfb2039c5a2e6fdf00f324f6c551" dependencies = [ "cc", "cfg-if", @@ -1439,9 +1427,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown", @@ -1458,15 +1446,15 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf84e73fa6f27f299dec58e13223cf70db80da872eb921d4f6138342a0eabc8" +checksum = "4c3b5acc1e2fd9375041a388da33d1eb8aed5f7a8c0dd3543e3ea2805adfbe20" dependencies = [ "darling 0.24.1", "indoc", "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -1489,9 +1477,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.35" +version = "0.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" +checksum = "b2b005715dcbeb0089a3c0dab99f2ff1cc3b2525323552703d648585d342a383" dependencies = [ "defmt 1.1.1", "jiff-core", @@ -1504,18 +1492,19 @@ dependencies = [ [[package]] name = "jiff-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" dependencies = [ "defmt 1.1.1", + "log", ] [[package]] name = "jiff-static" -version = "0.2.35" +version = "0.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" +checksum = "2cc9817253cf7c7ee4684451bd327e88d6f3658014e54a29198625590650695c" dependencies = [ "jiff-core", "proc-macro2", @@ -1525,15 +1514,15 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" [[package]] name = "libc" -version = "0.2.189" +version = "0.2.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" [[package]] name = "linked_list_allocator" @@ -1655,6 +1644,12 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "oneshot" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe21416a02c693fb9f980befcb230ecc70b0b3d1cc4abf88b9675c4c1457f0c" + [[package]] name = "paste" version = "1.0.15" @@ -1726,9 +1721,9 @@ checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -1953,9 +1948,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "sequential-storage" -version = "8.0.1" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e750f14f4f6e5a81277c66311713a56106c8df0196df62a634d1fc806556832b" +checksum = "1550e4d0c7a6a54e2d7884309dc6bfe206d2d8884cb5498177fd936cb233616d" dependencies = [ "embedded-storage-async", ] @@ -1999,7 +1994,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -2032,9 +2027,9 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" [[package]] name = "smoltcp" @@ -2175,9 +2170,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -2195,22 +2190,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.20" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.20" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" dependencies = [ "proc-macro2", "quote", - "syn 3.0.4", + "syn 3.0.6", ] [[package]] @@ -2233,9 +2228,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.13+spec-1.1.0" +version = "0.25.15+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" +checksum = "1340ea94a5856333492c9064b02c778b191dd2c853778d9609debdcdfea3a614" dependencies = [ "indexmap", "toml_datetime", @@ -2327,9 +2322,9 @@ checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "unsafe-libyaml" diff --git a/Cargo.toml b/Cargo.toml index b23ce9c..d164b05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ esp-backtrace = { version = "0.19.0", features = [ ] } esp-println = { version = "0.17.0", features = ["defmt-espflash", "esp32c6"] } -embassy-sync = { git = "https://github.com/embassy-rs/embassy", branch = "main" } +embassy-sync = { version = "0.8.0", features = ["defmt"] } embassy-futures = { version = "0.1.2", features = ["defmt"] } embassy-embedded-hal = { version = "0.6.0", features = ["defmt", "time"] } @@ -63,11 +63,15 @@ picoserve = { version = "0.19", features = ["defmt", "embassy", "json"] } sequential-storage = "8.0" esp-storage = { version = "0.9", features = ["defmt", "esp32c6"] } -postcard = { version = "1.1", default-features = false, features = ["defmt", "heapless"] } +postcard = { version = "1.1", default-features = false, features = [ + "defmt", + "heapless", +] } serde = { version = "1.0", default-features = false, features = ["derive"] } int-enum = "1.2.0" heapless = { version = "0.9.3", features = ["defmt", "serde"] } thiserror = { version = "2.0.20", default-features = false } +oneshot = { version = "0.2.1", features = ["async"] } # For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html diff --git a/src/config.rs b/src/config.rs index 652255b..2308c8a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,11 +1,13 @@ +use defmt::error; use embassy_embedded_hal::adapter::BlockingAsync; use embassy_executor::Spawner; -use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, rpc_service::RpcService}; +use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel}; use esp_hal::peripherals::FLASH; use esp_radio::wifi::sta::StationConfig; use esp_storage::FlashStorage; use heapless::String; use int_enum::IntEnum; +use oneshot::Sender; use postcard::to_slice; use sequential_storage::{ cache::{Cache, Uncached}, @@ -14,35 +16,28 @@ use sequential_storage::{ use serde::{Deserialize, Serialize}; use thiserror::Error; -pub static CONFIG_SERVICE: RpcService = - RpcService::new(); +pub async fn start_config(spawner: Spawner, flash: FLASH<'static>) { + let storage = MapStorage::::new( + BlockingAsync::new(FlashStorage::new(flash)), + const { MapConfig::new(0x3F_0000..0x40_0000) }, + Cache::new_uncached(), + ); -pub struct ConfigService { - storage: MapStorage< - ConfigKey, - BlockingAsync>, - Cache, - >, - data_buffer: [u8; 256], + spawner.spawn(handler(storage).unwrap()); } -impl ConfigService { - pub async fn set_wifi_creds(&mut self, value: WifiCredentials) -> Result<(), ConfigError> { - let mut buf = [0u8; 256]; - to_slice(&value, &mut buf)?; +pub async fn set_wifi_creds(value: WifiCredentials) -> Result<(), ConfigError> { + let (send, recv) = oneshot::channel(); + CONFIG_CHANNEL + .send(ConfigOperationMessage::SetWifiCreds(value, send)) + .await; + recv.await? +} - self.storage - .store_item(&mut self.data_buffer, &ConfigKey::Wifi, &buf) - .await - .map_err(|e| ConfigError::FlashError(e))?; +static CONFIG_CHANNEL: Channel = Channel::new(); - // TODO: send the change to the wifi service - // WIFI_SERVICE - // .call(|s| s.set_station_config(esp_radio::wifi::Config::Station(value.into()))) - // .await; - - Ok(()) - } +enum ConfigOperationMessage { + SetWifiCreds(WifiCredentials, Sender>), } #[derive(Debug, Deserialize, Serialize)] @@ -59,24 +54,50 @@ impl From for StationConfig { } } -pub async fn start_config(spawner: Spawner, flash: FLASH<'static>) { - let storage = MapStorage::::new( - BlockingAsync::new(FlashStorage::new(flash)), - const { MapConfig::new(0x3F_0000..0x40_0000) }, - Cache::new_uncached(), - ); - - let service = ConfigService { - storage: storage, - data_buffer: [0u8; 256], +// TODO: refactor this when try blocks are implemented +#[embassy_executor::task] +async fn handler( + mut storage: MapStorage< + ConfigKey, + BlockingAsync>, + Cache, + >, +) -> ! { + let resp_fail = |_| { + // TODO: make tracing work so if this code is reached you know where the error originated + error!("failed to respond"); }; - spawner.spawn(handler(service).unwrap()); -} + let mut data_buffer = [0u8; 256]; -#[embassy_executor::task] -async fn handler(mut service: ConfigService) -> ! { - CONFIG_SERVICE.run(&mut service).await + loop { + let operation = CONFIG_CHANNEL.receive().await; + + match operation { + ConfigOperationMessage::SetWifiCreds(value, resp) => { + let mut buf = [0u8; 256]; + if let Err(err) = to_slice(&value, &mut buf) { + let _ = resp.send(Err(err.into())).map_err(resp_fail); + continue; + }; + + if let Err(err) = storage + .store_item(&mut data_buffer, &ConfigKey::Wifi, &buf) + .await + { + let _ = resp.send(Err(err.into())).map_err(resp_fail); + continue; + }; + + // TODO: send the change to the wifi service + // WIFI_SERVICE + // .call(|s| s.set_station_config(esp_radio::wifi::Config::Station(value.into()))) + // .await; + + let _ = resp.send(Ok(())).map_err(resp_fail); + } + } + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, IntEnum)] @@ -122,4 +143,19 @@ pub enum ConfigError { #[error("Error storing data on the flash: {0:?}")] FlashError(sequential_storage::Error), + + #[error("Error receiving response: {0}")] + RecvError(oneshot::RecvError), +} + +impl From> for ConfigError { + fn from(v: sequential_storage::Error) -> Self { + Self::FlashError(v) + } +} + +impl From for ConfigError { + fn from(v: oneshot::RecvError) -> Self { + Self::RecvError(v) + } } diff --git a/src/wifi.rs b/src/wifi.rs index 12d2ecc..0b9ac76 100644 --- a/src/wifi.rs +++ b/src/wifi.rs @@ -1,36 +1,15 @@ use defmt::{error, info}; use embassy_executor::Spawner; +use embassy_futures::select::{Either, select}; use embassy_net::{Runner, Stack}; -use embassy_sync::{ - blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, rpc_service::RpcService, -}; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::channel::Channel; +use embassy_sync::signal::Signal; use embassy_time::{Duration, Timer}; use esp_hal::peripherals::WIFI; use esp_radio::wifi::sta::StationConfig; -use esp_radio::wifi::{ControllerConfig, Interface, WifiController, WifiError}; - -pub static WIFI_SERVICE: RpcService = RpcService::new(); - -pub struct WifiService { - pub net_stack: Stack<'static>, - wifi_controller: &'static Mutex>, -} - -impl WifiService { - 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 fn set_dhcp_config(&self, config: embassy_net::DhcpConfig) { - self.net_stack - .set_config_v4(embassy_net::ConfigV4::Dhcp(config)); - } -} +use esp_radio::wifi::{ControllerConfig, Interface, WifiController}; +use oneshot::{RecvError, Sender}; pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> { let wifi_config = esp_radio::wifi::Config::Station(StationConfig::default()); @@ -58,50 +37,89 @@ pub fn start_wifi(spawner: Spawner, wifi: WIFI<'static>) -> Stack<'static> { seed, ); - let service = WifiService { - net_stack: net_stack, - wifi_controller: crate::mk_static!(Mutex>, 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(connection_handler(wifi_controller).unwrap()); + spawner.spawn(handler(net_stack).unwrap()); spawner.spawn(ip_logger(net_stack).unwrap()); net_stack } -#[embassy_executor::task] -async fn handler(mut service: WifiService) -> ! { - WIFI_SERVICE.run(&mut service).await +pub async fn set_station_config(config: esp_radio::wifi::Config) -> Result<(), RecvError> { + let (send, recv) = oneshot::channel(); + WIFI_CHANNEL + .send(WifiOperationMessage::SetStationConfig(config, send)) + .await; + recv.await +} + +pub async fn set_dhcp_config(config: embassy_net::DhcpConfig) -> Result<(), RecvError> { + let (send, recv) = oneshot::channel(); + WIFI_CHANNEL + .send(WifiOperationMessage::SetDhcpConfig(config, send)) + .await; + recv.await +} + +static WIFI_CHANNEL: Channel = Channel::new(); + +enum WifiOperationMessage { + SetStationConfig(esp_radio::wifi::Config, Sender<()>), + SetDhcpConfig(embassy_net::DhcpConfig, Sender<()>), } #[embassy_executor::task] -async fn connection_handler( - controller: &'static Mutex>, -) -> ! { +async fn handler(net_stack: Stack<'static>) -> ! { loop { + match WIFI_CHANNEL.receive().await { + WifiOperationMessage::SetStationConfig(config, resp) => { + WIFI_HANDLER_RPC.signal(config); + if let Err(_) = resp.send(()) { + // TODO: find a way to not hard-code symbols in a string + error!("WifiOperationMessage::SetStationConfig failed to respond") + }; + } + WifiOperationMessage::SetDhcpConfig(config, resp) => { + net_stack.set_config_v4(embassy_net::ConfigV4::Dhcp(config)); + if let Err(_) = resp.send(()) { + // TODO: find a way to not hard-code symbols in a string + error!("WifiOperationMessage::SetDhcpConfig failed to respond") + }; + } + } + } +} + +static WIFI_HANDLER_RPC: Signal = Signal::new(); + +#[embassy_executor::task] +async fn connection_handler(mut controller: WifiController<'static>) -> ! { + async fn connection(controller: &mut WifiController<'static>) { info!("Connecting to WiFi..."); - match controller.lock().await.connect_async().await { + match controller.connect_async().await { Ok(info) => { info!("Wifi connected to {:?}", info); // wait until we're no longer connected - // TODO: reimplement the wait for disconnect - // let info = controller - // .lock() - // .await - // .wait_for_disconnect_async() - // .await - // .ok(); - // info!("Disconnected: {:?}", info); + 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) = + 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]