Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[package]
name = "libusb"
version = "0.3.0"
edition = "2018"
authors = ["David Cuddeback <[email protected]>"]
description = "Rust library for accessing USB devices."
license = "MIT"
Expand Down
209 changes: 147 additions & 62 deletions examples/list_devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,61 @@ extern crate libusb;

use std::time::Duration;

struct UsbDevice<'a> {
handle: libusb::DeviceHandle<'a>,
struct UsbDevice {
handle: libusb::DeviceHandle,
language: libusb::Language,
timeout: Duration
timeout: Duration,
}


fn main() {
list_devices().unwrap();
}

fn list_devices() -> libusb::Result<()> {
let timeout = Duration::from_secs(1);

let context = try!(libusb::Context::new());
let context = libusb::Context::new()?;

for device in try!(context.devices()).iter() {
for device in context.devices()?.iter() {
let device_desc = match device.device_descriptor() {
Ok(d) => d,
Err(_) => continue
Err(_) => continue,
};

let mut usb_device = {
match device.open() {
Ok(h) => {
match h.read_languages(timeout) {
Ok(l) => {
if l.len() > 0 {
Some(UsbDevice {
handle: h,
language: l[0],
timeout: timeout
})
}
else {
None
}
},
Err(_) => None
Ok(h) => match h.read_languages(timeout) {
Ok(l) => {
if l.len() > 0 {
Some(UsbDevice {
handle: h,
language: l[0],
timeout: timeout,
})
} else {
None
}
}
Err(_) => None,
},
Err(_) => None
Err(_) => None,
}
};

println!("Bus {:03} Device {:03} ID {:04x}:{:04x} {}", device.bus_number(), device.address(), device_desc.vendor_id(), device_desc.product_id(), get_speed(device.speed()));
println!(
"Bus {:03} Device {:03} ID {:04x}:{:04x} {}",
device.bus_number(),
device.address(),
device_desc.vendor_id(),
device_desc.product_id(),
get_speed(device.speed())
);
print_device(&device_desc, &mut usb_device);

for n in 0..device_desc.num_configurations() {
let config_desc = match device.config_descriptor(n) {
Ok(c) => c,
Err(_) => continue
Err(_) => continue,
};

print_config(&config_desc, &mut usb_device);
Expand All @@ -75,33 +78,72 @@ fn list_devices() -> libusb::Result<()> {

fn print_device(device_desc: &libusb::DeviceDescriptor, handle: &mut Option<UsbDevice>) {
println!("Device Descriptor:");
println!(" bcdUSB {:2}.{}{}", device_desc.usb_version().major(), device_desc.usb_version().minor(), device_desc.usb_version().sub_minor());
println!(
" bcdUSB {:2}.{}{}",
device_desc.usb_version().major(),
device_desc.usb_version().minor(),
device_desc.usb_version().sub_minor()
);
println!(" bDeviceClass {:#04x}", device_desc.class_code());
println!(" bDeviceSubClass {:#04x}", device_desc.sub_class_code());
println!(
" bDeviceSubClass {:#04x}",
device_desc.sub_class_code()
);
println!(" bDeviceProtocol {:#04x}", device_desc.protocol_code());
println!(" bMaxPacketSize0 {:3}", device_desc.max_packet_size());
println!(" idVendor {:#06x}", device_desc.vendor_id());
println!(" idProduct {:#06x}", device_desc.product_id());
println!(" bcdDevice {:2}.{}{}", device_desc.device_version().major(), device_desc.device_version().minor(), device_desc.device_version().sub_minor());
println!(" iManufacturer {:3} {}",
device_desc.manufacturer_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h.handle.read_manufacturer_string(h.language, device_desc, h.timeout).unwrap_or(String::new())));
println!(" iProduct {:3} {}",
device_desc.product_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h.handle.read_product_string(h.language, device_desc, h.timeout).unwrap_or(String::new())));
println!(" iSerialNumber {:3} {}",
device_desc.serial_number_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h.handle.read_serial_number_string(h.language, device_desc, h.timeout).unwrap_or(String::new())));
println!(" bNumConfigurations {:3}", device_desc.num_configurations());
println!(
" bcdDevice {:2}.{}{}",
device_desc.device_version().major(),
device_desc.device_version().minor(),
device_desc.device_version().sub_minor()
);
println!(
" iManufacturer {:3} {}",
device_desc.manufacturer_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h
.handle
.read_manufacturer_string(h.language, device_desc, h.timeout)
.unwrap_or(String::new()))
);
println!(
" iProduct {:3} {}",
device_desc.product_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h
.handle
.read_product_string(h.language, device_desc, h.timeout)
.unwrap_or(String::new()))
);
println!(
" iSerialNumber {:3} {}",
device_desc.serial_number_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h
.handle
.read_serial_number_string(h.language, device_desc, h.timeout)
.unwrap_or(String::new()))
);
println!(
" bNumConfigurations {:3}",
device_desc.num_configurations()
);
}

fn print_config(config_desc: &libusb::ConfigDescriptor, handle: &mut Option<UsbDevice>) {
println!(" Config Descriptor:");
println!(" bNumInterfaces {:3}", config_desc.num_interfaces());
println!(
" bNumInterfaces {:3}",
config_desc.num_interfaces()
);
println!(" bConfigurationValue {:3}", config_desc.number());
println!(" iConfiguration {:3} {}",
config_desc.description_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h.handle.read_configuration_string(h.language, config_desc, h.timeout).unwrap_or(String::new())));
println!(
" iConfiguration {:3} {}",
config_desc.description_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h
.handle
.read_configuration_string(h.language, config_desc, h.timeout)
.unwrap_or(String::new()))
);
println!(" bmAttributes:");
println!(" Self Powered {:>5}", config_desc.self_powered());
println!(" Remote Wakeup {:>5}", config_desc.remote_wakeup());
Expand All @@ -110,34 +152,77 @@ fn print_config(config_desc: &libusb::ConfigDescriptor, handle: &mut Option<UsbD

fn print_interface(interface_desc: &libusb::InterfaceDescriptor, handle: &mut Option<UsbDevice>) {
println!(" Interface Descriptor:");
println!(" bInterfaceNumber {:3}", interface_desc.interface_number());
println!(" bAlternateSetting {:3}", interface_desc.setting_number());
println!(" bNumEndpoints {:3}", interface_desc.num_endpoints());
println!(" bInterfaceClass {:#04x}", interface_desc.class_code());
println!(" bInterfaceSubClass {:#04x}", interface_desc.sub_class_code());
println!(" bInterfaceProtocol {:#04x}", interface_desc.protocol_code());
println!(" iInterface {:3} {}",
interface_desc.description_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h.handle.read_interface_string(h.language, interface_desc, h.timeout).unwrap_or(String::new())));
println!(
" bInterfaceNumber {:3}",
interface_desc.interface_number()
);
println!(
" bAlternateSetting {:3}",
interface_desc.setting_number()
);
println!(
" bNumEndpoints {:3}",
interface_desc.num_endpoints()
);
println!(
" bInterfaceClass {:#04x}",
interface_desc.class_code()
);
println!(
" bInterfaceSubClass {:#04x}",
interface_desc.sub_class_code()
);
println!(
" bInterfaceProtocol {:#04x}",
interface_desc.protocol_code()
);
println!(
" iInterface {:3} {}",
interface_desc.description_string_index().unwrap_or(0),
handle.as_mut().map_or(String::new(), |h| h
.handle
.read_interface_string(h.language, interface_desc, h.timeout)
.unwrap_or(String::new()))
);
}

