From c22218c72e4940a0aef3fc180ba18b557713cf40 Mon Sep 17 00:00:00 2001 From: Leon Camus Date: Mon, 6 Mar 2023 17:50:57 +0100 Subject: [PATCH 1/5] feat: Add multicast to udp socket --- embassy-net/Cargo.toml | 3 ++- embassy-net/src/lib.rs | 37 +++++++++++++++++++++++++++++++++ embassy-net/src/udp.rs | 47 ++++++++++++++++++++++++++++++------------ 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index ca34262d..1854d204 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" [package.metadata.embassy_docs] src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-v$VERSION/embassy-net/src/" src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net/src/" -features = ["nightly", "unstable-traits", "defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip"] +features = ["nightly", "unstable-traits", "defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "igmp"] target = "thumbv7em-none-eabi" [features] @@ -27,6 +27,7 @@ dhcpv4 = ["medium-ethernet", "smoltcp/socket-dhcpv4"] proto-ipv6 = ["smoltcp/proto-ipv6"] medium-ethernet = ["smoltcp/medium-ethernet"] medium-ip = ["smoltcp/medium-ip"] +igmp = ["smoltcp/proto-igmp"] [dependencies] diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 4ec1b5a7..57055bd7 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -304,6 +304,43 @@ impl Stack { } } +#[cfg(feature = "igmp")] +impl Stack { + pub(crate) fn join_multicast_group(&self, addr: T) -> Result + where + T: Into + { + let addr = addr.into(); + + self.with_mut(|s, i| { + s.iface.join_multicast_group( + &mut i.device, + addr, + instant_to_smoltcp(Instant::now()), + ) + }) + } + + pub(crate) fn leave_multicast_group(&self, addr: T) -> Result + where + T: Into + { + let addr = addr.into(); + + self.with_mut(|s, i| { + s.iface.leave_multicast_group( + &mut i.device, + addr, + instant_to_smoltcp(Instant::now()), + ) + }) + } + + pub(crate) fn has_multicast_group>(&self, addr: T) -> bool { + self.socket.borrow().iface.has_multicast_group(addr) + } +} + impl SocketStack { #[allow(clippy::absurd_extreme_comparisons, dead_code)] pub fn get_local_port(&mut self) -> u16 { diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index 0ee8c6e1..c840eeaa 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -6,9 +6,9 @@ use core::task::Poll; use embassy_net_driver::Driver; use smoltcp::iface::{Interface, SocketHandle}; use smoltcp::socket::udp::{self, PacketMetadata}; -use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; +use smoltcp::wire::{IpAddress, IpEndpoint, IpListenEndpoint}; -use crate::{SocketStack, Stack}; +use crate::Stack; #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -26,13 +26,13 @@ pub enum Error { NoRoute, } -pub struct UdpSocket<'a> { - stack: &'a RefCell, +pub struct UdpSocket<'a, D: Driver> { + stack: &'a Stack, handle: SocketHandle, } -impl<'a> UdpSocket<'a> { - pub fn new( +impl<'a, D: Driver> UdpSocket<'a, D> { + pub fn new( stack: &'a Stack, rx_meta: &'a mut [PacketMetadata], rx_buffer: &'a mut [u8], @@ -51,7 +51,7 @@ impl<'a> UdpSocket<'a> { )); Self { - stack: &stack.socket, + stack, handle, } } @@ -64,7 +64,7 @@ impl<'a> UdpSocket<'a> { if endpoint.port == 0 { // If user didn't specify port allocate a dynamic port. - endpoint.port = self.stack.borrow_mut().get_local_port(); + endpoint.port = self.stack.socket.borrow_mut().get_local_port(); } match self.with_mut(|s, _| s.bind(endpoint)) { @@ -75,13 +75,13 @@ impl<'a> UdpSocket<'a> { } fn with(&self, f: impl FnOnce(&udp::Socket, &Interface) -> R) -> R { - let s = &*self.stack.borrow(); + let s = &*self.stack.socket.borrow(); let socket = s.sockets.get::(self.handle); f(socket, &s.iface) } fn with_mut(&self, f: impl FnOnce(&mut udp::Socket, &mut Interface) -> R) -> R { - let s = &mut *self.stack.borrow_mut(); + let s = &mut *self.stack.socket.borrow_mut(); let socket = s.sockets.get_mut::(self.handle); let res = f(socket, &mut s.iface); s.waker.wake(); @@ -143,8 +143,29 @@ impl<'a> UdpSocket<'a> { } } -impl Drop for UdpSocket<'_> { - fn drop(&mut self) { - self.stack.borrow_mut().sockets.remove(self.handle); +#[cfg(feature = "igmp")] +impl<'a, D: Driver + smoltcp::phy::Device + 'static> UdpSocket<'a, D> { + pub fn join_multicast_group(&self, addr: T) -> Result + where + T: Into + { + self.stack.join_multicast_group(addr) + } + + pub fn leave_multicast_group(&self, addr: T) -> Result + where + T: Into + { + self.stack.leave_multicast_group(addr) + } + + pub fn has_multicast_group>(&self, addr: T) -> bool { + self.stack.has_multicast_group(addr) + } +} + +impl Drop for UdpSocket<'_, D> { + fn drop(&mut self) { + self.stack.socket.borrow_mut().sockets.remove(self.handle); } } From b62e3e1d47ef6d326e4b214bd7ac1e52142f2e3d Mon Sep 17 00:00:00 2001 From: Leon Camus Date: Tue, 7 Mar 2023 23:40:20 +0100 Subject: [PATCH 2/5] lint: Cargo fmt --- embassy-net/src/lib.rs | 22 ++++++++-------------- embassy-net/src/udp.rs | 13 +++++-------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 57055bd7..05bbd07f 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -307,32 +307,26 @@ impl Stack { #[cfg(feature = "igmp")] impl Stack { pub(crate) fn join_multicast_group(&self, addr: T) -> Result - where - T: Into + where + T: Into, { let addr = addr.into(); self.with_mut(|s, i| { - s.iface.join_multicast_group( - &mut i.device, - addr, - instant_to_smoltcp(Instant::now()), - ) + s.iface + .join_multicast_group(&mut i.device, addr, instant_to_smoltcp(Instant::now())) }) } pub(crate) fn leave_multicast_group(&self, addr: T) -> Result - where - T: Into + where + T: Into, { let addr = addr.into(); self.with_mut(|s, i| { - s.iface.leave_multicast_group( - &mut i.device, - addr, - instant_to_smoltcp(Instant::now()), - ) + s.iface + .leave_multicast_group(&mut i.device, addr, instant_to_smoltcp(Instant::now())) }) } diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index c840eeaa..a8a42604 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -50,10 +50,7 @@ impl<'a, D: Driver> UdpSocket<'a, D> { udp::PacketBuffer::new(tx_meta, tx_buffer), )); - Self { - stack, - handle, - } + Self { stack, handle } } pub fn bind(&mut self, endpoint: T) -> Result<(), BindError> @@ -146,15 +143,15 @@ impl<'a, D: Driver> UdpSocket<'a, D> { #[cfg(feature = "igmp")] impl<'a, D: Driver + smoltcp::phy::Device + 'static> UdpSocket<'a, D> { pub fn join_multicast_group(&self, addr: T) -> Result - where - T: Into + where + T: Into, { self.stack.join_multicast_group(addr) } pub fn leave_multicast_group(&self, addr: T) -> Result - where - T: Into + where + T: Into, { self.stack.leave_multicast_group(addr) } From 208756100304647d2ba12507b494663ddd37e90c Mon Sep 17 00:00:00 2001 From: Leon Camus Date: Tue, 7 Mar 2023 23:51:10 +0100 Subject: [PATCH 3/5] lint: Remove unused imports --- embassy-net/src/udp.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index a8a42604..78db9c8a 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -1,4 +1,3 @@ -use core::cell::RefCell; use core::future::poll_fn; use core::mem; use core::task::Poll; @@ -6,7 +5,7 @@ use core::task::Poll; use embassy_net_driver::Driver; use smoltcp::iface::{Interface, SocketHandle}; use smoltcp::socket::udp::{self, PacketMetadata}; -use smoltcp::wire::{IpAddress, IpEndpoint, IpListenEndpoint}; +use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; use crate::Stack; From 993875e11fc58a476b1e08d4aba752b83bb2b885 Mon Sep 17 00:00:00 2001 From: Leon Camus Date: Tue, 7 Mar 2023 23:52:25 +0100 Subject: [PATCH 4/5] fix: Add qualified imports --- embassy-net/src/udp.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index 78db9c8a..12bdbf40 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -143,19 +143,19 @@ impl<'a, D: Driver> UdpSocket<'a, D> { impl<'a, D: Driver + smoltcp::phy::Device + 'static> UdpSocket<'a, D> { pub fn join_multicast_group(&self, addr: T) -> Result where - T: Into, + T: Into, { self.stack.join_multicast_group(addr) } pub fn leave_multicast_group(&self, addr: T) -> Result where - T: Into, + T: Into, { self.stack.leave_multicast_group(addr) } - pub fn has_multicast_group>(&self, addr: T) -> bool { + pub fn has_multicast_group>(&self, addr: T) -> bool { self.stack.has_multicast_group(addr) } } From e484cb1b875adc7a0865299df5167f94302fcf49 Mon Sep 17 00:00:00 2001 From: Leon Camus Date: Wed, 8 Mar 2023 12:37:00 +0100 Subject: [PATCH 5/5] refactor: Multicast method modifiers on stack to public revert: udp.rs --- embassy-net/src/lib.rs | 6 +++--- embassy-net/src/udp.rs | 47 ++++++++++++++---------------------------- 2 files changed, 18 insertions(+), 35 deletions(-) diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 05bbd07f..7b9d0e77 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -306,7 +306,7 @@ impl Stack { #[cfg(feature = "igmp")] impl Stack { - pub(crate) fn join_multicast_group(&self, addr: T) -> Result + pub fn join_multicast_group(&self, addr: T) -> Result where T: Into, { @@ -318,7 +318,7 @@ impl Stack { }) } - pub(crate) fn leave_multicast_group(&self, addr: T) -> Result + pub fn leave_multicast_group(&self, addr: T) -> Result where T: Into, { @@ -330,7 +330,7 @@ impl Stack { }) } - pub(crate) fn has_multicast_group>(&self, addr: T) -> bool { + pub fn has_multicast_group>(&self, addr: T) -> bool { self.socket.borrow().iface.has_multicast_group(addr) } } diff --git a/embassy-net/src/udp.rs b/embassy-net/src/udp.rs index 12bdbf40..0ee8c6e1 100644 --- a/embassy-net/src/udp.rs +++ b/embassy-net/src/udp.rs @@ -1,3 +1,4 @@ +use core::cell::RefCell; use core::future::poll_fn; use core::mem; use core::task::Poll; @@ -7,7 +8,7 @@ use smoltcp::iface::{Interface, SocketHandle}; use smoltcp::socket::udp::{self, PacketMetadata}; use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; -use crate::Stack; +use crate::{SocketStack, Stack}; #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -25,13 +26,13 @@ pub enum Error { NoRoute, } -pub struct UdpSocket<'a, D: Driver> { - stack: &'a Stack, +pub struct UdpSocket<'a> { + stack: &'a RefCell, handle: SocketHandle, } -impl<'a, D: Driver> UdpSocket<'a, D> { - pub fn new( +impl<'a> UdpSocket<'a> { + pub fn new( stack: &'a Stack, rx_meta: &'a mut [PacketMetadata], rx_buffer: &'a mut [u8], @@ -49,7 +50,10 @@ impl<'a, D: Driver> UdpSocket<'a, D> { udp::PacketBuffer::new(tx_meta, tx_buffer), )); - Self { stack, handle } + Self { + stack: &stack.socket, + handle, + } } pub fn bind(&mut self, endpoint: T) -> Result<(), BindError> @@ -60,7 +64,7 @@ impl<'a, D: Driver> UdpSocket<'a, D> { if endpoint.port == 0 { // If user didn't specify port allocate a dynamic port. - endpoint.port = self.stack.socket.borrow_mut().get_local_port(); + endpoint.port = self.stack.borrow_mut().get_local_port(); } match self.with_mut(|s, _| s.bind(endpoint)) { @@ -71,13 +75,13 @@ impl<'a, D: Driver> UdpSocket<'a, D> { } fn with(&self, f: impl FnOnce(&udp::Socket, &Interface) -> R) -> R { - let s = &*self.stack.socket.borrow(); + let s = &*self.stack.borrow(); let socket = s.sockets.get::(self.handle); f(socket, &s.iface) } fn with_mut(&self, f: impl FnOnce(&mut udp::Socket, &mut Interface) -> R) -> R { - let s = &mut *self.stack.socket.borrow_mut(); + let s = &mut *self.stack.borrow_mut(); let socket = s.sockets.get_mut::(self.handle); let res = f(socket, &mut s.iface); s.waker.wake(); @@ -139,29 +143,8 @@ impl<'a, D: Driver> UdpSocket<'a, D> { } } -#[cfg(feature = "igmp")] -impl<'a, D: Driver + smoltcp::phy::Device + 'static> UdpSocket<'a, D> { - pub fn join_multicast_group(&self, addr: T) -> Result - where - T: Into, - { - self.stack.join_multicast_group(addr) - } - - pub fn leave_multicast_group(&self, addr: T) -> Result - where - T: Into, - { - self.stack.leave_multicast_group(addr) - } - - pub fn has_multicast_group>(&self, addr: T) -> bool { - self.stack.has_multicast_group(addr) - } -} - -impl Drop for UdpSocket<'_, D> { +impl Drop for UdpSocket<'_> { fn drop(&mut self) { - self.stack.socket.borrow_mut().sockets.remove(self.handle); + self.stack.borrow_mut().sockets.remove(self.handle); } }