1 //! This crate provides a safe wrapper around the native `libusb` library.
2 
3 pub use libusb1_sys as ffi;
4 pub use libusb1_sys::constants;
5 
6 #[cfg(unix)]
7 pub use crate::options::disable_device_discovery;
8 pub use crate::{
9     config_descriptor::{ConfigDescriptor, Interfaces},
10     context::{Context, GlobalContext, LogCallbackMode, LogLevel, UsbContext},
11     device::Device,
12     device_descriptor::DeviceDescriptor,
13     device_handle::DeviceHandle,
14     device_list::{DeviceList, Devices},
15     endpoint_descriptor::EndpointDescriptor,
16     error::{Error, Result},
17     fields::{
18         request_type, Direction, Recipient, RequestType, Speed, SyncType, TransferType, UsageType,
19         Version,
20     },
21     hotplug::{Hotplug, HotplugBuilder, Registration},
22     interface_descriptor::{
23         EndpointDescriptors, Interface, InterfaceDescriptor, InterfaceDescriptors,
24     },
25     language::{Language, PrimaryLanguage, SubLanguage},
26     options::UsbOption,
27     version::{version, LibraryVersion},
28 };
29 
30 #[cfg(test)]
31 #[macro_use]
32 mod test_helpers;
33 
34 #[macro_use]
35 mod error;
36 mod version;
37 
38 mod context;
39 mod device;
40 mod device_handle;
41 mod device_list;
42 
43 mod config_descriptor;
44 mod device_descriptor;
45 mod endpoint_descriptor;
46 mod fields;
47 mod hotplug;
48 mod interface_descriptor;
49 mod language;
50 mod options;
51 
52 /// Tests whether the running `libusb` library supports capability API.
has_capability() -> bool53 pub fn has_capability() -> bool {
54     GlobalContext::default().as_raw();
55     unsafe { libusb1_sys::libusb_has_capability(constants::LIBUSB_CAP_HAS_CAPABILITY) != 0 }
56 }
57 
58 /// Tests whether the running `libusb` library supports hotplug.
has_hotplug() -> bool59 pub fn has_hotplug() -> bool {
60     GlobalContext::default().as_raw();
61     unsafe { libusb1_sys::libusb_has_capability(constants::LIBUSB_CAP_HAS_HOTPLUG) != 0 }
62 }
63 
64 /// Tests whether the running `libusb` library has HID access.
has_hid_access() -> bool65 pub fn has_hid_access() -> bool {
66     GlobalContext::default().as_raw();
67     unsafe { libusb1_sys::libusb_has_capability(constants::LIBUSB_CAP_HAS_HID_ACCESS) != 0 }
68 }
69 
70 /// Tests whether the running `libusb` library supports detaching the kernel driver.
supports_detach_kernel_driver() -> bool71 pub fn supports_detach_kernel_driver() -> bool {
72     GlobalContext::default().as_raw();
73     unsafe {
74         libusb1_sys::libusb_has_capability(constants::LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER) != 0
75     }
76 }
77 
78 /// Returns a list of the current USB devices. Using global context
devices() -> crate::Result<DeviceList<GlobalContext>>79 pub fn devices() -> crate::Result<DeviceList<GlobalContext>> {
80     GlobalContext::default().devices()
81 }
82 
83 /// Sets the log level of a `libusb` global context.
set_log_level(level: LogLevel)84 pub fn set_log_level(level: LogLevel) {
85     unsafe {
86         libusb1_sys::libusb_set_debug(GlobalContext::default().as_raw(), level.as_c_int());
87     }
88 }
89 
90 /// Convenience function to open a device by its vendor ID and product ID.
91 /// Using global context
92 ///
93 /// This function is provided as a convenience for building prototypes without having to
94 /// iterate a [`DeviceList`](struct.DeviceList.html). It is not meant for production
95 /// applications.
96 ///
97 /// Returns a device handle for the first device found matching `vendor_id` and `product_id`.
98 /// On error, or if the device could not be found, it returns `None`.
open_device_with_vid_pid( vendor_id: u16, product_id: u16, ) -> Option<DeviceHandle<GlobalContext>>99 pub fn open_device_with_vid_pid(
100     vendor_id: u16,
101     product_id: u16,
102 ) -> Option<DeviceHandle<GlobalContext>> {
103     let handle = unsafe {
104         libusb1_sys::libusb_open_device_with_vid_pid(
105             GlobalContext::default().as_raw(),
106             vendor_id,
107             product_id,
108         )
109     };
110 
111     if handle.is_null() {
112         None
113     } else {
114         Some(unsafe {
115             DeviceHandle::from_libusb(
116                 GlobalContext::default(),
117                 std::ptr::NonNull::new_unchecked(handle),
118             )
119         })
120     }
121 }
122