OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/devices_app/usb/device_impl.h" | 5 #include "device/devices_app/usb/device_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 |
| 9 #include <algorithm> |
| 10 #include <numeric> |
8 #include <utility> | 11 #include <utility> |
| 12 #include <vector> |
9 | 13 |
10 #include "base/bind.h" | 14 #include "base/bind.h" |
11 #include "base/callback.h" | 15 #include "base/callback.h" |
12 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
13 #include "device/devices_app/usb/type_converters.h" | 17 #include "device/devices_app/usb/type_converters.h" |
14 #include "device/usb/usb_descriptors.h" | 18 #include "device/usb/usb_descriptors.h" |
15 #include "device/usb/usb_device.h" | 19 #include "device/usb/usb_device.h" |
16 #include "net/base/io_buffer.h" | 20 #include "net/base/io_buffer.h" |
17 | 21 |
18 namespace device { | 22 namespace device { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 USB_DIRECTION_OUTBOUND, | 125 USB_DIRECTION_OUTBOUND, |
122 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), | 126 mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type), |
123 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), | 127 mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient), |
124 params->request, params->value, params->index, buffer, data.size(), | 128 params->request, params->value, params->index, buffer, data.size(), |
125 timeout, base::Bind(&OnTransferOut, base::Passed(&callback))); | 129 timeout, base::Bind(&OnTransferOut, base::Passed(&callback))); |
126 } else { | 130 } else { |
127 callback->Run(TransferStatus::PERMISSION_DENIED); | 131 callback->Run(TransferStatus::PERMISSION_DENIED); |
128 } | 132 } |
129 } | 133 } |
130 | 134 |
| 135 mojo::Array<IsochronousPacketPtr> BuildIsochronousPacketArray( |
| 136 mojo::Array<uint32_t> packet_lengths, |
| 137 TransferStatus status) { |
| 138 mojo::Array<IsochronousPacketPtr> packets(packet_lengths.size()); |
| 139 for (size_t i = 0; i < packet_lengths.size(); ++i) { |
| 140 packets[i] = IsochronousPacket::New(); |
| 141 packets[i]->length = packet_lengths[i]; |
| 142 packets[i]->status = status; |
| 143 } |
| 144 return packets; |
| 145 } |
| 146 |
131 void OnIsochronousTransferIn( | 147 void OnIsochronousTransferIn( |
132 scoped_ptr<Device::IsochronousTransferInCallback> callback, | 148 scoped_ptr<Device::IsochronousTransferInCallback> callback, |
133 uint32_t packet_size, | |
134 UsbTransferStatus status, | |
135 scoped_refptr<net::IOBuffer> buffer, | 149 scoped_refptr<net::IOBuffer> buffer, |
136 size_t buffer_size) { | 150 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
137 size_t num_packets = buffer_size / packet_size; | 151 mojo::Array<uint8_t> data; |
138 mojo::Array<mojo::Array<uint8_t>> packets(num_packets); | |
139 if (buffer) { | 152 if (buffer) { |
140 for (size_t i = 0; i < num_packets; ++i) { | 153 // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a |
141 size_t packet_index = i * packet_size; | 154 // std::vector<uint8_t> instead of net::IOBuffer. Then we could move |
142 std::vector<uint8_t> bytes(packet_size); | 155 // instead of copy. |
143 std::copy(buffer->data() + packet_index, | 156 uint32_t buffer_size = |
144 buffer->data() + packet_index + packet_size, bytes.begin()); | 157 std::accumulate(packets.begin(), packets.end(), 0u, |
145 packets[i].Swap(&bytes); | 158 [](const uint32_t& a, |
146 } | 159 const UsbDeviceHandle::IsochronousPacket& packet) { |
| 160 return a + packet.length; |
| 161 }); |
| 162 std::vector<uint8_t> bytes(buffer_size); |
| 163 std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin()); |
| 164 data.Swap(&bytes); |
147 } | 165 } |
148 callback->Run(mojo::ConvertTo<TransferStatus>(status), std::move(packets)); | 166 callback->Run(std::move(data), |
| 167 mojo::Array<IsochronousPacketPtr>::From(packets)); |
149 } | 168 } |
150 | 169 |
151 void OnIsochronousTransferOut( | 170 void OnIsochronousTransferOut( |
152 scoped_ptr<Device::IsochronousTransferOutCallback> callback, | 171 scoped_ptr<Device::IsochronousTransferOutCallback> callback, |
153 UsbTransferStatus status, | |
154 scoped_refptr<net::IOBuffer> buffer, | 172 scoped_refptr<net::IOBuffer> buffer, |
155 size_t buffer_size) { | 173 const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) { |
156 callback->Run(mojo::ConvertTo<TransferStatus>(status)); | 174 callback->Run(mojo::Array<IsochronousPacketPtr>::From(packets)); |
157 } | 175 } |
158 | 176 |
159 } // namespace | 177 } // namespace |
160 | 178 |
161 DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device, | 179 DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device, |
162 PermissionProviderPtr permission_provider, | 180 PermissionProviderPtr permission_provider, |
163 mojo::InterfaceRequest<Device> request) | 181 mojo::InterfaceRequest<Device> request) |
164 : binding_(this, std::move(request)), | 182 : binding_(this, std::move(request)), |
165 device_(device), | 183 device_(device), |
166 permission_provider_(std::move(permission_provider)), | 184 permission_provider_(std::move(permission_provider)), |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); | 409 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
392 const std::vector<uint8_t>& storage = data.storage(); | 410 const std::vector<uint8_t>& storage = data.storage(); |
393 std::copy(storage.begin(), storage.end(), buffer->data()); | 411 std::copy(storage.begin(), storage.end(), buffer->data()); |
394 device_handle_->GenericTransfer( | 412 device_handle_->GenericTransfer( |
395 USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout, | 413 USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout, |
396 base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); | 414 base::Bind(&OnTransferOut, base::Passed(&callback_ptr))); |
397 } | 415 } |
398 | 416 |
399 void DeviceImpl::IsochronousTransferIn( | 417 void DeviceImpl::IsochronousTransferIn( |
400 uint8_t endpoint_number, | 418 uint8_t endpoint_number, |
401 uint32_t num_packets, | 419 mojo::Array<uint32_t> packet_lengths, |
402 uint32_t packet_length, | |
403 uint32_t timeout, | 420 uint32_t timeout, |
404 const IsochronousTransferInCallback& callback) { | 421 const IsochronousTransferInCallback& callback) { |
405 if (!device_handle_) { | 422 if (!device_handle_) { |
406 callback.Run(TransferStatus::TRANSFER_ERROR, | 423 callback.Run(mojo::Array<uint8_t>(), |
407 mojo::Array<mojo::Array<uint8_t>>()); | 424 BuildIsochronousPacketArray(std::move(packet_lengths), |
| 425 TransferStatus::TRANSFER_ERROR)); |
408 return; | 426 return; |
409 } | 427 } |
410 | 428 |
411 auto callback_ptr = | 429 auto callback_ptr = |
412 make_scoped_ptr(new IsochronousTransferInCallback(callback)); | 430 make_scoped_ptr(new IsochronousTransferInCallback(callback)); |
413 uint8_t endpoint_address = endpoint_number | 0x80; | 431 uint8_t endpoint_address = endpoint_number | 0x80; |
414 size_t transfer_size = static_cast<size_t>(num_packets) * packet_length; | 432 device_handle_->IsochronousTransferIn( |
415 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(transfer_size); | 433 endpoint_address, packet_lengths.storage(), timeout, |
416 device_handle_->IsochronousTransfer( | 434 base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr))); |
417 USB_DIRECTION_INBOUND, endpoint_address, buffer, transfer_size, | |
418 num_packets, packet_length, timeout, | |
419 base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr), | |
420 packet_length)); | |
421 } | 435 } |
422 | 436 |
423 void DeviceImpl::IsochronousTransferOut( | 437 void DeviceImpl::IsochronousTransferOut( |
424 uint8_t endpoint_number, | 438 uint8_t endpoint_number, |
425 mojo::Array<mojo::Array<uint8_t>> packets, | 439 mojo::Array<uint8_t> data, |
| 440 mojo::Array<uint32_t> packet_lengths, |
426 uint32_t timeout, | 441 uint32_t timeout, |
427 const IsochronousTransferOutCallback& callback) { | 442 const IsochronousTransferOutCallback& callback) { |
428 if (!device_handle_) { | 443 if (!device_handle_) { |
429 callback.Run(TransferStatus::TRANSFER_ERROR); | 444 callback.Run(BuildIsochronousPacketArray(std::move(packet_lengths), |
| 445 TransferStatus::TRANSFER_ERROR)); |
430 return; | 446 return; |
431 } | 447 } |
432 | 448 |
433 auto callback_ptr = | 449 auto callback_ptr = |
434 make_scoped_ptr(new IsochronousTransferOutCallback(callback)); | 450 make_scoped_ptr(new IsochronousTransferOutCallback(callback)); |
435 uint8_t endpoint_address = endpoint_number; | 451 uint8_t endpoint_address = endpoint_number; |
436 uint32_t packet_size = 0; | 452 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size()); |
437 for (size_t i = 0; i < packets.size(); ++i) { | 453 { |
438 packet_size = | 454 const std::vector<uint8_t>& storage = data.storage(); |
439 std::max(packet_size, static_cast<uint32_t>(packets[i].size())); | 455 std::copy(storage.begin(), storage.end(), buffer->data()); |
440 } | 456 } |
441 size_t transfer_size = packet_size * packets.size(); | 457 device_handle_->IsochronousTransferOut( |
442 scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(transfer_size); | 458 endpoint_address, buffer, packet_lengths.storage(), timeout, |
443 memset(buffer->data(), 0, transfer_size); | |
444 for (size_t i = 0; i < packets.size(); ++i) { | |
445 uint8_t* packet = | |
446 reinterpret_cast<uint8_t*>(&buffer->data()[i * packet_size]); | |
447 DCHECK_LE(packets[i].size(), static_cast<size_t>(packet_size)); | |
448 memcpy(packet, packets[i].storage().data(), packets[i].size()); | |
449 } | |
450 device_handle_->IsochronousTransfer( | |
451 USB_DIRECTION_OUTBOUND, endpoint_address, buffer, transfer_size, | |
452 static_cast<uint32_t>(packets.size()), packet_size, timeout, | |
453 base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr))); | 459 base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr))); |
454 } | 460 } |
455 | 461 |
456 } // namespace usb | 462 } // namespace usb |
457 } // namespace device | 463 } // namespace device |
OLD | NEW |