• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! This library provides access to Linux uhid.
2 
3 use bt_topshim::btif::{DisplayAddress, RawAddress};
4 use log::{debug, error};
5 use std::fs::File;
6 use uhid_virt::{Bus, CreateParams, UHIDDevice};
7 
8 const VID_DEFAULT: u32 = 0x0000;
9 const PID_DEFAULT: u32 = 0x0000;
10 
11 // Report descriptor for a standard mouse
12 const RDESC: [u8; 34] = [
13     0x05, 0x01, // USAGE_PAGE (Generic Desktop)
14     0x09, 0x02, // USAGE (Mouse)
15     0xa1, 0x01, // COLLECTION (Application)
16     0x09, 0x01, //   USAGE (Pointer)
17     0xa1, 0x00, //   COLLECTION (Physical)
18     0x05, 0x09, //     USAGE_PAGE (Button)
19     0x19, 0x01, //     USAGE_MINIMUM (Button 1)
20     0x29, 0x01, //     USAGE_MAXIMUM (Button 1)
21     0x15, 0x00, //     LOGICAL_MINIMUM (0)
22     0x25, 0x01, //     LOGICAL_MAXIMUM (1)
23     0x95, 0x01, //     REPORT_COUNT (1)
24     0x75, 0x01, //     REPORT_SIZE (1)
25     0x81, 0x02, //     INPUT (Data,Var,Abs)
26     0x95, 0x01, //     REPORT_COUNT (1)
27     0x75, 0x07, //     REPORT_SIZE (7)
28     0x81, 0x03, //     INPUT (Cnst,Var,Abs)
29     0xc0, //   END_COLLECTION
30     0xc0, // END_COLLECTION
31 ];
32 
33 pub struct UHid {
34     /// Open UHID objects.
35     devices: Vec<UHIDDevice<File>>,
36 }
37 
38 impl Drop for UHid {
drop(&mut self)39     fn drop(&mut self) {
40         self.clear();
41     }
42 }
43 
44 impl UHid {
45     /// Create a new UHid struct that holds a vector of uhid objects.
new() -> Self46     pub fn new() -> Self {
47         UHid { devices: Vec::<UHIDDevice<File>>::new() }
48     }
49 
50     /// Initialize a uhid device with kernel.
create( &mut self, name: String, phys: RawAddress, uniq: RawAddress, ) -> Result<(), String>51     pub fn create(
52         &mut self,
53         name: String,
54         phys: RawAddress,
55         uniq: RawAddress,
56     ) -> Result<(), String> {
57         debug!(
58             "Create a UHID {} with phys: {}, uniq: {}",
59             name,
60             DisplayAddress(&phys),
61             DisplayAddress(&uniq)
62         );
63         let rd_data = RDESC.to_vec();
64         let create_params = CreateParams {
65             name,
66             phys: phys.to_string().to_lowercase(),
67             uniq: uniq.to_string().to_lowercase(),
68             bus: Bus::BLUETOOTH,
69             vendor: VID_DEFAULT,
70             product: PID_DEFAULT,
71             version: 0,
72             country: 0,
73             rd_data,
74         };
75         match UHIDDevice::create(create_params) {
76             Ok(d) => self.devices.push(d),
77             Err(e) => return Err(e.to_string()),
78         }
79         Ok(())
80     }
81 
82     /// Destroy open UHID devices and clear the storage.
clear(&mut self)83     pub fn clear(&mut self) {
84         for device in self.devices.iter_mut() {
85             match device.destroy() {
86                 Err(e) => error!("Fail to destroy uhid {}", e),
87                 Ok(_) => (),
88             }
89         }
90         self.devices.clear();
91     }
92 
93     /// Return if the UHID vector is empty.
is_empty(&self) -> bool94     pub fn is_empty(&self) -> bool {
95         self.devices.is_empty()
96     }
97 }
98