diff options
Diffstat (limited to 'embassy-net/src/udp.rs')
| -rw-r--r-- | embassy-net/src/udp.rs | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index 1d5360187..3eb6e2f83 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs | |||
| @@ -1,17 +1,15 @@ | |||
| 1 | //! UDP sockets. | 1 | //! UDP sockets. |
| 2 | 2 | ||
| 3 | use core::cell::RefCell; | ||
| 4 | use core::future::poll_fn; | 3 | use core::future::poll_fn; |
| 5 | use core::mem; | 4 | use core::mem; |
| 6 | use core::task::{Context, Poll}; | 5 | use core::task::{Context, Poll}; |
| 7 | 6 | ||
| 8 | use embassy_net_driver::Driver; | ||
| 9 | use smoltcp::iface::{Interface, SocketHandle}; | 7 | use smoltcp::iface::{Interface, SocketHandle}; |
| 10 | use smoltcp::socket::udp; | 8 | use smoltcp::socket::udp; |
| 11 | pub use smoltcp::socket::udp::{PacketMetadata, UdpMetadata}; | 9 | pub use smoltcp::socket::udp::{PacketMetadata, UdpMetadata}; |
| 12 | use smoltcp::wire::IpListenEndpoint; | 10 | use smoltcp::wire::IpListenEndpoint; |
| 13 | 11 | ||
| 14 | use crate::{SocketStack, Stack}; | 12 | use crate::Stack; |
| 15 | 13 | ||
| 16 | /// Error returned by [`UdpSocket::bind`]. | 14 | /// Error returned by [`UdpSocket::bind`]. |
| 17 | #[derive(PartialEq, Eq, Clone, Copy, Debug)] | 15 | #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
| @@ -43,34 +41,31 @@ pub enum RecvError { | |||
| 43 | 41 | ||
| 44 | /// An UDP socket. | 42 | /// An UDP socket. |
| 45 | pub struct UdpSocket<'a> { | 43 | pub struct UdpSocket<'a> { |
| 46 | stack: &'a RefCell<SocketStack>, | 44 | stack: Stack<'a>, |
| 47 | handle: SocketHandle, | 45 | handle: SocketHandle, |
| 48 | } | 46 | } |
| 49 | 47 | ||
| 50 | impl<'a> UdpSocket<'a> { | 48 | impl<'a> UdpSocket<'a> { |
| 51 | /// Create a new UDP socket using the provided stack and buffers. | 49 | /// Create a new UDP socket using the provided stack and buffers. |
| 52 | pub fn new<D: Driver>( | 50 | pub fn new( |
| 53 | stack: &'a Stack<D>, | 51 | stack: Stack<'a>, |
| 54 | rx_meta: &'a mut [PacketMetadata], | 52 | rx_meta: &'a mut [PacketMetadata], |
| 55 | rx_buffer: &'a mut [u8], | 53 | rx_buffer: &'a mut [u8], |
| 56 | tx_meta: &'a mut [PacketMetadata], | 54 | tx_meta: &'a mut [PacketMetadata], |
| 57 | tx_buffer: &'a mut [u8], | 55 | tx_buffer: &'a mut [u8], |
| 58 | ) -> Self { | 56 | ) -> Self { |
| 59 | let s = &mut *stack.socket.borrow_mut(); | 57 | let handle = stack.with_mut(|i| { |
| 60 | 58 | let rx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(rx_meta) }; | |
| 61 | let rx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(rx_meta) }; | 59 | let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) }; |
| 62 | let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) }; | 60 | let tx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(tx_meta) }; |
| 63 | let tx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(tx_meta) }; | 61 | let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) }; |
| 64 | let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) }; | 62 | i.sockets.add(udp::Socket::new( |
| 65 | let handle = s.sockets.add(udp::Socket::new( | 63 | udp::PacketBuffer::new(rx_meta, rx_buffer), |
| 66 | udp::PacketBuffer::new(rx_meta, rx_buffer), | 64 | udp::PacketBuffer::new(tx_meta, tx_buffer), |
| 67 | udp::PacketBuffer::new(tx_meta, tx_buffer), | 65 | )) |
| 68 | )); | 66 | }); |
| 69 | 67 | ||
| 70 | Self { | 68 | Self { stack, handle } |
| 71 | stack: &stack.socket, | ||
| 72 | handle, | ||
| 73 | } | ||
| 74 | } | 69 | } |
| 75 | 70 | ||
| 76 | /// Bind the socket to a local endpoint. | 71 | /// Bind the socket to a local endpoint. |
| @@ -82,7 +77,7 @@ impl<'a> UdpSocket<'a> { | |||
| 82 | 77 | ||
| 83 | if endpoint.port == 0 { | 78 | if endpoint.port == 0 { |
| 84 | // If user didn't specify port allocate a dynamic port. | 79 | // If user didn't specify port allocate a dynamic port. |
| 85 | endpoint.port = self.stack.borrow_mut().get_local_port(); | 80 | endpoint.port = self.stack.with_mut(|i| i.get_local_port()); |
| 86 | } | 81 | } |
| 87 | 82 | ||
| 88 | match self.with_mut(|s, _| s.bind(endpoint)) { | 83 | match self.with_mut(|s, _| s.bind(endpoint)) { |
| @@ -93,17 +88,19 @@ impl<'a> UdpSocket<'a> { | |||
| 93 | } | 88 | } |
| 94 | 89 | ||
| 95 | fn with<R>(&self, f: impl FnOnce(&udp::Socket, &Interface) -> R) -> R { | 90 | fn with<R>(&self, f: impl FnOnce(&udp::Socket, &Interface) -> R) -> R { |
| 96 | let s = &*self.stack.borrow(); | 91 | self.stack.with(|i| { |
| 97 | let socket = s.sockets.get::<udp::Socket>(self.handle); | 92 | let socket = i.sockets.get::<udp::Socket>(self.handle); |
| 98 | f(socket, &s.iface) | 93 | f(socket, &i.iface) |
| 94 | }) | ||
| 99 | } | 95 | } |
| 100 | 96 | ||
| 101 | fn with_mut<R>(&self, f: impl FnOnce(&mut udp::Socket, &mut Interface) -> R) -> R { | 97 | fn with_mut<R>(&self, f: impl FnOnce(&mut udp::Socket, &mut Interface) -> R) -> R { |
| 102 | let s = &mut *self.stack.borrow_mut(); | 98 | self.stack.with_mut(|i| { |
| 103 | let socket = s.sockets.get_mut::<udp::Socket>(self.handle); | 99 | let socket = i.sockets.get_mut::<udp::Socket>(self.handle); |
| 104 | let res = f(socket, &mut s.iface); | 100 | let res = f(socket, &mut i.iface); |
| 105 | s.waker.wake(); | 101 | i.waker.wake(); |
| 106 | res | 102 | res |
| 103 | }) | ||
| 107 | } | 104 | } |
| 108 | 105 | ||
| 109 | /// Receive a datagram. | 106 | /// Receive a datagram. |
| @@ -298,6 +295,10 @@ impl<'a> UdpSocket<'a> { | |||
| 298 | 295 | ||
| 299 | impl Drop for UdpSocket<'_> { | 296 | impl Drop for UdpSocket<'_> { |
| 300 | fn drop(&mut self) { | 297 | fn drop(&mut self) { |
| 301 | self.stack.borrow_mut().sockets.remove(self.handle); | 298 | self.stack.with_mut(|i| i.sockets.remove(self.handle)); |
| 302 | } | 299 | } |
| 303 | } | 300 | } |
| 301 | |||
| 302 | fn _assert_covariant<'a, 'b: 'a>(x: UdpSocket<'b>) -> UdpSocket<'a> { | ||
| 303 | x | ||
| 304 | } | ||
