use std::thread;
use std::time::Duration;
use hidapi::HidApi;
use json::JsonValue;
use crate::{Device, Handler, Types};
use super::utils::*;
#[derive(Clone)]
pub struct Mac {}
impl Default for Mac {
fn default() -> Self {
Self::new()
}
}
impl Mac {
pub fn new() -> Self {
Self {}
}
pub fn run<F>(&mut self, factory: F)
where
F: Fn() -> Box<dyn Handler>,
{
loop {
let hidapi = match HidApi::new() {
Ok(e) => e,
Err(_) => {
continue;
}
};
for device in hidapi.device_list() {
let usage = device.usage();
let usage_page = device.usage_page();
if usage != 6 || usage_page != 1 {
continue;
}
let uid = if device.serial_number().unwrap().is_empty(){
let path = device.path().to_str().unwrap().to_string();
let re = path.trim().trim_start_matches("DevSrvsID:").parse::<u64>().unwrap();
u64_to_mac(re)
} else {
device.serial_number().unwrap().to_string()
};
let r = Device {
id: uid,
vid: device.vendor_id().to_string(),
pid: device.product_id().to_string(),
types: Types::Keyboard,
manufacturer: device.manufacturer_string().unwrap().trim().to_string(),
name: device.product_string().unwrap().trim().to_string(),
value: JsonValue::from("".to_string()),
count: 0,
};
factory().on_discover(r);
}
thread::sleep(Duration::from_secs(1));
}
}
pub fn connect<F>(&mut self, id: String, factory: F)
where
F: Fn() -> Box<dyn Handler>,
{
let hidapi = match HidApi::new() {
Ok(e) => e,
Err(e) => {
return factory().on_disconnected(id, e.to_string());
}
};
let device = hidapi.device_list().find(|device| {
let uid = if device.serial_number().unwrap().is_empty() {
let path = device.path().to_str().unwrap().to_string();
let re = path.trim().trim_start_matches("DevSrvsID:").parse::<u64>().unwrap();
u64_to_mac(re)
} else {
device.serial_number().unwrap().to_string()
};
uid == id
});
let device_info = match device {
Some(device) => device,
None => {
return factory().on_disconnected(id, "未找到设备".to_string());
}
};
let device = match device_info.open_device(&hidapi) {
Ok(e) => e,
Err(e) => return factory().on_disconnected(id, e.to_string())
};
factory().on_connect(id.clone());
let mut value = "".to_string();
loop {
if factory().on_is_close(id.clone()) {
factory().on_disconnected(id.clone(), "主动断开连接".to_string());
break;
}
let mut buf = [0u8; 64];
match device.read_timeout(&mut buf, 1000) {
Ok(n) => {
let data = &buf[..n];
if data.is_empty() {
continue;
}
if n < 4 {
continue;
}
if data[4] != 0 {
continue;
}
value = format!("{value}{}", keycode_to_digit(data[3]));
match value.find("\n") {
None => {}
Some(e) => {
value = value[..e].to_string();
factory().on_data(id.clone(), value.into());
value = "".to_string();
}
}
}
Err(e) => {
factory().on_disconnected(id.clone(), format!("设备连接失败: {}", e));
break;
}
}
}
}
}
fn keycode_to_digit(keycode: u8) -> &'static str {
match keycode {
88 | 40 => "\n",
86 | 45 => "-",
87 | 46 => "+",
89 | 30 => "1",
90 | 31 => "2",
91 | 32 => "3",
92 | 33 => "4",
93 | 34 => "5",
94 | 35 => "6",
95 | 36 => "7",
96 | 37 => "8",
97 | 38 => "9",
98 | 39 => "0",
99 | 55 => ".",
_ => "",
}
}