nusb/examples/control.rs
Kevin Mehall 14a8f171e5
Make blocking APIs optionally async (#100)
* Make blocking APIs optionally async

`DeviceInfo::open`, `Device::from_fd`, `Device::set_configuration`,
`Device::reset`, `Interface::set_alt_setting`, `Interface::clear_halt`
all perform IO but are currently blocking because the underlying OS APIs
are blocking.

`list_devices`,`list_buses`, `Device::claim_interface`
`Device::detach_and_claim_interface` theoretically don't perform IO, but
are also included here because they need to be async on WebUSB.

The `MaybeFuture` trait allows deferring these actions to the thread pool
from the `blocking` crate when used asynchronously with `.await` /
`IntoFuture`, or directly runs the blocking syscall synchronously with a
`.wait()` method.
2025-02-11 18:53:07 -07:00

65 lines
1.8 KiB
Rust

use futures_lite::future::block_on;
use nusb::{
transfer::{ControlIn, ControlOut, ControlType, Recipient},
MaybeFuture,
};
fn main() {
env_logger::init();
let di = nusb::list_devices()
.wait()
.unwrap()
.find(|d| d.vendor_id() == 0x59e3 && d.product_id() == 0x0a23)
.expect("device should be connected");
println!("Device info: {di:?}");
let device = di.open().wait().unwrap();
// Linux can make control transfers without claiming an interface
#[cfg(any(target_os = "linux", target_os = "macos"))]
{
let result = block_on(device.control_out(ControlOut {
control_type: ControlType::Vendor,
recipient: Recipient::Device,
request: 0x81,
value: 0x9999,
index: 0x9999,
data: &[1, 2, 3, 4],
}));
println!("{result:?}");
let result = block_on(device.control_in(ControlIn {
control_type: ControlType::Vendor,
recipient: Recipient::Device,
request: 0x81,
value: 0x9999,
index: 0x9999,
length: 256,
}));
println!("{result:?}");
}
// but we also provide an API on the `Interface` to support Windows
let interface = device.claim_interface(0).wait().unwrap();
let result = block_on(interface.control_out(ControlOut {
control_type: ControlType::Vendor,
recipient: Recipient::Device,
request: 0x81,
value: 0x9999,
index: 0x9999,
data: &[1, 2, 3, 4],
}));
println!("{result:?}");
let result = block_on(interface.control_in(ControlIn {
control_type: ControlType::Vendor,
recipient: Recipient::Device,
request: 0x81,
value: 0x9999,
index: 0x9999,
length: 256,
}));
println!("{result:?}");
}