Skip to main content

rs_matter_stack/
udp.rs

1//! UDP transport implementation for edge-nal
2
3use core::fmt::Debug;
4use core::net::{IpAddr, Ipv4Addr};
5
6use edge_nal::{MulticastV4, MulticastV6, Readable, UdpReceive, UdpSend};
7
8use rs_matter::error::{Error, ErrorCode};
9use rs_matter::transport::network::{Address, NetworkMulticast, NetworkReceive, NetworkSend};
10
11/// UDP transport implementation for edge-nal
12pub struct Udp<T>(pub T);
13
14impl<T> NetworkSend for Udp<T>
15where
16    T: UdpSend,
17{
18    async fn send_to(&mut self, data: &[u8], addr: Address) -> Result<(), Error> {
19        if let Address::Udp(remote) = addr {
20            self.0.send(remote, data).await.map_err(map_err)?;
21
22            Ok(())
23        } else {
24            Err(ErrorCode::NoNetworkInterface.into())
25        }
26    }
27}
28
29impl<T> NetworkReceive for Udp<T>
30where
31    T: UdpReceive + Readable,
32{
33    async fn wait_available(&mut self) -> Result<(), Error> {
34        self.0.readable().await.map_err(map_err)?;
35
36        Ok(())
37    }
38
39    async fn recv_from(&mut self, buffer: &mut [u8]) -> Result<(usize, Address), Error> {
40        let (size, addr) = self.0.receive(buffer).await.map_err(map_err)?;
41
42        Ok((size, Address::Udp(addr)))
43    }
44}
45
46pub struct Multicast<M4, M6> {
47    m4: M4,
48    m4_network: Ipv4Addr,
49    m6: M6,
50    m6_interface: u32,
51}
52
53impl<M4, M6> Multicast<M4, M6>
54where
55    M4: MulticastV4,
56    M6: MulticastV6,
57{
58    pub const fn new(m4: M4, m4_network: Ipv4Addr, m6: M6, m6_interface: u32) -> Self {
59        Self {
60            m4,
61            m4_network,
62            m6,
63            m6_interface,
64        }
65    }
66}
67
68impl<M4, M6> NetworkMulticast for Udp<Multicast<M4, M6>>
69where
70    M4: MulticastV4,
71    M6: MulticastV6,
72{
73    async fn join(&mut self, addr: IpAddr) -> Result<(), Error> {
74        match addr {
75            IpAddr::V4(remote) => self
76                .0
77                .m4
78                .join_v4(remote, self.0.m4_network)
79                .await
80                .map_err(map_err),
81            IpAddr::V6(remote) => self
82                .0
83                .m6
84                .join_v6(remote, self.0.m6_interface)
85                .await
86                .map_err(map_err),
87        }
88    }
89
90    async fn leave(&mut self, addr: IpAddr) -> Result<(), Error> {
91        match addr {
92            IpAddr::V4(remote) => self
93                .0
94                .m4
95                .leave_v4(remote, self.0.m4_network)
96                .await
97                .map_err(map_err),
98            IpAddr::V6(remote) => self
99                .0
100                .m6
101                .leave_v6(remote, self.0.m6_interface)
102                .await
103                .map_err(map_err),
104        }
105    }
106}
107
108fn map_err<E: Debug>(e: E) -> Error {
109    warn!("Network error: {:?}", debug2format!(e));
110    ErrorCode::StdIoError.into() // TODO
111}