1use std::{fs::File, sync::RwLock, thread};
2use std::fmt::{self, Debug};
3use std::fs::OpenOptions;
4use std::io::{BufWriter, Error, ErrorKind, Read, Write};
5use std::path::Path;
6use std::str::FromStr;
7use std::time::Duration;
8
9use num_enum::FromPrimitive;
10use strum_macros::EnumString;
11
12use crate::hid;
13
14pub struct Keyboard {
15 pub keyboard_device_file: File,
16 pub keyboard_path: String,
17}
18
19pub struct KeyboardState {
20 pub keys_down: RwLock<Vec<i32>>,
21 pub modifiers_down: RwLock<Vec<i32>>,
22}
23
24impl Default for KeyboardState {
25 fn default() -> Self {
26 KeyboardState {
27 keys_down: RwLock::new(Vec::new()),
28 modifiers_down: RwLock::new(Vec::new()),
29 }
30 }
31}
32
33#[derive(FromPrimitive, Debug, Clone, Copy)]
35#[repr(i16)]
36enum LinuxKeyCode {
37 #[num_enum(default)]
38 KEYRESERVED = 0,
39 KEYESC = 1,
40 KEY1 = 2,
41 KEY2 = 3,
42 KEY3 = 4,
43 KEY4 = 5,
44 KEY5 = 6,
45 KEY6 = 7,
46 KEY7 = 8,
47 KEY8 = 9,
48 KEY9 = 10,
49 KEY0 = 11,
50 KEYMINUS = 12,
51 KEYEQUAL = 13,
52 KEYBACKSPACE = 14,
53 KEYTAB = 15,
54 KEYQ = 16,
55 KEYW = 17,
56 KEYE = 18,
57 KEYR = 19,
58 KEYT = 20,
59 KEYY = 21,
60 KEYU = 22,
61 KEYI = 23,
62 KEYO = 24,
63 KEYP = 25,
64 KEYLEFTBRACE = 26,
65 KEYRIGHTBRACE = 27,
66 KEYENTER = 28,
67 KEYLEFTCTRL = 29,
68 KEYA = 30,
69 KEYS = 31,
70 KEYD = 32,
71 KEYF = 33,
72 KEYG = 34,
73 KEYH = 35,
74 KEYJ = 36,
75 KEYK = 37,
76 KEYL = 38,
77 KEYSEMICOLON = 39,
78 KEYAPOSTROPHE = 40,
79 KEYGRAVE = 41,
80 KEYLEFTSHIFT = 42,
81 KEYBACKSLASH = 43,
82 KEYZ = 44,
83 KEYX = 45,
84 KEYC = 46,
85 KEYV = 47,
86 KEYB = 48,
87 KEYN = 49,
88 KEYM = 50,
89 KEYCOMMA = 51,
90 KEYDOT = 52,
91 KEYSLASH = 53,
92 KEYRIGHTSHIFT = 54,
93 KEYKPASTERISK = 55,
94 KEYLEFTALT = 56,
95 KEYSPACE = 57,
96 KEYCAPSLOCK = 58,
97 KEYNUMLOCK = 69,
108 KEYSCROLLLOCK = 70,
109 KEYKP7 = 71,
110 KEYKP8 = 72,
111 KEYKP9 = 73,
112 KEYKPMINUS = 74,
113 KEYKP4 = 75,
114 KEYKP5 = 76,
115 KEYKP6 = 77,
116 KEYKPPLUS = 78,
117 KEYKP1 = 79,
118 KEYKP2 = 80,
119 KEYKP3 = 81,
120 KEYKP0 = 82,
121 KEYKPDOT = 83,
122
123 KEYZENKAKUHANKAKU = 85,
124 KEY102ND = 86,
125 KEYRO = 89,
128 KEYKATAKANA = 90,
129 KEYHIRAGANA = 91,
130 KEYHENKAN = 92,
131 KEYKATAKANAHIRAGANA = 93,
132 KEYMUHENKAN = 94,
133 KEYKPJPCOMMA = 95,
134 KEYKPENTER = 96,
135 KEYRIGHTCTRL = 97,
136 KEYKPSLASH = 98,
137 KEYSYSRQ = 99,
138 KEYRIGHTALT = 100,
139 KEYLINEFEED = 101,
140 KEYHOME = 102,
141 KEYUP = 103,
142 KEYPAGEUP = 104,
143 KEYLEFT = 105,
144 KEYRIGHT = 106,
145 KEYEND = 107,
146 KEYDOWN = 108,
147 KEYPAGEDOWN = 109,
148 KEYINSERT = 110,
149 KEYDELETE = 111,
150 KEYMACRO = 112,
151 KEYPOWER = 116,
152 KEYKPEQUAL = 117,
153 KEYKPPLUSMINUS = 118,
154 KEYPAUSE = 119,
155
156 KEYKPCOMMA = 121,
157
158 KEYHANJA = 123,
159 KEYYEN = 124,
160 KEYLEFTMETA = 125,
161 KEYRIGHTMETA = 126,
162 KEYCOMPOSE = 127,
163
164 KEYSTOP = 128,
165 KEYAGAIN = 129,
166 KEYPROPS = 130,
167 KEYUNDO = 131,
168 KEYFRONT = 132,
169 KEYCOPY = 133,
170 KEYOPEN = 134,
171 KEYPASTE = 135,
172 KEYFIND = 136,
173 KEYCUT = 137,
174 KEYHELP = 138,
175 KEYMENU = 139,
176 KEYCALC = 140,
177 KEYSETUP = 141,
178 KEYSLEEP = 142,
179 KEYWAKEUP = 143,
180 KEYFILE = 144,
181 KEYSENDFILE = 145,
182 KEYDELETEFILE = 146,
183 KEYXFER = 147,
184 KEYPROG1 = 148,
185 KEYPROG2 = 149,
186 KEYWWW = 150,
187 KEYFORWARD = 159,
188 KEYCLOSECD = 160,
189 KEYEJECTCD = 161,
190 KEYEJECTCLOSECD = 162,
191 KEYSTOPCD = 166,
192 KEYRECORD = 167,
193 KEYREWIND = 168,
194 KEYPHONE = 169,
195 KEYISO = 170,
196 KEYCONFIG = 171,
197 KEYHOMEPAGE = 172,
198 KEYREFRESH = 173,
199 KEYEXIT = 174,
200 KEYMOVE = 175,
201 KEYEDIT = 176,
202 KEYSCROLLUP = 177,
203 KEYSCROLLDOWN = 178,
204 KEYKPLEFTPAREN = 179,
205 KEYKPRIGHTPAREN = 180,
206 KEYNEW = 181,
207 KEYREDO = 182,
208
209 KEYF13 = 183,
210 KEYF14 = 184,
211 KEYF15 = 185,
212 KEYF16 = 186,
213 KEYF17 = 187,
214 KEYF18 = 188,
215 KEYF19 = 189,
216 KEYF20 = 190,
217 KEYF21 = 191,
218 KEYF22 = 192,
219 KEYF23 = 193,
220 KEYF24 = 194,
221
222 KEYPLAYCD = 200,
223 KEYPAUSECD = 201,
224 KEYPROG3 = 202,
225 KEYPROG4 = 203,
226 KEYSUSPEND = 205,
227 KEYCLOSE = 206,
228 KEYPLAY = 207,
229 KEYFASTFORWARD = 208,
230 KEYBASSBOOST = 209,
231 KEYPRINT = 210,
232 KEYHP = 211,
233 KEYCAMERA = 212,
234 KEYSOUND = 213,
235 KEYQUESTION = 214,
236 KEYEMAIL = 215,
237 KEYCHAT = 216,
238 KEYSEARCH = 217,
239 KEYCONNECT = 218,
240 KEYFINANCE = 219,
241 KEYSPORT = 220,
242 KEYSHOP = 221,
243 KEYALTERASE = 222,
244 KEYCANCEL = 223,
245
246 KEYF1 = 224,
262 KEYF2 = 225,
263 KEYF3 = 120,
264 KEYF4 = 204,
265 KEYF5 = 229,
266 KEYF6 = 230,
267 KEYF7 = 165,
268 KEYF8 = 164,
269 KEYF9 = 163,
270 KEYF10 = 113,
271 KEYF11 = 114,
272 KEYF12 = 115,
273
274 KEYMEDIA = 226,
275
276 KEYSWITCHVIDEOMODE = 227,
277 KEYKBDILLUMTOGGLE = 228,
278
279 KEYSEND = 231,
280 KEYREPLY = 232,
281 KEYFORWARDMAIL = 233,
282 KEYSAVE = 234,
283 KEYDOCUMENTS = 235,
284
285 KEYBATTERY = 236,
286
287 KEYBLUETOOTH = 237,
288 KEYWLAN = 238,
289 KEYUWB = 239,
290
291 KEYUNKNOWN = 240,
292
293 KEYVIDEONEXT = 241,
294 KEYVIDEOPREV = 242,
295 KEYBRIGHTNESSCYCLE = 243,
296 KEYBRIGHTNESSZERO = 244,
297 KEYDISPLAYOFF = 245,
298}
299
300impl fmt::Display for LinuxKeyCode {
301 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
302 write!(f, "{:?}", self)
303 }
304}
305
306#[derive(FromPrimitive, Clone, Copy, EnumString, Debug)]
308#[repr(i16)]
309pub enum UsbKeyCode {
310 #[num_enum(default)]
311 KEYRESERVED = 0x00,
312 KEYA = 0x04,
313 KEYB = 0x05,
314 KEYC = 0x06,
315 KEYD = 0x07,
316 KEYE = 0x08,
317 KEYF = 0x09,
318 KEYG = 0x0a,
319 KEYH = 0x0b,
320 KEYI = 0x0c,
321 KEYJ = 0x0d,
322 KEYK = 0x0e,
323 KEYL = 0x0f,
324 KEYM = 0x10,
325 KEYN = 0x11,
326 KEYO = 0x12,
327 KEYP = 0x13,
328 KEYQ = 0x14,
329 KEYR = 0x15,
330 KEYS = 0x16,
331 KEYT = 0x17,
332 KEYU = 0x18,
333 KEYV = 0x19,
334 KEYW = 0x1a,
335 KEYX = 0x1b,
336 KEYY = 0x1c,
337 KEYZ = 0x1d,
338
339 KEY1 = 0x1e,
340 KEY2 = 0x1f,
341 KEY3 = 0x20,
342 KEY4 = 0x21,
343 KEY5 = 0x22,
344 KEY6 = 0x23,
345 KEY7 = 0x24,
346 KEY8 = 0x25,
347 KEY9 = 0x26,
348 KEY0 = 0x27,
349
350 KEYENTER = 0x28,
351 KEYESC = 0x29,
352 KEYBACKSPACE = 0x2a,
353 KEYTAB = 0x2b,
354 KEYSPACE = 0x2c,
355 KEYMINUS = 0x2d,
356 KEYEQUAL = 0x2e,
357 KEYLEFTBRACE = 0x2f,
358 KEYRIGHTBRACE = 0x30,
359 KEYBACKSLASH = 0x31,
360 KEYHASHTILDE = 0x32,
361 KEYSEMICOLON = 0x33,
362 KEYAPOSTROPHE = 0x34,
363 KEYGRAVE = 0x35,
364 KEYCOMMA = 0x36,
365 KEYDOT = 0x37,
366 KEYSLASH = 0x38,
367 KEYCAPSLOCK = 0x39,
368
369 KEYF1 = 0x3a,
370 KEYF2 = 0x3b,
371 KEYF3 = 0x3c,
372 KEYF4 = 0x3d,
373 KEYF5 = 0x3e,
374 KEYF6 = 0x3f,
375 KEYF7 = 0x40,
376 KEYF8 = 0x41,
377 KEYF9 = 0x42,
378 KEYF10 = 0x43,
379 KEYF11 = 0x44,
380 KEYF12 = 0x45,
381
382 KEYSYSRQ = 0x46,
383 KEYSCROLLLOCK = 0x47,
384 KEYPAUSE = 0x48,
385 KEYINSERT = 0x49,
386 KEYHOME = 0x4a,
387 KEYPAGEUP = 0x4b,
388 KEYDELETE = 0x4c,
389 KEYEND = 0x4d,
390 KEYPAGEDOWN = 0x4e,
391 KEYRIGHT = 0x4f,
392 KEYLEFT = 0x50,
393 KEYDOWN = 0x51,
394 KEYUP = 0x52,
395
396 KEYNUMLOCK = 0x53,
397 KEYKPSLASH = 0x54,
398 KEYKPASTERISK = 0x55,
399 KEYKPMINUS = 0x56,
400 KEYKPPLUS = 0x57,
401 KEYKPENTER = 0x58,
402 KEYKP1 = 0x59,
403 KEYKP2 = 0x5a,
404 KEYKP3 = 0x5b,
405 KEYKP4 = 0x5c,
406 KEYKP5 = 0x5d,
407 KEYKP6 = 0x5e,
408 KEYKP7 = 0x5f,
409 KEYKP8 = 0x60,
410 KEYKP9 = 0x61,
411 KEYKP0 = 0x62,
412 KEYKPDOT = 0x63,
413
414 KEY102ND = 0x64,
415 KEYCOMPOSE = 0x65,
416 KEYPOWER = 0x66,
417 KEYKPEQUAL = 0x67,
418
419 KEYF13 = 0x68,
420 KEYF14 = 0x69,
421 KEYF15 = 0x6a,
422 KEYF16 = 0x6b,
423 KEYF17 = 0x6c,
424 KEYF18 = 0x6d,
425 KEYF19 = 0x6e,
426 KEYF20 = 0x6f,
427 KEYF21 = 0x70,
428 KEYF22 = 0x71,
429 KEYF23 = 0x72,
430 KEYF24 = 0x73,
431
432 KEYOPEN = 0x74,
433 KEYHELP = 0x75,
434 KEYPROPS = 0x76,
435 KEYFRONT = 0x77,
436 KEYSTOP = 0x78,
437 KEYAGAIN = 0x79,
438 KEYUNDO = 0x7a,
439 KEYCUT = 0x7b,
440 KEYCOPY = 0x7c,
441 KEYPASTE = 0x7d,
442 KEYFIND = 0x7e,
443 KEYMUTE = 0x7f,
444 KEYVOLUMEUP = 0x80,
445 KEYVOLUMEDOWN = 0x81,
446}
447
448impl fmt::Display for UsbKeyCode {
449 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
450 write!(f, "{:?}", self)
451 }
452}
453
454#[derive(PartialEq, FromPrimitive, Debug)]
455#[repr(i16)]
456enum EventType {
457 #[num_enum(default)]
458 EvSyn,
459 EvKey,
460 EvRel,
461 EvAbs,
462 EvMsc,
463 EvSw,
464 EvLed,
465 EvSnd,
466 EvRep,
467 EvFf,
468 EvPwr,
469 EvFfStatus,
470}
471
472#[derive(FromPrimitive, Debug)]
473#[repr(i32)]
474enum KeyState {
475 KeyUp,
476 #[num_enum(default)]
477 KeyDown,
478 KeyHold,
479}
480
481#[derive(FromPrimitive, EnumString, Clone, Copy, Debug)]
482#[repr(i32)]
483pub enum KeyCodeModifier {
484 #[num_enum(default)]
485 KEYLEFTCTRL = 0,
486 KEYLEFTSHIFT = 1,
487 KEYLEFTALT = 2,
488 KEYLEFTMETA = 3,
489 KEYRIGHTCTRL = 4,
490 KEYRIGHTSHIFT = 5,
491 KEYRIGHTALT = 6,
492 KEYRIGHTMETA = 7,
493}
494
495impl fmt::Display for KeyCodeModifier {
496 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
497 write!(f, "{:?}", self)
498 }
499}
500
501#[cfg(target_pointer_width = "64")]
502const BUFFER_LENGTH: usize = 24;
503
504#[cfg(target_pointer_width = "32")]
505const BUFFER_LENGTH: usize = 12;
506
507pub fn attempt_read(
508 keyboard: &mut Keyboard,
509 global_keyboard_state: &'static mut KeyboardState,
510 writer: &mut BufWriter<&mut File>
511) -> Result<(), Error> {
512 let mut keyboard_buffer = [0u8; BUFFER_LENGTH];
513
514 let keyboard_read_length = keyboard.keyboard_device_file.read(&mut keyboard_buffer)?;
515
516 if keyboard_read_length >= BUFFER_LENGTH {
517 let mut offset = match BUFFER_LENGTH {
518 24 => 16,
519 12 => 8,
520 _ => 8,
521 };
522
523 let key_type = i16::from_ne_bytes([keyboard_buffer[offset], keyboard_buffer[{ offset += 1; offset }]]);
524 let key_code = i16::from_ne_bytes([keyboard_buffer[{ offset += 1; offset }], keyboard_buffer[{ offset += 1; offset }]]);
525 let key_value = i32::from_ne_bytes([
526 keyboard_buffer[{ offset += 1; offset }],
527 keyboard_buffer[{ offset += 1; offset }],
528 keyboard_buffer[{ offset += 1; offset }],
529 keyboard_buffer[{ offset += 1; offset }],
530 ]);
531
532 let linux_code: LinuxKeyCode = LinuxKeyCode::from(key_code);
533 let usb_code = match UsbKeyCode::from_str(LinuxKeyCode::to_string(&linux_code).as_str()) {
534 Ok(code) => Some(code),
535 Err(_) => None
536 };
537
538 let event_type: EventType = EventType::from(key_type);
539 let key_state: KeyState = KeyState::from(key_value);
540
541 let key_modifier = match KeyCodeModifier::from_str(LinuxKeyCode::to_string(&linux_code).as_str()) {
542 Ok(modifier) => Some(modifier),
543 Err(_) => None
544 };
545
546 if event_type == EventType::EvKey {
547 let mut result: Result<(), Error> = Ok(());
548
549 match key_state {
550 KeyState::KeyDown | KeyState::KeyHold => {
551 match key_modifier {
552 Some(modifier) => {
553 result = add_generic_down(modifier as i32, &global_keyboard_state.modifiers_down);
554 }
555 None => {
556 if let Some(code) = usb_code {
557 result = add_generic_down(code as i32, &global_keyboard_state.keys_down);
558 }
559 }
560 }
561 }
562 KeyState::KeyUp => {
563 match key_modifier {
564 Some(modifier) => {
565 result = remove_generic_down(modifier as i32, &global_keyboard_state.modifiers_down);
566 }
567 None => {
568 if let Some(code) = usb_code {
569 result = remove_generic_down(code as i32, &global_keyboard_state.keys_down);
570 }
571 }
572 }
573 }
574 };
575
576 attempt_flush(global_keyboard_state, writer)?;
577
578 return result;
579 }
580 }
581
582 Ok(())
583}
584
585pub fn attempt_flush(
586 global_keyboard_state: &'static mut KeyboardState,
587 gadget_writer: &mut BufWriter<&mut File>,
588) -> Result<(), Error> {
589 hid::write_keyboard(global_keyboard_state, gadget_writer)
590}
591
592pub fn add_generic_down(key: i32, key_vec: &RwLock<Vec<i32>>) -> Result<(), Error> {
593 if let Ok(generic_keyvec) = key_vec.read() {
594 if generic_keyvec.contains(&(key)) {
595 return Ok(());
596 }
597 }
598
599 if let Ok(mut generic_keyvec_writer) = key_vec.write() {
600 generic_keyvec_writer.push(key);
601
602 return Ok(());
603 }
604
605 Err(Error::new(
606 ErrorKind::Other,
607 String::from("Failed to push key to generic keyvec (Modifier / Key)"),
608 ))
609}
610
611pub fn remove_generic_down(key: i32, key_vec: &RwLock<Vec<i32>>) -> Result<(), Error> {
612 if let Ok(mut key_vec) = key_vec.write() {
613 key_vec.retain(|k| *k != key);
614 return Ok(());
615 }
616
617 Err(Error::new(
618 ErrorKind::Other,
619 String::from("Failed to remove key from generic keyvec (Modifier / Key)"),
620 ))
621}
622
623pub fn check_keyboards(keyboard_inputs: &Vec<String>, keyboard_interfaces: &'static mut Vec<Keyboard>) {
624 for keyboard_input in keyboard_inputs {
625 if keyboard_interfaces.iter().any(|keyboard_interface| &keyboard_interface.keyboard_path == keyboard_input) {
626 thread::sleep(Duration::from_millis(1));
627 continue;
628 }
629
630 let keyboard_path = Path::new(&keyboard_input);
631
632 if Path::exists(keyboard_path) {
633 let keyboard = match OpenOptions::new()
634 .write(true)
635 .read(true)
636 .open(keyboard_path)
637 {
638 Ok(result) => result,
639 Err(_) => {
640 continue;
641 }
642 };
643
644 let mut keyboard_interface = Keyboard {
645 keyboard_device_file: keyboard,
646 keyboard_path: keyboard_input.clone(),
647 };
648
649 _ = write_scancode_set(&mut keyboard_interface);
650
651 keyboard_interfaces.push(keyboard_interface);
652 }
653 }
654}
655
656pub fn is_key_down(
657 key: UsbKeyCode,
658 global_keyboard_state: &&'static mut KeyboardState,
659) -> bool {
660 if let Ok(keyboard_state) = global_keyboard_state.keys_down.try_read() {
661 return keyboard_state.contains(&(key as i32));
662 }
663
664 false
665}
666
667pub fn is_modifier_down(
668 modifier: KeyCodeModifier,
669 global_keyboard_state: &&'static mut KeyboardState,
670) -> bool {
671 if let Ok(modifiers_down) = global_keyboard_state.modifiers_down.try_read() {
672 return modifiers_down.contains(&(modifier as i32));
673 }
674
675 false
676}
677
678pub fn write_scancode_set(keyboard: &mut Keyboard) -> Result<(), Error> {
680 let keyboard_scancode_packet: [u8; 2] = [0xF0, 2];
681
682 match keyboard.keyboard_device_file.write_all(&keyboard_scancode_packet) {
683 Ok(_) => {
684 match keyboard.keyboard_device_file.flush() {
685 Ok(_) => Ok(()),
686 Err(err) => Err(err),
687 }
688 }
689 Err(err) => Err(err)
690 }
691}