Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Adapt changes to upstream embassy-net #35

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions edge-nal-embassy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
19 changes: 5 additions & 14 deletions edge-nal-embassy/src/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<D>,
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<D>) -> 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(
Expand Down
8 changes: 4 additions & 4 deletions edge-nal-embassy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
}
Expand All @@ -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"),
}
Expand Down
39 changes: 15 additions & 24 deletions edge-nal-embassy/src/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<D>,
pub struct Tcp<'d, const N: usize, const TX_SZ: usize = 1024, const RX_SZ: usize = 1024> {
stack: Stack<'d>,
buffers: &'d TcpBuffers<N, TX_SZ, RX_SZ>,
}

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<N> 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<D>, buffers: &'d TcpBuffers<N, TX_SZ, RX_SZ>) -> Self {
pub fn new(stack: Stack<'d>, buffers: &'d TcpBuffers<N, TX_SZ, RX_SZ>) -> 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;

Expand All @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -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<D: Driver>(
stack: &'d Stack<D>,
fn new(
stack: Stack<'d>,
stack_buffers: &'d TcpBuffers<N, TX_SZ, RX_SZ>,
) -> Result<Self, TcpError> {
let mut socket_buffers = stack_buffers.pool.alloc().ok_or(TcpError::NoBuffers)?;
Expand Down
90 changes: 40 additions & 50 deletions edge-nal-embassy/src/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,31 @@ 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<D>,
stack: Stack<'d>,
buffers: &'d UdpBuffers<N, TX_SZ, RX_SZ, M>,
}

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.
pub fn new(stack: &'d Stack<D>, buffers: &'d UdpBuffers<N, TX_SZ, RX_SZ, M>) -> Self {
pub fn new(stack: Stack<'d>, buffers: &'d UdpBuffers<N, TX_SZ, RX_SZ, M>) -> 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;

Expand All @@ -55,26 +54,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<D>,
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<N, TX_SZ, RX_SZ, M>,
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<D>,
stack: Stack<'d>,
stack_buffers: &'d UdpBuffers<N, TX_SZ, RX_SZ, M>,
) -> Result<Self, UdpError> {
let mut socket_buffers = stack_buffers.pool.alloc().ok_or(UdpError::NoBuffers)?;
Expand All @@ -98,8 +90,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 {
Expand All @@ -110,24 +102,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?;
Expand All @@ -136,24 +128,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?;
Expand All @@ -162,16 +154,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
Expand All @@ -188,17 +180,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>
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,
multicast_addr: Ipv4Addr,
_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(())
}
Expand All @@ -209,15 +200,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,
Expand All @@ -236,8 +226,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")
Expand Down
Loading