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 <memory> | 8 #include <memory> |
9 #include <numeric> | 9 #include <numeric> |
10 #include <utility> | 10 #include <utility> |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "third_party/libusb/src/libusb/libusb.h" | 28 #include "third_party/libusb/src/libusb/libusb.h" |
29 | 29 |
30 namespace device { | 30 namespace device { |
31 | 31 |
32 typedef libusb_device* PlatformUsbDevice; | 32 typedef libusb_device* PlatformUsbDevice; |
33 | 33 |
34 void HandleTransferCompletion(PlatformUsbTransferHandle transfer); | 34 void HandleTransferCompletion(PlatformUsbTransferHandle transfer); |
35 | 35 |
36 namespace { | 36 namespace { |
37 | 37 |
38 uint8_t ConvertTransferDirection(UsbEndpointDirection direction) { | 38 uint8_t ConvertTransferDirection(UsbTransferDirection direction) { |
39 switch (direction) { | 39 switch (direction) { |
40 case USB_DIRECTION_INBOUND: | 40 case UsbTransferDirection::INBOUND: |
41 return LIBUSB_ENDPOINT_IN; | 41 return LIBUSB_ENDPOINT_IN; |
42 case USB_DIRECTION_OUTBOUND: | 42 case UsbTransferDirection::OUTBOUND: |
43 return LIBUSB_ENDPOINT_OUT; | 43 return LIBUSB_ENDPOINT_OUT; |
44 default: | |
45 NOTREACHED(); | |
46 return LIBUSB_ENDPOINT_IN; | |
47 } | 44 } |
| 45 NOTREACHED(); |
| 46 return 0; |
48 } | 47 } |
49 | 48 |
50 uint8_t CreateRequestType(UsbEndpointDirection direction, | 49 uint8_t CreateRequestType(UsbTransferDirection direction, |
51 UsbDeviceHandle::TransferRequestType request_type, | 50 UsbControlTransferType request_type, |
52 UsbDeviceHandle::TransferRecipient recipient) { | 51 UsbControlTransferRecipient recipient) { |
53 uint8_t result = ConvertTransferDirection(direction); | 52 uint8_t result = ConvertTransferDirection(direction); |
54 | 53 |
55 switch (request_type) { | 54 switch (request_type) { |
56 case UsbDeviceHandle::STANDARD: | 55 case UsbControlTransferType::STANDARD: |
57 result |= LIBUSB_REQUEST_TYPE_STANDARD; | 56 result |= LIBUSB_REQUEST_TYPE_STANDARD; |
58 break; | 57 break; |
59 case UsbDeviceHandle::CLASS: | 58 case UsbControlTransferType::CLASS: |
60 result |= LIBUSB_REQUEST_TYPE_CLASS; | 59 result |= LIBUSB_REQUEST_TYPE_CLASS; |
61 break; | 60 break; |
62 case UsbDeviceHandle::VENDOR: | 61 case UsbControlTransferType::VENDOR: |
63 result |= LIBUSB_REQUEST_TYPE_VENDOR; | 62 result |= LIBUSB_REQUEST_TYPE_VENDOR; |
64 break; | 63 break; |
65 case UsbDeviceHandle::RESERVED: | 64 case UsbControlTransferType::RESERVED: |
66 result |= LIBUSB_REQUEST_TYPE_RESERVED; | 65 result |= LIBUSB_REQUEST_TYPE_RESERVED; |
67 break; | 66 break; |
68 } | 67 } |
69 | 68 |
70 switch (recipient) { | 69 switch (recipient) { |
71 case UsbDeviceHandle::DEVICE: | 70 case UsbControlTransferRecipient::DEVICE: |
72 result |= LIBUSB_RECIPIENT_DEVICE; | 71 result |= LIBUSB_RECIPIENT_DEVICE; |
73 break; | 72 break; |
74 case UsbDeviceHandle::INTERFACE: | 73 case UsbControlTransferRecipient::INTERFACE: |
75 result |= LIBUSB_RECIPIENT_INTERFACE; | 74 result |= LIBUSB_RECIPIENT_INTERFACE; |
76 break; | 75 break; |
77 case UsbDeviceHandle::ENDPOINT: | 76 case UsbControlTransferRecipient::ENDPOINT: |
78 result |= LIBUSB_RECIPIENT_ENDPOINT; | 77 result |= LIBUSB_RECIPIENT_ENDPOINT; |
79 break; | 78 break; |
80 case UsbDeviceHandle::OTHER: | 79 case UsbControlTransferRecipient::OTHER: |
81 result |= LIBUSB_RECIPIENT_OTHER; | 80 result |= LIBUSB_RECIPIENT_OTHER; |
82 break; | 81 break; |
83 } | 82 } |
84 | 83 |
85 return result; | 84 return result; |
86 } | 85 } |
87 | 86 |
88 static UsbTransferStatus ConvertTransferStatus( | 87 static UsbTransferStatus ConvertTransferStatus( |
89 const libusb_transfer_status status) { | 88 const libusb_transfer_status status) { |
90 switch (status) { | 89 switch (status) { |
91 case LIBUSB_TRANSFER_COMPLETED: | 90 case LIBUSB_TRANSFER_COMPLETED: |
92 return USB_TRANSFER_COMPLETED; | 91 return UsbTransferStatus::COMPLETED; |
93 case LIBUSB_TRANSFER_ERROR: | 92 case LIBUSB_TRANSFER_ERROR: |
94 return USB_TRANSFER_ERROR; | 93 return UsbTransferStatus::TRANSFER_ERROR; |
95 case LIBUSB_TRANSFER_TIMED_OUT: | 94 case LIBUSB_TRANSFER_TIMED_OUT: |
96 return USB_TRANSFER_TIMEOUT; | 95 return UsbTransferStatus::TIMEOUT; |
97 case LIBUSB_TRANSFER_STALL: | 96 case LIBUSB_TRANSFER_STALL: |
98 return USB_TRANSFER_STALLED; | 97 return UsbTransferStatus::STALLED; |
99 case LIBUSB_TRANSFER_NO_DEVICE: | 98 case LIBUSB_TRANSFER_NO_DEVICE: |
100 return USB_TRANSFER_DISCONNECT; | 99 return UsbTransferStatus::DISCONNECT; |
101 case LIBUSB_TRANSFER_OVERFLOW: | 100 case LIBUSB_TRANSFER_OVERFLOW: |
102 return USB_TRANSFER_OVERFLOW; | 101 return UsbTransferStatus::BABBLE; |
103 case LIBUSB_TRANSFER_CANCELLED: | 102 case LIBUSB_TRANSFER_CANCELLED: |
104 return USB_TRANSFER_CANCELLED; | 103 return UsbTransferStatus::CANCELLED; |
105 default: | |
106 NOTREACHED(); | |
107 return USB_TRANSFER_ERROR; | |
108 } | 104 } |
| 105 NOTREACHED(); |
| 106 return UsbTransferStatus::TRANSFER_ERROR; |
109 } | 107 } |
110 | 108 |
111 static void RunTransferCallback( | 109 static void RunTransferCallback( |
112 scoped_refptr<base::TaskRunner> callback_task_runner, | 110 scoped_refptr<base::TaskRunner> callback_task_runner, |
113 const UsbDeviceHandle::TransferCallback& callback, | 111 const UsbDeviceHandle::TransferCallback& callback, |
114 UsbTransferStatus status, | 112 UsbTransferStatus status, |
115 scoped_refptr<net::IOBuffer> buffer, | 113 scoped_refptr<net::IOBuffer> buffer, |
116 size_t result) { | 114 size_t result) { |
117 if (callback_task_runner->RunsTasksOnCurrentThread()) { | 115 if (callback_task_runner->RunsTasksOnCurrentThread()) { |
118 callback.Run(status, buffer, result); | 116 callback.Run(status, buffer, result); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 uint8_t type, | 289 uint8_t type, |
292 uint8_t request, | 290 uint8_t request, |
293 uint16_t value, | 291 uint16_t value, |
294 uint16_t index, | 292 uint16_t index, |
295 uint16_t length, | 293 uint16_t length, |
296 scoped_refptr<net::IOBuffer> buffer, | 294 scoped_refptr<net::IOBuffer> buffer, |
297 unsigned int timeout, | 295 unsigned int timeout, |
298 scoped_refptr<base::TaskRunner> callback_task_runner, | 296 scoped_refptr<base::TaskRunner> callback_task_runner, |
299 const TransferCallback& callback) { | 297 const TransferCallback& callback) { |
300 std::unique_ptr<Transfer> transfer(new Transfer( | 298 std::unique_ptr<Transfer> transfer(new Transfer( |
301 device_handle, nullptr, USB_TRANSFER_CONTROL, buffer, | 299 device_handle, nullptr, UsbTransferType::CONTROL, buffer, |
302 length + LIBUSB_CONTROL_SETUP_SIZE, callback_task_runner, callback)); | 300 length + LIBUSB_CONTROL_SETUP_SIZE, callback_task_runner, callback)); |
303 | 301 |
304 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 302 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
305 if (!transfer->platform_transfer_) { | 303 if (!transfer->platform_transfer_) { |
306 USB_LOG(ERROR) << "Failed to allocate control transfer."; | 304 USB_LOG(ERROR) << "Failed to allocate control transfer."; |
307 return nullptr; | 305 return nullptr; |
308 } | 306 } |
309 | 307 |
310 libusb_fill_control_setup(reinterpret_cast<uint8_t*>(buffer->data()), type, | 308 libusb_fill_control_setup(reinterpret_cast<uint8_t*>(buffer->data()), type, |
311 request, value, index, length); | 309 request, value, index, length); |
(...skipping 11 matching lines...) Expand all Loading... |
323 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( | 321 UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( |
324 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 322 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
325 uint8_t endpoint, | 323 uint8_t endpoint, |
326 scoped_refptr<net::IOBuffer> buffer, | 324 scoped_refptr<net::IOBuffer> buffer, |
327 int length, | 325 int length, |
328 unsigned int timeout, | 326 unsigned int timeout, |
329 scoped_refptr<base::TaskRunner> callback_task_runner, | 327 scoped_refptr<base::TaskRunner> callback_task_runner, |
330 const TransferCallback& callback) { | 328 const TransferCallback& callback) { |
331 std::unique_ptr<Transfer> transfer(new Transfer( | 329 std::unique_ptr<Transfer> transfer(new Transfer( |
332 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), | 330 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
333 USB_TRANSFER_BULK, buffer, length, callback_task_runner, callback)); | 331 UsbTransferType::BULK, buffer, length, callback_task_runner, callback)); |
334 | 332 |
335 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 333 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
336 if (!transfer->platform_transfer_) { | 334 if (!transfer->platform_transfer_) { |
337 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; | 335 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; |
338 return nullptr; | 336 return nullptr; |
339 } | 337 } |
340 | 338 |
341 libusb_fill_bulk_transfer(transfer->platform_transfer_, | 339 libusb_fill_bulk_transfer(transfer->platform_transfer_, |
342 device_handle->handle_, endpoint, | 340 device_handle->handle_, endpoint, |
343 reinterpret_cast<uint8_t*>(buffer->data()), length, | 341 reinterpret_cast<uint8_t*>(buffer->data()), length, |
344 &UsbDeviceHandleImpl::Transfer::PlatformCallback, | 342 &UsbDeviceHandleImpl::Transfer::PlatformCallback, |
345 transfer.get(), timeout); | 343 transfer.get(), timeout); |
346 | 344 |
347 return transfer; | 345 return transfer; |
348 } | 346 } |
349 | 347 |
350 // static | 348 // static |
351 std::unique_ptr<UsbDeviceHandleImpl::Transfer> | 349 std::unique_ptr<UsbDeviceHandleImpl::Transfer> |
352 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( | 350 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( |
353 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 351 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
354 uint8_t endpoint, | 352 uint8_t endpoint, |
355 scoped_refptr<net::IOBuffer> buffer, | 353 scoped_refptr<net::IOBuffer> buffer, |
356 int length, | 354 int length, |
357 unsigned int timeout, | 355 unsigned int timeout, |
358 scoped_refptr<base::TaskRunner> callback_task_runner, | 356 scoped_refptr<base::TaskRunner> callback_task_runner, |
359 const TransferCallback& callback) { | 357 const TransferCallback& callback) { |
360 std::unique_ptr<Transfer> transfer(new Transfer( | 358 std::unique_ptr<Transfer> transfer(new Transfer( |
361 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), | 359 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
362 USB_TRANSFER_INTERRUPT, buffer, length, callback_task_runner, callback)); | 360 UsbTransferType::INTERRUPT, buffer, length, callback_task_runner, |
| 361 callback)); |
363 | 362 |
364 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 363 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
365 if (!transfer->platform_transfer_) { | 364 if (!transfer->platform_transfer_) { |
366 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; | 365 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; |
367 return nullptr; | 366 return nullptr; |
368 } | 367 } |
369 | 368 |
370 libusb_fill_interrupt_transfer( | 369 libusb_fill_interrupt_transfer( |
371 transfer->platform_transfer_, device_handle->handle_, endpoint, | 370 transfer->platform_transfer_, device_handle->handle_, endpoint, |
372 reinterpret_cast<uint8_t*>(buffer->data()), length, | 371 reinterpret_cast<uint8_t*>(buffer->data()), length, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 callback_(callback) { | 425 callback_(callback) { |
427 task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 426 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
428 } | 427 } |
429 | 428 |
430 UsbDeviceHandleImpl::Transfer::Transfer( | 429 UsbDeviceHandleImpl::Transfer::Transfer( |
431 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 430 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
432 scoped_refptr<InterfaceClaimer> claimed_interface, | 431 scoped_refptr<InterfaceClaimer> claimed_interface, |
433 scoped_refptr<net::IOBuffer> buffer, | 432 scoped_refptr<net::IOBuffer> buffer, |
434 scoped_refptr<base::TaskRunner> callback_task_runner, | 433 scoped_refptr<base::TaskRunner> callback_task_runner, |
435 const IsochronousTransferCallback& callback) | 434 const IsochronousTransferCallback& callback) |
436 : transfer_type_(USB_TRANSFER_ISOCHRONOUS), | 435 : transfer_type_(UsbTransferType::ISOCHRONOUS), |
437 device_handle_(device_handle), | 436 device_handle_(device_handle), |
438 buffer_(buffer), | 437 buffer_(buffer), |
439 claimed_interface_(claimed_interface), | 438 claimed_interface_(claimed_interface), |
440 callback_task_runner_(callback_task_runner), | 439 callback_task_runner_(callback_task_runner), |
441 iso_callback_(callback) { | 440 iso_callback_(callback) { |
442 task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 441 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
443 } | 442 } |
444 | 443 |
445 UsbDeviceHandleImpl::Transfer::~Transfer() { | 444 UsbDeviceHandleImpl::Transfer::~Transfer() { |
446 if (platform_transfer_) { | 445 if (platform_transfer_) { |
447 libusb_free_transfer(platform_transfer_); | 446 libusb_free_transfer(platform_transfer_); |
448 } | 447 } |
449 } | 448 } |
450 | 449 |
451 void UsbDeviceHandleImpl::Transfer::Submit() { | 450 void UsbDeviceHandleImpl::Transfer::Submit() { |
452 const int rv = libusb_submit_transfer(platform_transfer_); | 451 const int rv = libusb_submit_transfer(platform_transfer_); |
453 if (rv != LIBUSB_SUCCESS) { | 452 if (rv != LIBUSB_SUCCESS) { |
454 USB_LOG(EVENT) << "Failed to submit transfer: " | 453 USB_LOG(EVENT) << "Failed to submit transfer: " |
455 << ConvertPlatformUsbErrorToString(rv); | 454 << ConvertPlatformUsbErrorToString(rv); |
456 TransferComplete(USB_TRANSFER_ERROR, 0); | 455 TransferComplete(UsbTransferStatus::TRANSFER_ERROR, 0); |
457 } | 456 } |
458 } | 457 } |
459 | 458 |
460 void UsbDeviceHandleImpl::Transfer::Cancel() { | 459 void UsbDeviceHandleImpl::Transfer::Cancel() { |
461 if (!cancelled_) { | 460 if (!cancelled_) { |
462 libusb_cancel_transfer(platform_transfer_); | 461 libusb_cancel_transfer(platform_transfer_); |
463 claimed_interface_ = nullptr; | 462 claimed_interface_ = nullptr; |
464 } | 463 } |
465 cancelled_ = true; | 464 cancelled_ = true; |
466 } | 465 } |
467 | 466 |
468 void UsbDeviceHandleImpl::Transfer::ProcessCompletion() { | 467 void UsbDeviceHandleImpl::Transfer::ProcessCompletion() { |
469 DCHECK_GE(platform_transfer_->actual_length, 0) | 468 DCHECK_GE(platform_transfer_->actual_length, 0) |
470 << "Negative actual length received"; | 469 << "Negative actual length received"; |
471 size_t actual_length = | 470 size_t actual_length = |
472 static_cast<size_t>(std::max(platform_transfer_->actual_length, 0)); | 471 static_cast<size_t>(std::max(platform_transfer_->actual_length, 0)); |
473 | 472 |
474 DCHECK(length_ >= actual_length) | 473 DCHECK(length_ >= actual_length) |
475 << "data too big for our buffer (libusb failure?)"; | 474 << "data too big for our buffer (libusb failure?)"; |
476 | 475 |
477 switch (transfer_type_) { | 476 switch (transfer_type_) { |
478 case USB_TRANSFER_CONTROL: | 477 case UsbTransferType::CONTROL: |
479 // If the transfer is a control transfer we do not expose the control | 478 // If the transfer is a control transfer we do not expose the control |
480 // setup header to the caller. This logic strips off the header if | 479 // setup header to the caller. This logic strips off the header if |
481 // present before invoking the callback provided with the transfer. | 480 // present before invoking the callback provided with the transfer. |
482 if (actual_length > 0) { | 481 if (actual_length > 0) { |
483 CHECK(length_ >= LIBUSB_CONTROL_SETUP_SIZE) | 482 CHECK(length_ >= LIBUSB_CONTROL_SETUP_SIZE) |
484 << "buffer was not correctly set: too small for the control header"; | 483 << "buffer was not correctly set: too small for the control header"; |
485 | 484 |
486 if (length_ >= (LIBUSB_CONTROL_SETUP_SIZE + actual_length)) { | 485 if (length_ >= (LIBUSB_CONTROL_SETUP_SIZE + actual_length)) { |
487 // If the payload is zero bytes long, pad out the allocated buffer | 486 // If the payload is zero bytes long, pad out the allocated buffer |
488 // size to one byte so that an IOBuffer of that size can be allocated. | 487 // size to one byte so that an IOBuffer of that size can be allocated. |
489 scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer( | 488 scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer( |
490 std::max(actual_length, static_cast<size_t>(1))); | 489 std::max(actual_length, static_cast<size_t>(1))); |
491 memcpy(resized_buffer->data(), | 490 memcpy(resized_buffer->data(), |
492 buffer_->data() + LIBUSB_CONTROL_SETUP_SIZE, actual_length); | 491 buffer_->data() + LIBUSB_CONTROL_SETUP_SIZE, actual_length); |
493 buffer_ = resized_buffer; | 492 buffer_ = resized_buffer; |
494 } | 493 } |
495 } | 494 } |
496 // Fall through! | 495 // Fall through! |
497 | 496 |
498 case USB_TRANSFER_BULK: | 497 case UsbTransferType::BULK: |
499 case USB_TRANSFER_INTERRUPT: | 498 case UsbTransferType::INTERRUPT: |
500 TransferComplete(ConvertTransferStatus(platform_transfer_->status), | 499 TransferComplete(ConvertTransferStatus(platform_transfer_->status), |
501 actual_length); | 500 actual_length); |
502 break; | 501 break; |
503 | 502 |
504 case USB_TRANSFER_ISOCHRONOUS: | 503 case UsbTransferType::ISOCHRONOUS: |
505 IsochronousTransferComplete(); | 504 IsochronousTransferComplete(); |
506 break; | 505 break; |
507 | 506 |
508 default: | 507 default: |
509 NOTREACHED() << "Invalid usb transfer type"; | 508 NOTREACHED() << "Invalid usb transfer type"; |
510 break; | 509 break; |
511 } | 510 } |
512 } | 511 } |
513 | 512 |
514 /* static */ | 513 /* static */ |
515 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback( | 514 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback( |
516 PlatformUsbTransferHandle platform_transfer) { | 515 PlatformUsbTransferHandle platform_transfer) { |
517 Transfer* transfer = | 516 Transfer* transfer = |
518 reinterpret_cast<Transfer*>(platform_transfer->user_data); | 517 reinterpret_cast<Transfer*>(platform_transfer->user_data); |
519 DCHECK(transfer->platform_transfer_ == platform_transfer); | 518 DCHECK(transfer->platform_transfer_ == platform_transfer); |
520 transfer->ProcessCompletion(); | 519 transfer->ProcessCompletion(); |
521 } | 520 } |
522 | 521 |
523 void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status, | 522 void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status, |
524 size_t bytes_transferred) { | 523 size_t bytes_transferred) { |
525 base::Closure closure; | 524 base::Closure closure; |
526 if (transfer_type_ == USB_TRANSFER_ISOCHRONOUS) { | 525 if (transfer_type_ == UsbTransferType::ISOCHRONOUS) { |
527 DCHECK_NE(LIBUSB_TRANSFER_COMPLETED, platform_transfer_->status); | 526 DCHECK_NE(LIBUSB_TRANSFER_COMPLETED, platform_transfer_->status); |
528 std::vector<IsochronousPacket> packets(platform_transfer_->num_iso_packets); | 527 std::vector<IsochronousPacket> packets(platform_transfer_->num_iso_packets); |
529 for (size_t i = 0; i < packets.size(); ++i) { | 528 for (size_t i = 0; i < packets.size(); ++i) { |
530 packets[i].length = platform_transfer_->iso_packet_desc[i].length; | 529 packets[i].length = platform_transfer_->iso_packet_desc[i].length; |
531 packets[i].transferred_length = 0; | 530 packets[i].transferred_length = 0; |
532 packets[i].status = status; | 531 packets[i].status = status; |
533 } | 532 } |
534 closure = base::Bind(iso_callback_, buffer_, packets); | 533 closure = base::Bind(iso_callback_, buffer_, packets); |
535 } else { | 534 } else { |
536 closure = base::Bind(callback_, status, buffer_, bytes_transferred); | 535 closure = base::Bind(callback_, status, buffer_, bytes_transferred); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 if (transfer->claimed_interface() == interface_claimer) { | 689 if (transfer->claimed_interface() == interface_claimer) { |
691 transfer->Cancel(); | 690 transfer->Cancel(); |
692 } | 691 } |
693 } | 692 } |
694 | 693 |
695 blocking_task_runner_->PostTask( | 694 blocking_task_runner_->PostTask( |
696 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ClearHaltOnBlockingThread, | 695 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ClearHaltOnBlockingThread, |
697 this, endpoint, callback)); | 696 this, endpoint, callback)); |
698 } | 697 } |
699 | 698 |
700 void UsbDeviceHandleImpl::ControlTransfer(UsbEndpointDirection direction, | 699 void UsbDeviceHandleImpl::ControlTransfer(UsbTransferDirection direction, |
701 TransferRequestType request_type, | 700 UsbControlTransferType request_type, |
702 TransferRecipient recipient, | 701 UsbControlTransferRecipient recipient, |
703 uint8_t request, | 702 uint8_t request, |
704 uint16_t value, | 703 uint16_t value, |
705 uint16_t index, | 704 uint16_t index, |
706 scoped_refptr<net::IOBuffer> buffer, | 705 scoped_refptr<net::IOBuffer> buffer, |
707 size_t length, | 706 size_t length, |
708 unsigned int timeout, | 707 unsigned int timeout, |
709 const TransferCallback& callback) { | 708 const TransferCallback& callback) { |
710 if (task_runner_->BelongsToCurrentThread()) { | 709 if (task_runner_->BelongsToCurrentThread()) { |
711 ControlTransferInternal(direction, request_type, recipient, request, value, | 710 ControlTransferInternal(direction, request_type, recipient, request, value, |
712 index, buffer, length, timeout, task_runner_, | 711 index, buffer, length, timeout, task_runner_, |
713 callback); | 712 callback); |
714 } else { | 713 } else { |
715 task_runner_->PostTask( | 714 task_runner_->PostTask( |
716 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ControlTransferInternal, | 715 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ControlTransferInternal, |
717 this, direction, request_type, recipient, request, | 716 this, direction, request_type, recipient, request, |
718 value, index, buffer, length, timeout, | 717 value, index, buffer, length, timeout, |
719 base::ThreadTaskRunnerHandle::Get(), callback)); | 718 base::ThreadTaskRunnerHandle::Get(), callback)); |
720 } | 719 } |
721 } | 720 } |
722 | 721 |
723 void UsbDeviceHandleImpl::IsochronousTransferIn( | 722 void UsbDeviceHandleImpl::IsochronousTransferIn( |
724 uint8_t endpoint_number, | 723 uint8_t endpoint_number, |
725 const std::vector<uint32_t>& packet_lengths, | 724 const std::vector<uint32_t>& packet_lengths, |
726 unsigned int timeout, | 725 unsigned int timeout, |
727 const IsochronousTransferCallback& callback) { | 726 const IsochronousTransferCallback& callback) { |
728 uint8_t endpoint_address = | 727 uint8_t endpoint_address = |
729 ConvertTransferDirection(USB_DIRECTION_INBOUND) | endpoint_number; | 728 ConvertTransferDirection(UsbTransferDirection::INBOUND) | endpoint_number; |
730 if (task_runner_->BelongsToCurrentThread()) { | 729 if (task_runner_->BelongsToCurrentThread()) { |
731 IsochronousTransferInInternal(endpoint_address, packet_lengths, timeout, | 730 IsochronousTransferInInternal(endpoint_address, packet_lengths, timeout, |
732 task_runner_, callback); | 731 task_runner_, callback); |
733 } else { | 732 } else { |
734 task_runner_->PostTask( | 733 task_runner_->PostTask( |
735 FROM_HERE, | 734 FROM_HERE, |
736 base::Bind(&UsbDeviceHandleImpl::IsochronousTransferInInternal, this, | 735 base::Bind(&UsbDeviceHandleImpl::IsochronousTransferInInternal, this, |
737 endpoint_address, packet_lengths, timeout, | 736 endpoint_address, packet_lengths, timeout, |
738 base::ThreadTaskRunnerHandle::Get(), callback)); | 737 base::ThreadTaskRunnerHandle::Get(), callback)); |
739 } | 738 } |
740 } | 739 } |
741 | 740 |
742 void UsbDeviceHandleImpl::IsochronousTransferOut( | 741 void UsbDeviceHandleImpl::IsochronousTransferOut( |
743 uint8_t endpoint_number, | 742 uint8_t endpoint_number, |
744 scoped_refptr<net::IOBuffer> buffer, | 743 scoped_refptr<net::IOBuffer> buffer, |
745 const std::vector<uint32_t>& packet_lengths, | 744 const std::vector<uint32_t>& packet_lengths, |
746 unsigned int timeout, | 745 unsigned int timeout, |
747 const IsochronousTransferCallback& callback) { | 746 const IsochronousTransferCallback& callback) { |
748 uint8_t endpoint_address = | 747 uint8_t endpoint_address = |
749 ConvertTransferDirection(USB_DIRECTION_OUTBOUND) | endpoint_number; | 748 ConvertTransferDirection(UsbTransferDirection::OUTBOUND) | |
| 749 endpoint_number; |
750 if (task_runner_->BelongsToCurrentThread()) { | 750 if (task_runner_->BelongsToCurrentThread()) { |
751 IsochronousTransferOutInternal(endpoint_address, buffer, packet_lengths, | 751 IsochronousTransferOutInternal(endpoint_address, buffer, packet_lengths, |
752 timeout, task_runner_, callback); | 752 timeout, task_runner_, callback); |
753 } else { | 753 } else { |
754 task_runner_->PostTask( | 754 task_runner_->PostTask( |
755 FROM_HERE, | 755 FROM_HERE, |
756 base::Bind(&UsbDeviceHandleImpl::IsochronousTransferOutInternal, this, | 756 base::Bind(&UsbDeviceHandleImpl::IsochronousTransferOutInternal, this, |
757 endpoint_address, buffer, packet_lengths, timeout, | 757 endpoint_address, buffer, packet_lengths, timeout, |
758 base::ThreadTaskRunnerHandle::Get(), callback)); | 758 base::ThreadTaskRunnerHandle::Get(), callback)); |
759 } | 759 } |
760 } | 760 } |
761 | 761 |
762 void UsbDeviceHandleImpl::GenericTransfer(UsbEndpointDirection direction, | 762 void UsbDeviceHandleImpl::GenericTransfer(UsbTransferDirection direction, |
763 uint8_t endpoint_number, | 763 uint8_t endpoint_number, |
764 scoped_refptr<net::IOBuffer> buffer, | 764 scoped_refptr<net::IOBuffer> buffer, |
765 size_t length, | 765 size_t length, |
766 unsigned int timeout, | 766 unsigned int timeout, |
767 const TransferCallback& callback) { | 767 const TransferCallback& callback) { |
768 uint8_t endpoint_address = | 768 uint8_t endpoint_address = |
769 ConvertTransferDirection(direction) | endpoint_number; | 769 ConvertTransferDirection(direction) | endpoint_number; |
770 if (task_runner_->BelongsToCurrentThread()) { | 770 if (task_runner_->BelongsToCurrentThread()) { |
771 GenericTransferInternal(endpoint_address, buffer, length, timeout, | 771 GenericTransferInternal(endpoint_address, buffer, length, timeout, |
772 task_runner_, callback); | 772 task_runner_, callback); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 | 962 |
963 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> | 963 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> |
964 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(uint8_t endpoint) { | 964 UsbDeviceHandleImpl::GetClaimedInterfaceForEndpoint(uint8_t endpoint) { |
965 const auto endpoint_it = endpoint_map_.find(endpoint); | 965 const auto endpoint_it = endpoint_map_.find(endpoint); |
966 if (endpoint_it != endpoint_map_.end()) | 966 if (endpoint_it != endpoint_map_.end()) |
967 return claimed_interfaces_[endpoint_it->second.interface->interface_number]; | 967 return claimed_interfaces_[endpoint_it->second.interface->interface_number]; |
968 return nullptr; | 968 return nullptr; |
969 } | 969 } |
970 | 970 |
971 void UsbDeviceHandleImpl::ControlTransferInternal( | 971 void UsbDeviceHandleImpl::ControlTransferInternal( |
972 UsbEndpointDirection direction, | 972 UsbTransferDirection direction, |
973 TransferRequestType request_type, | 973 UsbControlTransferType request_type, |
974 TransferRecipient recipient, | 974 UsbControlTransferRecipient recipient, |
975 uint8_t request, | 975 uint8_t request, |
976 uint16_t value, | 976 uint16_t value, |
977 uint16_t index, | 977 uint16_t index, |
978 scoped_refptr<net::IOBuffer> buffer, | 978 scoped_refptr<net::IOBuffer> buffer, |
979 size_t length, | 979 size_t length, |
980 unsigned int timeout, | 980 unsigned int timeout, |
981 scoped_refptr<base::TaskRunner> callback_task_runner, | 981 scoped_refptr<base::TaskRunner> callback_task_runner, |
982 const TransferCallback& callback) { | 982 const TransferCallback& callback) { |
983 DCHECK(thread_checker_.CalledOnValidThread()); | 983 DCHECK(thread_checker_.CalledOnValidThread()); |
984 | 984 |
985 if (!device_) { | 985 if (!device_) { |
986 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT, | 986 RunTransferCallback(callback_task_runner, callback, |
987 buffer, 0); | 987 UsbTransferStatus::DISCONNECT, buffer, 0); |
988 return; | 988 return; |
989 } | 989 } |
990 | 990 |
991 if (!base::IsValueInRangeForNumericType<uint16_t>(length)) { | 991 if (!base::IsValueInRangeForNumericType<uint16_t>(length)) { |
992 USB_LOG(USER) << "Transfer too long."; | 992 USB_LOG(USER) << "Transfer too long."; |
993 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 993 RunTransferCallback(callback_task_runner, callback, |
994 buffer, 0); | 994 UsbTransferStatus::TRANSFER_ERROR, buffer, 0); |
995 return; | 995 return; |
996 } | 996 } |
997 | 997 |
998 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; | 998 const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; |
999 scoped_refptr<net::IOBuffer> resized_buffer = | 999 scoped_refptr<net::IOBuffer> resized_buffer = |
1000 new net::IOBufferWithSize(resized_length); | 1000 new net::IOBufferWithSize(resized_length); |
1001 if (!resized_buffer.get()) { | 1001 if (!resized_buffer.get()) { |
1002 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 1002 RunTransferCallback(callback_task_runner, callback, |
1003 buffer, 0); | 1003 UsbTransferStatus::TRANSFER_ERROR, buffer, 0); |
1004 return; | 1004 return; |
1005 } | 1005 } |
1006 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), | 1006 memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), |
1007 length); | 1007 length); |
1008 | 1008 |
1009 std::unique_ptr<Transfer> transfer = Transfer::CreateControlTransfer( | 1009 std::unique_ptr<Transfer> transfer = Transfer::CreateControlTransfer( |
1010 this, CreateRequestType(direction, request_type, recipient), request, | 1010 this, CreateRequestType(direction, request_type, recipient), request, |
1011 value, index, static_cast<uint16_t>(length), resized_buffer, timeout, | 1011 value, index, static_cast<uint16_t>(length), resized_buffer, timeout, |
1012 callback_task_runner, callback); | 1012 callback_task_runner, callback); |
1013 if (!transfer) { | 1013 if (!transfer) { |
1014 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 1014 RunTransferCallback(callback_task_runner, callback, |
1015 buffer, 0); | 1015 UsbTransferStatus::TRANSFER_ERROR, buffer, 0); |
1016 return; | 1016 return; |
1017 } | 1017 } |
1018 | 1018 |
1019 SubmitTransfer(std::move(transfer)); | 1019 SubmitTransfer(std::move(transfer)); |
1020 } | 1020 } |
1021 | 1021 |
1022 void UsbDeviceHandleImpl::IsochronousTransferInInternal( | 1022 void UsbDeviceHandleImpl::IsochronousTransferInInternal( |
1023 uint8_t endpoint_address, | 1023 uint8_t endpoint_address, |
1024 const std::vector<uint32_t>& packet_lengths, | 1024 const std::vector<uint32_t>& packet_lengths, |
1025 unsigned int timeout, | 1025 unsigned int timeout, |
1026 scoped_refptr<base::TaskRunner> callback_task_runner, | 1026 scoped_refptr<base::TaskRunner> callback_task_runner, |
1027 const IsochronousTransferCallback& callback) { | 1027 const IsochronousTransferCallback& callback) { |
1028 DCHECK(thread_checker_.CalledOnValidThread()); | 1028 DCHECK(thread_checker_.CalledOnValidThread()); |
1029 | 1029 |
1030 if (!device_) { | 1030 if (!device_) { |
1031 ReportIsochronousTransferError(callback_task_runner, callback, | 1031 ReportIsochronousTransferError(callback_task_runner, callback, |
1032 packet_lengths, USB_TRANSFER_DISCONNECT); | 1032 packet_lengths, |
| 1033 UsbTransferStatus::DISCONNECT); |
1033 return; | 1034 return; |
1034 } | 1035 } |
1035 | 1036 |
1036 size_t length = | 1037 size_t length = |
1037 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); | 1038 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); |
1038 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(length)); | 1039 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(length)); |
1039 std::unique_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( | 1040 std::unique_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( |
1040 this, endpoint_address, buffer, length, packet_lengths, timeout, | 1041 this, endpoint_address, buffer, length, packet_lengths, timeout, |
1041 callback_task_runner, callback); | 1042 callback_task_runner, callback); |
1042 | 1043 |
1043 SubmitTransfer(std::move(transfer)); | 1044 SubmitTransfer(std::move(transfer)); |
1044 } | 1045 } |
1045 | 1046 |
1046 void UsbDeviceHandleImpl::IsochronousTransferOutInternal( | 1047 void UsbDeviceHandleImpl::IsochronousTransferOutInternal( |
1047 uint8_t endpoint_address, | 1048 uint8_t endpoint_address, |
1048 scoped_refptr<net::IOBuffer> buffer, | 1049 scoped_refptr<net::IOBuffer> buffer, |
1049 const std::vector<uint32_t>& packet_lengths, | 1050 const std::vector<uint32_t>& packet_lengths, |
1050 unsigned int timeout, | 1051 unsigned int timeout, |
1051 scoped_refptr<base::TaskRunner> callback_task_runner, | 1052 scoped_refptr<base::TaskRunner> callback_task_runner, |
1052 const IsochronousTransferCallback& callback) { | 1053 const IsochronousTransferCallback& callback) { |
1053 DCHECK(thread_checker_.CalledOnValidThread()); | 1054 DCHECK(thread_checker_.CalledOnValidThread()); |
1054 | 1055 |
1055 if (!device_) { | 1056 if (!device_) { |
1056 ReportIsochronousTransferError(callback_task_runner, callback, | 1057 ReportIsochronousTransferError(callback_task_runner, callback, |
1057 packet_lengths, USB_TRANSFER_DISCONNECT); | 1058 packet_lengths, |
| 1059 UsbTransferStatus::DISCONNECT); |
1058 return; | 1060 return; |
1059 } | 1061 } |
1060 | 1062 |
1061 size_t length = | 1063 size_t length = |
1062 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); | 1064 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); |
1063 std::unique_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( | 1065 std::unique_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( |
1064 this, endpoint_address, buffer, length, packet_lengths, timeout, | 1066 this, endpoint_address, buffer, length, packet_lengths, timeout, |
1065 callback_task_runner, callback); | 1067 callback_task_runner, callback); |
1066 | 1068 |
1067 SubmitTransfer(std::move(transfer)); | 1069 SubmitTransfer(std::move(transfer)); |
1068 } | 1070 } |
1069 | 1071 |
1070 void UsbDeviceHandleImpl::GenericTransferInternal( | 1072 void UsbDeviceHandleImpl::GenericTransferInternal( |
1071 uint8_t endpoint_address, | 1073 uint8_t endpoint_address, |
1072 scoped_refptr<net::IOBuffer> buffer, | 1074 scoped_refptr<net::IOBuffer> buffer, |
1073 size_t length, | 1075 size_t length, |
1074 unsigned int timeout, | 1076 unsigned int timeout, |
1075 scoped_refptr<base::TaskRunner> callback_task_runner, | 1077 scoped_refptr<base::TaskRunner> callback_task_runner, |
1076 const TransferCallback& callback) { | 1078 const TransferCallback& callback) { |
1077 DCHECK(thread_checker_.CalledOnValidThread()); | 1079 DCHECK(thread_checker_.CalledOnValidThread()); |
1078 | 1080 |
1079 if (!device_) { | 1081 if (!device_) { |
1080 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT, | 1082 RunTransferCallback(callback_task_runner, callback, |
1081 buffer, 0); | 1083 UsbTransferStatus::DISCONNECT, buffer, 0); |
1082 return; | 1084 return; |
1083 } | 1085 } |
1084 | 1086 |
1085 const auto endpoint_it = endpoint_map_.find(endpoint_address); | 1087 const auto endpoint_it = endpoint_map_.find(endpoint_address); |
1086 if (endpoint_it == endpoint_map_.end()) { | 1088 if (endpoint_it == endpoint_map_.end()) { |
1087 USB_LOG(DEBUG) << "Failed to submit transfer because endpoint " | 1089 USB_LOG(DEBUG) << "Failed to submit transfer because endpoint " |
1088 << static_cast<int>(endpoint_address) | 1090 << static_cast<int>(endpoint_address) |
1089 << " not part of a claimed interface."; | 1091 << " not part of a claimed interface."; |
1090 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 1092 RunTransferCallback(callback_task_runner, callback, |
1091 buffer, 0); | 1093 UsbTransferStatus::TRANSFER_ERROR, buffer, 0); |
1092 return; | 1094 return; |
1093 } | 1095 } |
1094 | 1096 |
1095 if (!base::IsValueInRangeForNumericType<int>(length)) { | 1097 if (!base::IsValueInRangeForNumericType<int>(length)) { |
1096 USB_LOG(DEBUG) << "Transfer too long."; | 1098 USB_LOG(DEBUG) << "Transfer too long."; |
1097 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 1099 RunTransferCallback(callback_task_runner, callback, |
1098 buffer, 0); | 1100 UsbTransferStatus::TRANSFER_ERROR, buffer, 0); |
1099 return; | 1101 return; |
1100 } | 1102 } |
1101 | 1103 |
1102 std::unique_ptr<Transfer> transfer; | 1104 std::unique_ptr<Transfer> transfer; |
1103 UsbTransferType transfer_type = endpoint_it->second.endpoint->transfer_type; | 1105 UsbTransferType transfer_type = endpoint_it->second.endpoint->transfer_type; |
1104 if (transfer_type == USB_TRANSFER_BULK) { | 1106 if (transfer_type == UsbTransferType::BULK) { |
1105 transfer = Transfer::CreateBulkTransfer(this, endpoint_address, buffer, | 1107 transfer = Transfer::CreateBulkTransfer(this, endpoint_address, buffer, |
1106 static_cast<int>(length), timeout, | 1108 static_cast<int>(length), timeout, |
1107 callback_task_runner, callback); | 1109 callback_task_runner, callback); |
1108 } else if (transfer_type == USB_TRANSFER_INTERRUPT) { | 1110 } else if (transfer_type == UsbTransferType::INTERRUPT) { |
1109 transfer = Transfer::CreateInterruptTransfer( | 1111 transfer = Transfer::CreateInterruptTransfer( |
1110 this, endpoint_address, buffer, static_cast<int>(length), timeout, | 1112 this, endpoint_address, buffer, static_cast<int>(length), timeout, |
1111 callback_task_runner, callback); | 1113 callback_task_runner, callback); |
1112 } else { | 1114 } else { |
1113 USB_LOG(DEBUG) << "Endpoint " << static_cast<int>(endpoint_address) | 1115 USB_LOG(DEBUG) << "Endpoint " << static_cast<int>(endpoint_address) |
1114 << " is not a bulk or interrupt endpoint."; | 1116 << " is not a bulk or interrupt endpoint."; |
1115 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 1117 RunTransferCallback(callback_task_runner, callback, |
1116 buffer, 0); | 1118 UsbTransferStatus::TRANSFER_ERROR, buffer, 0); |
1117 return; | 1119 return; |
1118 } | 1120 } |
1119 | 1121 |
1120 SubmitTransfer(std::move(transfer)); | 1122 SubmitTransfer(std::move(transfer)); |
1121 } | 1123 } |
1122 | 1124 |
1123 void UsbDeviceHandleImpl::SubmitTransfer(std::unique_ptr<Transfer> transfer) { | 1125 void UsbDeviceHandleImpl::SubmitTransfer(std::unique_ptr<Transfer> transfer) { |
1124 DCHECK(thread_checker_.CalledOnValidThread()); | 1126 DCHECK(thread_checker_.CalledOnValidThread()); |
1125 | 1127 |
1126 // Transfer is owned by libusb until its completion callback is run. This | 1128 // Transfer is owned by libusb until its completion callback is run. This |
(...skipping 16 matching lines...) Expand all Loading... |
1143 } else { | 1145 } else { |
1144 transfer->callback_task_runner()->PostTask(FROM_HERE, callback); | 1146 transfer->callback_task_runner()->PostTask(FROM_HERE, callback); |
1145 } | 1147 } |
1146 | 1148 |
1147 // libusb_free_transfer races with libusb_submit_transfer and only work- | 1149 // libusb_free_transfer races with libusb_submit_transfer and only work- |
1148 // around is to make sure to call them on the same thread. | 1150 // around is to make sure to call them on the same thread. |
1149 blocking_task_runner_->DeleteSoon(FROM_HERE, transfer); | 1151 blocking_task_runner_->DeleteSoon(FROM_HERE, transfer); |
1150 } | 1152 } |
1151 | 1153 |
1152 } // namespace device | 1154 } // namespace device |
OLD | NEW |