Skip to content
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[package]
name = "rusb"
version = "0.8.0"
authors = ["David Cuddeback <[email protected]>", "Ilya Averyanov <[email protected]>"]
authors = [
"David Cuddeback <[email protected]>",
"Ilya Averyanov <[email protected]>",
]
description = "Rust library for accessing USB devices."
license = "MIT"
homepage = "https://github.com/a1ien/rusb"
Expand All @@ -15,14 +18,16 @@ build = "build.rs"
travis-ci = { repository = "a1ien/rusb" }

[features]
vendored = [ "libusb1-sys/vendored" ]
vendored = ["libusb1-sys/vendored"]

[workspace]
members = ["libusb1-sys"]

[dependencies]
libusb1-sys = { path = "libusb1-sys", version = "0.5.0" }
libc = "0.2"
log = "0.4"
thiserror = "1"

[dev-dependencies]
regex = "1"
68 changes: 68 additions & 0 deletions examples/read_async.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use rusb::{AsyncPool, Context, UsbContext};

use std::str::FromStr;
use std::time::Duration;

fn main() {
let args: Vec<String> = std::env::args().collect();

if args.len() < 4 {
eprintln!("Usage: read_async <vendor-id> <product-id> <endpoint>");
return;
}

let vid: u16 = FromStr::from_str(args[1].as_ref()).unwrap();
let pid: u16 = FromStr::from_str(args[2].as_ref()).unwrap();
let endpoint: u8 = FromStr::from_str(args[3].as_ref()).unwrap();

let ctx = Context::new().expect("Could not initialize libusb");
let device = ctx
.open_device_with_vid_pid(vid, pid)
.expect("Could not find device");

const NUM_TRANSFERS: usize = 32;
const BUF_SIZE: usize = 1024;

let mut buffers = Vec::new();
for _ in 0..NUM_TRANSFERS {
let buf = Vec::with_capacity(BUF_SIZE);
buffers.push(buf);
}

let mut async_pool =
AsyncPool::new_bulk(device, endpoint, buffers).expect("Failed to create async pool!");

let mut swap_vec = Vec::with_capacity(BUF_SIZE);
let timeout = Duration::from_secs(10);

let mut num_bytes = 0u64;
let mut num_transfers = 0u64;
let mut last_time = std::time::Instant::now();
loop {
let poll_result = async_pool.poll(timeout, swap_vec);
match poll_result {
Ok(data) => {
num_bytes += data.len() as u64;
swap_vec = data
Comment thread
TheButlah marked this conversation as resolved.
}
Err((err, buf)) => {
eprintln!("Error: {}", err);
swap_vec = buf
}
}
num_transfers += 1;

let elapsed = last_time.elapsed();
if elapsed >= Duration::from_millis(1000) {
let elapsed = elapsed.as_secs_f32();
println!(
"KiB per second: {}, \tTx per second: {}",
num_bytes as f32 / 1024. / elapsed,
num_transfers as f32 / elapsed
);
num_bytes = 0;
num_transfers = 0;
last_time = std::time::Instant::now();
}
}
}
20 changes: 4 additions & 16 deletions src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use crate::{
config_descriptor::{self, ConfigDescriptor},
device_descriptor::{self, DeviceDescriptor},
device_handle::DeviceHandle,
error,
fields::{self, Speed},
Error, UsbContext,
error,
};

/// A reference to a USB device.
Expand Down Expand Up @@ -150,27 +150,16 @@ impl<T: UsbContext> Device<T> {
pub fn get_parent(&self) -> Option<Self> {
let device = unsafe { libusb_get_parent(self.device.as_ptr()) };
NonNull::new(device)
.map(|device|
unsafe {
Device::from_libusb(
self.context.clone(),
device,
)
}
)
.map(|device| unsafe { Device::from_libusb(self.context.clone(), device) })
}

/// Get the list of all port numbers from root for the specified device
pub fn port_numbers(&self) -> Result<Vec<u8>, Error> {
// As per the USB 3.0 specs, the current maximum limit for the depth is 7.
let mut ports = [0;7];
let mut ports = [0; 7];

let result = unsafe {
libusb_get_port_numbers(
self.device.as_ptr(),
ports.as_mut_ptr(),
ports.len() as i32
)
libusb_get_port_numbers(self.device.as_ptr(), ports.as_mut_ptr(), ports.len() as i32)
};

let ports_number = if result < 0 {
Expand All @@ -180,5 +169,4 @@ impl<T: UsbContext> Device<T> {
};
Ok(ports[0..ports_number as usize].to_vec())
}

}
Loading