diff --git a/adb_client/src/device/adb_usb_device.rs b/adb_client/src/device/adb_usb_device.rs index 25a003a..5467d6f 100644 --- a/adb_client/src/device/adb_usb_device.rs +++ b/adb_client/src/device/adb_usb_device.rs @@ -1,3 +1,4 @@ +use rusb::constants::LIBUSB_CLASS_VENDOR_SPEC; use rusb::Device; use rusb::DeviceDescriptor; use rusb::UsbContext; @@ -57,8 +58,6 @@ fn search_adb_devices() -> Result> { } fn is_adb_device(device: &Device, des: &DeviceDescriptor) -> bool { - const ADB_CLASS: u8 = 0xff; - const ADB_SUBCLASS: u8 = 0x42; const ADB_PROTOCOL: u8 = 0x1; @@ -77,7 +76,7 @@ fn is_adb_device(device: &Device, des: &DeviceDescriptor) -> b let class = interface_des.class_code(); let subcl = interface_des.sub_class_code(); if proto == ADB_PROTOCOL - && ((class == ADB_CLASS && subcl == ADB_SUBCLASS) + && ((class == LIBUSB_CLASS_VENDOR_SPEC && subcl == ADB_SUBCLASS) || (class == BULK_CLASS && subcl == BULK_ADB_SUBCLASS)) { return true; diff --git a/adb_client/src/error.rs b/adb_client/src/error.rs index 700ebce..42dbdc1 100644 --- a/adb_client/src/error.rs +++ b/adb_client/src/error.rs @@ -67,7 +67,7 @@ pub enum RustADBError { #[error("Cannot get home directory")] NoHomeDirectory, /// Generic USB error - #[error(transparent)] + #[error("USB Error: {0}")] UsbError(#[from] rusb::Error), /// USB device not found #[error("USB Device not found: {0} {1}")] diff --git a/adb_client/src/transports/usb_transport.rs b/adb_client/src/transports/usb_transport.rs index 5b37f87..2ff9554 100644 --- a/adb_client/src/transports/usb_transport.rs +++ b/adb_client/src/transports/usb_transport.rs @@ -11,7 +11,7 @@ use crate::{ Result, RustADBError, }; -#[derive(Debug)] +#[derive(Clone, Debug)] struct Endpoint { iface: u8, address: u8, @@ -22,6 +22,8 @@ struct Endpoint { pub struct USBTransport { device: Device, handle: Option>>, + read_endpoint: Option, + write_endpoint: Option, } impl USBTransport { @@ -49,6 +51,8 @@ impl USBTransport { Self { device: rusb_device, handle: None, + read_endpoint: None, + write_endpoint: None, } } @@ -62,43 +66,34 @@ impl USBTransport { .cloned() } + fn get_read_endpoint(&self) -> Result { + self.read_endpoint + .as_ref() + .ok_or(RustADBError::IOError(std::io::Error::new( + std::io::ErrorKind::NotConnected, + "no read endpoint setup", + ))) + .cloned() + } + + fn get_write_endpoint(&self) -> Result<&Endpoint> { + self.write_endpoint + .as_ref() + .ok_or(RustADBError::IOError(std::io::Error::new( + std::io::ErrorKind::NotConnected, + "no write endpoint setup", + ))) + } + fn configure_endpoint(handle: &DeviceHandle, endpoint: &Endpoint) -> Result<()> { handle.claim_interface(endpoint.iface)?; Ok(()) } - fn find_readable_endpoint(&self) -> Result { - let handle = self.get_raw_connection()?; - for n in 0..handle.device().device_descriptor()?.num_configurations() { - let config_desc = match handle.device().config_descriptor(n) { - Ok(c) => c, - Err(_) => continue, - }; + fn find_endpoints(&self, handle: &DeviceHandle) -> Result<(Endpoint, Endpoint)> { + let mut read_endpoint: Option = None; + let mut write_endpoint: Option = None; - for interface in config_desc.interfaces() { - for interface_desc in interface.descriptors() { - for endpoint_desc in interface_desc.endpoint_descriptors() { - if endpoint_desc.direction() == Direction::In - && endpoint_desc.transfer_type() == TransferType::Bulk - && interface_desc.class_code() == LIBUSB_CLASS_VENDOR_SPEC - && interface_desc.sub_class_code() == 0x42 - && interface_desc.protocol_code() == 0x01 - { - return Ok(Endpoint { - iface: interface_desc.interface_number(), - address: endpoint_desc.address(), - }); - } - } - } - } - } - - Err(RustADBError::USBNoDescriptorFound) - } - - fn find_writable_endpoint(&self) -> Result { - let handle = self.get_raw_connection()?; for n in 0..handle.device().device_descriptor()?.num_configurations() { let config_desc = match handle.device().config_descriptor(n) { Ok(c) => c, @@ -108,16 +103,31 @@ impl USBTransport { for interface in config_desc.interfaces() { for interface_desc in interface.descriptors() { for endpoint_desc in interface_desc.endpoint_descriptors() { - if endpoint_desc.direction() == Direction::Out - && endpoint_desc.transfer_type() == TransferType::Bulk + if endpoint_desc.transfer_type() == TransferType::Bulk && interface_desc.class_code() == LIBUSB_CLASS_VENDOR_SPEC && interface_desc.sub_class_code() == 0x42 && interface_desc.protocol_code() == 0x01 { - return Ok(Endpoint { + let endpoint = Endpoint { iface: interface_desc.interface_number(), address: endpoint_desc.address(), - }); + }; + match endpoint_desc.direction() { + Direction::In => { + if let Some(write_endpoint) = write_endpoint { + return Ok((endpoint, write_endpoint)); + } else { + read_endpoint = Some(endpoint); + } + } + Direction::Out => { + if let Some(read_endpoint) = read_endpoint { + return Ok((read_endpoint, endpoint)); + } else { + write_endpoint = Some(endpoint); + } + } + } } } } @@ -130,7 +140,18 @@ impl USBTransport { impl ADBTransport for USBTransport { fn connect(&mut self) -> crate::Result<()> { - self.handle = Some(Arc::new(self.device.open()?)); + let device = self.device.open()?; + + let (read_endpoint, write_endpoint) = self.find_endpoints(&device)?; + + Self::configure_endpoint(&device, &read_endpoint)?; + self.read_endpoint = Some(read_endpoint); + + Self::configure_endpoint(&device, &write_endpoint)?; + self.write_endpoint = Some(write_endpoint); + + self.handle = Some(Arc::new(device)); + Ok(()) } @@ -146,11 +167,9 @@ impl ADBMessageTransport for USBTransport { message: ADBTransportMessage, timeout: Duration, ) -> Result<()> { - let endpoint = self.find_writable_endpoint()?; + let endpoint = self.get_write_endpoint()?; let handle = self.get_raw_connection()?; - Self::configure_endpoint(&handle, &endpoint)?; - let message_bytes = message.header().as_bytes()?; let mut total_written = 0; loop { @@ -177,11 +196,9 @@ impl ADBMessageTransport for USBTransport { } fn read_message_with_timeout(&mut self, timeout: Duration) -> Result { - let endpoint = self.find_readable_endpoint()?; + let endpoint = self.get_read_endpoint()?; let handle = self.get_raw_connection()?; - Self::configure_endpoint(&handle, &endpoint)?; - let mut data = [0; 24]; let mut total_read = 0; loop {