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