Merge pull request #3350 from embassy-rs/net-fixes2

net: add all combinations of wait methods for link/config up/down.
This commit is contained in:
Dario Nieuwenhuis 2024-09-18 19:51:37 +00:00 committed by GitHub
commit 45cbcb513d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 17 deletions

View File

@ -120,7 +120,7 @@ impl<'a> Control<'a> {
pwd: unwrap!(String::try_from(password)), pwd: unwrap!(String::try_from(password)),
bssid: String::new(), bssid: String::new(),
listen_interval: 3, listen_interval: 3,
is_wpa3_supported: false, is_wpa3_supported: true,
}; };
ioctl!(self, ReqConnectAp, RespConnectAp, req, resp); ioctl!(self, ReqConnectAp, RespConnectAp, req, resp);
self.state_ch.set_link_state(LinkState::Up); self.state_ch.set_link_state(LinkState::Up);

View File

@ -137,7 +137,7 @@ where
let (ch_runner, device) = ch::new(&mut state.ch, ch::driver::HardwareAddress::Ethernet([0; 6])); let (ch_runner, device) = ch::new(&mut state.ch, ch::driver::HardwareAddress::Ethernet([0; 6]));
let state_ch = ch_runner.state_runner(); let state_ch = ch_runner.state_runner();
let mut runner = Runner { let runner = Runner {
ch: ch_runner, ch: ch_runner,
state_ch, state_ch,
shared: &state.shared, shared: &state.shared,
@ -148,7 +148,6 @@ where
spi, spi,
heartbeat_deadline: Instant::now() + HEARTBEAT_MAX_GAP, heartbeat_deadline: Instant::now() + HEARTBEAT_MAX_GAP,
}; };
runner.init().await;
(device, Control::new(state_ch, &state.shared), runner) (device, Control::new(state_ch, &state.shared), runner)
} }
@ -174,8 +173,6 @@ where
IN: InputPin + Wait, IN: InputPin + Wait,
OUT: OutputPin, OUT: OutputPin,
{ {
async fn init(&mut self) {}
/// Run the packet processing. /// Run the packet processing.
pub async fn run(mut self) -> ! { pub async fn run(mut self) -> ! {
debug!("resetting..."); debug!("resetting...");

View File

@ -260,7 +260,10 @@ pub struct Stack<'d> {
pub(crate) struct Inner { pub(crate) struct Inner {
pub(crate) sockets: SocketSet<'static>, // Lifetime type-erased. pub(crate) sockets: SocketSet<'static>, // Lifetime type-erased.
pub(crate) iface: Interface, pub(crate) iface: Interface,
/// Waker used for triggering polls.
pub(crate) waker: WakerRegistration, pub(crate) waker: WakerRegistration,
/// Waker used for waiting for link up or config up.
state_waker: WakerRegistration,
hardware_address: HardwareAddress, hardware_address: HardwareAddress,
next_local_port: u16, next_local_port: u16,
link_up: bool, link_up: bool,
@ -270,7 +273,6 @@ pub(crate) struct Inner {
static_v6: Option<StaticConfigV6>, static_v6: Option<StaticConfigV6>,
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
dhcp_socket: Option<SocketHandle>, dhcp_socket: Option<SocketHandle>,
config_waker: WakerRegistration,
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
dns_socket: SocketHandle, dns_socket: SocketHandle,
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
@ -326,6 +328,7 @@ pub fn new<'d, D: Driver, const SOCK: usize>(
sockets, sockets,
iface, iface,
waker: WakerRegistration::new(), waker: WakerRegistration::new(),
state_waker: WakerRegistration::new(),
next_local_port, next_local_port,
hardware_address, hardware_address,
link_up: false, link_up: false,
@ -335,7 +338,6 @@ pub fn new<'d, D: Driver, const SOCK: usize>(
static_v6: None, static_v6: None,
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
dhcp_socket: None, dhcp_socket: None,
config_waker: WakerRegistration::new(),
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
dns_socket, dns_socket,
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
@ -421,10 +423,20 @@ impl<'d> Stack<'d> {
v4_up || v6_up v4_up || v6_up
} }
/// Wait for the network device to obtain a link signal.
pub async fn wait_link_up(&self) {
self.wait(|| self.is_link_up()).await
}
/// Wait for the network device to lose link signal.
pub async fn wait_link_down(&self) {
self.wait(|| !self.is_link_up()).await
}
/// Wait for the network stack to obtain a valid IP configuration. /// Wait for the network stack to obtain a valid IP configuration.
/// ///
/// ## Notes: /// ## Notes:
/// - Ensure [`Stack::run`] has been called before using this function. /// - Ensure [`Runner::run`] has been started before using this function.
/// ///
/// - This function may never return (e.g. if no configuration is obtained through DHCP). /// - This function may never return (e.g. if no configuration is obtained through DHCP).
/// The caller is supposed to handle a timeout for this case. /// The caller is supposed to handle a timeout for this case.
@ -451,13 +463,17 @@ impl<'d> Stack<'d> {
/// // ... /// // ...
/// ``` /// ```
pub async fn wait_config_up(&self) { pub async fn wait_config_up(&self) {
// If the config is up already, we can return immediately. self.wait(|| self.is_config_up()).await
if self.is_config_up() { }
return;
}
poll_fn(|cx| { /// Wait for the network stack to lose a valid IP configuration.
if self.is_config_up() { pub async fn wait_config_down(&self) {
self.wait(|| !self.is_config_up()).await
}
fn wait<'a>(&'a self, mut predicate: impl FnMut() -> bool + 'a) -> impl Future<Output = ()> + 'a {
poll_fn(move |cx| {
if predicate() {
Poll::Ready(()) Poll::Ready(())
} else { } else {
// If the config is not up, we register a waker that is woken up // If the config is not up, we register a waker that is woken up
@ -465,13 +481,12 @@ impl<'d> Stack<'d> {
trace!("Waiting for config up"); trace!("Waiting for config up");
self.with_mut(|i| { self.with_mut(|i| {
i.config_waker.register(cx.waker()); i.state_waker.register(cx.waker());
}); });
Poll::Pending Poll::Pending
} }
}) })
.await;
} }
/// Get the current IPv4 configuration. /// Get the current IPv4 configuration.
@ -775,7 +790,7 @@ impl Inner {
.update_servers(&dns_servers[..count]); .update_servers(&dns_servers[..count]);
} }
self.config_waker.wake(); self.state_waker.wake();
} }
fn poll<D: Driver>(&mut self, cx: &mut Context<'_>, driver: &mut D) { fn poll<D: Driver>(&mut self, cx: &mut Context<'_>, driver: &mut D) {
@ -813,6 +828,7 @@ impl Inner {
// Print when changed // Print when changed
if old_link_up != self.link_up { if old_link_up != self.link_up {
info!("link_up = {:?}", self.link_up); info!("link_up = {:?}", self.link_up);
self.state_waker.wake();
} }
#[allow(unused_mut)] #[allow(unused_mut)]