From 2eae12b7f1cbe38d850ebf30f23a776323815af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jan=20Czocha=C5=84ski?= Date: Wed, 18 Jan 2023 09:56:38 +0100 Subject: [PATCH 1/5] Update smoltcp to the newest master --- embassy-net/Cargo.toml | 2 +- embassy-net/src/device.rs | 13 +++++++------ embassy-net/src/lib.rs | 30 ++++++++++-------------------- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 9214fd17..a2ef3b4f 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -51,7 +51,7 @@ atomic-polyfill = { version = "1.0" } [dependencies.smoltcp] version = "0.8.0" git = "https://github.com/smoltcp-rs/smoltcp" -rev = "b7a7c4b1c56e8d4c2524c1e3a056c745a13cc09f" +rev = "7b631c27cefe9b29e322a507c076b4156f477ee2" default-features = false features = [ "proto-ipv4", diff --git a/embassy-net/src/device.rs b/embassy-net/src/device.rs index 44f7dc7b..d0c8a62d 100644 --- a/embassy-net/src/device.rs +++ b/embassy-net/src/device.rs @@ -2,6 +2,7 @@ use core::task::Context; use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken}; use smoltcp::phy; +use smoltcp::time::Instant; pub(crate) struct DriverAdapter<'d, 'c, T> where @@ -19,14 +20,14 @@ where type RxToken<'a> = RxTokenAdapter> where Self: 'a; type TxToken<'a> = TxTokenAdapter> where Self: 'a; - fn receive(&mut self) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { + fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { self.inner .receive(self.cx.as_deref_mut().unwrap()) .map(|(rx, tx)| (RxTokenAdapter(rx), TxTokenAdapter(tx))) } /// Construct a transmit token. - fn transmit(&mut self) -> Option> { + fn transmit(&mut self, _timestamp: Instant) -> Option> { self.inner.transmit(self.cx.as_deref_mut().unwrap()).map(TxTokenAdapter) } @@ -76,9 +77,9 @@ impl phy::RxToken for RxTokenAdapter where T: RxToken, { - fn consume(self, _timestamp: smoltcp::time::Instant, f: F) -> smoltcp::Result + fn consume(self, f: F) -> R where - F: FnOnce(&mut [u8]) -> smoltcp::Result, + F: FnOnce(&mut [u8]) -> R, { self.0.consume(|buf| f(buf)) } @@ -92,9 +93,9 @@ impl phy::TxToken for TxTokenAdapter where T: TxToken, { - fn consume(self, _timestamp: smoltcp::time::Instant, len: usize, f: F) -> smoltcp::Result + fn consume(self, len: usize, f: F) -> R where - F: FnOnce(&mut [u8]) -> smoltcp::Result, + F: FnOnce(&mut [u8]) -> R, { self.0.consume(len, |buf| f(buf)) } diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index e4a4218e..757d3e27 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -23,11 +23,11 @@ use embassy_sync::waitqueue::WakerRegistration; use embassy_time::{Instant, Timer}; use futures::pin_mut; use heapless::Vec; +#[cfg(feature = "medium-ethernet")] +use smoltcp::iface::Routes; #[cfg(feature = "dhcpv4")] use smoltcp::iface::SocketHandle; use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage}; -#[cfg(feature = "medium-ethernet")] -use smoltcp::iface::{Neighbor, NeighborCache, Route, Routes}; #[cfg(feature = "dhcpv4")] use smoltcp::socket::dhcpv4; // smoltcp reexports @@ -45,25 +45,16 @@ use crate::device::DriverAdapter; const LOCAL_PORT_MIN: u16 = 1025; const LOCAL_PORT_MAX: u16 = 65535; -pub struct StackResources { - addresses: [IpCidr; ADDR], +pub struct StackResources { + addresses: [IpCidr; 5], sockets: [SocketStorage<'static>; SOCK], - - #[cfg(feature = "medium-ethernet")] - routes: [Option<(IpCidr, Route)>; 1], - #[cfg(feature = "medium-ethernet")] - neighbor_cache: [Option<(IpAddress, Neighbor)>; NEIGHBOR], } -impl StackResources { +impl StackResources { pub fn new() -> Self { Self { - addresses: [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 32); ADDR], + addresses: [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 32); 5], sockets: [SocketStorage::EMPTY; SOCK], - #[cfg(feature = "medium-ethernet")] - routes: [None; 1], - #[cfg(feature = "medium-ethernet")] - neighbor_cache: [None; NEIGHBOR], } } } @@ -105,21 +96,20 @@ impl Stack { pub fn new( mut device: D, config: ConfigStrategy, - resources: &'static mut StackResources, + resources: &'static mut StackResources, random_seed: u64, ) -> Self { #[cfg(feature = "medium-ethernet")] let medium = device.capabilities().medium; let mut b = InterfaceBuilder::new(); - b = b.ip_addrs(&mut resources.addresses[..]); + b = b.ip_addrs(Vec::::from_iter(resources.addresses)); b = b.random_seed(random_seed); #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { b = b.hardware_addr(HardwareAddress::Ethernet(EthernetAddress(device.ethernet_address()))); - b = b.neighbor_cache(NeighborCache::new(&mut resources.neighbor_cache[..])); - b = b.routes(Routes::new(&mut resources.routes[..])); + b = b.routes(Routes::new()); } let iface = b.finalize(&mut DriverAdapter { @@ -266,7 +256,7 @@ impl Inner { cx: Some(cx), inner: &mut self.device, }; - if s.iface.poll(timestamp, &mut smoldev, &mut s.sockets).is_err() { + if !s.iface.poll(timestamp, &mut smoldev, &mut s.sockets) { // If poll() returns error, it may not be done yet, so poll again later. cx.waker().wake_by_ref(); return; From 8f4fae9b36f017a8ab65491ef49b72499a9486dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jan=20Czocha=C5=84ski?= Date: Wed, 18 Jan 2023 10:10:33 +0100 Subject: [PATCH 2/5] Add smoltcp dhcp socket configuration --- embassy-net/src/lib.rs | 72 ++++++++++++++++------- examples/nrf52840/src/bin/usb_ethernet.rs | 11 +--- examples/rp/src/bin/usb_ethernet.rs | 11 +--- examples/std/Cargo.toml | 2 +- examples/std/src/bin/net.rs | 15 ++--- examples/std/src/bin/net_udp.rs | 13 ++-- examples/stm32f7/src/bin/eth.rs | 11 +--- examples/stm32h7/src/bin/eth.rs | 11 +--- examples/stm32h7/src/bin/eth_client.rs | 11 +--- examples/stm32l5/src/bin/usb_ethernet.rs | 11 +--- 10 files changed, 81 insertions(+), 87 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 757d3e27..c419ec1f 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -30,6 +30,8 @@ use smoltcp::iface::SocketHandle; use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage}; #[cfg(feature = "dhcpv4")] use smoltcp::socket::dhcpv4; +use smoltcp::socket::dhcpv4::RetryConfig; +use smoltcp::time::Duration; // smoltcp reexports pub use smoltcp::time::{Duration as SmolDuration, Instant as SmolInstant}; #[cfg(feature = "medium-ethernet")] @@ -45,31 +47,53 @@ use crate::device::DriverAdapter; const LOCAL_PORT_MIN: u16 = 1025; const LOCAL_PORT_MAX: u16 = 65535; -pub struct StackResources { - addresses: [IpCidr; 5], +pub struct StackResources { sockets: [SocketStorage<'static>; SOCK], } -impl StackResources { +impl StackResources { pub fn new() -> Self { Self { - addresses: [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 32); 5], sockets: [SocketStorage::EMPTY; SOCK], } } } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Config { +pub struct StaticConfig { pub address: Ipv4Cidr, pub gateway: Option, pub dns_servers: Vec, } -pub enum ConfigStrategy { - Static(Config), +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DhcpConfig { + pub max_lease_duration: Option, + pub retry_config: RetryConfig, + /// Ignore NAKs. + pub ignore_naks: bool, + /// Server port config + pub server_port: u16, + /// Client port config + pub client_port: u16, +} + +impl Default for DhcpConfig { + fn default() -> Self { + Self { + max_lease_duration: Default::default(), + retry_config: Default::default(), + ignore_naks: Default::default(), + server_port: smoltcp::wire::DHCP_SERVER_PORT, + client_port: smoltcp::wire::DHCP_CLIENT_PORT, + } + } +} + +pub enum Config { + Static(StaticConfig), #[cfg(feature = "dhcpv4")] - Dhcp, + Dhcp(DhcpConfig), } pub struct Stack { @@ -80,7 +104,7 @@ pub struct Stack { struct Inner { device: D, link_up: bool, - config: Option, + config: Option, #[cfg(feature = "dhcpv4")] dhcp_socket: Option, } @@ -93,17 +117,16 @@ pub(crate) struct SocketStack { } impl Stack { - pub fn new( + pub fn new( mut device: D, - config: ConfigStrategy, - resources: &'static mut StackResources, + config: Config, + resources: &'static mut StackResources, random_seed: u64, ) -> Self { #[cfg(feature = "medium-ethernet")] let medium = device.capabilities().medium; let mut b = InterfaceBuilder::new(); - b = b.ip_addrs(Vec::::from_iter(resources.addresses)); b = b.random_seed(random_seed); #[cfg(feature = "medium-ethernet")] @@ -136,10 +159,12 @@ impl Stack { }; match config { - ConfigStrategy::Static(config) => inner.apply_config(&mut socket, config), + Config::Static(config) => inner.apply_config(&mut socket, config), #[cfg(feature = "dhcpv4")] - ConfigStrategy::Dhcp => { - let handle = socket.sockets.add(smoltcp::socket::dhcpv4::Socket::new()); + Config::Dhcp(config) => { + let mut dhcp_socket = smoltcp::socket::dhcpv4::Socket::new(); + inner.apply_dhcp_config(&mut dhcp_socket, config); + let handle = socket.sockets.add(dhcp_socket); inner.dhcp_socket = Some(handle); } } @@ -170,7 +195,7 @@ impl Stack { self.with(|_s, i| i.config.is_some()) } - pub fn config(&self) -> Option { + pub fn config(&self) -> Option { self.with(|_s, i| i.config.clone()) } @@ -185,7 +210,7 @@ impl Stack { } impl SocketStack { - #[allow(clippy::absurd_extreme_comparisons)] + #[allow(clippy::absurd_extreme_comparisons, dead_code)] pub fn get_local_port(&mut self) -> u16 { let res = self.next_local_port; self.next_local_port = if res >= LOCAL_PORT_MAX { LOCAL_PORT_MIN } else { res + 1 }; @@ -194,7 +219,7 @@ impl SocketStack { } impl Inner { - fn apply_config(&mut self, s: &mut SocketStack, config: Config) { + fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfig) { #[cfg(feature = "medium-ethernet")] let medium = self.device.capabilities().medium; @@ -220,6 +245,13 @@ impl Inner { self.config = Some(config) } + fn apply_dhcp_config(&self, socket: &mut smoltcp::socket::dhcpv4::Socket, config: DhcpConfig) { + socket.set_ignore_naks(config.ignore_naks); + socket.set_max_lease_duration(config.max_lease_duration); + socket.set_ports(config.server_port, config.client_port); + socket.set_retry_config(config.retry_config); + } + #[allow(unused)] // used only with dhcp fn unapply_config(&mut self, s: &mut SocketStack) { #[cfg(feature = "medium-ethernet")] @@ -280,7 +312,7 @@ impl Inner { None => {} Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s), Some(dhcpv4::Event::Configured(config)) => { - let config = Config { + let config = StaticConfig { address: config.address, gateway: config.router, dns_servers: config.dns_servers, diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs index e5f70452..1390bfc8 100644 --- a/examples/nrf52840/src/bin/usb_ethernet.rs +++ b/examples/nrf52840/src/bin/usb_ethernet.rs @@ -101,8 +101,8 @@ async fn main(spawner: Spawner) { let (runner, device) = class.into_embassy_net_device::(singleton!(NetState::new()), our_mac_addr); unwrap!(spawner.spawn(usb_ncm_task(runner))); - let config = embassy_net::ConfigStrategy::Dhcp; - //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { + let config = embassy_net::Config::Dhcp(Default::default()); + //let config = embassy_net::Config::Static(embassy_net::StaticConfig { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), @@ -115,12 +115,7 @@ async fn main(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); unwrap!(spawner.spawn(net_task(stack))); diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index d0aec874..e9b72712 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs @@ -92,8 +92,8 @@ async fn main(spawner: Spawner) { let (runner, device) = class.into_embassy_net_device::(singleton!(NetState::new()), our_mac_addr); unwrap!(spawner.spawn(usb_ncm_task(runner))); - let config = embassy_net::ConfigStrategy::Dhcp; - //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { + let config = embassy_net::Config::Dhcp(Default::default()); + //let config = embassy_net::Config::Static(embassy_net::StaticConfig { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), @@ -103,12 +103,7 @@ async fn main(spawner: Spawner) { let seed = 1234; // guaranteed random, chosen by a fair dice roll // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); unwrap!(spawner.spawn(net_task(stack))); diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 45b2a4a4..af1481e0 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -17,7 +17,7 @@ async-io = "1.6.0" env_logger = "0.9.0" futures = { version = "0.3.17" } log = "0.4.14" -nix = "0.22.1" +nix = "0.26.2" libc = "0.2.101" clap = { version = "3.0.0-beta.5", features = ["derive"] } rand_core = { version = "0.6.3", features = ["std"] } diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 9b1450b7..1ae39cac 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -1,9 +1,11 @@ #![feature(type_alias_impl_trait)] +use std::default::Default; + use clap::Parser; use embassy_executor::{Executor, Spawner}; use embassy_net::tcp::TcpSocket; -use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, Stack, StackResources}; +use embassy_net::{Config, Ipv4Address, Ipv4Cidr, Stack, StackResources}; use embedded_io::asynch::Write; use heapless::Vec; use log::*; @@ -48,13 +50,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - ConfigStrategy::Static(embassy_net::Config { + Config::Static(embassy_net::StaticConfig { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - ConfigStrategy::Dhcp + Config::Dhcp(Default::default()) }; // Generate random seed @@ -63,12 +65,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index 392a97f0..d1a8fe1e 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -3,7 +3,7 @@ use clap::Parser; use embassy_executor::{Executor, Spawner}; use embassy_net::udp::UdpSocket; -use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources}; +use embassy_net::{Config, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources}; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; @@ -47,13 +47,13 @@ async fn main_task(spawner: Spawner) { // Choose between dhcp or static ip let config = if opts.static_ip { - ConfigStrategy::Static(embassy_net::Config { + Config::Static(embassy_net::StaticConfig { address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24), dns_servers: Vec::new(), gateway: Some(Ipv4Address::new(192, 168, 69, 1)), }) } else { - ConfigStrategy::Dhcp + Config::Dhcp(Default::default()) }; // Generate random seed @@ -62,12 +62,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 224cc202..6f33a4f8 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -69,20 +69,15 @@ async fn main(spawner: Spawner) -> ! { 0, ); - let config = embassy_net::ConfigStrategy::Dhcp; - //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { + let config = embassy_net::Config::Dhcp(Default::default()); + //let config = embassy_net::Config::Static(embassy_net::StaticConfig { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), //}); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); // Launch network task unwrap!(spawner.spawn(net_task(&stack))); diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 551325ca..ad7fcc5c 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -70,20 +70,15 @@ async fn main(spawner: Spawner) -> ! { 0, ); - let config = embassy_net::ConfigStrategy::Dhcp; - //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { + let config = embassy_net::Config::Dhcp(Default::default()); + //let config = embassy_net::Config::Static(embassy_net::StaticConfig { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), //}); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); // Launch network task unwrap!(spawner.spawn(net_task(&stack))); diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 61a08ae1..7d3904f6 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -71,20 +71,15 @@ async fn main(spawner: Spawner) -> ! { 0, ); - let config = embassy_net::ConfigStrategy::Dhcp; - //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { + let config = embassy_net::Config::Dhcp(Default::default()); + //let config = embassy_net::Config::StaticConfig(embassy_net::Config { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), //}); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); // Launch network task unwrap!(spawner.spawn(net_task(&stack))); diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index b49329ea..ff44c2fc 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -98,8 +98,8 @@ async fn main(spawner: Spawner) { let (runner, device) = class.into_embassy_net_device::(singleton!(NetState::new()), our_mac_addr); unwrap!(spawner.spawn(usb_ncm_task(runner))); - let config = embassy_net::ConfigStrategy::Dhcp; - //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { + let config = embassy_net::Config::Dhcp(Default::default()); + //let config = embassy_net::Config::Static(embassy_net::StaticConfig { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), @@ -110,12 +110,7 @@ async fn main(spawner: Spawner) { let seed = rng.next_u64(); // Init network stack - let stack = &*singleton!(Stack::new( - device, - config, - singleton!(StackResources::<1, 2, 8>::new()), - seed - )); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); unwrap!(spawner.spawn(net_task(stack))); From 570ffab6703083f4e7f08a982afbf1c6de93b801 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 19 Jan 2023 13:30:51 +0100 Subject: [PATCH 3/5] net: poll returning false is not an error. No need to repoll. --- embassy-net/src/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index c419ec1f..b8e766b8 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -288,11 +288,7 @@ impl Inner { cx: Some(cx), inner: &mut self.device, }; - if !s.iface.poll(timestamp, &mut smoldev, &mut s.sockets) { - // If poll() returns error, it may not be done yet, so poll again later. - cx.waker().wake_by_ref(); - return; - } + s.iface.poll(timestamp, &mut smoldev, &mut s.sockets); // Update link up let old_link_up = self.link_up; From fe15a7beee5f948b1e4c1cb8ab8e5cc85efb4662 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 19 Jan 2023 14:40:58 +0100 Subject: [PATCH 4/5] net: allocate space for 2 sockets, needed for dhcp. --- examples/nrf52840/src/bin/usb_ethernet.rs | 2 +- examples/rp/src/bin/usb_ethernet.rs | 2 +- examples/std/src/bin/net.rs | 2 +- examples/std/src/bin/net_udp.rs | 2 +- examples/stm32f7/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth.rs | 2 +- examples/stm32h7/src/bin/eth_client.rs | 2 +- examples/stm32l5/src/bin/usb_ethernet.rs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs index 1390bfc8..a8d53e46 100644 --- a/examples/nrf52840/src/bin/usb_ethernet.rs +++ b/examples/nrf52840/src/bin/usb_ethernet.rs @@ -115,7 +115,7 @@ async fn main(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); unwrap!(spawner.spawn(net_task(stack))); diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index e9b72712..104b25d3 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs @@ -103,7 +103,7 @@ async fn main(spawner: Spawner) { let seed = 1234; // guaranteed random, chosen by a fair dice roll // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); unwrap!(spawner.spawn(net_task(stack))); diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 1ae39cac..451850d9 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -65,7 +65,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index d1a8fe1e..f1923f18 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -62,7 +62,7 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); // Launch network task spawner.spawn(net_task(stack)).unwrap(); diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index 6f33a4f8..571a6c1b 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -77,7 +77,7 @@ async fn main(spawner: Spawner) -> ! { //}); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); // Launch network task unwrap!(spawner.spawn(net_task(&stack))); diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index ad7fcc5c..cb245c32 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -78,7 +78,7 @@ async fn main(spawner: Spawner) -> ! { //}); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); // Launch network task unwrap!(spawner.spawn(net_task(&stack))); diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 7d3904f6..cce85a08 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -79,7 +79,7 @@ async fn main(spawner: Spawner) -> ! { //}); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); // Launch network task unwrap!(spawner.spawn(net_task(&stack))); diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index ff44c2fc..e5a46b06 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -110,7 +110,7 @@ async fn main(spawner: Spawner) { let seed = rng.next_u64(); // Init network stack - let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<1>::new()), seed)); + let stack = &*singleton!(Stack::new(device, config, singleton!(StackResources::<2>::new()), seed)); unwrap!(spawner.spawn(net_task(stack))); From 78c2c1709b8c111468fd7dd2ec1f3792d2fcea67 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 19 Jan 2023 14:41:39 +0100 Subject: [PATCH 5/5] net: update smoltcp. --- embassy-net/Cargo.toml | 2 +- embassy-net/src/lib.rs | 42 ++++++++++++++++++++---------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index a2ef3b4f..15cbb595 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -51,7 +51,7 @@ atomic-polyfill = { version = "1.0" } [dependencies.smoltcp] version = "0.8.0" git = "https://github.com/smoltcp-rs/smoltcp" -rev = "7b631c27cefe9b29e322a507c076b4156f477ee2" +rev = "5740b765749b95c18aace5de8dc21cab75ba33d4" default-features = false features = [ "proto-ipv4", diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index b8e766b8..8d0119f6 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -23,11 +23,9 @@ use embassy_sync::waitqueue::WakerRegistration; use embassy_time::{Instant, Timer}; use futures::pin_mut; use heapless::Vec; -#[cfg(feature = "medium-ethernet")] -use smoltcp::iface::Routes; #[cfg(feature = "dhcpv4")] use smoltcp::iface::SocketHandle; -use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage}; +use smoltcp::iface::{Interface, SocketSet, SocketStorage}; #[cfg(feature = "dhcpv4")] use smoltcp::socket::dhcpv4; use smoltcp::socket::dhcpv4::RetryConfig; @@ -111,7 +109,7 @@ struct Inner { pub(crate) struct SocketStack { pub(crate) sockets: SocketSet<'static>, - pub(crate) iface: Interface<'static>, + pub(crate) iface: Interface, pub(crate) waker: WakerRegistration, next_local_port: u16, } @@ -126,19 +124,20 @@ impl Stack { #[cfg(feature = "medium-ethernet")] let medium = device.capabilities().medium; - let mut b = InterfaceBuilder::new(); - b = b.random_seed(random_seed); - + let mut iface_cfg = smoltcp::iface::Config::new(); + iface_cfg.random_seed = random_seed; #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { - b = b.hardware_addr(HardwareAddress::Ethernet(EthernetAddress(device.ethernet_address()))); - b = b.routes(Routes::new()); + iface_cfg.hardware_addr = Some(HardwareAddress::Ethernet(EthernetAddress(device.ethernet_address()))); } - let iface = b.finalize(&mut DriverAdapter { - inner: &mut device, - cx: None, - }); + let iface = Interface::new( + iface_cfg, + &mut DriverAdapter { + inner: &mut device, + cx: None, + }, + ); let sockets = SocketSet::new(&mut resources.sockets[..]); @@ -226,7 +225,13 @@ impl Inner { debug!("Acquired IP configuration:"); debug!(" IP address: {}", config.address); - self.set_ipv4_addr(s, config.address); + s.iface.update_ip_addrs(|addrs| { + if addrs.is_empty() { + addrs.push(IpCidr::Ipv4(config.address)).unwrap(); + } else { + addrs[0] = IpCidr::Ipv4(config.address); + } + }); #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { @@ -258,7 +263,7 @@ impl Inner { let medium = self.device.capabilities().medium; debug!("Lost IP configuration"); - self.set_ipv4_addr(s, Ipv4Cidr::new(Ipv4Address::UNSPECIFIED, 0)); + s.iface.update_ip_addrs(|ip_addrs| ip_addrs.clear()); #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { s.iface.routes_mut().remove_default_ipv4_route(); @@ -266,13 +271,6 @@ impl Inner { self.config = None } - fn set_ipv4_addr(&mut self, s: &mut SocketStack, cidr: Ipv4Cidr) { - s.iface.update_ip_addrs(|addrs| { - let dest = addrs.iter_mut().next().unwrap(); - *dest = IpCidr::Ipv4(cidr); - }); - } - fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { s.waker.register(cx.waker());