Skip to content

Commit e3e6e85

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

File tree

4 files changed

+111
-49
lines changed

4 files changed

+111
-49
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: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ 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.socket.connect(to_emb_socket(remote).ok_or(TcpError::UnsupportedProto)?).await?;
4848

4949
Ok(socket)
5050
}
@@ -82,7 +82,7 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize> edge_nal::TcpAccept
8282
async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> {
8383
let mut socket = TcpSocket::new(self.stack.stack, self.stack.buffers)?;
8484

85-
socket.socket.accept(to_emb_bind_socket(self.local)).await?;
85+
socket.socket.accept(to_emb_bind_socket(self.local).ok_or(TcpError::UnsupportedProto)?).await?;
8686

8787
let local_endpoint = unwrap!(socket.socket.local_endpoint());
8888

@@ -286,6 +286,7 @@ pub enum TcpError {
286286
Connect(ConnectError),
287287
Accept(AcceptError),
288288
NoBuffers,
289+
UnsupportedProto,
289290
}
290291

291292
impl From<Error> for TcpError {
@@ -314,6 +315,7 @@ impl embedded_io_async::Error for TcpError {
314315
TcpError::Connect(_) => ErrorKind::Other,
315316
TcpError::Accept(_) => ErrorKind::Other,
316317
TcpError::NoBuffers => ErrorKind::OutOfMemory,
318+
TcpError::UnsupportedProto => ErrorKind::InvalidInput,
317319
}
318320
}
319321
}

edge-nal-embassy/src/udp.rs

Lines changed: 65 additions & 18 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,7 @@ 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.socket.bind(to_emb_bind_socket(local).ok_or(UdpError::UnsupportedProto)?)?;
5353

