eculocate

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit ae0393cd4883468187b2715645c03f080eb9f049
parent 35c7d34b8dfd997093a7158d5a82abac8166f41c
Author: Daniel Barlow <dan@telent.net>
Date:   Tue, 23 Dec 2025 16:51:10 +0000

rearrange as workspace of crates

I would rather like to be able to write tests for the complicated
bits, but using "cargo test" with the esp32 tolchain/libraries
is beyond my skill level if it's even possible.  Hence we now have
an ecu-portable crate for stuff that can be built using plain old Rust
(e.g. x86_64 with std)  and an ecu-esp32 crate for the rest of it

Diffstat:
MCargo.lock | 7++++++-
MCargo.toml | 90+++----------------------------------------------------------------------------
Aecu-esp32/Cargo.toml | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rbuild.rs -> ecu-esp32/build.rs | 0
Rrust-toolchain.toml -> ecu-esp32/rust-toolchain.toml | 0
Rsrc/ecu.rs -> ecu-esp32/src/ecu.rs | 0
Rsrc/main.rs -> ecu-esp32/src/main.rs | 0
Rsrc/wibble.rs -> ecu-esp32/src/wibble.rs | 0
Aecu-esp32/src/wifi.rs | 322+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aecu-portable/Cargo.toml | 6++++++
Aecu-portable/src/lib.rs | 41+++++++++++++++++++++++++++++++++++++++++
Mnotes.md | 13+++++++++++++
Dsrc/wifi.rs | 312-------------------------------------------------------------------------------
13 files changed, 480 insertions(+), 400 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -290,12 +290,13 @@ dependencies = [ ] [[package]] -name = "eculogical" +name = "ecu-esp32" version = "0.1.0" dependencies = [ "bleps", "bt-hci", "dns-protocol", + "ecu_portable", "embassy-executor", "embassy-futures", "embassy-net", @@ -317,6 +318,10 @@ dependencies = [ ] [[package]] +name = "ecu_portable" +version = "0.1.0" + +[[package]] name = "embassy-embedded-hal" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml @@ -1,87 +1,3 @@ -[package] -edition = "2024" -name = "eculogical" -rust-version = "1.88" -version = "0.1.0" - - -[dependencies] -esp-hal = { version = "1.0.0", features = ["esp32c3", "log-04", "unstable"] } - -esp-rtos = { version = "0.2.0", features = [ - "esp-alloc", - "esp-radio", - "esp32c3", - "log-04", - "embassy", -] } - -esp-bootloader-esp-idf = { version = "0.4.0", features = ["esp32c3", "log-04"] } -log = "0.4.27" - -bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [ - "async", - "macros", -] } -esp-alloc = "0.9.0" -bt-hci = { version = "0.6.0" } -embassy-executor = { version = "0.9.1", features = [] } -embassy-time = { version = "0.5.0", features = [] } -embedded-io = { version = "0.7.1", features = [] } -embedded-io-async = { version = "0.7.0", features = [] } -esp-backtrace = { version = "0.18.1", features = [ - "esp32c3", - "panic-handler", - "println", -] } -esp-println = { version = "0.16.1", features = ["esp32c3", "log-04"] } -esp-radio = { version = "0.17.0", features = [ - "ble", - "esp-alloc", - "esp32c3", - "log-04", - "unstable", - "wifi", - "smoltcp" -] } - -smoltcp = { version = "0.12.0", default-features = false, features = [ - "medium-ethernet", - "socket-raw", - "proto-dhcpv4", - "proto-ipv4" -] } - - -embassy-futures = "0.1.1" -embassy-sync = { version = "0.7" } - -static_cell = "2" -trouble-host = { version = "0.5.0", features = [ - "peripheral", "gatt", "default-packet-pool-mtu-255", - "derive", "scan", -] } -embassy-net = { version = "0.7.1", features = [ - "medium-ethernet", "proto-ipv4", "tcp", "dhcpv4", "udp", - "dns", "mdns", "multicast" -] } - -dns-protocol = { version = "0.1.2", default-features = false, features = [ - # no "std" feature -] } - - - -[profile.dev] -# Rust debug is too slow. -# For debug builds always builds with some optimization -opt-level = "s" - -[profile.release] -codegen-units = 1 # LLVM can perform better optimizations using a single thread -debug = 2 -debug-assertions = false -incremental = false -lto = 'fat' -opt-level = 's' -overflow-checks = false +[workspace] +resolver = "3" +members = ["ecu-esp32", "ecu-portable"] diff --git a/ecu-esp32/Cargo.toml b/ecu-esp32/Cargo.toml @@ -0,0 +1,89 @@ +[package] +edition = "2024" +name = "ecu-esp32" +rust-version = "1.88" +version = "0.1.0" + + +[dependencies] +ecu_portable = { path = "../ecu-portable" } + +esp-hal = { version = "1.0.0", features = ["esp32c3", "log-04", "unstable"] } + +esp-rtos = { version = "0.2.0", features = [ + "esp-alloc", + "esp-radio", + "esp32c3", + "log-04", + "embassy", +] } + +esp-bootloader-esp-idf = { version = "0.4.0", features = ["esp32c3", "log-04"] } +log = "0.4.27" + +bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [ + "async", + "macros", +] } +esp-alloc = "0.9.0" +bt-hci = { version = "0.6.0" } +embassy-executor = { version = "0.9.1", features = [] } +embassy-time = { version = "0.5.0", features = [] } +embedded-io = { version = "0.7.1", features = [] } +embedded-io-async = { version = "0.7.0", features = [] } +esp-backtrace = { version = "0.18.1", features = [ + "esp32c3", + "panic-handler", + "println", +] } +esp-println = { version = "0.16.1", features = ["esp32c3", "log-04"] } +esp-radio = { version = "0.17.0", features = [ + "ble", + "esp-alloc", + "esp32c3", + "log-04", + "unstable", + "wifi", + "smoltcp" +] } + +smoltcp = { version = "0.12.0", default-features = false, features = [ + "medium-ethernet", + "socket-raw", + "proto-dhcpv4", + "proto-ipv4" +] } + + +embassy-futures = "0.1.1" +embassy-sync = { version = "0.7" } + +static_cell = "2" +trouble-host = { version = "0.5.0", features = [ + "peripheral", "gatt", "default-packet-pool-mtu-255", + "derive", "scan", +] } +embassy-net = { version = "0.7.1", features = [ + "medium-ethernet", "proto-ipv4", "tcp", "dhcpv4", "udp", + "dns", "mdns", "multicast" +] } + +dns-protocol = { version = "0.1.2", default-features = false, features = [ + # no "std" feature +] } + + + +[profile.dev] +# Rust debug is too slow. +# For debug builds always builds with some optimization +opt-level = "s" + +[profile.release] +codegen-units = 1 # LLVM can perform better optimizations using a single thread +debug = 2 +debug-assertions = false +incremental = false +lto = 'fat' +opt-level = 's' +overflow-checks = false diff --git a/build.rs b/ecu-esp32/build.rs diff --git a/rust-toolchain.toml b/ecu-esp32/rust-toolchain.toml diff --git a/src/ecu.rs b/ecu-esp32/src/ecu.rs diff --git a/src/main.rs b/ecu-esp32/src/main.rs diff --git a/src/wibble.rs b/ecu-esp32/src/wibble.rs diff --git a/ecu-esp32/src/wifi.rs b/ecu-esp32/src/wifi.rs @@ -0,0 +1,322 @@ +//! Set SSID and PASSWORD env variable before running this example. +//! +//! This gets an ip address via DHCP and advertises it with mdns + + +use embassy_executor::Spawner; +use embassy_net::{ + Runner, + StackResources, + udp::{PacketMetadata, UdpSocket, UdpMetadata}, + IpAddress, + IpEndpoint +}; + +use embassy_time::{Duration, Timer}; +use esp_alloc as _; +use esp_backtrace as _; +use esp_hal::{ + rng::Rng, +}; +use esp_println::println; +use esp_radio::{ + Controller, + wifi::{ + ClientConfig, + ModeConfig, + ScanConfig, + WifiController, + WifiDevice, + WifiEvent, + WifiStaState, + }, +}; + +use log::info; + + +use dns_protocol::{Message, Question, + MessageType, + Label, + ResourceRecord, ResourceType, Flags}; + +// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html +macro_rules! mk_static { + ($t:ty,$val:expr) => {{ + static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); + #[deny(unused_attributes)] + let x = STATIC_CELL.uninit().write(($val)); + x + }}; +} + +const SSID: &str = env!("SSID"); +const PASSWORD: &str = env!("PASSWORD"); + +const MDNS_IP: IpAddress = IpAddress::v4(224, 0, 0, 251); +const MDNS_PORT: u16 = 5353; +const MDNS_ENDPOINT: IpEndpoint = IpEndpoint::new(MDNS_IP, MDNS_PORT); + +const CACHE_FLUSH : u16 = 1<<15; + + +// RFC: "Multicast DNS responses MUST NOT contain any questions in the +// Question Section. ". However, responses to "legacy" queries (port != 5353) +// should have a question section just like traditional DNS + +async fn send_advert(sock: &UdpSocket<'_>, + id: u16, + endpoint: IpEndpoint, + question: Option<&Question<'_>>, + my_address: &[u8]) { + + let questions = match question { + Some(q) =>&mut [*q][..], + None => &mut [][..] + }; + + let mut buf : [u8; 32] = [0; 32]; + + info!("ptr data bytes: {:?}", + ecu_portable::ptr_data( + &["myname", "_keihin", "_udp"], + &mut buf) + ); + + // FIXME for legacy unicast response max ttl is 10s + + let mut answer = [ + ResourceRecord::new( + "eculogical.local", + ResourceType::A, + 1 | CACHE_FLUSH, + 120, // ttl + &my_address + ) + ]; + + let mut flags = Flags::new(); + flags.set_qr(MessageType::Reply); + flags.set_authoritative(true); + + let advert_message = Message::new( + id, + flags, + questions, + &mut answer, + &mut [], + &mut []); + + let mut data_buf = [0; 4096]; + // Serialize the message into the buffer + assert!(advert_message.space_needed() <= data_buf.len()); + + log::info!("ready to send to {:?}", endpoint); + + match advert_message.write(&mut data_buf) { + Result::Ok(len) => { + log::info!("sock.send: {:?}", sock.send_to(&data_buf[..len], endpoint).await); + }, + Result::Err(err) => { + log::error!("message.write {:?}", err); + } + } +} + +async fn send_responses(sock: &UdpSocket<'_>, + my_address: &[u8], + message: &Message<'_,'_>, + meta: &UdpMetadata) { + + let my_hostname = Label::from("eculogical.local"); + let q_id = message.id(); + + // for each relevant question we want to add RRs (as answers + // or additional) to the reply packet. I'm uncertain whether + // it's ok to do this for legacy queries but they probably + // don't have multiple questions anyway + for q in message.questions() { + log::info!("question {:?} {:?} {:?} flags {:?} from {:?}", + q.name(), q.ty(), q.class(), + message.flags().raw(), + meta.endpoint); + if q.name().eq(&my_hostname) { + if meta.endpoint.port == 5353 { + send_advert(&sock, q_id, MDNS_ENDPOINT, None, &my_address).await; + } else if (q.class() & 0x8000) != 0 { + log::info!("unicast"); + send_advert(&sock, q_id, meta.endpoint, None, &my_address).await; + } else { + // legacy unicast, send questions + send_advert(&sock, q_id, meta.endpoint, Some(q), &my_address).await; + } + log::info!("IT ME"); + } + } +} + +pub async fn start_wifi(spawner: &Spawner, + wifi_peripheral: esp_hal::peripherals::WIFI<'static>) -> ! { + + + let esp_radio_ctrl = &*mk_static!(Controller<'static>, esp_radio::init().unwrap()); + + let (controller, interfaces) = + esp_radio::wifi::new(esp_radio_ctrl, wifi_peripheral, Default::default()).unwrap(); + + let wifi_interface = interfaces.sta; + + let config = embassy_net::Config::dhcpv4(Default::default()); + + let rng = Rng::new(); + let seed = (rng.random() as u64) << 32 | rng.random() as u64; + + // Init network stack + let (stack, runner) = embassy_net::new( + wifi_interface, + config, + mk_static!(StackResources<3>, StackResources::<3>::new()), + seed, + ); + + spawner.spawn(connection(controller)).ok(); + spawner.spawn(net_task(runner)).ok(); + + let mut rx_buffer = [0; 4096]; + let mut tx_buffer = [0; 4096]; + let my_address; + + loop { + if stack.is_link_up() { + break; + } + Timer::after(Duration::from_millis(500)).await; + } + + println!("Waiting to get IP address..."); + loop { + if let Some(config) = stack.config_v4() { + println!("Got IP: {}", config.address); + my_address = config.address.address().octets(); + break; + } + Timer::after(Duration::from_millis(500)).await; + } + + let mut rx_meta = [PacketMetadata::EMPTY; 512]; + let mut tx_meta = [PacketMetadata::EMPTY; 512]; + let mut sock = UdpSocket::new( + stack, + &mut rx_meta, + &mut rx_buffer, + &mut tx_meta, + &mut tx_buffer, + ); + sock.set_hop_limit(Some(1)); + + log::info!("sock.bind(5353) res: {:?}", sock.bind(MDNS_PORT)); + log::info!( + "multicast_res: {:?}", + stack.join_multicast_group(MDNS_IP) + ); + + + send_advert(&sock, rng.random() as u16, MDNS_ENDPOINT, None, &my_address).await; + + let mut data_buf = [0; 4096]; + + loop { + if sock.may_recv() { + let mut questions = [Question::default(); 16]; + let mut answers = [ResourceRecord::default(); 16]; + let mut authorities = [ResourceRecord::default(); 16]; + let mut addl = [ResourceRecord::default(); 16]; + + let res = sock.recv_from(&mut data_buf).await; + if let Ok((n, meta)) = res { + log::info!("received packet len {n}"); + let message = Message::read( + &data_buf[..n], + &mut questions, + &mut answers, + &mut authorities, + &mut addl, + ); + + match message { + Result::Ok(message) => { + send_responses(&sock, &my_address, &message, &meta).await; + }, + Result::Err(err) => { + log::error!("parsing dns message: {:?}", err); + } + } + } + } + + Timer::after(Duration::from_millis(80)).await; + } + + // _ = stack.leave_multicast_group(MDNS_IP); + // sock.close(); + // drop(sock); + + // loop { + // Timer::after(Duration::from_millis(1_000)).await; + // log::info!("bump"); + // } + +} + +#[embassy_executor::task] +async fn connection(mut controller: WifiController<'static>) { + println!("start connection task"); + println!("Device capabilities: {:?}", controller.capabilities()); + loop { + match esp_radio::wifi::sta_state() { + WifiStaState::Connected => { + // wait until we're no longer connected + controller + .wait_for_event(WifiEvent::StaDisconnected) + .await; + Timer::after(Duration::from_millis(5000)).await + } + _ => {} + } + if !matches!(controller.is_started(), Ok(true)) { + let station_config = ModeConfig::Client( + ClientConfig::default() + .with_ssid(SSID.into()) + .with_password(PASSWORD.into()), + ); + controller.set_config(&station_config).unwrap(); + println!("Starting wifi"); + controller.start_async().await.unwrap(); + println!("Wifi started!"); + + println!("Scan"); + let scan_config = ScanConfig::default().with_max(10); + let result = controller + .scan_with_config_async(scan_config) + .await + .unwrap(); + for ap in result { + println!("{:?}", ap); + } + } + println!("About to connect..."); + + match controller.connect_async().await { + Ok(_) => println!("Wifi connected!"), + Err(e) => { + println!("Failed to connect to wifi: {e:?}"); + Timer::after(Duration::from_millis(5000)).await + } + } + } +} + +#[embassy_executor::task] +async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) { + runner.run().await +} diff --git a/ecu-portable/Cargo.toml b/ecu-portable/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ecu_portable" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/ecu-portable/src/lib.rs b/ecu-portable/src/lib.rs @@ -0,0 +1,41 @@ +#![no_std] + +use core::iter::Iterator; + +pub fn ptr_data<'b>(labels : &[&str], buf : &'b mut[u8]) -> &'b mut [u8] { + let mut offset = 0; + for l in labels.iter() { + buf[offset] = l.len() as u8; + for (i, &item) in l.as_bytes().iter().enumerate() { + buf[offset + 1 + i] = item; + } + offset = offset + l.len() + 1; + } + &mut buf[..offset] +} + + +#[cfg(test)] +mod tests { + extern crate std; + use super::*; + + #[test] + fn test_ptr_data() { + let mut buf : [u8; 32] = [0; 32]; + assert_eq!(ptr_data(&["hello"], &mut buf), + [5, 104, 101, 108, 108, 111]); + + assert_eq!(ptr_data(&[], &mut buf), + []); + + assert_eq!(ptr_data(&["hello", "world"], &mut buf), + [5, 104, 101, 108, 108, 111, + 5, 119, 111, 114, 108, 100]); + + assert_eq!(ptr_data(&["hello", "cool", "world"], &mut buf), + [5, 104, 101, 108, 108, 111, + 4, 99, 111, 111, 108, + 5, 119, 111, 114, 108, 100]); + } +} diff --git a/notes.md b/notes.md @@ -1,3 +1,16 @@ +# Building + +The repo is split into two crates in a cargo workspace: code in +ecu-portable can be built and run using the native compiler, hence is +unit-testable, and code in ecu-esp32 depends on all the esp32 gubbins +so you can test it only by running it. + +``` + cargo test -p ecu-portable --target x86_64-unknown-linux-gnu + SSID=my-wifi PASSWORD="my-wifi-password" cargo run --release +``` + + # Resources https://github.com/aeaphichart/HondaECU-1 diff --git a/src/wifi.rs b/src/wifi.rs @@ -1,312 +0,0 @@ -//! Set SSID and PASSWORD env variable before running this example. -//! -//! This gets an ip address via DHCP and advertises it with mdns - - -use embassy_executor::Spawner; -use embassy_net::{ - Runner, - StackResources, - udp::{PacketMetadata, UdpSocket, UdpMetadata}, - IpAddress, - IpEndpoint -}; - -use embassy_time::{Duration, Timer}; -use esp_alloc as _; -use esp_backtrace as _; -use esp_hal::{ - rng::Rng, -}; -use esp_println::println; -use esp_radio::{ - Controller, - wifi::{ - ClientConfig, - ModeConfig, - ScanConfig, - WifiController, - WifiDevice, - WifiEvent, - WifiStaState, - }, -}; - - -use dns_protocol::{Message, Question, - MessageType, - Label, - ResourceRecord, ResourceType, Flags}; - -// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html -macro_rules! mk_static { - ($t:ty,$val:expr) => {{ - static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); - #[deny(unused_attributes)] - let x = STATIC_CELL.uninit().write(($val)); - x - }}; -} - -const SSID: &str = env!("SSID"); -const PASSWORD: &str = env!("PASSWORD"); - -const MDNS_IP: IpAddress = IpAddress::v4(224, 0, 0, 251); -const MDNS_PORT: u16 = 5353; -const MDNS_ENDPOINT: IpEndpoint = IpEndpoint::new(MDNS_IP, MDNS_PORT); - -const CACHE_FLUSH : u16 = 1<<15; - - -// RFC: "Multicast DNS responses MUST NOT contain any questions in the -// Question Section. ". However, responses to "legacy" queries (port != 5353) -// should have a question section just like traditional DNS - -async fn send_advert(sock: &UdpSocket<'_>, - id: u16, - endpoint: IpEndpoint, - question: Option<&Question<'_>>, - my_address: &[u8]) { - - let questions = match question { - Some(q) =>&mut [*q][..], - None => &mut [][..] - }; - - // FIXME for legacy unicast response max ttl is 10s - - let mut answer = [ - ResourceRecord::new( - "eculogical.local", - ResourceType::A, - 1 | CACHE_FLUSH, - 120, // ttl - &my_address - ) - ]; - - let mut flags = Flags::new(); - flags.set_qr(MessageType::Reply); - flags.set_authoritative(true); - - let advert_message = Message::new( - id, - flags, - questions, - &mut answer, - &mut [], - &mut []); - - let mut data_buf = [0; 4096]; - // Serialize the message into the buffer - assert!(advert_message.space_needed() <= data_buf.len()); - - log::info!("ready to send to {:?}", endpoint); - - match advert_message.write(&mut data_buf) { - Result::Ok(len) => { - log::info!("sock.send: {:?}", sock.send_to(&data_buf[..len], endpoint).await); - }, - Result::Err(err) => { - log::error!("message.write {:?}", err); - } - } -} - -async fn send_responses(sock: &UdpSocket<'_>, - my_address: &[u8], - message: &Message<'_,'_>, - meta: &UdpMetadata) { - - let my_hostname = Label::from("eculogical.local"); - let q_id = message.id(); - - // for each relevant question we want to add RRs (as answers - // or additional) to the reply packet. I'm uncertain whether - // it's ok to do this for legacy queries but they probably - // don't have multiple questions anyway - for q in message.questions() { - log::info!("question {:?} {:?} {:?} flags {:?} from {:?}", - q.name(), q.ty(), q.class(), - message.flags().raw(), - meta.endpoint); - if q.name().eq(&my_hostname) { - if meta.endpoint.port == 5353 { - send_advert(&sock, q_id, MDNS_ENDPOINT, None, &my_address).await; - } else if (q.class() & 0x8000) != 0 { - log::info!("unicast"); - send_advert(&sock, q_id, meta.endpoint, None, &my_address).await; - } else { - // legacy unicast, send questions - send_advert(&sock, q_id, meta.endpoint, Some(q), &my_address).await; - } - log::info!("IT ME"); - } - } -} - -pub async fn start_wifi(spawner: &Spawner, - wifi_peripheral: esp_hal::peripherals::WIFI<'static>) -> ! { - - - let esp_radio_ctrl = &*mk_static!(Controller<'static>, esp_radio::init().unwrap()); - - let (controller, interfaces) = - esp_radio::wifi::new(esp_radio_ctrl, wifi_peripheral, Default::default()).unwrap(); - - let wifi_interface = interfaces.sta; - - let config = embassy_net::Config::dhcpv4(Default::default()); - - let rng = Rng::new(); - let seed = (rng.random() as u64) << 32 | rng.random() as u64; - - // Init network stack - let (stack, runner) = embassy_net::new( - wifi_interface, - config, - mk_static!(StackResources<3>, StackResources::<3>::new()), - seed, - ); - - spawner.spawn(connection(controller)).ok(); - spawner.spawn(net_task(runner)).ok(); - - let mut rx_buffer = [0; 4096]; - let mut tx_buffer = [0; 4096]; - let my_address; - - loop { - if stack.is_link_up() { - break; - } - Timer::after(Duration::from_millis(500)).await; - } - - println!("Waiting to get IP address..."); - loop { - if let Some(config) = stack.config_v4() { - println!("Got IP: {}", config.address); - my_address = config.address.address().octets(); - break; - } - Timer::after(Duration::from_millis(500)).await; - } - - let mut rx_meta = [PacketMetadata::EMPTY; 512]; - let mut tx_meta = [PacketMetadata::EMPTY; 512]; - let mut sock = UdpSocket::new( - stack, - &mut rx_meta, - &mut rx_buffer, - &mut tx_meta, - &mut tx_buffer, - ); - sock.set_hop_limit(Some(1)); - - log::info!("sock.bind(5353) res: {:?}", sock.bind(MDNS_PORT)); - log::info!( - "multicast_res: {:?}", - stack.join_multicast_group(MDNS_IP) - ); - - - send_advert(&sock, rng.random() as u16, MDNS_ENDPOINT, None, &my_address).await; - - let mut data_buf = [0; 4096]; - - loop { - if sock.may_recv() { - let mut questions = [Question::default(); 16]; - let mut answers = [ResourceRecord::default(); 16]; - let mut authorities = [ResourceRecord::default(); 16]; - let mut addl = [ResourceRecord::default(); 16]; - - let res = sock.recv_from(&mut data_buf).await; - if let Ok((n, meta)) = res { - log::info!("received packet len {n}"); - let message = Message::read( - &data_buf[..n], - &mut questions, - &mut answers, - &mut authorities, - &mut addl, - ); - - match message { - Result::Ok(message) => { - send_responses(&sock, &my_address, &message, &meta).await; - }, - Result::Err(err) => { - log::error!("parsing dns message: {:?}", err); - } - } - } - } - - Timer::after(Duration::from_millis(80)).await; - } - - // _ = stack.leave_multicast_group(MDNS_IP); - // sock.close(); - // drop(sock); - - // loop { - // Timer::after(Duration::from_millis(1_000)).await; - // log::info!("bump"); - // } - -} - -#[embassy_executor::task] -async fn connection(mut controller: WifiController<'static>) { - println!("start connection task"); - println!("Device capabilities: {:?}", controller.capabilities()); - loop { - match esp_radio::wifi::sta_state() { - WifiStaState::Connected => { - // wait until we're no longer connected - controller - .wait_for_event(WifiEvent::StaDisconnected) - .await; - Timer::after(Duration::from_millis(5000)).await - } - _ => {} - } - if !matches!(controller.is_started(), Ok(true)) { - let station_config = ModeConfig::Client( - ClientConfig::default() - .with_ssid(SSID.into()) - .with_password(PASSWORD.into()), - ); - controller.set_config(&station_config).unwrap(); - println!("Starting wifi"); - controller.start_async().await.unwrap(); - println!("Wifi started!"); - - println!("Scan"); - let scan_config = ScanConfig::default().with_max(10); - let result = controller - .scan_with_config_async(scan_config) - .await - .unwrap(); - for ap in result { - println!("{:?}", ap); - } - } - println!("About to connect..."); - - match controller.connect_async().await { - Ok(_) => println!("Wifi connected!"), - Err(e) => { - println!("Failed to connect to wifi: {e:?}"); - Timer::after(Duration::from_millis(5000)).await - } - } - } -} - -#[embassy_executor::task] -async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) { - runner.run().await -}