Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ rusb = { version = "0.9" }

[target.'cfg(not(windows))'.dependencies]
rusb = { version = "0.9", optional = true }
nusb = { version = "0.1", optional = true }
nusb = { version = "0.2", optional = true }

[dev-dependencies]
hex = "0.4"
15 changes: 15 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
use nusb::Error as nusbError;
#[cfg(any(feature = "rusb", target_os = "windows"))]
use rusb::Error as usbError;
use std::error;
Expand All @@ -9,6 +11,8 @@ pub enum ChallengeResponseError {
IOError(ioError),
#[cfg(any(feature = "rusb", target_os = "windows"))]
UsbError(usbError),
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
NusbError(nusbError),
CommandNotSupported,
DeviceNotFound,
OpenDeviceError,
Expand All @@ -25,6 +29,8 @@ impl fmt::Display for ChallengeResponseError {
ChallengeResponseError::IOError(ref err) => write!(f, "IO error: {}", err),
#[cfg(any(feature = "rusb", target_os = "windows"))]
ChallengeResponseError::UsbError(ref err) => write!(f, "USB error: {}", err),
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
ChallengeResponseError::NusbError(ref err) => write!(f, "NUSB error: {}", err),
ChallengeResponseError::DeviceNotFound => write!(f, "Device not found"),
ChallengeResponseError::OpenDeviceError => write!(f, "Can not open device"),
ChallengeResponseError::CommandNotSupported => write!(f, "Command Not Supported"),
Expand All @@ -42,6 +48,8 @@ impl error::Error for ChallengeResponseError {
match *self {
#[cfg(any(feature = "rusb", target_os = "windows"))]
ChallengeResponseError::UsbError(ref err) => Some(err),
#[cfg(all(feature = "nusb", not(target_os = "windows")))]
ChallengeResponseError::NusbError(ref err) => Some(err),
_ => None,
}
}
Expand All @@ -59,3 +67,10 @@ impl From<usbError> for ChallengeResponseError {
ChallengeResponseError::UsbError(err)
}
}

#[cfg(all(feature = "nusb", not(target_os = "windows")))]
impl From<nusbError> for ChallengeResponseError {
fn from(err: nusbError) -> ChallengeResponseError {
ChallengeResponseError::NusbError(err)
}
}
48 changes: 25 additions & 23 deletions src/usb/nusb.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::time::Duration;

use nusb::{Device as NUSBDevice, Interface};
use nusb::{Device as NUSBDevice, Interface, MaybeFuture};

use crate::error::ChallengeResponseError;
use crate::usb::{Backend, Device, HID_GET_REPORT, HID_SET_REPORT, PRODUCT_ID, REPORT_TYPE_FEATURE, VENDOR_ID};
Expand All @@ -17,16 +17,16 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {
bus_id: u8,
address_id: u8,
) -> Result<(NUSBDevice, Vec<Interface>), ChallengeResponseError> {
let nusb_devices = match nusb::list_devices() {
let nusb_devices = match nusb::list_devices().wait() {
Ok(d) => d,
Err(e) => return Err(e.into()),
};
for device_info in nusb_devices {
if device_info.bus_number() != bus_id || device_info.device_address() != address_id {
if device_info.busnum() != bus_id || device_info.device_address() != address_id {
continue;
}

let device = match device_info.open() {
let device = match device_info.open().wait() {
Ok(d) => d,
Err(_) => {
return Err(ChallengeResponseError::OpenDeviceError);
Expand All @@ -35,7 +35,10 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {

let mut interfaces: Vec<Interface> = Vec::new();
for interface in device_info.interfaces() {
let interface = match device.detach_and_claim_interface(interface.interface_number()) {
let interface = match device
.detach_and_claim_interface(interface.interface_number())
.wait()
{
Ok(interface) => interface,
Err(_) => continue,
};
Expand All @@ -60,38 +63,37 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {
assert_eq!(buf.len(), 8);

let control_type = nusb::transfer::ControlType::Class;
let control_in = nusb::transfer::Control {
let control_in = nusb::transfer::ControlIn {
control_type,
recipient: nusb::transfer::Recipient::Interface,
request: HID_GET_REPORT,
value: REPORT_TYPE_FEATURE << 8,
index: 0,
length: 8,
};

match handle.control_in_blocking(control_in, buf, Duration::new(2, 0)) {
Ok(r) => Ok(r),
match handle.control_in(control_in, Duration::new(2, 0)).wait() {
Ok(r) => {
buf.copy_from_slice(&r);
Ok(r.len())
}
Err(_e) => Err(ChallengeResponseError::CanNotReadFromDevice),
}
}

fn raw_write(&self, handle: &mut NUSBDevice, packet: &[u8]) -> Result<(), ChallengeResponseError> {
let control_type = nusb::transfer::ControlType::Class;
let control_out = nusb::transfer::Control {
let control_out = nusb::transfer::ControlOut {
control_type,
recipient: nusb::transfer::Recipient::Interface,
request: HID_SET_REPORT,
value: REPORT_TYPE_FEATURE << 8,
index: 0,
data: packet,
};

match handle.control_out_blocking(control_out, packet, Duration::new(2, 0)) {
Ok(bytes_written) => {
if bytes_written != 8 {
Err(ChallengeResponseError::CanNotWriteToDevice)
} else {
Ok(())
}
}
match handle.control_out(control_out, Duration::new(2, 0)).wait() {
Ok(_) => Ok(()),
Err(_) => Err(ChallengeResponseError::CanNotWriteToDevice),
}
}
Expand All @@ -110,7 +112,7 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {
}

fn find_device_from_serial(&mut self, serial: u32) -> Result<Device, ChallengeResponseError> {
let nusb_devices = nusb::list_devices()?;
let nusb_devices = nusb::list_devices().wait()?;
for device_info in nusb_devices {
let product_id = device_info.product_id();
let vendor_id = device_info.vendor_id();
Expand All @@ -120,7 +122,7 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {
}

let device_serial =
match self.read_serial_from_device(device_info.bus_number(), device_info.device_address()) {
match self.read_serial_from_device(device_info.busnum(), device_info.device_address()) {
Ok(s) => s,
Err(_) => continue,
};
Expand All @@ -134,7 +136,7 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {
serial: Some(serial),
product_id,
vendor_id,
bus_id: device_info.bus_number(),
bus_id: device_info.busnum(),
address_id: device_info.device_address(),
});
}
Expand All @@ -144,7 +146,7 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {

fn find_all_devices(&mut self) -> Result<Vec<Device>, ChallengeResponseError> {
let mut devices: Vec<Device> = Vec::new();
let nusb_devices = nusb::list_devices()?;
let nusb_devices = nusb::list_devices().wait()?;
for device_info in nusb_devices {
let product_id = device_info.product_id();
let vendor_id = device_info.vendor_id();
Expand All @@ -154,7 +156,7 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {
}

let device_serial = self
.read_serial_from_device(device_info.bus_number(), device_info.device_address())
.read_serial_from_device(device_info.busnum(), device_info.device_address())
.ok();

devices.push(Device {
Expand All @@ -165,7 +167,7 @@ impl Backend<NUSBDevice, Interface> for NUSBBackend {
serial: device_serial,
product_id,
vendor_id,
bus_id: device_info.bus_number(),
bus_id: device_info.busnum(),
address_id: device_info.device_address(),
});
}
Expand Down