Skip to content
Open
Show file tree
Hide file tree
Changes from all 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: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ sudo: false

language: rust
rust:
- 1.3.0
- stable
- beta
- nightly
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ readme = "README.md"
keywords = ["usb", "libusb", "hardware", "bindings"]

[dependencies]
bit-set = "0.2.0"
bit-set = "0.5.0"
libusb-sys = "0.2.3"
libc = "0.2"

Expand Down
18 changes: 18 additions & 0 deletions examples/list_devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ fn print_config(config_desc: &libusb::ConfigDescriptor, handle: &mut Option<UsbD
println!(" Self Powered {:>5}", config_desc.self_powered());
println!(" Remote Wakeup {:>5}", config_desc.remote_wakeup());
println!(" bMaxPower {:4}mW", config_desc.max_power());

if let Some(extra) = config_desc.extra() {
println!(" Extra: {:?}", extra);
} else {
println!(" Extra: None");
}
}

fn print_interface(interface_desc: &libusb::InterfaceDescriptor, handle: &mut Option<UsbDevice>) {
Expand All @@ -119,6 +125,12 @@ fn print_interface(interface_desc: &libusb::InterfaceDescriptor, handle: &mut Op
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())));

if let Some(extra) = interface_desc.extra() {
println!(" Extra: {:?}", extra);
} else {
println!(" Extra: None");
}
}

