use embassy_futures::select::select;
use embassy_net::udp::UdpSocket;
use embassy_time::{Instant, Timer};
use hick_smoltcp::Engine;
use rand_core::Rng;
use crate::{
io::{DualUdp, wait_either_recv},
time::EmbassyInstant,
};
pub async fn run<R: Rng>(
mut v4: Option<&mut UdpSocket<'_>>,
mut v6: Option<&mut UdpSocket<'_>>,
mut engine: Engine<EmbassyInstant, R>,
scratch: &mut [u8],
) -> ! {
if let Some(s) = v4.as_deref_mut() {
s.set_hop_limit(Some(255));
#[cfg(feature = "defmt")]
defmt::debug!("hick-embassy: v4 hop-limit set to 255 (RFC 6762 §11)");
}
if let Some(s) = v6.as_deref_mut() {
s.set_hop_limit(Some(255));
#[cfg(feature = "defmt")]
defmt::debug!("hick-embassy: v6 hop-limit set to 255 (RFC 6762 §11)");
}
loop {
let now = EmbassyInstant(Instant::now());
let deadline = {
let mut io = DualUdp::new(v4.as_deref(), v6.as_deref());
engine.pump(now, &mut io, scratch)
};
match deadline {
Some(d) => {
#[cfg(feature = "defmt")]
defmt::trace!("hick-embassy: waiting for recv or deadline timer");
let _ = select(
wait_either_recv(v4.as_deref(), v6.as_deref()),
Timer::at(d.0),
)
.await;
}
None => {
#[cfg(feature = "defmt")]
defmt::trace!("hick-embassy: no deadline, waiting for recv");
wait_either_recv(v4.as_deref(), v6.as_deref()).await;
}
}
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests;