edge_nal/udp.rs
1//! Traits for modeling UDP sending/receiving functionality on embedded devices
2
3use core::net::SocketAddr;
4
5use embedded_io_async::ErrorType;
6
7/// This trait is implemented by UDP sockets and models their datagram receiving functionality.
8///
9/// The socket it represents might be either bound (has a local IP address, port and interface) or
10/// connected (also has a remote IP address and port).
11///
12/// The term "connected" here refers to the semantics of POSIX datagram sockets, through which datagrams
13/// are sent and received without having a remote address per call. It does not imply any process
14/// of establishing a connection (which is absent in UDP). While there is typically no POSIX
15/// `bind()` call in the creation of such sockets, these are implicitly bound to a suitable local
16/// address at connect time.
17pub trait UdpReceive: ErrorType {
18 /// Receive a datagram into the provided buffer.
19 ///
20 /// If the received datagram exceeds the buffer's length, it is received regardless, and the
21 /// remaining bytes are discarded. The full datagram size is still indicated in the result,
22 /// allowing the recipient to detect that truncation.
23 ///
24 /// The remote addresses is given in the result along with the number of bytes.
25 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error>;
26}
27
28/// This trait is implemented by UDP sockets and models their datagram sending functionality.
29///
30/// The socket it represents might be either bound (has a local IP address, port and interface) or
31/// connected (also has a remote IP address and port).
32///
33/// The term "connected" here refers to the semantics of POSIX datagram sockets, through which datagrams
34/// are sent and received without having a remote address per call. It does not imply any process
35/// of establishing a connection (which is absent in UDP). While there is typically no POSIX
36/// `bind()` call in the creation of such sockets, these are implicitly bound to a suitable local
37/// address at connect time.
38pub trait UdpSend: ErrorType {
39 /// Send the provided data to a peer:
40 /// - In case the socket is connected, the provided remote address is ignored.
41 /// - In case the socket is unconnected the remote address is used.
42 async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error>;
43}
44
45pub trait UdpSocket: UdpReceive + UdpSend {}
46
47impl<T> UdpReceive for &mut T
48where
49 T: UdpReceive,
50{
51 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> {
52 (**self).receive(buffer).await
53 }
54}
55
56impl<T> UdpSend for &mut T
57where
58 T: UdpSend,
59{
60 async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
61 (**self).send(remote, data).await
62 }
63}