blob: d9841973780fd14632a6fe0c7ca500b5e08fb2cb [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <usb/usb.h>
#include <unittest/unittest.h>
namespace {
// Raw descriptors obtained from a Pixelbook with a USB flash drive connected to it.
// To re-generate this, merge the tool at commit
// b934c6e31e31a291b3761383b28cd1d0004e5423 on sandbox/idwmaster/ums-descriptor-debugger
// Be careful to not accidentally submit this tool in a CL
// (it is meant for debugging, not production use).
// to run the tool; simply type the command: debug
// in your device's terminal after connecting a USB mass storage device.
// The raw descriptor dump will be put in /data/debug
// You can copy this to your PC with fx cp
// and convert to an unsigned char array with your favorite conversion script.
constexpr unsigned char kDescriptors[] = {
// Data from a real USB flash drive
9, 4, 0, 0, 2, 8, 6, 80, 0, 7, 5, 129, 2,
0, 4, 0, 6, 48, 3, 0, 0, 0, 7, 5, 2, 2, 0,
4, 0, 6, 48, 3, 0, 0, 0,
// Synthetic data to test alternate interfaces
9, 4, 0, 1, 2, 8, 6, 80, 0};
constexpr usb_interface_descriptor_t kParsedDescriptors[] = {
// Data from a real USB flash drive
{9, 4, 0, 0, 2, 8, 6, 80, 0},
// Synthetic data to test alternate interfaces
{9, 4, 0, 1, 2, 8, 6, 80, 0}};
const usb_endpoint_descriptor_t kEndpointDescriptors[] = {
{7, 5, 129, 2, 1024, 0},
{7, 5, 2, 2, 1024, 0}};
static void GetDescriptors(
void* ctx,
void* out_descs_buffer,
size_t descs_size,
size_t* out_descs_actual) {
if (descs_size != sizeof(kDescriptors)) {
return;
}
memcpy(out_descs_buffer, kDescriptors, descs_size);
*out_descs_actual = descs_size;
}
static size_t GetDescriptorsLength(void* context) {
return sizeof(kDescriptors);
}
bool InterfaceListTest() {
BEGIN_TEST;
usb_protocol_ops_t ops;
ops.get_descriptors_length = GetDescriptorsLength;
ops.get_descriptors = GetDescriptors;
usb_protocol_t proto = {};
proto.ops = &ops;
usb::InterfaceList list(&proto, true);
ASSERT_EQ(ZX_OK, list.check(), "");
size_t count = 0;
for (auto interface : list) {
ASSERT_EQ(
0,
memcmp(kParsedDescriptors + count, interface.descriptor(),
sizeof(usb_interface_descriptor_t)),
"");
size_t endpoint_count = 0;
for (auto endpoint : interface) {
ASSERT_EQ(
0,
memcmp(kEndpointDescriptors + endpoint_count, &endpoint,
sizeof(usb_endpoint_descriptor_t)),
"");
endpoint_count++;
}
ASSERT_EQ(2, endpoint_count, "");
count++;
}
ASSERT_EQ(count, 1, "");
count = 0;
usb::InterfaceList list2(&proto);
for (auto interface : list2) {
ASSERT_EQ(0,
memcmp(kParsedDescriptors + count, interface.descriptor(),
sizeof(usb_interface_descriptor_t)),
"");
size_t endpoint_count = 0;
for (auto endpoint : interface) {
ASSERT_EQ(0,
memcmp(kEndpointDescriptors + endpoint_count,
&endpoint,
sizeof(usb_endpoint_descriptor_t)),
"");
endpoint_count++;
}
ASSERT_EQ(count ? 0U : 2U, endpoint_count, "");
count++;
}
ASSERT_EQ(count, 2, "");
count = 0;
for (auto iter = list2.cbegin(); iter != list2.cend(); iter++) {
auto interface = *iter;
ASSERT_EQ(0, memcmp(kParsedDescriptors + count, interface.descriptor(), sizeof(usb_interface_descriptor_t)),
"");
size_t endpoint_count = 0;
for (auto endpoint : interface) {
ASSERT_EQ(0,
memcmp(kEndpointDescriptors + endpoint_count, &endpoint,
sizeof(usb_endpoint_descriptor_t)),
"");
endpoint_count++;
}
ASSERT_EQ(count ? 0U : 2U, endpoint_count, "");
count++;
}
END_TEST;
}
} // namespace
BEGIN_TEST_CASE(usb_wrapper_tests)
RUN_NAMED_TEST("InterfaceList test", InterfaceListTest)
END_TEST_CASE(usb_wrapper_tests);