Skip to main content

usb_gadget/function/
hid.rs

1//! Human interface device (HID) function.
2//!
3//! The Linux kernel configuration option `CONFIG_USB_CONFIGFS_F_HID` must be enabled.
4
5use std::{ffi::OsString, io::Result, path::PathBuf};
6
7use super::{
8    util::{FunctionDir, Status},
9    Function, Handle,
10};
11
12/// Builder for USB human interface device (HID) function.
13#[derive(Debug, Clone)]
14#[non_exhaustive]
15pub struct HidBuilder {
16    /// HID subclass to use.
17    pub sub_class: u8,
18    /// HID protocol to use.
19    pub protocol: u8,
20    /// Data to be used in HID reports.
21    pub report_desc: Vec<u8>,
22    /// HID report length.
23    pub report_len: u8,
24    /// No out endpoint?
25    pub no_out_endpoint: bool,
26}
27
28impl HidBuilder {
29    /// Build the USB function.
30    ///
31    /// The returned handle must be added to a USB gadget configuration.
32    #[must_use]
33    pub fn build(self) -> (Hid, Handle) {
34        let dir = FunctionDir::new();
35        (Hid { dir: dir.clone() }, Handle::new(HidFunction { builder: self, dir }))
36    }
37}
38
39#[derive(Debug)]
40struct HidFunction {
41    builder: HidBuilder,
42    dir: FunctionDir,
43}
44
45impl Function for HidFunction {
46    fn driver(&self) -> OsString {
47        "hid".into()
48    }
49
50    fn dir(&self) -> FunctionDir {
51        self.dir.clone()
52    }
53
54    fn register(&self) -> Result<()> {
55        self.dir.write("subclass", self.builder.sub_class.to_string())?;
56        self.dir.write("protocol", self.builder.protocol.to_string())?;
57        self.dir.write("report_desc", &self.builder.report_desc)?;
58        self.dir.write("report_length", self.builder.report_len.to_string())?;
59        self.dir.write("no_out_endpoint", if self.builder.no_out_endpoint { "1" } else { "0" })?;
60
61        Ok(())
62    }
63}
64
65/// USB human interface device (HID) function.
66#[derive(Debug)]
67pub struct Hid {
68    dir: FunctionDir,
69}
70
71impl Hid {
72    /// Creates a new USB human interface device (HID) builder.
73    pub fn builder() -> HidBuilder {
74        HidBuilder { sub_class: 0, protocol: 0, report_desc: Vec::new(), report_len: 0, no_out_endpoint: false }
75    }
76
77    /// Access to registration status.
78    pub fn status(&self) -> Status {
79        self.dir.status()
80    }
81
82    /// Device major and minor numbers.
83    pub fn device(&self) -> Result<(u32, u32)> {
84        self.dir.dev_numbers()
85    }
86
87    /// Device path in `/dev`.
88    pub fn device_path(&self) -> Result<PathBuf> {
89        self.dir.dev_path()
90    }
91}