Skip to content

Commit

Permalink
Add async implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
newAM committed Oct 9, 2022
1 parent e84b239 commit f1e20e6
Show file tree
Hide file tree
Showing 13 changed files with 3,857 additions and 621 deletions.
4 changes: 2 additions & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[alias]
test-all = "test --features std,log,eh0,eh1,time,chrono,num-rational,w5500-tls"
test-dhcp = "test -p w5500-dhcp --features log,std"
test-ll = "test -p w5500-ll --features eh0,eh1,std"
test-hl = "test -p w5500-hl --features eh0,eh1,std"
test-ll = "test -p w5500-ll --all-features"
test-hl = "test -p w5500-hl --all-features"
test-mqtt = "test -p w5500-mqtt --features log,std,w5500-tls"
test-regsim = "test -p w5500-regsim"
test-sntp = "test -p w5500-sntp --features std,log,eh0,eh1,time,chrono,num-rational"
Expand Down
26 changes: 14 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
env: {"RUSTFLAGS": "-D warnings"}
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- run: cargo build
- run: cargo build --all-features
- run: cargo build -p testsuite
Expand All @@ -33,7 +33,7 @@ jobs:
- "thumbv7em-none-eabi"
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
with:
target: ${{ matrix.target }}
- run: cargo build --target ${{ matrix.target }} -p w5500-ll
Expand Down Expand Up @@ -65,6 +65,8 @@ jobs:
- run: cargo build --target ${{ matrix.target }} -p w5500-sntp --features chrono
- run: cargo build --target ${{ matrix.target }} -p w5500-sntp --features num-rational
- run: cargo build --target ${{ matrix.target }} -p w5500-mqtt --features w5500-tls
- run: cargo build --target ${{ matrix.target }} -p w5500-ll --features async
- run: cargo build --target ${{ matrix.target }} -p w5500-ll --features eha0
- run: cargo build --target ${{ matrix.target }} -p w5500-tls --features p256-cm4
if: ${{ matrix.target == 'thumbv7em-none-eabi' }}
- run: cargo build --target ${{ matrix.target }} -p w5500-mqtt --features w5500-tls,p256-cm4
Expand All @@ -76,15 +78,15 @@ jobs:
env: {"RUSTFLAGS": "-D warnings"}
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- run: cargo test-all

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
with:
components: clippy
- run: cargo clippy --all-features -- --deny warnings
Expand Down Expand Up @@ -136,7 +138,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- name: Publish
run: |
cd ll
Expand All @@ -157,7 +159,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- name: Publish
run: |
cd hl
Expand All @@ -178,7 +180,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- name: Publish
run: |
cd dhcp
Expand All @@ -199,7 +201,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- name: Publish
run: |
cd regsim
Expand All @@ -220,7 +222,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- name: Publish
run: |
cd dns
Expand All @@ -241,7 +243,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- name: Publish
run: |
cd mqtt
Expand All @@ -262,7 +264,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- name: Publish
run: |
cd sntp
Expand All @@ -283,7 +285,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
- name: Publish
run: |
cd tls
Expand Down
2 changes: 2 additions & 0 deletions hl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ categories = ["embedded", "hardware-support", "no-std"]
homepage = "https://github.com/newAM/w5500-rs"

[features]
async = ["w5500-ll/async"]
defmt = ["w5500-ll/defmt", "dep:defmt"]
eh0 = ["w5500-ll/eh0"]
eh1 = ["w5500-ll/eh1"]
eha0 = ["w5500-ll/eha0"]
std = ["w5500-ll/std"]

[dependencies]
Expand Down
1 change: 1 addition & 0 deletions hl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ All features are disabled by default.
* `defmt`: Passthrough to [`w5500-ll`].
* `eh0`: Passthrough to [`w5500-ll`].
* `eh1`: Passthrough to [`w5500-ll`].
* `eha0`: Passthrough to [`w5500-ll`].
* `std`: Passthrough to [`w5500-ll`].

## Examples
Expand Down
32 changes: 32 additions & 0 deletions hl/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,22 @@ pub trait Read<E> {
fn done(self) -> Result<(), E>;
}