5454
Ok(socket)
5555
}
@@ -58,6 +58,7 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Udp
5858
/// A UDP socket
5959
/// Implements the `UdpReceive` `UdpSend` and `UdpSplit` traits from `edge-nal`
6060
pub struct UdpSocket<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> {
61+
#[allow(unused)]
6162
stack: embassy_net::Stack<'d>,
6263
socket: embassy_net::udp::UdpSocket<'d>,
6364
stack_buffers: &'d UdpBuffers<N, TX_SZ, RX_SZ, M>,
@@ -125,7 +126,7 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Udp
125126
for UdpSocket<'_, N, TX_SZ, RX_SZ, M>
126127
{
127128
async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
128-
self.socket.send_to(data, to_emb_socket(remote)).await?;
129+
self.socket.send_to(data, to_emb_socket(remote).ok_or(UdpError::UnsupportedProto)?).await?;
129130

130131
Ok(())
131132
}
@@ -151,7 +152,7 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Udp
151152
for &UdpSocket<'_, N, TX_SZ, RX_SZ, M>
152153
{
153154
async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
154-
self.socket.send_to(data, remote).await?;
155+
self.socket.send_to(data, to_emb_socket(remote).ok_or(UdpError::UnsupportedProto)?).await?;
155156

156157
Ok(())
157158
}
@@ -189,22 +190,40 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Mul
189190
{
190191
async fn join_v4(
191192
&mut self,
193+
#[allow(unused)]
192194
multicast_addr: Ipv4Addr,
193195
_interface: Ipv4Addr,
194196
) -> Result<(), Self::Error> {
195-
self.stack
196-
.join_multicast_group(IpAddr::V4(multicast_addr))?;
197+
#[cfg(feature = "multicast")]
198+
{
199+
self.stack
200+
.join_multicast_group(crate::to_emb_addr(core::net::IpAddr::V4(multicast_addr)).ok_or(UdpError::UnsupportedProto)?)?;
201+
}
202+
203+
#[cfg(not(feature = "multicast"))]
204+
{
205+
Err(UdpError::UnsupportedProto)?;
206+
}
197207

198208
Ok(())
199209
}
200210

201211
async fn leave_v4(
202212
&mut self,
213+
#[allow(unused)]
203214
multicast_addr: Ipv4Addr,
204215
_interface: Ipv4Addr,
205216
) -> Result<(), Self::Error> {
206-
self.stack
207-
.leave_multicast_group(IpAddr::V4(multicast_addr))?;
217+
#[cfg(feature = "multicast")]
218+
{
219+
self.stack
220+
.leave_multicast_group(crate::to_emb_addr(core::net::IpAddr::V4(multicast_addr)).ok_or(UdpError::UnsupportedProto)?)?;
221+
}
222+
223+
#[cfg(not(feature = "multicast"))]
224+
{
225+
Err(UdpError::UnsupportedProto)?;
226+
}
208227

209228
Ok(())
210229
}
@@ -215,22 +234,40 @@ impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize, const M: usize> Mul
215234
{
216235
async fn join_v6(
217236
&mut self,
237+
#[allow(unused)]
218238
multicast_addr: Ipv6Addr,
219239
_interface: u32,
220240
) -> Result<(), Self::Error> {
221-
self.stack
222-
.join_multicast_group(IpAddr::V6(multicast_addr))?;
241+
#[cfg(feature = "multicast")]
242+
{
243+
self.stack
244+
.join_multicast_group(crate::to_emb_addr(core::net::IpAddr::V6(multicast_addr)).ok_or(UdpError::UnsupportedProto)?)?;
245+
}
246+
247+
#[cfg(not(feature = "multicast"))]
248+
{
249+
Err(UdpError::UnsupportedProto)?;
250+
}
223251

224252
Ok(())
225253
}
226254

227255
async fn leave_v6(
228256
&mut self,
257+
#[allow(unused)]
229258
multicast_addr: Ipv6Addr,
230259
_interface: u32,
231260
) -> Result<(), Self::Error> {
232-
self.stack
233-
.leave_multicast_group(IpAddr::V6(multicast_addr))?;
261+
#[cfg(feature = "multicast")]
262+
{
263+
self.stack
264+
.leave_multicast_group(crate::to_emb_addr(core::net::IpAddr::V6(multicast_addr)).ok_or(UdpError::UnsupportedProto)?)?;
265+
}
266+
267+
#[cfg(not(feature = "multicast"))]
268+
{
269+
Err(UdpError::UnsupportedProto)?;
270+
}
234271

235272
Ok(())
236273
}
@@ -252,8 +289,12 @@ pub enum UdpError {
252289
Recv(RecvError),
253290
Send(SendError),
254291
Bind(BindError),
255-
Multicast(MulticastError),
292+
/// The table of joined multicast groups is already full.
293+
MulticastGroupTableFull,
294+
/// Cannot join/leave the given multicast group.
295+
MulticastUnaddressable,
256296
NoBuffers,
297+
UnsupportedProto,
257298
}
258299

259300
impl From<RecvError> for UdpError {
@@ -274,9 +315,13 @@ impl From<BindError> for UdpError {
274315
}
275316
}
276317

277-
impl From<MulticastError> for UdpError {
278-
fn from(e: MulticastError) -> Self {
279-
UdpError::Multicast(e)
318+
#[cfg(all(feature = "multicast", any(feature = "proto-ipv4", feature = "proto-ipv6")))]
319+
impl From<embassy_net::MulticastError> for UdpError {
320+
fn from(e: embassy_net::MulticastError) -> Self {
321+
match e {
322+
embassy_net::MulticastError::GroupTableFull => UdpError::MulticastGroupTableFull,
323+
embassy_net::MulticastError::Unaddressable => UdpError::MulticastUnaddressable,
324+
}
280325
}
281326
}
282327

@@ -287,8 +332,10 @@ impl embedded_io_async::Error for UdpError {
287332
UdpError::Recv(_) => ErrorKind::Other,
288333
UdpError::Send(_) => ErrorKind::Other,
289334
UdpError::Bind(_) => ErrorKind::Other,
290-
UdpError::Multicast(_) => ErrorKind::Other,
335+
UdpError::MulticastGroupTableFull => ErrorKind::Other,
336+
UdpError::MulticastUnaddressable => ErrorKind::Other,
291337
UdpError::NoBuffers => ErrorKind::OutOfMemory,
338+
UdpError::UnsupportedProto => ErrorKind::InvalidInput,
292339
}
293340
}
294341
}

0 commit comments

Comments
 (0)