| 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 |