From 17b6563f04f45e53c0657ed182beba62d051e8fd Mon Sep 17 00:00:00 2001 From: ivmarkov Date: Thu, 2 Jan 2025 11:19:55 +0200 Subject: [PATCH] Update to embassy-net 0.5 (#50) * Update to embassy-net 0.5 (#49) * Adapt changes to upstream embassy-net * Remove leftover imports And use the now release embassy-net. * Implement Readable for embassy-net 0.5 * Simplify the internal helpers --------- Co-authored-by: Shaw Drastin <168159404+showier-drastic@users.noreply.github.com> * fix a bunch of clippy errors with latest nightly * Ipv6 multicast support --------- Co-authored-by: Luca Barbato Co-authored-by: Shaw Drastin <168159404+showier-drastic@users.noreply.github.com> --- clippy.toml | 2 +- edge-nal-embassy/Cargo.toml | 14 +++- edge-nal-embassy/README.md | 3 +- edge-nal-embassy/src/dns.rs | 24 ++----- edge-nal-embassy/src/lib.rs | 47 ++----------- edge-nal-embassy/src/tcp.rs | 98 ++++++++++++++-------------- edge-nal-embassy/src/udp.rs | 127 +++++++++++++++++++----------------- 7 files changed, 137 insertions(+), 178 deletions(-) diff --git a/clippy.toml b/clippy.toml index f3c4fee..52df439 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -future-size-threshold = 200 +future-size-threshold = 300 diff --git a/edge-nal-embassy/Cargo.toml b/edge-nal-embassy/Cargo.toml index d3a4f37..63a3c83 100644 --- a/edge-nal-embassy/Cargo.toml +++ b/edge-nal-embassy/Cargo.toml @@ -11,13 +11,21 @@ categories = [ "embedded", "no-std::no-alloc", "asynchronous", - "network-programming" + "network-programming", ] [dependencies] embedded-io-async = { workspace = true } edge-nal = { workspace = true } heapless = { workspace = true } -# TODO: Do not require these features and conditionalize the code instead -embassy-net = { version = "0.4", features = ["tcp", "udp", "dns", "proto-ipv6", "medium-ethernet", "proto-ipv4", "igmp"] } +# Do not require these features and conditionalize the code instead +embassy-net = { version = "0.5", features = [ + "tcp", + "udp", + "dns", + "proto-ipv6", + "medium-ethernet", + "proto-ipv4", + "multicast", +] } embassy-futures = { workspace = true } diff --git a/edge-nal-embassy/README.md b/edge-nal-embassy/README.md index 3df5501..bde536b 100644 --- a/edge-nal-embassy/README.md +++ b/edge-nal-embassy/README.md @@ -14,9 +14,8 @@ All traits except `Readable` which - while implemented - panics if called. ### UDP -* All traits except `UdpConnect`. +* All traits except `UdpConnect`. * `MulticastV6` - while implemented - panics if `join_v6` / `leave_v6` are called. -* `Readable` - while implemented - panics if called. ### Raw sockets diff --git a/edge-nal-embassy/src/dns.rs b/edge-nal-embassy/src/dns.rs index 1d16cbb..865ff6b 100644 --- a/edge-nal-embassy/src/dns.rs +++ b/edge-nal-embassy/src/dns.rs @@ -4,37 +4,25 @@ use edge_nal::AddrType; use embassy_net::{ dns::{DnsQueryType, Error}, - driver::Driver, Stack, }; use embedded_io_async::ErrorKind; -use crate::to_net_addr; - /// A struct that implements the `Dns` trait from `edge-nal` -pub struct Dns<'a, D> -where - D: Driver + 'static, -{ - stack: &'a Stack, +pub struct Dns<'a> { + stack: Stack<'a>, } -impl<'a, D> Dns<'a, D> -where - D: Driver + 'static, -{ +impl<'a> Dns<'a> { /// Create a new `Dns` instance for the provided Embassy networking stack /// /// NOTE: If using DHCP, make sure it has reconfigured the stack to ensure the DNS servers are updated - pub fn new(stack: &'a Stack) -> Self { + pub fn new(stack: Stack<'a>) -> Self { Self { stack } } } -impl<'a, D> edge_nal::Dns for Dns<'a, D> -where - D: Driver + 'static, -{ +impl edge_nal::Dns for Dns<'_> { type Error = DnsError; async fn get_host_by_name( @@ -48,7 +36,7 @@ where }; let addrs = self.stack.dns_query(host, qtype).await?; if let Some(first) = addrs.first() { - Ok(to_net_addr(*first)) + Ok((*first).into()) } else { Err(Error::Failed.into()) } diff --git a/edge-nal-embassy/src/lib.rs b/edge-nal-embassy/src/lib.rs index 6761a3f..5fdc7c8 100644 --- a/edge-nal-embassy/src/lib.rs +++ b/edge-nal-embassy/src/lib.rs @@ -4,10 +4,10 @@ use core::cell::{Cell, UnsafeCell}; use core::mem::MaybeUninit; -use core::net::{IpAddr, SocketAddr}; +use core::net::SocketAddr; use core::ptr::NonNull; -use embassy_net::{IpAddress, IpEndpoint, IpListenEndpoint}; +use embassy_net::IpEndpoint; pub use dns::*; pub use tcp::*; @@ -25,6 +25,7 @@ pub(crate) struct Pool { impl Pool { #[allow(clippy::declare_interior_mutable_const)] const VALUE: Cell = Cell::new(false); + #[allow(clippy::declare_interior_mutable_const)] const UNINIT: UnsafeCell> = UnsafeCell::new(MaybeUninit::uninit()); const fn new() -> Self { @@ -59,7 +60,7 @@ impl Pool { } pub(crate) fn to_net_socket(socket: IpEndpoint) -> SocketAddr { - SocketAddr::new(to_net_addr(socket.addr), socket.port) + SocketAddr::new(socket.addr.into(), socket.port) } // pub(crate) fn to_net_socket2(socket: IpListenEndpoint) -> SocketAddr { @@ -71,43 +72,3 @@ pub(crate) fn to_net_socket(socket: IpEndpoint) -> SocketAddr { // socket.port, // ) // } - -pub(crate) fn to_emb_socket(socket: SocketAddr) -> IpEndpoint { - IpEndpoint { - addr: to_emb_addr(socket.ip()), - port: socket.port(), - } -} - -pub(crate) fn to_emb_bind_socket(socket: SocketAddr) -> IpListenEndpoint { - IpListenEndpoint { - addr: (!socket.ip().is_unspecified()).then(|| to_emb_addr(socket.ip())), - port: socket.port(), - } -} - -pub(crate) fn to_net_addr(addr: IpAddress) -> IpAddr { - match addr { - //#[cfg(feature = "proto-ipv4")] - IpAddress::Ipv4(addr) => addr.0.into(), - // #[cfg(not(feature = "proto-ipv4"))] - // IpAddr::V4(_) => panic!("ipv4 support not enabled"), - //#[cfg(feature = "proto-ipv6")] - IpAddress::Ipv6(addr) => addr.0.into(), - // #[cfg(not(feature = "proto-ipv6"))] - // IpAddr::V6(_) => panic!("ipv6 support not enabled"), - } -} - -pub(crate) fn to_emb_addr(addr: IpAddr) -> IpAddress { - match addr { - //#[cfg(feature = "proto-ipv4")] - IpAddr::V4(addr) => IpAddress::Ipv4(embassy_net::Ipv4Address::from_bytes(&addr.octets())), - // #[cfg(not(feature = "proto-ipv4"))] - // IpAddr::V4(_) => panic!("ipv4 support not enabled"), - //#[cfg(feature = "proto-ipv6")] - IpAddr::V6(addr) => IpAddress::Ipv6(embassy_net::Ipv6Address::from_bytes(&addr.octets())), - // #[cfg(not(feature = "proto-ipv6"))] - // IpAddr::V6(_) => panic!("ipv6 support not enabled"), - } -} diff --git a/edge-nal-embassy/src/tcp.rs b/edge-nal-embassy/src/tcp.rs index 8e86906..2575a68 100644 --- a/edge-nal-embassy/src/tcp.rs +++ b/edge-nal-embassy/src/tcp.rs @@ -6,37 +6,33 @@ use edge_nal::{Close, Readable, TcpBind, TcpConnect, TcpShutdown, TcpSplit}; use embassy_futures::join::join; -use embassy_net::driver::Driver; use embassy_net::tcp::{AcceptError, ConnectError, Error, TcpReader, TcpWriter}; use embassy_net::Stack; use embedded_io_async::{ErrorKind, ErrorType, Read, Write}; -use crate::{to_emb_bind_socket, to_emb_socket, to_net_socket, Pool}; +use crate::{to_net_socket, Pool}; /// A struct that implements the `TcpConnect` and `TcpBind` factory traits from `edge-nal` /// Capable of managing up to N concurrent connections with TX and RX buffers according to TX_SZ and RX_SZ. -pub struct Tcp<'d, D: Driver, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> -{ - stack: &'d Stack, +pub struct Tcp<'d, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> { + stack: Stack<'d>, buffers: &'d TcpBuffers, } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> - Tcp<'d, D, N, TX_SZ, RX_SZ> -{ +impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> Tcp<'d, N, TX_SZ, RX_SZ> { /// Create a new `Tcp` instance for the provided Embassy networking stack, using the provided TCP buffers /// /// Ensure that the number of buffers `N` fits within StackResources of /// [embassy_net::Stack], while taking into account the sockets used for DHCP, DNS, etc. else /// [smoltcp::iface::SocketSet] will panic with `adding a socket to a full SocketSet`. - pub fn new(stack: &'d Stack, buffers: &'d TcpBuffers) -> Self { + pub fn new(stack: Stack<'d>, buffers: &'d TcpBuffers) -> Self { Self { stack, buffers } } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpConnect - for Tcp<'d, D, N, TX_SZ, RX_SZ> +impl TcpConnect + for Tcp<'_, N, TX_SZ, RX_SZ> { type Error = TcpError; @@ -48,19 +44,17 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpC async fn connect(&self, remote: SocketAddr) -> Result, Self::Error> { let mut socket = TcpSocket::new(self.stack, self.buffers)?; - socket.socket.connect(to_emb_socket(remote)).await?; + socket.socket.connect(remote).await?; Ok(socket) } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpBind - for Tcp<'d, D, N, TX_SZ, RX_SZ> -{ +impl TcpBind for Tcp<'_, N, TX_SZ, RX_SZ> { type Error = TcpError; type Accept<'a> - = TcpAccept<'a, D, N, TX_SZ, RX_SZ> + = TcpAccept<'a, N, TX_SZ, RX_SZ> where Self: 'a; @@ -70,19 +64,13 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpB } /// Represents an acceptor for incoming TCP client connections. Implements the `TcpAccept` factory trait from `edge-nal` -pub struct TcpAccept< - 'd, - D: Driver, - const N: usize, - const TX_SZ: usize = 1024, - const RX_SZ: usize = 1024, -> { - stack: &'d Tcp<'d, D, N, TX_SZ, RX_SZ>, +pub struct TcpAccept<'d, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> { + stack: &'d Tcp<'d, N, TX_SZ, RX_SZ>, local: SocketAddr, } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> edge_nal::TcpAccept - for TcpAccept<'d, D, N, TX_SZ, RX_SZ> +impl edge_nal::TcpAccept + for TcpAccept<'_, N, TX_SZ, RX_SZ> { type Error = TcpError; @@ -94,7 +82,7 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> edge async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> { let mut socket = TcpSocket::new(self.stack.stack, self.stack.buffers)?; - socket.socket.accept(to_emb_bind_socket(self.local)).await?; + socket.socket.accept(self.local).await?; let local_endpoint = socket.socket.local_endpoint().unwrap(); @@ -111,8 +99,8 @@ pub struct TcpSocket<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> } impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpSocket<'d, N, TX_SZ, RX_SZ> { - fn new( - stack: &'d Stack, + fn new( + stack: Stack<'d>, stack_buffers: &'d TcpBuffers, ) -> Result { let mut socket_buffers = stack_buffers.pool.alloc().ok_or(TcpError::NoBuffers)?; @@ -171,8 +159,8 @@ impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpSocket<'d, N } } -impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> Drop - for TcpSocket<'d, N, TX_SZ, RX_SZ> +impl Drop + for TcpSocket<'_, N, TX_SZ, RX_SZ> { fn drop(&mut self) { unsafe { @@ -182,22 +170,22 @@ impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> Drop } } -impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> ErrorType - for TcpSocket<'d, N, TX_SZ, RX_SZ> +impl ErrorType + for TcpSocket<'_, N, TX_SZ, RX_SZ> { type Error = TcpError; } -impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> Read - for TcpSocket<'d, N, TX_SZ, RX_SZ> +impl Read + for TcpSocket<'_, N, TX_SZ, RX_SZ> { async fn read(&mut self, buf: &mut [u8]) -> Result { Ok(self.socket.read(buf).await?) } } -impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> Write - for TcpSocket<'d, N, TX_SZ, RX_SZ> +impl Write + for TcpSocket<'_, N, TX_SZ, RX_SZ> { async fn write(&mut self, buf: &[u8]) -> Result { Ok(self.socket.write(buf).await?) @@ -210,16 +198,17 @@ impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> Write } } -impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> Readable - for TcpSocket<'d, N, TX_SZ, RX_SZ> +impl Readable + for TcpSocket<'_, N, TX_SZ, RX_SZ> { async fn readable(&mut self) -> Result<(), Self::Error> { - panic!("Not implemented yet") + self.socket.wait_read_ready().await; + Ok(()) } } -impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpShutdown - for TcpSocket<'d, N, TX_SZ, RX_SZ> +impl TcpShutdown + for TcpSocket<'_, N, TX_SZ, RX_SZ> { async fn close(&mut self, what: Close) -> Result<(), Self::Error> { TcpSocket::close(self, what).await @@ -234,19 +223,20 @@ impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpShutdown /// Implements the `Read` trait from `embedded-io-async` pub struct TcpSocketRead<'a>(TcpReader<'a>); -impl<'a> ErrorType for TcpSocketRead<'a> { +impl ErrorType for TcpSocketRead<'_> { type Error = TcpError; } -impl<'a> Read for TcpSocketRead<'a> { +impl Read for TcpSocketRead<'_> { async fn read(&mut self, buf: &mut [u8]) -> Result { self.0.read(buf).await.map_err(TcpError::from) } } -impl<'a> Readable for TcpSocketRead<'a> { +impl Readable for TcpSocketRead<'_> { async fn readable(&mut self) -> Result<(), Self::Error> { - panic!("Not implemented yet") + self.0.wait_read_ready().await; + Ok(()) } } @@ -254,11 +244,11 @@ impl<'a> Readable for TcpSocketRead<'a> { /// Implements the `Write` trait from `embedded-io-async` pub struct TcpSocketWrite<'a>(TcpWriter<'a>); -impl<'a> ErrorType for TcpSocketWrite<'a> { +impl ErrorType for TcpSocketWrite<'_> { type Error = TcpError; } -impl<'a> Write for TcpSocketWrite<'a> { +impl Write for TcpSocketWrite<'_> { async fn write(&mut self, buf: &[u8]) -> Result { self.0.write(buf).await.map_err(TcpError::from) } @@ -268,8 +258,8 @@ impl<'a> Write for TcpSocketWrite<'a> { } } -impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpSplit - for TcpSocket<'d, N, TX_SZ, RX_SZ> +impl TcpSplit + for TcpSocket<'_, N, TX_SZ, RX_SZ> { type Read<'a> = TcpSocketRead<'a> @@ -332,6 +322,14 @@ pub struct TcpBuffers { pool: Pool<([u8; TX_SZ], [u8; RX_SZ]), N>, } +impl Default + for TcpBuffers +{ + fn default() -> Self { + Self::new() + } +} + impl TcpBuffers { /// Create a new `TcpBuffers` instance pub const fn new() -> Self { diff --git a/edge-nal-embassy/src/udp.rs b/edge-nal-embassy/src/udp.rs index 9f4f89f..5c2d10f 100644 --- a/edge-nal-embassy/src/udp.rs +++ b/edge-nal-embassy/src/udp.rs @@ -3,55 +3,53 @@ use core::ptr::NonNull; use edge_nal::{MulticastV4, MulticastV6, Readable, UdpBind, UdpReceive, UdpSend, UdpSplit}; -use embassy_net::driver::Driver; use embassy_net::udp::{BindError, PacketMetadata, RecvError, SendError}; use embassy_net::{MulticastError, Stack}; use embedded_io_async::{ErrorKind, ErrorType}; -use crate::{to_emb_addr, to_emb_bind_socket, to_emb_socket, to_net_socket, Pool}; +use crate::{to_net_socket, Pool}; /// A struct that implements the `UdpBind` factory trait from `edge-nal` /// Capable of managing up to N concurrent connections with TX and RX buffers according to TX_SZ and RX_SZ, and packet metadata according to `M`. pub struct Udp< 'd, - D: Driver, const N: usize, const TX_SZ: usize = 1500, const RX_SZ: usize = 1500, const M: usize = 2, > { - stack: &'d Stack, + stack: Stack<'d>, buffers: &'d UdpBuffers, } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> - Udp<'d, D, N, TX_SZ, RX_SZ, M> +impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> + Udp<'d, N, TX_SZ, RX_SZ, M> { /// Create a new `Udp` instance for the provided Embassy networking stack using the provided UDP buffers. /// /// Ensure that the number of buffers `N` fits within StackResources of /// [embassy_net::Stack], while taking into account the sockets used for DHCP, DNS, etc. else /// [smoltcp::iface::SocketSet] will panic with `adding a socket to a full SocketSet`. - pub fn new(stack: &'d Stack, buffers: &'d UdpBuffers) -> Self { + pub fn new(stack: Stack<'d>, buffers: &'d UdpBuffers) -> Self { Self { stack, buffers } } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpBind - for Udp<'d, D, N, TX_SZ, RX_SZ, M> +impl UdpBind + for Udp<'_, N, TX_SZ, RX_SZ, M> { type Error = UdpError; type Socket<'a> - = UdpSocket<'a, D, N, TX_SZ, RX_SZ, M> + = UdpSocket<'a, N, TX_SZ, RX_SZ, M> where Self: 'a; async fn bind(&self, local: SocketAddr) -> Result, Self::Error> { let mut socket = UdpSocket::new(self.stack, self.buffers)?; - socket.socket.bind(to_emb_bind_socket(local))?; + socket.socket.bind(local)?; Ok(socket) } @@ -59,26 +57,19 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, cons /// A UDP socket /// Implements the `UdpReceive` `UdpSend` and `UdpSplit` traits from `edge-nal` -pub struct UdpSocket< - 'd, - D: Driver, - const N: usize, - const TX_SZ: usize, - const RX_SZ: usize, - const M: usize, -> { - stack: &'d embassy_net::Stack, +pub struct UdpSocket<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> { + stack: embassy_net::Stack<'d>, socket: embassy_net::udp::UdpSocket<'d>, stack_buffers: &'d UdpBuffers, socket_buffers: NonNull<([u8; TX_SZ], [u8; RX_SZ])>, socket_meta_buffers: NonNull<([PacketMetadata; M], [PacketMetadata; M])>, } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> - UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> + UdpSocket<'d, N, TX_SZ, RX_SZ, M> { fn new( - stack: &'d Stack, + stack: Stack<'d>, stack_buffers: &'d UdpBuffers, ) -> Result { let mut socket_buffers = stack_buffers.pool.alloc().ok_or(UdpError::NoBuffers)?; @@ -102,8 +93,8 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, cons } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Drop - for UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl Drop + for UdpSocket<'_, N, TX_SZ, RX_SZ, M> { fn drop(&mut self) { unsafe { @@ -114,68 +105,69 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, cons } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> - ErrorType for UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl ErrorType + for UdpSocket<'_, N, TX_SZ, RX_SZ, M> { type Error = UdpError; } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> - UdpReceive for UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl UdpReceive + for UdpSocket<'_, N, TX_SZ, RX_SZ, M> { async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> { let (len, remote_endpoint) = self.socket.recv_from(buffer).await?; - Ok((len, to_net_socket(remote_endpoint))) + Ok((len, to_net_socket(remote_endpoint.endpoint))) } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpSend - for UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl UdpSend + for UdpSocket<'_, N, TX_SZ, RX_SZ, M> { async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> { - self.socket.send_to(data, to_emb_socket(remote)).await?; + self.socket.send_to(data, remote).await?; Ok(()) } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> - ErrorType for &UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl ErrorType + for &UdpSocket<'_, N, TX_SZ, RX_SZ, M> { type Error = UdpError; } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> - UdpReceive for &UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl UdpReceive + for &UdpSocket<'_, N, TX_SZ, RX_SZ, M> { async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> { let (len, remote_endpoint) = self.socket.recv_from(buffer).await?; - Ok((len, to_net_socket(remote_endpoint))) + Ok((len, to_net_socket(remote_endpoint.endpoint))) } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpSend - for &UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl UdpSend + for &UdpSocket<'_, N, TX_SZ, RX_SZ, M> { async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> { - self.socket.send_to(data, to_emb_socket(remote)).await?; + self.socket.send_to(data, remote).await?; Ok(()) } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Readable - for &UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl Readable + for &UdpSocket<'_, N, TX_SZ, RX_SZ, M> { async fn readable(&mut self) -> Result<(), Self::Error> { - panic!("Not implemented yet") + self.socket.wait_recv_ready().await; + Ok(()) } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpSplit - for UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl UdpSplit + for UdpSocket<'_, N, TX_SZ, RX_SZ, M> { type Receive<'a> = &'a Self @@ -192,8 +184,8 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, cons } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> - MulticastV4 for UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl MulticastV4 + for UdpSocket<'_, N, TX_SZ, RX_SZ, M> { async fn join_v4( &mut self, @@ -201,8 +193,7 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, cons _interface: Ipv4Addr, ) -> Result<(), Self::Error> { self.stack - .join_multicast_group(to_emb_addr(IpAddr::V4(multicast_addr))) - .await?; + .join_multicast_group(IpAddr::V4(multicast_addr))?; Ok(()) } @@ -213,38 +204,44 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, cons _interface: Ipv4Addr, ) -> Result<(), Self::Error> { self.stack - .leave_multicast_group(to_emb_addr(IpAddr::V4(multicast_addr))) - .await?; + .leave_multicast_group(IpAddr::V4(multicast_addr))?; Ok(()) } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> - MulticastV6 for UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl MulticastV6 + for UdpSocket<'_, N, TX_SZ, RX_SZ, M> { async fn join_v6( &mut self, - _multicast_addr: Ipv6Addr, + multicast_addr: Ipv6Addr, _interface: u32, ) -> Result<(), Self::Error> { - panic!("Joining an Ipv6 multicast group is not supported yet") + self.stack + .join_multicast_group(IpAddr::V6(multicast_addr))?; + + Ok(()) } async fn leave_v6( &mut self, - _multicast_addr: Ipv6Addr, + multicast_addr: Ipv6Addr, _interface: u32, ) -> Result<(), Self::Error> { - panic!("Leaving an Ipv6 multicast group is not supported yet") + self.stack + .leave_multicast_group(IpAddr::V6(multicast_addr))?; + + Ok(()) } } -impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Readable - for UdpSocket<'d, D, N, TX_SZ, RX_SZ, M> +impl Readable + for UdpSocket<'_, N, TX_SZ, RX_SZ, M> { async fn readable(&mut self) -> Result<(), Self::Error> { - panic!("Not implemented yet") + self.socket.wait_recv_ready().await; + Ok(()) } } @@ -307,6 +304,14 @@ pub struct UdpBuffers, } +impl Default + for UdpBuffers +{ + fn default() -> Self { + Self::new() + } +} + impl UdpBuffers {