1#![allow(unused)]
10
11#[cfg(feature = "hardware")]
12mod hardware;
13#[cfg(feature = "hardware")]
14pub use hardware::lk201::{LK201Hardware, ScanCell};
15#[cfg(feature = "hardware")]
16pub use hardware::lk250::{LK250Hardware, Lk250Mode};
17
18mod software;
19pub use software::{LK201, LK201Sender};
20
21mod keys;
22
23pub use keys::{ALL_KEYS, Key, SpecialKey};
24use std::{collections::VecDeque, fmt, sync::mpsc};
25
26use tracing::trace;
27
28#[derive(Clone, Copy, PartialEq, Eq)]
40pub struct Led(u8);
41
42impl Led {
43 pub fn new(byte: u8) -> Self {
44 Led(byte)
45 }
46
47 pub fn is_wait(&self) -> bool {
48 self.0 & 0x01 == 0x01
49 }
50
51 pub fn is_compose(&self) -> bool {
52 self.0 & 0x02 == 0x02
53 }
54
55 pub fn is_lock(&self) -> bool {
56 self.0 & 0x04 == 0x04
57 }
58
59 pub fn is_hold(&self) -> bool {
60 self.0 & 0x08 == 0x08
61 }
62
63 pub fn is_all(&self) -> bool {
64 self.0 & 0x0F == 0x0F
65 }
66}
67
68impl fmt::Debug for Led {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 write!(f, "Led({:02X}=", self.0)?;
71 let mut first = true;
72 for led in [
73 ("Wait", self.is_wait()),
74 ("Compose", self.is_compose()),
75 ("Lock", self.is_lock()),
76 ("Hold", self.is_hold()),
77 ] {
78 if led.1 {
79 if first {
80 first = false;
81 } else {
82 write!(f, "+")?;
83 }
84 write!(f, "{}", led.0)?;
85 }
86 }
87 write!(f, ")")?;
88 Ok(())
89 }
90}
91
92#[derive(Debug, Clone, Copy, PartialEq, Eq)]
94pub enum KeyMode {
95 Down = 0x80,
97 AutoDown = 0x82,
99 Illegal = 0x84,
101 UpDown = 0x86,
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq)]
107pub struct Division(pub u8);
108
109impl Division {
110 pub fn new(div: u8) -> Option<Self> {
111 if div <= 14 && div > 0 {
112 Some(Division(div))
113 } else {
114 None
115 }
116 }
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq)]
121pub struct AutoRepeatRegister(pub u8);
122
123impl AutoRepeatRegister {
124 pub fn new(reg: u8) -> Option<Self> {
125 if reg <= 3 {
126 Some(AutoRepeatRegister(reg))
127 } else {
128 None
129 }
130 }
131}
132
133#[derive(Debug, Clone, Copy, PartialEq, Eq)]
135pub struct Volume(pub u8);
136
137impl Volume {
138 pub fn new(level: u8) -> Option<Self> {
139 if level <= 7 {
140 Some(Volume(level))
141 } else {
142 None
143 }
144 }
145
146 pub fn as_param_byte(self) -> u8 {
147 0x80 | (self.0 & 0x7)
148 }
149}
150
151#[derive(Debug, Copy, Clone, PartialEq, Eq)]
153pub enum LK201Command {
154 LedEnable(Led),
157 LedDisable(Led),
159
160 KeyClickEnable(Volume),
163 CtrlKeyClickEnable,
165 KeyClickDisable,
167 CtrlKeyClickDisable,
169 SoundClick,
171
172 BellEnable(Volume),
175 BellDisable,
177 RingBell,
179
180 SetMode { mode: KeyMode, division: Division },
183 SetModeWithAutoRepeat {
185 mode: KeyMode,
186 division: Division,
187 register: AutoRepeatRegister,
188 },
189 RepeatToDown,
191 EnableRepeat,
193 DisableRepeat,
195 EnableLK401,
197 DisableLK401,
199 TempNoRepeat,
201
202 SetAutoRepeat {
205 register: AutoRepeatRegister,
206 timeout: u8,
208 rate: u8,
210 },
211
212 PowerUp,
215 RequestId,
217 SetDefaults,
219 TestMode,
221 TestExit,
223
224 Inhibit,
227 Resume,
229
230 Unknown(u8),
232 Unknown2(u8, u8),
234 Unknown3(u8, u8, u8),
236}
237
238impl LK201Command {
239 pub fn len(&self) -> usize {
241 match self {
242 LK201Command::LedEnable(_) => 2,
243 LK201Command::LedDisable(_) => 2,
244 LK201Command::KeyClickEnable(_) => 2,
245 LK201Command::CtrlKeyClickEnable => 1,
246 LK201Command::KeyClickDisable => 1,
247 LK201Command::CtrlKeyClickDisable => 1,
248 LK201Command::SoundClick => 1,
249 LK201Command::BellEnable(_) => 2,
250 LK201Command::BellDisable => 1,
251 LK201Command::RingBell => 1,
252 LK201Command::SetMode { .. } => 1,
253 LK201Command::SetModeWithAutoRepeat { .. } => 2,
254 LK201Command::RepeatToDown => 1,
255 LK201Command::EnableRepeat => 1,
256 LK201Command::DisableRepeat => 1,
257 LK201Command::EnableLK401 => 1,
258 LK201Command::DisableLK401 => 1,
259 LK201Command::TempNoRepeat => 1,
260 LK201Command::SetAutoRepeat { .. } => 3,
261 LK201Command::PowerUp => 1,
262 LK201Command::RequestId => 1,
263 LK201Command::SetDefaults => 1,
264 LK201Command::TestMode => 1,
265 LK201Command::TestExit => 1,
266 LK201Command::Inhibit => 1,
267 LK201Command::Resume => 1,
268 LK201Command::Unknown(_) => 1,
269 LK201Command::Unknown2(_, _) => 2,
270 LK201Command::Unknown3(_, _, _) => 3,
271 }
272 }
273
274 pub fn response(&self) -> Option<LK201Response> {
283 Some(match self {
284 LK201Command::PowerUp => LK201Response::PowerUpSelfTest {
286 keyboard_id_firmware: 0x01, keyboard_id_hardware: 0x00, error: PowerUpError::NoError,
289 keycode: 0,
290 },
291 LK201Command::RequestId => LK201Response::KeyboardId {
292 firmware_id: 0x01, hardware_id: 0x01, },
295
296 LK201Command::SetMode { .. } => LK201Response::ModeChangeAck,
299 LK201Command::SetModeWithAutoRepeat { .. } => LK201Response::ModeChangeAck,
300 LK201Command::TempNoRepeat => LK201Response::ModeChangeAck,
301 LK201Command::SetDefaults => LK201Response::ModeChangeAck,
302
303 LK201Command::TestMode => LK201Response::TestModeAck,
305 LK201Command::Inhibit => LK201Response::KeyboardLockAck,
306
307 LK201Command::Unknown(_) => LK201Response::InputError,
309 LK201Command::Unknown2(_, _) => LK201Response::InputError,
310 LK201Command::Unknown3(_, _, _) => LK201Response::InputError,
311
312 _ => return None,
314 })
315 }
316}
317
318impl TryFrom<&VecDeque<u8>> for LK201Command {
319 type Error = ();
320
321 fn try_from(value: &VecDeque<u8>) -> Result<Self, Self::Error> {
322 let Some(&byte0) = value.get(0) else {
323 return Err(());
324 };
325
326 match byte0 {
327 0x13 => {
329 let Some(&led_byte) = value.get(1) else {
330 return Err(());
331 };
332 let led = Led::new(led_byte);
333 Ok(LK201Command::LedEnable(led))
334 }
335 0x11 => {
336 let Some(&led_byte) = value.get(1) else {
337 return Err(());
338 };
339 let led = Led::new(led_byte);
340 Ok(LK201Command::LedDisable(led))
341 }
342
343 0x1B => {
345 let Some(&vol_byte) = value.get(1) else {
346 return Err(());
347 };
348 let Some(volume) = Volume::new((vol_byte & 0x7) as u8) else {
349 return Ok(LK201Command::Unknown2(0x1B, vol_byte));
350 };
351 Ok(LK201Command::KeyClickEnable(volume))
352 }
353 0xBB => Ok(LK201Command::CtrlKeyClickEnable),
354 0x99 => Ok(LK201Command::KeyClickDisable),
355 0xB9 => Ok(LK201Command::CtrlKeyClickDisable),
356 0x9F => Ok(LK201Command::SoundClick),
357 0x80 => Ok(LK201Command::TestExit),
358
359 0x23 => {
361 let Some(&vol_byte) = value.get(1) else {
362 return Err(());
363 };
364 let Some(volume) = Volume::new((vol_byte & 0x7) as u8) else {
365 return Ok(LK201Command::Unknown2(0x23, vol_byte));
366 };
367 Ok(LK201Command::BellEnable(volume))
368 }
369 0xA1 => Ok(LK201Command::BellDisable),
370 0xA7 => Ok(LK201Command::RingBell),
371
372 0x78..=0x7F if (byte0 >> 3) & 0xF == 0xF => {
374 let Some(&timeout) = value.get(1) else {
375 return Err(());
376 };
377 let Some(&rate) = value.get(2) else {
378 return Err(());
379 };
380 let Some(register) = AutoRepeatRegister::new((byte0 >> 1) & 0x3) else {
381 return Ok(LK201Command::Unknown2(0x78, byte0));
382 };
383 Ok(LK201Command::SetAutoRepeat {
384 register,
385 timeout: timeout & 0x7F,
386 rate: rate & 0x7F,
387 })
388 }
389
390 b if (b & 0x01) == 0 => {
395 let division_bits = (b >> 3) & 0xF;
397 let mode_bits = (b >> 1) & 0x3;
398 let has_param = (b & 0x80) == 0;
399
400 if division_bits <= 14 {
402 let Some(division) = Division::new(division_bits) else {
403 return Ok(LK201Command::Unknown(b));
404 };
405 let mode = match mode_bits {
406 0b00 => KeyMode::Down,
407 0b01 => KeyMode::AutoDown,
408 0b11 => KeyMode::UpDown,
409 _ => return Ok(LK201Command::Unknown(b)),
410 };
411
412 if has_param {
414 let Some(¶m_byte) = value.get(1) else {
416 return Err(());
417 };
418 let Some(register) = AutoRepeatRegister::new(param_byte & 0x3) else {
419 return Ok(LK201Command::Unknown2(b, param_byte));
420 };
421 return Ok(LK201Command::SetModeWithAutoRepeat {
422 mode,
423 division,
424 register,
425 });
426 } else {
427 return Ok(LK201Command::SetMode { mode, division });
429 }
430 }
431
432 Ok(LK201Command::Unknown(byte0))
434 }
435
436 0xC1 => Ok(LK201Command::TempNoRepeat),
438 0xD9 => Ok(LK201Command::RepeatToDown),
439 0xE1 => Ok(LK201Command::DisableRepeat),
440 0xE3 => Ok(LK201Command::EnableRepeat),
441 0xE9 => Ok(LK201Command::EnableLK401),
442 0xEB => Ok(LK201Command::DisableLK401),
443
444 0xFD => Ok(LK201Command::PowerUp),
446 0xAB => Ok(LK201Command::RequestId),
447 0xD3 => Ok(LK201Command::SetDefaults),
448 0xCB => Ok(LK201Command::TestMode),
449
450 0x8B => Ok(LK201Command::Resume),
452 0x89 => Ok(LK201Command::Inhibit),
453
454 _ => Ok(LK201Command::Unknown(byte0)),
456 }
457 }
458}
459
460impl Into<Vec<u8>> for LK201Command {
461 fn into(self) -> Vec<u8> {
462 match self {
463 LK201Command::LedEnable(led) => vec![0x13, led.0],
464 LK201Command::LedDisable(led) => vec![0x11, led.0],
465 LK201Command::KeyClickEnable(vol) => vec![0x1B, vol.as_param_byte()],
466 LK201Command::CtrlKeyClickEnable => vec![0xBB],
467 LK201Command::KeyClickDisable => vec![0x99],
468 LK201Command::CtrlKeyClickDisable => vec![0xB9],
469 LK201Command::SoundClick => vec![0x9F],
470 LK201Command::BellEnable(vol) => vec![0x23, vol.as_param_byte()],
471 LK201Command::BellDisable => vec![0xA1],
472 LK201Command::RingBell => vec![0xA7],
473 LK201Command::SetMode { mode, division } => {
474 let mode_bits = match mode {
475 KeyMode::Down => 0b00,
476 KeyMode::AutoDown => 0b01,
477 KeyMode::UpDown => 0b11,
478 KeyMode::Illegal => 0b10,
479 };
480 vec![(division.0 << 3) | (mode_bits << 1) | 0x80]
481 }
482 LK201Command::SetModeWithAutoRepeat {
483 mode,
484 division,
485 register,
486 } => {
487 let mode_bits = match mode {
488 KeyMode::Down => 0b00,
489 KeyMode::AutoDown => 0b01,
490 KeyMode::UpDown => 0b11,
491 KeyMode::Illegal => 0b10,
492 };
493 vec![
494 (division.0 << 3) | (mode_bits << 1),
495 0x80 | (register.0 & 0x3),
496 ]
497 }
498 LK201Command::RepeatToDown => vec![0xD9],
499 LK201Command::EnableRepeat => vec![0xE3],
500 LK201Command::DisableRepeat => vec![0xE1],
501 LK201Command::EnableLK401 => vec![0xE9],
502 LK201Command::DisableLK401 => vec![0xEB],
503 LK201Command::TempNoRepeat => vec![0xC1],
504 LK201Command::SetAutoRepeat {
505 register,
506 timeout,
507 rate,
508 } => {
509 vec![
510 0b0_1111_000 | (register.0 << 1),
511 (timeout / 5) & 0x7F,
512 rate & 0x7F | 0x80,
513 ]
514 }
515 LK201Command::PowerUp => vec![0xFD],
516 LK201Command::RequestId => vec![0xAB],
517 LK201Command::SetDefaults => vec![0xD3],
518 LK201Command::TestMode => vec![0xCB],
519 LK201Command::TestExit => vec![0x80],
520 LK201Command::Inhibit => vec![0x89],
521 LK201Command::Resume => vec![0x8B],
522 LK201Command::Unknown(b) => vec![b],
523 LK201Command::Unknown2(b1, b2) => vec![b1, b2],
524 LK201Command::Unknown3(b1, b2, b3) => vec![b1, b2, b3],
525 }
526 }
527}
528
529pub mod keycodes {
531 pub const KEY_LOCK: u8 = 0xB0;
533 pub const KEY_SHIFT: u8 = 0xAE;
535 pub const KEY_CTRL: u8 = 0xAF;
537 pub const KEY_COMP: u8 = 0xB1;
539}
540
541#[derive(Debug, Clone, PartialEq, Eq)]
543pub enum LK201Response {
544 PowerUpSelfTest {
547 keyboard_id_firmware: u8,
548 keyboard_id_hardware: u8,
549 error: PowerUpError,
550 keycode: u8,
551 },
552 KeyboardId { firmware_id: u8, hardware_id: u8 },
554
555 ModeChangeAck,
558 KeyboardLockAck,
560 TestModeAck,
562
563 InputError,
566 OutputError,
568
569 KeyDown(u8),
572 Repeat,
574 AllUp,
576 PrefixKeyDown(u8),
578}
579
580impl LK201Response {
581 pub fn to_bytes(&self) -> Vec<u8> {
583 match self {
584 LK201Response::PowerUpSelfTest {
585 keyboard_id_firmware,
586 keyboard_id_hardware,
587 error,
588 keycode,
589 } => {
590 vec![
591 *keyboard_id_firmware,
592 *keyboard_id_hardware,
593 (*error).into(),
594 *keycode,
595 ]
596 }
597 LK201Response::KeyboardId {
598 firmware_id,
599 hardware_id,
600 } => {
601 vec![*firmware_id, *hardware_id]
602 }
603 LK201Response::ModeChangeAck => vec![0xBA],
604 LK201Response::TestModeAck => vec![0xB8],
605 LK201Response::KeyboardLockAck => vec![0xB7],
606 LK201Response::InputError => vec![0xB6],
607 LK201Response::OutputError => vec![0xB5],
608 LK201Response::KeyDown(keycode) => vec![*keycode],
609 LK201Response::Repeat => vec![0xB4],
610 LK201Response::AllUp => vec![0xB3],
611 LK201Response::PrefixKeyDown(keycode) => vec![0xB9, *keycode],
612 }
613 }
614}
615
616#[derive(Debug, Clone, Copy, PartialEq, Eq)]
618pub enum KeyboardType {
619 LK201 = 1,
621 LK401 = 2,
623 LK443 = 3,
625 LK421 = 4,
627}
628
629impl KeyboardType {
630 pub fn from_id(id: u8) -> Option<Self> {
631 match id {
632 1 => Some(KeyboardType::LK201),
633 2 => Some(KeyboardType::LK401),
634 3 => Some(KeyboardType::LK443),
635 4 => Some(KeyboardType::LK421),
636 _ => None,
637 }
638 }
639}
640
641#[derive(Debug, Clone, Copy, PartialEq, Eq)]
643pub enum PowerUpError {
644 NoError,
646 KeyDownError,
648 PowerError,
650 Unknown(u8),
652}
653
654impl From<u8> for PowerUpError {
655 fn from(byte: u8) -> Self {
656 match byte {
657 0x00 => PowerUpError::NoError,
658 0x3D => PowerUpError::KeyDownError,
659 0x3E => PowerUpError::PowerError,
660 other => PowerUpError::Unknown(other),
661 }
662 }
663}
664
665impl From<PowerUpError> for u8 {
666 fn from(error: PowerUpError) -> u8 {
667 match error {
668 PowerUpError::NoError => 0x00,
669 PowerUpError::KeyDownError => 0x3D,
670 PowerUpError::PowerError => 0x3E,
671 PowerUpError::Unknown(byte) => byte,
672 }
673 }
674}
675
676#[cfg(test)]
677mod tests {
678 use super::*;
679
680 #[track_caller]
681 fn test_parse(input: &[u8], expected: LK201Command) {
682 let queue = VecDeque::from_iter(input.iter().copied());
683 let command = LK201Command::try_from(&queue).unwrap();
684 assert_eq!(
685 command, expected,
686 "input: {:02X?}, expected: {:?}",
687 input, expected
688 );
689 assert_eq!(
690 input.len(),
691 command.len(),
692 "input: {:02X?}, expected: {:?}",
693 input,
694 expected
695 );
696 }
697
698 #[test]
699 fn test_mode_commands() {
700 test_parse(
702 &[0x0A, 0x80],
703 LK201Command::SetModeWithAutoRepeat {
704 division: Division(1),
705 mode: KeyMode::AutoDown,
706 register: AutoRepeatRegister(0),
707 },
708 );
709
710 test_parse(
712 &[0x12, 0x81],
713 LK201Command::SetModeWithAutoRepeat {
714 division: Division(2),
715 mode: KeyMode::AutoDown,
716 register: AutoRepeatRegister(1),
717 },
718 );
719
720 test_parse(
722 &[0x72, 0x82],
723 LK201Command::SetModeWithAutoRepeat {
724 division: Division(14),
725 mode: KeyMode::AutoDown,
726 register: AutoRepeatRegister(2),
727 },
728 );
729
730 test_parse(
732 &[0xA2],
733 LK201Command::SetMode {
734 mode: KeyMode::AutoDown,
735 division: Division(4),
736 },
737 );
738 }
739
740 #[test]
741 fn test_autorepeat_commands() {
742 test_parse(
744 &[0x78, 0x64, 0x9E],
745 LK201Command::SetAutoRepeat {
746 register: AutoRepeatRegister(0),
747 timeout: 0x64,
748 rate: 0x1E,
749 },
750 );
751
752 test_parse(
754 &[0x7A, 0x64, 0x9E],
755 LK201Command::SetAutoRepeat {
756 register: AutoRepeatRegister(1),
757 timeout: 0x64,
758 rate: 0x1E,
759 },
760 );
761
762 test_parse(
764 &[0x7C, 0x64, 0x9E],
765 LK201Command::SetAutoRepeat {
766 register: AutoRepeatRegister(2),
767 timeout: 0x64,
768 rate: 0x1E,
769 },
770 );
771 }
772
773 #[test]
774 fn test_led_commands() {
775 test_parse(&[0x13, 0x84], LK201Command::LedEnable(Led::new(0x84)));
777 test_parse(&[0x11, 0x88], LK201Command::LedDisable(Led::new(0x88)));
778 test_parse(&[0x13, 0x8F], LK201Command::LedEnable(Led::new(0x8F)));
779 test_parse(&[0x13, 0x81], LK201Command::LedEnable(Led::new(0x81)));
780
781 test_parse(&[0x13, 0x80], LK201Command::LedEnable(Led::new(0x80))); test_parse(&[0x13, 0x83], LK201Command::LedEnable(Led::new(0x83))); test_parse(&[0x13, 0x85], LK201Command::LedEnable(Led::new(0x85))); test_parse(&[0x13, 0x86], LK201Command::LedEnable(Led::new(0x86))); test_parse(&[0x13, 0x8C], LK201Command::LedEnable(Led::new(0x8C))); test_parse(&[0x11, 0x8D], LK201Command::LedDisable(Led::new(0x8D))); }
789
790 #[test]
791 fn test_bell_and_click_commands() {
792 test_parse(&[0x23, 0x80], LK201Command::BellEnable(Volume(0)));
794 test_parse(&[0xA1], LK201Command::BellDisable);
795 test_parse(&[0xA7], LK201Command::RingBell);
796
797 test_parse(&[0x1B, 0x80], LK201Command::KeyClickEnable(Volume(0)));
799 test_parse(&[0x99], LK201Command::KeyClickDisable);
800 test_parse(&[0xBB], LK201Command::CtrlKeyClickEnable);
801 test_parse(&[0xB9], LK201Command::CtrlKeyClickDisable);
802 }
803
804 #[test]
805 fn test_control_commands() {
806 test_parse(&[0xFD], LK201Command::PowerUp);
807 test_parse(&[0xAB], LK201Command::RequestId);
808 test_parse(&[0xE3], LK201Command::EnableRepeat);
809 test_parse(&[0xE1], LK201Command::DisableRepeat);
810 test_parse(&[0xD9], LK201Command::RepeatToDown);
811 test_parse(&[0xC1], LK201Command::TempNoRepeat);
812 test_parse(&[0xD3], LK201Command::SetDefaults);
813 test_parse(&[0xCB], LK201Command::TestMode);
814 test_parse(&[0x8B], LK201Command::Resume);
815 test_parse(&[0x89], LK201Command::Inhibit);
816 test_parse(&[0x80], LK201Command::TestExit);
817 }
818
819 #[test]
820 fn test_unknown_commands() {
821 test_parse(&[0x0D], LK201Command::Unknown(0x0D));
823 test_parse(&[0xFF], LK201Command::Unknown(0xFF));
824 test_parse(&[0x01], LK201Command::Unknown(0x01));
825 test_parse(&[0x55], LK201Command::Unknown(0x55));
826
827 let cmd = LK201Command::Unknown(0x0D);
829 let resp = cmd.response().unwrap();
830 assert_eq!(resp, LK201Response::InputError);
831 assert_eq!(resp.to_bytes(), vec![0xB6]);
832 }
833
834 #[test]
835 fn test_command_responses() {
836 let cmd = LK201Command::PowerUp;
838 let resp = cmd.response().unwrap();
839 assert_eq!(resp.to_bytes(), vec![0x01, 0x00, 0x00, 0x00]);
840
841 let cmd = LK201Command::RequestId;
842 let resp = cmd.response().unwrap();
843 assert_eq!(resp.to_bytes(), vec![0x01, 0x01]);
844
845 let cmd = LK201Command::SetMode {
847 mode: KeyMode::AutoDown,
848 division: Division(1),
849 };
850 let resp = cmd.response().unwrap();
851 assert_eq!(resp.to_bytes(), vec![0xBA]);
852
853 let cmd = LK201Command::SetModeWithAutoRepeat {
854 mode: KeyMode::AutoDown,
855 division: Division(1),
856 register: AutoRepeatRegister(0),
857 };
858 let resp = cmd.response().unwrap();
859 assert_eq!(resp.to_bytes(), vec![0xBA]);
860
861 let resp = LK201Command::SetDefaults.response().unwrap();
862 assert_eq!(resp.to_bytes(), vec![0xBA]);
863
864 let cmd = LK201Command::TestMode;
866 let resp = cmd.response().unwrap();
867 assert_eq!(resp.to_bytes(), vec![0xB8]);
868
869 let cmd = LK201Command::Inhibit;
870 let resp = cmd.response().unwrap();
871 assert_eq!(resp.to_bytes(), vec![0xB7]);
872
873 let cmd = LK201Command::Unknown(0xFF);
875 let resp = cmd.response().unwrap();
876 assert_eq!(resp.to_bytes(), vec![0xB6]);
877
878 assert!(LK201Command::LedEnable(Led::new(0x84)).response().is_none());
880 assert!(LK201Command::BellEnable(Volume(4)).response().is_none());
881 assert!(LK201Command::KeyClickDisable.response().is_none());
882 assert!(LK201Command::Resume.response().is_none());
883 }
884
885 #[test]
886 fn test_response_serialization() {
887 let resp = LK201Response::ModeChangeAck;
889 assert_eq!(resp.to_bytes(), vec![0xBA]);
890
891 let resp = LK201Response::KeyboardLockAck;
892 assert_eq!(resp.to_bytes(), vec![0xB7]);
893
894 let resp = LK201Response::TestModeAck;
895 assert_eq!(resp.to_bytes(), vec![0xB8]);
896
897 let resp = LK201Response::InputError;
898 assert_eq!(resp.to_bytes(), vec![0xB6]);
899
900 let resp = LK201Response::OutputError;
901 assert_eq!(resp.to_bytes(), vec![0xB5]);
902
903 let resp = LK201Response::Repeat;
904 assert_eq!(resp.to_bytes(), vec![0xB4]);
905
906 let resp = LK201Response::AllUp;
907 assert_eq!(resp.to_bytes(), vec![0xB3]);
908
909 let resp = LK201Response::KeyDown(0x42);
910 assert_eq!(resp.to_bytes(), vec![0x42]);
911
912 let resp = LK201Response::PrefixKeyDown(0x42);
913 assert_eq!(resp.to_bytes(), vec![0xB9, 0x42]);
914 }
915
916 #[test]
917 fn test_full_sequence() {
918 test_parse(
921 &[0x0A, 0x80],
922 LK201Command::SetModeWithAutoRepeat {
923 division: Division(1),
924 mode: KeyMode::AutoDown,
925 register: AutoRepeatRegister(0),
926 },
927 );
928
929 test_parse(
931 &[0x1A, 0x80],
932 LK201Command::SetModeWithAutoRepeat {
933 division: Division(3),
934 mode: KeyMode::AutoDown,
935 register: AutoRepeatRegister(0),
936 },
937 );
938
939 test_parse(
941 &[0x3A, 0x80],
942 LK201Command::SetModeWithAutoRepeat {
943 division: Division(7),
944 mode: KeyMode::AutoDown,
945 register: AutoRepeatRegister(0),
946 },
947 );
948
949 test_parse(
951 &[0x42, 0x81],
952 LK201Command::SetModeWithAutoRepeat {
953 division: Division(8),
954 mode: KeyMode::AutoDown,
955 register: AutoRepeatRegister(1),
956 },
957 );
958
959 test_parse(
961 &[0x4A, 0x82],
962 LK201Command::SetModeWithAutoRepeat {
963 division: Division(9),
964 mode: KeyMode::AutoDown,
965 register: AutoRepeatRegister(2),
966 },
967 );
968
969 test_parse(
971 &[0x5A, 0x82],
972 LK201Command::SetModeWithAutoRepeat {
973 division: Division(11),
974 mode: KeyMode::AutoDown,
975 register: AutoRepeatRegister(2),
976 },
977 );
978
979 test_parse(
981 &[0x62, 0x82],
982 LK201Command::SetModeWithAutoRepeat {
983 division: Division(12),
984 mode: KeyMode::AutoDown,
985 register: AutoRepeatRegister(2),
986 },
987 );
988
989 test_parse(
991 &[0x6A, 0x82],
992 LK201Command::SetModeWithAutoRepeat {
993 division: Division(13),
994 mode: KeyMode::AutoDown,
995 register: AutoRepeatRegister(2),
996 },
997 );
998 }
999
1000 #[test]
1001 fn test_lk201() {
1002 test_parse(&[0xE9], LK201Command::EnableLK401);
1003 test_parse(&[0xEB], LK201Command::DisableLK401);
1004 }
1005}