1use hidapi::HidDevice;
2use std::io;
3use thiserror::Error;
4
5pub mod convert;
6
7#[cfg(test)]
8mod tests {
9 use crate::{
10 convert::{convert_four_bytes_from_buffer_to_id, make_response_handler},
11 new_hid_device, AudioMothDevice,
12 };
13
14 #[test]
15 fn it_works() {
16 let result = 2 + 2;
17 assert_eq!(result, 4);
18 }
19 #[test]
20 fn new_device_test() {
21 let device = new_hid_device().expect("打开设备失败");
22 let audio_moth = AudioMothDevice { device: device };
23 let buffer = [0x00, 0x03];
24 audio_moth.write_call(
26 &buffer,
27 make_response_handler(0x03, convert_four_bytes_from_buffer_to_id, |e, d| {
28 if e != None {
29 println!("{:?} get device id get error", e)
30 } else {
31 println!("{:?}", d)
32 }
33 }),
34 );
35 }
36}
37
38const USB_MSG_TYPE_GET_TIME: u8 = 0x01;
41const USB_MSG_TYPE_SET_TIME: u8 = 0x02;
42const USB_MSG_TYPE_GET_UID: u8 = 0x03;
43const USB_MSG_TYPE_GET_BATTERY: u8 = 0x04;
44const USB_MSG_TYPE_GET_APP_PACKET: u8 = 0x05;
45const USB_MSG_TYPE_SET_APP_PACKET: u8 = 0x06;
46const USB_MSG_TYPE_GET_FIRMWARE_VERSION: u8 = 0x07;
47const USB_MSG_TYPE_GET_FIRMWARE_DESCRIPTION: u8 = 0x08;
48const USB_MSG_TYPE_QUERY_BOOTLOADER: u8 = 0x09;
49const USB_MSG_TYPE_SWITCH_TO_BOOTLOADER: u8 = 0x0A;
50
51const VENDORID: u16 = 0x10c4;
52const PRODUCTID: u16 = 0x0002;
53
54type AudioMothResult<T> = std::result::Result<T, AudioMothError>;
55
56#[derive(Error, Debug)]
57pub enum AudioMothError {
58 #[error("HID device not connect")]
59 HidError(#[from] hidapi::HidError),
60 #[error("OtherError")]
61 OtherError(String),
62 #[error("data store disconnected")]
63 IOError(#[from] io::Error),
64 #[error("get battery error is error")]
65 BatteryError(),
66}
67
68fn new_hid_device() -> Option<HidDevice> {
72 let api =
73 hidapi::HidApi::new().unwrap_or_else(|e| panic!("Hid is init error{}", e.to_string()));
74 let hid = match api.open(VENDORID, PRODUCTID) {
75 Ok(hid) => hid,
76 Err(_) => {
77 return None;
78 }
79 };
80 Some(hid)
81}
82
83pub struct AudioMothDevice {
84 device: HidDevice,
85}
86
87#[allow(dead_code)]
88impl AudioMothDevice {
89 pub fn new() -> Option<Self> {
90 let device = new_hid_device();
91 match device {
92 Some(d) => {
93 return Some(AudioMothDevice { device: d });
94 }
95 None => None,
96 }
97 }
98
99 pub fn write_call(&self, data: &[u8], callback: impl Fn(Option<String>, Option<&[u8]>)) {
101 self.device.write(data).unwrap();
102 let mut buf: [u8; 64] = [0; 64];
103 match self.device.read(&mut buf) {
104 Ok(ok) => callback(None, Some(&buf)),
105 Err(_) => callback(Some("No data read".to_string()), None),
106 };
107 }
108
109 pub fn write(&self, data: &[u8]) -> AudioMothResult<usize> {
110 match self.device.write(data) {
111 Ok(size) => {
112 return Ok(size);
113 }
114 Err(e) => return Err(AudioMothError::HidError(e)),
115 }
116 }
117
118 pub fn get_time(&self) -> AudioMothResult<Option<String>> {
120 let data: [u8; 2] = [0x00, USB_MSG_TYPE_GET_TIME];
121 match self.write(&data) {
122 Ok(usize) => {
123 if usize != 0 {
124 let mut buff: [u8; 64] = [0; 64];
125 if let Ok(size) = self.device.read(&mut buff) {
126 if size > 0 && buff[0] == USB_MSG_TYPE_GET_TIME {
127 return Ok(Some(
128 crate::convert::convert_four_bytes_from_buffer_to_date(
129 &mut buff, 1,
130 )
131 .to_string(),
132 ));
133 }
134 }
135 }
136 }
137 Err(_) => {
138 return Err(AudioMothError::OtherError(String::from(
139 "Failed to get time",
140 )))
141 }
142 }
143 return Err(AudioMothError::OtherError(String::from(
144 "Failed to get time",
145 )));
146 }
147
148 pub fn send_time(&self, unix_time_stamp: i64) -> AudioMothResult<usize> {
150 let mut msg_data = [0x00, USB_MSG_TYPE_SET_TIME, 0x00, 0x00, 0x00, 0x00];
151 convert::convert_date_to_four_bytes_in_buffer(&mut msg_data, 2, unix_time_stamp);
152 if let Ok(size) = self.write(&msg_data) {
153 if size == 0 {
154 return Err(AudioMothError::OtherError(String::from("send time error")));
155 }
156 let mut buf = [0u8; 64];
157 match self.device.read(&mut buf[..]) {
158 Ok(size) => {
159 if size > 0 && buf[0] == USB_MSG_TYPE_SET_TIME {
160 return Ok(size);
161 } else {
162 return Err(AudioMothError::OtherError(String::from("send time error")));
163 }
164 }
165 Err(e) => return Err(AudioMothError::HidError(e)),
166 }
167 }
168 return Err(AudioMothError::OtherError(String::from("send time error")));
169 }
170
171 pub fn get_id(&self) -> AudioMothResult<String> {
173 let data: [u8; 2] = [0x00, USB_MSG_TYPE_GET_UID];
174 match self.write(&data) {
175 Ok(usize) => {
176 if usize != 0 {
177 let mut buff: [u8; 64] = [0; 64];
178 if let Ok(size) = self.device.read(&mut buff) {
179 if size > 0 && buff[0] == USB_MSG_TYPE_GET_UID {
180 return Ok(convert::convert_four_bytes_from_buffer_to_id(&buff, 1));
181 } else {
182 return Err(AudioMothError::OtherError(String::from(
183 " Incorrect message type from AudioMoth device",
184 )));
185 }
186 }
187 }
188 }
189 Err(e) => {
190 return Err(e);
191 }
192 }
193 return Err(AudioMothError::OtherError(String::from("get id error")));
194 }
195 pub fn get_battery(&self) -> AudioMothResult<String> {
197 let data: [u8; 2] = [0x00, USB_MSG_TYPE_GET_BATTERY];
198 match self.write(&data) {
199 Ok(usize) => {
200 if usize != 0 {
201 let mut buff: [u8; 64] = [0; 64];
202 if let Ok(size) = self.device.read(&mut buff) {
203 if size > 0 && buff[0] == USB_MSG_TYPE_GET_BATTERY {
204 return Ok(convert::convert_one_byte_from_buffer_to_battery_state(
205 &buff, 1,
206 ));
207 } else {
208 return Err(AudioMothError::OtherError(String::from(
209 " Incorrect message type from AudioMoth device",
210 )));
211 }
212 }
213 }
214 }
215 Err(e) => {
216 return Err(e);
217 }
218 }
219 return Err(AudioMothError::BatteryError());
220 }
221
222 pub fn get_packet(&self) -> AudioMothResult<Option<[u8; 64]>> {
224 let msg_data = [0x00, USB_MSG_TYPE_GET_APP_PACKET];
225 let mut buff: [u8; 64] = [0; 64];
226 match self.write(&msg_data) {
227 Ok(size) => {
228 if size > 0 {
229 match self.device.read(&mut buff) {
230 Ok(size) => {
231 if size > 0 && buff[0] == USB_MSG_TYPE_GET_APP_PACKET {
232 return Ok(Some(buff));
233 }
234 }
235 Err(e) => return Err(AudioMothError::HidError(e)),
236 }
237 }
238 }
239 Err(e) => return Err(e),
240 }
241 return Err(AudioMothError::OtherError(String::from("get packet error")));
242 }
243
244 pub fn send_packet(&self, msg_data: &[u8]) -> AudioMothResult<usize> {
249 let mut buffer = vec![0x00, USB_MSG_TYPE_SET_APP_PACKET];
250 msg_data.iter().for_each(|f| buffer.push(*f));
251 match self.device.write(&msg_data) {
252 Ok(uszie) => {
253 return Ok(uszie);
254 }
255 Err(e) => return Err(AudioMothError::HidError(e)),
256 }
257 }
258
259 pub fn get_firmware_version(&self) -> AudioMothResult<[u8; 3]> {
261 let buffer = [0x00, USB_MSG_TYPE_GET_FIRMWARE_VERSION];
262 match self.write(&buffer) {
263 Ok(usize) => {
264 if usize != 0 {
265 let mut buff: [u8; 64] = [0; 64];
266 if let Ok(size) = self.device.read(&mut buff) {
267 if size > 0 && buff[0] == USB_MSG_TYPE_GET_FIRMWARE_VERSION {
268 return Ok(
269 convert::convert_three_bytes_from_buffer_to_firmware_version(
270 &buff, 1,
271 ),
272 );
273 } else {
274 return Err(AudioMothError::OtherError(String::from(
275 " Incorrect message type from AudioMoth device",
276 )));
277 }
278 }
279 }
280 }
281 Err(e) => return Err(e),
282 }
283 return Err(AudioMothError::OtherError(String::from(
284 "get firmware version error",
285 )));
286 }
287
288 pub fn get_firmware_description(&self) -> AudioMothResult<String> {
292 let buffer = [0x00, USB_MSG_TYPE_GET_FIRMWARE_DESCRIPTION];
293 match self.write(&buffer) {
294 Ok(usize) => {
295 if usize != 0 {
296 let mut buff: [u8; 64] = [0; 64];
297 if let Ok(size) = self.device.read(&mut buff) {
298 if size > 0 && buff[0] == USB_MSG_TYPE_GET_FIRMWARE_DESCRIPTION {
299 return Ok(convert::convert_bytes_from_buffer_to_firmware_description(
300 &buff, 1,
301 ));
302 } else {
303 return Err(AudioMothError::OtherError(String::from(
304 " Incorrect message type from AudioMoth device",
305 )));
306 }
307 }
308 }
309 }
310 Err(e) => {
311 return Err(e);
312 }
313 }
314 return Err(AudioMothError::OtherError(String::from(
315 "get firmware description error",
316 )));
317 }
318
319 pub fn query_bootloader_state(&self) -> AudioMothResult<bool> {
321 let buffer = [0x00, USB_MSG_TYPE_QUERY_BOOTLOADER];
322 let _ = self.write(&buffer).unwrap();
323 let mut buf = [0u8; 64];
324 let _ = self.device.read(&mut buf);
325 Ok(convert::convert_bytes_to_bootloader_state(&mut buf, 1))
326 }
327
328 pub fn switch_to_bootloader(&self) -> AudioMothResult<usize> {
330 let buffer = [0x00, USB_MSG_TYPE_SWITCH_TO_BOOTLOADER];
331 match self.write(&buffer) {
332 Ok(_) => {
333 let mut buf = [0u8; 64];
334 match self.device.read(&mut buf[..]) {
335 Ok(usize) => return Ok(usize),
336 Err(e) => return Err(AudioMothError::HidError(e)),
337 }
338 }
339 Err(e) => return Err(e),
340 }
341 }
342}