1use std::ffi;
2use std::io;
3use std::iter::repeat;
4use std::mem;
5use std::slice;
6
7use bytes::BytesMut;
8use slog;
9
10use character_device::{Decoder, Encoder};
11use uhid_sys as sys;
12
13quick_error! {
14 #[derive(Debug)]
15 pub enum StreamError {
16 Io(err: io::Error) {
17 from()
18 }
19 UnknownEventType(event_type_value: u32) {
20 description("Unknown/Unsupported event type")
21 display(r#"Unknown/Unsupported event type: "{}""#, event_type_value)
22 }
23 BufferOverflow(data_size: usize, max_size: usize) {
24 description("Size exceeds available space.")
25 display(r#"Size "{}" exceeds available space "{}""#, data_size, max_size)
26 }
27 Nul(err: ffi::NulError) {
28 from()
29 }
30 Unknown
31 }
32}
33
34bitflags! {
35 pub struct DevFlags: u64 {
36 const NUMBERED_FEATURE_REPORTS = 0b00000001;
37 const NUMBERED_OUTPUT_REPORTS = 0b00000010;
38 const NUMBERED_INPUT_REPORTS = 0b00000100;
39 }
40}
41
42#[allow(non_camel_case_types)]
43#[derive(Debug)]
44pub enum ReportType {
45 Feature = 0,
46 Output = 1,
47 Input = 2,
48}
49
50#[allow(non_camel_case_types)]
51pub enum Bus {
52 PCI = 1,
53 ISAPNP = 2,
54 USB = 3,
55 HIL = 4,
56 BLUETOOTH = 5,
57 VIRTUAL = 6,
58 ISA = 16,
59 I8042 = 17,
60 XTKBD = 18,
61 RS232 = 19,
62 GAMEPORT = 20,
63 PARPORT = 21,
64 AMIGA = 22,
65 ADB = 23,
66 I2C = 24,
67 HOST = 25,
68 GSC = 26,
69 ATARI = 27,
70 SPI = 28,
71 RMI = 29,
72 CEC = 30,
73 INTEL_ISHTP = 31,
74}
75
76pub enum InputEvent {
77 Create {
78 name: String,
79 phys: String,
80 uniq: String,
81 bus: Bus,
82 vendor: u32,
83 product: u32,
84 version: u32,
85 country: u32,
86 data: Vec<u8>,
87 },
88 Destroy,
89 Input {
90 data: Vec<u8>,
91 },
92 GetReportReply {
93 id: u32,
94 err: u16,
95 data: Vec<u8>,
96 },
97 SetReportReply {
98 id: u32,
99 err: u16,
100 },
101}
102
103pub enum OutputEvent {
104 Start {
105 dev_flags: DevFlags,
106 },
107 Stop,
108 Open,
109 Close,
110 Output {
111 data: Vec<u8>,
112 },
113 GetReport {
114 id: u32,
115 report_number: u8,
116 report_type: ReportType,
117 },
118 SetReport {
119 id: u32,
120 report_number: u8,
121 report_type: ReportType,
122 data: Vec<u8>,
123 },
124}
125
126impl slog::Value for OutputEvent {
127 fn serialize(
128 &self,
129 record: &slog::Record,
130 key: slog::Key,
131 serializer: &mut slog::Serializer,
132 ) -> slog::Result {
133 match self {
134 &OutputEvent::Start { .. } => "Start",
135 &OutputEvent::Stop => "Stop",
136 &OutputEvent::Open => "Open",
137 &OutputEvent::Close => "Close",
138 &OutputEvent::Output { .. } => "Output",
139 &OutputEvent::GetReport { .. } => "GetReport",
140 &OutputEvent::SetReport { .. } => "SetReport",
141 }.serialize(record, key, serializer)
142 }
143}
144
145#[derive(Debug, Default)]
146pub struct UHIDCodec;
147
148impl InputEvent {
149 fn to_uhid_event(self) -> Result<sys::uhid_event, StreamError> {
150 let mut event: sys::uhid_event = unsafe { mem::zeroed() };
151
152 match self {
153 InputEvent::Create {
154 name,
155 phys,
156 uniq,
157 bus,
158 vendor,
159 product,
160 version,
161 country,
162 data,
163 } => {
164 event.type_ = sys::uhid_event_type_UHID_CREATE2 as u32;
165 unsafe {
166 let payload = &mut event.u.create2;
167 copy_as_cstr(name, &mut payload.name)?;
168 copy_as_cstr(phys, &mut payload.phys)?;
169 copy_as_cstr(uniq, &mut payload.uniq)?;
170 payload.rd_size = copy_bytes_sized(data, &mut payload.rd_data)? as u16;
171 payload.bus = bus as u16;
172 payload.vendor = vendor;
173 payload.product = product;
174 payload.version = version;
175 payload.country = country;
176 }
177 }
178 InputEvent::Destroy => {
179 event.type_ = sys::uhid_event_type_UHID_DESTROY as u32;
180 }
181 InputEvent::Input { data } => {
182 event.type_ = sys::uhid_event_type_UHID_INPUT2 as u32;
183 unsafe {
184 let payload = &mut event.u.input2;
185 payload.size = copy_bytes_sized(data, &mut payload.data)? as u16;
186 }
187 }
188 InputEvent::GetReportReply { err, data, .. } => {
189 event.type_ = sys::uhid_event_type_UHID_GET_REPORT_REPLY as u32;
190 unsafe {
191 let payload = &mut event.u.get_report_reply;
192 payload.err = err;
193 payload.size = copy_bytes_sized(data, &mut payload.data)? as u16;
194 }
195 }
196 InputEvent::SetReportReply { err, .. } => {
197 event.type_ = sys::uhid_event_type_UHID_SET_REPORT_REPLY as u32;
198 unsafe {
199 let payload = &mut event.u.set_report_reply;
200 payload.err = err;
201 }
202 }
203 };
204
205 Ok(event)
206 }
207}
208
209fn copy_bytes_sized(src: Vec<u8>, dst: &mut [u8]) -> Result<usize, StreamError> {
210 let src_size = src.len();
211 let dst_size = dst.len();
212
213 if src_size > dst_size {
214 return Err(StreamError::BufferOverflow(src_size, dst_size));
215 }
216
217 dst.get_mut(0..src_size)
218 .unwrap()
219 .copy_from_slice(src.as_slice());
220 Ok(src_size)
221}
222
223fn copy_as_cstr(string: String, dst: &mut [u8]) -> Result<(), StreamError> {
224 let mut src: Vec<u8> = ffi::CString::new(string)?.into_bytes_with_nul();
225 let src_size = src.len();
226 let dst_size = dst.len();
227
228 if src_size >= dst_size {
229 return Err(StreamError::BufferOverflow(src_size, dst_size));
230 }
231
232 src.extend(repeat(0).take(dst_size - src_size));
233 dst.copy_from_slice(src.as_slice());
234 Ok(())
235}
236
237fn decode_event(event: sys::uhid_event) -> Result<OutputEvent, StreamError> {
238 if let Some(event_type) = to_uhid_event_type(event.type_) {
239 match event_type {
240 sys::uhid_event_type_UHID_START => Ok(unsafe {
241 let payload = &event.u.start;
242 OutputEvent::Start {
243 dev_flags: mem::transmute(payload.dev_flags),
244 }
245 }),
246 sys::uhid_event_type_UHID_STOP => Ok(OutputEvent::Stop),
247 sys::uhid_event_type_UHID_OPEN => Ok(OutputEvent::Open),
248 sys::uhid_event_type_UHID_CLOSE => Ok(OutputEvent::Close),
249 sys::uhid_event_type_UHID_OUTPUT => Ok(unsafe {
250 let payload = &event.u.output;
251 assert_eq!(
252 payload.rtype,
253 sys::uhid_report_type_UHID_OUTPUT_REPORT as u8
254 );
255 OutputEvent::Output {
256 data: slice::from_raw_parts(
257 &payload.data[0] as *const u8,
258 payload.size as usize,
259 ).to_vec(),
260 }
261 }),
262 sys::uhid_event_type_UHID_GET_REPORT => Ok(unsafe {
263 let payload = &event.u.get_report;
264 OutputEvent::GetReport {
265 id: payload.id,
266 report_number: payload.rnum,
267 report_type: mem::transmute(payload.rtype),
268 }
269 }),
270 sys::uhid_event_type_UHID_SET_REPORT => Ok(unsafe {
271 let payload = &event.u.set_report;
272 OutputEvent::SetReport {
273 id: payload.id,
274 report_number: payload.rnum,
275 report_type: mem::transmute(payload.rtype),
276 data: slice::from_raw_parts(
277 &payload.data[0] as *const u8,
278 payload.size as usize,
279 ).to_vec(),
280 }
281 }),
282 _ => Err(StreamError::UnknownEventType(event.type_)),
283 }
284 } else {
285 Err(StreamError::UnknownEventType(event.type_))
286 }
287}
288
289fn to_uhid_event_type(value: u32) -> Option<sys::uhid_event_type> {
290 let last_valid_value = sys::uhid_event_type_UHID_SET_REPORT_REPLY as u32;
291 if value <= last_valid_value {
292 Some(unsafe { mem::transmute(value) })
293 } else {
294 None
295 }
296}
297
298fn read_event(src: &mut BytesMut) -> Option<sys::uhid_event> {
299 let uhid_event_size = mem::size_of::<sys::uhid_event>();
300 if src.len() >= uhid_event_size {
301 let bytes = src.split_to(uhid_event_size);
302 let ptr = bytes.as_ptr();
303 Some(unsafe { *mem::transmute::<*const u8, &sys::uhid_event>(ptr) })
304 } else {
305 None
306 }
307}
308
309fn encode_event(event: &sys::uhid_event) -> &[u8] {
310 unsafe { as_u8_slice(event) }
311}
312
313unsafe fn as_u8_slice<T: Sized>(p: &T) -> &[u8] {
314 slice::from_raw_parts((p as *const T) as *const u8, mem::size_of::<T>())
315}
316
317impl Decoder for UHIDCodec {
318 type Item = OutputEvent;
319 type Error = StreamError;
320
321 fn decode(&mut self, src: &mut BytesMut) -> Result<Self::Item, Self::Error> {
322 if let Some(event) = read_event(src) {
323 Ok(decode_event(event)?)
324 } else {
325 Err(StreamError::Unknown)
326 }
327 }
328
329 fn read_len(&self) -> usize {
330 mem::size_of::<sys::uhid_event>()
331 }
332}
333
334impl Encoder for UHIDCodec {
335 type Item = InputEvent;
336 type Error = StreamError;
337
338 fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
339 let event = item.to_uhid_event()?;
340 dst.extend_from_slice(encode_event(&event));
341 Ok(())
342 }
343}
344
345#[cfg(test)]
346mod tests {
347 use super::*;
348
349 const RDESC: [u8; 85] = [
350 0x05, 0x01 , 0x09, 0x02 ,
351 0xa1, 0x01 , 0x09, 0x01 ,
352 0xa1, 0x00 , 0x85, 0x01 , 0x05,
353 0x09 , 0x19, 0x01 , 0x29,
354 0x03 , 0x15, 0x00 , 0x25,
355 0x01 , 0x95, 0x03 , 0x75,
356 0x01 , 0x81, 0x02 , 0x95,
357 0x01 , 0x75, 0x05 , 0x81,
358 0x01 , 0x05, 0x01 ,
359 0x09, 0x30 , 0x09, 0x31 , 0x09,
360 0x38 , 0x15, 0x81 , 0x25,
361 0x7f , 0x75, 0x08 , 0x95,
362 0x03 , 0x81, 0x06 ,
363 0xc0 , 0xc0 , 0x05,
364 0x01 , 0x09, 0x06 , 0xa1,
365 0x01 , 0x85, 0x02 , 0x05,
366 0x08 , 0x19, 0x01 , 0x29,
367 0x03 , 0x15, 0x00 , 0x25,
368 0x01 , 0x95, 0x03 , 0x75,
369 0x01 , 0x91, 0x02 , 0x95,
370 0x01 , 0x75, 0x05 , 0x91,
371 0x01 , 0xc0 ,
372 ];
373
374 fn assert_bytes_eq(actual: &[u8], expected: &[u8]) {
375 assert_eq!(actual.len(), expected.len(), "Size of slices differs");
376 for index in 0..actual.len() {
377 assert_eq!(
378 actual[index],
379 expected[index],
380 "Bytes differ at index {}",
381 index
382 );
383 }
384 }
385
386 #[test]
387 fn encode_create_request() {
388 let mut expected = vec![0; mem::size_of::<sys::uhid_event>()];
389 expected[0] = 0x0b;
390 expected[4] = 0x74;
391 expected[5] = 0x65;
392 expected[6] = 0x73;
393 expected[7] = 0x74;
394 expected[8] = 0x2d;
395 expected[9] = 0x75;
396 expected[10] = 0x68;
397 expected[11] = 0x69;
398 expected[12] = 0x64;
399 expected[13] = 0x2d;
400 expected[14] = 0x64;
401 expected[15] = 0x65;
402 expected[16] = 0x76;
403 expected[17] = 0x69;
404 expected[18] = 0x63;
405 expected[19] = 0x65;
406 expected[260] = 0x55;
407 expected[262] = 0x03;
408 expected[264] = 0xd9;
409 expected[265] = 0x15;
410 expected[268] = 0x37;
411 expected[269] = 0x0a;
412 expected[280] = 0x05;
413 expected[281] = 0x01;
414 expected[282] = 0x09;
415 expected[283] = 0x02;
416 expected[284] = 0xa1;
417 expected[285] = 0x01;
418 expected[286] = 0x09;
419 expected[287] = 0x01;
420 expected[288] = 0xa1;
421 expected[290] = 0x85;
422 expected[291] = 0x01;
423 expected[292] = 0x05;
424 expected[293] = 0x09;
425 expected[294] = 0x19;
426 expected[295] = 0x01;
427 expected[296] = 0x29;
428 expected[297] = 0x03;
429 expected[298] = 0x15;
430 expected[300] = 0x25;
431 expected[301] = 0x01;
432 expected[302] = 0x95;
433 expected[303] = 0x03;
434 expected[304] = 0x75;
435 expected[305] = 0x01;
436 expected[306] = 0x81;
437 expected[307] = 0x02;
438 expected[308] = 0x95;
439 expected[309] = 0x01;
440 expected[310] = 0x75;
441 expected[311] = 0x05;
442 expected[312] = 0x81;
443 expected[313] = 0x01;
444 expected[314] = 0x05;
445 expected[315] = 0x01;
446 expected[316] = 0x09;
447 expected[317] = 0x30;
448 expected[318] = 0x09;
449 expected[319] = 0x31;
450 expected[320] = 0x09;
451 expected[321] = 0x38;
452 expected[322] = 0x15;
453 expected[323] = 0x81;
454 expected[324] = 0x25;
455 expected[325] = 0x7f;
456 expected[326] = 0x75;
457 expected[327] = 0x08;
458 expected[328] = 0x95;
459 expected[329] = 0x03;
460 expected[330] = 0x81;
461 expected[331] = 0x06;
462 expected[332] = 0xc0;
463 expected[333] = 0xc0;
464 expected[334] = 0x05;
465 expected[335] = 0x01;
466 expected[336] = 0x09;
467 expected[337] = 0x06;
468 expected[338] = 0xa1;
469 expected[339] = 0x01;
470 expected[340] = 0x85;
471 expected[341] = 0x02;
472 expected[342] = 0x05;
473 expected[343] = 0x08;
474 expected[344] = 0x19;
475 expected[345] = 0x01;
476 expected[346] = 0x29;
477 expected[347] = 0x03;
478 expected[348] = 0x15;
479 expected[350] = 0x25;
480 expected[351] = 0x01;
481 expected[352] = 0x95;
482 expected[353] = 0x03;
483 expected[354] = 0x75;
484 expected[355] = 0x01;
485 expected[356] = 0x91;
486 expected[357] = 0x02;
487 expected[358] = 0x95;
488 expected[359] = 0x01;
489 expected[360] = 0x75;
490 expected[361] = 0x05;
491 expected[362] = 0x91;
492 expected[363] = 0x01;
493 expected[364] = 0xc0;
494 let mut result = BytesMut::new();
495
496 UHIDCodec
497 .encode(
498 InputEvent::Create {
499 name: String::from("test-uhid-device"),
500 phys: String::from(""),
501 uniq: String::from(""),
502 bus: Bus::USB,
503 vendor: 0x15d9,
504 product: 0x0a37,
505 version: 0,
506 country: 0,
507 data: RDESC.to_vec(),
508 },
509 &mut result,
510 )
511 .unwrap();
512
513 assert_bytes_eq(&result[..], &expected);
514 }
515
516 #[test]
517 fn encode_destroy_request() {
518 let mut expected = vec![0; mem::size_of::<sys::uhid_event>()];
519 expected[0] = 0x01;
520 let mut result = BytesMut::new();
521
522 UHIDCodec.encode(InputEvent::Destroy, &mut result).unwrap();
523
524 assert_bytes_eq(&result[..], &expected);
525 }
526}