embedded_nal/stack/
udp.rs

1use core::net::SocketAddr;
2
3/// This trait is implemented by UDP/IP stacks. You could, for example, have
4/// an implementation which knows how to send AT commands to an ESP8266 WiFi
5/// module. You could have another implementation which knows how to driver the
6/// Rust Standard Library's `std::net` module. Given this trait, you can how
7/// write a portable CoAP client which can work with either implementation.
8pub trait UdpClientStack {
9	/// The type returned when we create a new UDP socket
10	type UdpSocket;
11	/// The type returned when we have an error
12	type Error: core::fmt::Debug;
13
14	/// Allocate a socket for further use.
15	fn socket(&mut self) -> Result<Self::UdpSocket, Self::Error>;
16
17	/// Connect a UDP socket with a peer using a dynamically selected port.
18	///
19	/// Selects a port number automatically and initializes for read/writing.
20	fn connect(
21		&mut self,
22		socket: &mut Self::UdpSocket,
23		remote: SocketAddr,
24	) -> Result<(), Self::Error>;
25
26	/// Send a datagram to the remote host.
27	///
28	/// The remote host used is either the one specified in `UdpStack::connect`
29	/// or the last one used in `UdpServerStack::write_to`.
30	fn send(&mut self, socket: &mut Self::UdpSocket, buffer: &[u8]) -> nb::Result<(), Self::Error>;
31
32	/// Read a datagram the remote host has sent to us.
33	///
34	/// Returns `Ok((n, remote))`, which means a datagram of size `n` has been
35	/// received from `remote` and been placed in `&buffer[0..n]`, or an error.
36	/// If a packet has not been received when called, then [`nb::Error::WouldBlock`]
37	/// should be returned.
38	fn receive(
39		&mut self,
40		socket: &mut Self::UdpSocket,
41		buffer: &mut [u8],
42	) -> nb::Result<(usize, SocketAddr), Self::Error>;
43
44	/// Close an existing UDP socket.
45	fn close(&mut self, socket: Self::UdpSocket) -> Result<(), Self::Error>;
46}
47
48/// This trait is implemented by UDP/IP stacks.  It provides the ability to
49/// listen for packets on a specified port and send replies.
50pub trait UdpFullStack: UdpClientStack {
51	/// Bind a UDP socket with a specified port
52	fn bind(&mut self, socket: &mut Self::UdpSocket, local_port: u16) -> Result<(), Self::Error>;
53
54	/// Send a packet to a remote host/port.
55	fn send_to(
56		&mut self,
57		socket: &mut Self::UdpSocket,
58		remote: SocketAddr,
59		buffer: &[u8],
60	) -> nb::Result<(), Self::Error>;
61}
62
63impl<T: UdpClientStack> UdpClientStack for &mut T {
64	type Error = T::Error;
65
66	type UdpSocket = T::UdpSocket;
67
68	fn socket(&mut self) -> Result<Self::UdpSocket, Self::Error> {
69		T::socket(self)
70	}
71
72	fn connect(
73		&mut self,
74		socket: &mut Self::UdpSocket,
75		remote: SocketAddr,
76	) -> Result<(), Self::Error> {
77		T::connect(self, socket, remote)
78	}
79
80	fn send(&mut self, socket: &mut Self::UdpSocket, buffer: &[u8]) -> nb::Result<(), Self::Error> {
81		T::send(self, socket, buffer)
82	}
83
84	fn receive(
85		&mut self,
86		socket: &mut Self::UdpSocket,
87		buffer: &mut [u8],
88	) -> nb::Result<(usize, SocketAddr), Self::Error> {
89		T::receive(self, socket, buffer)
90	}
91
92	fn close(&mut self, socket: Self::UdpSocket) -> Result<(), Self::Error> {
93		T::close(self, socket)
94	}
95}
96
97impl<T: UdpFullStack> UdpFullStack for &mut T {
98	fn bind(&mut self, socket: &mut Self::UdpSocket, local_port: u16) -> Result<(), Self::Error> {
99		T::bind(self, socket, local_port)
100	}
101
102	fn send_to(
103		&mut self,
104		socket: &mut Self::UdpSocket,
105		remote: SocketAddr,
106		buffer: &[u8],
107	) -> nb::Result<(), Self::Error> {
108		T::send_to(self, socket, remote, buffer)
109	}
110}