• 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 #[derive(Default)]
34 pub struct UHid {
35     /// Open UHID objects.
36     devices: Vec<UHIDDevice<File>>,
37 }
38 
39 impl Drop for UHid {
drop(&mut self)40     fn drop(&mut self) {
41         self.clear();
42     }
43 }
44 
45 impl UHid {
46     /// Create a new UHid struct that holds a vector of uhid objects.
new() -> Self47     pub fn new() -> Self {
48         Default::default()
49     }
50 
51     /// Initialize a uhid device with kernel.
create( &mut self, name: String, phys: RawAddress, uniq: RawAddress, ) -> Result<(), String>52     pub fn create(
53         &mut self,
54         name: String,
55         phys: RawAddress,
56         uniq: RawAddress,
57     ) -> Result<(), String> {
58         debug!(
59             "Create a UHID {} with phys: {}, uniq: {}",
60             name,
61             DisplayAddress(&phys),
62             DisplayAddress(&uniq)
63         );
64         let rd_data = RDESC.to_vec();
65         let create_params = CreateParams {
66             name,
67             phys: phys.to_string().to_lowercase(),
68             uniq: uniq.to_string().to_lowercase(),
69             bus: Bus::BLUETOOTH,
70             vendor: VID_DEFAULT,
71             product: PID_DEFAULT,
72             version: 0,
73             country: 0,
74             rd_data,
75         };
76         match UHIDDevice::create(create_params) {
77             Ok(d) => self.devices.push(d),
78             Err(e) => return Err(e.to_string()),
79         }
80         Ok(())
81     }
82 
83     /// Destroy open UHID devices and clear the storage.
clear(&mut self)84     pub fn clear(&mut self) {
85         for device in self.devices.iter_mut() {
86             match device.destroy() {
87                 Err(e) => error!("Fail to destroy uhid {}", e),
88                 Ok(_) => (),
89             }
90         }
91         self.devices.clear();
92     }
93 
94     /// Return if the UHID vector is empty.
is_empty(&self) -> bool95     pub fn is_empty(&self) -> bool {
96         self.devices.is_empty()
97     }
98 }
99