OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/usb_service/usb_device_handle_impl.h" | 5 #include "device/usb/usb_device_handle_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/strings/string16.h" | 14 #include "base/strings/string16.h" |
15 #include "base/synchronization/lock.h" | 15 #include "base/synchronization/lock.h" |
16 #include "base/thread_task_runner_handle.h" | 16 #include "base/thread_task_runner_handle.h" |
17 #include "components/usb_service/usb_context.h" | 17 #include "device/usb/usb_context.h" |
18 #include "components/usb_service/usb_device_impl.h" | 18 #include "device/usb/usb_device_impl.h" |
19 #include "components/usb_service/usb_error.h" | 19 #include "device/usb/usb_error.h" |
20 #include "components/usb_service/usb_interface.h" | 20 #include "device/usb/usb_interface.h" |
21 #include "components/usb_service/usb_service.h" | 21 #include "device/usb/usb_service.h" |
22 #include "third_party/libusb/src/libusb/libusb.h" | 22 #include "third_party/libusb/src/libusb/libusb.h" |
23 | 23 |
24 namespace usb_service { | 24 namespace device { |
25 | 25 |
26 typedef libusb_device* PlatformUsbDevice; | 26 typedef libusb_device* PlatformUsbDevice; |
27 | 27 |
28 void HandleTransferCompletion(usb_service::PlatformUsbTransferHandle transfer); | 28 void HandleTransferCompletion(PlatformUsbTransferHandle transfer); |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 static uint8 ConvertTransferDirection(const UsbEndpointDirection direction) { | 32 static uint8 ConvertTransferDirection(const UsbEndpointDirection direction) { |
33 switch (direction) { | 33 switch (direction) { |
34 case USB_DIRECTION_INBOUND: | 34 case USB_DIRECTION_INBOUND: |
35 return LIBUSB_ENDPOINT_IN; | 35 return LIBUSB_ENDPOINT_IN; |
36 case USB_DIRECTION_OUTBOUND: | 36 case USB_DIRECTION_OUTBOUND: |
37 return LIBUSB_ENDPOINT_OUT; | 37 return LIBUSB_ENDPOINT_OUT; |
38 default: | 38 default: |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 alternate_setting_(0) { | 138 alternate_setting_(0) { |
139 } | 139 } |
140 | 140 |
141 UsbDeviceHandleImpl::InterfaceClaimer::~InterfaceClaimer() { | 141 UsbDeviceHandleImpl::InterfaceClaimer::~InterfaceClaimer() { |
142 libusb_release_interface(handle_->handle(), interface_number_); | 142 libusb_release_interface(handle_->handle(), interface_number_); |
143 } | 143 } |
144 | 144 |
145 bool UsbDeviceHandleImpl::InterfaceClaimer::Claim() const { | 145 bool UsbDeviceHandleImpl::InterfaceClaimer::Claim() const { |
146 const int rv = libusb_claim_interface(handle_->handle(), interface_number_); | 146 const int rv = libusb_claim_interface(handle_->handle(), interface_number_); |
147 if (rv != LIBUSB_SUCCESS) { | 147 if (rv != LIBUSB_SUCCESS) { |
148 VLOG(1) << "Failed to claim interface: " << ConvertErrorToString(rv); | 148 VLOG(1) << "Failed to claim interface: " |
| 149 << ConvertPlatformUsbErrorToString(rv); |
149 } | 150 } |
150 return rv == LIBUSB_SUCCESS; | 151 return rv == LIBUSB_SUCCESS; |
151 } | 152 } |
152 | 153 |
153 struct UsbDeviceHandleImpl::Transfer { | 154 struct UsbDeviceHandleImpl::Transfer { |
154 Transfer(); | 155 Transfer(); |
155 ~Transfer(); | 156 ~Transfer(); |
156 | 157 |
157 void Complete(UsbTransferStatus status, size_t bytes_transferred); | 158 void Complete(UsbTransferStatus status, size_t bytes_transferred); |
158 | 159 |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 if (!ContainsKey(claimed_interfaces_, interface_number)) | 351 if (!ContainsKey(claimed_interfaces_, interface_number)) |
351 return false; | 352 return false; |
352 const int rv = libusb_set_interface_alt_setting( | 353 const int rv = libusb_set_interface_alt_setting( |
353 handle_, interface_number, alternate_setting); | 354 handle_, interface_number, alternate_setting); |
354 if (rv == LIBUSB_SUCCESS) { | 355 if (rv == LIBUSB_SUCCESS) { |
355 claimed_interfaces_[interface_number]->set_alternate_setting( | 356 claimed_interfaces_[interface_number]->set_alternate_setting( |
356 alternate_setting); | 357 alternate_setting); |
357 RefreshEndpointMap(); | 358 RefreshEndpointMap(); |
358 } else { | 359 } else { |
359 VLOG(1) << "Failed to set interface (" << interface_number << ", " | 360 VLOG(1) << "Failed to set interface (" << interface_number << ", " |
360 << alternate_setting << "): " << ConvertErrorToString(rv); | 361 << alternate_setting |
| 362 << "): " << ConvertPlatformUsbErrorToString(rv); |
361 } | 363 } |
362 return rv == LIBUSB_SUCCESS; | 364 return rv == LIBUSB_SUCCESS; |
363 } | 365 } |
364 | 366 |
365 bool UsbDeviceHandleImpl::ResetDevice() { | 367 bool UsbDeviceHandleImpl::ResetDevice() { |
366 DCHECK(thread_checker_.CalledOnValidThread()); | 368 DCHECK(thread_checker_.CalledOnValidThread()); |
367 if (!device_) | 369 if (!device_) |
368 return false; | 370 return false; |
369 | 371 |
370 const int rv = libusb_reset_device(handle_); | 372 const int rv = libusb_reset_device(handle_); |
371 if (rv != LIBUSB_SUCCESS) { | 373 if (rv != LIBUSB_SUCCESS) { |
372 VLOG(1) << "Failed to reset device: " << ConvertErrorToString(rv); | 374 VLOG(1) << "Failed to reset device: " |
| 375 << ConvertPlatformUsbErrorToString(rv); |
373 } | 376 } |
374 return rv == LIBUSB_SUCCESS; | 377 return rv == LIBUSB_SUCCESS; |
375 } | 378 } |
376 | 379 |
377 bool UsbDeviceHandleImpl::GetSupportedLanguages() { | 380 bool UsbDeviceHandleImpl::GetSupportedLanguages() { |
378 if (!languages_.empty()) { | 381 if (!languages_.empty()) { |
379 return true; | 382 return true; |
380 } | 383 } |
381 | 384 |
382 // The 1-byte length field limits the descriptor to 256-bytes (128 uint16s). | 385 // The 1-byte length field limits the descriptor to 256-bytes (128 uint16s). |
383 uint16 languages[128]; | 386 uint16 languages[128]; |
384 int size = libusb_get_string_descriptor( | 387 int size = libusb_get_string_descriptor( |
385 handle_, | 388 handle_, |
386 0, | 389 0, |
387 0, | 390 0, |
388 reinterpret_cast<unsigned char*>(&languages[0]), | 391 reinterpret_cast<unsigned char*>(&languages[0]), |
389 sizeof(languages)); | 392 sizeof(languages)); |
390 if (size < 0) { | 393 if (size < 0) { |
391 VLOG(1) << "Failed to get list of supported languages: " | 394 VLOG(1) << "Failed to get list of supported languages: " |
392 << ConvertErrorToString(size); | 395 << ConvertPlatformUsbErrorToString(size); |
393 return false; | 396 return false; |
394 } else if (size < 2) { | 397 } else if (size < 2) { |
395 VLOG(1) << "String descriptor zero has no header."; | 398 VLOG(1) << "String descriptor zero has no header."; |
396 return false; | 399 return false; |
397 // The first 2 bytes of the descriptor are the total length and type tag. | 400 // The first 2 bytes of the descriptor are the total length and type tag. |
398 } else if ((languages[0] & 0xff) != size) { | 401 } else if ((languages[0] & 0xff) != size) { |
399 VLOG(1) << "String descriptor zero size mismatch: " << (languages[0] & 0xff) | 402 VLOG(1) << "String descriptor zero size mismatch: " << (languages[0] & 0xff) |
400 << " != " << size; | 403 << " != " << size; |
401 return false; | 404 return false; |
402 } else if ((languages[0] >> 8) != LIBUSB_DT_STRING) { | 405 } else if ((languages[0] >> 8) != LIBUSB_DT_STRING) { |
403 VLOG(1) << "String descriptor zero is not a string descriptor."; | 406 VLOG(1) << "String descriptor zero is not a string descriptor."; |
404 return false; | 407 return false; |
405 } | 408 } |
406 | 409 |
407 languages_.assign(languages[1], languages[(size - 2) / 2]); | 410 languages_.assign(languages[1], languages[(size - 2) / 2]); |
(...skipping 18 matching lines...) Expand all Loading... |
426 // The 1-byte length field limits the descriptor to 256-bytes (128 char16s). | 429 // The 1-byte length field limits the descriptor to 256-bytes (128 char16s). |
427 base::char16 text[128]; | 430 base::char16 text[128]; |
428 int size = | 431 int size = |
429 libusb_get_string_descriptor(handle_, | 432 libusb_get_string_descriptor(handle_, |
430 string_id, | 433 string_id, |
431 language_id, | 434 language_id, |
432 reinterpret_cast<unsigned char*>(&text[0]), | 435 reinterpret_cast<unsigned char*>(&text[0]), |
433 sizeof(text)); | 436 sizeof(text)); |
434 if (size < 0) { | 437 if (size < 0) { |
435 VLOG(1) << "Failed to get string descriptor " << string_id << " (langid " | 438 VLOG(1) << "Failed to get string descriptor " << string_id << " (langid " |
436 << language_id << "): " << ConvertErrorToString(size); | 439 << language_id << "): " << ConvertPlatformUsbErrorToString(size); |
437 continue; | 440 continue; |
438 } else if (size < 2) { | 441 } else if (size < 2) { |
439 VLOG(1) << "String descriptor " << string_id << " (langid " << language_id | 442 VLOG(1) << "String descriptor " << string_id << " (langid " << language_id |
440 << ") has no header."; | 443 << ") has no header."; |
441 continue; | 444 continue; |
442 // The first 2 bytes of the descriptor are the total length and type tag. | 445 // The first 2 bytes of the descriptor are the total length and type tag. |
443 } else if ((text[0] & 0xff) != size) { | 446 } else if ((text[0] & 0xff) != size) { |
444 VLOG(1) << "String descriptor " << string_id << " (langid " << language_id | 447 VLOG(1) << "String descriptor " << string_id << " (langid " << language_id |
445 << ") size mismatch: " << (text[0] & 0xff) << " != " << size; | 448 << ") size mismatch: " << (text[0] & 0xff) << " != " << size; |
446 continue; | 449 continue; |
447 } else if ((text[0] >> 8) != LIBUSB_DT_STRING) { | 450 } else if ((text[0] >> 8) != LIBUSB_DT_STRING) { |
448 VLOG(1) << "String descriptor " << string_id << " (langid " << language_id | 451 VLOG(1) << "String descriptor " << string_id << " (langid " << language_id |
449 << ") is not a string descriptor."; | 452 << ") is not a string descriptor."; |
450 continue; | 453 continue; |
451 } | 454 } |
452 | 455 |
453 *string = base::string16(text + 1, (size - 2) / 2); | 456 *string = base::string16(text + 1, (size - 2) / 2); |
454 strings_[string_id] = *string; | 457 strings_[string_id] = *string; |
455 return true; | 458 return true; |
456 } | 459 } |
457 | 460 |
458 return false; | 461 return false; |
459 } | 462 } |
460 | 463 |
461 bool UsbDeviceHandleImpl::GetManufacturer(base::string16* manufacturer) { | 464 bool UsbDeviceHandleImpl::GetManufacturer(base::string16* manufacturer) { |
462 DCHECK(thread_checker_.CalledOnValidThread()); | 465 DCHECK(thread_checker_.CalledOnValidThread()); |
463 PlatformUsbDevice device = libusb_get_device(handle_); | 466 PlatformUsbDevice device = libusb_get_device(handle_); |
464 libusb_device_descriptor desc; | 467 libusb_device_descriptor desc; |
465 | 468 |
466 // This is a non-blocking call as libusb has the descriptor in memory. | 469 // This is a non-blocking call as libusb has the descriptor in memory. |
467 const int rv = libusb_get_device_descriptor(device, &desc); | 470 const int rv = libusb_get_device_descriptor(device, &desc); |
468 if (rv != LIBUSB_SUCCESS) { | 471 if (rv != LIBUSB_SUCCESS) { |
469 VLOG(1) << "Failed to read device descriptor: " << ConvertErrorToString(rv); | 472 VLOG(1) << "Failed to read device descriptor: " |
| 473 << ConvertPlatformUsbErrorToString(rv); |
470 return false; | 474 return false; |
471 } | 475 } |
472 | 476 |
473 if (desc.iManufacturer == 0) { | 477 if (desc.iManufacturer == 0) { |
474 return false; | 478 return false; |
475 } | 479 } |
476 | 480 |
477 return GetStringDescriptor(desc.iManufacturer, manufacturer); | 481 return GetStringDescriptor(desc.iManufacturer, manufacturer); |
478 } | 482 } |
479 | 483 |
480 bool UsbDeviceHandleImpl::GetProduct(base::string16* product) { | 484 bool UsbDeviceHandleImpl::GetProduct(base::string16* product) { |
481 DCHECK(thread_checker_.CalledOnValidThread()); | 485 DCHECK(thread_checker_.CalledOnValidThread()); |
482 PlatformUsbDevice device = libusb_get_device(handle_); | 486 PlatformUsbDevice device = libusb_get_device(handle_); |
483 libusb_device_descriptor desc; | 487 libusb_device_descriptor desc; |
484 | 488 |
485 // This is a non-blocking call as libusb has the descriptor in memory. | 489 // This is a non-blocking call as libusb has the descriptor in memory. |
486 const int rv = libusb_get_device_descriptor(device, &desc); | 490 const int rv = libusb_get_device_descriptor(device, &desc); |
487 if (rv != LIBUSB_SUCCESS) { | 491 if (rv != LIBUSB_SUCCESS) { |
488 VLOG(1) << "Failed to read device descriptor: " << ConvertErrorToString(rv); | 492 VLOG(1) << "Failed to read device descriptor: " |
| 493 << ConvertPlatformUsbErrorToString(rv); |
489 return false; | 494 return false; |
490 } | 495 } |
491 | 496 |
492 if (desc.iProduct == 0) { | 497 if (desc.iProduct == 0) { |
493 return false; | 498 return false; |
494 } | 499 } |
495 | 500 |
496 return GetStringDescriptor(desc.iProduct, product); | 501 return GetStringDescriptor(desc.iProduct, product); |
497 } | 502 } |
498 | 503 |
499 bool UsbDeviceHandleImpl::GetSerial(base::string16* serial) { | 504 bool UsbDeviceHandleImpl::GetSerial(base::string16* serial) { |
500 DCHECK(thread_checker_.CalledOnValidThread()); | 505 DCHECK(thread_checker_.CalledOnValidThread()); |
501 PlatformUsbDevice device = libusb_get_device(handle_); | 506 PlatformUsbDevice device = libusb_get_device(handle_); |
502 libusb_device_descriptor desc; | 507 libusb_device_descriptor desc; |
503 | 508 |
504 // This is a non-blocking call as libusb has the descriptor in memory. | 509 // This is a non-blocking call as libusb has the descriptor in memory. |
505 const int rv = libusb_get_device_descriptor(device, &desc); | 510 const int rv = libusb_get_device_descriptor(device, &desc); |
506 if (rv != LIBUSB_SUCCESS) { | 511 if (rv != LIBUSB_SUCCESS) { |
507 VLOG(1) << "Failed to read device descriptor: " << ConvertErrorToString(rv); | 512 VLOG(1) << "Failed to read device descriptor: " |
| 513 << ConvertPlatformUsbErrorToString(rv); |
508 return false; | 514 return false; |
509 } | 515 } |
510 | 516 |
511 if (desc.iSerialNumber == 0) { | 517 if (desc.iSerialNumber == 0) { |
512 return false; | 518 return false; |
513 } | 519 } |
514 | 520 |
515 return GetStringDescriptor(desc.iSerialNumber, serial); | 521 return GetStringDescriptor(desc.iSerialNumber, serial); |
516 } | 522 } |
517 | 523 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 } | 728 } |
723 | 729 |
724 // It's OK for this method to return NULL. libusb_submit_transfer will fail if | 730 // It's OK for this method to return NULL. libusb_submit_transfer will fail if |
725 // it requires an interface we didn't claim. | 731 // it requires an interface we didn't claim. |
726 transfer.claimed_interface = GetClaimedInterfaceForEndpoint(handle->endpoint); | 732 transfer.claimed_interface = GetClaimedInterfaceForEndpoint(handle->endpoint); |
727 | 733 |
728 const int rv = libusb_submit_transfer(handle); | 734 const int rv = libusb_submit_transfer(handle); |
729 if (rv == LIBUSB_SUCCESS) { | 735 if (rv == LIBUSB_SUCCESS) { |
730 transfers_[handle] = transfer; | 736 transfers_[handle] = transfer; |
731 } else { | 737 } else { |
732 VLOG(1) << "Failed to submit transfer: " << ConvertErrorToString(rv); | 738 VLOG(1) << "Failed to submit transfer: " |
| 739 << ConvertPlatformUsbErrorToString(rv); |
733 transfer.Complete(USB_TRANSFER_ERROR, 0); | 740 transfer.Complete(USB_TRANSFER_ERROR, 0); |
734 } | 741 } |
735 } | 742 } |
736 | 743 |
737 void UsbDeviceHandleImpl::InternalClose() { | 744 void UsbDeviceHandleImpl::InternalClose() { |
738 DCHECK(thread_checker_.CalledOnValidThread()); | 745 DCHECK(thread_checker_.CalledOnValidThread()); |
739 if (!device_) | 746 if (!device_) |
740 return; | 747 return; |
741 | 748 |
742 // Cancel all the transfers. | 749 // Cancel all the transfers. |
743 for (TransferMap::iterator it = transfers_.begin(); it != transfers_.end(); | 750 for (TransferMap::iterator it = transfers_.begin(); it != transfers_.end(); |
744 ++it) { | 751 ++it) { |
745 // The callback will be called some time later. | 752 // The callback will be called some time later. |
746 libusb_cancel_transfer(it->first); | 753 libusb_cancel_transfer(it->first); |
747 } | 754 } |
748 | 755 |
749 // Attempt-release all the interfaces. | 756 // Attempt-release all the interfaces. |
750 // It will be retained until the transfer cancellation is finished. | 757 // It will be retained until the transfer cancellation is finished. |
751 claimed_interfaces_.clear(); | 758 claimed_interfaces_.clear(); |
752 | 759 |
753 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to | 760 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to |
754 // finish. | 761 // finish. |
755 device_ = NULL; | 762 device_ = NULL; |
756 } | 763 } |
757 | 764 |
758 } // namespace usb_service | 765 } // namespace device |
OLD | NEW |