/// Socket asyncrhonous reader trait.
#[cfg(feature = "async")]
pub trait AsyncRead<E> {
type ReadFuture<'a>: core::future::Future<Output = Result<u16, E>> + 'a
where
Self: 'a;

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a>;

type ReadExactFuture<'a>: core::future::Future<Output = Result<(), Error<E>>> + 'a
where
Self: 'a;

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadExactFuture<'a>;
}

/// Socket writer trait.
pub trait Write<E> {
/// Write data to the socket buffer, and return the number of bytes written.
Expand Down Expand Up @@ -158,6 +174,22 @@ pub trait Write<E> {
fn send(self) -> Result<(), E>;
}

/// Socket asyncrhonous writer trait.
#[cfg(feature = "async")]
pub trait AsyncWrite<E> {
type WriteFuture<'a>: core::future::Future<Output = Result<u16, E>> + 'a
where
Self: 'a;

fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a>;

type WriteAllFuture<'a>: core::future::Future<Output = Result<(), Error<E>>> + 'a
where
Self: 'a;

fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteAllFuture<'a>;
}

#[cfg(test)]
mod tests {
use super::{Error, SeekFrom};
Expand Down
2 changes: 2 additions & 0 deletions hl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
//! * `defmt`: Passthrough to [`w5500-ll`].
//! * `eh0`: Passthrough to [`w5500-ll`].
//! * `eh1`: Passthrough to [`w5500-ll`].
//! * `eha0`: Passthrough to [`w5500-ll`].
//! * `std`: Passthrough to [`w5500-ll`].
//!
//! # Examples
Expand Down Expand Up @@ -97,6 +98,7 @@
//! [Wiznet W5500]: https://www.wiznet.io/product-item/w5500/
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
#![cfg_attr(feature = "async", feature(type_alias_impl_trait))]

mod hostname;
pub mod io;
Expand Down
82 changes: 82 additions & 0 deletions hl/src/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,47 @@ impl<'a, W5500: Registers> Read<W5500::Error> for TcpReader<'a, W5500> {
}
}

#[cfg(feature = "async")]
impl<'w, W5500: w5500_ll::aio::Registers + 'w> crate::io::AsyncRead<W5500::Error>
for TcpReader<'w, W5500>
{
type ReadFuture<'a> = impl core::future::Future<Output = Result<u16, W5500::Error>> + 'a
where Self: 'a;

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
async move {
let read_size: u16 = min(self.remain(), buf.len().try_into().unwrap_or(u16::MAX));
if read_size != 0 {
self.w5500
.sn_rx_buf(self.sn, self.ptr, &mut buf[..usize::from(read_size)])
.await?;
self.ptr = self.ptr.wrapping_add(read_size);

Ok(read_size)
} else {
Ok(0)
}
}
}

type ReadExactFuture<'a> = impl core::future::Future<Output = Result<(), Error<W5500::Error>>> + 'a
where Self: 'a;

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadExactFuture<'a> {
async move {
let buf_len: u16 = buf.len().try_into().unwrap_or(u16::MAX);
let write_size: u16 = min(self.remain(), buf_len);
if write_size != buf_len {
Err(Error::OutOfMemory)
} else {
self.w5500.set_sn_tx_buf(self.sn, self.ptr, buf).await?;
self.ptr = self.ptr.wrapping_add(write_size);
Ok(())
}
}
}
}

/// Streaming writer for a UDP socket buffer.
///
/// This implements the [`Seek`] traits.
Expand Down Expand Up @@ -222,6 +263,47 @@ impl<'w, W5500: Registers> Write<W5500::Error> for TcpWriter<'w, W5500> {
}
}

#[cfg(feature = "async")]
impl<'w, W5500: w5500_ll::aio::Registers + 'w> crate::io::AsyncWrite<W5500::Error>
for TcpWriter<'w, W5500>
{
type WriteFuture<'a> = impl core::future::Future<Output = Result<u16, W5500::Error>> + 'a
where Self: 'a;

fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
async move {
let write_size: u16 = min(self.remain(), buf.len().try_into().unwrap_or(u16::MAX));
if write_size != 0 {
self.w5500
.set_sn_tx_buf(self.sn, self.ptr, &buf[..usize::from(write_size)])
.await?;
self.ptr = self.ptr.wrapping_add(write_size);

Ok(write_size)
} else {
Ok(0)
}
}
}

