1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#pragma once
6
7#include <ddk/device.h>
8#include <ddktl/device.h>
9#include <ddktl/protocol/hidbus.h>
10#include <fbl/mutex.h>
11#include <fbl/unique_ptr.h>
12#include <threads.h>
13#include <zircon/compiler.h>
14#include <zircon/device/hidctl.h>
15#include <zircon/types.h>
16#include <lib/zx/socket.h>
17
18namespace hidctl {
19
20class HidCtl : public ddk::Device<HidCtl, ddk::Ioctlable> {
21  public:
22    HidCtl(zx_device_t* device);
23
24    void DdkRelease();
25    zx_status_t DdkIoctl(uint32_t op, const void* in_buf, size_t in_len, void* out_buf,
26                         size_t out_len, size_t* out_actual);
27};
28
29class HidDevice : public ddk::Device<HidDevice, ddk::Unbindable>,
30                  public ddk::HidBusProtocol<HidDevice> {
31  public:
32    HidDevice(zx_device_t* device, const hid_ioctl_config* config, zx::socket data);
33
34    void DdkRelease();
35    void DdkUnbind();
36
37    zx_status_t HidBusQuery(uint32_t options, hid_info_t* info);
38    zx_status_t HidBusStart(ddk::HidBusIfcProxy proxy);
39    void HidBusStop();
40    zx_status_t HidBusGetDescriptor(uint8_t desc_type, void** data, size_t* len);
41    zx_status_t HidBusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len,
42                                size_t* out_len);
43    zx_status_t HidBusSetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len);
44    zx_status_t HidBusGetIdle(uint8_t rpt_id, uint8_t* duration);
45    zx_status_t HidBusSetIdle(uint8_t rpt_id, uint8_t duration);
46    zx_status_t HidBusGetProtocol(uint8_t* protocol);
47    zx_status_t HidBusSetProtocol(uint8_t protocol);
48
49    int Thread();
50    void Shutdown();
51
52  private:
53    zx_status_t Recv(uint8_t* buffer, uint32_t capacity);
54
55    bool boot_device_;
56    uint8_t dev_class_;
57    fbl::unique_ptr<uint8_t[]> report_desc_;
58    size_t report_desc_len_ = 0;
59    uint32_t mtu_ = 256;  // TODO: set this based on report_desc_
60
61    fbl::Mutex lock_;
62    ddk::HidBusIfcProxy proxy_ __TA_GUARDED(lock_);
63    zx::socket data_;
64    thrd_t thread_;
65};
66
67}  // namespace hidctl
68