| 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 |