Skip to main content

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}