summaryrefslogtreecommitdiffstats
path: root/device/devices_app/usb
diff options
context:
space:
mode:
Diffstat (limited to 'device/devices_app/usb')
-rw-r--r--device/devices_app/usb/device_impl.cc96
-rw-r--r--device/devices_app/usb/device_impl.h12
-rw-r--r--device/devices_app/usb/device_impl_unittest.cc195
-rw-r--r--device/devices_app/usb/public/interfaces/device.mojom37
-rw-r--r--device/devices_app/usb/type_converters.cc13
-rw-r--r--device/devices_app/usb/type_converters.h12
6 files changed, 239 insertions, 126 deletions
diff --git a/device/devices_app/usb/device_impl.cc b/device/devices_app/usb/device_impl.cc
index fd2f0ff..ae8ad40 100644
--- a/device/devices_app/usb/device_impl.cc
+++ b/device/devices_app/usb/device_impl.cc
@@ -5,7 +5,11 @@
#include "device/devices_app/usb/device_impl.h"
#include <stddef.h>
+
+#include <algorithm>
+#include <numeric>
#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/callback.h"
@@ -128,32 +132,46 @@ void OnControlTransferOutPermissionCheckComplete(
}
}
+mojo::Array<IsochronousPacketPtr> BuildIsochronousPacketArray(
+ mojo::Array<uint32_t> packet_lengths,
+ TransferStatus status) {
+ mojo::Array<IsochronousPacketPtr> packets(packet_lengths.size());
+ for (size_t i = 0; i < packet_lengths.size(); ++i) {
+ packets[i] = IsochronousPacket::New();
+ packets[i]->length = packet_lengths[i];
+ packets[i]->status = status;
+ }
+ return packets;
+}
+
void OnIsochronousTransferIn(
scoped_ptr<Device::IsochronousTransferInCallback> callback,
- uint32_t packet_size,
- UsbTransferStatus status,
scoped_refptr<net::IOBuffer> buffer,
- size_t buffer_size) {
- size_t num_packets = buffer_size / packet_size;
- mojo::Array<mojo::Array<uint8_t>> packets(num_packets);
+ const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
+ mojo::Array<uint8_t> data;
if (buffer) {
- for (size_t i = 0; i < num_packets; ++i) {
- size_t packet_index = i * packet_size;
- std::vector<uint8_t> bytes(packet_size);
- std::copy(buffer->data() + packet_index,
- buffer->data() + packet_index + packet_size, bytes.begin());
- packets[i].Swap(&bytes);
- }
+ // TODO(rockot/reillyg): We should change UsbDeviceHandle to use a
+ // std::vector<uint8_t> instead of net::IOBuffer. Then we could move
+ // instead of copy.
+ uint32_t buffer_size =
+ std::accumulate(packets.begin(), packets.end(), 0u,
+ [](const uint32_t& a,
+ const UsbDeviceHandle::IsochronousPacket& packet) {
+ return a + packet.length;
+ });
+ std::vector<uint8_t> bytes(buffer_size);
+ std::copy(buffer->data(), buffer->data() + buffer_size, bytes.begin());
+ data.Swap(&bytes);
}
- callback->Run(mojo::ConvertTo<TransferStatus>(status), std::move(packets));
+ callback->Run(std::move(data),
+ mojo::Array<IsochronousPacketPtr>::From(packets));
}
void OnIsochronousTransferOut(
scoped_ptr<Device::IsochronousTransferOutCallback> callback,
- UsbTransferStatus status,
scoped_refptr<net::IOBuffer> buffer,
- size_t buffer_size) {
- callback->Run(mojo::ConvertTo<TransferStatus>(status));
+ const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
+ callback->Run(mojo::Array<IsochronousPacketPtr>::From(packets));
}
} // namespace
@@ -398,58 +416,46 @@ void DeviceImpl::GenericTransferOut(
void DeviceImpl::IsochronousTransferIn(
uint8_t endpoint_number,
- uint32_t num_packets,
- uint32_t packet_length,
+ mojo::Array<uint32_t> packet_lengths,
uint32_t timeout,
const IsochronousTransferInCallback& callback) {
if (!device_handle_) {
- callback.Run(TransferStatus::TRANSFER_ERROR,
- mojo::Array<mojo::Array<uint8_t>>());
+ callback.Run(mojo::Array<uint8_t>(),
+ BuildIsochronousPacketArray(std::move(packet_lengths),
+ TransferStatus::TRANSFER_ERROR));
return;
}
auto callback_ptr =
make_scoped_ptr(new IsochronousTransferInCallback(callback));
uint8_t endpoint_address = endpoint_number | 0x80;
- size_t transfer_size = static_cast<size_t>(num_packets) * packet_length;
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(transfer_size);
- device_handle_->IsochronousTransfer(
- USB_DIRECTION_INBOUND, endpoint_address, buffer, transfer_size,
- num_packets, packet_length, timeout,
- base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr),
- packet_length));
+ device_handle_->IsochronousTransferIn(
+ endpoint_address, packet_lengths.storage(), timeout,
+ base::Bind(&OnIsochronousTransferIn, base::Passed(&callback_ptr)));
}
void DeviceImpl::IsochronousTransferOut(
uint8_t endpoint_number,
- mojo::Array<mojo::Array<uint8_t>> packets,
+ mojo::Array<uint8_t> data,
+ mojo::Array<uint32_t> packet_lengths,
uint32_t timeout,
const IsochronousTransferOutCallback& callback) {
if (!device_handle_) {
- callback.Run(TransferStatus::TRANSFER_ERROR);
+ callback.Run(BuildIsochronousPacketArray(std::move(packet_lengths),
+ TransferStatus::TRANSFER_ERROR));
return;
}
auto callback_ptr =
make_scoped_ptr(new IsochronousTransferOutCallback(callback));
uint8_t endpoint_address = endpoint_number;
- uint32_t packet_size = 0;
- for (size_t i = 0; i < packets.size(); ++i) {
- packet_size =
- std::max(packet_size, static_cast<uint32_t>(packets[i].size()));
- }
- size_t transfer_size = packet_size * packets.size();
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(transfer_size);
- memset(buffer->data(), 0, transfer_size);
- for (size_t i = 0; i < packets.size(); ++i) {
- uint8_t* packet =
- reinterpret_cast<uint8_t*>(&buffer->data()[i * packet_size]);
- DCHECK_LE(packets[i].size(), static_cast<size_t>(packet_size));
- memcpy(packet, packets[i].storage().data(), packets[i].size());
+ scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size());
+ {
+ const std::vector<uint8_t>& storage = data.storage();
+ std::copy(storage.begin(), storage.end(), buffer->data());
}
- device_handle_->IsochronousTransfer(
- USB_DIRECTION_OUTBOUND, endpoint_address, buffer, transfer_size,
- static_cast<uint32_t>(packets.size()), packet_size, timeout,
+ device_handle_->IsochronousTransferOut(
+ endpoint_address, buffer, packet_lengths.storage(), timeout,
base::Bind(&OnIsochronousTransferOut, base::Passed(&callback_ptr)));
}
diff --git a/device/devices_app/usb/device_impl.h b/device/devices_app/usb/device_impl.h
index 5290fa7..2b438c8 100644
--- a/device/devices_app/usb/device_impl.h
+++ b/device/devices_app/usb/device_impl.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef DEVICE_USB_DEVICE_IMPL_H_
-#define DEVICE_USB_DEVICE_IMPL_H_
+#ifndef DEVICE_DEVICES_APP_USB_DEVICE_IMPL_H_
+#define DEVICE_DEVICES_APP_USB_DEVICE_IMPL_H_
#include <stdint.h>
@@ -84,13 +84,13 @@ class DeviceImpl : public Device {
const GenericTransferOutCallback& callback) override;
void IsochronousTransferIn(
uint8_t endpoint_number,
- uint32_t num_packets,
- uint32_t packet_length,
+ mojo::Array<uint32_t> packet_lengths,
uint32_t timeout,
const IsochronousTransferInCallback& callback) override;
void IsochronousTransferOut(
uint8_t endpoint_number,
- mojo::Array<mojo::Array<uint8_t>> packets,
+ mojo::Array<uint8_t> data,
+ mojo::Array<uint32_t> packet_lengths,
uint32_t timeout,
const IsochronousTransferOutCallback& callback) override;
@@ -110,4 +110,4 @@ class DeviceImpl : public Device {
} // namespace usb
} // namespace device
-#endif // DEVICE_USB_DEVICE_IMPL_H_
+#endif // DEVICE_DEVICES_APP_USB_DEVICE_IMPL_H_
diff --git a/device/devices_app/usb/device_impl_unittest.cc b/device/devices_app/usb/device_impl_unittest.cc
index 87324d2..e5ee893 100644
--- a/device/devices_app/usb/device_impl_unittest.cc
+++ b/device/devices_app/usb/device_impl_unittest.cc
@@ -6,9 +6,12 @@
#include <stddef.h>
#include <stdint.h>
+
#include <map>
+#include <numeric>
#include <queue>
#include <set>
+#include <string>
#include <utility>
#include <vector>
@@ -34,7 +37,7 @@ namespace {
class ConfigBuilder {
public:
- ConfigBuilder(uint8_t value) { config_.configuration_value = value; }
+ explicit ConfigBuilder(uint8_t value) { config_.configuration_value = value; }
ConfigBuilder& AddInterface(uint8_t interface_number,
uint8_t alternate_setting,
@@ -102,21 +105,35 @@ void ExpectTransferInAndThen(TransferStatus expected_status,
continuation.Run();
}
-void ExpectPacketsAndThen(
- TransferStatus expected_status,
- const std::vector<std::vector<uint8_t>>& expected_packets,
- const base::Closure& continuation,
- TransferStatus actual_status,
- mojo::Array<mojo::Array<uint8_t>> actual_packets) {
- EXPECT_EQ(expected_status, actual_status);
+void ExpectPacketsOutAndThen(const std::vector<uint32_t>& expected_packets,
+ const base::Closure& continuation,
+ mojo::Array<IsochronousPacketPtr> actual_packets) {
ASSERT_EQ(expected_packets.size(), actual_packets.size());
for (size_t i = 0; i < expected_packets.size(); ++i) {
- EXPECT_EQ(expected_packets[i].size(), actual_packets[i].size())
- << "Packet sizes differ at index: " << i;
- for (size_t j = 0; j < expected_packets[i].size(); ++j) {
- EXPECT_EQ(expected_packets[i][j], actual_packets[i][j])
- << "Contents of packet " << i << " differ at index " << j;
- }
+ EXPECT_EQ(expected_packets[i], actual_packets[i]->transferred_length)
+ << "Packet lengths differ at index: " << i;
+ EXPECT_EQ(TransferStatus::COMPLETED, actual_packets[i]->status)
+ << "Packet at index " << i << " not completed.";
+ }
+ continuation.Run();
+}
+
+void ExpectPacketsInAndThen(const std::vector<uint8_t>& expected_bytes,
+ const std::vector<uint32_t>& expected_packets,
+ const base::Closure& continuation,
+ mojo::Array<uint8_t> actual_bytes,
+ mojo::Array<IsochronousPacketPtr> actual_packets) {
+ ASSERT_EQ(expected_packets.size(), actual_packets.size());
+ for (size_t i = 0; i < expected_packets.size(); ++i) {
+ EXPECT_EQ(expected_packets[i], actual_packets[i]->transferred_length)
+ << "Packet lengths differ at index: " << i;
+ EXPECT_EQ(TransferStatus::COMPLETED, actual_packets[i]->status)
+ << "Packet at index " << i << " not completed.";
+ }
+ ASSERT_EQ(expected_bytes.size(), actual_bytes.size());
+ for (size_t i = 0; i < expected_bytes.size(); ++i) {
+ EXPECT_EQ(expected_bytes[i], actual_bytes[i])
+ << "Contents differ at index: " << i;
}
continuation.Run();
}
@@ -186,8 +203,11 @@ class USBDeviceImplTest : public testing::Test {
.WillByDefault(Invoke(this, &USBDeviceImplTest::ControlTransfer));
ON_CALL(mock_handle(), GenericTransfer(_, _, _, _, _, _))
.WillByDefault(Invoke(this, &USBDeviceImplTest::GenericTransfer));
- ON_CALL(mock_handle(), IsochronousTransfer(_, _, _, _, _, _, _, _))
- .WillByDefault(Invoke(this, &USBDeviceImplTest::IsochronousTransfer));
+ ON_CALL(mock_handle(), IsochronousTransferIn(_, _, _, _))
+ .WillByDefault(Invoke(this, &USBDeviceImplTest::IsochronousTransferIn));
+ ON_CALL(mock_handle(), IsochronousTransferOut(_, _, _, _, _))
+ .WillByDefault(
+ Invoke(this, &USBDeviceImplTest::IsochronousTransferOut));
return proxy;
}
@@ -206,10 +226,24 @@ class USBDeviceImplTest : public testing::Test {
mock_inbound_data_.push(data);
}
+ void AddMockInboundPackets(
+ const std::vector<uint8_t>& data,
+ const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
+ mock_inbound_data_.push(data);
+ mock_inbound_packets_.push(packets);
+ }
+
void AddMockOutboundData(const std::vector<uint8_t>& data) {
mock_outbound_data_.push(data);
}
+ void AddMockOutboundPackets(
+ const std::vector<uint8_t>& data,
+ const std::vector<UsbDeviceHandle::IsochronousPacket>& packets) {
+ mock_outbound_data_.push(data);
+ mock_outbound_packets_.push(packets);
+ }
+
private:
void OpenMockHandle(const UsbDevice::OpenCallback& callback) {
EXPECT_FALSE(is_device_open_);
@@ -336,18 +370,59 @@ class USBDeviceImplTest : public testing::Test {
OutboundTransfer(buffer, length, callback);
}
- void IsochronousTransfer(UsbEndpointDirection direction,
- uint8_t endpoint,
- scoped_refptr<net::IOBuffer> buffer,
- size_t length,
- unsigned int packets,
- unsigned int packet_length,
- unsigned int timeout,
- const UsbDeviceHandle::TransferCallback& callback) {
- if (direction == USB_DIRECTION_INBOUND)
- InboundTransfer(callback);
- else
- OutboundTransfer(buffer, length, callback);
+ void IsochronousTransferIn(
+ uint8_t endpoint_number,
+ const std::vector<uint32_t>& packet_lengths,
+ unsigned int timeout,
+ const UsbDeviceHandle::IsochronousTransferCallback& callback) {
+ ASSERT_FALSE(mock_inbound_data_.empty());
+ const std::vector<uint8_t>& bytes = mock_inbound_data_.front();
+ size_t length = bytes.size();
+ scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(length);
+ std::copy(bytes.begin(), bytes.end(), buffer->data());
+ mock_inbound_data_.pop();
+
+ ASSERT_FALSE(mock_inbound_packets_.empty());
+ std::vector<UsbDeviceHandle::IsochronousPacket> packets =
+ mock_inbound_packets_.front();
+ ASSERT_EQ(packets.size(), packet_lengths.size());
+ for (size_t i = 0; i < packets.size(); ++i) {
+ EXPECT_EQ(packets[i].length, packet_lengths[i])
+ << "Packet lengths differ at index: " << i;
+ }
+ mock_inbound_packets_.pop();
+
+ callback.Run(buffer, packets);
+ }
+
+ void IsochronousTransferOut(
+ uint8_t endpoint_number,
+ scoped_refptr<net::IOBuffer> buffer,
+ const std::vector<uint32_t>& packet_lengths,
+ unsigned int timeout,
+ const UsbDeviceHandle::IsochronousTransferCallback& callback) {
+ ASSERT_FALSE(mock_outbound_data_.empty());
+ const std::vector<uint8_t>& bytes = mock_outbound_data_.front();
+ size_t length =
+ std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u);
+ ASSERT_EQ(bytes.size(), length);
+ for (size_t i = 0; i < length; ++i) {
+ EXPECT_EQ(bytes[i], buffer->data()[i]) << "Contents differ at index: "
+ << i;
+ }
+ mock_outbound_data_.pop();
+
+ ASSERT_FALSE(mock_outbound_packets_.empty());
+ std::vector<UsbDeviceHandle::IsochronousPacket> packets =
+ mock_outbound_packets_.front();
+ ASSERT_EQ(packets.size(), packet_lengths.size());
+ for (size_t i = 0; i < packets.size(); ++i) {
+ EXPECT_EQ(packets[i].length, packet_lengths[i])
+ << "Packet lengths differ at index: " << i;
+ }
+ mock_outbound_packets_.pop();
+
+ callback.Run(buffer, packets);
}
scoped_ptr<base::MessageLoop> message_loop_;
@@ -361,6 +436,10 @@ class USBDeviceImplTest : public testing::Test {
std::queue<std::vector<uint8_t>> mock_inbound_data_;
std::queue<std::vector<uint8_t>> mock_outbound_data_;
+ std::queue<std::vector<UsbDeviceHandle::IsochronousPacket>>
+ mock_inbound_packets_;
+ std::queue<std::vector<UsbDeviceHandle::IsochronousPacket>>
+ mock_outbound_packets_;
std::set<uint8_t> claimed_interfaces_;
@@ -758,56 +837,52 @@ TEST_F(USBDeviceImplTest, IsochronousTransfer) {
loop.Run();
}
- std::string outbound_packet_data = "aaaaaaaabbbbbbbbccccccccdddddddd";
- std::vector<uint8_t> fake_outbound_packets(outbound_packet_data.size());
- std::copy(outbound_packet_data.begin(), outbound_packet_data.end(),
- fake_outbound_packets.begin());
+ std::vector<UsbDeviceHandle::IsochronousPacket> fake_packets(4);
+ for (size_t i = 0; i < fake_packets.size(); ++i) {
+ fake_packets[i].length = 8;
+ fake_packets[i].transferred_length = 8;
+ fake_packets[i].status = USB_TRANSFER_COMPLETED;
+ }
+ std::vector<uint32_t> fake_packet_lengths(4, 8);
+
+ std::vector<uint32_t> expected_transferred_lengths(4, 8);
+
+ std::string outbound_data = "aaaaaaaabbbbbbbbccccccccdddddddd";
+ std::vector<uint8_t> fake_outbound_data(outbound_data.size());
+ std::copy(outbound_data.begin(), outbound_data.end(),
+ fake_outbound_data.begin());
- std::string inbound_packet_data = "ddddddddccccccccbbbbbbbbaaaaaaaa";
- std::vector<uint8_t> fake_inbound_packets(inbound_packet_data.size());
- std::copy(inbound_packet_data.begin(), inbound_packet_data.end(),
- fake_inbound_packets.begin());
+ std::string inbound_data = "ddddddddccccccccbbbbbbbbaaaaaaaa";
+ std::vector<uint8_t> fake_inbound_data(inbound_data.size());
+ std::copy(inbound_data.begin(), inbound_data.end(),
+ fake_inbound_data.begin());
AddMockConfig(ConfigBuilder(1).AddInterface(7, 0, 1, 2, 3));
- AddMockOutboundData(fake_outbound_packets);
- AddMockInboundData(fake_inbound_packets);
+ AddMockOutboundPackets(fake_outbound_data, fake_packets);
+ AddMockInboundPackets(fake_inbound_data, fake_packets);
EXPECT_CALL(mock_handle(),
- IsochronousTransfer(USB_DIRECTION_OUTBOUND, 0x01, _,
- fake_outbound_packets.size(), 4, 8, 0, _));
+ IsochronousTransferOut(0x01, _, fake_packet_lengths, 0, _));
{
base::RunLoop loop;
- mojo::Array<mojo::Array<uint8_t>> packets =
- mojo::Array<mojo::Array<uint8_t>>::New(4);
- for (size_t i = 0; i < 4; ++i) {
- std::vector<uint8_t> bytes(8);
- std::copy(outbound_packet_data.begin() + i * 8,
- outbound_packet_data.begin() + i * 8 + 8, bytes.begin());
- packets[i].Swap(&bytes);
- }
device->IsochronousTransferOut(
- 1, std::move(packets), 0,
- base::Bind(&ExpectTransferStatusAndThen, TransferStatus::COMPLETED,
+ 1, mojo::Array<uint8_t>::From(fake_outbound_data),
+ mojo::Array<uint32_t>::From(fake_packet_lengths), 0,
+ base::Bind(&ExpectPacketsOutAndThen, expected_transferred_lengths,
loop.QuitClosure()));
loop.Run();
}
EXPECT_CALL(mock_handle(),
- IsochronousTransfer(USB_DIRECTION_INBOUND, 0x81, _,
- fake_inbound_packets.size(), 4, 8, 0, _));
+ IsochronousTransferIn(0x81, fake_packet_lengths, 0, _));
{
base::RunLoop loop;
- std::vector<std::vector<uint8_t>> packets(4);
- for (size_t i = 0; i < 4; ++i) {
- packets[i].resize(8);
- std::copy(inbound_packet_data.begin() + i * 8,
- inbound_packet_data.begin() + i * 8 + 8, packets[i].begin());
- }
device->IsochronousTransferIn(
- 1, 4, 8, 0, base::Bind(&ExpectPacketsAndThen, TransferStatus::COMPLETED,
- packets, loop.QuitClosure()));
+ 1, mojo::Array<uint32_t>::From(fake_packet_lengths), 0,
+ base::Bind(&ExpectPacketsInAndThen, fake_inbound_data,
+ expected_transferred_lengths, loop.QuitClosure()));
loop.Run();
}
diff --git a/device/devices_app/usb/public/interfaces/device.mojom b/device/devices_app/usb/public/interfaces/device.mojom
index 438aed1..25addb2 100644
--- a/device/devices_app/usb/public/interfaces/device.mojom
+++ b/device/devices_app/usb/public/interfaces/device.mojom
@@ -139,6 +139,12 @@ enum TransferStatus {
SHORT_PACKET,
};
+struct IsochronousPacket {
+ uint32 length;
+ uint32 transferred_length;
+ TransferStatus status;
+};
+
interface Device {
// Retrieve a DeviceInfo struct containing metadata about the device,
// including the set of all available device configurations.
@@ -238,22 +244,22 @@ interface Device {
// transfers can be initiated on the endpoint. The endpoint must be of type
// ISOCHRONOUS.
//
- // |packet_length| specifies the maximum expected number of bytes to receive
- // for each packet in this transfer. |num_packets| specifies the maximum total
- // number of packets to receive.
+ // |packet_lengths| specifies the maximum expected number of bytes to receive
+ // for each packet in this transfer.
//
// |timeout| specifies the request timeout in milliseconds. A timeout of 0
// indicates no timeout: the request will remain pending indefinitely until
// completed or otherwise terminated.
//
- // |packets| contains the set of packets received from the device, in order.
- // No received packet's size will exceed |packet_length|, and will be null
- // if |status| is neither COMPLETED, BABBLE, or SHORT_PACKET.
+ // |data| contains the data received from the device, if any. |packets|
+ // contains the status of each packet received from the device, in order. The
+ // length of the packet indicates its position in |data| while it's
+ // transferred length gives the amount of data actually received from the
+ // device.
IsochronousTransferIn(uint8 endpoint_number,
- uint32 num_packets,
- uint32 packet_length,
+ array<uint32> packet_lengths,
uint32 timeout)
- => (TransferStatus status, array<array<uint8>>? packets);
+ => (array<uint8>? data, array<IsochronousPacket> packets);
// Initiates an outbound isochronous transfer request on a specific endpoint.
// The interface to which |endpoint_number| belongs must be claimed, and the
@@ -261,14 +267,19 @@ interface Device {
// transfers can be initiated on the endpoint. The endpoint must be of type
// ISOCHRONOUS.
//
- // |packets| specifies the series of data packets to send to the device for
- // this transfer.
+ // |data| specifies the bytes to send to the device.
+ //
+ // |packet_lengths| specifies how |data| should be separated into packets when
+ // it is sent to the device.
//
// |timeout| specifies the request timeout in milliseconds. A timeout of 0
// indicates no timeout: the request will remain pending indefinitely until
// completed or otherwise terminated.
+
+ // |packets| contains the status of each packet sent to the device, in order.
IsochronousTransferOut(uint8 endpoint_number,
- array<array<uint8>> packets,
+ array<uint8> data,
+ array<uint32> packet_lengths,
uint32 timeout)
- => (TransferStatus status);
+ => (array<IsochronousPacket> packets);
};
diff --git a/device/devices_app/usb/type_converters.cc b/device/devices_app/usb/type_converters.cc
index e7b2ea6..709b0ca 100644
--- a/device/devices_app/usb/type_converters.cc
+++ b/device/devices_app/usb/type_converters.cc
@@ -267,4 +267,17 @@ TypeConverter<device::usb::DeviceInfoPtr, device::UsbDevice>::Convert(
return info;
}
+// static
+device::usb::IsochronousPacketPtr
+TypeConverter<device::usb::IsochronousPacketPtr,
+ device::UsbDeviceHandle::IsochronousPacket>::
+ Convert(const device::UsbDeviceHandle::IsochronousPacket& packet) {
+ device::usb::IsochronousPacketPtr info =
+ device::usb::IsochronousPacket::New();
+ info->length = packet.length;
+ info->transferred_length = packet.transferred_length;
+ info->status = mojo::ConvertTo<device::usb::TransferStatus>(packet.status);
+ return info;
+}
+
} // namespace mojo
diff --git a/device/devices_app/usb/type_converters.h b/device/devices_app/usb/type_converters.h
index 59c2f4c..15484ea 100644
--- a/device/devices_app/usb/type_converters.h
+++ b/device/devices_app/usb/type_converters.h
@@ -16,8 +16,9 @@
#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/type_converter.h"
-// Type converters to convert objects between internal device/usb data types and
-// public Mojo interface data types.
+// Type converters to translate between internal device/usb data types and
+// public Mojo interface data types. This must be included by any source file
+// that uses these conversions explicitly or implicitly.
namespace device {
class UsbDevice;
@@ -121,6 +122,13 @@ struct TypeConverter<device::usb::DeviceInfoPtr, device::UsbDevice> {
static device::usb::DeviceInfoPtr Convert(const device::UsbDevice& device);
};
+template <>
+struct TypeConverter<device::usb::IsochronousPacketPtr,
+ device::UsbDeviceHandle::IsochronousPacket> {
+ static device::usb::IsochronousPacketPtr Convert(
+ const device::UsbDeviceHandle::IsochronousPacket& packet);
+};
+
} // namespace mojo
#endif // DEVICE_DEVICES_APP_USB_TYPE_CONVERTERS_H_