diff --git a/src/lib.rs b/src/lib.rs index 2b9d94d..18b9392 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,6 +66,11 @@ impl ChallengeResponse { self.backend.find_all_devices() } + pub fn read_serial_number(&mut self, conf: Config) -> Result { + self.backend + .read_serial_from_device(conf.device.bus_id, conf.device.address_id) + } + pub fn write_config(&mut self, conf: Config, device_config: &mut DeviceModeConfig) -> Result<()> { let d = device_config.to_frame(conf.command); let mut buf = [0; usb::STATUS_UPDATE_PAYLOAD_SIZE]; @@ -87,39 +92,6 @@ impl ChallengeResponse { Ok(()) } - pub fn read_serial_number(&mut self, conf: Config) -> Result { - let (mut handle, interfaces) = self - .backend - .open_device(conf.device.bus_id, conf.device.address_id)?; - - let challenge = [0; CHALLENGE_SIZE]; - let command = Command::DeviceSerial; - - let d = Frame::new(challenge, command); // FixMe: do not need a challange - let mut buf = [0; usb::STATUS_UPDATE_PAYLOAD_SIZE]; - self.backend.wait( - &mut handle, - |f| !f.contains(usb::Flags::SLOT_WRITE_FLAG), - &mut buf, - )?; - - self.backend.write_frame(&mut handle, &d)?; - - // Read the response. - let mut response = [0; usb::RESPONSE_SIZE]; - self.backend.read_response(&mut handle, &mut response)?; - self.backend.close_device(handle, interfaces)?; - - // Check response. - if crc16(&response[..6]) != CRC_RESIDUAL_OK { - return Err(ChallengeResponseError::WrongCRC); - } - - let serial = structure!("2I").unpack(response[..8].to_vec())?; - - Ok(serial.0) - } - pub fn challenge_response_hmac(&mut self, chall: &[u8], conf: Config) -> Result { let mut hmac = Hmac([0; 20]); diff --git a/src/usb.rs b/src/usb.rs index 8b16011..0f8502a 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -190,4 +190,34 @@ pub trait Backend { self.write_reset(handle)?; Ok(r0) } + + fn read_serial_from_device( + &mut self, + device_bus_id: u8, + device_address: u8, + ) -> Result { + let (mut handle, interfaces) = self.open_device(device_bus_id, device_address)?; + let challenge = [0; CHALLENGE_SIZE]; + let command = Command::DeviceSerial; + + let d = Frame::new(challenge, command); // FIXME: do not need a challange + let mut buf = [0; STATUS_UPDATE_PAYLOAD_SIZE]; + self.wait(&mut handle, |f| !f.contains(Flags::SLOT_WRITE_FLAG), &mut buf)?; + + self.write_frame(&mut handle, &d)?; + + // Read the response. + let mut response = [0; RESPONSE_SIZE]; + self.read_response(&mut handle, &mut response)?; + self.close_device(handle, interfaces)?; + + // Check response. + if crc16(&response[..6]) != crate::sec::CRC_RESIDUAL_OK { + return Err(ChallengeResponseError::WrongCRC); + } + + let serial = structure!("2I").unpack(response[..8].to_vec())?; + + Ok(serial.0) + } } diff --git a/src/usb/nusb.rs b/src/usb/nusb.rs index d9360ce..d6e74f0 100644 --- a/src/usb/nusb.rs +++ b/src/usb/nusb.rs @@ -118,13 +118,11 @@ impl Backend for NUSBBackend { continue; } - let device_serial = match device_info.serial_number() { - Some(s) => match s.parse::() { + let device_serial = + match self.read_serial_from_device(device_info.bus_number(), device_info.device_address()) { Ok(s) => s, Err(_) => continue, - }, - None => continue, - }; + }; if device_serial == serial { return Ok(Device { @@ -154,18 +152,16 @@ impl Backend for NUSBBackend { continue; } + let device_serial = self + .read_serial_from_device(device_info.bus_number(), device_info.device_address()) + .ok(); + devices.push(Device { name: match device_info.manufacturer_string() { Some(name) => Some(name.to_string()), None => Some("unknown".to_string()), }, - serial: match device_info.serial_number() { - Some(serial) => match serial.parse::() { - Ok(s) => Some(s), - Err(_) => None, - }, - None => None, - }, + serial: device_serial, product_id, vendor_id, bus_id: device_info.bus_number(), diff --git a/src/usb/rusb.rs b/src/usb/rusb.rs index 6a20fb5..7e642a0 100644 --- a/src/usb/rusb.rs +++ b/src/usb/rusb.rs @@ -1,13 +1,7 @@ use error::ChallengeResponseError; -use rusb::{ - request_type, Context, Device as RUSBDevice, DeviceHandle, Direction, Recipient, RequestType, UsbContext, -}; -use sec::crc16; +use rusb::{request_type, Context, DeviceHandle, Direction, Recipient, RequestType, UsbContext}; use std::time::Duration; -use usb::{ - Backend, Command, Device, Flags, Frame, CHALLENGE_SIZE, HID_GET_REPORT, HID_SET_REPORT, PRODUCT_ID, - REPORT_TYPE_FEATURE, RESPONSE_SIZE, STATUS_UPDATE_PAYLOAD_SIZE, VENDOR_ID, -}; +use usb::{Backend, Device, HID_GET_REPORT, HID_SET_REPORT, PRODUCT_ID, REPORT_TYPE_FEATURE, VENDOR_ID}; pub struct RUSBBackend { context: Context, @@ -144,7 +138,9 @@ impl Backend, u8> for RUSBBackend { } let name = device.open()?.read_product_string_ascii(&descr).ok(); - let serial = self.read_serial_from_device(device.clone()).ok(); + let serial = self + .read_serial_from_device(device.bus_number(), device.address()) + .ok(); let device = Device { name, serial, @@ -174,7 +170,10 @@ impl Backend, u8> for RUSBBackend { } let name = device.open()?.read_product_string_ascii(&descr).ok(); - let fetched_serial = match self.read_serial_from_device(device.clone()).ok() { + let fetched_serial = match self + .read_serial_from_device(device.bus_number(), device.address()) + .ok() + { Some(s) => s, None => 0, }; @@ -210,7 +209,9 @@ impl Backend, u8> for RUSBBackend { } let name = device.open()?.read_product_string_ascii(&descr).ok(); - let serial = self.read_serial_from_device(device.clone()).ok(); + let serial = self + .read_serial_from_device(device.bus_number(), device.address()) + .ok(); let device = Device { name, serial, @@ -229,31 +230,3 @@ impl Backend, u8> for RUSBBackend { Err(ChallengeResponseError::DeviceNotFound) } } - -impl RUSBBackend { - fn read_serial_from_device(&mut self, device: RUSBDevice) -> Result { - let (mut handle, interfaces) = self.open_device(device.bus_number(), device.address())?; - let challenge = [0; CHALLENGE_SIZE]; - let command = Command::DeviceSerial; - - let d = Frame::new(challenge, command); // FixMe: do not need a challange - let mut buf = [0; STATUS_UPDATE_PAYLOAD_SIZE]; - self.wait(&mut handle, |f| !f.contains(Flags::SLOT_WRITE_FLAG), &mut buf)?; - - self.write_frame(&mut handle, &d)?; - - // Read the response. - let mut response = [0; RESPONSE_SIZE]; - self.read_response(&mut handle, &mut response)?; - self.close_device(handle, interfaces)?; - - // Check response. - if crc16(&response[..6]) != crate::sec::CRC_RESIDUAL_OK { - return Err(ChallengeResponseError::WrongCRC); - } - - let serial = structure!("2I").unpack(response[..8].to_vec())?; - - Ok(serial.0) - } -}