use std::fmt::{Display, Formatter, Result as FmtResult};
use std::sync::LazyLock;
use anyhow::{Context, Result};
use log::error;
use serde::{Deserialize, Serialize};
use super::config::*;
use super::{UsbDeviceRequest, UsbPacket, UsbPacketStatus};
use ui::input::{set_kbd_led_state, MEDIA_NEXT, MEDIA_PLAY_PAUSE, MEDIA_PREVIOUS, MEDIA_STOP};
const HID_KEYBOARD_LEFT_CONTROL: u8 = 0xe0;
#[allow(unused)]
const HID_KEYBOARD_LEFT_SHIFT: u8 = 0xe1;
#[allow(unused)]
const HID_KEYBOARD_LEFT_ALT: u8 = 0xe2;
#[allow(unused)]
const HID_KEYBOARD_LEFT_GUI: u8 = 0xe3;
#[allow(unused)]
const HID_KEYBOARD_RIGHT_CONTROL: u8 = 0xe4;
#[allow(unused)]
const HID_KEYBOARD_RIGHT_SHIFT: u8 = 0xe5;
#[allow(unused)]
const HID_KEYBOARD_RIGHT_ALT: u8 = 0xe6;
const HID_KEYBOARD_RIGHT_GUI: u8 = 0xe7;
pub const HID_GET_REPORT: u8 = 0x01;
pub const HID_GET_IDLE: u8 = 0x02;
pub const HID_GET_PROTOCOL: u8 = 0x03;
pub const HID_SET_REPORT: u8 = 0x09;
pub const HID_SET_IDLE: u8 = 0x0a;
pub const HID_SET_PROTOCOL: u8 = 0x0b;
#[allow(unused)]
const HID_PROTOCTL_BOOT: u8 = 0;
const HID_PROTOCOL_REPORT: u8 = 1;
const KEYCODE_UP: u32 = 0x80;
pub const QUEUE_LENGTH: u32 = 16;
pub const QUEUE_MASK: u32 = QUEUE_LENGTH - 1;
const HID_USAGE_ERROR_ROLLOVER: u8 = 0x1;
const HID_CODE: [u8; 0x100] = [
0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c, 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33, 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55, 0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f, 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
0x5a, 0x5b, 0x62, 0x63, 0x46, 0x00, 0x64, 0x44, 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
0x88, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x89, 0xe7, 0x65,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, 0x4a, 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x66, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
const TABLET_REPORT_DESCRIPTOR: [u8; 89] = [
0x05, 0x01,
0x09, 0x02,
0xa1, 0x01,
0x09, 0x01,
0xa1, 0x00,
0x05, 0x09,
0x19, 0x01,
0x29, 0x05,
0x15, 0x00,
0x25, 0x01,
0x95, 0x05,
0x75, 0x01,
0x81, 0x02,
0x95, 0x01,
0x75, 0x03,
0x81, 0x01,
0x05, 0x01,
0x09, 0x30,
0x09, 0x31,
0x15, 0x00,
0x26, 0xff, 0x7f,
0x35, 0x00,
0x46, 0xff, 0x7f,
0x75, 0x10,
0x95, 0x02,
0x81, 0x02,
0x05, 0x01,
0x09, 0x38,
0x15, 0x81,
0x25, 0x7f,
0x35, 0x00,
0x45, 0x00,
0x75, 0x08,
0x95, 0x01,
0x81, 0x06,
0x05, 0x0c,
0x0a, 0x38, 0x02,
0x15, 0x81,
0x25, 0x7f,
0x75, 0x08,
0x95, 0x01,
0x81, 0x06,
0xc0, 0xc0,
];
const KEYBOARD_REPORT_DESCRIPTOR: [u8; 63] = [
0x05, 0x01,
0x09, 0x06,
0xa1, 0x01,
0x75, 0x01,
0x95, 0x08,
0x05, 0x07,
0x19, 0xe0,
0x29, 0xe7,
0x15, 0x00,
0x25, 0x01,
0x81, 0x02,
0x95, 0x01,
0x75, 0x08,
0x81, 0x01,
0x95, 0x05,
0x75, 0x01,
0x05, 0x08,
0x19, 0x01,
0x29, 0x05,
0x91, 0x02,
0x95, 0x01,
0x75, 0x03,
0x91, 0x01,
0x95, 0x06,
0x75, 0x08,
0x15, 0x00,
0x25, 0xff,
0x05, 0x07,
0x19, 0x00,
0x29, 0xff,
0x81, 0x00,
0xc0,
];
pub static CONSUMER_REPORT_DESCRIPTOR: LazyLock<Vec<u8>> = LazyLock::new(|| {
vec![
0x05, 0x0C,
0x09, 0x01,
0xa1, 0x01,
0x15, 0x00,
0x25, 0x01,
0x75, 0x01,
0x95, 0x04,
0x09, 0xCD,
0x09, 0xB7,
0x09, 0xB5,
0x09, 0xB6,
0x81, 0x02,
0x75, 0x01,
0x95, 0x04,
0x81, 0x03,
0xc0,
]
});
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum HidType {
Mouse,
Tablet,
Keyboard,
Consumer,
UnKnown,
}
impl From<u8> for HidType {
fn from(value: u8) -> Self {
match value {
0 => HidType::Mouse,
1 => HidType::Tablet,
2 => HidType::Keyboard,
3 => HidType::Consumer,
_ => HidType::UnKnown,
}
}
}
impl From<HidType> for u8 {
fn from(value: HidType) -> Self {
match value {
HidType::Mouse => 0,
HidType::Tablet => 1,
HidType::Keyboard => 2,
HidType::Consumer => 3,
HidType::UnKnown => u8::MAX,
}
}
}
pub struct HidKeyboard {
pub keycodes: [u32; QUEUE_LENGTH as usize],
pub modifiers: u16,
pub key_buf: [u8; QUEUE_LENGTH as usize],
pub key_num: u32,
}
#[derive(Copy, Clone, Deserialize, Serialize)]
struct HidKeyboardState {
keycodes: [u32; QUEUE_LENGTH as usize],
modifiers: u16,
key_buf: [u8; QUEUE_LENGTH as usize],
key_num: u32,
}
impl Default for HidKeyboardState {
fn default() -> Self {
HidKeyboardState {
keycodes: [0; QUEUE_LENGTH as usize],
modifiers: 0,
key_buf: [0; QUEUE_LENGTH as usize],
key_num: 0,
}
}
}
impl HidKeyboard {
fn new() -> HidKeyboard {
HidKeyboard {
keycodes: [0; QUEUE_LENGTH as usize],
modifiers: 0,
key_buf: [0; QUEUE_LENGTH as usize],
key_num: 0,
}
}
fn reset(&mut self) {
self.keycodes.iter_mut().for_each(|x| *x = 0);
self.modifiers = 0;
self.key_buf.iter_mut().for_each(|x| *x = 0);
self.key_num = 0;
}
fn get_state(&self) -> HidKeyboardState {
HidKeyboardState {
keycodes: self.keycodes,
modifiers: self.modifiers,
key_buf: self.key_buf,
key_num: self.key_num,
}
}
fn set_state(&mut self, state: &HidKeyboardState) {
self.keycodes = state.keycodes;
self.modifiers = state.modifiers;
self.key_buf = state.key_buf;
self.key_num = state.key_num;
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct HidPointerEvent {
pub pos_x: u32,
pub pos_y: u32,
pub v_wheel: i32,
pub h_wheel: i32,
pub button_state: u32,
}
#[derive(Copy, Clone, Deserialize, Serialize, Default)]
struct HidPointerEventState {
pos_x: u32,
pos_y: u32,
v_wheel: i32,
h_wheel: i32,
button_state: u32,
}
impl HidPointerEvent {
fn get_state(&self) -> HidPointerEventState {
HidPointerEventState {
pos_x: self.pos_x,
pos_y: self.pos_y,
v_wheel: self.v_wheel,
h_wheel: self.h_wheel,
button_state: self.button_state,
}
}
fn set_state(&mut self, state: &HidPointerEventState) {
self.pos_x = state.pos_x;
self.pos_y = state.pos_y;
self.v_wheel = state.v_wheel;
self.h_wheel = state.h_wheel;
self.button_state = state.button_state;
}
}
pub struct HidPointer {
pub queue: [HidPointerEvent; QUEUE_LENGTH as usize],
}
#[derive(Copy, Clone, Deserialize, Serialize)]
struct HidPointerState {
queue: [HidPointerEventState; QUEUE_LENGTH as usize],
}
impl Default for HidPointerState {
fn default() -> Self {
HidPointerState {
queue: [HidPointerEventState::default(); QUEUE_LENGTH as usize],
}
}
}
impl HidPointer {
fn new() -> Self {
HidPointer {
queue: [HidPointerEvent::default(); QUEUE_LENGTH as usize],
}
}
fn reset(&mut self) {
self.queue
.iter_mut()
.for_each(|x| *x = HidPointerEvent::default());
}
fn get_state(&self) -> HidPointerState {
let mut queue_state = [HidPointerEventState::default(); QUEUE_LENGTH as usize];
for (i, event) in self.queue.iter().enumerate() {
queue_state[i] = event.get_state();
}
HidPointerState { queue: queue_state }
}
fn set_state(&mut self, state: &HidPointerState) {
for (i, event_state) in state.queue.iter().enumerate() {
self.queue[i].set_state(event_state);
}
}
}
pub struct HidConsumer {
pub keycodes: [u16; QUEUE_LENGTH as usize],
}
#[derive(Copy, Clone, Deserialize, Serialize)]
struct HidConsumerState {
keycodes: [u16; QUEUE_LENGTH as usize],
}
impl Default for HidConsumerState {
fn default() -> Self {
HidConsumerState {
keycodes: [0; QUEUE_LENGTH as usize],
}
}
}
impl HidConsumer {
fn new() -> Self {
HidConsumer {
keycodes: [0; QUEUE_LENGTH as usize],
}
}
fn reset(&mut self) {
self.keycodes.iter_mut().for_each(|x| *x = 0);
}
fn get_state(&self) -> HidConsumerState {
HidConsumerState {
keycodes: self.keycodes,
}
}
fn set_state(&mut self, state: &HidConsumerState) {
self.keycodes = state.keycodes;
}
}
pub struct Hid {
pub(crate) head: u32,
pub(crate) num: u32,
pub(crate) kind: HidType,
protocol: u8,
idle: u8,
pub(crate) keyboard: HidKeyboard,
pub(crate) pointer: HidPointer,
pub(crate) consumer: HidConsumer,
}
#[derive(Deserialize, Serialize)]
pub struct HidDevState {
head: u32,
num: u32,
kind: u8,
protocol: u8,
idle: u8,
hid_state_buf: Vec<u8>,
}
impl Hid {
pub fn new(kind: HidType) -> Self {
Hid {
head: 0,
num: 0,
kind,
protocol: 0,
idle: 0,
keyboard: HidKeyboard::new(),
pointer: HidPointer::new(),
consumer: HidConsumer::new(),
}
}
pub fn reset(&mut self) {
self.head = 0;
self.num = 0;
self.protocol = HID_PROTOCOL_REPORT;
self.idle = 0;
self.keyboard.reset();
self.pointer.reset();
self.consumer.reset();
}
fn convert_to_hid_code(&mut self) {
if self.num == 0 {
return;
}
let slot = self.head & QUEUE_MASK;
self.increase_head();
self.num -= 1;
let keycode = self.keyboard.keycodes[slot as usize];
let key = keycode & 0x7f;
let index = key | ((u32::from(self.keyboard.modifiers) & (1 << 8)) >> 1);
let hid_code = HID_CODE[index as usize];
self.keyboard.modifiers &= !(1 << 8);
trace::usb_convert_to_hid_code(&hid_code, &index, &key);
if hid_code == 0x0 {
return;
}
if hid_code == HID_KEYBOARD_LEFT_CONTROL && self.keyboard.modifiers & (1 << 9) == (1 << 9) {
self.keyboard.modifiers ^= (1 << 8) | (1 << 9);
return;
}
if (HID_KEYBOARD_LEFT_CONTROL..=HID_KEYBOARD_RIGHT_GUI).contains(&hid_code)
&& keycode & KEYCODE_UP == KEYCODE_UP
{
self.keyboard.modifiers &= !(1 << (hid_code & 0x0f));
return;
}
if (HID_KEYBOARD_LEFT_CONTROL..=0xe9).contains(&hid_code) {
self.keyboard.modifiers |= 1 << (hid_code & 0x0f);
return;
}
if (0xea..=0xef).contains(&hid_code) {
error!("Convert error, invalid code {}", hid_code);
return;
}
if keycode & KEYCODE_UP == KEYCODE_UP {
let mut i = self.keyboard.key_num as i32 - 1;
while i >= 0 {
if self.keyboard.key_buf[i as usize] == hid_code {
self.keyboard.key_num -= 1;
self.keyboard.key_buf[i as usize] =
self.keyboard.key_buf[self.keyboard.key_num as usize];
self.keyboard.key_buf[self.keyboard.key_num as usize] = 0x0;
break;
}
i -= 1;
}
} else {
let mut i = self.keyboard.key_num as i32 - 1;
while i >= 0 {
if self.keyboard.key_buf[i as usize] == hid_code {
break;
}
i -= 1;
}
if i < 0 && self.keyboard.key_num < self.keyboard.key_buf.len() as u32 {
self.keyboard.key_buf[self.keyboard.key_num as usize] = hid_code;
self.keyboard.key_num += 1;
}
}
}
fn keyboard_poll(&mut self) -> Vec<u8> {
let mut data = vec![0; 8];
self.convert_to_hid_code();
data[0] = self.keyboard.modifiers as u8;
data[1] = 0;
let len = data.len() - 2;
if self.keyboard.key_num > 6 {
for i in 0..len {
data[i + 2] = HID_USAGE_ERROR_ROLLOVER;
}
} else {
data[2..(len + 2)].clone_from_slice(&self.keyboard.key_buf[..len]);
}
data
}
fn consumer_poll(&mut self) -> Vec<u8> {
let mut data = vec![1];
if self.num != 0 {
let slot = self.head & QUEUE_MASK;
self.increase_head();
self.num -= 1;
let keycode = self.consumer.keycodes[slot as usize];
data[0] = match keycode {
MEDIA_PLAY_PAUSE => 1,
MEDIA_STOP => 2,
MEDIA_PREVIOUS => 4,
MEDIA_NEXT => 8,
_ => 0,
};
}
data
}
fn pointer_poll(&mut self) -> Vec<u8> {
let index = self.head;
if self.num != 0 {
self.increase_head();
self.num -= 1;
}
let evt = &mut self.pointer.queue[(index & QUEUE_MASK) as usize];
vec![
evt.button_state as u8,
evt.pos_x as u8,
(evt.pos_x >> 8) as u8,
evt.pos_y as u8,
(evt.pos_y >> 8) as u8,
evt.v_wheel as u8,
evt.h_wheel as u8,
]
}
fn increase_head(&mut self) {
if self.head + 1 >= QUEUE_LENGTH {
self.head = 0;
} else {
self.head += 1;
}
}
pub fn handle_control_packet(
&mut self,
packet: &mut UsbPacket,
device_req: &UsbDeviceRequest,
data: &mut [u8],
) {
match device_req.request_type {
USB_INTERFACE_IN_REQUEST => {
self.do_interface_in_request(packet, device_req, data);
}
USB_INTERFACE_CLASS_IN_REQUEST => {
self.do_interface_class_in_request(packet, device_req, data);
}
USB_INTERFACE_CLASS_OUT_REQUEST => {
self.do_interface_class_out_request(packet, device_req, data);
}
_ => {
error!("Unhandled request {}", device_req.request);
packet.status = UsbPacketStatus::Stall;
}
}
}
fn do_interface_in_request(
&mut self,
packet: &mut UsbPacket,
device_req: &UsbDeviceRequest,
data: &mut [u8],
) {
match device_req.request {
USB_REQUEST_GET_DESCRIPTOR => match device_req.value >> 8 {
0x22 => match self.kind {
HidType::Tablet => {
data[..TABLET_REPORT_DESCRIPTOR.len()]
.clone_from_slice(&TABLET_REPORT_DESCRIPTOR[..]);
packet.actual_length = TABLET_REPORT_DESCRIPTOR.len() as u32;
}
HidType::Keyboard => {
data[..KEYBOARD_REPORT_DESCRIPTOR.len()]
.clone_from_slice(&KEYBOARD_REPORT_DESCRIPTOR[..]);
packet.actual_length = KEYBOARD_REPORT_DESCRIPTOR.len() as u32;
}
HidType::Consumer => {
data[..CONSUMER_REPORT_DESCRIPTOR.len()]
.clone_from_slice(&CONSUMER_REPORT_DESCRIPTOR);
packet.actual_length = CONSUMER_REPORT_DESCRIPTOR.len() as u32;
}
_ => {
error!("Unknown HID type");
packet.status = UsbPacketStatus::Stall;
}
},
_ => {
error!("Invalid value: {:?}", device_req);
packet.status = UsbPacketStatus::Stall;
}
},
_ => {
error!("Unhandled request {}", device_req.request);
packet.status = UsbPacketStatus::Stall;
}
}
}
fn do_interface_class_in_request(
&mut self,
packet: &mut UsbPacket,
device_req: &UsbDeviceRequest,
data: &mut [u8],
) {
match device_req.request {
HID_GET_REPORT => match self.kind {
HidType::Tablet => {
let buf = self.pointer_poll();
data[0..buf.len()].copy_from_slice(buf.as_slice());
packet.actual_length = buf.len() as u32;
}
HidType::Keyboard => {
let buf = self.keyboard_poll();
data[0..buf.len()].copy_from_slice(buf.as_slice());
packet.actual_length = buf.len() as u32;
}
HidType::Consumer => {
let buf = self.consumer_poll();
data[0..buf.len()].copy_from_slice(buf.as_slice());
packet.actual_length = buf.len() as u32;
}
_ => {
error!("Unsupported HID type for report");
packet.status = UsbPacketStatus::Stall;
}
},
HID_GET_PROTOCOL => {
data[0] = self.protocol;
packet.actual_length = 1;
}
HID_GET_IDLE => {
data[0] = self.idle;
packet.actual_length = 1;
}
_ => {
error!("Unhandled request {}", device_req.request);
packet.status = UsbPacketStatus::Stall;
}
}
}
fn do_interface_class_out_request(
&mut self,
packet: &mut UsbPacket,
device_req: &UsbDeviceRequest,
data: &[u8],
) {
match device_req.request {
HID_SET_REPORT => match self.kind {
HidType::Keyboard => {
trace::usb_keyboard_set_report(&data[0]);
set_kbd_led_state(data[0]);
}
_ => {
error!("Unsupported to set report");
packet.status = UsbPacketStatus::Stall;
}
},
HID_SET_PROTOCOL => {
self.protocol = device_req.value as u8;
}
HID_SET_IDLE => {
self.idle = (device_req.value >> 8) as u8;
}
_ => {
error!("Unhandled request {}", device_req.request);
packet.status = UsbPacketStatus::Stall;
}
}
}
pub fn handle_data_packet(&mut self, p: &mut UsbPacket) {
match p.pid as u8 {
USB_TOKEN_IN => {
self.handle_token_in(p);
}
_ => {
error!("Unhandled packet {}", p.pid);
p.status = UsbPacketStatus::Stall;
}
};
}
fn handle_token_in(&mut self, p: &mut UsbPacket) {
let mut buf = Vec::new();
if p.ep_number == 1 {
if self.num == 0 {
trace::usb_no_data_in_usb_device();
p.status = UsbPacketStatus::Nak;
return;
}
match self.kind {
HidType::Keyboard => {
buf = self.keyboard_poll();
}
HidType::Tablet => {
buf = self.pointer_poll();
}
HidType::Consumer => {
buf = self.consumer_poll();
}
_ => {
error!("Unsupported HID device");
p.status = UsbPacketStatus::Stall;
}
}
let len = buf.len();
p.transfer_packet(&mut buf, len);
} else {
error!("Unhandled endpoint {}", p.ep_number);
p.status = UsbPacketStatus::Stall;
}
}
pub fn get_state(&self) -> Result<HidDevState> {
let hid_state_buf = match self.kind {
HidType::Keyboard => serde_json::to_vec(&self.keyboard.get_state())
.with_context(|| "Failed to get vec of kbd hid device")?,
HidType::Tablet => serde_json::to_vec(&self.pointer.get_state())
.with_context(|| "Failed to get vec of tablet hid device")?,
HidType::Consumer => serde_json::to_vec(&self.consumer.get_state())
.with_context(|| "Failed to get vec of consumer hid device")?,
_ => Vec::new(),
};
Ok(HidDevState {
head: self.head,
num: self.num,
kind: self.kind.into(),
protocol: self.protocol,
idle: self.idle,
hid_state_buf,
})
}
pub fn set_state(&mut self, state: &HidDevState) -> Result<()> {
self.head = state.head;
self.num = state.num;
self.kind = state.kind.into();
self.protocol = state.protocol;
self.idle = state.idle;
match self.kind {
HidType::Keyboard => {
let k_state: HidKeyboardState = serde_json::from_slice(&state.hid_state_buf[..])
.with_context(|| "Failed to get HidKeyboardState from slice")?;
self.keyboard.set_state(&k_state);
}
HidType::Tablet => {
let p_state: HidPointerState = serde_json::from_slice(&state.hid_state_buf[..])
.with_context(|| "Failed to get HidKeyboardState from slice")?;
self.pointer.set_state(&p_state);
}
HidType::Consumer => {
let c_state: HidConsumerState = serde_json::from_slice(&state.hid_state_buf[..])
.with_context(|| "Failed to get HidConsumerState from slice")?;
self.consumer.set_state(&c_state);
}
_ => {}
}
Ok(())
}
}
impl Display for Hid {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(
f,
"HID head {} num {} kind {:?} protocol {} idle {}",
self.head, self.num, self.kind, self.protocol, self.idle
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_common_hid_snapshot() {
let mut hid_device = Hid::new(HidType::UnKnown);
hid_device.head = 7;
hid_device.num = 7;
hid_device.protocol = 7;
hid_device.idle = 7;
let dev_state = hid_device.get_state();
assert!(dev_state.is_ok());
hid_device.head = u32::MAX;
hid_device.num = u32::MAX;
hid_device.protocol = u8::MAX;
hid_device.idle = u8::MAX;
let dev_state = dev_state.unwrap();
let ret = hid_device.set_state(&dev_state);
assert!(ret.is_ok());
assert_eq!(hid_device.head, 7);
assert_eq!(hid_device.num, 7);
assert_eq!(hid_device.protocol, 7);
assert_eq!(hid_device.idle, 7);
}
#[test]
fn test_kbd_hid_snapshot() {
let mut hid_device = Hid::new(HidType::Keyboard);
hid_device.keyboard.keycodes = [7; QUEUE_LENGTH as usize];
hid_device.keyboard.modifiers = 7;
hid_device.keyboard.key_buf = [7; QUEUE_LENGTH as usize];
hid_device.keyboard.key_num = 7;
let dev_state = hid_device.get_state();
assert!(dev_state.is_ok());
hid_device.keyboard.keycodes = [u32::MAX; QUEUE_LENGTH as usize];
hid_device.keyboard.modifiers = u16::MAX;
hid_device.keyboard.key_buf = [u8::MAX; QUEUE_LENGTH as usize];
hid_device.keyboard.key_num = u32::MAX;
let dev_state = dev_state.unwrap();
let ret = hid_device.set_state(&dev_state);
assert!(ret.is_ok());
assert_eq!(hid_device.keyboard.keycodes, [7; QUEUE_LENGTH as usize]);
assert_eq!(hid_device.keyboard.modifiers, 7);
assert_eq!(hid_device.keyboard.key_buf, [7; QUEUE_LENGTH as usize]);
assert_eq!(hid_device.keyboard.key_num, 7);
}
#[test]
fn test_tablet_hid_snapshot() {
let mut hid_device = Hid::new(HidType::Tablet);
hid_device.pointer.queue[7].pos_x = 7;
hid_device.pointer.queue[7].pos_y = 7;
hid_device.pointer.queue[7].v_wheel = 7;
hid_device.pointer.queue[7].h_wheel = 7;
hid_device.pointer.queue[7].button_state = 7;
let dev_state = hid_device.get_state();
assert!(dev_state.is_ok());
hid_device.pointer.queue[7].pos_x = u32::MAX;
hid_device.pointer.queue[7].pos_y = u32::MAX;
hid_device.pointer.queue[7].v_wheel = i32::MAX;
hid_device.pointer.queue[7].h_wheel = i32::MAX;
hid_device.pointer.queue[7].button_state = u32::MAX;
let dev_state = dev_state.unwrap();
let ret = hid_device.set_state(&dev_state);
assert!(ret.is_ok());
assert_eq!(hid_device.pointer.queue[7].pos_x, 7);
assert_eq!(hid_device.pointer.queue[7].pos_y, 7);
assert_eq!(hid_device.pointer.queue[7].v_wheel, 7);
assert_eq!(hid_device.pointer.queue[7].h_wheel, 7);
assert_eq!(hid_device.pointer.queue[7].button_state, 7);
}
}