1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use hidapi::HidDevice;
use crate::{
Access,
Error,
};
pub struct AccessHid {
device: HidDevice,
retries: u32,
timeout: i32,
}
impl AccessHid {
pub fn new(device: HidDevice, retries: u32, timeout: i32) -> Result<Self, Error> {
Ok(Self {
device,
retries,
timeout,
})
}
pub fn device(&mut self) -> &mut HidDevice {
&mut self.device
}
unsafe fn command_try(&mut self, cmd: u8, data: &mut [u8]) -> Result<Option<u8>, Error> {
const HID_CMD: usize = 1;
const HID_RES: usize = 2;
const HID_DATA: usize = 3;
let mut hid_data = [0; 33];
if data.len() + HID_DATA > hid_data.len() {
return Err(Error::DataLength(data.len()));
}
hid_data[HID_CMD] = cmd;
for i in 0..data.len() {
hid_data[HID_DATA + i] = data[i];
}
let count = self.device.write(&hid_data)?;
if count != hid_data.len() {
return Err(Error::Verify);
}
let count = self.device.read_timeout(&mut hid_data[1..], self.timeout)?;
if count == hid_data.len() - 1 {
for i in 0..data.len() {
data[i] = hid_data[HID_DATA + i];
}
Ok(Some(hid_data[HID_RES]))
} else if count == 0 {
Ok(None)
} else {
Err(Error::Verify)
}
}
}
impl Access for AccessHid {
unsafe fn command(&mut self, cmd: u8, data: &mut [u8]) -> Result<u8, Error> {
for _ in 0..self.retries {
match self.command_try(cmd, data)? {
Some(some) => return Ok(some),
None => continue,
}
}
Err(Error::Timeout)
}
fn data_size(&self) -> usize {
32 - 2
}
}