1use 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
11pub 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() }