fn print_endpoint(endpoint_desc: &libusb::EndpointDescriptor) {
println!(" Endpoint Descriptor:");
println!(" bEndpointAddress {:#04x} EP {} {:?}", endpoint_desc.address(), endpoint_desc.number(), endpoint_desc.direction());
println!(
" bEndpointAddress {:#04x} EP {} {:?}",
endpoint_desc.address(),
endpoint_desc.number(),
endpoint_desc.direction()
);
println!(" bmAttributes:");
println!(" Transfer Type {:?}", endpoint_desc.transfer_type());
println!(" Synch Type {:?}", endpoint_desc.sync_type());
println!(" Usage Type {:?}", endpoint_desc.usage_type());
println!(" wMaxPacketSize {:#06x}", endpoint_desc.max_packet_size());
println!(" bInterval {:3}", endpoint_desc.interval());
println!(
" Transfer Type {:?}",
endpoint_desc.transfer_type()
);
println!(
" Synch Type {:?}",
endpoint_desc.sync_type()
);
println!(
" Usage Type {:?}",
endpoint_desc.usage_type()
);
println!(
" wMaxPacketSize {:#06x}",
endpoint_desc.max_packet_size()
);
println!(
" bInterval {:3}",
endpoint_desc.interval()
);
}

fn get_speed(speed: libusb::Speed) -> &'static str {
match speed {
libusb::Speed::Super => "5000 Mbps",
libusb::Speed::High => " 480 Mbps",
libusb::Speed::Full => " 12 Mbps",
libusb::Speed::Low => " 1.5 Mbps",
libusb::Speed::Unknown => "(unknown)"
libusb::Speed::Super => "5000 Mbps",
libusb::Speed::High => " 480 Mbps",
libusb::Speed::Full => " 12 Mbps",
libusb::Speed::Low => " 1.5 Mbps",
libusb::Speed::Unknown => "(unknown)",
}
}
Loading