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 "components/usb_service/usb_device_handle_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/strings/string16.h" | 12 #include "base/strings/string16.h" |
13 #include "base/synchronization/lock.h" | 13 #include "base/synchronization/lock.h" |
14 #include "components/usb_service/usb_context.h" | 14 #include "components/usb_service/usb_context.h" |
15 #include "components/usb_service/usb_device_impl.h" | 15 #include "components/usb_service/usb_device_impl.h" |
| 16 #include "components/usb_service/usb_error.h" |
16 #include "components/usb_service/usb_interface.h" | 17 #include "components/usb_service/usb_interface.h" |
17 #include "components/usb_service/usb_service.h" | 18 #include "components/usb_service/usb_service.h" |
18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
19 #include "third_party/libusb/src/libusb/libusb.h" | 20 #include "third_party/libusb/src/libusb/libusb.h" |
20 | 21 |
21 using content::BrowserThread; | 22 using content::BrowserThread; |
22 | 23 |
23 namespace usb_service { | 24 namespace usb_service { |
24 | 25 |
25 typedef libusb_device* PlatformUsbDevice; | 26 typedef libusb_device* PlatformUsbDevice; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 : handle_(handle), | 152 : handle_(handle), |
152 interface_number_(interface_number), | 153 interface_number_(interface_number), |
153 alternate_setting_(0) { | 154 alternate_setting_(0) { |
154 } | 155 } |
155 | 156 |
156 UsbDeviceHandleImpl::InterfaceClaimer::~InterfaceClaimer() { | 157 UsbDeviceHandleImpl::InterfaceClaimer::~InterfaceClaimer() { |
157 libusb_release_interface(handle_->handle(), interface_number_); | 158 libusb_release_interface(handle_->handle(), interface_number_); |
158 } | 159 } |
159 | 160 |
160 bool UsbDeviceHandleImpl::InterfaceClaimer::Claim() const { | 161 bool UsbDeviceHandleImpl::InterfaceClaimer::Claim() const { |
161 return libusb_claim_interface(handle_->handle(), interface_number_) == 0; | 162 const int rv = libusb_claim_interface(handle_->handle(), interface_number_); |
| 163 if (rv != LIBUSB_SUCCESS) { |
| 164 LOG(ERROR) << "Failed to claim interface: " << ConvertErrorToString(rv); |
| 165 } |
| 166 return rv == LIBUSB_SUCCESS; |
162 } | 167 } |
163 | 168 |
164 struct UsbDeviceHandleImpl::Transfer { | 169 struct UsbDeviceHandleImpl::Transfer { |
165 Transfer(); | 170 Transfer(); |
166 ~Transfer(); | 171 ~Transfer(); |
167 | 172 |
168 UsbTransferType transfer_type; | 173 UsbTransferType transfer_type; |
169 scoped_refptr<net::IOBuffer> buffer; | 174 scoped_refptr<net::IOBuffer> buffer; |
170 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface; | 175 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface; |
171 scoped_refptr<base::MessageLoopProxy> message_loop_proxy; | 176 scoped_refptr<base::MessageLoopProxy> message_loop_proxy; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 bool UsbDeviceHandleImpl::SetInterfaceAlternateSetting( | 342 bool UsbDeviceHandleImpl::SetInterfaceAlternateSetting( |
338 const int interface_number, | 343 const int interface_number, |
339 const int alternate_setting) { | 344 const int alternate_setting) { |
340 DCHECK(thread_checker_.CalledOnValidThread()); | 345 DCHECK(thread_checker_.CalledOnValidThread()); |
341 if (!device_) | 346 if (!device_) |
342 return false; | 347 return false; |
343 if (!ContainsKey(claimed_interfaces_, interface_number)) | 348 if (!ContainsKey(claimed_interfaces_, interface_number)) |
344 return false; | 349 return false; |
345 const int rv = libusb_set_interface_alt_setting( | 350 const int rv = libusb_set_interface_alt_setting( |
346 handle_, interface_number, alternate_setting); | 351 handle_, interface_number, alternate_setting); |
347 if (rv == 0) { | 352 if (rv == LIBUSB_SUCCESS) { |
348 claimed_interfaces_[interface_number]->set_alternate_setting( | 353 claimed_interfaces_[interface_number]->set_alternate_setting( |
349 alternate_setting); | 354 alternate_setting); |
350 RefreshEndpointMap(); | 355 RefreshEndpointMap(); |
351 return true; | 356 } else { |
| 357 LOG(ERROR) << "Failed to set interface (" << interface_number |
| 358 << ", " << alternate_setting << "): " << ConvertErrorToString(rv); |
352 } | 359 } |
353 return false; | 360 return rv == LIBUSB_SUCCESS; |
354 } | 361 } |
355 | 362 |
356 bool UsbDeviceHandleImpl::ResetDevice() { | 363 bool UsbDeviceHandleImpl::ResetDevice() { |
357 DCHECK(thread_checker_.CalledOnValidThread()); | 364 DCHECK(thread_checker_.CalledOnValidThread()); |
358 if (!device_) | 365 if (!device_) |
359 return false; | 366 return false; |
360 | 367 |
361 return libusb_reset_device(handle_) == 0; | 368 const int rv = libusb_reset_device(handle_); |
| 369 if (rv != LIBUSB_SUCCESS) { |
| 370 LOG(ERROR) << "Failed to reset device: " << ConvertErrorToString(rv); |
| 371 } |
| 372 return rv == LIBUSB_SUCCESS; |
362 } | 373 } |
363 | 374 |
364 bool UsbDeviceHandleImpl::GetSerial(base::string16* serial) { | 375 bool UsbDeviceHandleImpl::GetSerial(base::string16* serial) { |
365 DCHECK(thread_checker_.CalledOnValidThread()); | 376 DCHECK(thread_checker_.CalledOnValidThread()); |
366 PlatformUsbDevice device = libusb_get_device(handle_); | 377 PlatformUsbDevice device = libusb_get_device(handle_); |
367 libusb_device_descriptor desc; | 378 libusb_device_descriptor desc; |
368 | 379 |
369 if (libusb_get_device_descriptor(device, &desc) != LIBUSB_SUCCESS) | 380 const int rv = libusb_get_device_descriptor(device, &desc); |
| 381 if (rv != LIBUSB_SUCCESS) { |
| 382 LOG(ERROR) << "Failed to read device descriptor: " |
| 383 << ConvertErrorToString(rv); |
370 return false; | 384 return false; |
| 385 } |
371 | 386 |
372 if (desc.iSerialNumber == 0) | 387 if (desc.iSerialNumber == 0) |
373 return false; | 388 return false; |
374 | 389 |
375 // Getting supported language ID. | 390 // Getting supported language ID. |
376 uint16 langid[128] = {0}; | 391 uint16 langid[128] = {0}; |
377 | 392 |
378 int size = | 393 int size = |
379 libusb_get_string_descriptor(handle_, | 394 libusb_get_string_descriptor(handle_, |
380 0, | 395 0, |
381 0, | 396 0, |
382 reinterpret_cast<unsigned char*>(&langid[0]), | 397 reinterpret_cast<unsigned char*>(&langid[0]), |
383 sizeof(langid)); | 398 sizeof(langid)); |
384 if (size < 0) | 399 if (size < 0) { |
| 400 LOG(ERROR) << "Failed to get language IDs: " |
| 401 << ConvertErrorToString(size); |
385 return false; | 402 return false; |
| 403 } |
386 | 404 |
387 int language_count = (size - 2) / 2; | 405 int language_count = (size - 2) / 2; |
388 | 406 |
389 for (int i = 1; i <= language_count; ++i) { | 407 for (int i = 1; i <= language_count; ++i) { |
390 // Get the string using language ID. | 408 // Get the string using language ID. |
391 base::char16 text[256] = {0}; | 409 base::char16 text[256] = {0}; |
392 size = | 410 size = |
393 libusb_get_string_descriptor(handle_, | 411 libusb_get_string_descriptor(handle_, |
394 desc.iSerialNumber, | 412 desc.iSerialNumber, |
395 langid[i], | 413 langid[i], |
396 reinterpret_cast<unsigned char*>(&text[0]), | 414 reinterpret_cast<unsigned char*>(&text[0]), |
397 sizeof(text)); | 415 sizeof(text)); |
| 416 if (size < 0) { |
| 417 LOG(ERROR) << "Failed to get serial number (langid " << langid[i] << "): " |
| 418 << ConvertErrorToString(size); |
| 419 continue; |
| 420 } |
398 if (size <= 2) | 421 if (size <= 2) |
399 continue; | 422 continue; |
400 if ((text[0] >> 8) != LIBUSB_DT_STRING) | 423 if ((text[0] >> 8) != LIBUSB_DT_STRING) |
401 continue; | 424 continue; |
402 if ((text[0] & 255) > size) | 425 if ((text[0] & 255) > size) |
403 continue; | 426 continue; |
404 | 427 |
405 size = size / 2 - 1; | 428 size = size / 2 - 1; |
406 *serial = base::string16(text + 1, size); | 429 *serial = base::string16(text + 1, size); |
407 return true; | 430 return true; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 transfer.transfer_type = transfer_type; | 642 transfer.transfer_type = transfer_type; |
620 transfer.buffer = buffer; | 643 transfer.buffer = buffer; |
621 transfer.length = length; | 644 transfer.length = length; |
622 transfer.callback = callback; | 645 transfer.callback = callback; |
623 transfer.message_loop_proxy = message_loop_proxy; | 646 transfer.message_loop_proxy = message_loop_proxy; |
624 | 647 |
625 // It's OK for this method to return NULL. libusb_submit_transfer will fail if | 648 // It's OK for this method to return NULL. libusb_submit_transfer will fail if |
626 // it requires an interface we didn't claim. | 649 // it requires an interface we didn't claim. |
627 transfer.claimed_interface = GetClaimedInterfaceForEndpoint(handle->endpoint); | 650 transfer.claimed_interface = GetClaimedInterfaceForEndpoint(handle->endpoint); |
628 | 651 |
629 if (libusb_submit_transfer(handle) == LIBUSB_SUCCESS) { | 652 const int rv = libusb_submit_transfer(handle); |
| 653 if (rv == LIBUSB_SUCCESS) { |
630 transfers_[handle] = transfer; | 654 transfers_[handle] = transfer; |
631 } else { | 655 } else { |
| 656 LOG(ERROR) << "Failed to submit transfer: " << ConvertErrorToString(rv); |
632 message_loop_proxy->PostTask( | 657 message_loop_proxy->PostTask( |
633 FROM_HERE, | 658 FROM_HERE, |
634 base::Bind( | 659 base::Bind( |
635 callback, USB_TRANSFER_ERROR, make_scoped_refptr(buffer), 0)); | 660 callback, USB_TRANSFER_ERROR, make_scoped_refptr(buffer), 0)); |
636 } | 661 } |
637 } | 662 } |
638 | 663 |
639 void UsbDeviceHandleImpl::InternalClose() { | 664 void UsbDeviceHandleImpl::InternalClose() { |
640 DCHECK(thread_checker_.CalledOnValidThread()); | 665 DCHECK(thread_checker_.CalledOnValidThread()); |
641 if (!device_) | 666 if (!device_) |
642 return; | 667 return; |
643 | 668 |
644 // Cancel all the transfers. | 669 // Cancel all the transfers. |
645 for (TransferMap::iterator it = transfers_.begin(); it != transfers_.end(); | 670 for (TransferMap::iterator it = transfers_.begin(); it != transfers_.end(); |
646 ++it) { | 671 ++it) { |
647 // The callback will be called some time later. | 672 // The callback will be called some time later. |
648 libusb_cancel_transfer(it->first); | 673 libusb_cancel_transfer(it->first); |
649 } | 674 } |
650 | 675 |
651 // Attempt-release all the interfaces. | 676 // Attempt-release all the interfaces. |
652 // It will be retained until the transfer cancellation is finished. | 677 // It will be retained until the transfer cancellation is finished. |
653 claimed_interfaces_.clear(); | 678 claimed_interfaces_.clear(); |
654 | 679 |
655 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to | 680 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to |
656 // finish. | 681 // finish. |
657 device_ = NULL; | 682 device_ = NULL; |
658 } | 683 } |
659 | 684 |
660 } // namespace usb_service | 685 } // namespace usb_service |
OLD | NEW |