Skip to content

Commit 2950851

Browse files
committed
Option to only select a subset of the embassy-net/smoltcp features
1 parent b98764d commit 2950851

File tree

4 files changed

+140
-53
lines changed

4 files changed

+140
-53
lines changed

edge-nal-embassy/Cargo.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,22 @@ categories = [
1515
]
1616

1717
[features]
18+
default = ["proto-ipv4", "proto-ipv6", "medium-ethernet", "dns", "udp", "tcp", "multicast"]
1819
defmt = ["dep:defmt", "heapless/defmt-03", "embassy-net/defmt"]
20+
proto-ipv4 = ["embassy-net/proto-ipv4"]
21+
proto-ipv6 = ["embassy-net/proto-ipv6"]
22+
medium-ethernet = ["embassy-net/medium-ethernet"]
23+
medium-ip = ["embassy-net/medium-ip"]
24+
dns = ["embassy-net/dns"]
25+
udp = ["embassy-net/udp"]
26+
tcp = ["embassy-net/tcp"]
27+
multicast = ["embassy-net/multicast"]
1928

2029
[dependencies]
2130
log = { version = "0.4", default-features = false, optional = true }
2231
defmt = { version = "0.3", optional = true }
2332
embedded-io-async = { workspace = true }
2433
edge-nal = { workspace = true }
2534
heapless = { workspace = true }
26-
# Do not require these features and conditionalize the code instead
27-
embassy-net = { version = "0.6", features = [
28-
"tcp",
29-
"udp",
30-
"dns",
31-
"proto-ipv6",
32-
"medium-ethernet",
33-
"proto-ipv4",
34-
"multicast",
35-
] }
35+
embassy-net = "0.6"
3636
embassy-futures = { workspace = true }

edge-nal-embassy/src/lib.rs

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,26 @@
44

55
use core::cell::{Cell, UnsafeCell};
66
use core::mem::MaybeUninit;
7-
use core::net::SocketAddr;
7+
use core::net::{IpAddr, SocketAddr};
88
use core::ptr::NonNull;
99

10-
use embassy_net::{IpEndpoint, IpListenEndpoint};
10+
use embassy_net::{IpAddress, IpEndpoint, IpListenEndpoint};
1111

12+
#[cfg(feature = "dns")]
1213
pub use dns::*;
14+
#[cfg(feature = "tcp")]
1315
pub use tcp::*;
16+
#[cfg(feature = "udp")]
1417
pub use udp::*;
1518

1619
// This mod MUST go first, so that the others see its macros.
1720
pub(crate) mod fmt;
1821

22+
#[cfg(feature = "dns")]
1923
mod dns;
24+
#[cfg(feature = "tcp")]
2025
mod tcp;
26+
#[cfg(feature = "udp")]
2127
mod udp;
2228