fn print_endpoint(endpoint_desc: &libusb::EndpointDescriptor) {
Expand All @@ -130,6 +142,12 @@ fn print_endpoint(endpoint_desc: &libusb::EndpointDescriptor) {
println!(" Usage Type {:?}", endpoint_desc.usage_type());
println!(" wMaxPacketSize {:#06x}", endpoint_desc.max_packet_size());
println!(" bInterval {:3}", endpoint_desc.interval());

if let Some(extra) = endpoint_desc.extra() {
println!(" Extra: {:?}", extra);
} else {
println!(" Extra: None");
}
}

fn get_speed(speed: libusb::Speed) -> &'static str {
Expand Down
18 changes: 15 additions & 3 deletions src/config_descriptor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::fmt;
use std::mem;
use std::slice;

use libusb::*;
Expand Down Expand Up @@ -33,7 +32,7 @@ impl ConfigDescriptor {
/// Returns the device's maximum power consumption (in milliwatts) in this configuration.
pub fn max_power(&self) -> u16 {
unsafe {
(*self.descriptor).bMaxPower as u16 * 2
u16::from((*self.descriptor).bMaxPower) * 2
}
}

Expand Down Expand Up @@ -79,14 +78,27 @@ impl ConfigDescriptor {

Interfaces { iter: interfaces.iter() }
}

/// Returns the unknown 'extra' bytes that libusb does not understand.
pub fn extra(&self) -> Option<& [u8]> {
unsafe {
match (*self.descriptor).extra_length {
len if len > 0 => Some(slice::from_raw_parts(
(*self.descriptor).extra,
len as usize,
)),
_ => None,
}
}
}
}

impl fmt::Debug for ConfigDescriptor {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let mut debug = fmt.debug_struct("ConfigDescriptor");

let descriptor: &libusb_config_descriptor = unsafe {
mem::transmute(self.descriptor)
&*self.descriptor
};

debug.field("bLength", &descriptor.bLength);
Expand Down
9 changes: 5 additions & 4 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl Context {

try_unsafe!(libusb_init(&mut context));

Ok(Context { context: context })
Ok(Context { context })
}

/// Sets the log level of a `libusb` context.
Expand Down Expand Up @@ -91,7 +91,7 @@ impl Context {
///
/// Returns a device handle for the first device found matching `vendor_id` and `product_id`.
/// On error, or if the device could not be found, it returns `None`.
pub fn open_device_with_vid_pid<'a>(&'a self, vendor_id: u16, product_id: u16) -> Option<DeviceHandle<'a>> {
pub fn open_device_with_vid_pid(&self, vendor_id: u16, product_id: u16) -> Option<DeviceHandle> {
let handle = unsafe { libusb_open_device_with_vid_pid(self.context, vendor_id, product_id) };

if handle.is_null() {
Expand All @@ -105,6 +105,7 @@ impl Context {


/// Library logging levels.
#[derive(Clone,Copy)]
pub enum LogLevel {
/// No messages are printed by `libusb` (default).
None,
Expand All @@ -125,8 +126,8 @@ pub enum LogLevel {
}

impl LogLevel {
fn as_c_int(&self) -> c_int {
match *self {
fn as_c_int(self) -> c_int {
match self {
LogLevel::None => LIBUSB_LOG_LEVEL_NONE,
LogLevel::Error => LIBUSB_LOG_LEVEL_ERROR,
LogLevel::Warning => LIBUSB_LOG_LEVEL_WARNING,
Expand Down
9 changes: 7 additions & 2 deletions src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,19 @@ impl<'a> Device<'a> {

Ok(unsafe { device_handle::from_libusb(self.context, handle) })
}

/// Returns the device's port number
pub fn port_number(&self) -> u8 {
unsafe { libusb_get_port_number(self.device) }
}
}

#[doc(hidden)]
pub unsafe fn from_libusb<'a>(context: PhantomData<&'a Context>, device: *mut libusb_device) -> Device<'a> {
libusb_ref_device(device);

Device {
context: context,
device: device,
context,
device,
}
}
42 changes: 21 additions & 21 deletions src/device_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl<'a> DeviceHandle<'a> {

/// Sets the device's active configuration.
pub fn set_active_configuration(&mut self, config: u8) -> ::Result<()> {
try_unsafe!(libusb_set_configuration(self.handle, config as c_int));
try_unsafe!(libusb_set_configuration(self.handle, c_int::from(config)));
Ok(())
}

Expand All @@ -69,7 +69,7 @@ impl<'a> DeviceHandle<'a> {
///
/// This method is not supported on all platforms.
pub fn kernel_driver_active(&self, iface: u8) -> ::Result<bool> {
match unsafe { libusb_kernel_driver_active(self.handle, iface as c_int) } {
match unsafe { libusb_kernel_driver_active(self.handle, c_int::from(iface)) } {
0 => Ok(false),
1 => Ok(true),
err => Err(error::from_libusb(err)),
Expand All @@ -80,15 +80,15 @@ impl<'a> DeviceHandle<'a> {
///
/// This method is not supported on all platforms.
pub fn detach_kernel_driver(&mut self, iface: u8) -> ::Result<()> {
try_unsafe!(libusb_detach_kernel_driver(self.handle, iface as c_int));
try_unsafe!(libusb_detach_kernel_driver(self.handle, c_int::from(iface)));
Ok(())
}

/// Attaches a kernel driver to the device.
///
/// This method is not supported on all platforms.
pub fn attach_kernel_driver(&mut self, iface: u8) -> ::Result<()> {
try_unsafe!(libusb_attach_kernel_driver(self.handle, iface as c_int));
try_unsafe!(libusb_attach_kernel_driver(self.handle, c_int::from(iface)));
Ok(())
}

Expand All @@ -97,21 +97,21 @@ impl<'a> DeviceHandle<'a> {
/// An interface must be claimed before operating on it. All claimed interfaces are released
/// when the device handle goes out of scope.
pub fn claim_interface(&mut self, iface: u8) -> ::Result<()> {
try_unsafe!(libusb_claim_interface(self.handle, iface as c_int));
try_unsafe!(libusb_claim_interface(self.handle, c_int::from(iface)));
self.interfaces.insert(iface as usize);
Ok(())
}

/// Releases a claimed interface.
pub fn release_interface(&mut self, iface: u8) -> ::Result<()> {
try_unsafe!(libusb_release_interface(self.handle, iface as c_int));
self.interfaces.remove(&(iface as usize));
try_unsafe!(libusb_release_interface(self.handle, c_int::from(iface)));
self.interfaces.remove(iface as usize);
Ok(())
}

/// Sets an interface's active setting.
pub fn set_alternate_setting(&mut self, iface: u8, setting: u8) -> ::Result<()> {
try_unsafe!(libusb_set_interface_alt_setting(self.handle, iface as c_int, setting as c_int));
try_unsafe!(libusb_set_interface_alt_setting(self.handle, c_int::from(iface), c_int::from(setting)));
Ok(())
}

Expand Down Expand Up @@ -146,7 +146,7 @@ impl<'a> DeviceHandle<'a> {

let ptr = buf.as_mut_ptr() as *mut c_uchar;
let len = buf.len() as c_int;
let timeout_ms = (timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000) as c_uint;
let timeout_ms = (timeout.as_secs() * 1000 + u64::from(timeout.subsec_nanos()) / 1_000_000) as c_uint;

match unsafe { libusb_interrupt_transfer(self.handle, endpoint, ptr, len, &mut transferred, timeout_ms) } {
0 => {
Expand Down Expand Up @@ -192,7 +192,7 @@ impl<'a> DeviceHandle<'a> {

let ptr = buf.as_ptr() as *mut c_uchar;
let len = buf.len() as c_int;
let timeout_ms = (timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000) as c_uint;
let timeout_ms = (timeout.as_secs() * 1000 + u64::from(timeout.subsec_nanos()) / 1_000_000) as c_uint;

match unsafe { libusb_interrupt_transfer(self.handle, endpoint, ptr, len, &mut transferred, timeout_ms) } {
0 => {
Expand Down Expand Up @@ -240,7 +240,7 @@ impl<'a> DeviceHandle<'a> {

let ptr = buf.as_mut_ptr() as *mut c_uchar;
let len = buf.len() as c_int;
let timeout_ms = (timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000) as c_uint;
let timeout_ms = (timeout.as_secs() * 1000 + u64::from(timeout.subsec_nanos()) / 1_000_000) as c_uint;

match unsafe { libusb_bulk_transfer(self.handle, endpoint, ptr, len, &mut transferred, timeout_ms) } {
0 => {
Expand Down Expand Up @@ -286,7 +286,7 @@ impl<'a> DeviceHandle<'a> {

let ptr = buf.as_ptr() as *mut c_uchar;
let len = buf.len() as c_int;
let timeout_ms = (timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000) as c_uint;
let timeout_ms = (timeout.as_secs() * 1000 + u64::from(timeout.subsec_nanos()) / 1_000_000) as c_uint;

match unsafe { libusb_bulk_transfer(self.handle, endpoint, ptr, len, &mut transferred, timeout_ms) } {
0 => {
Expand Down Expand Up @@ -337,7 +337,7 @@ impl<'a> DeviceHandle<'a> {

let ptr = buf.as_mut_ptr() as *mut c_uchar;
let len = buf.len() as u16;
let timeout_ms = (timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000) as c_uint;
let timeout_ms = (timeout.as_secs() * 1000 + u64::from(timeout.subsec_nanos()) / 1_000_000) as c_uint;

let res = unsafe {
libusb_control_transfer(self.handle, request_type, request, value, index, ptr, len, timeout_ms)
Expand Down Expand Up @@ -383,7 +383,7 @@ impl<'a> DeviceHandle<'a> {

let ptr = buf.as_ptr() as *mut c_uchar;
let len = buf.len() as u16;
let timeout_ms = (timeout.as_secs() * 1000 + timeout.subsec_nanos() as u64 / 1_000_000) as c_uint;
let timeout_ms = (timeout.as_secs() * 1000 + u64::from(timeout.subsec_nanos()) / 1_000_000) as c_uint;

let res = unsafe {
libusb_control_transfer(self.handle, request_type, request, value, index, ptr, len, timeout_ms)
Expand All @@ -403,13 +403,13 @@ impl<'a> DeviceHandle<'a> {
pub fn read_languages(&self, timeout: Duration) -> ::Result<Vec<Language>> {
let mut buf = Vec::<u8>::with_capacity(256);

let mut buf_slice = unsafe {
let buf_slice = unsafe {
slice::from_raw_parts_mut((&mut buf[..]).as_mut_ptr(), buf.capacity())
};

let len = try!(self.read_control(request_type(Direction::In, RequestType::Standard, Recipient::Device),
LIBUSB_REQUEST_GET_DESCRIPTOR,
(LIBUSB_DT_STRING as u16) << 8,
u16::from(LIBUSB_DT_STRING) << 8,
0,
buf_slice,
timeout));
Expand All @@ -419,7 +419,7 @@ impl<'a> DeviceHandle<'a> {
}

Ok(buf.chunks(2).skip(1).map(|chunk| {
let lang_id = chunk[0] as u16 | (chunk[1] as u16) << 8;
let lang_id = u16::from(chunk[0]) | u16::from(chunk[1]) << 8;
::language::from_lang_id(lang_id)
}).collect())
}
Expand All @@ -430,13 +430,13 @@ impl<'a> DeviceHandle<'a> {
pub fn read_string_descriptor(&self, language: Language, index: u8, timeout: Duration) -> ::Result<String> {
let mut buf = Vec::<u8>::with_capacity(256);

let mut buf_slice = unsafe {
let buf_slice = unsafe {
slice::from_raw_parts_mut((&mut buf[..]).as_mut_ptr(), buf.capacity())
};

let len = try!(self.read_control(request_type(Direction::In, RequestType::Standard, Recipient::Device),
LIBUSB_REQUEST_GET_DESCRIPTOR,
(LIBUSB_DT_STRING as u16) << 8 | index as u16,
u16::from(LIBUSB_DT_STRING) << 8 | u16::from(index),
language.lang_id(),
buf_slice,
timeout));
Expand All @@ -446,7 +446,7 @@ impl<'a> DeviceHandle<'a> {
}

let utf16: Vec<u16> = buf.chunks(2).skip(1).map(|chunk| {
chunk[0] as u16 | (chunk[1] as u16) << 8
u16::from(chunk[0]) | u16::from(chunk[1]) << 8
}).collect();

String::from_utf16(&utf16[..]).map_err(|_| Error::Other)
Expand Down Expand Up @@ -497,7 +497,7 @@ impl<'a> DeviceHandle<'a> {
pub unsafe fn from_libusb<'a>(context: PhantomData<&'a Context>, handle: *mut libusb_device_handle) -> DeviceHandle<'a> {
DeviceHandle {
_context: context,
handle: handle,
handle,
interfaces: BitSet::with_capacity(u8::max_value() as usize + 1),
}
}
9 changes: 6 additions & 3 deletions src/device_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ impl<'a> DeviceList<'a> {
self.len
}

/// Returns true if the list is empty, else returns false.
pub fn is_empty(&self) -> bool { self.len == 0 }

/// Returns an iterator over the devices in the list.
///
/// The iterator yields a sequence of `Device` objects.
Expand Down Expand Up @@ -70,10 +73,10 @@ impl<'a, 'b> Iterator for Devices<'a, 'b> {


#[doc(hidden)]
pub unsafe fn from_libusb<'a>(_context: &'a Context, list: *const *mut libusb_device, len: usize,) -> DeviceList<'a> {
pub unsafe fn from_libusb(_context: &Context, list: *const *mut libusb_device, len: usize,) -> DeviceList {
DeviceList {
context: PhantomData,
list: list,
len: len,
list,
len,
}
}
13 changes: 13 additions & 0 deletions src/endpoint_descriptor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fmt;
use std::slice;

use libusb::*;

Expand Down Expand Up @@ -71,6 +72,18 @@ impl<'a> EndpointDescriptor<'a> {
pub fn interval(&self) -> u8 {
self.descriptor.bInterval
}

/// Returns the unknown 'extra' bytes that libusb does not understand.
pub fn extra(&'a self) -> Option<&'a [u8]> {
unsafe {
match (*self.descriptor).extra_length {
len if len > 0 => {
Some(slice::from_raw_parts((*self.descriptor).extra, len as usize))
},
_ => None
}
}
}
}

impl<'a> fmt::Debug for EndpointDescriptor<'a> {
Expand Down
Loading