Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions examples/list_devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ extern crate libusb;

use std::time::Duration;

struct UsbDevice<'a> {
handle: libusb::DeviceHandle<'a>,
struct UsbDevice {
handle: libusb::DeviceHandle,
language: libusb::Language,
timeout: Duration,
}
Expand Down
4 changes: 2 additions & 2 deletions examples/read_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn main() {
let pid: u16 = FromStr::from_str(args[2].as_ref()).unwrap();

match libusb::Context::new() {
Ok(mut context) => match open_device(&mut context, vid, pid) {
Ok(context) => match open_device(context, vid, pid) {
Some((mut device, device_desc, mut handle)) => {
read_device(&mut device, &device_desc, &mut handle).unwrap()
}
Expand All @@ -35,7 +35,7 @@ fn main() {
}

fn open_device(
context: &mut libusb::Context,
context: libusb::Context,
vid: u16,
pid: u16,
) -> Option<(
Expand Down
14 changes: 5 additions & 9 deletions src/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::marker::PhantomData;
use std::mem;
use std::rc::Rc;

use libc::c_int;
use libusb::*;
Expand Down Expand Up @@ -62,15 +62,15 @@ impl Context {
}

/// Returns a list of the current USB devices. The context must outlive the device list.
pub fn devices<'a>(&'a self) -> error::Result<DeviceList<'a>> {
pub fn devices(self) -> error::Result<DeviceList> {
let mut list: *const *mut libusb_device = unsafe { mem::uninitialized() };

let n = unsafe { libusb_get_device_list(self.context, &mut list) };

if n < 0 {
Err(error::from_libusb(n as c_int))
} else {
Ok(unsafe { device_list::from_libusb(self, list, n as usize) })
Ok(unsafe { device_list::from_libusb(Rc::new(self), list, n as usize) })
}
}

Expand All @@ -82,18 +82,14 @@ 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() {
None
} else {
Some(unsafe { device_handle::from_libusb(PhantomData, handle) })
Some(unsafe { device_handle::from_libusb(Rc::new(self), handle) })
}
}
}
Expand Down
27 changes: 13 additions & 14 deletions src/device.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::marker::PhantomData;
use std::mem;
use std::rc::Rc;

use libusb::*;

Expand All @@ -11,24 +11,26 @@ use crate::error;
use crate::fields::{self, Speed};

/// A reference to a USB device.
pub struct Device<'a> {
context: PhantomData<&'a Context>,
pub struct Device {
context: Rc<Context>,
device: *mut libusb_device,
}

impl<'a> Drop for Device<'a> {
impl Drop for Device {
/// Releases the device reference.
fn drop(&mut self) {
unsafe {
libusb_unref_device(self.device);
}

drop(&self.context);
}
}

unsafe impl<'a> Send for Device<'a> {}
unsafe impl<'a> Sync for Device<'a> {}
unsafe impl Send for Device {}
unsafe impl Sync for Device {}

impl<'a> Device<'a> {
impl Device {
/// Reads the device descriptor.
pub fn device_descriptor(&self) -> error::Result<DeviceDescriptor> {
let mut descriptor: libusb_device_descriptor = unsafe { mem::uninitialized() };
Expand Down Expand Up @@ -80,24 +82,21 @@ impl<'a> Device<'a> {
}

/// Opens the device.
pub fn open(&self) -> error::Result<DeviceHandle<'a>> {
pub fn open(&self) -> error::Result<DeviceHandle> {
let mut handle: *mut libusb_device_handle = unsafe { mem::uninitialized() };

try_unsafe!(libusb_open(self.device, &mut handle));

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

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

Device {
context: context,
context: context.clone(),
device: device,
}
}
23 changes: 11 additions & 12 deletions src/device_handle.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::marker::PhantomData;
use std::mem;
use std::rc::Rc;
use std::slice;
use std::time::Duration;

Expand All @@ -16,13 +16,13 @@ use crate::interface_descriptor::InterfaceDescriptor;
use crate::language::{self, Language};

/// A handle to an open USB device.
pub struct DeviceHandle<'a> {
_context: PhantomData<&'a Context>,
pub struct DeviceHandle {
context: Rc<Context>,
handle: *mut libusb_device_handle,
interfaces: BitSet,
}

impl<'a> Drop for DeviceHandle<'a> {
impl Drop for DeviceHandle {
/// Closes the device.
fn drop(&mut self) {
unsafe {
Expand All @@ -32,13 +32,15 @@ impl<'a> Drop for DeviceHandle<'a> {

libusb_close(self.handle);
}

drop(&self.context);
}
}

unsafe impl<'a> Send for DeviceHandle<'a> {}
unsafe impl<'a> Sync for DeviceHandle<'a> {}
unsafe impl Send for DeviceHandle {}
unsafe impl Sync for DeviceHandle {}

impl<'a> DeviceHandle<'a> {
impl DeviceHandle {
/// Returns the active configuration number.
pub fn active_configuration(&self) -> error::Result<u8> {
let mut config = unsafe { mem::uninitialized() };
Expand Down Expand Up @@ -615,12 +617,9 @@ impl<'a> DeviceHandle<'a> {
}

#[doc(hidden)]
pub unsafe fn from_libusb<'a>(
context: PhantomData<&'a Context>,
handle: *mut libusb_device_handle,
) -> DeviceHandle<'a> {
pub unsafe fn from_libusb(context: Rc<Context>, handle: *mut libusb_device_handle) -> DeviceHandle {
DeviceHandle {
_context: context,
context: context.clone(),
handle: handle,
interfaces: BitSet::with_capacity(u8::max_value() as usize + 1),
}
Expand Down
38 changes: 20 additions & 18 deletions src/device_list.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::marker::PhantomData;
use std::rc::Rc;
use std::slice;

use libusb::*;
Expand All @@ -7,22 +7,23 @@ use crate::context::Context;
use crate::device::{self, Device};

/// A list of detected USB devices.
pub struct DeviceList<'a> {
context: PhantomData<&'a Context>,
pub struct DeviceList {
context: Rc<Context>,
list: *const *mut libusb_device,
len: usize,
}

impl<'a> Drop for DeviceList<'a> {
impl Drop for DeviceList {
/// Frees the device list.
fn drop(&mut self) {
unsafe {
libusb_free_device_list(self.list, 1);
}
drop(&self.context);
}
}

impl<'a> DeviceList<'a> {
impl DeviceList {
/// Returns the number of devices in the list.
pub fn len(&self) -> usize {
self.len
Expand All @@ -31,31 +32,32 @@ impl<'a> DeviceList<'a> {
/// Returns an iterator over the devices in the list.
///
/// The iterator yields a sequence of `Device` objects.
pub fn iter<'b>(&'b self) -> Devices<'a, 'b> {
pub fn iter(&self) -> Devices {
Devices {
context: self.context,
context: self.context.clone(),
devices: unsafe { slice::from_raw_parts(self.list, self.len) },
index: 0,
}
}
}

/// Iterator over detected USB devices.
pub struct Devices<'a, 'b> {
context: PhantomData<&'a Context>,
devices: &'b [*mut libusb_device],
pub struct Devices<'a> {
context: Rc<Context>,
devices: &'a [*mut libusb_device],
index: usize,
}

impl<'a, 'b> Iterator for Devices<'a, 'b> {
type Item = Device<'a>;
impl<'a> Iterator for Devices<'a> {
type Item = Device;

fn next(&mut self) -> Option<Device<'a>> {
fn next(&mut self) -> Option<Device> {
if self.index < self.devices.len() {
let device = self.devices[self.index];

self.index += 1;
Some(unsafe { device::from_libusb(self.context, device) })
let ctx = Rc::clone(&self.context);
Some(unsafe { device::from_libusb(ctx, device) })
} else {
None
}
Expand All @@ -68,13 +70,13 @@ impl<'a, 'b> Iterator for Devices<'a, 'b> {
}

#[doc(hidden)]
pub unsafe fn from_libusb<'a>(
_context: &'a Context,
pub unsafe fn from_libusb(
context: Rc<Context>,
list: *const *mut libusb_device,
len: usize,
) -> DeviceList<'a> {
) -> DeviceList {
DeviceList {
context: PhantomData,
context: context.clone(),
list: list,
len: len,
}
Expand Down