2329
pub(crate) struct Pool<T, const N: usize> {
@@ -66,26 +72,33 @@ pub(crate) fn to_net_socket(socket: IpEndpoint) -> SocketAddr {
6672
SocketAddr::new(socket.addr.into(), socket.port)
6773
}
6874

69-
// pub(crate) fn to_net_socket2(socket: IpListenEndpoint) -> SocketAddr {
70-
// SocketAddr::new(
71-
// socket
72-
// .addr
73-
// .map(to_net_addr)
74-
// .unwrap_or(IpAddr::V6(Ipv6Addr::UNSPECIFIED)),
75-
// socket.port,
76-
// )
77-
// }
78-
79-
pub(crate) fn to_emb_socket(socket: SocketAddr) -> IpEndpoint {
80-
IpEndpoint {
81-
addr: socket.ip().into(),
75+
pub(crate) fn to_emb_socket(socket: SocketAddr) -> Option<IpEndpoint> {
76+
Some(IpEndpoint {
77+
addr: to_emb_addr(socket.ip())?,
8278
port: socket.port(),
83-
}
79+
})
8480
}
8581

86-
pub(crate) fn to_emb_bind_socket(socket: SocketAddr) -> IpListenEndpoint {
87-
IpListenEndpoint {
88-
addr: (!socket.ip().is_unspecified()).then(|| socket.ip().into()),
82+
pub(crate) fn to_emb_bind_socket(socket: SocketAddr) -> Option<IpListenEndpoint> {
83+
let addr = if socket.ip().is_unspecified() {
84+
None
85+
} else {
86+
Some(to_emb_addr(socket.ip())?)
87+
};
88+
89+
Some(IpListenEndpoint {
90+
addr,
8991
port: socket.port(),
92+
})
93+
}
94+
95+
pub(crate) fn to_emb_addr(addr: IpAddr) -> Option<IpAddress> {
96+
match addr {
97+
#[cfg(feature = "proto-ipv4")]
98+
IpAddr::V4(addr) => Some(addr.into()),
99+
#[cfg(feature = "proto-ipv6")]
100+
IpAddr::V6(addr) => Some(addr.into()),
101+
#[allow(unreachable_patterns)]
102+
_ => None,
90103
}
91104
}

edge-nal-embassy/src/tcp.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize> TcpConnect
4444
async fn connect(&self, remote: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
4545
let mut socket = TcpSocket::new(self.stack, self.buffers)?;
4646

47-
socket.socket.connect(to_emb_socket(remote)).await?;
47+
socket
48+
.socket
49+
.connect(to_emb_socket(remote).ok_or(TcpError::UnsupportedProto)?)
50+
.await?;
4851

4952
Ok(socket)
5053
}
@@ -82,7 +85,10 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize> edge_nal::TcpAccept
8285
async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> {
8386
let mut socket = TcpSocket::new(self.stack.stack, self.stack.buffers)?;
8487

85-
socket.socket.accept(to_emb_bind_socket(self.local)).await?;
88+
socket
89+
.socket
90+
.accept(to_emb_bind_socket(self.local).ok_or(TcpError::UnsupportedProto)?)
91+
.await?;
8692

8793
let local_endpoint = unwrap!(socket.socket.local_endpoint());
8894

@@ -286,6 +292,7 @@ pub enum TcpError {
286292
Connect(ConnectError),
287293
Accept(AcceptError),
288294
NoBuffers,
295+
UnsupportedProto,
289296
}
290297

291298
impl From<Error> for TcpError {
@@ -314,6 +321,7 @@ impl embedded_io_async::Error for TcpError {
314321
TcpError::Connect(_) => ErrorKind::Other,
315322
TcpError::Accept(_) => ErrorKind::Other,
316323
TcpError::NoBuffers => ErrorKind::OutOfMemory,
324+
TcpError::UnsupportedProto => ErrorKind::InvalidInput,
317325
}
318326
}
319327
}

edge-nal-embassy/src/udp.rs

Lines changed: 88 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
1+
use core::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
22
use core::ptr::NonNull;
33

44
use edge_nal::{MulticastV4, MulticastV6, Readable, UdpBind, UdpReceive, UdpSend, UdpSplit};
55

66
use embassy_net::udp::{BindError, PacketMetadata, RecvError, SendError};
7-
use embassy_net::{MulticastError, Stack};
7+
use embassy_net::Stack;
88

99
use embedded_io_async::{ErrorKind, ErrorType};
1010

@@ -49,7 +49,9 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Udp
4949
async fn bind(&self, local: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
5050
let mut socket = UdpSocket::new(self.stack, self.buffers)?;
5151

52-
socket.socket.bind(to_emb_bind_socket(local))?;
52+
socket
53+
.socket
54+
.bind(to_emb_bind_socket(local).ok_or(UdpError::UnsupportedProto)?)?;
5355

5456
Ok(socket)
5557
}
@@ -58,6 +60,7 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Udp
5860
/// A UDP socket
5961
/// Implements the `UdpReceive` `UdpSend` and `UdpSplit` traits from `edge-nal`
6062
pub struct UdpSocket<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> {
63+
#[allow(unused)]
6164
stack: embassy_net::Stack<'d>,
6265
socket: embassy_net::udp::UdpSocket<'d>,
6366
stack_buffers: &'d UdpBuffers<N, TX_SZ, RX_SZ, M>,
@@ -125,7 +128,12 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Udp
125128
for UdpSocket<'_, N, TX_SZ, RX_SZ, M>
126129
{
127130
async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
128-
self.socket.send_to(data, to_emb_socket(remote)).await?;
131+
self.socket
132+
.send_to(
133+
data,
134+
to_emb_socket(remote).ok_or(UdpError::UnsupportedProto)?,
135+
)
136+
.await?;
129137

130138
Ok(())
131139
}
@@ -151,7 +159,12 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Udp
151159
for &UdpSocket<'_, N, TX_SZ, RX_SZ, M>
152160
{
153161
async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
154-
self.socket.send_to(data, remote).await?;
162+
self.socket
163+
.send_to(
164+
data,
165+
to_emb_socket(remote).ok_or(UdpError::UnsupportedProto)?,
166+
)
167+
.await?;
155168

156169
Ok(())
157170
}
@@ -189,22 +202,42 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Mul
189202
{
190203
async fn join_v4(
191204
&mut self,
192-
multicast_addr: Ipv4Addr,
205+
#[allow(unused)] multicast_addr: Ipv4Addr,
193206
_interface: Ipv4Addr,
194207
) -> Result<(), Self::Error> {
195-
self.stack
196-
.join_multicast_group(IpAddr::V4(multicast_addr))?;
208+
#[cfg(feature = "multicast")]
209+
{
210+
self.stack.join_multicast_group(
211+
crate::to_emb_addr(core::net::IpAddr::V4(multicast_addr))
212+
.ok_or(UdpError::UnsupportedProto)?,
213+
)?;
214+
}
215+
216+
#[cfg(not(feature = "multicast"))]
217+
{
218+
Err(UdpError::UnsupportedProto)?;
219+
}
197220

198221
Ok(())
199222
}
200223

201224
async fn leave_v4(
202225
&mut self,
203-
multicast_addr: Ipv4Addr,
226+
#[allow(unused)] multicast_addr: Ipv4Addr,
204227
_interface: Ipv4Addr,
205228
) -> Result<(), Self::Error> {
206-
self.stack
207-
.leave_multicast_group(IpAddr::V4(multicast_addr))?;
229+
#[cfg(feature = "multicast")]
230+
{
231+
self.stack.leave_multicast_group(
232+
crate::to_emb_addr(core::net::IpAddr::V4(multicast_addr))
233+
.ok_or(UdpError::UnsupportedProto)?,
234+
)?;
235+
}
236+
237+
#[cfg(not(feature = "multicast"))]
238+
{
239+
Err(UdpError::UnsupportedProto)?;
240+
}
208241

209242
Ok(())
210243
}
@@ -215,22 +248,42 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Mul
215248
{
216249
async fn join_v6(
217250
&mut self,
218-
multicast_addr: Ipv6Addr,
251+
#[allow(unused)] multicast_addr: Ipv6Addr,
219252
_interface: u32,
220253
) -> Result<(), Self::Error> {
221-
self.stack
222-
.join_multicast_group(IpAddr::V6(multicast_addr))?;
254+
#[cfg(feature = "multicast")]
255+
{
256+
self.stack.join_multicast_group(
257+
crate::to_emb_addr(core::net::IpAddr::V6(multicast_addr))
258+
.ok_or(UdpError::UnsupportedProto)?,
259+
)?;
260+
}
261+
262+
#[cfg(not(feature = "multicast"))]
263+
{
264+
Err(UdpError::UnsupportedProto)?;
265+
}
223266

224267
Ok(())
225268
}
226269

227270
async fn leave_v6(
228271
&mut self,
229-
multicast_addr: Ipv6Addr,
272+
#[allow(unused)] multicast_addr: Ipv6Addr,
230273
_interface: u32,
231274
) -> Result<(), Self::Error> {
232-
self.stack
233-
.leave_multicast_group(IpAddr::V6(multicast_addr))?;
275+
#[cfg(feature = "multicast")]
276+
{
277+
self.stack.leave_multicast_group(
278+
crate::to_emb_addr(core::net::IpAddr::V6(multicast_addr))
279+
.ok_or(UdpError::UnsupportedProto)?,
280+
)?;
281+
}
282+
283+
#[cfg(not(feature = "multicast"))]
284+
{
285+
Err(UdpError::UnsupportedProto)?;
286+
}
234287

235288
Ok(())
236289
}
@@ -252,8 +305,12 @@ pub enum UdpError {
252305
Recv(RecvError),
253306
Send(SendError),
254307
Bind(BindError),
255-
Multicast(MulticastError),
308+
/// The table of joined multicast groups is already full.
309+
MulticastGroupTableFull,
310+
/// Cannot join/leave the given multicast group.
311+
MulticastUnaddressable,
256312
NoBuffers,
313+
UnsupportedProto,
257314
}
258315

259316
impl From<RecvError> for UdpError {
@@ -274,9 +331,16 @@ impl From<BindError> for UdpError {
274331
}
275332
}
276333

277-
impl From<MulticastError> for UdpError {
278-
fn from(e: MulticastError) -> Self {
279-
UdpError::Multicast(e)
334+
#[cfg(all(
335+
feature = "multicast",
336+
any(feature = "proto-ipv4", feature = "proto-ipv6")
337+
))]
338+
impl From<embassy_net::MulticastError> for UdpError {
339+
fn from(e: embassy_net::MulticastError) -> Self {
340+
match e {
341+
embassy_net::MulticastError::GroupTableFull => UdpError::MulticastGroupTableFull,
342+
embassy_net::MulticastError::Unaddressable => UdpError::MulticastUnaddressable,
343+
}
280344
}
281345
}
282346

@@ -287,8 +351,10 @@ impl embedded_io_async::Error for UdpError {
287351
UdpError::Recv(_) => ErrorKind::Other,
288352
UdpError::Send(_) => ErrorKind::Other,
289353
UdpError::Bind(_) => ErrorKind::Other,
290-
UdpError::Multicast(_) => ErrorKind::Other,
354+
UdpError::MulticastGroupTableFull => ErrorKind::Other,
355+
UdpError::MulticastUnaddressable => ErrorKind::Other,
291356
UdpError::NoBuffers => ErrorKind::OutOfMemory,
357+
UdpError::UnsupportedProto => ErrorKind::InvalidInput,
292358
}
293359
}
294360
}

0 commit comments

Comments
 (0)