From 0427c442ea531673e18da304c7402927589b8d0b Mon Sep 17 00:00:00 2001
From: Gustav Toft <guto@factbird.com>
Date: Thu, 4 Apr 2024 15:51:25 +0200
Subject: [PATCH 1/6] Implement raw sockets in embassy-net

---
 embassy-net/Cargo.toml |   6 +-
 embassy-net/src/lib.rs |   2 +
 embassy-net/src/raw.rs | 178 +++++++++++++++++++++++++++++++++++++++++
 examples/rp/Cargo.toml |   2 +-
 4 files changed, 185 insertions(+), 3 deletions(-)
 create mode 100644 embassy-net/src/raw.rs

diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index be9f1d784..47faaa205 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -16,11 +16,11 @@ categories = [
 [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 = ["defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
+features = ["defmt", "tcp", "udp","raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
 target = "thumbv7em-none-eabi"
 
 [package.metadata.docs.rs]
-features = ["defmt", "tcp", "udp", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
+features = ["defmt", "tcp", "udp", "raw","dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
 
 [features]
 default = []
@@ -38,6 +38,8 @@ packet-trace = []
 
 ## Enable UDP support
 udp = ["smoltcp/socket-udp"]
+## Enable Raw support
+raw = ["smoltcp/socket-raw"]
 ## Enable TCP support
 tcp = ["smoltcp/socket-tcp"]
 ## Enable DNS support
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index 1c0cf1a12..05c8aec7b 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -20,6 +20,8 @@ pub mod tcp;
 mod time;
 #[cfg(feature = "udp")]
 pub mod udp;
+#[cfg(feature = "raw")]
+pub mod raw;
 
 use core::cell::RefCell;
 use core::future::{poll_fn, Future};
diff --git a/embassy-net/src/raw.rs b/embassy-net/src/raw.rs
new file mode 100644
index 000000000..a0e458fff
--- /dev/null
+++ b/embassy-net/src/raw.rs
@@ -0,0 +1,178 @@
+//! Raw sockets.
+
+use core::cell::RefCell;
+use core::future::poll_fn;
+use core::mem;
+use core::task::{Context, Poll};
+
+use embassy_net_driver::Driver;
+use smoltcp::iface::{Interface, SocketHandle};
+use smoltcp::socket::raw;
+pub use smoltcp::socket::raw::PacketMetadata;
+use smoltcp::wire::{IpProtocol, IpVersion};
+
+use crate::{SocketStack, Stack};
+
+
+/// Unrelavent for RawSocket?
+/* /// Error returned by [`RawSocket::bind`].
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum BindError {
+    /// The socket was already open.
+    InvalidState,
+    /// No route to host.
+    NoRoute,
+} */
+
+/// Error returned by [`RawSocket::recv_from`] and [`RawSocket::send_to`].
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum SendError {
+    /// No route to host.
+    NoRoute,
+    /// Socket not bound to an outgoing port.
+    SocketNotBound,
+}
+
+/// Error returned by [`RawSocket::recv`] and [`RawSocket::send`].
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum RecvError {
+    /// Provided buffer was smaller than the received packet.
+    Truncated,
+}
+
+/// An Raw socket.
+pub struct RawSocket<'a> {
+    stack: &'a RefCell<SocketStack>,
+    handle: SocketHandle,
+}
+
+impl<'a> RawSocket<'a> {
+    /// Create a new Raw socket using the provided stack and buffers.
+    pub fn new<D: Driver>(
+        stack: &'a Stack<D>,
+        ip_version: IpVersion,
+        ip_protocol: IpProtocol,
+        rx_meta: &'a mut [PacketMetadata],
+        rx_buffer: &'a mut [u8],
+        tx_meta: &'a mut [PacketMetadata],
+        tx_buffer: &'a mut [u8],
+    ) -> Self {
+        let s = &mut *stack.socket.borrow_mut();
+
+        let rx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(rx_meta) };
+        let rx_buffer: &'static mut [u8] = unsafe { mem::transmute(rx_buffer) };
+        let tx_meta: &'static mut [PacketMetadata] = unsafe { mem::transmute(tx_meta) };
+        let tx_buffer: &'static mut [u8] = unsafe { mem::transmute(tx_buffer) };
+        let handle = s.sockets.add(raw::Socket::new(
+            ip_version,
+            ip_protocol,
+            raw::PacketBuffer::new(rx_meta, rx_buffer),
+            raw::PacketBuffer::new(tx_meta, tx_buffer),
+        ));
+
+        Self {
+            stack: &stack.socket,
+            handle,
+        }
+    }
+
+    fn with_mut<R>(&self, f: impl FnOnce(&mut raw::Socket, &mut Interface) -> R) -> R {
+        let s = &mut *self.stack.borrow_mut();
+        let socket = s.sockets.get_mut::<raw::Socket>(self.handle);
+        let res = f(socket, &mut s.iface);
+        s.waker.wake();
+        res
+    }
+
+    /// Bind the socket to a local endpoint.
+    /// 
+    /// How to handle this in RawSocket? no need for bind?
+    /// 
+    /* pub fn bind<T>(&mut self, endpoint: T) -> Result<(), BindError>
+    where
+        T: Into<IpListenEndpoint>,
+    {
+        let mut endpoint = endpoint.into();
+
+        if endpoint.port == 0 {
+            // If user didn't specify port allocate a dynamic port.
+            endpoint.port = self.stack.borrow_mut().get_local_port();
+        }
+
+        match self.with_mut(|s, _| s.bind(endpoint)) {
+            Ok(()) => Ok(()),
+            Err(raw::BindError::InvalidState) => Err(BindError::InvalidState),
+            Err(raw::BindError::Unaddressable) => Err(BindError::NoRoute),
+        }
+    }
+
+    fn with<R>(&self, f: impl FnOnce(&raw::Socket, &Interface) -> R) -> R {
+        let s = &*self.stack.borrow();
+        let socket = s.sockets.get::<raw::Socket>(self.handle);
+        f(socket, &s.iface)
+    }
+
+    fn with_mut<R>(&self, f: impl FnOnce(&mut raw::Socket, &mut Interface) -> R) -> R {
+        let s = &mut *self.stack.borrow_mut();
+        let socket = s.sockets.get_mut::<raw::Socket>(self.handle);
+        let res = f(socket, &mut s.iface);
+        s.waker.wake();
+        res
+    } */
+
+    /// Receive a datagram.
+    ///
+    /// This method will wait until a datagram is received.
+    pub async fn recv(&self, buf: &mut [u8]) -> Result<usize, RecvError> {
+        poll_fn(move |cx| self.poll_recv(buf, cx)).await
+    }
+
+    /// 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.
+    pub fn poll_recv(&self, buf: &mut [u8], cx: &mut Context<'_>) -> Poll<Result<usize, RecvError>> {
+        self.with_mut(|s, _| match s.recv_slice(buf) {
+            Ok(n) => Poll::Ready(Ok(n)),
+            // No data ready
+            Err(raw::RecvError::Truncated) => Poll::Ready(Err(RecvError::Truncated)),
+            Err(raw::RecvError::Exhausted) => {
+                s.register_recv_waker(cx.waker());
+                Poll::Pending
+            }
+        })
+    }
+
+    /// Send a datagram.
+    ///
+    /// This method will wait until the datagram has been sent.`
+    pub async fn send<T>(&self, buf: &[u8]) -> Result<(), SendError> {
+        poll_fn(move |cx| self.poll_send(buf, cx)).await
+    }
+
+    /// Send a datagram.
+    ///
+    /// 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.
+    pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<Result<(), SendError>>{
+        self.with_mut(|s, _| match s.send_slice(buf) {
+            // Entire datagram has been sent
+            Ok(()) => Poll::Ready(Ok(())),
+            Err(raw::SendError::BufferFull) => {
+                s.register_send_waker(cx.waker());
+                Poll::Pending
+            }
+        })
+    }
+    }
+
+impl Drop for RawSocket<'_> {
+    fn drop(&mut self) {
+        self.stack.borrow_mut().sockets.remove(self.handle);
+    }
+}
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml
index 585349506..0f58f143c 100644
--- a/examples/rp/Cargo.toml
+++ b/examples/rp/Cargo.toml
@@ -12,7 +12,7 @@ embassy-executor = { version = "0.5.0", path = "../../embassy-executor", feature
 embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
 embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-pac", "time-driver", "critical-section-impl"] }
 embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
-embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
+embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet"] }
 embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
 embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
 embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" }

From 6663be0b36a078893b0ef3f3f869b17adf62ca30 Mon Sep 17 00:00:00 2001
From: Gustav Toft <guto@factbird.com>
Date: Wed, 10 Apr 2024 09:07:20 +0200
Subject: [PATCH 2/6] Fixed commented issues.

---
 .vscode/settings.json  | 12 ++++----
 embassy-net/Cargo.toml |  4 +--
 embassy-net/src/lib.rs |  4 +--
 embassy-net/src/raw.rs | 64 ++----------------------------------------
 4 files changed, 13 insertions(+), 71 deletions(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index 0c195a13b..343331950 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -10,24 +10,24 @@
   "rust-analyzer.cargo.noDefaultFeatures": true,
   "rust-analyzer.showUnlinkedFileNotification": false,
   // uncomment the target of your chip.
-  //"rust-analyzer.cargo.target": "thumbv6m-none-eabi",
+  "rust-analyzer.cargo.target": "thumbv6m-none-eabi",
   //"rust-analyzer.cargo.target": "thumbv7m-none-eabi",
-  "rust-analyzer.cargo.target": "thumbv7em-none-eabi",
+  //"rust-analyzer.cargo.target": "thumbv7em-none-eabi",
   //"rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf",
-  "rust-analyzer.cargo.features": [
+  /* "rust-analyzer.cargo.features": [
     "stm32f103c8",
     "time-driver-any",
     "unstable-pac",
     "exti",
-  ],
+  ], */
   "rust-analyzer.linkedProjects": [
     // Uncomment ONE line for the chip you want to work on.
     // This makes rust-analyzer work on the example crate and all its dependencies.
-    "embassy-stm32/Cargo.toml",
+    // "embassy-stm32/Cargo.toml",
     // "examples/nrf52840-rtic/Cargo.toml",
     // "examples/nrf5340/Cargo.toml",
     // "examples/nrf-rtos-trace/Cargo.toml",
-    // "examples/rp/Cargo.toml",
+    "examples/rp/Cargo.toml",
     // "examples/std/Cargo.toml",
     // "examples/stm32c0/Cargo.toml",
     // "examples/stm32f0/Cargo.toml",
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index 47faaa205..ee7289ad8 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -16,11 +16,11 @@ categories = [
 [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 = ["defmt", "tcp", "udp","raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
+features = ["defmt", "tcp", "udp", "raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
 target = "thumbv7em-none-eabi"
 
 [package.metadata.docs.rs]
-features = ["defmt", "tcp", "udp", "raw","dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
+features = ["defmt", "tcp", "udp", "raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
 
 [features]
 default = []
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index 05c8aec7b..86ced1ded 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -15,13 +15,13 @@ pub(crate) mod fmt;
 mod device;
 #[cfg(feature = "dns")]
 pub mod dns;
+#[cfg(feature = "raw")]
+pub mod raw;
 #[cfg(feature = "tcp")]
 pub mod tcp;
 mod time;
 #[cfg(feature = "udp")]
 pub mod udp;
-#[cfg(feature = "raw")]
-pub mod raw;
 
 use core::cell::RefCell;
 use core::future::{poll_fn, Future};
diff --git a/embassy-net/src/raw.rs b/embassy-net/src/raw.rs
index a0e458fff..ad8d69853 100644
--- a/embassy-net/src/raw.rs
+++ b/embassy-net/src/raw.rs
@@ -13,28 +13,6 @@ use smoltcp::wire::{IpProtocol, IpVersion};
 
 use crate::{SocketStack, Stack};
 
-
-/// Unrelavent for RawSocket?
-/* /// Error returned by [`RawSocket::bind`].
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
-pub enum BindError {
-    /// The socket was already open.
-    InvalidState,
-    /// No route to host.
-    NoRoute,
-} */
-
-/// Error returned by [`RawSocket::recv_from`] and [`RawSocket::send_to`].
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
-pub enum SendError {
-    /// No route to host.
-    NoRoute,
-    /// Socket not bound to an outgoing port.
-    SocketNotBound,
-}
-
 /// Error returned by [`RawSocket::recv`] and [`RawSocket::send`].
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -87,42 +65,6 @@ impl<'a> RawSocket<'a> {
         res
     }
 
-    /// Bind the socket to a local endpoint.
-    /// 
-    /// How to handle this in RawSocket? no need for bind?
-    /// 
-    /* pub fn bind<T>(&mut self, endpoint: T) -> Result<(), BindError>
-    where
-        T: Into<IpListenEndpoint>,
-    {
-        let mut endpoint = endpoint.into();
-
-        if endpoint.port == 0 {
-            // If user didn't specify port allocate a dynamic port.
-            endpoint.port = self.stack.borrow_mut().get_local_port();
-        }
-
-        match self.with_mut(|s, _| s.bind(endpoint)) {
-            Ok(()) => Ok(()),
-            Err(raw::BindError::InvalidState) => Err(BindError::InvalidState),
-            Err(raw::BindError::Unaddressable) => Err(BindError::NoRoute),
-        }
-    }
-
-    fn with<R>(&self, f: impl FnOnce(&raw::Socket, &Interface) -> R) -> R {
-        let s = &*self.stack.borrow();
-        let socket = s.sockets.get::<raw::Socket>(self.handle);
-        f(socket, &s.iface)
-    }
-
-    fn with_mut<R>(&self, f: impl FnOnce(&mut raw::Socket, &mut Interface) -> R) -> R {
-        let s = &mut *self.stack.borrow_mut();
-        let socket = s.sockets.get_mut::<raw::Socket>(self.handle);
-        let res = f(socket, &mut s.iface);
-        s.waker.wake();
-        res
-    } */
-
     /// Receive a datagram.
     ///
     /// This method will wait until a datagram is received.
@@ -149,7 +91,7 @@ impl<'a> RawSocket<'a> {
     /// Send a datagram.
     ///
     /// This method will wait until the datagram has been sent.`
-    pub async fn send<T>(&self, buf: &[u8]) -> Result<(), SendError> {
+    pub async fn send<T>(&self, buf: &[u8]) -> Result<(), raw::SendError> {
         poll_fn(move |cx| self.poll_send(buf, cx)).await
     }
 
@@ -159,7 +101,7 @@ impl<'a> RawSocket<'a> {
     ///
     /// 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.
-    pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<Result<(), SendError>>{
+    pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<Result<(), raw::SendError>> {
         self.with_mut(|s, _| match s.send_slice(buf) {
             // Entire datagram has been sent
             Ok(()) => Poll::Ready(Ok(())),
@@ -169,7 +111,7 @@ impl<'a> RawSocket<'a> {
             }
         })
     }
-    }
+}
 
 impl Drop for RawSocket<'_> {
     fn drop(&mut self) {

From 11bf2ca987f5830fe8637029adbc208b1ff7349d Mon Sep 17 00:00:00 2001
From: Gustav Toft <guto@factbird.com>
Date: Wed, 10 Apr 2024 13:26:12 +0200
Subject: [PATCH 3/6] Fixed commented issues

---
 embassy-net/Cargo.toml |  4 +--
 embassy-net/src/lib.rs |  4 +--
 embassy-net/src/raw.rs | 64 ++----------------------------------------
 3 files changed, 7 insertions(+), 65 deletions(-)

diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index 47faaa205..ee7289ad8 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -16,11 +16,11 @@ categories = [
 [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 = ["defmt", "tcp", "udp","raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
+features = ["defmt", "tcp", "udp", "raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
 target = "thumbv7em-none-eabi"
 
 [package.metadata.docs.rs]
-features = ["defmt", "tcp", "udp", "raw","dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
+features = ["defmt", "tcp", "udp", "raw", "dns", "dhcpv4", "proto-ipv6", "medium-ethernet", "medium-ip", "medium-ieee802154", "igmp", "dhcpv4-hostname"]
 
 [features]
 default = []
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index 05c8aec7b..86ced1ded 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -15,13 +15,13 @@ pub(crate) mod fmt;
 mod device;
 #[cfg(feature = "dns")]
 pub mod dns;
+#[cfg(feature = "raw")]
+pub mod raw;
 #[cfg(feature = "tcp")]
 pub mod tcp;
 mod time;
 #[cfg(feature = "udp")]
 pub mod udp;
-#[cfg(feature = "raw")]
-pub mod raw;
 
 use core::cell::RefCell;
 use core::future::{poll_fn, Future};
diff --git a/embassy-net/src/raw.rs b/embassy-net/src/raw.rs
index a0e458fff..ad8d69853 100644
--- a/embassy-net/src/raw.rs
+++ b/embassy-net/src/raw.rs
@@ -13,28 +13,6 @@ use smoltcp::wire::{IpProtocol, IpVersion};
 
 use crate::{SocketStack, Stack};
 
-
-/// Unrelavent for RawSocket?
-/* /// Error returned by [`RawSocket::bind`].
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
-pub enum BindError {
-    /// The socket was already open.
-    InvalidState,
-    /// No route to host.
-    NoRoute,
-} */
-
-/// Error returned by [`RawSocket::recv_from`] and [`RawSocket::send_to`].
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
-pub enum SendError {
-    /// No route to host.
-    NoRoute,
-    /// Socket not bound to an outgoing port.
-    SocketNotBound,
-}
-
 /// Error returned by [`RawSocket::recv`] and [`RawSocket::send`].
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -87,42 +65,6 @@ impl<'a> RawSocket<'a> {
         res
     }
 
-    /// Bind the socket to a local endpoint.
-    /// 
-    /// How to handle this in RawSocket? no need for bind?
-    /// 
-    /* pub fn bind<T>(&mut self, endpoint: T) -> Result<(), BindError>
-    where
-        T: Into<IpListenEndpoint>,
-    {
-        let mut endpoint = endpoint.into();
-
-        if endpoint.port == 0 {
-            // If user didn't specify port allocate a dynamic port.
-            endpoint.port = self.stack.borrow_mut().get_local_port();
-        }
-
-        match self.with_mut(|s, _| s.bind(endpoint)) {
-            Ok(()) => Ok(()),
-            Err(raw::BindError::InvalidState) => Err(BindError::InvalidState),
-            Err(raw::BindError::Unaddressable) => Err(BindError::NoRoute),
-        }
-    }
-
-    fn with<R>(&self, f: impl FnOnce(&raw::Socket, &Interface) -> R) -> R {
-        let s = &*self.stack.borrow();
-        let socket = s.sockets.get::<raw::Socket>(self.handle);
-        f(socket, &s.iface)
-    }
-
-    fn with_mut<R>(&self, f: impl FnOnce(&mut raw::Socket, &mut Interface) -> R) -> R {
-        let s = &mut *self.stack.borrow_mut();
-        let socket = s.sockets.get_mut::<raw::Socket>(self.handle);
-        let res = f(socket, &mut s.iface);
-        s.waker.wake();
-        res
-    } */
-
     /// Receive a datagram.
     ///
     /// This method will wait until a datagram is received.
@@ -149,7 +91,7 @@ impl<'a> RawSocket<'a> {
     /// Send a datagram.
     ///
     /// This method will wait until the datagram has been sent.`
-    pub async fn send<T>(&self, buf: &[u8]) -> Result<(), SendError> {
+    pub async fn send<T>(&self, buf: &[u8]) -> Result<(), raw::SendError> {
         poll_fn(move |cx| self.poll_send(buf, cx)).await
     }
 
@@ -159,7 +101,7 @@ impl<'a> RawSocket<'a> {
     ///
     /// 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.
-    pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<Result<(), SendError>>{
+    pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<Result<(), raw::SendError>> {
         self.with_mut(|s, _| match s.send_slice(buf) {
             // Entire datagram has been sent
             Ok(()) => Poll::Ready(Ok(())),
@@ -169,7 +111,7 @@ impl<'a> RawSocket<'a> {
             }
         })
     }
-    }
+}
 
 impl Drop for RawSocket<'_> {
     fn drop(&mut self) {

From ec0896037ad6c48d527e1abb88ca49ec0f376663 Mon Sep 17 00:00:00 2001
From: Gustav Toft <guto@factbird.com>
Date: Thu, 11 Apr 2024 08:29:06 +0200
Subject: [PATCH 4/6] Removed Result for send and poll_send.

---
 embassy-net/src/raw.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/embassy-net/src/raw.rs b/embassy-net/src/raw.rs
index ad8d69853..a6500a51f 100644
--- a/embassy-net/src/raw.rs
+++ b/embassy-net/src/raw.rs
@@ -91,7 +91,7 @@ impl<'a> RawSocket<'a> {
     /// Send a datagram.
     ///
     /// This method will wait until the datagram has been sent.`
-    pub async fn send<T>(&self, buf: &[u8]) -> Result<(), raw::SendError> {
+    pub async fn send<T>(&self, buf: &[u8]) {
         poll_fn(move |cx| self.poll_send(buf, cx)).await
     }
 
@@ -101,10 +101,10 @@ impl<'a> RawSocket<'a> {
     ///
     /// 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.
-    pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<Result<(), raw::SendError>> {
+    pub fn poll_send(&self, buf: &[u8], cx: &mut Context<'_>) -> Poll<()> {
         self.with_mut(|s, _| match s.send_slice(buf) {
             // Entire datagram has been sent
-            Ok(()) => Poll::Ready(Ok(())),
+            Ok(()) => Poll::Ready(()),
             Err(raw::SendError::BufferFull) => {
                 s.register_send_waker(cx.waker());
                 Poll::Pending

From fd5113eeb00add4af38cb0a3ff95c7d414c68b87 Mon Sep 17 00:00:00 2001
From: Gustav Toft <guto@factbird.com>
Date: Thu, 11 Apr 2024 09:08:10 +0200
Subject: [PATCH 5/6] Restore vscode settings

---
 .vscode/settings.json | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index 343331950..0c195a13b 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -10,24 +10,24 @@
   "rust-analyzer.cargo.noDefaultFeatures": true,
   "rust-analyzer.showUnlinkedFileNotification": false,
   // uncomment the target of your chip.
-  "rust-analyzer.cargo.target": "thumbv6m-none-eabi",
+  //"rust-analyzer.cargo.target": "thumbv6m-none-eabi",
   //"rust-analyzer.cargo.target": "thumbv7m-none-eabi",
-  //"rust-analyzer.cargo.target": "thumbv7em-none-eabi",
+  "rust-analyzer.cargo.target": "thumbv7em-none-eabi",
   //"rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf",
-  /* "rust-analyzer.cargo.features": [
+  "rust-analyzer.cargo.features": [
     "stm32f103c8",
     "time-driver-any",
     "unstable-pac",
     "exti",
-  ], */
+  ],
   "rust-analyzer.linkedProjects": [
     // Uncomment ONE line for the chip you want to work on.
     // This makes rust-analyzer work on the example crate and all its dependencies.
-    // "embassy-stm32/Cargo.toml",
+    "embassy-stm32/Cargo.toml",
     // "examples/nrf52840-rtic/Cargo.toml",
     // "examples/nrf5340/Cargo.toml",
     // "examples/nrf-rtos-trace/Cargo.toml",
-    "examples/rp/Cargo.toml",
+    // "examples/rp/Cargo.toml",
     // "examples/std/Cargo.toml",
     // "examples/stm32c0/Cargo.toml",
     // "examples/stm32f0/Cargo.toml",

From b578d3e645a534bdc76f43e603e9f5b2cab131fa Mon Sep 17 00:00:00 2001
From: Gustav Toft <guto@factbird.com>
Date: Thu, 11 Apr 2024 10:34:17 +0200
Subject: [PATCH 6/6] Removed generic type parameter.

---
 embassy-net/src/raw.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/embassy-net/src/raw.rs b/embassy-net/src/raw.rs
index a6500a51f..7ecd913e7 100644
--- a/embassy-net/src/raw.rs
+++ b/embassy-net/src/raw.rs
@@ -91,7 +91,7 @@ impl<'a> RawSocket<'a> {
     /// Send a datagram.
     ///
     /// This method will wait until the datagram has been sent.`
-    pub async fn send<T>(&self, buf: &[u8]) {
+    pub async fn send(&self, buf: &[u8]) {
         poll_fn(move |cx| self.poll_send(buf, cx)).await
     }