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 "device/usb/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" |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 } else { | 370 } else { |
371 VLOG(1) << "Failed to submit transfer: " | 371 VLOG(1) << "Failed to submit transfer: " |
372 << ConvertPlatformUsbErrorToString(rv); | 372 << ConvertPlatformUsbErrorToString(rv); |
373 Complete(USB_TRANSFER_ERROR, 0); | 373 Complete(USB_TRANSFER_ERROR, 0); |
374 return false; | 374 return false; |
375 } | 375 } |
376 } | 376 } |
377 | 377 |
378 void UsbDeviceHandleImpl::Transfer::Cancel() { | 378 void UsbDeviceHandleImpl::Transfer::Cancel() { |
379 libusb_cancel_transfer(platform_transfer_); | 379 libusb_cancel_transfer(platform_transfer_); |
| 380 claimed_interface_ = nullptr; |
380 } | 381 } |
381 | 382 |
382 void UsbDeviceHandleImpl::Transfer::ProcessCompletion() { | 383 void UsbDeviceHandleImpl::Transfer::ProcessCompletion() { |
383 DCHECK_GE(platform_transfer_->actual_length, 0) | 384 DCHECK_GE(platform_transfer_->actual_length, 0) |
384 << "Negative actual length received"; | 385 << "Negative actual length received"; |
385 size_t actual_length = | 386 size_t actual_length = |
386 static_cast<size_t>(std::max(platform_transfer_->actual_length, 0)); | 387 static_cast<size_t>(std::max(platform_transfer_->actual_length, 0)); |
387 | 388 |
388 DCHECK(length_ >= actual_length) | 389 DCHECK(length_ >= actual_length) |
389 << "data too big for our buffer (libusb failure?)"; | 390 << "data too big for our buffer (libusb failure?)"; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 // will be discarded if the handle has been freed. | 471 // will be discarded if the handle has been freed. |
471 Transfer* tmp_transfer = transfer.get(); // base::Passed invalidates transfer | 472 Transfer* tmp_transfer = transfer.get(); // base::Passed invalidates transfer |
472 tmp_transfer->task_runner_->PostTask( | 473 tmp_transfer->task_runner_->PostTask( |
473 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::CompleteTransfer, | 474 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::CompleteTransfer, |
474 tmp_transfer->device_handle_, | 475 tmp_transfer->device_handle_, |
475 base::Passed(&transfer))); | 476 base::Passed(&transfer))); |
476 } | 477 } |
477 | 478 |
478 UsbDeviceHandleImpl::UsbDeviceHandleImpl(scoped_refptr<UsbContext> context, | 479 UsbDeviceHandleImpl::UsbDeviceHandleImpl(scoped_refptr<UsbContext> context, |
479 UsbDeviceImpl* device, | 480 UsbDeviceImpl* device, |
480 PlatformUsbDeviceHandle handle, | 481 PlatformUsbDeviceHandle handle) |
481 const UsbConfigDescriptor& config) | |
482 : device_(device), | 482 : device_(device), |
483 handle_(handle), | 483 handle_(handle), |
484 config_(config), | |
485 context_(context), | 484 context_(context), |
486 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 485 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
487 weak_factory_(this) { | 486 weak_factory_(this) { |
488 DCHECK(handle) << "Cannot create device with NULL handle."; | 487 DCHECK(handle) << "Cannot create device with NULL handle."; |
489 } | 488 } |
490 | 489 |
491 UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { | 490 UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { |
492 DCHECK(thread_checker_.CalledOnValidThread()); | 491 DCHECK(thread_checker_.CalledOnValidThread()); |
493 | 492 |
494 libusb_close(handle_); | 493 libusb_close(handle_); |
495 handle_ = NULL; | 494 handle_ = NULL; |
496 } | 495 } |
497 | 496 |
498 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const { | 497 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const { |
499 return static_cast<UsbDevice*>(device_); | 498 return static_cast<UsbDevice*>(device_); |
500 } | 499 } |
501 | 500 |
502 void UsbDeviceHandleImpl::Close() { | 501 void UsbDeviceHandleImpl::Close() { |
503 DCHECK(thread_checker_.CalledOnValidThread()); | 502 DCHECK(thread_checker_.CalledOnValidThread()); |
504 if (device_) | 503 if (device_) |
505 device_->Close(this); | 504 device_->Close(this); |
506 } | 505 } |
507 | 506 |
| 507 bool UsbDeviceHandleImpl::SetConfiguration(int configuration_value) { |
| 508 DCHECK(thread_checker_.CalledOnValidThread()); |
| 509 if (!device_) { |
| 510 return false; |
| 511 } |
| 512 |
| 513 for (Transfer* transfer : transfers_) { |
| 514 transfer->Cancel(); |
| 515 } |
| 516 claimed_interfaces_.clear(); |
| 517 |
| 518 int rv = libusb_set_configuration(handle_, configuration_value); |
| 519 if (rv == LIBUSB_SUCCESS) { |
| 520 device_->RefreshConfiguration(); |
| 521 RefreshEndpointMap(); |
| 522 } else { |
| 523 VLOG(1) << "Failed to set configuration " << configuration_value << ": " |
| 524 << ConvertPlatformUsbErrorToString(rv); |
| 525 } |
| 526 return rv == LIBUSB_SUCCESS; |
| 527 } |
| 528 |
508 bool UsbDeviceHandleImpl::ClaimInterface(const int interface_number) { | 529 bool UsbDeviceHandleImpl::ClaimInterface(const int interface_number) { |
509 DCHECK(thread_checker_.CalledOnValidThread()); | 530 DCHECK(thread_checker_.CalledOnValidThread()); |
510 if (!device_) | 531 if (!device_) |
511 return false; | 532 return false; |
512 if (ContainsKey(claimed_interfaces_, interface_number)) | 533 if (ContainsKey(claimed_interfaces_, interface_number)) |
513 return true; | 534 return true; |
514 | 535 |
515 scoped_refptr<InterfaceClaimer> claimer = | 536 scoped_refptr<InterfaceClaimer> claimer = |
516 new InterfaceClaimer(this, interface_number); | 537 new InterfaceClaimer(this, interface_number); |
517 | 538 |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( | 744 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( |
724 ConvertTransferDirection(direction) | endpoint, buffer, | 745 ConvertTransferDirection(direction) | endpoint, buffer, |
725 static_cast<int>(length), packets, packet_length, timeout, callback); | 746 static_cast<int>(length), packets, packet_length, timeout, callback); |
726 | 747 |
727 PostOrSubmitTransfer(transfer.Pass()); | 748 PostOrSubmitTransfer(transfer.Pass()); |
728 } | 749 } |
729 | 750 |
730 void UsbDeviceHandleImpl::RefreshEndpointMap() { | 751 void UsbDeviceHandleImpl::RefreshEndpointMap() { |
731 DCHECK(thread_checker_.CalledOnValidThread()); | 752 DCHECK(thread_checker_.CalledOnValidThread()); |
732 endpoint_map_.clear(); | 753 endpoint_map_.clear(); |
733 for (ClaimedInterfaceMap::iterator claimedIt = claimed_interfaces_.begin(); | 754 const UsbConfigDescriptor* config = device_->GetConfiguration(); |
734 claimedIt != claimed_interfaces_.end(); | 755 if (config) { |
735 ++claimedIt) { | 756 for (const auto& map_entry : claimed_interfaces_) { |
736 for (UsbInterfaceDescriptor::Iterator ifaceIt = config_.interfaces.begin(); | 757 int interface_number = map_entry.first; |
737 ifaceIt != config_.interfaces.end(); | 758 const scoped_refptr<InterfaceClaimer>& claimed_iface = map_entry.second; |
738 ++ifaceIt) { | 759 |
739 if (ifaceIt->interface_number == claimedIt->first && | 760 for (const UsbInterfaceDescriptor& iface : config->interfaces) { |
740 ifaceIt->alternate_setting == | 761 if (iface.interface_number == interface_number && |
741 claimedIt->second->alternate_setting()) { | 762 iface.alternate_setting == claimed_iface->alternate_setting()) { |
742 for (UsbEndpointDescriptor::Iterator endpointIt = | 763 for (const UsbEndpointDescriptor& endpoint : iface.endpoints) { |
743 ifaceIt->endpoints.begin(); | 764 endpoint_map_[endpoint.address] = interface_number; |
744 endpointIt != ifaceIt->endpoints.end(); | 765 } |
745 ++endpointIt) { | 766 break; |
746 endpoint_map_[endpointIt->address] = claimedIt->first; | |
747 } | 767 } |
748 break; | |
749 } | 768 } |
750 } | 769 } |
751 } | 770 } |
752 } | 771 } |
753 | 772 |
754 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> | 773 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> |
755 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) { | 774 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(unsigned char endpoint) { |
756 if (ContainsKey(endpoint_map_, endpoint)) | 775 if (ContainsKey(endpoint_map_, endpoint)) |
757 return claimed_interfaces_[endpoint_map_[endpoint]]; | 776 return claimed_interfaces_[endpoint_map_[endpoint]]; |
758 return NULL; | 777 return NULL; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 // Attempt-release all the interfaces. | 856 // Attempt-release all the interfaces. |
838 // It will be retained until the transfer cancellation is finished. | 857 // It will be retained until the transfer cancellation is finished. |
839 claimed_interfaces_.clear(); | 858 claimed_interfaces_.clear(); |
840 | 859 |
841 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to | 860 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to |
842 // finish. | 861 // finish. |
843 device_ = NULL; | 862 device_ = NULL; |
844 } | 863 } |
845 | 864 |
846 } // namespace device | 865 } // namespace device |
OLD | NEW |