aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-09-09 20:06:52 +0000
committerGitHub <[email protected]>2023-09-09 20:06:52 +0000
commit2132afb48b783ad2711c88e1ae939244f9fdd809 (patch)
treef7fb5a9cddb7054b2e159e4b2fbb86445294e489
parentf17f09057d8ef4b2ba09fb26e2a320384549b513 (diff)
parent0e9131fd1465d8fc765c4da05ce63d9dfbf950c7 (diff)
Merge pull request #1874 from JuliDi/eth-getstatus-async
embassy-net: add async wait_config_up
-rw-r--r--embassy-net/src/lib.rs54
-rw-r--r--examples/stm32f4/src/bin/eth.rs5
-rw-r--r--examples/stm32f7/src/bin/eth.rs5
-rw-r--r--examples/stm32h5/src/bin/eth.rs3
-rw-r--r--examples/stm32h7/src/bin/eth.rs3
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs8
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);