diff --git a/edge-nal-embassy/Cargo.toml b/edge-nal-embassy/Cargo.toml index d3a4f37..5ad451f 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.4", features = [ + "tcp", + "udp", + "dns", + "proto-ipv6", + "medium-ethernet", + "proto-ipv4", + "multicast", +] } embassy-futures = { workspace = true } diff --git a/edge-nal-embassy/src/dns.rs b/edge-nal-embassy/src/dns.rs index 1d16cbb..a4688b6 100644 --- a/edge-nal-embassy/src/dns.rs +++ b/edge-nal-embassy/src/dns.rs @@ -12,29 +12,20 @@ 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<'a> edge_nal::Dns for Dns<'a> { type Error = DnsError; async fn get_host_by_name( diff --git a/edge-nal-embassy/src/lib.rs b/edge-nal-embassy/src/lib.rs index 6761a3f..0f99f6e 100644 --- a/edge-nal-embassy/src/lib.rs +++ b/edge-nal-embassy/src/lib.rs @@ -89,11 +89,11 @@ pub(crate) fn to_emb_bind_socket(socket: SocketAddr) -> IpListenEndpoint { pub(crate) fn to_net_addr(addr: IpAddress) -> IpAddr { match addr { //#[cfg(feature = "proto-ipv4")] - IpAddress::Ipv4(addr) => addr.0.into(), + IpAddress::Ipv4(addr) => addr.into(), // #[cfg(not(feature = "proto-ipv4"))] // IpAddr::V4(_) => panic!("ipv4 support not enabled"), //#[cfg(feature = "proto-ipv6")] - IpAddress::Ipv6(addr) => addr.0.into(), + IpAddress::Ipv6(addr) => addr.into(), // #[cfg(not(feature = "proto-ipv6"))] // IpAddr::V6(_) => panic!("ipv6 support not enabled"), } @@ -102,11 +102,11 @@ pub(crate) fn to_net_addr(addr: IpAddress) -> IpAddr { 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())), + IpAddr::V4(addr) => IpAddress::Ipv4(addr), // #[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())), + IpAddr::V6(addr) => IpAddress::Ipv6(addr), // #[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..c53ab57 100644 --- a/edge-nal-embassy/src/tcp.rs +++ b/edge-nal-embassy/src/tcp.rs @@ -16,27 +16,24 @@ use crate::{to_emb_bind_socket, to_emb_socket, 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpConnect + for Tcp<'d, N, TX_SZ, RX_SZ> { type Error = TcpError; @@ -54,13 +51,13 @@ impl<'d, D: Driver, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpC } } -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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpBind + for Tcp<'d, 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 +67,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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> edge_nal::TcpAccept + for TcpAccept<'d, N, TX_SZ, RX_SZ> { type Error = TcpError; @@ -111,8 +102,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)?; diff --git a/edge-nal-embassy/src/udp.rs b/edge-nal-embassy/src/udp.rs index 9f4f89f..7e9e6e7 100644 --- a/edge-nal-embassy/src/udp.rs +++ b/edge-nal-embassy/src/udp.rs @@ -15,36 +15,35 @@ use crate::{to_emb_addr, to_emb_bind_socket, to_emb_socket, to_net_socket, Pool} /// 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpBind + for Udp<'d, 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; @@ -59,26 +58,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 +94,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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Drop + for UdpSocket<'d, N, TX_SZ, RX_SZ, M> { fn drop(&mut self) { unsafe { @@ -114,24 +106,24 @@ 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> ErrorType + for UdpSocket<'d, 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpReceive + for UdpSocket<'d, 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpSend + for UdpSocket<'d, 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?; @@ -140,24 +132,24 @@ 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> ErrorType + for &UdpSocket<'d, 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpReceive + for &UdpSocket<'d, 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpSend + for &UdpSocket<'d, 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?; @@ -166,16 +158,16 @@ 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> Readable - for &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> Readable + for &UdpSocket<'d, N, TX_SZ, RX_SZ, M> { async fn readable(&mut self) -> Result<(), Self::Error> { panic!("Not implemented yet") } } -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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> UdpSplit + for UdpSocket<'d, 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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> MulticastV4 + for UdpSocket<'d, 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(to_emb_addr(IpAddr::V4(multicast_addr)))?; Ok(()) } @@ -213,15 +204,14 @@ 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(to_emb_addr(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<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> MulticastV6 + for UdpSocket<'d, N, TX_SZ, RX_SZ, M> { async fn join_v6( &mut self, @@ -240,8 +230,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> Readable - for 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> Readable + for UdpSocket<'d, N, TX_SZ, RX_SZ, M> { async fn readable(&mut self) -> Result<(), Self::Error> { panic!("Not implemented yet")