summaryrefslogtreecommitdiffstats
path: root/device/usb/usb_device_handle_impl.h
blob: 0498f263cf1f739edbbe13a79657b4b606128bdd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef DEVICE_USB_USB_DEVICE_HANDLE_IMPL_H_
#define DEVICE_USB_USB_DEVICE_HANDLE_IMPL_H_

#include <map>
#include <vector>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "base/threading/thread_checker.h"
#include "device/usb/usb_device_handle.h"
#include "net/base/io_buffer.h"
#include "third_party/libusb/src/libusb/libusb.h"

namespace base {
class SingleThreadTaskRunner;
}

namespace device {

class UsbContext;
struct UsbConfigDescriptor;
class UsbDeviceImpl;

typedef libusb_device_handle* PlatformUsbDeviceHandle;
typedef libusb_iso_packet_descriptor* PlatformUsbIsoPacketDescriptor;
typedef libusb_transfer* PlatformUsbTransferHandle;

// UsbDeviceHandle class provides basic I/O related functionalities.
class UsbDeviceHandleImpl : public UsbDeviceHandle {
 public:
  virtual scoped_refptr<UsbDevice> GetDevice() const OVERRIDE;
  virtual void Close() OVERRIDE;
  virtual bool ClaimInterface(const int interface_number) OVERRIDE;
  virtual bool ReleaseInterface(const int interface_number) OVERRIDE;
  virtual bool SetInterfaceAlternateSetting(
      const int interface_number,
      const int alternate_setting) OVERRIDE;
  virtual bool ResetDevice() OVERRIDE;
  virtual bool GetManufacturer(base::string16* manufacturer) OVERRIDE;
  virtual bool GetProduct(base::string16* product) OVERRIDE;
  virtual bool GetSerial(base::string16* serial) OVERRIDE;
  virtual void ControlTransfer(const UsbEndpointDirection direction,
                               const TransferRequestType request_type,
                               const TransferRecipient recipient,
                               const uint8 request,
                               const uint16 value,
                               const uint16 index,
                               net::IOBuffer* buffer,
                               const size_t length,
                               const unsigned int timeout,
                               const UsbTransferCallback& callback) OVERRIDE;

  virtual void BulkTransfer(const UsbEndpointDirection direction,
                            const uint8 endpoint,
                            net::IOBuffer* buffer,
                            const size_t length,
                            const unsigned int timeout,
                            const UsbTransferCallback& callback) OVERRIDE;

  virtual void InterruptTransfer(const UsbEndpointDirection direction,
                                 const uint8 endpoint,
                                 net::IOBuffer* buffer,
                                 const size_t length,
                                 const unsigned int timeout,
                                 const UsbTransferCallback& callback) OVERRIDE;

  virtual void IsochronousTransfer(
      const UsbEndpointDirection direction,
      const uint8 endpoint,
      net::IOBuffer* buffer,
      const size_t length,
      const unsigned int packets,
      const unsigned int packet_length,
      const unsigned int timeout,
      const UsbTransferCallback& callback) OVERRIDE;

  PlatformUsbDeviceHandle handle() const { return handle_; }

 protected:
  friend class UsbDeviceImpl;

  // This constructor is called by UsbDevice.
  UsbDeviceHandleImpl(scoped_refptr<UsbContext> context,
                      UsbDeviceImpl* device,
                      PlatformUsbDeviceHandle handle,
                      const UsbConfigDescriptor& config);

  virtual ~UsbDeviceHandleImpl();

 private:
  class InterfaceClaimer;
  struct Transfer;

  // Refresh endpoint_map_ after ClaimInterface, ReleaseInterface and
  // SetInterfaceAlternateSetting.
  void RefreshEndpointMap();

  // Look up the claimed interface by endpoint. Return NULL if the interface
  // of the endpoint is not found.
  scoped_refptr<InterfaceClaimer> GetClaimedInterfaceForEndpoint(
      unsigned char endpoint);

  // If the device's task runner is on the current thread then the transfer will
  // be submitted directly, otherwise a task to do so it posted. The callback
  // will be called on the current message loop of the thread where this
  // function was called.
  void PostOrSubmitTransfer(PlatformUsbTransferHandle handle,
                            UsbTransferType transfer_type,
                            net::IOBuffer* buffer,
                            size_t length,
                            const UsbTransferCallback& callback);

  // Submits a transfer and starts tracking it. Retains the buffer and copies
  // the completion callback until the transfer finishes, whereupon it invokes
  // the callback then releases the buffer.
  void SubmitTransfer(PlatformUsbTransferHandle handle,
                      UsbTransferType transfer_type,
                      net::IOBuffer* buffer,
                      const size_t length,
                      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
                      const UsbTransferCallback& callback);

  static void LIBUSB_CALL
      PlatformTransferCallback(PlatformUsbTransferHandle handle);

  // Invokes the callbacks associated with a given transfer, and removes it from
  // the in-flight transfer set.
  void CompleteTransfer(PlatformUsbTransferHandle transfer);

  bool GetSupportedLanguages();
  bool GetStringDescriptor(uint8 string_id, base::string16* string);

  // Informs the object to drop internal references.
  void InternalClose();

  UsbDeviceImpl* device_;

  PlatformUsbDeviceHandle handle_;

  const UsbConfigDescriptor& config_;

  std::vector<uint16> languages_;
  std::map<uint8, base::string16> strings_;

  typedef std::map<int, scoped_refptr<InterfaceClaimer> > ClaimedInterfaceMap;
  ClaimedInterfaceMap claimed_interfaces_;

  typedef std::map<PlatformUsbTransferHandle, Transfer> TransferMap;
  TransferMap transfers_;

  // A map from endpoints to interfaces
  typedef std::map<int, int> EndpointMap;
  EndpointMap endpoint_map_;

  // Retain the UsbContext so that the platform context will not be destroyed
  // before this handle.
  scoped_refptr<UsbContext> context_;

  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;

  base::ThreadChecker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(UsbDeviceHandleImpl);
};

}  // namespace device

#endif  // DEVICE_USB_USB_DEVICE_HANDLE_IMPL_H_