From 371b91c85fcd2df4940b54e9955b2c0d210d0feb Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Sun, 15 Jun 2025 10:12:21 -0600 Subject: [PATCH] EndpointRead / EndpointWrite examples with tokio and smol --- Cargo.toml | 10 ++++ examples/bulk_io.rs | 18 ++++++- examples/bulk_io_smol.rs | 99 +++++++++++++++++++++++++++++++++++++++ examples/bulk_io_tokio.rs | 95 +++++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 examples/bulk_io_smol.rs create mode 100644 examples/bulk_io_tokio.rs diff --git a/Cargo.toml b/Cargo.toml index 22878b3..a5c61a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ slab = "0.4.9" [dev-dependencies] env_logger = "0.11" futures-lite = "2.0" +tokio = { version = "1", features = ["rt", "macros", "io-util", "rt-multi-thread"] } [target.'cfg(any(target_os="linux", target_os="android"))'.dependencies] rustix = { version = "1.0.1", features = ["fs", "event", "net", "time", "mm"] } @@ -49,3 +50,12 @@ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] } [package.metadata.docs.rs] all-features = true + +[[example]] +name = "bulk_io_smol" +required-features = ["smol"] + +[[example]] +name = "bulk_io_tokio" +required-features = ["tokio"] + diff --git a/examples/bulk_io.rs b/examples/bulk_io.rs index 0a41518..1f91ddc 100644 --- a/examples/bulk_io.rs +++ b/examples/bulk_io.rs @@ -31,7 +31,8 @@ fn main() { let mut reader = main_interface .endpoint::(0x83) .unwrap() - .reader(128); + .reader(128) + .with_num_transfers(8); writer.write_all(&[1; 16]).unwrap(); writer.write_all(&[2; 256]).unwrap(); @@ -47,6 +48,21 @@ fn main() { dbg!(reader.fill_buf().unwrap().len()); + let mut buf = [0; 1000]; + for len in 0..1000 { + reader.read_exact(&mut buf[..len]).unwrap(); + writer.write_all(&buf[..len]).unwrap(); + } + + reader.cancel_all(); + loop { + let n = reader.read(&mut buf).unwrap(); + dbg!(n); + if n == 0 { + break; + } + } + let echo_interface = device.claim_interface(1).wait().unwrap(); echo_interface.set_alt_setting(1).wait().unwrap(); diff --git a/examples/bulk_io_smol.rs b/examples/bulk_io_smol.rs new file mode 100644 index 0000000..7ebedc3 --- /dev/null +++ b/examples/bulk_io_smol.rs @@ -0,0 +1,99 @@ +use std::time::Duration; + +use nusb::{ + transfer::{Bulk, In, Out}, + MaybeFuture, +}; + +use futures_lite::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt}; + +fn main() { + env_logger::init(); + let di = nusb::list_devices() + .wait() + .unwrap() + .find(|d| d.vendor_id() == 0x59e3 && d.product_id() == 0x00aa) + .expect("device should be connected"); + + println!("Device info: {di:?}"); + + futures_lite::future::block_on(async { + let device = di.open().await.unwrap(); + + let main_interface = device.claim_interface(0).await.unwrap(); + + let mut writer = main_interface + .endpoint::(0x03) + .unwrap() + .writer(128) + .with_num_transfers(8); + + let mut reader = main_interface + .endpoint::(0x83) + .unwrap() + .reader(128) + .with_num_transfers(8); + + writer.write_all(&[1; 16]).await.unwrap(); + writer.write_all(&[2; 256]).await.unwrap(); + writer.flush().await.unwrap(); + writer.write_all(&[3; 64]).await.unwrap(); + writer.flush_end_async().await.unwrap(); + + let mut buf = [0; 16]; + reader.read_exact(&mut buf).await.unwrap(); + + let mut buf = [0; 64]; + reader.read_exact(&mut buf).await.unwrap(); + + dbg!(reader.fill_buf().await.unwrap().len()); + + let mut buf = [0; 1000]; + for len in 0..1000 { + reader.read_exact(&mut buf[..len]).await.unwrap(); + writer.write_all(&buf[..len]).await.unwrap(); + } + + reader.cancel_all(); + loop { + let n = reader.read(&mut buf).await.unwrap(); + dbg!(n); + if n == 0 { + break; + } + } + + let echo_interface = device.claim_interface(1).await.unwrap(); + echo_interface.set_alt_setting(1).await.unwrap(); + + let mut writer = echo_interface + .endpoint::(0x01) + .unwrap() + .writer(64) + .with_num_transfers(1); + let mut reader = echo_interface + .endpoint::(0x81) + .unwrap() + .reader(64) + .with_num_transfers(8) + .with_read_timeout(Duration::from_millis(100)); + + let mut pkt_reader = reader.until_short_packet(); + + writer.write_all(&[1; 16]).await.unwrap(); + writer.flush_end_async().await.unwrap(); + + writer.write_all(&[2; 128]).await.unwrap(); + writer.flush_end_async().await.unwrap(); + + let mut v = Vec::new(); + pkt_reader.read_to_end(&mut v).await.unwrap(); + assert_eq!(&v[..], &[1; 16]); + pkt_reader.consume_end().unwrap(); + + let mut v = Vec::new(); + pkt_reader.read_to_end(&mut v).await.unwrap(); + assert_eq!(&v[..], &[2; 128]); + pkt_reader.consume_end().unwrap(); + }) +} diff --git a/examples/bulk_io_tokio.rs b/examples/bulk_io_tokio.rs new file mode 100644 index 0000000..19b28e0 --- /dev/null +++ b/examples/bulk_io_tokio.rs @@ -0,0 +1,95 @@ +use std::time::Duration; + +use nusb::transfer::{Bulk, In, Out}; + +use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt}; + +#[tokio::main] +async fn main() { + env_logger::init(); + let di = nusb::list_devices() + .await + .unwrap() + .find(|d| d.vendor_id() == 0x59e3 && d.product_id() == 0x00aa) + .expect("device should be connected"); + + println!("Device info: {di:?}"); + + let device = di.open().await.unwrap(); + + let main_interface = device.claim_interface(0).await.unwrap(); + + let mut writer = main_interface + .endpoint::(0x03) + .unwrap() + .writer(128) + .with_num_transfers(8); + + let mut reader = main_interface + .endpoint::(0x83) + .unwrap() + .reader(128) + .with_num_transfers(8); + + writer.write_all(&[1; 16]).await.unwrap(); + writer.write_all(&[2; 256]).await.unwrap(); + writer.flush().await.unwrap(); + writer.write_all(&[3; 64]).await.unwrap(); + writer.flush_end_async().await.unwrap(); + + let mut buf = [0; 16]; + reader.read_exact(&mut buf).await.unwrap(); + + let mut buf = [0; 64]; + reader.read_exact(&mut buf).await.unwrap(); + + dbg!(reader.fill_buf().await.unwrap().len()); + + let mut buf = [0; 1000]; + for len in 0..1000 { + reader.read_exact(&mut buf[..len]).await.unwrap(); + writer.write_all(&buf[..len]).await.unwrap(); + } + + reader.cancel_all(); + loop { + let n = reader.read(&mut buf).await.unwrap(); + dbg!(n); + if n == 0 { + break; + } + } + + let echo_interface = device.claim_interface(1).await.unwrap(); + echo_interface.set_alt_setting(1).await.unwrap(); + + let mut writer = echo_interface + .endpoint::(0x01) + .unwrap() + .writer(64) + .with_num_transfers(1); + let mut reader = echo_interface + .endpoint::(0x81) + .unwrap() + .reader(64) + .with_num_transfers(8) + .with_read_timeout(Duration::from_millis(100)); + + let mut pkt_reader = reader.until_short_packet(); + + writer.write_all(&[1; 16]).await.unwrap(); + writer.flush_end_async().await.unwrap(); + + writer.write_all(&[2; 128]).await.unwrap(); + writer.flush_end_async().await.unwrap(); + + let mut v = Vec::new(); + pkt_reader.read_to_end(&mut v).await.unwrap(); + assert_eq!(&v[..], &[1; 16]); + pkt_reader.consume_end().unwrap(); + + let mut v = Vec::new(); + pkt_reader.read_to_end(&mut v).await.unwrap(); + assert_eq!(&v[..], &[2; 128]); + pkt_reader.consume_end().unwrap(); +}