aboutsummaryrefslogtreecommitdiff
path: root/embassy-net/src/udp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-net/src/udp.rs')
-rw-r--r--embassy-net/src/udp.rs63
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
3use core::cell::RefCell;
4use core::future::poll_fn; 3use core::future::poll_fn;
5use core::mem; 4use core::mem;
6use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
7 6
8use embassy_net_driver::Driver;
9use smoltcp::iface::{Interface, SocketHandle}; 7use smoltcp::iface::{Interface, SocketHandle};
10use smoltcp::socket::udp; 8use smoltcp::socket::udp;
11pub use smoltcp::socket::udp::{PacketMetadata, UdpMetadata}; 9pub use smoltcp::socket::udp::{PacketMetadata, UdpMetadata};
12use smoltcp::wire::IpListenEndpoint; 10use smoltcp::wire::IpListenEndpoint;
13 11
14use crate::{SocketStack, Stack}; 12use 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.
45pub struct UdpSocket<'a> { 43pub struct UdpSocket<'a> {
46 stack: &'a RefCell<SocketStack>, 44 stack: Stack<'a>,
47 handle: SocketHandle, 45 handle: SocketHandle,
48} 46}
49 47
50impl<'a> UdpSocket<'a> { 48impl<'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
299impl Drop for UdpSocket<'_> { 296impl 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
302fn _assert_covariant<'a, 'b: 'a>(x: UdpSocket<'b>) -> UdpSocket<'a> {
303 x
304}