Skip to main content

edge_nal/stack/
udp.rs

1//! Factory traits for creating UDP sockets on embedded devices
2
3use core::net::SocketAddr;
4
5use embedded_io_async::ErrorType;
6
7use crate::udp::{UdpReceive, UdpSend};
8use crate::{MulticastV4, MulticastV6, Readable};
9
10/// This trait is implemented by UDP sockets that can be split into separate `send` and `receive` halves that can operate
11/// independently from each other (i.e., a full-duplex connection)
12pub trait UdpSplit: ErrorType {
13    type Receive<'a>: UdpReceive<Error = Self::Error> + Readable<Error = Self::Error>
14    where
15        Self: 'a;
16    type Send<'a>: UdpSend<Error = Self::Error>
17    where
18        Self: 'a;
19
20    fn split(&mut self) -> (Self::Receive<'_>, Self::Send<'_>);
21}
22
23impl<T> UdpSplit for &mut T
24where
25    T: UdpSplit,
26{
27    type Receive<'a>
28        = T::Receive<'a>
29    where
30        Self: 'a;
31    type Send<'a>
32        = T::Send<'a>
33    where
34        Self: 'a;
35
36    fn split(&mut self) -> (Self::Receive<'_>, Self::Send<'_>) {
37        (**self).split()
38    }
39}
40
41/// This trait is implemented by UDP sockets that can be split into separate
42/// `receive`, `send`, `MulticastV4`, and `MulticastV6` parts that can operate independently from each other
43/// (i.e., a full-duplex connection with multicasting capabilities)
44pub trait UdpSplitMulticast: UdpSplit {
45    type MulticastV4<'a>: MulticastV4<Error = Self::Error>
46    where
47        Self: 'a;
48    type MulticastV6<'a>: MulticastV6<Error = Self::Error>
49    where
50        Self: 'a;
51
52    fn split_multicast(
53        &mut self,
54    ) -> (
55        Self::Receive<'_>,
56        Self::Send<'_>,
57        Self::MulticastV4<'_>,
58        Self::MulticastV6<'_>,
59    );
60}
61
62impl<T> UdpSplitMulticast for &mut T
63where
64    T: UdpSplitMulticast,
65{
66    type MulticastV4<'a>
67        = T::MulticastV4<'a>
68    where
69        Self: 'a;
70    type MulticastV6<'a>
71        = T::MulticastV6<'a>
72    where
73        Self: 'a;
74
75    fn split_multicast(
76        &mut self,
77    ) -> (
78        Self::Receive<'_>,
79        Self::Send<'_>,
80        Self::MulticastV4<'_>,
81        Self::MulticastV6<'_>,
82    ) {
83        (**self).split_multicast()
84    }
85}
86
87/// This is a factory trait for creating connected UDP sockets
88pub trait UdpConnect {
89    /// Error type returned on socket creation failure
90    type Error: embedded_io_async::Error;
91
92    /// The socket type returned by the factory
93    type Socket<'a>: UdpReceive<Error = Self::Error>
94        + UdpSend<Error = Self::Error>
95        + UdpSplitMulticast<Error = Self::Error>
96        + MulticastV4<Error = Self::Error>
97        + MulticastV6<Error = Self::Error>
98        + Readable<Error = Self::Error>
99    where
100        Self: 'a;
101
102    /// Connect to a remote socket
103    async fn connect(
104        &self,
105        local: SocketAddr,
106        remote: SocketAddr,
107    ) -> Result<Self::Socket<'_>, Self::Error>;
108}
109
110/// This is a factory trait for binding UDP sockets
111pub trait UdpBind {
112    /// Error type returned on socket creation failure
113    type Error: embedded_io_async::Error;
114
115    /// The socket type returned by the stack
116    type Socket<'a>: UdpReceive<Error = Self::Error>
117        + UdpSend<Error = Self::Error>
118        + UdpSplitMulticast<Error = Self::Error>
119        + MulticastV4<Error = Self::Error>
120        + MulticastV6<Error = Self::Error>
121        + Readable<Error = Self::Error>
122    where
123        Self: 'a;
124
125    /// Bind to a local socket address
126    async fn bind(&self, local: SocketAddr) -> Result<Self::Socket<'_>, Self::Error>;
127}
128
129impl<T> UdpConnect for &T
130where
131    T: UdpConnect,
132{
133    type Error = T::Error;
134    type Socket<'a>
135        = T::Socket<'a>
136    where
137        Self: 'a;
138
139    async fn connect(
140        &self,
141        local: SocketAddr,
142        remote: SocketAddr,
143    ) -> Result<Self::Socket<'_>, Self::Error> {
144        (*self).connect(local, remote).await
145    }
146}
147
148impl<T> UdpConnect for &mut T
149where
150    T: UdpConnect,
151{
152    type Error = T::Error;
153    type Socket<'a>
154        = T::Socket<'a>
155    where
156        Self: 'a;
157
158    async fn connect(
159        &self,
160        local: SocketAddr,
161        remote: SocketAddr,
162    ) -> Result<Self::Socket<'_>, Self::Error> {
163        (**self).connect(local, remote).await
164    }
165}
166
167impl<T> UdpBind for &T
168where
169    T: UdpBind,
170{
171    type Error = T::Error;
172    type Socket<'a>
173        = T::Socket<'a>
174    where
175        Self: 'a;
176
177    async fn bind(&self, local: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
178        (*self).bind(local).await
179    }
180}
181
182impl<T> UdpBind for &mut T
183where
184    T: UdpBind,
185{
186    type Error = T::Error;
187    type Socket<'a>
188        = T::Socket<'a>
189    where
190        Self: 'a;
191
192    async fn bind(&self, local: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
193        (**self).bind(local).await
194    }
195}