blob: db08c2cf5fc73354a7b049ad96988fd90dbcddcb [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.
#pragma once
#include <memory>
#include <vector>
#include <ddk/device.h>
#include <ddktl/device.h>
#include <ddktl/protocol/usb/function.h>
#include <zircon/hw/usb/hid.h>
namespace usb_hid_function {
// This driver is for testing the USB-HID driver. It binds as a peripheral USB
// device and sends fake HID report descriptors and HID reports. The tests for
// this driver and the USB-HID driver are with the other usb-virtual-bus tests.
class FakeUsbHidFunction;
using DeviceType = ddk::Device<FakeUsbHidFunction, ddk::Unbindable>;
class FakeUsbHidFunction : public DeviceType {
public:
FakeUsbHidFunction(zx_device_t* parent)
: DeviceType(parent), function_(parent) {}
zx_status_t Bind();
// |ddk::Device|
void DdkUnbind();
// |ddk::Device|
void DdkRelease();
static size_t UsbFunctionInterfaceGetDescriptorsSize(void* ctx);
static void UsbFunctionInterfaceGetDescriptors(void* ctx, void* out_descriptors_buffer,
size_t descriptors_size,
size_t* out_descriptors_actual);
static zx_status_t UsbFunctionInterfaceControl(void* ctx, const usb_setup_t* setup,
const void* write_buffer, size_t write_size,
void* out_read_buffer, size_t read_size,
size_t* out_read_actual);
static zx_status_t UsbFunctionInterfaceSetConfigured(void* ctx, bool configured,
usb_speed_t speed);
static zx_status_t UsbFunctionInterfaceSetInterface(void* ctx, uint8_t interface,
uint8_t alt_setting);
private:
usb_function_interface_protocol_ops_t function_interface_ops_ {
.get_descriptors_size = UsbFunctionInterfaceGetDescriptorsSize,
.get_descriptors = UsbFunctionInterfaceGetDescriptors,
.control = UsbFunctionInterfaceControl,
.set_configured = UsbFunctionInterfaceSetConfigured,
.set_interface = UsbFunctionInterfaceSetInterface,
};
ddk::UsbFunctionProtocolClient function_;
std::vector<uint8_t> report_desc_;
std::vector<uint8_t> report_;
struct fake_usb_hid_descriptor_t {
usb_interface_descriptor_t interface;
usb_endpoint_descriptor_t interrupt;
usb_hid_descriptor_t hid_descriptor;
} __PACKED;
struct DescriptorDeleter {
void operator()(fake_usb_hid_descriptor_t* desc) { free(desc); }
};
std::unique_ptr<fake_usb_hid_descriptor_t, DescriptorDeleter> descriptor_;
size_t descriptor_size_;
};
} // namespace usb_hid_function