1use std::sync::{Arc, Mutex};
5use std::{time::Duration};
6use rand::Rng;
7use rusb::{
8 DeviceHandle, DeviceList, Language,
9 Device, UsbContext, Direction,
10};
11
12use crate::reader::*;
13use crate::reader::processing::*;
14use crate::errors::*;
15
16const UEM_VID: u16 = 0xC251;
17const UEM_PID: u16 = 0x130A;
18
19#[derive(Debug, Default)]
20struct ReaderUsb<T: UsbContext> {
21 handle: Option<DeviceHandle<T>>,
22 device: Option<Device<T>>,
23 language: Option<Language>,
24 timeout: Duration,
25 ep_in_addr: u8,
26 ep_out_addr: u8,
27 ncommand: u8,
28}
29
30impl<T: UsbContext> CommandsCounter for ReaderUsb<T> {
31 fn commands_count(&self) -> u8 {
32 self.ncommand
33 }
34
35 fn increment_commands(&mut self) {
36 if self.commands_count() == u8::MAX {
37 self.ncommand = 0;
38 }
39 self.ncommand += 1;
40 }
41}
42
43impl<T: UsbContext> UemReaderInternalTrait for ReaderUsb<T> {
44 fn open(&mut self) -> UemResult {
47 if self.handle.is_some() {
48 return Err(UemError::ReaderAlreadyConnected);
49 }
50 if let Ok(h) = self.device.take().unwrap().open() {
51 if let Ok(l) = h.read_languages(TIMEOUT) {
52 if !l.is_empty() {
53 self.language = Some(l[0]);
54 }
55 }
56 self.handle = Some(h);
57 self.timeout = TIMEOUT;
58 return Ok(())
59 }
60 Err(UemError::ReaderConnectionFailed)
61 }
62
63 fn close(&mut self) -> core::result::Result<(), UemError> {
65 if self.handle.is_none() {
66 return Err(UemError::ReaderNotConnected);
67 }
68 if let Some(h) = self.handle.take() {
69 self.device = Some(h.device());
70 return Ok(())
71 }
72 Ok(())
73 }
74
75 fn send(&mut self, command: &[u8]) -> UemResultVec {
77
78 if self.handle.is_none() {
79 return Err(UemError::ReaderNotConnected);
80 }
81 if command.is_empty() {
82 return Err(UemError::IncorrectParameter);
83 }
84
85 let send_buffer = prepare_command(self, &command);
86 if send_buffer.is_empty() {
87 return Err(UemError::IncorrectParameter);
88 }
89
90 let handle = self.handle.as_mut().unwrap();
91
92 handle.claim_interface(0).map_err(|_| UemError::Access)?;
93
94 let mut res = handle.write_bulk(self.ep_out_addr, send_buffer.as_slice(), TIMEOUT);
95
96 if res.is_err() {
97 return Err(UemError::NotTransacted);
98 }
99
100 let mut receive_buffer = vec![0u8; 256];
101
102 res = handle.read_bulk(self.ep_in_addr, &mut receive_buffer, TIMEOUT);
103
104 handle.release_interface(0).map_err(|_| UemError::Access)?;
105
106 if res.is_err() {
107 return Err(UemError::ReaderResponseFailure);
108 }
109
110 let response_length = res.unwrap();
111
112 if response_length <= 6 {
113 return Err(UemError::ReaderResponseFailure);
114 }
115
116 let response = parse_response(&receive_buffer[..response_length].to_vec())?;
117
118 if (response.len() < 2) || (response[0] != command[0]) {
119 return Err(UemError::ReaderIncorrectResponse);
120 }
121
122 if response[1] != 0x00 {
123 if response.len() == 2 {
124 return Err(UemError::ReaderUnsuccessful(UemInternalError::from_byte(response[1]), None));
125 }
126 return Err(UemError::ReaderUnsuccessful(UemInternalError::from_byte(response[1]), Some(response[2..].to_vec())));
127 }
128
129 Ok(response[2..].to_vec())
130 }
131}
132
133pub fn find_usb_readers() -> Vec<UemReader> {
161 let mut usb_readers: Vec<UemReader> = Vec::new();
162 let devices = DeviceList::new();
163 if let Err(_) = devices {
164 return usb_readers;
165 }
166 for device in devices.unwrap().iter() {
167 let device_desc = match device.device_descriptor() {
168 Ok(d) => d,
169 Err(_) => continue,
170 };
171
172 if device_desc.vendor_id() != UEM_VID ||
173 device_desc.product_id() != UEM_PID {
174 continue
175 }
176
177 let mut usb_reader = ReaderUsb {
178 ncommand: rand::thread_rng().gen(),
179 ..Default::default()
180 };
181
182 for n in 0..device_desc.num_configurations() {
183 let config_desc = match device.config_descriptor(n) {
184 Ok(c) => c,
185 Err(_) => continue,
186 };
187
188 for interface in config_desc.interfaces() {
189 for interface_desc in interface.descriptors() {
190 for endpoint_desc in interface_desc.endpoint_descriptors() {
191 match endpoint_desc.direction() {
192 Direction::In => usb_reader.ep_in_addr = endpoint_desc.address(),
193 Direction::Out => usb_reader.ep_out_addr = endpoint_desc.address()
194 }
195 }
196 }
197 }
198 }
199 usb_reader.device = Some(device);
200 usb_readers.push(Arc::new(Mutex::new(usb_reader)));
201 }
202
203 usb_readers
204}