Skip to content

Commit

Permalink
Implement embedded_io::{ReadReady, WriteReady} traits for `WifiStac…
Browse files Browse the repository at this point in the history
…k` (#1882)

* implement `ReadReady` and `WriteReady` traits from `embedded-io` for Wi-Fi

* Allow non-static lifetime for `WifiStack`

* Update `CHANGELOG.md`

* clippy
  • Loading branch information
jessebraham authored Jul 31, 2024
1 parent 81f3776 commit 311f012
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 13 deletions.
6 changes: 2 additions & 4 deletions esp-wifi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Implement `embedded_io::{ReadReady, WriteReady}` traits for `WifiStack` (#1882)

### Changed

### Fixed
Expand All @@ -17,8 +19,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## 0.7.1 - 2024-07-17

### Added

### Changed

- Check no password is set when using `AuthMethod::None`(#1806)
Expand All @@ -27,8 +27,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Downgrade `embedded-svc` to 0.27.1 (#1820)

### Removed

## 0.7.0 - 2024-07-15

### Added
Expand Down
55 changes: 46 additions & 9 deletions esp-wifi/src/wifi_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
use core::{borrow::BorrowMut, cell::RefCell, fmt::Display};

#[cfg(feature = "tcp")]
use embedded_io::ErrorType;
#[cfg(feature = "tcp")]
use embedded_io::{Read, Write};
#[cfg(feature = "dhcpv4")]
use smoltcp::socket::dhcpv4::Socket as Dhcpv4Socket;
#[cfg(feature = "tcp")]
Expand Down Expand Up @@ -34,7 +30,7 @@ const LOCAL_PORT_MAX: u16 = 65535;
///
/// Mostly a convenience wrapper for `smoltcp`
pub struct WifiStack<'a, MODE: WifiDeviceMode> {
device: RefCell<WifiDevice<'static, MODE>>, // TODO allow non static lifetime
device: RefCell<WifiDevice<'a, MODE>>,
network_interface: RefCell<Interface>,
sockets: RefCell<SocketSet<'a>>,
current_millis_fn: fn() -> u64,
Expand All @@ -53,7 +49,7 @@ pub struct WifiStack<'a, MODE: WifiDeviceMode> {
impl<'a, MODE: WifiDeviceMode> WifiStack<'a, MODE> {
pub fn new(
network_interface: Interface,
device: WifiDevice<'static, MODE>, // TODO relax this lifetime requirement
device: WifiDevice<'a, MODE>,
#[allow(unused_mut)] mut sockets: SocketSet<'a>,
current_millis_fn: fn() -> u64,
) -> WifiStack<'a, MODE> {
Expand Down Expand Up @@ -709,12 +705,12 @@ impl embedded_io::Error for IoError {
}

#[cfg(feature = "tcp")]
impl<'s, 'n: 's, MODE: WifiDeviceMode> ErrorType for Socket<'s, 'n, MODE> {
impl<'s, 'n: 's, MODE: WifiDeviceMode> embedded_io::ErrorType for Socket<'s, 'n, MODE> {
type Error = IoError;
}

#[cfg(feature = "tcp")]
impl<'s, 'n: 's, MODE: WifiDeviceMode> Read for Socket<'s, 'n, MODE> {
impl<'s, 'n: 's, MODE: WifiDeviceMode> embedded_io::Read for Socket<'s, 'n, MODE> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
self.network.with_mut(|interface, device, sockets| {
use smoltcp::socket::tcp::RecvError;
Expand All @@ -735,7 +731,25 @@ impl<'s, 'n: 's, MODE: WifiDeviceMode> Read for Socket<'s, 'n, MODE> {
}

#[cfg(feature = "tcp")]
impl<'s, 'n: 's, MODE: WifiDeviceMode> Write for Socket<'s, 'n, MODE> {
impl<'s, 'n: 's, MODE: WifiDeviceMode> embedded_io::ReadReady for Socket<'s, 'n, MODE> {
fn read_ready(&mut self) -> Result<bool, Self::Error> {
self.network.with_mut(|interface, device, sockets| {
use smoltcp::socket::tcp::RecvError;

interface.poll(timestamp(), device, sockets);
let socket = sockets.get_mut::<TcpSocket>(self.socket_handle);

match socket.peek(1) {
Ok(s) => Ok(!s.is_empty()),
Err(RecvError::Finished) => Err(IoError::SocketClosed),
Err(RecvError::InvalidState) => Err(IoError::TcpRecvError),
}
})
}
}

#[cfg(feature = "tcp")]
impl<'s, 'n: 's, MODE: WifiDeviceMode> embedded_io::Write for Socket<'s, 'n, MODE> {
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
loop {
let (may_send, is_open, can_send) =
Expand Down Expand Up @@ -799,6 +813,29 @@ impl<'s, 'n: 's, MODE: WifiDeviceMode> Write for Socket<'s, 'n, MODE> {
}
}

#[cfg(feature = "tcp")]
impl<'s, 'n: 's, MODE: WifiDeviceMode> embedded_io::WriteReady for Socket<'s, 'n, MODE> {
fn write_ready(&mut self) -> Result<bool, Self::Error> {
let (may_send, is_open, can_send) = self.network.with_mut(|interface, device, sockets| {
interface.poll(
Instant::from_millis((self.network.current_millis_fn)() as i64),
device,
sockets,
);

let socket = sockets.get_mut::<TcpSocket>(self.socket_handle);

(socket.may_send(), socket.is_open(), socket.can_send())
});

if !is_open || !can_send {
return Err(IoError::SocketClosed);
}

Ok(may_send)
}
}

/// A UDP socket
#[cfg(feature = "udp")]
pub struct UdpSocket<'s, 'n: 's, MODE: WifiDeviceMode> {
Expand Down

0 comments on commit 311f012

Please sign in to comment.