1 // Copyright 2019 The Chromium OS 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 use base::{ioctl_ior_nr, ioctl_iow_nr, ioctl_with_mut_ref, ioctl_with_ptr, ioctl_with_ref};
6 use data_model::Le32;
7 
8 use super::constants::*;
9 use super::virtio_input_absinfo;
10 use super::virtio_input_bitmap;
11 use super::virtio_input_device_ids;
12 use super::InputError;
13 use super::Result;
14 
15 use std::collections::BTreeMap;
16 use std::os::raw::c_uint;
17 use std::ptr::null;
18 
19 use base::{AsRawDescriptor, Descriptor};
20 
21 const EVDEV: c_uint = 69;
22 
23 #[repr(C)]
24 #[derive(Copy, Clone)]
25 struct evdev_buffer {
26     buffer: [std::os::raw::c_uchar; 128],
27 }
28 
29 impl evdev_buffer {
new() -> evdev_buffer30     fn new() -> evdev_buffer {
31         evdev_buffer { buffer: [0u8; 128] }
32     }
33 
get(&self, bit: usize) -> bool34     fn get(&self, bit: usize) -> bool {
35         let idx = bit / 8;
36         let inner_bit = bit % 8;
37         self.buffer
38             .get(idx)
39             .map_or(false, |val| val & (1u8 << inner_bit) != 0)
40     }
41 }
42 
43 #[repr(C)]
44 #[derive(Copy, Clone)]
45 struct evdev_id {
46     bustype: u16,
47     vendor: u16,
48     product: u16,
49     version: u16,
50 }
51 
52 impl evdev_id {
new() -> evdev_id53     fn new() -> evdev_id {
54         evdev_id {
55             bustype: 0,
56             vendor: 0,
57             product: 0,
58             version: 0,
59         }
60     }
61 }
62 
63 #[repr(C)]
64 #[derive(Copy, Clone)]
65 struct evdev_abs_info {
66     // These should technically by signed ints, but Le32 is only compatible with u32 and we only
67     // forward the bytes but don't care about its actual values.
68     value: u32,
69     minimum: u32,
70     maximum: u32,
71     fuzz: u32,
72     flat: u32,
73     resolution: u32,
74 }
75 
76 impl evdev_abs_info {
new() -> evdev_abs_info77     fn new() -> evdev_abs_info {
78         evdev_abs_info {
79             value: 0,
80             minimum: 0,
81             maximum: 0,
82             fuzz: 0,
83             flat: 0,
84             resolution: 0,
85         }
86     }
87 }
88 
89 impl From<evdev_abs_info> for virtio_input_absinfo {
from(other: evdev_abs_info) -> Self90     fn from(other: evdev_abs_info) -> Self {
91         virtio_input_absinfo {
92             min: Le32::from(other.minimum),
93             max: Le32::from(other.maximum),
94             fuzz: Le32::from(other.fuzz),
95             flat: Le32::from(other.flat),
96         }
97     }
98 }
99 
100 ioctl_ior_nr!(EVIOCGID, EVDEV, 0x02, evdev_id);
101 ioctl_ior_nr!(EVIOCGNAME, EVDEV, 0x06, evdev_buffer);
102 ioctl_ior_nr!(EVIOCGUNIQ, EVDEV, 0x08, evdev_buffer);
103 ioctl_ior_nr!(EVIOCGPROP, EVDEV, 0x09, evdev_buffer);
104 ioctl_ior_nr!(EVIOCGBIT, EVDEV, 0x20 + evt, evdev_buffer, evt);
105 ioctl_ior_nr!(EVIOCGABS, EVDEV, 0x40 + abs, evdev_abs_info, abs);
106 ioctl_iow_nr!(EVIOCGRAB, EVDEV, 0x90, u32);
107 
errno() -> base::Error108 fn errno() -> base::Error {
109     base::Error::last()
110 }
111 
112 /// Gets id information from an event device (see EVIOCGID ioctl for details).
device_ids<T: AsRawDescriptor>(descriptor: &T) -> Result<virtio_input_device_ids>113 pub fn device_ids<T: AsRawDescriptor>(descriptor: &T) -> Result<virtio_input_device_ids> {
114     let mut dev_id = evdev_id::new();
115     let len = unsafe {
116         // Safe because the kernel won't write more than size of evdev_id and we check the return
117         // value
118         ioctl_with_mut_ref(
119             &Descriptor(descriptor.as_raw_descriptor()),
120             EVIOCGID(),
121             &mut dev_id,
122         )
123     };
124     if len < 0 {
125         return Err(InputError::EvdevIdError(errno()));
126     }
127     Ok(virtio_input_device_ids::new(
128         dev_id.bustype,
129         dev_id.vendor,
130         dev_id.product,
131         dev_id.version,
132     ))
133 }
134 
135 /// Gets the name of an event device (see EVIOCGNAME ioctl for details).
name<T: AsRawDescriptor>(descriptor: &T) -> Result<Vec<u8>>136 pub fn name<T: AsRawDescriptor>(descriptor: &T) -> Result<Vec<u8>> {
137     let mut name = evdev_buffer::new();
138     let len = unsafe {
139         // Safe because the kernel won't write more than size of evdev_buffer and we check the
140         // return value
141         ioctl_with_mut_ref(
142             &Descriptor(descriptor.as_raw_descriptor()),
143             EVIOCGNAME(),
144             &mut name,
145         )
146     };
147     if len < 0 {
148         return Err(InputError::EvdevNameError(errno()));
149     }
150     Ok(name.buffer[0..len as usize].to_vec())
151 }
152 
153 /// Gets the unique (serial) name of an event device (see EVIOCGUNIQ ioctl for details).
serial_name<T: AsRawDescriptor>(descriptor: &T) -> Result<Vec<u8>>154 pub fn serial_name<T: AsRawDescriptor>(descriptor: &T) -> Result<Vec<u8>> {
155     let mut uniq = evdev_buffer::new();
156     let len = unsafe {
157         // Safe because the kernel won't write more than size of evdev_buffer and we check the
158         // return value
159         ioctl_with_mut_ref(
160             &Descriptor(descriptor.as_raw_descriptor()),
161             EVIOCGUNIQ(),
162             &mut uniq,
163         )
164     };
165     if len < 0 {
166         return Err(InputError::EvdevSerialError(errno()));
167     }
168     Ok(uniq.buffer[0..len as usize].to_vec())
169 }
170 
171 /// Gets the properties of an event device (see EVIOCGPROP ioctl for details).
properties<T: AsRawDescriptor>(descriptor: &T) -> Result<virtio_input_bitmap>172 pub fn properties<T: AsRawDescriptor>(descriptor: &T) -> Result<virtio_input_bitmap> {
173     let mut props = evdev_buffer::new();
174     let len = unsafe {
175         // Safe because the kernel won't write more than size of evdev_buffer and we check the
176         // return value
177         ioctl_with_mut_ref(
178             &Descriptor(descriptor.as_raw_descriptor()),
179             EVIOCGPROP(),
180             &mut props,
181         )
182     };
183     if len < 0 {
184         return Err(InputError::EvdevPropertiesError(errno()));
185     }
186     Ok(virtio_input_bitmap::new(props.buffer))
187 }
188 
189 /// Gets the event types supported by an event device as well as the event codes supported for each
190 /// type (see EVIOCGBIT ioctl for details).
supported_events<T: AsRawDescriptor>( descriptor: &T, ) -> Result<BTreeMap<u16, virtio_input_bitmap>>191 pub fn supported_events<T: AsRawDescriptor>(
192     descriptor: &T,
193 ) -> Result<BTreeMap<u16, virtio_input_bitmap>> {
194     let mut evts: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
195 
196     let mut evt_types = evdev_buffer::new();
197     let len = unsafe {
198         // Safe because the kernel won't write more than size of evdev_buffer and we check the
199         // return value
200         ioctl_with_mut_ref(
201             &Descriptor(descriptor.as_raw_descriptor()),
202             EVIOCGBIT(0),
203             &mut evt_types,
204         )
205     };
206     if len < 0 {
207         return Err(InputError::EvdevEventTypesError(errno()));
208     }
209 
210     // no need to ask for zero (EV_SYN) since it's always supported and treated as a special case
211     for ev in 1..EV_MAX {
212         if ev == EV_REP || !evt_types.get(ev as usize) {
213             // Event type not supported, skip it.
214             continue;
215         }
216         // Create a new zero-filled buffer every time to avoid carry-overs.
217         let mut evt_codes = evdev_buffer::new();
218         let len = unsafe {
219             // Safe because the kernel won't write more than size of evdev_buffer and we check the
220             // return value
221             ioctl_with_mut_ref(
222                 &Descriptor(descriptor.as_raw_descriptor()),
223                 EVIOCGBIT(ev as c_uint),
224                 &mut evt_codes,
225             )
226         };
227         if len < 0 {
228             return Err(InputError::EvdevEventTypesError(errno()));
229         }
230         evts.insert(ev, virtio_input_bitmap::new(evt_codes.buffer));
231     }
232     Ok(evts)
233 }
234 
235 /// Gets the absolute axes of an event device (see EVIOCGABS ioctl for details).
abs_info<T: AsRawDescriptor>(descriptor: &T) -> BTreeMap<u16, virtio_input_absinfo>236 pub fn abs_info<T: AsRawDescriptor>(descriptor: &T) -> BTreeMap<u16, virtio_input_absinfo> {
237     let mut ret: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
238 
239     for abs in 0..ABS_MAX {
240         // Create a new one, zero-ed out every time to avoid carry-overs.
241         let mut abs_info = evdev_abs_info::new();
242         let len = unsafe {
243             // Safe because the kernel won't write more than size of evdev_buffer and we check the
244             // return value
245             ioctl_with_mut_ref(
246                 &Descriptor(descriptor.as_raw_descriptor()),
247                 EVIOCGABS(abs as c_uint),
248                 &mut abs_info,
249             )
250         };
251         if len > 0 {
252             ret.insert(abs, virtio_input_absinfo::from(abs_info));
253         }
254     }
255     ret
256 }
257 
258 /// Grabs an event device (see EVIOCGGRAB ioctl for details). After this function succeeds the given
259 /// descriptor has exclusive access to the device, effectively making it unusable for any other process in
260 /// the host.
grab_evdev<T: AsRawDescriptor>(descriptor: &mut T) -> Result<()>261 pub fn grab_evdev<T: AsRawDescriptor>(descriptor: &mut T) -> Result<()> {
262     let val: u32 = 1;
263     let ret = unsafe {
264         // Safe because the kernel only read the value of the ptr and we check the return value
265         ioctl_with_ref(
266             &Descriptor(descriptor.as_raw_descriptor()),
267             EVIOCGRAB(),
268             &val,
269         )
270     };
271     if ret == 0 {
272         Ok(())
273     } else {
274         Err(InputError::EvdevGrabError(errno()))
275     }
276 }
277 
ungrab_evdev<T: AsRawDescriptor>(descriptor: &mut T) -> Result<()>278 pub fn ungrab_evdev<T: AsRawDescriptor>(descriptor: &mut T) -> Result<()> {
279     let ret = unsafe {
280         // Safe because the kernel only reads the value of the ptr (doesn't dereference) and
281         // we check the return value
282         ioctl_with_ptr(
283             &Descriptor(descriptor.as_raw_descriptor()),
284             EVIOCGRAB(),
285             null::<u32>(),
286         )
287     };
288     if ret == 0 {
289         Ok(())
290     } else {
291         Err(InputError::EvdevGrabError(errno()))
292     }
293 }
294