| 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 <numeric> |
| 8 #include <utility> | 9 #include <utility> |
| 9 #include <vector> | 10 #include <vector> |
| 10 | 11 |
| 11 #include "base/bind.h" | 12 #include "base/bind.h" |
| 12 #include "base/location.h" | 13 #include "base/location.h" |
| 13 #include "base/macros.h" | 14 #include "base/macros.h" |
| 14 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 15 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 16 #include "base/strings/string16.h" | 17 #include "base/strings/string16.h" |
| 17 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 scoped_refptr<net::IOBuffer> buffer, | 113 scoped_refptr<net::IOBuffer> buffer, |
| 113 size_t result) { | 114 size_t result) { |
| 114 if (callback_task_runner->RunsTasksOnCurrentThread()) { | 115 if (callback_task_runner->RunsTasksOnCurrentThread()) { |
| 115 callback.Run(status, buffer, result); | 116 callback.Run(status, buffer, result); |
| 116 } else { | 117 } else { |
| 117 callback_task_runner->PostTask( | 118 callback_task_runner->PostTask( |
| 118 FROM_HERE, base::Bind(callback, status, buffer, result)); | 119 FROM_HERE, base::Bind(callback, status, buffer, result)); |
| 119 } | 120 } |
| 120 } | 121 } |
| 121 | 122 |
| 123 void ReportIsochronousTransferError( |
| 124 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 125 const UsbDeviceHandle::IsochronousTransferCallback& callback, |
| 126 const std::vector<uint32_t> packet_lengths, |
| 127 UsbTransferStatus status) { |
| 128 std::vector<UsbDeviceHandle::IsochronousPacket> packets( |
| 129 packet_lengths.size()); |
| 130 for (size_t i = 0; i < packet_lengths.size(); ++i) { |
| 131 packets[i].length = packet_lengths[i]; |
| 132 packets[i].transferred_length = 0; |
| 133 packets[i].status = status; |
| 134 } |
| 135 if (callback_task_runner->RunsTasksOnCurrentThread()) { |
| 136 callback.Run(nullptr, packets); |
| 137 } else { |
| 138 callback_task_runner->PostTask(FROM_HERE, |
| 139 base::Bind(callback, nullptr, packets)); |
| 140 } |
| 141 } |
| 142 |
| 122 } // namespace | 143 } // namespace |
| 123 | 144 |
| 124 class UsbDeviceHandleImpl::InterfaceClaimer | 145 class UsbDeviceHandleImpl::InterfaceClaimer |
| 125 : public base::RefCountedThreadSafe<UsbDeviceHandleImpl::InterfaceClaimer> { | 146 : public base::RefCountedThreadSafe<UsbDeviceHandleImpl::InterfaceClaimer> { |
| 126 public: | 147 public: |
| 127 InterfaceClaimer(scoped_refptr<UsbDeviceHandleImpl> handle, | 148 InterfaceClaimer(scoped_refptr<UsbDeviceHandleImpl> handle, |
| 128 int interface_number); | 149 int interface_number); |
| 129 | 150 |
| 130 int alternate_setting() const { return alternate_setting_; } | 151 int alternate_setting() const { return alternate_setting_; } |
| 131 void set_alternate_setting(const int alternate_setting) { | 152 void set_alternate_setting(const int alternate_setting) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 scoped_refptr<net::IOBuffer> buffer, | 204 scoped_refptr<net::IOBuffer> buffer, |
| 184 int length, | 205 int length, |
| 185 unsigned int timeout, | 206 unsigned int timeout, |
| 186 scoped_refptr<base::TaskRunner> callback_task_runner, | 207 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 187 const TransferCallback& callback); | 208 const TransferCallback& callback); |
| 188 static scoped_ptr<Transfer> CreateIsochronousTransfer( | 209 static scoped_ptr<Transfer> CreateIsochronousTransfer( |
| 189 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 210 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
| 190 uint8_t endpoint, | 211 uint8_t endpoint, |
| 191 scoped_refptr<net::IOBuffer> buffer, | 212 scoped_refptr<net::IOBuffer> buffer, |
| 192 size_t length, | 213 size_t length, |
| 193 unsigned int packets, | 214 const std::vector<uint32_t>& packet_lengths, |
| 194 unsigned int packet_length, | |
| 195 unsigned int timeout, | 215 unsigned int timeout, |
| 196 scoped_refptr<base::TaskRunner> task_runner, | 216 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 197 const TransferCallback& callback); | 217 const IsochronousTransferCallback& callback); |
| 198 | 218 |
| 199 ~Transfer(); | 219 ~Transfer(); |
| 200 | 220 |
| 201 void Submit(); | 221 void Submit(); |
| 202 void Cancel(); | 222 void Cancel(); |
| 203 void ProcessCompletion(); | 223 void ProcessCompletion(); |
| 204 void TransferComplete(UsbTransferStatus status, size_t bytes_transferred); | 224 void TransferComplete(UsbTransferStatus status, size_t bytes_transferred); |
| 205 | 225 |
| 206 const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const { | 226 const UsbDeviceHandleImpl::InterfaceClaimer* claimed_interface() const { |
| 207 return claimed_interface_.get(); | 227 return claimed_interface_.get(); |
| 208 } | 228 } |
| 209 | 229 |
| 210 scoped_refptr<base::TaskRunner> callback_task_runner() const { | 230 scoped_refptr<base::TaskRunner> callback_task_runner() const { |
| 211 return callback_task_runner_; | 231 return callback_task_runner_; |
| 212 } | 232 } |
| 213 | 233 |
| 214 private: | 234 private: |
| 215 Transfer(scoped_refptr<UsbDeviceHandleImpl> device_handle, | 235 Transfer(scoped_refptr<UsbDeviceHandleImpl> device_handle, |
| 216 scoped_refptr<InterfaceClaimer> claimed_interface, | 236 scoped_refptr<InterfaceClaimer> claimed_interface, |
| 217 UsbTransferType transfer_type, | 237 UsbTransferType transfer_type, |
| 218 scoped_refptr<net::IOBuffer> buffer, | 238 scoped_refptr<net::IOBuffer> buffer, |
| 219 size_t length, | 239 size_t length, |
| 220 scoped_refptr<base::TaskRunner> callback_task_runner, | 240 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 221 const TransferCallback& callback); | 241 const TransferCallback& callback); |
| 242 Transfer(scoped_refptr<UsbDeviceHandleImpl> device_handle, |
| 243 scoped_refptr<InterfaceClaimer> claimed_interface, |
| 244 scoped_refptr<net::IOBuffer> buffer, |
| 245 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 246 const IsochronousTransferCallback& callback); |
| 222 | 247 |
| 223 static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle); | 248 static void LIBUSB_CALL PlatformCallback(PlatformUsbTransferHandle handle); |
| 224 | 249 |
| 250 void IsochronousTransferComplete(); |
| 251 |
| 225 UsbTransferType transfer_type_; | 252 UsbTransferType transfer_type_; |
| 226 scoped_refptr<UsbDeviceHandleImpl> device_handle_; | 253 scoped_refptr<UsbDeviceHandleImpl> device_handle_; |
| 227 PlatformUsbTransferHandle platform_transfer_ = nullptr; | 254 PlatformUsbTransferHandle platform_transfer_ = nullptr; |
| 228 scoped_refptr<net::IOBuffer> buffer_; | 255 scoped_refptr<net::IOBuffer> buffer_; |
| 229 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_; | 256 scoped_refptr<UsbDeviceHandleImpl::InterfaceClaimer> claimed_interface_; |
| 230 size_t length_; | 257 size_t length_; |
| 231 bool cancelled_ = false; | 258 bool cancelled_ = false; |
| 232 scoped_refptr<base::SequencedTaskRunner> task_runner_; | 259 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 233 scoped_refptr<base::TaskRunner> callback_task_runner_; | 260 scoped_refptr<base::TaskRunner> callback_task_runner_; |
| 234 TransferCallback callback_; | 261 TransferCallback callback_; |
| 262 IsochronousTransferCallback iso_callback_; |
| 235 }; | 263 }; |
| 236 | 264 |
| 237 // static | 265 // static |
| 238 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 266 scoped_ptr<UsbDeviceHandleImpl::Transfer> |
| 239 UsbDeviceHandleImpl::Transfer::CreateControlTransfer( | 267 UsbDeviceHandleImpl::Transfer::CreateControlTransfer( |
| 240 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 268 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
| 241 uint8_t type, | 269 uint8_t type, |
| 242 uint8_t request, | 270 uint8_t request, |
| 243 uint16_t value, | 271 uint16_t value, |
| 244 uint16_t index, | 272 uint16_t index, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 scoped_ptr<Transfer> transfer(new Transfer( | 309 scoped_ptr<Transfer> transfer(new Transfer( |
| 282 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), | 310 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
| 283 USB_TRANSFER_BULK, buffer, length, callback_task_runner, callback)); | 311 USB_TRANSFER_BULK, buffer, length, callback_task_runner, callback)); |
| 284 | 312 |
| 285 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 313 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
| 286 if (!transfer->platform_transfer_) { | 314 if (!transfer->platform_transfer_) { |
| 287 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; | 315 USB_LOG(ERROR) << "Failed to allocate bulk transfer."; |
| 288 return nullptr; | 316 return nullptr; |
| 289 } | 317 } |
| 290 | 318 |
| 291 libusb_fill_bulk_transfer( | 319 libusb_fill_bulk_transfer(transfer->platform_transfer_, |
| 292 transfer->platform_transfer_, device_handle->handle_, endpoint, | 320 device_handle->handle_, endpoint, |
| 293 reinterpret_cast<uint8_t*>(buffer->data()), static_cast<int>(length), | 321 reinterpret_cast<uint8_t*>(buffer->data()), length, |
| 294 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), | 322 &UsbDeviceHandleImpl::Transfer::PlatformCallback, |
| 295 timeout); | 323 transfer.get(), timeout); |
| 296 | 324 |
| 297 return transfer; | 325 return transfer; |
| 298 } | 326 } |
| 299 | 327 |
| 300 // static | 328 // static |
| 301 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 329 scoped_ptr<UsbDeviceHandleImpl::Transfer> |
| 302 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( | 330 UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( |
| 303 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 331 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
| 304 uint8_t endpoint, | 332 uint8_t endpoint, |
| 305 scoped_refptr<net::IOBuffer> buffer, | 333 scoped_refptr<net::IOBuffer> buffer, |
| 306 int length, | 334 int length, |
| 307 unsigned int timeout, | 335 unsigned int timeout, |
| 308 scoped_refptr<base::TaskRunner> callback_task_runner, | 336 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 309 const TransferCallback& callback) { | 337 const TransferCallback& callback) { |
| 310 scoped_ptr<Transfer> transfer(new Transfer( | 338 scoped_ptr<Transfer> transfer(new Transfer( |
| 311 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), | 339 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
| 312 USB_TRANSFER_INTERRUPT, buffer, length, callback_task_runner, callback)); | 340 USB_TRANSFER_INTERRUPT, buffer, length, callback_task_runner, callback)); |
| 313 | 341 |
| 314 transfer->platform_transfer_ = libusb_alloc_transfer(0); | 342 transfer->platform_transfer_ = libusb_alloc_transfer(0); |
| 315 if (!transfer->platform_transfer_) { | 343 if (!transfer->platform_transfer_) { |
| 316 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; | 344 USB_LOG(ERROR) << "Failed to allocate interrupt transfer."; |
| 317 return nullptr; | 345 return nullptr; |
| 318 } | 346 } |
| 319 | 347 |
| 320 libusb_fill_interrupt_transfer( | 348 libusb_fill_interrupt_transfer( |
| 321 transfer->platform_transfer_, device_handle->handle_, endpoint, | 349 transfer->platform_transfer_, device_handle->handle_, endpoint, |
| 322 reinterpret_cast<uint8_t*>(buffer->data()), static_cast<int>(length), | 350 reinterpret_cast<uint8_t*>(buffer->data()), length, |
| 323 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), | 351 &UsbDeviceHandleImpl::Transfer::PlatformCallback, transfer.get(), |
| 324 timeout); | 352 timeout); |
| 325 | 353 |
| 326 return transfer; | 354 return transfer; |
| 327 } | 355 } |
| 328 | 356 |
| 329 // static | 357 // static |
| 330 scoped_ptr<UsbDeviceHandleImpl::Transfer> | 358 scoped_ptr<UsbDeviceHandleImpl::Transfer> |
| 331 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( | 359 UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( |
| 332 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 360 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
| 333 uint8_t endpoint, | 361 uint8_t endpoint, |
| 334 scoped_refptr<net::IOBuffer> buffer, | 362 scoped_refptr<net::IOBuffer> buffer, |
| 335 size_t length, | 363 size_t length, |
| 336 unsigned int packets, | 364 const std::vector<uint32_t>& packet_lengths, |
| 337 unsigned int packet_length, | |
| 338 unsigned int timeout, | 365 unsigned int timeout, |
| 339 scoped_refptr<base::TaskRunner> callback_task_runner, | 366 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 340 const TransferCallback& callback) { | 367 const IsochronousTransferCallback& callback) { |
| 341 DCHECK(packets <= length && (packets * packet_length) <= length) | |
| 342 << "transfer length is too small"; | |
| 343 | |
| 344 scoped_ptr<Transfer> transfer(new Transfer( | 368 scoped_ptr<Transfer> transfer(new Transfer( |
| 345 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), | 369 device_handle, device_handle->GetClaimedInterfaceForEndpoint(endpoint), |
| 346 USB_TRANSFER_ISOCHRONOUS, buffer, length, callback_task_runner, | 370 buffer, callback_task_runner, callback)); |
| 347 callback)); | |
| 348 | 371 |
| 349 transfer->platform_transfer_ = libusb_alloc_transfer(packets); | 372 int num_packets = static_cast<int>(packet_lengths.size()); |
| 373 transfer->platform_transfer_ = libusb_alloc_transfer(num_packets); |
| 350 if (!transfer->platform_transfer_) { | 374 if (!transfer->platform_transfer_) { |
| 351 USB_LOG(ERROR) << "Failed to allocate isochronous transfer."; | 375 USB_LOG(ERROR) << "Failed to allocate isochronous transfer."; |
| 352 return nullptr; | 376 return nullptr; |
| 353 } | 377 } |
| 354 | 378 |
| 355 libusb_fill_iso_transfer( | 379 libusb_fill_iso_transfer( |
| 356 transfer->platform_transfer_, device_handle->handle_, endpoint, | 380 transfer->platform_transfer_, device_handle->handle_, endpoint, |
| 357 reinterpret_cast<uint8_t*>(buffer->data()), static_cast<int>(length), | 381 reinterpret_cast<uint8_t*>(buffer->data()), static_cast<int>(length), |
| 358 packets, &Transfer::PlatformCallback, transfer.get(), timeout); | 382 num_packets, &Transfer::PlatformCallback, transfer.get(), timeout); |
| 359 libusb_set_iso_packet_lengths(transfer->platform_transfer_, packet_length); | 383 |
| 384 for (size_t i = 0; i < packet_lengths.size(); ++i) |
| 385 transfer->platform_transfer_->iso_packet_desc[i].length = packet_lengths[i]; |
| 360 | 386 |
| 361 return transfer; | 387 return transfer; |
| 362 } | 388 } |
| 363 | 389 |
| 364 UsbDeviceHandleImpl::Transfer::Transfer( | 390 UsbDeviceHandleImpl::Transfer::Transfer( |
| 365 scoped_refptr<UsbDeviceHandleImpl> device_handle, | 391 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
| 366 scoped_refptr<InterfaceClaimer> claimed_interface, | 392 scoped_refptr<InterfaceClaimer> claimed_interface, |
| 367 UsbTransferType transfer_type, | 393 UsbTransferType transfer_type, |
| 368 scoped_refptr<net::IOBuffer> buffer, | 394 scoped_refptr<net::IOBuffer> buffer, |
| 369 size_t length, | 395 size_t length, |
| 370 scoped_refptr<base::TaskRunner> callback_task_runner, | 396 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 371 const TransferCallback& callback) | 397 const TransferCallback& callback) |
| 372 : transfer_type_(transfer_type), | 398 : transfer_type_(transfer_type), |
| 373 device_handle_(device_handle), | 399 device_handle_(device_handle), |
| 374 buffer_(buffer), | 400 buffer_(buffer), |
| 375 claimed_interface_(claimed_interface), | 401 claimed_interface_(claimed_interface), |
| 376 length_(length), | 402 length_(length), |
| 377 callback_task_runner_(callback_task_runner), | 403 callback_task_runner_(callback_task_runner), |
| 378 callback_(callback) { | 404 callback_(callback) { |
| 379 task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 405 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 380 } | 406 } |
| 381 | 407 |
| 408 UsbDeviceHandleImpl::Transfer::Transfer( |
| 409 scoped_refptr<UsbDeviceHandleImpl> device_handle, |
| 410 scoped_refptr<InterfaceClaimer> claimed_interface, |
| 411 scoped_refptr<net::IOBuffer> buffer, |
| 412 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 413 const IsochronousTransferCallback& callback) |
| 414 : transfer_type_(USB_TRANSFER_ISOCHRONOUS), |
| 415 device_handle_(device_handle), |
| 416 buffer_(buffer), |
| 417 claimed_interface_(claimed_interface), |
| 418 callback_task_runner_(callback_task_runner), |
| 419 iso_callback_(callback) { |
| 420 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 421 } |
| 422 |
| 382 UsbDeviceHandleImpl::Transfer::~Transfer() { | 423 UsbDeviceHandleImpl::Transfer::~Transfer() { |
| 383 if (platform_transfer_) { | 424 if (platform_transfer_) { |
| 384 libusb_free_transfer(platform_transfer_); | 425 libusb_free_transfer(platform_transfer_); |
| 385 } | 426 } |
| 386 } | 427 } |
| 387 | 428 |
| 388 void UsbDeviceHandleImpl::Transfer::Submit() { | 429 void UsbDeviceHandleImpl::Transfer::Submit() { |
| 389 const int rv = libusb_submit_transfer(platform_transfer_); | 430 const int rv = libusb_submit_transfer(platform_transfer_); |
| 390 if (rv != LIBUSB_SUCCESS) { | 431 if (rv != LIBUSB_SUCCESS) { |
| 391 USB_LOG(EVENT) << "Failed to submit transfer: " | 432 USB_LOG(EVENT) << "Failed to submit transfer: " |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 if (length_ >= (LIBUSB_CONTROL_SETUP_SIZE + actual_length)) { | 464 if (length_ >= (LIBUSB_CONTROL_SETUP_SIZE + actual_length)) { |
| 424 // If the payload is zero bytes long, pad out the allocated buffer | 465 // If the payload is zero bytes long, pad out the allocated buffer |
| 425 // size to one byte so that an IOBuffer of that size can be allocated. | 466 // size to one byte so that an IOBuffer of that size can be allocated. |
| 426 scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer( | 467 scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer( |
| 427 std::max(actual_length, static_cast<size_t>(1))); | 468 std::max(actual_length, static_cast<size_t>(1))); |
| 428 memcpy(resized_buffer->data(), | 469 memcpy(resized_buffer->data(), |
| 429 buffer_->data() + LIBUSB_CONTROL_SETUP_SIZE, actual_length); | 470 buffer_->data() + LIBUSB_CONTROL_SETUP_SIZE, actual_length); |
| 430 buffer_ = resized_buffer; | 471 buffer_ = resized_buffer; |
| 431 } | 472 } |
| 432 } | 473 } |
| 474 // Fall through! |
| 475 |
| 476 case USB_TRANSFER_BULK: |
| 477 case USB_TRANSFER_INTERRUPT: |
| 478 TransferComplete(ConvertTransferStatus(platform_transfer_->status), |
| 479 actual_length); |
| 433 break; | 480 break; |
| 434 | 481 |
| 435 case USB_TRANSFER_ISOCHRONOUS: | 482 case USB_TRANSFER_ISOCHRONOUS: |
| 436 // Isochronous replies might carry data in the different isoc packets even | 483 IsochronousTransferComplete(); |
| 437 // if the transfer actual_data value is zero. Furthermore, not all of the | |
| 438 // received packets might contain data, so we need to calculate how many | |
| 439 // data bytes we are effectively providing and pack the results. | |
| 440 if (actual_length == 0) { | |
| 441 size_t packet_buffer_start = 0; | |
| 442 for (int i = 0; i < platform_transfer_->num_iso_packets; ++i) { | |
| 443 PlatformUsbIsoPacketDescriptor packet = | |
| 444 &platform_transfer_->iso_packet_desc[i]; | |
| 445 if (packet->actual_length > 0) { | |
| 446 // We don't need to copy as long as all packets until now provide | |
| 447 // all the data the packet can hold. | |
| 448 if (actual_length < packet_buffer_start) { | |
| 449 CHECK(packet_buffer_start + packet->actual_length <= length_); | |
| 450 memmove(buffer_->data() + actual_length, | |
| 451 buffer_->data() + packet_buffer_start, | |
| 452 packet->actual_length); | |
| 453 } | |
| 454 actual_length += packet->actual_length; | |
| 455 } | |
| 456 | |
| 457 packet_buffer_start += packet->length; | |
| 458 } | |
| 459 } | |
| 460 break; | |
| 461 | |
| 462 case USB_TRANSFER_BULK: | |
| 463 case USB_TRANSFER_INTERRUPT: | |
| 464 break; | 484 break; |
| 465 | 485 |
| 466 default: | 486 default: |
| 467 NOTREACHED() << "Invalid usb transfer type"; | 487 NOTREACHED() << "Invalid usb transfer type"; |
| 468 break; | 488 break; |
| 469 } | 489 } |
| 470 | |
| 471 TransferComplete(ConvertTransferStatus(platform_transfer_->status), | |
| 472 actual_length); | |
| 473 } | 490 } |
| 474 | 491 |
| 475 /* static */ | 492 /* static */ |
| 476 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback( | 493 void LIBUSB_CALL UsbDeviceHandleImpl::Transfer::PlatformCallback( |
| 477 PlatformUsbTransferHandle platform_transfer) { | 494 PlatformUsbTransferHandle platform_transfer) { |
| 478 Transfer* transfer = | 495 Transfer* transfer = |
| 479 reinterpret_cast<Transfer*>(platform_transfer->user_data); | 496 reinterpret_cast<Transfer*>(platform_transfer->user_data); |
| 480 DCHECK(transfer->platform_transfer_ == platform_transfer); | 497 DCHECK(transfer->platform_transfer_ == platform_transfer); |
| 481 transfer->ProcessCompletion(); | 498 transfer->ProcessCompletion(); |
| 482 } | 499 } |
| 483 | 500 |
| 484 void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status, | 501 void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status, |
| 485 size_t bytes_transferred) { | 502 size_t bytes_transferred) { |
| 503 base::Closure closure; |
| 504 if (transfer_type_ == USB_TRANSFER_ISOCHRONOUS) { |
| 505 DCHECK_NE(LIBUSB_TRANSFER_COMPLETED, platform_transfer_->status); |
| 506 std::vector<IsochronousPacket> packets(platform_transfer_->num_iso_packets); |
| 507 for (size_t i = 0; i < packets.size(); ++i) { |
| 508 packets[i].length = platform_transfer_->iso_packet_desc[i].length; |
| 509 packets[i].transferred_length = 0; |
| 510 packets[i].status = status; |
| 511 } |
| 512 closure = base::Bind(iso_callback_, buffer_, packets); |
| 513 } else { |
| 514 closure = base::Bind(callback_, status, buffer_, bytes_transferred); |
| 515 } |
| 486 task_runner_->PostTask( | 516 task_runner_->PostTask( |
| 487 FROM_HERE, | 517 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::TransferComplete, |
| 488 base::Bind(&UsbDeviceHandleImpl::TransferComplete, device_handle_, | 518 device_handle_, base::Unretained(this), closure)); |
| 489 base::Unretained(this), | 519 } |
| 490 base::Bind(callback_, status, buffer_, bytes_transferred))); | 520 |
| 521 void UsbDeviceHandleImpl::Transfer::IsochronousTransferComplete() { |
| 522 std::vector<IsochronousPacket> packets(platform_transfer_->num_iso_packets); |
| 523 for (size_t i = 0; i < packets.size(); ++i) { |
| 524 packets[i].length = platform_transfer_->iso_packet_desc[i].length; |
| 525 packets[i].transferred_length = |
| 526 platform_transfer_->iso_packet_desc[i].actual_length; |
| 527 packets[i].status = |
| 528 ConvertTransferStatus(platform_transfer_->iso_packet_desc[i].status); |
| 529 } |
| 530 task_runner_->PostTask( |
| 531 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::TransferComplete, |
| 532 device_handle_, base::Unretained(this), |
| 533 base::Bind(iso_callback_, buffer_, packets))); |
| 491 } | 534 } |
| 492 | 535 |
| 493 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const { | 536 scoped_refptr<UsbDevice> UsbDeviceHandleImpl::GetDevice() const { |
| 494 return device_; | 537 return device_; |
| 495 } | 538 } |
| 496 | 539 |
| 497 void UsbDeviceHandleImpl::Close() { | 540 void UsbDeviceHandleImpl::Close() { |
| 498 DCHECK(thread_checker_.CalledOnValidThread()); | 541 DCHECK(thread_checker_.CalledOnValidThread()); |
| 499 if (device_) | 542 if (device_) |
| 500 device_->Close(this); | 543 device_->Close(this); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 callback); | 667 callback); |
| 625 } else { | 668 } else { |
| 626 task_runner_->PostTask( | 669 task_runner_->PostTask( |
| 627 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ControlTransferInternal, | 670 FROM_HERE, base::Bind(&UsbDeviceHandleImpl::ControlTransferInternal, |
| 628 this, direction, request_type, recipient, request, | 671 this, direction, request_type, recipient, request, |
| 629 value, index, buffer, length, timeout, | 672 value, index, buffer, length, timeout, |
| 630 base::ThreadTaskRunnerHandle::Get(), callback)); | 673 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 631 } | 674 } |
| 632 } | 675 } |
| 633 | 676 |
| 634 void UsbDeviceHandleImpl::IsochronousTransfer( | 677 void UsbDeviceHandleImpl::IsochronousTransferIn( |
| 635 UsbEndpointDirection direction, | |
| 636 uint8_t endpoint_number, | 678 uint8_t endpoint_number, |
| 637 scoped_refptr<net::IOBuffer> buffer, | 679 const std::vector<uint32_t>& packet_lengths, |
| 638 size_t length, | |
| 639 unsigned int packets, | |
| 640 unsigned int packet_length, | |
| 641 unsigned int timeout, | 680 unsigned int timeout, |
| 642 const TransferCallback& callback) { | 681 const IsochronousTransferCallback& callback) { |
| 643 uint8_t endpoint_address = | 682 uint8_t endpoint_address = |
| 644 ConvertTransferDirection(direction) | endpoint_number; | 683 ConvertTransferDirection(USB_DIRECTION_INBOUND) | endpoint_number; |
| 645 if (task_runner_->BelongsToCurrentThread()) { | 684 if (task_runner_->BelongsToCurrentThread()) { |
| 646 IsochronousTransferInternal(endpoint_address, buffer, length, packets, | 685 IsochronousTransferInInternal(endpoint_address, packet_lengths, timeout, |
| 647 packet_length, timeout, task_runner_, callback); | 686 task_runner_, callback); |
| 648 } else { | 687 } else { |
| 649 task_runner_->PostTask( | 688 task_runner_->PostTask( |
| 650 FROM_HERE, | 689 FROM_HERE, |
| 651 base::Bind(&UsbDeviceHandleImpl::IsochronousTransferInternal, this, | 690 base::Bind(&UsbDeviceHandleImpl::IsochronousTransferInInternal, this, |
| 652 endpoint_address, buffer, length, packets, packet_length, | 691 endpoint_address, packet_lengths, timeout, |
| 653 timeout, base::ThreadTaskRunnerHandle::Get(), callback)); | 692 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 654 } | 693 } |
| 655 } | 694 } |
| 656 | 695 |
| 696 void UsbDeviceHandleImpl::IsochronousTransferOut( |
| 697 uint8_t endpoint_number, |
| 698 scoped_refptr<net::IOBuffer> buffer, |
| 699 const std::vector<uint32_t>& packet_lengths, |
| 700 unsigned int timeout, |
| 701 const IsochronousTransferCallback& callback) { |
| 702 uint8_t endpoint_address = |
| 703 ConvertTransferDirection(USB_DIRECTION_OUTBOUND) | endpoint_number; |
| 704 if (task_runner_->BelongsToCurrentThread()) { |
| 705 IsochronousTransferOutInternal(endpoint_address, buffer, packet_lengths, |
| 706 timeout, task_runner_, callback); |
| 707 } else { |
| 708 task_runner_->PostTask( |
| 709 FROM_HERE, |
| 710 base::Bind(&UsbDeviceHandleImpl::IsochronousTransferOutInternal, this, |
| 711 endpoint_address, buffer, packet_lengths, timeout, |
| 712 base::ThreadTaskRunnerHandle::Get(), callback)); |
| 713 } |
| 714 } |
| 715 |
| 657 void UsbDeviceHandleImpl::GenericTransfer(UsbEndpointDirection direction, | 716 void UsbDeviceHandleImpl::GenericTransfer(UsbEndpointDirection direction, |
| 658 uint8_t endpoint_number, | 717 uint8_t endpoint_number, |
| 659 scoped_refptr<net::IOBuffer> buffer, | 718 scoped_refptr<net::IOBuffer> buffer, |
| 660 size_t length, | 719 size_t length, |
| 661 unsigned int timeout, | 720 unsigned int timeout, |
| 662 const TransferCallback& callback) { | 721 const TransferCallback& callback) { |
| 663 uint8_t endpoint_address = | 722 uint8_t endpoint_address = |
| 664 ConvertTransferDirection(direction) | endpoint_number; | 723 ConvertTransferDirection(direction) | endpoint_number; |
| 665 if (task_runner_->BelongsToCurrentThread()) { | 724 if (task_runner_->BelongsToCurrentThread()) { |
| 666 GenericTransferInternal(endpoint_address, buffer, length, timeout, | 725 GenericTransferInternal(endpoint_address, buffer, length, timeout, |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 callback_task_runner, callback); | 937 callback_task_runner, callback); |
| 879 if (!transfer) { | 938 if (!transfer) { |
| 880 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 939 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, |
| 881 buffer, 0); | 940 buffer, 0); |
| 882 return; | 941 return; |
| 883 } | 942 } |
| 884 | 943 |
| 885 SubmitTransfer(std::move(transfer)); | 944 SubmitTransfer(std::move(transfer)); |
| 886 } | 945 } |
| 887 | 946 |
| 888 void UsbDeviceHandleImpl::IsochronousTransferInternal( | 947 void UsbDeviceHandleImpl::IsochronousTransferInInternal( |
| 889 uint8_t endpoint_address, | 948 uint8_t endpoint_address, |
| 890 scoped_refptr<net::IOBuffer> buffer, | 949 const std::vector<uint32_t>& packet_lengths, |
| 891 size_t length, | |
| 892 unsigned int packets, | |
| 893 unsigned int packet_length, | |
| 894 unsigned int timeout, | 950 unsigned int timeout, |
| 895 scoped_refptr<base::TaskRunner> callback_task_runner, | 951 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 896 const TransferCallback& callback) { | 952 const IsochronousTransferCallback& callback) { |
| 897 DCHECK(thread_checker_.CalledOnValidThread()); | 953 DCHECK(thread_checker_.CalledOnValidThread()); |
| 898 | 954 |
| 899 if (!device_) { | 955 if (!device_) { |
| 900 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT, | 956 ReportIsochronousTransferError(callback_task_runner, callback, |
| 901 buffer, 0); | 957 packet_lengths, USB_TRANSFER_DISCONNECT); |
| 902 return; | 958 return; |
| 903 } | 959 } |
| 904 | 960 |
| 905 if (!base::IsValueInRangeForNumericType<int>(length)) { | 961 size_t length = |
| 906 USB_LOG(USER) << "Transfer too long."; | 962 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); |
| 907 RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR, | 963 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(length)); |
| 908 buffer, 0); | 964 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( |
| 965 this, endpoint_address, buffer, length, packet_lengths, timeout, |
| 966 callback_task_runner, callback); |
| 967 |
| 968 SubmitTransfer(std::move(transfer)); |
| 969 } |
| 970 |
| 971 void UsbDeviceHandleImpl::IsochronousTransferOutInternal( |
| 972 uint8_t endpoint_address, |
| 973 scoped_refptr<net::IOBuffer> buffer, |
| 974 const std::vector<uint32_t>& packet_lengths, |
| 975 unsigned int timeout, |
| 976 scoped_refptr<base::TaskRunner> callback_task_runner, |
| 977 const IsochronousTransferCallback& callback) { |
| 978 DCHECK(thread_checker_.CalledOnValidThread()); |
| 979 |
| 980 if (!device_) { |
| 981 ReportIsochronousTransferError(callback_task_runner, callback, |
| 982 packet_lengths, USB_TRANSFER_DISCONNECT); |
| 909 return; | 983 return; |
| 910 } | 984 } |
| 911 | 985 |
| 986 size_t length = |
| 987 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); |
| 912 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( | 988 scoped_ptr<Transfer> transfer = Transfer::CreateIsochronousTransfer( |
| 913 this, endpoint_address, buffer, static_cast<int>(length), packets, | 989 this, endpoint_address, buffer, length, packet_lengths, timeout, |
| 914 packet_length, timeout, callback_task_runner, callback); | 990 callback_task_runner, callback); |
| 915 | 991 |
| 916 SubmitTransfer(std::move(transfer)); | 992 SubmitTransfer(std::move(transfer)); |
| 917 } | 993 } |
| 918 | 994 |
| 919 void UsbDeviceHandleImpl::GenericTransferInternal( | 995 void UsbDeviceHandleImpl::GenericTransferInternal( |
| 920 uint8_t endpoint_address, | 996 uint8_t endpoint_address, |
| 921 scoped_refptr<net::IOBuffer> buffer, | 997 scoped_refptr<net::IOBuffer> buffer, |
| 922 size_t length, | 998 size_t length, |
| 923 unsigned int timeout, | 999 unsigned int timeout, |
| 924 scoped_refptr<base::TaskRunner> callback_task_runner, | 1000 scoped_refptr<base::TaskRunner> callback_task_runner, |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 // Attempt-release all the interfaces. | 1087 // Attempt-release all the interfaces. |
| 1012 // It will be retained until the transfer cancellation is finished. | 1088 // It will be retained until the transfer cancellation is finished. |
| 1013 claimed_interfaces_.clear(); | 1089 claimed_interfaces_.clear(); |
| 1014 | 1090 |
| 1015 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to | 1091 // Cannot close device handle here. Need to wait for libusb_cancel_transfer to |
| 1016 // finish. | 1092 // finish. |
| 1017 device_ = NULL; | 1093 device_ = NULL; |
| 1018 } | 1094 } |
| 1019 | 1095 |
| 1020 } // namespace device | 1096 } // namespace device |
| OLD | NEW |