diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-09-09 20:06:52 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-09 20:06:52 +0000 |
| commit | 2132afb48b783ad2711c88e1ae939244f9fdd809 (patch) | |
| tree | f7fb5a9cddb7054b2e159e4b2fbb86445294e489 | |
| parent | f17f09057d8ef4b2ba09fb26e2a320384549b513 (diff) | |
| parent | 0e9131fd1465d8fc765c4da05ce63d9dfbf950c7 (diff) | |
Merge pull request #1874 from JuliDi/eth-getstatus-async
embassy-net: add async wait_config_up
| -rw-r--r-- | embassy-net/src/lib.rs | 54 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/eth.rs | 5 | ||||
| -rw-r--r-- | examples/stm32f7/src/bin/eth.rs | 5 | ||||
| -rw-r--r-- | examples/stm32h5/src/bin/eth.rs | 3 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/eth.rs | 3 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/eth_client.rs | 8 |
6 files changed, 72 insertions, 6 deletions
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index c2575267c..de32edc2f 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs | |||
| @@ -172,6 +172,7 @@ impl Config { | |||
| 172 | /// | 172 | /// |
| 173 | /// # Example | 173 | /// # Example |
| 174 | /// ```rust | 174 | /// ```rust |
| 175 | /// # use embassy_net::Config; | ||
| 175 | /// let _cfg = Config::dhcpv4(Default::default()); | 176 | /// let _cfg = Config::dhcpv4(Default::default()); |
| 176 | /// ``` | 177 | /// ``` |
| 177 | #[cfg(feature = "dhcpv4")] | 178 | #[cfg(feature = "dhcpv4")] |
| @@ -226,6 +227,7 @@ struct Inner<D: Driver> { | |||
| 226 | static_v6: Option<StaticConfigV6>, | 227 | static_v6: Option<StaticConfigV6>, |
| 227 | #[cfg(feature = "dhcpv4")] | 228 | #[cfg(feature = "dhcpv4")] |
| 228 | dhcp_socket: Option<SocketHandle>, | 229 | dhcp_socket: Option<SocketHandle>, |
| 230 | config_waker: WakerRegistration, | ||
| 229 | #[cfg(feature = "dns")] | 231 | #[cfg(feature = "dns")] |
| 230 | dns_socket: SocketHandle, | 232 | dns_socket: SocketHandle, |
| 231 | #[cfg(feature = "dns")] | 233 | #[cfg(feature = "dns")] |
| @@ -297,6 +299,7 @@ impl<D: Driver + 'static> Stack<D> { | |||
| 297 | static_v6: None, | 299 | static_v6: None, |
| 298 | #[cfg(feature = "dhcpv4")] | 300 | #[cfg(feature = "dhcpv4")] |
| 299 | dhcp_socket: None, | 301 | dhcp_socket: None, |
| 302 | config_waker: WakerRegistration::new(), | ||
| 300 | #[cfg(feature = "dns")] | 303 | #[cfg(feature = "dns")] |
| 301 | dns_socket: socket.sockets.add(dns::Socket::new( | 304 | dns_socket: socket.sockets.add(dns::Socket::new( |
| 302 | &[], | 305 | &[], |
| @@ -363,6 +366,55 @@ impl<D: Driver + 'static> Stack<D> { | |||
| 363 | v4_up || v6_up | 366 | v4_up || v6_up |
| 364 | } | 367 | } |
| 365 | 368 | ||
| 369 | /// Wait for the network stack to obtain a valid IP configuration. | ||
| 370 | /// | ||
| 371 | /// ## Notes: | ||
| 372 | /// - Ensure [`Stack::run`] has been called before using this function. | ||
| 373 | /// | ||
| 374 | /// - This function may never return (e.g. if no configuration is obtained through DHCP). | ||
| 375 | /// The caller is supposed to handle a timeout for this case. | ||
| 376 | /// | ||
| 377 | /// ## Example | ||
| 378 | /// ```ignore | ||
| 379 | /// let config = embassy_net::Config::dhcpv4(Default::default()); | ||
| 380 | ///// Init network stack | ||
| 381 | /// let stack = &*make_static!(embassy_net::Stack::new( | ||
| 382 | /// device, | ||
| 383 | /// config, | ||
| 384 | /// make_static!(embassy_net::StackResources::<2>::new()), | ||
| 385 | /// seed | ||
| 386 | /// )); | ||
| 387 | /// // Launch network task that runs `stack.run().await` | ||
| 388 | /// spawner.spawn(net_task(stack)).unwrap(); | ||
| 389 | /// // Wait for DHCP config | ||
| 390 | /// stack.wait_config_up().await; | ||
| 391 | /// // use the network stack | ||
| 392 | /// // ... | ||
| 393 | /// ``` | ||
| 394 | pub async fn wait_config_up(&self) { | ||
| 395 | // If the config is up already, we can return immediately. | ||
| 396 | if self.is_config_up() { | ||
| 397 | return; | ||
| 398 | } | ||
| 399 | |||
| 400 | poll_fn(|cx| { | ||
| 401 | if self.is_config_up() { | ||
| 402 | Poll::Ready(()) | ||
| 403 | } else { | ||
| 404 | // If the config is not up, we register a waker that is woken up | ||
| 405 | // when a config is applied (static or DHCP). | ||
| 406 | trace!("Waiting for config up"); | ||
| 407 | |||
| 408 | self.with_mut(|_, i| { | ||
| 409 | i.config_waker.register(cx.waker()); | ||
| 410 | }); | ||
| 411 | |||
| 412 | Poll::Pending | ||
| 413 | } | ||
| 414 | }) | ||
| 415 | .await; | ||
| 416 | } | ||
| 417 | |||
| 366 | /// Get the current IPv4 configuration. | 418 | /// Get the current IPv4 configuration. |
| 367 | /// | 419 | /// |
| 368 | /// If using DHCP, this will be None if DHCP hasn't been able to | 420 | /// If using DHCP, this will be None if DHCP hasn't been able to |
| @@ -706,6 +758,8 @@ impl<D: Driver + 'static> Inner<D> { | |||
| 706 | s.sockets | 758 | s.sockets |
| 707 | .get_mut::<smoltcp::socket::dns::Socket>(self.dns_socket) | 759 | .get_mut::<smoltcp::socket::dns::Socket>(self.dns_socket) |
| 708 | .update_servers(&dns_servers[..]); | 760 | .update_servers(&dns_servers[..]); |
| 761 | |||
| 762 | self.config_waker.wake(); | ||
| 709 | } | 763 | } |
| 710 | 764 | ||
| 711 | fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { | 765 | fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { |
diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index 393e60b73..5f1e62d0a 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs | |||
| @@ -79,7 +79,10 @@ async fn main(spawner: Spawner) -> ! { | |||
| 79 | )); | 79 | )); |
| 80 | 80 | ||
| 81 | // Launch network task | 81 | // Launch network task |
| 82 | unwrap!(spawner.spawn(net_task(&stack))); | 82 | unwrap!(spawner.spawn(net_task(stack))); |
| 83 | |||
| 84 | // Ensure DHCP configuration is up before trying connect | ||
| 85 | stack.wait_config_up().await; | ||
| 83 | 86 | ||
| 84 | info!("Network task initialized"); | 87 | info!("Network task initialized"); |
| 85 | 88 | ||
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index f0e280c35..01c38106e 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs | |||
| @@ -80,7 +80,10 @@ async fn main(spawner: Spawner) -> ! { | |||
| 80 | )); | 80 | )); |
| 81 | 81 | ||
| 82 | // Launch network task | 82 | // Launch network task |
| 83 | unwrap!(spawner.spawn(net_task(&stack))); | 83 | unwrap!(spawner.spawn(net_task(stack))); |
| 84 | |||
| 85 | // Ensure DHCP configuration is up before trying connect | ||
| 86 | stack.wait_config_up().await; | ||
| 84 | 87 | ||
| 85 | info!("Network task initialized"); | 88 | info!("Network task initialized"); |
| 86 | 89 | ||
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 763520ab8..c32e0fdb5 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs | |||
| @@ -101,6 +101,9 @@ async fn main(spawner: Spawner) -> ! { | |||
| 101 | // Launch network task | 101 | // Launch network task |
| 102 | unwrap!(spawner.spawn(net_task(&stack))); | 102 | unwrap!(spawner.spawn(net_task(&stack))); |
| 103 | 103 | ||
| 104 | // Ensure DHCP configuration is up before trying connect | ||
| 105 | stack.wait_config_up().await; | ||
| 106 | |||
| 104 | info!("Network task initialized"); | 107 | info!("Network task initialized"); |
| 105 | 108 | ||
| 106 | // Then we can use it! | 109 | // Then we can use it! |
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 26a386e49..e691c6d06 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs | |||
| @@ -83,6 +83,9 @@ async fn main(spawner: Spawner) -> ! { | |||
| 83 | // Launch network task | 83 | // Launch network task |
| 84 | unwrap!(spawner.spawn(net_task(&stack))); | 84 | unwrap!(spawner.spawn(net_task(&stack))); |
| 85 | 85 | ||
| 86 | // Ensure DHCP configuration is up before trying connect | ||
| 87 | stack.wait_config_up().await; | ||
| 88 | |||
| 86 | info!("Network task initialized"); | 89 | info!("Network task initialized"); |
| 87 | 90 | ||
| 88 | // Then we can use it! | 91 | // Then we can use it! |
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 6664410c8..ebef54c3c 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs | |||
| @@ -82,12 +82,12 @@ async fn main(spawner: Spawner) -> ! { | |||
| 82 | )); | 82 | )); |
| 83 | 83 | ||
| 84 | // Launch network task | 84 | // Launch network task |
| 85 | unwrap!(spawner.spawn(net_task(&stack))); | 85 | unwrap!(spawner.spawn(net_task(stack))); |
| 86 | 86 | ||
| 87 | info!("Network task initialized"); | 87 | // Ensure DHCP configuration is up before trying connect |
| 88 | stack.wait_config_up().await; | ||
| 88 | 89 | ||
| 89 | // To ensure DHCP configuration before trying connect | 90 | info!("Network task initialized"); |
| 90 | Timer::after(Duration::from_secs(20)).await; | ||
| 91 | 91 | ||
| 92 | static STATE: TcpClientState<1, 1024, 1024> = TcpClientState::new(); | 92 | static STATE: TcpClientState<1, 1024, 1024> = TcpClientState::new(); |
| 93 | let client = TcpClient::new(&stack, &STATE); | 93 | let client = TcpClient::new(&stack, &STATE); |
