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 |