type WriteAllFuture<'a> = impl core::future::Future<Output = Result<(), Error<W5500::Error>>> + 'a
where Self: 'a;

fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteAllFuture<'a> {
async move {
let buf_len: u16 = buf.len().try_into().unwrap_or(u16::MAX);
let write_size: u16 = min(self.remain(), buf_len);
if write_size != buf_len {
Err(Error::OutOfMemory)
} else {
self.w5500.set_sn_tx_buf(self.sn, self.ptr, buf).await?;
self.ptr = self.ptr.wrapping_add(write_size);
Ok(())
}
}
}
}

/// A W5500 TCP trait.
pub trait Tcp: Registers {
/// Starts the 3-way TCP handshake with the remote host.
Expand Down
60 changes: 60 additions & 0 deletions hl/src/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,25 @@ impl<'w, W5500: Registers> Read<W5500::Error> for UdpReader<'w, W5500> {
}
}

#[cfg(feature = "async")]
impl<'w, W5500: w5500_ll::aio::Registers + 'w> crate::io::AsyncRead<W5500::Error>
for UdpReader<'w, W5500>
{
type ReadFuture<'a> = impl core::future::Future<Output = Result<u16, W5500::Error>> + 'a
where Self: 'a;

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
async move { self.inner.read(buf).await }
}

type ReadExactFuture<'a> = impl core::future::Future<Output = Result<(), Error<W5500::Error>>> + 'a
where Self: 'a;

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadExactFuture<'a> {
async move { self.inner.read_exact(buf).await }
}
}

/// Streaming writer for a UDP socket buffer.
///
/// This implements the [`Seek`] traits.
Expand Down Expand Up @@ -226,6 +245,47 @@ impl<'w, W5500: Registers> Write<W5500::Error> for UdpWriter<'w, W5500> {
}
}

#[cfg(feature = "async")]
impl<'w, W5500: w5500_ll::aio::Registers + 'w> crate::io::AsyncWrite<W5500::Error>
for UdpWriter<'w, W5500>
{
type WriteFuture<'a> = impl core::future::Future<Output = Result<u16, W5500::Error>> + 'a
where Self: 'a;

fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
async move {
let write_size: u16 = min(self.remain(), buf.len().try_into().unwrap_or(u16::MAX));
if write_size != 0 {
self.w5500
.set_sn_tx_buf(self.sn, self.ptr, &buf[..usize::from(write_size)])
.await?;
self.ptr = self.ptr.wrapping_add(write_size);

Ok(write_size)
} else {
Ok(0)
}
}
}

type WriteAllFuture<'a> = impl core::future::Future<Output = Result<(), Error<W5500::Error>>> + 'a
where Self: 'a;

fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteAllFuture<'a> {
async move {
let buf_len: u16 = buf.len().try_into().unwrap_or(u16::MAX);
let write_size: u16 = min(self.remain(), buf_len);
if write_size != buf_len {
Err(Error::OutOfMemory)
} else {
self.w5500.set_sn_tx_buf(self.sn, self.ptr, buf).await?;
self.ptr = self.ptr.wrapping_add(write_size);
Ok(())
}
}
}
}

impl<'w, W5500: Registers> UdpWriter<'w, W5500> {
/// Send all data previously written with [`UdpWriter::write`] and
/// [`UdpWriter::write_all`] to the given address.
Expand Down
2 changes: 2 additions & 0 deletions ll/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Added support for `embedded-hal` version `1.0.0-alpha.9` with the `eh1` feature.
- Added support for `embedded-hal-async` version `0.1.0-alpha.1` with the `eha0` feature.
- Added an `aio` module with async traits.

### Changed
- Changed the `embedded-hal` version `0.2` feature name to `eh0`.
Expand Down
Loading

0 comments on commit f1e20e6

Please sign in to comment.