Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: device/usb/usb_device_handle_impl.cc

Issue 1618393004: Update device/usb and its Mojo interface for variable size ISO packets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698