Loading fastboot/usb.h +9 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,14 @@ struct usb_ifc_info { char device_path[256]; }; class UsbTransport : public Transport { // Resets the underlying transport. Returns 0 on success. // This effectively simulates unplugging and replugging public: virtual int Reset() = 0; }; typedef int (*ifc_match_func)(usb_ifc_info *ifc); Transport* usb_open(ifc_match_func callback); // 0 is non blocking UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms = 0); fastboot/usb_linux.cpp +21 −9 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ using namespace std::chrono_literals; #define MAX_RETRIES 5 #define MAX_RETRIES 2 /* Timeout in seconds for usb_wait_for_disconnect. * It doesn't usually take long for a device to disconnect (almost always Loading Loading @@ -91,18 +91,21 @@ struct usb_handle unsigned char ep_out; }; class LinuxUsbTransport : public Transport { class LinuxUsbTransport : public UsbTransport { public: explicit LinuxUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} explicit LinuxUsbTransport(std::unique_ptr<usb_handle> handle, uint32_t ms_timeout = 0) : handle_(std::move(handle)), ms_timeout_(ms_timeout) {} ~LinuxUsbTransport() override = default; ssize_t Read(void* data, size_t len) override; ssize_t Write(const void* data, size_t len) override; int Close() override; int Reset() override; int WaitForDisconnect() override; private: std::unique_ptr<usb_handle> handle_; const uint32_t ms_timeout_; DISALLOW_COPY_AND_ASSIGN(LinuxUsbTransport); }; Loading Loading @@ -402,7 +405,7 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) bulk.ep = handle_->ep_out; bulk.len = xfer; bulk.data = data; bulk.timeout = 0; bulk.timeout = ms_timeout_; n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk); if(n != xfer) { Loading Loading @@ -436,7 +439,7 @@ ssize_t LinuxUsbTransport::Read(void* _data, size_t len) bulk.ep = handle_->ep_in; bulk.len = xfer; bulk.data = data; bulk.timeout = 0; bulk.timeout = ms_timeout_; retry = 0; do { Loading @@ -447,7 +450,7 @@ ssize_t LinuxUsbTransport::Read(void* _data, size_t len) if (n < 0) { DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno)); if (++retry > MAX_RETRIES) return -1; std::this_thread::sleep_for(1s); std::this_thread::sleep_for(100ms); } } while (n < 0); Loading Loading @@ -477,10 +480,19 @@ int LinuxUsbTransport::Close() return 0; } Transport* usb_open(ifc_match_func callback) { int LinuxUsbTransport::Reset() { int ret = 0; // We reset the USB connection if ((ret = ioctl(handle_->desc, USBDEVFS_RESET, 0))) { return ret; } return 0; } UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms) { std::unique_ptr<usb_handle> handle = find_usb_device("/sys/bus/usb/devices", callback); return handle ? new LinuxUsbTransport(std::move(handle)) : nullptr; return handle ? new LinuxUsbTransport(std::move(handle), timeout_ms) : nullptr; } /* Wait for the system to notice the device is gone, so that a subsequent Loading fastboot/usb_osx.cpp +39 −7 Original line number Diff line number Diff line Loading @@ -65,17 +65,21 @@ struct usb_handle unsigned int zero_mask; }; class OsxUsbTransport : public Transport { class OsxUsbTransport : public UsbTransport { public: OsxUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} // A timeout of 0 is blocking OsxUsbTransport(std::unique_ptr<usb_handle> handle, uint32_t ms_timeout = 0) : handle_(std::move(handle)), ms_timeout_(ms_timeout) {} ~OsxUsbTransport() override = default; ssize_t Read(void* data, size_t len) override; ssize_t Write(const void* data, size_t len) override; int Close() override; int Reset() override; private: std::unique_ptr<usb_handle> handle_; const uint32_t ms_timeout_; DISALLOW_COPY_AND_ASSIGN(OsxUsbTransport); }; Loading Loading @@ -456,7 +460,7 @@ static int init_usb(ifc_match_func callback, std::unique_ptr<usb_handle>* handle * Definitions of this file's public functions. */ Transport* usb_open(ifc_match_func callback) { UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms) { std::unique_ptr<usb_handle> handle; if (init_usb(callback, &handle) < 0) { Loading @@ -464,7 +468,7 @@ Transport* usb_open(ifc_match_func callback) { return nullptr; } return new OsxUsbTransport(std::move(handle)); return new OsxUsbTransport(std::move(handle), timeout_ms); } int OsxUsbTransport::Close() { Loading @@ -472,6 +476,19 @@ int OsxUsbTransport::Close() { return 0; } /* TODO: this SHOULD be easy to do with ResetDevice() from IOUSBDeviceInterface. However to perform operations that manipulate the state of the device, you must claim ownership of the device with USBDeviceOpenSeize(). However, this operation always fails with kIOReturnExclusiveAccess. It seems that the kext com.apple.driver.usb.AppleUSBHostCompositeDevice always loads and claims ownership of the device and refuses to give it up. */ int OsxUsbTransport::Reset() { ERR("USB reset is currently unsupported on osx\n"); return -1; } ssize_t OsxUsbTransport::Read(void* data, size_t len) { IOReturn result; UInt32 numBytes = len; Loading @@ -494,7 +511,14 @@ ssize_t OsxUsbTransport::Read(void* data, size_t len) { return -1; } result = (*handle_->interface)->ReadPipe(handle_->interface, handle_->bulkIn, data, &numBytes); if (!ms_timeout_) { result = (*handle_->interface) ->ReadPipe(handle_->interface, handle_->bulkIn, data, &numBytes); } else { result = (*handle_->interface) ->ReadPipeTO(handle_->interface, handle_->bulkIn, data, &numBytes, ms_timeout_, ms_timeout_); } if (result == 0) { return (int) numBytes; Loading Loading @@ -541,8 +565,16 @@ ssize_t OsxUsbTransport::Write(const void* data, size_t len) { int lenToSend = lenRemaining > maxLenToSend ? maxLenToSend : lenRemaining; result = (*handle_->interface)->WritePipe( handle_->interface, handle_->bulkOut, (void *)data, lenToSend); if (!ms_timeout_) { // blocking result = (*handle_->interface) ->WritePipe(handle_->interface, handle_->bulkOut, (void*)data, lenToSend); } else { result = (*handle_->interface) ->WritePipeTO(handle_->interface, handle_->bulkOut, (void*)data, lenToSend, ms_timeout_, ms_timeout_); } if (result != 0) break; lenRemaining -= lenToSend; Loading fastboot/usb_windows.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ struct usb_handle { std::string interface_name; }; class WindowsUsbTransport : public Transport { class WindowsUsbTransport : public UsbTransport { public: WindowsUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} ~WindowsUsbTransport() override = default; Loading @@ -74,6 +74,7 @@ class WindowsUsbTransport : public Transport { ssize_t Read(void* data, size_t len) override; ssize_t Write(const void* data, size_t len) override; int Close() override; int Reset() override; private: std::unique_ptr<usb_handle> handle_; Loading Loading @@ -261,6 +262,12 @@ int WindowsUsbTransport::Close() { return 0; } int WindowsUsbTransport::Reset() { DBG("usb_reset currently unsupported\n\n"); // TODO, this is a bit complicated since it is using ADB return -1; } int recognized_device(usb_handle* handle, ifc_match_func callback) { struct usb_ifc_info info; USB_DEVICE_DESCRIPTOR device_desc; Loading Loading @@ -366,8 +373,7 @@ static std::unique_ptr<usb_handle> find_usb_device(ifc_match_func callback) { return handle; } Transport* usb_open(ifc_match_func callback) { UsbTransport* usb_open(ifc_match_func callback, uint32_t) { std::unique_ptr<usb_handle> handle = find_usb_device(callback); return handle ? new WindowsUsbTransport(std::move(handle)) : nullptr; } Loading
fastboot/usb.h +9 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,14 @@ struct usb_ifc_info { char device_path[256]; }; class UsbTransport : public Transport { // Resets the underlying transport. Returns 0 on success. // This effectively simulates unplugging and replugging public: virtual int Reset() = 0; }; typedef int (*ifc_match_func)(usb_ifc_info *ifc); Transport* usb_open(ifc_match_func callback); // 0 is non blocking UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms = 0);
fastboot/usb_linux.cpp +21 −9 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ using namespace std::chrono_literals; #define MAX_RETRIES 5 #define MAX_RETRIES 2 /* Timeout in seconds for usb_wait_for_disconnect. * It doesn't usually take long for a device to disconnect (almost always Loading Loading @@ -91,18 +91,21 @@ struct usb_handle unsigned char ep_out; }; class LinuxUsbTransport : public Transport { class LinuxUsbTransport : public UsbTransport { public: explicit LinuxUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} explicit LinuxUsbTransport(std::unique_ptr<usb_handle> handle, uint32_t ms_timeout = 0) : handle_(std::move(handle)), ms_timeout_(ms_timeout) {} ~LinuxUsbTransport() override = default; ssize_t Read(void* data, size_t len) override; ssize_t Write(const void* data, size_t len) override; int Close() override; int Reset() override; int WaitForDisconnect() override; private: std::unique_ptr<usb_handle> handle_; const uint32_t ms_timeout_; DISALLOW_COPY_AND_ASSIGN(LinuxUsbTransport); }; Loading Loading @@ -402,7 +405,7 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) bulk.ep = handle_->ep_out; bulk.len = xfer; bulk.data = data; bulk.timeout = 0; bulk.timeout = ms_timeout_; n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk); if(n != xfer) { Loading Loading @@ -436,7 +439,7 @@ ssize_t LinuxUsbTransport::Read(void* _data, size_t len) bulk.ep = handle_->ep_in; bulk.len = xfer; bulk.data = data; bulk.timeout = 0; bulk.timeout = ms_timeout_; retry = 0; do { Loading @@ -447,7 +450,7 @@ ssize_t LinuxUsbTransport::Read(void* _data, size_t len) if (n < 0) { DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno)); if (++retry > MAX_RETRIES) return -1; std::this_thread::sleep_for(1s); std::this_thread::sleep_for(100ms); } } while (n < 0); Loading Loading @@ -477,10 +480,19 @@ int LinuxUsbTransport::Close() return 0; } Transport* usb_open(ifc_match_func callback) { int LinuxUsbTransport::Reset() { int ret = 0; // We reset the USB connection if ((ret = ioctl(handle_->desc, USBDEVFS_RESET, 0))) { return ret; } return 0; } UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms) { std::unique_ptr<usb_handle> handle = find_usb_device("/sys/bus/usb/devices", callback); return handle ? new LinuxUsbTransport(std::move(handle)) : nullptr; return handle ? new LinuxUsbTransport(std::move(handle), timeout_ms) : nullptr; } /* Wait for the system to notice the device is gone, so that a subsequent Loading
fastboot/usb_osx.cpp +39 −7 Original line number Diff line number Diff line Loading @@ -65,17 +65,21 @@ struct usb_handle unsigned int zero_mask; }; class OsxUsbTransport : public Transport { class OsxUsbTransport : public UsbTransport { public: OsxUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} // A timeout of 0 is blocking OsxUsbTransport(std::unique_ptr<usb_handle> handle, uint32_t ms_timeout = 0) : handle_(std::move(handle)), ms_timeout_(ms_timeout) {} ~OsxUsbTransport() override = default; ssize_t Read(void* data, size_t len) override; ssize_t Write(const void* data, size_t len) override; int Close() override; int Reset() override; private: std::unique_ptr<usb_handle> handle_; const uint32_t ms_timeout_; DISALLOW_COPY_AND_ASSIGN(OsxUsbTransport); }; Loading Loading @@ -456,7 +460,7 @@ static int init_usb(ifc_match_func callback, std::unique_ptr<usb_handle>* handle * Definitions of this file's public functions. */ Transport* usb_open(ifc_match_func callback) { UsbTransport* usb_open(ifc_match_func callback, uint32_t timeout_ms) { std::unique_ptr<usb_handle> handle; if (init_usb(callback, &handle) < 0) { Loading @@ -464,7 +468,7 @@ Transport* usb_open(ifc_match_func callback) { return nullptr; } return new OsxUsbTransport(std::move(handle)); return new OsxUsbTransport(std::move(handle), timeout_ms); } int OsxUsbTransport::Close() { Loading @@ -472,6 +476,19 @@ int OsxUsbTransport::Close() { return 0; } /* TODO: this SHOULD be easy to do with ResetDevice() from IOUSBDeviceInterface. However to perform operations that manipulate the state of the device, you must claim ownership of the device with USBDeviceOpenSeize(). However, this operation always fails with kIOReturnExclusiveAccess. It seems that the kext com.apple.driver.usb.AppleUSBHostCompositeDevice always loads and claims ownership of the device and refuses to give it up. */ int OsxUsbTransport::Reset() { ERR("USB reset is currently unsupported on osx\n"); return -1; } ssize_t OsxUsbTransport::Read(void* data, size_t len) { IOReturn result; UInt32 numBytes = len; Loading @@ -494,7 +511,14 @@ ssize_t OsxUsbTransport::Read(void* data, size_t len) { return -1; } result = (*handle_->interface)->ReadPipe(handle_->interface, handle_->bulkIn, data, &numBytes); if (!ms_timeout_) { result = (*handle_->interface) ->ReadPipe(handle_->interface, handle_->bulkIn, data, &numBytes); } else { result = (*handle_->interface) ->ReadPipeTO(handle_->interface, handle_->bulkIn, data, &numBytes, ms_timeout_, ms_timeout_); } if (result == 0) { return (int) numBytes; Loading Loading @@ -541,8 +565,16 @@ ssize_t OsxUsbTransport::Write(const void* data, size_t len) { int lenToSend = lenRemaining > maxLenToSend ? maxLenToSend : lenRemaining; result = (*handle_->interface)->WritePipe( handle_->interface, handle_->bulkOut, (void *)data, lenToSend); if (!ms_timeout_) { // blocking result = (*handle_->interface) ->WritePipe(handle_->interface, handle_->bulkOut, (void*)data, lenToSend); } else { result = (*handle_->interface) ->WritePipeTO(handle_->interface, handle_->bulkOut, (void*)data, lenToSend, ms_timeout_, ms_timeout_); } if (result != 0) break; lenRemaining -= lenToSend; Loading
fastboot/usb_windows.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ struct usb_handle { std::string interface_name; }; class WindowsUsbTransport : public Transport { class WindowsUsbTransport : public UsbTransport { public: WindowsUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} ~WindowsUsbTransport() override = default; Loading @@ -74,6 +74,7 @@ class WindowsUsbTransport : public Transport { ssize_t Read(void* data, size_t len) override; ssize_t Write(const void* data, size_t len) override; int Close() override; int Reset() override; private: std::unique_ptr<usb_handle> handle_; Loading Loading @@ -261,6 +262,12 @@ int WindowsUsbTransport::Close() { return 0; } int WindowsUsbTransport::Reset() { DBG("usb_reset currently unsupported\n\n"); // TODO, this is a bit complicated since it is using ADB return -1; } int recognized_device(usb_handle* handle, ifc_match_func callback) { struct usb_ifc_info info; USB_DEVICE_DESCRIPTOR device_desc; Loading Loading @@ -366,8 +373,7 @@ static std::unique_ptr<usb_handle> find_usb_device(ifc_match_func callback) { return handle; } Transport* usb_open(ifc_match_func callback) { UsbTransport* usb_open(ifc_match_func callback, uint32_t) { std::unique_ptr<usb_handle> handle = find_usb_device(callback); return handle ? new WindowsUsbTransport(std::move(handle)) : nullptr; }