From f54e1cea90527871f65ea449e58dc57fcf7cdb37 Mon Sep 17 00:00:00 2001 From: Roy Buitenhuis Date: Wed, 12 Jul 2023 11:32:02 +0200 Subject: [PATCH 1/3] Add poll functions on UdpSocket. --- embassy-net/src/udp.rs | 47 +++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index 36f8d06f2..bd7a32f7c 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -102,37 +102,42 @@ impl<'a> UdpSocket<'a> { /// /// Returns the number of bytes received and the remote endpoint. pub async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, IpEndpoint), Error> { - poll_fn(move |cx| { - self.with_mut(|s, _| match s.recv_slice(buf) { - Ok((n, meta)) => Poll::Ready(Ok((n, meta.endpoint))), - // No data ready - Err(udp::RecvError::Exhausted) => { - s.register_recv_waker(cx.waker()); - Poll::Pending - } - }) + poll_fn(move |cx| self.poll_recv_from(buf, cx)).await + } + + pub fn poll_recv_from(&self, buf: &mut[u8], cx: Context) -> Poll> { + self.with_mut(|s, _| match s.recv_slice(buf) { + Ok((n, meta)) => Poll::Ready(Ok((n, meta.endpoint))), + // No data ready + Err(udp::RecvError::Exhausted) => { + s.register_recv_waker(cx.waker()); + Poll::Pending + } }) - .await } /// Send a datagram to the specified remote endpoint. pub async fn send_to(&self, buf: &[u8], remote_endpoint: T) -> Result<(), Error> + where + T: Into, + { + poll_fn(move |cx| self.poll_send_to(buf, remote_endpoint, cx)).await + } + + pub fn poll_send_to(&self, buf: &[u8], remote_endpoint: T, cx: Context) -> Poll> where T: Into, { let remote_endpoint = remote_endpoint.into(); - poll_fn(move |cx| { - self.with_mut(|s, _| match s.send_slice(buf, remote_endpoint) { - // Entire datagram has been sent - Ok(()) => Poll::Ready(Ok(())), - Err(udp::SendError::BufferFull) => { - s.register_send_waker(cx.waker()); - Poll::Pending - } - Err(udp::SendError::Unaddressable) => Poll::Ready(Err(Error::NoRoute)), - }) + self.with_mut(|s, _| match s.send_slice(buf, remote_endpoint) { + // Entire datagram has been sent + Ok(()) => Poll::Ready(Ok(())), + Err(udp::SendError::BufferFull) => { + s.register_send_waker(cx.waker()); + Poll::Pending + } + Err(udp::SendError::Unaddressable) => Poll::Ready(Err(Error::NoRoute)), }) - .await } /// Returns the local endpoint of the socket. From b81c14f442839de61f2217cf88e09d390d465f3d Mon Sep 17 00:00:00 2001 From: Roy Buitenhuis Date: Wed, 12 Jul 2023 11:32:02 +0200 Subject: [PATCH 2/3] Add polling fn's for send_to and recv_from in UdpSocket. --- embassy-net/src/udp.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index bd7a32f7c..16f48bcb0 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -3,7 +3,7 @@ use core::cell::RefCell; use core::future::poll_fn; use core::mem; -use core::task::Poll; +use core::task::{Poll, Context}; use embassy_net_driver::Driver; use smoltcp::iface::{Interface, SocketHandle}; @@ -105,7 +105,14 @@ impl<'a> UdpSocket<'a> { poll_fn(move |cx| self.poll_recv_from(buf, cx)).await } - pub fn poll_recv_from(&self, buf: &mut[u8], cx: Context) -> Poll> { + /// Receive a datagram. + /// + /// When no datagram is available, this method will return `Poll::Pending` and + /// register the current task to be notified when a datagram is received. + /// + /// When a datagram is received, this method will return `Poll::Ready` with the + /// number of bytes received and the remote endpoint. + pub fn poll_recv_from(&self, buf: &mut[u8], cx: &mut Context<'_>) -> Poll> { self.with_mut(|s, _| match s.recv_slice(buf) { Ok((n, meta)) => Poll::Ready(Ok((n, meta.endpoint))), // No data ready @@ -117,18 +124,30 @@ impl<'a> UdpSocket<'a> { } /// Send a datagram to the specified remote endpoint. + /// + /// This method will wait until the datagram has been sent. + /// + /// When the remote endpoint is not reachable, this method will return `Err(Error::NoRoute)` pub async fn send_to(&self, buf: &[u8], remote_endpoint: T) -> Result<(), Error> where T: Into, { + let remote_endpoint: IpEndpoint = remote_endpoint.into(); poll_fn(move |cx| self.poll_send_to(buf, remote_endpoint, cx)).await } - pub fn poll_send_to(&self, buf: &[u8], remote_endpoint: T, cx: Context) -> Poll> + /// Send a datagram to the specified remote endpoint. + /// + /// When the datagram has been sent, this method will return `Poll::Ready(Ok())`. + /// + /// When the socket's send buffer is full, this method will return `Poll::Pending` + /// and register the current task to be notified when the buffer has space available. + /// + /// When the remote endpoint is not reachable, this method will return `Poll::Ready(Err(Error::NoRoute))`. + pub fn poll_send_to(&self, buf: &[u8], remote_endpoint: T, cx: &mut Context<'_>) -> Poll> where T: Into, { - let remote_endpoint = remote_endpoint.into(); self.with_mut(|s, _| match s.send_slice(buf, remote_endpoint) { // Entire datagram has been sent Ok(()) => Poll::Ready(Ok(())), From f192f440187c705ce2674731c4d595dc327f08a3 Mon Sep 17 00:00:00 2001 From: Roy Buitenhuis Date: Wed, 12 Jul 2023 11:32:02 +0200 Subject: [PATCH 3/3] fmt --- embassy-net/src/udp.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index 16f48bcb0..0d97b6db1 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -3,7 +3,7 @@ use core::cell::RefCell; use core::future::poll_fn; use core::mem; -use core::task::{Poll, Context}; +use core::task::{Context, Poll}; use embassy_net_driver::Driver; use smoltcp::iface::{Interface, SocketHandle}; @@ -106,13 +106,13 @@ impl<'a> UdpSocket<'a> { } /// Receive a datagram. - /// + /// /// When no datagram is available, this method will return `Poll::Pending` and /// register the current task to be notified when a datagram is received. - /// + /// /// When a datagram is received, this method will return `Poll::Ready` with the /// number of bytes received and the remote endpoint. - pub fn poll_recv_from(&self, buf: &mut[u8], cx: &mut Context<'_>) -> Poll> { + pub fn poll_recv_from(&self, buf: &mut [u8], cx: &mut Context<'_>) -> Poll> { self.with_mut(|s, _| match s.recv_slice(buf) { Ok((n, meta)) => Poll::Ready(Ok((n, meta.endpoint))), // No data ready @@ -124,9 +124,9 @@ impl<'a> UdpSocket<'a> { } /// Send a datagram to the specified remote endpoint. - /// + /// /// This method will wait until the datagram has been sent. - /// + /// /// When the remote endpoint is not reachable, this method will return `Err(Error::NoRoute)` pub async fn send_to(&self, buf: &[u8], remote_endpoint: T) -> Result<(), Error> where @@ -137,12 +137,12 @@ impl<'a> UdpSocket<'a> { } /// Send a datagram to the specified remote endpoint. - /// + /// /// When the datagram has been sent, this method will return `Poll::Ready(Ok())`. - /// + /// /// When the socket's send buffer is full, this method will return `Poll::Pending` /// and register the current task to be notified when the buffer has space available. - /// + /// /// When the remote endpoint is not reachable, this method will return `Poll::Ready(Err(Error::NoRoute))`. pub fn poll_send_to(&self, buf: &[u8], remote_endpoint: T, cx: &mut Context<'_>) -> Poll> where