OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/usb/usb_device.h" | 5 #include "chrome/browser/usb/usb_device.h" |
6 | 6 |
| 7 #include <vector> |
| 8 |
7 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
8 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
| 11 #include "chrome/browser/usb/usb_interface.h" |
9 #include "chrome/browser/usb/usb_service.h" | 12 #include "chrome/browser/usb/usb_service.h" |
10 #include "third_party/libusb/src/libusb/libusb.h" | 13 #include "third_party/libusb/src/libusb/libusb.h" |
11 | 14 |
12 namespace { | 15 namespace { |
13 | 16 |
14 static uint8 ConvertTransferDirection( | 17 static uint8 ConvertTransferDirection( |
15 const UsbDevice::TransferDirection direction) { | 18 const UsbEndpointDirection direction) { |
16 switch (direction) { | 19 switch (direction) { |
17 case UsbDevice::INBOUND: | 20 case USB_DIRECTION_INBOUND: |
18 return LIBUSB_ENDPOINT_IN; | 21 return LIBUSB_ENDPOINT_IN; |
19 case UsbDevice::OUTBOUND: | 22 case USB_DIRECTION_OUTBOUND: |
20 return LIBUSB_ENDPOINT_OUT; | 23 return LIBUSB_ENDPOINT_OUT; |
| 24 default: |
| 25 NOTREACHED(); |
| 26 return LIBUSB_ENDPOINT_IN; |
21 } | 27 } |
22 NOTREACHED(); | |
23 return LIBUSB_ENDPOINT_OUT; | |
24 } | 28 } |
25 | 29 |
26 static uint8 CreateRequestType(const UsbDevice::TransferDirection direction, | 30 static uint8 CreateRequestType(const UsbEndpointDirection direction, |
27 const UsbDevice::TransferRequestType request_type, | 31 const UsbDevice::TransferRequestType request_type, |
28 const UsbDevice::TransferRecipient recipient) { | 32 const UsbDevice::TransferRecipient recipient) { |
29 uint8 result = ConvertTransferDirection(direction); | 33 uint8 result = ConvertTransferDirection(direction); |
30 | 34 |
31 switch (request_type) { | 35 switch (request_type) { |
32 case UsbDevice::STANDARD: | 36 case UsbDevice::STANDARD: |
33 result |= LIBUSB_REQUEST_TYPE_STANDARD; | 37 result |= LIBUSB_REQUEST_TYPE_STANDARD; |
34 break; | 38 break; |
35 case UsbDevice::CLASS: | 39 case UsbDevice::CLASS: |
36 result |= LIBUSB_REQUEST_TYPE_CLASS; | 40 result |= LIBUSB_REQUEST_TYPE_CLASS; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 case LIBUSB_TRANSFER_TIMED_OUT: | 75 case LIBUSB_TRANSFER_TIMED_OUT: |
72 return USB_TRANSFER_TIMEOUT; | 76 return USB_TRANSFER_TIMEOUT; |
73 case LIBUSB_TRANSFER_STALL: | 77 case LIBUSB_TRANSFER_STALL: |
74 return USB_TRANSFER_STALLED; | 78 return USB_TRANSFER_STALLED; |
75 case LIBUSB_TRANSFER_NO_DEVICE: | 79 case LIBUSB_TRANSFER_NO_DEVICE: |
76 return USB_TRANSFER_DISCONNECT; | 80 return USB_TRANSFER_DISCONNECT; |
77 case LIBUSB_TRANSFER_OVERFLOW: | 81 case LIBUSB_TRANSFER_OVERFLOW: |
78 return USB_TRANSFER_OVERFLOW; | 82 return USB_TRANSFER_OVERFLOW; |
79 case LIBUSB_TRANSFER_CANCELLED: | 83 case LIBUSB_TRANSFER_CANCELLED: |
80 return USB_TRANSFER_CANCELLED; | 84 return USB_TRANSFER_CANCELLED; |
| 85 default: |
| 86 NOTREACHED(); |
| 87 return USB_TRANSFER_ERROR; |
81 } | 88 } |
82 NOTREACHED(); | |
83 return USB_TRANSFER_ERROR; | |
84 } | 89 } |
85 | 90 |
86 static void LIBUSB_CALL HandleTransferCompletion( | 91 static void LIBUSB_CALL HandleTransferCompletion( |
87 struct libusb_transfer* transfer) { | 92 struct libusb_transfer* transfer) { |
88 UsbDevice* const device = reinterpret_cast<UsbDevice*>(transfer->user_data); | 93 UsbDevice* const device = reinterpret_cast<UsbDevice*>(transfer->user_data); |
89 device->TransferComplete(transfer); | 94 device->TransferComplete(transfer); |
90 } | 95 } |
91 | 96 |
92 } // namespace | 97 } // namespace |
93 | 98 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 NOTREACHED() << "Invalid usb transfer type"; | 189 NOTREACHED() << "Invalid usb transfer type"; |
185 } | 190 } |
186 | 191 |
187 transfer->callback.Run(ConvertTransferStatus(handle->status), buffer, | 192 transfer->callback.Run(ConvertTransferStatus(handle->status), buffer, |
188 actual_length); | 193 actual_length); |
189 | 194 |
190 transfers_.erase(handle); | 195 transfers_.erase(handle); |
191 libusb_free_transfer(handle); | 196 libusb_free_transfer(handle); |
192 } | 197 } |
193 | 198 |
| 199 void UsbDevice::ListInterfaces(UsbConfigDescriptor* config, |
| 200 const UsbInterfaceCallback& callback) { |
| 201 CheckDevice(); |
| 202 |
| 203 PlatformUsbDevice device = libusb_get_device(handle_); |
| 204 |
| 205 PlatformUsbConfigDescriptor platform_config; |
| 206 const int list_result = libusb_get_active_config_descriptor(device, |
| 207 &platform_config); |
| 208 if (list_result == 0) { |
| 209 config->Reset(platform_config); |
| 210 } |
| 211 callback.Run(list_result == 0); |
| 212 } |
| 213 |
194 void UsbDevice::ClaimInterface(const int interface_number, | 214 void UsbDevice::ClaimInterface(const int interface_number, |
195 const UsbInterfaceCallback& callback) { | 215 const UsbInterfaceCallback& callback) { |
196 CheckDevice(); | 216 CheckDevice(); |
197 | 217 |
198 const int claim_result = libusb_claim_interface(handle_, interface_number); | 218 const int claim_result = libusb_claim_interface(handle_, interface_number); |
199 callback.Run(claim_result == 0); | 219 callback.Run(claim_result == 0); |
200 } | 220 } |
201 | 221 |
202 void UsbDevice::ReleaseInterface(const int interface_number, | 222 void UsbDevice::ReleaseInterface(const int interface_number, |
203 const UsbInterfaceCallback& callback) { | 223 const UsbInterfaceCallback& callback) { |
204 CheckDevice(); | 224 CheckDevice(); |
205 | 225 |
206 const int release_result = libusb_release_interface(handle_, | 226 const int release_result = libusb_release_interface(handle_, |
207 interface_number); | 227 interface_number); |
208 callback.Run(release_result == 0); | 228 callback.Run(release_result == 0); |
209 } | 229 } |
210 | 230 |
211 void UsbDevice::SetInterfaceAlternateSetting( | 231 void UsbDevice::SetInterfaceAlternateSetting( |
212 const int interface_number, | 232 const int interface_number, |
213 const int alternate_setting, | 233 const int alternate_setting, |
214 const UsbInterfaceCallback& callback) { | 234 const UsbInterfaceCallback& callback) { |
215 CheckDevice(); | 235 CheckDevice(); |
216 | 236 |
217 const int setting_result = libusb_set_interface_alt_setting(handle_, | 237 const int setting_result = libusb_set_interface_alt_setting(handle_, |
218 interface_number, alternate_setting); | 238 interface_number, alternate_setting); |
219 | 239 |
220 callback.Run(setting_result == 0); | 240 callback.Run(setting_result == 0); |
221 } | 241 } |
222 | 242 |
223 void UsbDevice::ControlTransfer(const TransferDirection direction, | 243 void UsbDevice::ControlTransfer(const UsbEndpointDirection direction, |
224 const TransferRequestType request_type, const TransferRecipient recipient, | 244 const TransferRequestType request_type, const TransferRecipient recipient, |
225 const uint8 request, const uint16 value, const uint16 index, | 245 const uint8 request, const uint16 value, const uint16 index, |
226 net::IOBuffer* buffer, const size_t length, const unsigned int timeout, | 246 net::IOBuffer* buffer, const size_t length, const unsigned int timeout, |
227 const UsbTransferCallback& callback) { | 247 const UsbTransferCallback& callback) { |
228 CheckDevice(); | 248 CheckDevice(); |
229 | 249 |
230 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; | 250 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; |
231 scoped_refptr<net::IOBuffer> resized_buffer(new net::IOBufferWithSize( | 251 scoped_refptr<net::IOBuffer> resized_buffer(new net::IOBufferWithSize( |
232 resized_length)); | 252 resized_length)); |
233 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), | 253 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), |
234 length); | 254 length); |
235 | 255 |
236 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); | 256 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); |
237 const uint8 converted_type = CreateRequestType(direction, request_type, | 257 const uint8 converted_type = CreateRequestType(direction, request_type, |
238 recipient); | 258 recipient); |
239 libusb_fill_control_setup(reinterpret_cast<uint8*>(resized_buffer->data()), | 259 libusb_fill_control_setup(reinterpret_cast<uint8*>(resized_buffer->data()), |
240 converted_type, request, value, index, length); | 260 converted_type, request, value, index, length); |
241 libusb_fill_control_transfer(transfer, handle_, reinterpret_cast<uint8*>( | 261 libusb_fill_control_transfer(transfer, handle_, reinterpret_cast<uint8*>( |
242 resized_buffer->data()), HandleTransferCompletion, this, timeout); | 262 resized_buffer->data()), HandleTransferCompletion, this, timeout); |
243 SubmitTransfer(transfer, USB_TRANSFER_CONTROL, resized_buffer, resized_length, | 263 SubmitTransfer(transfer, USB_TRANSFER_CONTROL, resized_buffer, resized_length, |
244 callback); | 264 callback); |
245 } | 265 } |
246 | 266 |
247 void UsbDevice::BulkTransfer(const TransferDirection direction, | 267 void UsbDevice::BulkTransfer(const UsbEndpointDirection direction, |
248 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, | 268 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, |
249 const unsigned int timeout, const UsbTransferCallback& callback) { | 269 const unsigned int timeout, const UsbTransferCallback& callback) { |
250 CheckDevice(); | 270 CheckDevice(); |
251 | 271 |
252 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); | 272 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); |
253 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; | 273 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; |
254 libusb_fill_bulk_transfer(transfer, handle_, new_endpoint, | 274 libusb_fill_bulk_transfer(transfer, handle_, new_endpoint, |
255 reinterpret_cast<uint8*>(buffer->data()), length, | 275 reinterpret_cast<uint8*>(buffer->data()), length, |
256 HandleTransferCompletion, this, timeout); | 276 HandleTransferCompletion, this, timeout); |
257 SubmitTransfer(transfer, USB_TRANSFER_BULK, buffer, length, callback); | 277 SubmitTransfer(transfer, USB_TRANSFER_BULK, buffer, length, callback); |
258 } | 278 } |
259 | 279 |
260 void UsbDevice::InterruptTransfer(const TransferDirection direction, | 280 void UsbDevice::InterruptTransfer(const UsbEndpointDirection direction, |
261 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, | 281 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, |
262 const unsigned int timeout, const UsbTransferCallback& callback) { | 282 const unsigned int timeout, const UsbTransferCallback& callback) { |
263 CheckDevice(); | 283 CheckDevice(); |
264 | 284 |
265 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); | 285 struct libusb_transfer* const transfer = libusb_alloc_transfer(0); |
266 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; | 286 const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; |
267 libusb_fill_interrupt_transfer(transfer, handle_, new_endpoint, | 287 libusb_fill_interrupt_transfer(transfer, handle_, new_endpoint, |
268 reinterpret_cast<uint8*>(buffer->data()), length, | 288 reinterpret_cast<uint8*>(buffer->data()), length, |
269 HandleTransferCompletion, this, timeout); | 289 HandleTransferCompletion, this, timeout); |
270 SubmitTransfer(transfer, USB_TRANSFER_INTERRUPT, buffer, length, callback); | 290 SubmitTransfer(transfer, USB_TRANSFER_INTERRUPT, buffer, length, callback); |
271 } | 291 } |
272 | 292 |
273 void UsbDevice::IsochronousTransfer(const TransferDirection direction, | 293 void UsbDevice::IsochronousTransfer(const UsbEndpointDirection direction, |
274 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, | 294 const uint8 endpoint, net::IOBuffer* buffer, const size_t length, |
275 const unsigned int packets, const unsigned int packet_length, | 295 const unsigned int packets, const unsigned int packet_length, |
276 const unsigned int timeout, const UsbTransferCallback& callback) { | 296 const unsigned int timeout, const UsbTransferCallback& callback) { |
277 CheckDevice(); | 297 CheckDevice(); |
278 | 298 |
279 const uint64 total_length = packets * packet_length; | 299 const uint64 total_length = packets * packet_length; |
280 CHECK(packets <= length && total_length <= length) << | 300 CHECK(packets <= length && total_length <= length) << |
281 "transfer length is too small"; | 301 "transfer length is too small"; |
282 | 302 |
283 struct libusb_transfer* const transfer = libusb_alloc_transfer(packets); | 303 struct libusb_transfer* const transfer = libusb_alloc_transfer(packets); |
(...skipping 25 matching lines...) Expand all Loading... |
309 transfer.buffer = buffer; | 329 transfer.buffer = buffer; |
310 transfer.length = length; | 330 transfer.length = length; |
311 transfer.callback = callback; | 331 transfer.callback = callback; |
312 | 332 |
313 { | 333 { |
314 base::AutoLock lock(lock_); | 334 base::AutoLock lock(lock_); |
315 transfers_[handle] = transfer; | 335 transfers_[handle] = transfer; |
316 libusb_submit_transfer(handle); | 336 libusb_submit_transfer(handle); |
317 } | 337 } |
318 } | 338 } |
OLD | NEW |