Skip to content

Commit 0eecce5

Browse files
committed
UDP stack based on embassy-net
1 parent 762438c commit 0eecce5

File tree

6 files changed

+276
-78
lines changed

6 files changed

+276
-78
lines changed

examples/onoff_light/src/main.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ use matter::error::Error;
3131
use matter::mdns::{DefaultMdns, DefaultMdnsRunner};
3232
use matter::persist::FilePsm;
3333
use matter::secure_channel::spake2p::VerifierData;
34-
use matter::transport::network::{Ipv4Addr, Ipv6Addr};
34+
use matter::transport::network::{Ipv4Addr, Ipv6Addr, NetworkStack};
3535
use matter::transport::runner::{RxBuf, TransportRunner, TxBuf};
36+
use matter::transport::udp::UdpBuffers;
3637
use matter::utils::select::EitherUnwrap;
3738

3839
mod dev_att;
@@ -131,6 +132,13 @@ fn run() -> Result<(), Error> {
131132
let mut tx_buf = TxBuf::uninit();
132133
let mut rx_buf = RxBuf::uninit();
133134

135+
// NOTE (no_std): If using the `embassy-net` UDP implementation, replace this dummy stack with the `embassy-net` one
136+
// When using a custom UDP stack, remove this
137+
let stack = NetworkStack::new();
138+
139+
let mut mdns_udp_buffers = UdpBuffers::new();
140+
let mut trans_udp_buffers = UdpBuffers::new();
141+
134142
#[cfg(all(feature = "std", not(target_os = "espidf")))]
135143
{
136144
let mut buf = [0; 4096];
@@ -164,16 +172,21 @@ fn run() -> Result<(), Error> {
164172
let runner = &mut runner;
165173
let tx_buf = &mut tx_buf;
166174
let rx_buf = &mut rx_buf;
175+
let stack = &stack;
176+
let mdns_udp_buffers = &mut mdns_udp_buffers;
177+
let trans_udp_buffers = &mut trans_udp_buffers;
167178

168179
info!(
169180
"About to run wth node {:p}, handler {:p}, transport runner {:p}, mdns_runner {:p}",
170181
node, handler, runner, &mdns_runner
171182
);
172183

173184
let mut fut = pin!(async move {
174-
// NOTE (no_std): On no_std, the `run_udp` is a no-op so you might want to replace it with `run` and
175-
// connect the pipes of the `run` method with your own UDP stack
185+
// NOTE: If using a custom UDP stack, replace `run_udp` with `run`
186+
// and connect the pipes of the `run` method with the custom UDP stack
176187
let mut transport = pin!(runner.run_udp(
188+
stack,
189+
trans_udp_buffers,
177190
tx_buf,
178191
rx_buf,
179192
CommissioningData {
@@ -184,9 +197,9 @@ fn run() -> Result<(), Error> {
184197
&handler,
185198
));
186199

187-
// NOTE (no_std): On no_std, the `run_udp` is a no-op so you might want to replace it with `run` and
188-
// connect the pipes of the `run` method with your own UDP stack
189-
let mut mdns = pin!(mdns_runner.run_udp());
200+
// NOTE: If using a custom UDP stack, replace `run_udp` with `run`
201+
// and connect the pipes of the `run` method with the custom UDP stack
202+
let mut mdns = pin!(mdns_runner.run_udp(stack, mdns_udp_buffers));
190203

191204
let mut save = pin!(save(matter, &psm));
192205
select3(&mut transport, &mut mdns, &mut save).await.unwrap()

matter/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ nightly = []
2424
crypto_openssl = ["alloc", "openssl", "foreign-types", "hmac", "sha2"]
2525
crypto_mbedtls = ["alloc", "mbedtls"]
2626
crypto_rustcrypto = ["alloc", "sha2", "hmac", "pbkdf2", "hkdf", "aes", "ccm", "p256", "elliptic-curve", "crypto-bigint", "x509-cert", "rand_core"]
27+
embassy-net = ["dep:embassy-net", "dep:embassy-net-driver", "smoltcp"]
2728

2829
[dependencies]
2930
matter_macro_derive = { path = "../matter_macro_derive" }
@@ -46,6 +47,9 @@ embassy-time = { version = "0.1.1", features = ["generic-queue-8"] }
4647
embassy-sync = "0.2"
4748
critical-section = "1.1.1"
4849
domain = { version = "0.7.2", default_features = false, features = ["heapless"] }
50+
embassy-net = { version = "0.1", features = ["udp", "igmp", "proto-ipv6", "medium-ethernet", "medium-ip"], optional = true }
51+
embassy-net-driver = { version = "0.1", optional = true }
52+
smoltcp = { version = "0.10", default-features = false, optional = true }
4953

5054
# STD-only dependencies
5155
rand = { version = "0.8.5", optional = true }

matter/src/mdns/builtin.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,30 @@
1-
use core::{cell::RefCell, mem::MaybeUninit, pin::pin};
1+
use core::{cell::RefCell, pin::pin};
22

33
use domain::base::name::FromStrError;
44
use domain::base::{octets::ParseError, ShortBuf};
5-
use embassy_futures::select::{select, select3};
5+
use embassy_futures::select::select;
66
use embassy_time::{Duration, Timer};
77
use log::info;
88

99
use crate::data_model::cluster_basic_information::BasicInfoConfig;
1010
use crate::error::{Error, ErrorCode};
1111
use crate::transport::network::{Address, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
12-
use crate::transport::packet::{MAX_RX_BUF_SIZE, MAX_TX_BUF_SIZE};
1312
use crate::transport::pipe::{Chunk, Pipe};
14-
use crate::transport::udp::UdpListener;
1513
use crate::utils::select::{EitherUnwrap, Notification};
1614

1715
use super::{
1816
proto::{Host, Services},
1917
Service, ServiceMode,
2018
};
2119

22-
const IP_BIND_ADDR: IpAddr = IpAddr::V6(Ipv6Addr::UNSPECIFIED);
23-
2420
const IP_BROADCAST_ADDR: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 251);
2521
const IPV6_BROADCAST_ADDR: Ipv6Addr = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0x00fb);
2622

2723
const PORT: u16 = 5353;
2824

29-
type MdnsTxBuf = MaybeUninit<[u8; MAX_TX_BUF_SIZE]>;
30-
type MdnsRxBuf = MaybeUninit<[u8; MAX_RX_BUF_SIZE]>;
31-
3225
pub struct Mdns<'a> {
3326
host: Host<'a>,
27+
#[allow(unused)]
3428
interface: u32,
3529
dev_det: &'a BasicInfoConfig<'a>,
3630
matter_port: u16,
@@ -108,9 +102,21 @@ impl<'a> MdnsRunner<'a> {
108102
Self(mdns)
109103
}
110104

111-
pub async fn run_udp(&mut self) -> Result<(), Error> {
112-
let mut tx_buf = MdnsTxBuf::uninit();
113-
let mut rx_buf = MdnsRxBuf::uninit();
105+
#[cfg(any(feature = "std", feature = "embassy-net"))]
106+
pub async fn run_udp<D>(
107+
&mut self,
108+
stack: &crate::transport::network::NetworkStack<D>,
109+
buffers: &mut crate::transport::udp::UdpBuffers,
110+
) -> Result<(), Error>
111+
where
112+
D: crate::transport::network::NetworkStackMulticastDriver
113+
+ crate::transport::network::NetworkStackDriver
114+
+ 'static,
115+
{
116+
let mut tx_buf =
117+
core::mem::MaybeUninit::<[u8; crate::transport::packet::MAX_TX_BUF_SIZE]>::uninit();
118+
let mut rx_buf =
119+
core::mem::MaybeUninit::<[u8; crate::transport::packet::MAX_RX_BUF_SIZE]>::uninit();
114120

115121
let tx_buf = &mut tx_buf;
116122
let rx_buf = &mut rx_buf;
@@ -121,10 +127,18 @@ impl<'a> MdnsRunner<'a> {
121127
let tx_pipe = &tx_pipe;
122128
let rx_pipe = &rx_pipe;
123129

124-
let mut udp = UdpListener::new(SocketAddr::new(IP_BIND_ADDR, PORT)).await?;
130+
let mut udp = crate::transport::udp::UdpListener::new(
131+
stack,
132+
crate::transport::network::SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), PORT),
133+
buffers,
134+
)
135+
.await?;
125136

126137
udp.join_multicast_v6(IPV6_BROADCAST_ADDR, self.0.interface)?;
127-
udp.join_multicast_v4(IP_BROADCAST_ADDR, Ipv4Addr::from(self.0.host.ip))?;
138+
udp.join_multicast_v4(
139+
IP_BROADCAST_ADDR,
140+
crate::transport::network::Ipv4Addr::from(self.0.host.ip),
141+
)?;
128142

129143
let udp = &udp;
130144

@@ -168,7 +182,9 @@ impl<'a> MdnsRunner<'a> {
168182

169183
let mut run = pin!(async move { self.run(tx_pipe, rx_pipe).await });
170184

171-
select3(&mut tx, &mut rx, &mut run).await.unwrap()
185+
embassy_futures::select::select3(&mut tx, &mut rx, &mut run)
186+
.await
187+
.unwrap()
172188
}
173189

174190
pub async fn run(&self, tx_pipe: &Pipe<'_>, rx_pipe: &Pipe<'_>) -> Result<(), Error> {

matter/src/transport/network.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,35 @@ impl Debug for Address {
5555
}
5656
}
5757
}
58+
59+
#[cfg(all(feature = "std", not(feature = "embassy-net")))]
60+
pub use std_stack::*;
61+
62+
#[cfg(feature = "embassy-net")]
63+
pub use embassy_stack::*;
64+
65+
#[cfg(all(feature = "std", not(feature = "embassy-net")))]
66+
mod std_stack {
67+
pub trait NetworkStackDriver {}
68+
69+
impl NetworkStackDriver for () {}
70+
71+
pub trait NetworkStackMulticastDriver {}
72+
73+
impl NetworkStackMulticastDriver for () {}
74+
75+
pub struct NetworkStack<D>(D);
76+
77+
impl NetworkStack<()> {
78+
pub const fn new() -> Self {
79+
Self(())
80+
}
81+
}
82+
}
83+
84+
#[cfg(feature = "embassy-net")]
85+
mod embassy_stack {
86+
pub use embassy_net::Stack as NetworkStack;
87+
pub use embassy_net_driver::Driver as NetworkStackDriver;
88+
pub use smoltcp::phy::Device as NetworkStackMulticastDriver;
89+
}

matter/src/transport/runner.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ use crate::{
2121
alloc,
2222
data_model::{core::DataModel, objects::DataModelHandler},
2323
interaction_model::core::PROTO_ID_INTERACTION_MODEL,
24-
transport::network::{Address, IpAddr, Ipv6Addr, SocketAddr},
2524
CommissioningData, Matter,
2625
};
27-
use embassy_futures::select::{select, select3, select_slice, Either};
26+
use embassy_futures::select::{select, select_slice, Either};
2827
use embassy_sync::{blocking_mutex::raw::NoopRawMutex, channel::Channel};
2928
use log::{error, info, warn};
3029

@@ -40,7 +39,6 @@ use super::{
4039
exchange::{ExchangeCtr, Notification, MAX_EXCHANGES},
4140
packet::{MAX_RX_STATUS_BUF_SIZE, MAX_TX_BUF_SIZE},
4241
pipe::{Chunk, Pipe},
43-
udp::UdpListener,
4442
};
4543

4644
pub type TxBuf = MaybeUninit<[u8; MAX_TX_BUF_SIZE]>;
@@ -103,20 +101,30 @@ impl<'a> TransportRunner<'a> {
103101
&self.transport
104102
}
105103

106-
pub async fn run_udp<H>(
104+
#[cfg(any(feature = "std", feature = "embassy-net"))]
105+
pub async fn run_udp<D, H>(
107106
&mut self,
107+
stack: &crate::transport::network::NetworkStack<D>,
108+
buffers: &mut crate::transport::udp::UdpBuffers,
108109
tx_buf: &mut TxBuf,
109110
rx_buf: &mut RxBuf,
110111
dev_comm: CommissioningData,
111112
handler: &H,
112113
) -> Result<(), Error>
113114
where
115+
D: crate::transport::network::NetworkStackDriver,
114116
H: DataModelHandler,
115117
{
116-
let udp = UdpListener::new(SocketAddr::new(
117-
IpAddr::V6(Ipv6Addr::UNSPECIFIED),
118-
self.transport.matter().port,
119-
))
118+
let udp = crate::transport::udp::UdpListener::new(
119+
stack,
120+
crate::transport::network::SocketAddr::new(
121+
crate::transport::network::IpAddr::V6(
122+
crate::transport::network::Ipv6Addr::UNSPECIFIED,
123+
),
124+
self.transport.matter().port,
125+
),
126+
buffers,
127+
)
120128
.await?;
121129

122130
let tx_pipe = Pipe::new(unsafe { tx_buf.assume_init_mut() });
@@ -154,7 +162,7 @@ impl<'a> TransportRunner<'a> {
154162
data.chunk = Some(Chunk {
155163
start: 0,
156164
end: len,
157-
addr: Address::Udp(addr),
165+
addr: crate::transport::network::Address::Udp(addr),
158166
});
159167
rx_pipe.data_supplied_notification.signal(());
160168
}
@@ -166,7 +174,9 @@ impl<'a> TransportRunner<'a> {
166174

167175
let mut run = pin!(async move { self.run(tx_pipe, rx_pipe, dev_comm, handler).await });
168176

169-
select3(&mut tx, &mut rx, &mut run).await.unwrap()
177+
embassy_futures::select::select3(&mut tx, &mut rx, &mut run)
178+
.await
179+
.unwrap()
170180
}
171181

172182
pub async fn run<H>(

0 commit comments

Comments
 (0)