diff options
author | David Pursell <dpursell@google.com> | 2015-10-30 11:22:01 -0700 |
---|---|---|
committer | David Pursell <dpursell@google.com> | 2015-11-13 11:08:17 -0800 |
commit | 6f233a7799a681e65c539e9c8287db0814c8948f (patch) | |
tree | 3fa9f8b84c7d48cb3907d3c3964a3cb3e130e204 /fastboot/usb_linux.cpp | |
parent | ab75edb4ad01b518cb5c96a5a3d4ad344bc4ce26 (diff) |
fastboot: create Transport object.
This CL creates a Transport object to provide a generic interface for
various transports. Specifically this is designed to be able to add UDP
support to fastboot in an upcoming CL without changing the main program
logic.
Also includes some minor code style fixes and replaces malloc/free
in the USB implementation files with smart pointers and std::string.
Bug: http://b/22029765
Change-Id: I68641af0da7d13db4647f5e20a18d04d67f0b327
Diffstat (limited to 'fastboot/usb_linux.cpp')
-rw-r--r-- | fastboot/usb_linux.cpp | 91 |
1 files changed, 48 insertions, 43 deletions
diff --git a/fastboot/usb_linux.cpp b/fastboot/usb_linux.cpp index 7b879073d..02ffcd978 100644 --- a/fastboot/usb_linux.cpp +++ b/fastboot/usb_linux.cpp @@ -43,6 +43,8 @@ #include <linux/version.h> #include <linux/usb/ch9.h> +#include <memory> + #include "fastboot.h" #include "usb.h" @@ -85,6 +87,22 @@ struct usb_handle unsigned char ep_out; }; +class LinuxUsbTransport : public Transport { + public: + LinuxUsbTransport(std::unique_ptr<usb_handle> handle) : handle_(std::move(handle)) {} + ~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 WaitForDisconnect() override; + + private: + std::unique_ptr<usb_handle> handle_; + + DISALLOW_COPY_AND_ASSIGN(LinuxUsbTransport); +}; + /* True if name isn't a valid name for a USB device in /sys/bus/usb/devices. * Device names are made up of numbers, dots, and dashes, e.g., '7-1.5'. * We reject interfaces (e.g., '7-1.5:1.0') and host controllers (e.g. 'usb1'). @@ -308,9 +326,9 @@ static int convert_to_devfs_name(const char* sysfs_name, return 0; } -static usb_handle *find_usb_device(const char *base, ifc_match_func callback) +static std::unique_ptr<usb_handle> find_usb_device(const char* base, ifc_match_func callback) { - usb_handle *usb = 0; + std::unique_ptr<usb_handle> usb; char devname[64]; char desc[1024]; int n, in, out, ifc; @@ -321,39 +339,37 @@ static usb_handle *find_usb_device(const char *base, ifc_match_func callback) int writable; busdir = opendir(base); - if(busdir == 0) return 0; + if (busdir == 0) return 0; - while((de = readdir(busdir)) && (usb == 0)) { - if(badname(de->d_name)) continue; + while ((de = readdir(busdir)) && (usb == nullptr)) { + if (badname(de->d_name)) continue; - if(!convert_to_devfs_name(de->d_name, devname, sizeof(devname))) { + if (!convert_to_devfs_name(de->d_name, devname, sizeof(devname))) { // DBG("[ scanning %s ]\n", devname); writable = 1; - if((fd = open(devname, O_RDWR)) < 0) { + if ((fd = open(devname, O_RDWR)) < 0) { // Check if we have read-only access, so we can give a helpful // diagnostic like "adb devices" does. writable = 0; - if((fd = open(devname, O_RDONLY)) < 0) { + if ((fd = open(devname, O_RDONLY)) < 0) { continue; } } n = read(fd, desc, sizeof(desc)); - if(filter_usb_device(de->d_name, desc, n, writable, callback, - &in, &out, &ifc) == 0) { - usb = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle))); + if (filter_usb_device(de->d_name, desc, n, writable, callback, &in, &out, &ifc) == 0) { + usb.reset(new usb_handle()); strcpy(usb->fname, devname); usb->ep_in = in; usb->ep_out = out; usb->desc = fd; n = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &ifc); - if(n != 0) { + if (n != 0) { close(fd); - free(usb); - usb = 0; + usb.reset(); continue; } } else { @@ -366,14 +382,14 @@ static usb_handle *find_usb_device(const char *base, ifc_match_func callback) return usb; } -int usb_write(usb_handle *h, const void *_data, int len) +ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) { unsigned char *data = (unsigned char*) _data; unsigned count = 0; struct usbdevfs_bulktransfer bulk; int n; - if(h->ep_out == 0 || h->desc == -1) { + if (handle_->ep_out == 0 || handle_->desc == -1) { return -1; } @@ -381,12 +397,12 @@ int usb_write(usb_handle *h, const void *_data, int len) int xfer; xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; - bulk.ep = h->ep_out; + bulk.ep = handle_->ep_out; bulk.len = xfer; bulk.data = data; bulk.timeout = 0; - n = ioctl(h->desc, USBDEVFS_BULK, &bulk); + n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk); if(n != xfer) { DBG("ERROR: n = %d, errno = %d (%s)\n", n, errno, strerror(errno)); @@ -401,30 +417,30 @@ int usb_write(usb_handle *h, const void *_data, int len) return count; } -int usb_read(usb_handle *h, void *_data, int len) +ssize_t LinuxUsbTransport::Read(void* _data, size_t len) { unsigned char *data = (unsigned char*) _data; unsigned count = 0; struct usbdevfs_bulktransfer bulk; int n, retry; - if(h->ep_in == 0 || h->desc == -1) { + if (handle_->ep_in == 0 || handle_->desc == -1) { return -1; } while(len > 0) { int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; - bulk.ep = h->ep_in; + bulk.ep = handle_->ep_in; bulk.len = xfer; bulk.data = data; bulk.timeout = 0; retry = 0; do{ - DBG("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname); - n = ioctl(h->desc, USBDEVFS_BULK, &bulk); - DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, h->fname, retry); + DBG("[ usb read %d fd = %d], fname=%s\n", xfer, handle_->desc, handle_->fname); + n = ioctl(handle_->desc, USBDEVFS_BULK, &bulk); + DBG("[ usb read %d ] = %d, fname=%s, Retry %d \n", xfer, n, handle_->fname, retry); if( n < 0 ) { DBG1("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno)); @@ -446,24 +462,12 @@ int usb_read(usb_handle *h, void *_data, int len) return count; } -void usb_kick(usb_handle *h) -{ - int fd; - - fd = h->desc; - h->desc = -1; - if(fd >= 0) { - close(fd); - DBG("[ usb closed %d ]\n", fd); - } -} - -int usb_close(usb_handle *h) +int LinuxUsbTransport::Close() { int fd; - fd = h->desc; - h->desc = -1; + fd = handle_->desc; + handle_->desc = -1; if(fd >= 0) { close(fd); DBG("[ usb closed %d ]\n", fd); @@ -472,20 +476,21 @@ int usb_close(usb_handle *h) return 0; } -usb_handle *usb_open(ifc_match_func callback) +Transport* usb_open(ifc_match_func callback) { - return find_usb_device("/sys/bus/usb/devices", callback); + std::unique_ptr<usb_handle> handle = find_usb_device("/sys/bus/usb/devices", callback); + return handle ? new LinuxUsbTransport(std::move(handle)) : nullptr; } /* Wait for the system to notice the device is gone, so that a subsequent * fastboot command won't try to access the device before it's rebooted. * Returns 0 for success, -1 for timeout. */ -int usb_wait_for_disconnect(usb_handle *usb) +int LinuxUsbTransport::WaitForDisconnect() { double deadline = now() + WAIT_FOR_DISCONNECT_TIMEOUT; while (now() < deadline) { - if (access(usb->fname, F_OK)) + if (access(handle_->fname, F_OK)) return 0; usleep(50000); } |