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 UsbInterfaceDescriptor; 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 scoped_refptr<UsbConfigDescriptor> interfaces); 124 125 // This constructor variant is for use in testing only. 126 UsbDeviceHandle(); 127 virtual ~UsbDeviceHandle(); 128 129 UsbDevice* device_; 130 131 private: 132 friend void HandleTransferCompletion(PlatformUsbTransferHandle handle); 133 134 class InterfaceClaimer; 135 struct Transfer; 136 137 // Refresh endpoint_map_ after ClaimInterface, ReleaseInterface and 138 // SetInterfaceAlternateSetting. 139 void RefreshEndpointMap(); 140 141 // Look up the claimed interface by endpoint. Return NULL if the interface 142 // of the endpoint is not found. 143 scoped_refptr<InterfaceClaimer> GetClaimedInterfaceForEndpoint( 144 unsigned char endpoint); 145 146 // Submits a transfer and starts tracking it. Retains the buffer and copies 147 // the completion callback until the transfer finishes, whereupon it invokes 148 // the callback then releases the buffer. 149 void SubmitTransfer(PlatformUsbTransferHandle handle, 150 UsbTransferType transfer_type, 151 net::IOBuffer* buffer, 152 const size_t length, 153 scoped_refptr<base::MessageLoopProxy> message_loop_proxy, 154 const UsbTransferCallback& callback); 155 156 // Invokes the callbacks associated with a given transfer, and removes it from 157 // the in-flight transfer set. 158 void TransferComplete(PlatformUsbTransferHandle transfer); 159 160 // Informs the object to drop internal references. 161 void InternalClose(); 162 163 PlatformUsbDeviceHandle handle_; 164 165 scoped_refptr<UsbConfigDescriptor> interfaces_; 166 167 typedef std::map<int, scoped_refptr<InterfaceClaimer> > ClaimedInterfaceMap; 168 ClaimedInterfaceMap claimed_interfaces_; 169 170 typedef std::map<PlatformUsbTransferHandle, Transfer> TransferMap; 171 TransferMap transfers_; 172 173 // A map from endpoints to interfaces 174 typedef std::map<int, int> EndpointMap; 175 EndpointMap endpoint_map_; 176 177 // Retain the UsbContext so that the platform context will not be destroyed 178 // before this handle. 179 scoped_refptr<UsbContext> context_; 180 181 base::ThreadChecker thread_checker_; 182 183 DISALLOW_COPY_AND_ASSIGN(UsbDeviceHandle); 184 }; 185 186 #endif // CHROME_BROWSER_USB_USB_DEVICE_HANDLE_H_ 187