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