use alloc::string::String; use chrono::{DateTime, Utc}; use core::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use embassy_net::{Runner, Stack}; use embassy_time::{Duration, Timer}; use edge_dhcp::{ io::{self, DEFAULT_SERVER_PORT}, server::{Server, ServerOptions}, }; use edge_nal::UdpBind; use edge_nal_embassy::{Udp, UdpBuffers}; use esp_radio::wifi::Interface; use log::{warn, error}; use serde::Serialize; #[derive(Serialize, Debug, PartialEq)] pub enum SntpMode { OFFLINE, SYNC { current: DateTime }, } #[derive(Serialize, Debug, PartialEq)] pub enum NetworkMode { WIFI { sntp: SntpMode, mqtt: bool, ip_address: String, }, OFFLINE, } #[embassy_executor::task(pool_size = 2)] pub(crate) async fn net_task(mut runner: Runner<'static, Interface<'static>>) { runner.run().await; } #[embassy_executor::task] pub(crate) async fn run_dhcp(stack: Stack<'static>, ip: Ipv4Addr) { let mut buf = [0u8; 1500]; let mut gw_buf = [Ipv4Addr::UNSPECIFIED]; let buffers = UdpBuffers::<3, 1024, 1024, 10>::new(); let unbound_socket = Udp::new(stack, &buffers); let mut bound_socket = match unbound_socket .bind(SocketAddr::V4(SocketAddrV4::new( Ipv4Addr::UNSPECIFIED, DEFAULT_SERVER_PORT, ))) .await { Ok(s) => s, Err(e) => { error!("dhcp task failed to bind socket: {:?}", e); return; } }; loop { _ = io::server::run( &mut Server::<_, 64>::new_with_et(ip), &ServerOptions::new(ip, Some(&mut gw_buf)), &mut bound_socket, &mut buf, ) .await .inspect_err(|e| warn!("DHCP server error: {e:?}")); Timer::after(Duration::from_millis(500)).await; } }