From c257893da9f31337861a59e71022609e1bbaad95 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 26 Nov 2021 04:12:14 +0100 Subject: [PATCH] net: update smoltcp --- embassy-net/Cargo.toml | 4 +-- embassy-net/src/config/dhcp.rs | 19 +++++------- embassy-net/src/config/mod.rs | 5 ++-- embassy-net/src/config/statik.rs | 9 ++---- embassy-net/src/lib.rs | 3 +- embassy-net/src/stack.rs | 31 +++++++------------- embassy-net/src/tcp_socket.rs | 50 +++++++++++++++++--------------- examples/std/src/bin/net.rs | 2 +- examples/std/src/serial_port.rs | 2 +- examples/std/src/tuntap.rs | 3 +- 10 files changed, 55 insertions(+), 73 deletions(-) diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 4b932ceb..a62bdde4 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -34,8 +34,8 @@ futures = { version = "0.3.17", default-features = false, features = atomic-pool = "0.2.1" [dependencies.smoltcp] -git = "https://github.com/bobmcwhirter/smoltcp" -rev = "faf81d21daae16b650b16e59a8422a8283e8a302" +git = "https://github.com/smoltcp-rs/smoltcp" +rev = "453183f8a1d16daf2f6739b565d3dc7ac93b662e" default-features = false features = [ "proto-ipv4", diff --git a/embassy-net/src/config/dhcp.rs b/embassy-net/src/config/dhcp.rs index 8bbcd817..298657ed 100644 --- a/embassy-net/src/config/dhcp.rs +++ b/embassy-net/src/config/dhcp.rs @@ -1,10 +1,11 @@ use heapless::Vec; -use smoltcp::socket::{Dhcpv4Event, Dhcpv4Socket, SocketHandle}; +use smoltcp::iface::SocketHandle; +use smoltcp::socket::{Dhcpv4Event, Dhcpv4Socket}; use smoltcp::time::Instant; use super::*; use crate::device::LinkState; -use crate::{Interface, SocketSet}; +use crate::Interface; pub struct DhcpConfigurator { handle: Option, @@ -17,20 +18,16 @@ impl DhcpConfigurator { } impl Configurator for DhcpConfigurator { - fn poll( - &mut self, - iface: &mut Interface, - sockets: &mut SocketSet, - _timestamp: Instant, - ) -> Event { + fn poll(&mut self, iface: &mut Interface, _timestamp: Instant) -> Event { if self.handle.is_none() { - let handle = sockets.add(Dhcpv4Socket::new()); + let handle = iface.add_socket(Dhcpv4Socket::new()); self.handle = Some(handle) } - let mut socket = sockets.get::(self.handle.unwrap()); - let link_up = iface.device_mut().device.link_state() == LinkState::Up; + + let socket = iface.get_socket::(self.handle.unwrap()); + if !link_up { socket.reset(); return Event::Deconfigured; diff --git a/embassy-net/src/config/mod.rs b/embassy-net/src/config/mod.rs index 0f1886ae..eb1b6636 100644 --- a/embassy-net/src/config/mod.rs +++ b/embassy-net/src/config/mod.rs @@ -2,7 +2,7 @@ use heapless::Vec; use smoltcp::time::Instant; use smoltcp::wire::{Ipv4Address, Ipv4Cidr}; -use crate::{Interface, SocketSet}; +use crate::Interface; mod statik; pub use statik::StaticConfigurator; @@ -31,6 +31,5 @@ pub struct Config { } pub trait Configurator { - fn poll(&mut self, iface: &mut Interface, sockets: &mut SocketSet, timestamp: Instant) - -> Event; + fn poll(&mut self, iface: &mut Interface, timestamp: Instant) -> Event; } diff --git a/embassy-net/src/config/statik.rs b/embassy-net/src/config/statik.rs index 9a530717..e614db73 100644 --- a/embassy-net/src/config/statik.rs +++ b/embassy-net/src/config/statik.rs @@ -1,7 +1,7 @@ use smoltcp::time::Instant; use super::*; -use crate::{Interface, SocketSet}; +use crate::Interface; pub struct StaticConfigurator { config: Config, @@ -18,12 +18,7 @@ impl StaticConfigurator { } impl Configurator for StaticConfigurator { - fn poll( - &mut self, - _iface: &mut Interface, - _sockets: &mut SocketSet, - _timestamp: Instant, - ) -> Event { + fn poll(&mut self, _iface: &mut Interface, _timestamp: Instant) -> Event { if self.returned { Event::NoChange } else { diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index db2a7ebd..30717955 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -26,7 +26,6 @@ pub use tcp_socket::TcpSocket; pub use smoltcp::phy::{DeviceCapabilities, Medium}; pub use smoltcp::time::Duration as SmolDuration; pub use smoltcp::time::Instant as SmolInstant; -pub use smoltcp::wire::{IpAddress, IpCidr, Ipv4Address, Ipv4Cidr}; +pub use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr, Ipv4Address, Ipv4Cidr}; pub type Interface = smoltcp::iface::Interface<'static, device::DeviceAdapter>; -pub type SocketSet = smoltcp::socket::SocketSet<'static>; pub use smoltcp::{Error, Result}; diff --git a/embassy-net/src/stack.rs b/embassy-net/src/stack.rs index 4faf9495..610260a8 100644 --- a/embassy-net/src/stack.rs +++ b/embassy-net/src/stack.rs @@ -7,31 +7,31 @@ use embassy::time::{Instant, Timer}; use embassy::waitqueue::WakerRegistration; use futures::pin_mut; use smoltcp::iface::InterfaceBuilder; +use smoltcp::iface::SocketStorage; #[cfg(feature = "medium-ethernet")] use smoltcp::iface::{Neighbor, NeighborCache, Route, Routes}; #[cfg(feature = "medium-ethernet")] use smoltcp::phy::Device as _; #[cfg(feature = "medium-ethernet")] use smoltcp::phy::Medium; -use smoltcp::socket::SocketSetItem; use smoltcp::time::Instant as SmolInstant; #[cfg(feature = "medium-ethernet")] use smoltcp::wire::EthernetAddress; #[cfg(feature = "medium-ethernet")] use smoltcp::wire::IpAddress; -use smoltcp::wire::{IpCidr, Ipv4Address, Ipv4Cidr}; +use smoltcp::wire::{HardwareAddress, IpCidr, Ipv4Address, Ipv4Cidr}; use crate::config::Configurator; use crate::config::Event; use crate::device::{Device, DeviceAdapter, LinkState}; -use crate::{Interface, SocketSet}; +use crate::Interface; const LOCAL_PORT_MIN: u16 = 1025; const LOCAL_PORT_MAX: u16 = 65535; pub struct StackResources { addresses: [IpCidr; ADDR], - sockets: [Option>; SOCK], + sockets: [SocketStorage<'static>; SOCK], #[cfg(feature = "medium-ethernet")] routes: [Option<(IpCidr, Route)>; 1], @@ -43,11 +43,9 @@ impl StackResources { pub fn new() -> Self { - const NONE_SOCKET: Option> = None; - Self { addresses: [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 32); ADDR], - sockets: [NONE_SOCKET; SOCK], + sockets: [SocketStorage::EMPTY; SOCK], #[cfg(feature = "medium-ethernet")] routes: [None; 1], #[cfg(feature = "medium-ethernet")] @@ -59,8 +57,7 @@ impl static STACK: ThreadModeMutex>> = ThreadModeMutex::new(RefCell::new(None)); pub(crate) struct Stack { - iface: Interface, - pub sockets: SocketSet, + pub iface: Interface, link_up: bool, config_up: bool, next_local_port: u16, @@ -94,10 +91,7 @@ impl Stack { #[cfg(feature = "medium-ethernet")] let medium = self.iface.device().capabilities().medium; - match self - .configurator - .poll(&mut self.iface, &mut self.sockets, timestamp) - { + match self.configurator.poll(&mut self.iface, timestamp) { Event::NoChange => {} Event::Configured(config) => { debug!("Acquired IP configuration:"); @@ -141,7 +135,7 @@ impl Stack { self.waker.register(cx.waker()); let timestamp = instant_to_smoltcp(Instant::now()); - if self.iface.poll(&mut self.sockets, timestamp).is_err() { + if self.iface.poll(timestamp).is_err() { // If poll() returns error, it may not be done yet, so poll again later. cx.waker().wake_by_ref(); return; @@ -160,7 +154,7 @@ impl Stack { self.poll_configurator(timestamp) } - if let Some(poll_at) = self.iface.poll_at(&self.sockets, timestamp) { + if let Some(poll_at) = self.iface.poll_at(timestamp) { let t = Timer::at(instant_from_smoltcp(poll_at)); pin_mut!(t); if t.poll(cx).is_ready() { @@ -194,20 +188,18 @@ pub fn init( [0, 0, 0, 0, 0, 0] }; - let mut b = InterfaceBuilder::new(DeviceAdapter::new(device)); + let mut b = InterfaceBuilder::new(DeviceAdapter::new(device), &mut resources.sockets[..]); b = b.ip_addrs(&mut resources.addresses[..]); #[cfg(feature = "medium-ethernet")] if medium == Medium::Ethernet { - b = b.ethernet_addr(EthernetAddress(ethernet_addr)); + b = b.hardware_addr(HardwareAddress::Ethernet(EthernetAddress(ethernet_addr))); b = b.neighbor_cache(NeighborCache::new(&mut resources.neighbor_cache[..])); b = b.routes(Routes::new(&mut resources.routes[..])); } let iface = b.finalize(); - let sockets = SocketSet::new(&mut resources.sockets[..]); - let local_port = loop { let mut res = [0u8; 2]; rand(&mut res); @@ -219,7 +211,6 @@ pub fn init( let stack = Stack { iface, - sockets, link_up: false, config_up: false, configurator, diff --git a/embassy-net/src/tcp_socket.rs b/embassy-net/src/tcp_socket.rs index bb1b626e..39bdd0c1 100644 --- a/embassy-net/src/tcp_socket.rs +++ b/embassy-net/src/tcp_socket.rs @@ -4,7 +4,7 @@ use core::pin::Pin; use core::task::{Context, Poll}; use embassy::io; use embassy::io::{AsyncBufRead, AsyncWrite}; -use smoltcp::socket::SocketHandle; +use smoltcp::iface::{Context as SmolContext, SocketHandle}; use smoltcp::socket::TcpSocket as SyncTcpSocket; use smoltcp::socket::{TcpSocketBuffer, TcpState}; use smoltcp::time::Duration; @@ -25,7 +25,7 @@ impl<'a> TcpSocket<'a> { let handle = Stack::with(|stack| { let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) }; let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) }; - stack.sockets.add(SyncTcpSocket::new( + stack.iface.add_socket(SyncTcpSocket::new( TcpSocketBuffer::new(rx_buffer), TcpSocketBuffer::new(tx_buffer), )) @@ -42,10 +42,10 @@ impl<'a> TcpSocket<'a> { T: Into, { let local_port = Stack::with(|stack| stack.get_local_port()); - self.with(|s| s.connect(remote_endpoint, local_port))?; + self.with(|s, cx| s.connect(cx, remote_endpoint, local_port))?; futures::future::poll_fn(|cx| { - self.with(|s| match s.state() { + self.with(|s, _| match s.state() { TcpState::Closed | TcpState::TimeWait => Poll::Ready(Err(Error::Unaddressable)), TcpState::Listen => Poll::Ready(Err(Error::Illegal)), TcpState::SynSent | TcpState::SynReceived => { @@ -62,10 +62,10 @@ impl<'a> TcpSocket<'a> { where T: Into, { - self.with(|s| s.listen(local_endpoint))?; + self.with(|s, _| s.listen(local_endpoint))?; futures::future::poll_fn(|cx| { - self.with(|s| match s.state() { + self.with(|s, _| match s.state() { TcpState::Closed | TcpState::TimeWait => Poll::Ready(Err(Error::Unaddressable)), TcpState::Listen => Poll::Ready(Ok(())), TcpState::SynSent | TcpState::SynReceived => { @@ -79,50 +79,52 @@ impl<'a> TcpSocket<'a> { } pub fn set_timeout(&mut self, duration: Option) { - self.with(|s| s.set_timeout(duration)) + self.with(|s, _| s.set_timeout(duration)) } pub fn set_keep_alive(&mut self, interval: Option) { - self.with(|s| s.set_keep_alive(interval)) + self.with(|s, _| s.set_keep_alive(interval)) } pub fn set_hop_limit(&mut self, hop_limit: Option) { - self.with(|s| s.set_hop_limit(hop_limit)) + self.with(|s, _| s.set_hop_limit(hop_limit)) } pub fn local_endpoint(&self) -> IpEndpoint { - self.with(|s| s.local_endpoint()) + self.with(|s, _| s.local_endpoint()) } pub fn remote_endpoint(&self) -> IpEndpoint { - self.with(|s| s.remote_endpoint()) + self.with(|s, _| s.remote_endpoint()) } pub fn state(&self) -> TcpState { - self.with(|s| s.state()) + self.with(|s, _| s.state()) } pub fn close(&mut self) { - self.with(|s| s.close()) + self.with(|s, _| s.close()) } pub fn abort(&mut self) { - self.with(|s| s.abort()) + self.with(|s, _| s.abort()) } pub fn may_send(&self) -> bool { - self.with(|s| s.may_send()) + self.with(|s, _| s.may_send()) } pub fn may_recv(&self) -> bool { - self.with(|s| s.may_recv()) + self.with(|s, _| s.may_recv()) } - fn with(&self, f: impl FnOnce(&mut SyncTcpSocket) -> R) -> R { + fn with(&self, f: impl FnOnce(&mut SyncTcpSocket, &mut SmolContext) -> R) -> R { Stack::with(|stack| { let res = { - let mut s = stack.sockets.get::(self.handle); - f(&mut *s) + let (s, cx) = stack + .iface + .get_socket_and_context::(self.handle); + f(s, cx) }; stack.wake(); res @@ -138,7 +140,7 @@ fn to_ioerr(_err: Error) -> io::Error { impl<'a> Drop for TcpSocket<'a> { fn drop(&mut self) { Stack::with(|stack| { - stack.sockets.remove(self.handle); + stack.iface.remove_socket(self.handle); }) } } @@ -148,10 +150,10 @@ impl<'a> AsyncBufRead for TcpSocket<'a> { self: Pin<&'z mut Self>, cx: &mut Context<'_>, ) -> Poll> { - self.with(|socket| match socket.peek(1 << 30) { + self.with(|s, _| match s.peek(1 << 30) { // No data ready Ok(buf) if buf.is_empty() => { - socket.register_recv_waker(cx.waker()); + s.register_recv_waker(cx.waker()); Poll::Pending } // Data ready! @@ -176,7 +178,7 @@ impl<'a> AsyncBufRead for TcpSocket<'a> { // even if we're "reading" 0 bytes. return; } - self.with(|s| s.recv(|_| (amt, ()))).unwrap() + self.with(|s, _| s.recv(|_| (amt, ()))).unwrap() } } @@ -186,7 +188,7 @@ impl<'a> AsyncWrite for TcpSocket<'a> { cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { - self.with(|s| match s.send_slice(buf) { + self.with(|s, _| match s.send_slice(buf) { // Not ready to send (no space in the tx buffer) Ok(0) => { s.register_send_waker(cx.waker()); diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 8abcc586..be78e3a7 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -67,7 +67,7 @@ async fn main_task(spawner: Spawner) { socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); - let remote_endpoint = (Ipv4Address::new(192, 168, 69, 74), 8000); + let remote_endpoint = (Ipv4Address::new(192, 168, 69, 100), 8000); info!("connecting to {:?}...", remote_endpoint); let r = socket.connect(remote_endpoint).await; if let Err(e) = r { diff --git a/examples/std/src/serial_port.rs b/examples/std/src/serial_port.rs index aadaeb81..6825cbeb 100644 --- a/examples/std/src/serial_port.rs +++ b/examples/std/src/serial_port.rs @@ -9,7 +9,7 @@ pub struct SerialPort { } impl SerialPort { - pub fn new<'a, P: ?Sized + nix::NixPath>( + pub fn new( path: &P, baudrate: termios::BaudRate, ) -> io::Result { diff --git a/examples/std/src/tuntap.rs b/examples/std/src/tuntap.rs index 4d30118f..7ab08539 100644 --- a/examples/std/src/tuntap.rs +++ b/examples/std/src/tuntap.rs @@ -170,8 +170,7 @@ impl crate::Device for TunTapDevice { Err(e) if e.kind() == io::ErrorKind::WouldBlock => { let ready = if let Some(w) = self.waker.as_ref() { let mut cx = Context::from_waker(w); - let ready = self.device.poll_readable(&mut cx).is_ready(); - ready + self.device.poll_readable(&mut cx).is_ready() } else { false };