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

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

Powered by Google App Engine
This is Rietveld 408576698