1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_ 6 #define CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/memory/ref_counted.h" 12 #include "base/strings/string16.h" 13 #include "base/synchronization/lock.h" 14 #include "base/threading/thread_checker.h" 15 #include "chrome/browser/usb/usb_interface.h" 16 #include "content/public/browser/browser_thread.h" 17 #include "net/base/completion_callback.h" 18 #include "net/base/io_buffer.h" 19 20 struct libusb_device_handle; 21 struct libusb_iso_packet_descriptor; 22 struct libusb_transfer; 23 24 typedef libusb_device_handle* PlatformUsbDeviceHandle; 25 typedef libusb_iso_packet_descriptor* PlatformUsbIsoPacketDescriptor; 26 typedef libusb_transfer* PlatformUsbTransferHandle; 27 28 class UsbContext; 29 class UsbConfigDescriptor; 30 class UsbDevice; 31 class UsbInterface; 32 33 namespace base { 34 class MessageLoopProxy; 35 } // namespace base 36 37 namespace net { 38 class IOBuffer; 39 } // namespace net 40 41 enum UsbTransferStatus { 42 USB_TRANSFER_COMPLETED = 0, 43 USB_TRANSFER_ERROR, 44 USB_TRANSFER_TIMEOUT, 45 USB_TRANSFER_CANCELLED, 46 USB_TRANSFER_STALLED, 47 USB_TRANSFER_DISCONNECT, 48 USB_TRANSFER_OVERFLOW, 49 USB_TRANSFER_LENGTH_SHORT, 50 }; 51 52 typedef base::Callback<void(UsbTransferStatus, scoped_refptr<net::IOBuffer>, 53 size_t)> UsbTransferCallback; 54 55 // UsbDeviceHandle class provides basic I/O related functionalities. 56 class UsbDeviceHandle : public base::RefCountedThreadSafe<UsbDeviceHandle> { 57 public: 58 enum TransferRequestType { STANDARD, CLASS, VENDOR, RESERVED }; 59 enum TransferRecipient { DEVICE, INTERFACE, ENDPOINT, OTHER }; 60 61 scoped_refptr<UsbDevice> device() const; 62 PlatformUsbDeviceHandle handle() const { return handle_; } 63 64 // Notifies UsbDevice to drop the reference of this object; cancels all the 65 // flying transfers. 66 // It is possible that the object has no other reference after this call. So 67 // if it is called using a raw pointer, it could be invalidated. 68 // The platform device handle will be closed when UsbDeviceHandle destructs. 69 virtual void Close(); 70 71 // Device manipulation operations. These methods are blocking and must be 72 // called on FILE thread. 73 virtual bool ClaimInterface(const int interface_number); 74 virtual bool ReleaseInterface(const int interface_number); 75 virtual bool SetInterfaceAlternateSetting( 76 const int interface_number, 77 const int alternate_setting); 78 virtual bool ResetDevice(); 79 virtual bool GetSerial(base::string16* serial); 80 81 // Async IO. Can be called on any thread. 82 virtual void ControlTransfer(const UsbEndpointDirection direction, 83 const TransferRequestType request_type, 84 const TransferRecipient recipient, 85 const uint8 request, 86 const uint16 value, 87 const uint16 index, 88 net::IOBuffer* buffer, 89 const size_t length, 90 const unsigned int timeout, 91 const UsbTransferCallback& callback); 92 93 virtual void BulkTransfer(const UsbEndpointDirection direction, 94 const uint8 endpoint, 95 net::IOBuffer* buffer, 96 const size_t length, 97 const unsigned int timeout, 98 const UsbTransferCallback& callback); 99 100 virtual void InterruptTransfer(const UsbEndpointDirection direction, 101 const uint8 endpoint, 102 net::IOBuffer* buffer, 103 const size_t length, 104 const unsigned int timeout, 105 const UsbTransferCallback& callback); 106 107 virtual void IsochronousTransfer(const UsbEndpointDirection direction, 108 const uint8 endpoint, 109 net::IOBuffer* buffer, 110 const size_t length, 111 const unsigned int packets, 112 const unsigned int packet_length, 113 const unsigned int timeout, 114 const UsbTransferCallback& callback); 115 116 protected: 117 friend class base::RefCountedThreadSafe<UsbDeviceHandle>; 118 friend class UsbDevice; 119 120 // This constructor is called by UsbDevice. 121 UsbDeviceHandle(scoped_refptr<UsbContext> context, 122 UsbDevice* device, PlatformUsbDeviceHandle handle); 123 124 // This constructor variant is for use in testing only. 125 UsbDeviceHandle(); 126 virtual ~UsbDeviceHandle(); 127 128 UsbDevice* device_; 129 130 private: 131 friend void HandleTransferCompletion(PlatformUsbTransferHandle handle); 132 133 class InterfaceClaimer; 134 struct Transfer; 135 136 // Refresh endpoint_map_ after ClaimInterface, ReleaseInterface and 137 // SetInterfaceAlternateSetting. 138 void RefreshEndpointMap(); 139 140 // Look up the claimed interface by endpoint. Return NULL if the interface 141 // of the endpoint is not found. 142 scoped_refptr<InterfaceClaimer> GetClaimedInterfaceForEndpoint( 143 unsigned char endpoint); 144 145 // Submits a transfer and starts tracking it. Retains the buffer and copies 146 // the completion callback until the transfer finishes, whereupon it invokes 147 // the callback then releases the buffer. 148 void SubmitTransfer(PlatformUsbTransferHandle handle, 149 UsbTransferType transfer_type, 150 net::IOBuffer* buffer, 151 const size_t length, 152 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 153 const UsbTransferCallback& callback); 154 155 // Invokes the callbacks associated with a given transfer, and removes it from 156 // the in-flight transfer set. 157 void TransferComplete(PlatformUsbTransferHandle transfer); 158 159 // Informs the object to drop internal references. 160 void InternalClose(); 161 162 PlatformUsbDeviceHandle handle_; 163 164 scoped_refptr<UsbConfigDescriptor> interfaces_; 165 166 typedef std::map<int, scoped_refptr<InterfaceClaimer> > ClaimedInterfaceMap; 167 ClaimedInterfaceMap claimed_interfaces_; 168 169 typedef std::map<PlatformUsbTransferHandle, Transfer> TransferMap; 170 TransferMap transfers_; 171 172 // A map from endpoints to interfaces 173 typedef std::map<int, int> EndpointMap; 174 EndpointMap endpoint_map_; 175 176 // Retain the UsbContext so that the platform context will not be destroyed 177 // before this handle. 178 scoped_refptr<UsbContext> context_; 179 180 base::ThreadChecker thread_checker_; 181 182 DISALLOW_COPY_AND_ASSIGN(UsbDeviceHandle); 183 }; 184 185 #endif // CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_ 186