uem_reader/commands/
reader.rs

1//! Commands relative to control behavior of
2//! a reader itself
3
4#![allow(dead_code)]
5
6use crate::reader::*;
7use crate::errors::*;
8
9use enum_iterator::Sequence;
10
11#[repr(u8)]
12#[derive(Debug, PartialEq, Sequence, Clone, Copy)]
13/// LED color combinations
14pub enum UemColor {
15    /// LED is off
16    Off = 0b000,
17    Red = 0b001,
18    Green = 0b010,
19    Blue = 0b100,
20    Yellow = 0b011,
21    Magenta = 0b101,
22    Cyan = 0b110,
23    White = 0b111,
24}
25
26/// Structure for commands controlling 
27/// a reader itself
28pub struct UemCommandsReader<'a> {
29    reader: &'a UemReader,
30}
31
32/// Accessing reader related commands group
33pub trait UemCommandsReaderTrait {
34    fn reader(&mut self) -> UemCommandsReader;
35}
36
37impl<'a> UemCommandsReader<'a> {
38    pub(crate) fn new(rd: &'a UemReader) -> Self {
39        UemCommandsReader {reader: rd}
40    }
41
42    /// Make short sound signals of specific count
43    /// 
44    /// # Arguments
45    ///
46    /// * `count` - Number of beeps to perform
47    /// 
48    /// # Returns
49    /// 
50    /// `Ok(())` on success, otherwise returns an error.
51    /// 
52    /// # Example
53    /// 
54    /// ```
55    /// # use uem_reader::reader::{UemReaderInternal, usb::find_usb_readers};
56    /// # use uem_reader::commands::{UemCommandsTrait, reader::*};
57    /// # let mut uem_readers = find_usb_readers();
58    /// # if uem_readers.is_empty() { return; }
59    /// # let uem_reader = uem_readers.get_mut(0);
60    /// # if uem_reader.is_none() { return; }
61    /// # let uem_reader = uem_reader.unwrap();
62    /// # if uem_reader.open().is_err() { return; }
63    /// // Beep 5 times
64    /// if uem_reader.commands().reader()
65    ///     .beep(5)
66    /// .is_err() {
67    ///     return;
68    /// }
69    /// # if uem_reader.close().is_err() { return; }
70    /// ```
71    pub fn beep(&mut self, count: u8) -> UemResult {
72        if count < 1 {
73            return Err(UemError::IncorrectParameter);
74        }
75        let mut raw_reader = self.reader.lock().unwrap();
76        raw_reader.send(&vec![0x05, count]).map(|_| ())
77    }
78
79    /// Blink `count` times with led of specific color
80    /// and remain with other color switched on
81    /// 
82    /// # Arguments
83    ///
84    /// * `count` - Number of blinks to perform
85    /// * `color` - [color](UemColor) to blink with
86    /// * `post_color` - [color](UemColor) to leave on
87    /// 
88    /// # Returns
89    /// 
90    /// `Ok(())` on success, otherwise returns an error.
91    /// 
92    /// # Example
93    /// 
94    /// ```
95    /// # use uem_reader::reader::{
96    ///     UemReaderInternal,
97    ///     usb::find_usb_readers};
98    /// # use uem_reader::commands::{UemCommandsTrait, reader::*};
99    /// # let mut uem_readers = find_usb_readers();
100    /// # if uem_readers.is_empty() { return; }
101    /// # let uem_reader = uem_readers.get_mut(0);
102    /// # if uem_reader.is_none() { return; }
103    /// # let uem_reader = uem_reader.unwrap();
104    /// # if uem_reader.open().is_err() { return; }
105    /// // Blink 3 times with green and remain yellow
106    /// if uem_reader.commands().reader()
107    ///     .led(3, UemColor::Green, UemColor::Yellow)
108    /// .is_err() {
109    ///     return;
110    /// }
111    /// # if uem_reader.close().is_err() { return; }
112    /// ```
113    pub fn led(&mut self, count: u8, color: UemColor, post_color: UemColor) -> UemResult {
114        let mut raw_reader = self.reader.lock().unwrap();
115        raw_reader.send(&vec![0x07, color as u8, count, post_color as u8]).map(|_| ())
116    }
117
118    /// Turn radio chip on
119    /// 
120    /// # Arguments
121    /// 
122    /// - `on` - `true` if needed to power on the radio, 
123    /// otherwise `false`
124    /// 
125    /// # Returns
126    /// 
127    /// `Ok(())` on success, otherwise returns an [`UemError`](UemError).
128    /// 
129    /// # Example
130    /// 
131    /// ```
132    /// # use uem_reader::reader::{UemReaderInternal, usb::find_usb_readers};
133    /// # use uem_reader::commands::{UemCommandsTrait, reader::*};
134    /// # let mut uem_readers = find_usb_readers();
135    /// # if uem_readers.is_empty() { return; }
136    /// # let uem_reader = uem_readers.get_mut(0);
137    /// # if uem_reader.is_none() { return; }
138    /// # let uem_reader = uem_reader.unwrap();
139    /// # if uem_reader.open().is_err() { return; }
140    /// let mut uem_cmds = uem_reader.commands();
141    /// let mut uem_cmds_reader = uem_cmds.reader();
142    /// if uem_cmds_reader.power_radio(true).is_err() {
143    ///     return;
144    /// }
145    /// # if uem_reader.close().is_err() { return; }
146    /// ```
147    pub fn power_radio(&mut self, on: bool) -> UemResult {
148        let mut raw_reader = self.reader.lock().unwrap();
149        match on {
150            true => raw_reader.send(&vec![0x10]).map(|_| ()),
151            false => raw_reader.send(&vec![0x04, 0x80, 0x01]).map(|_| ())
152        }
153    }
154
155    /// Switch radio field off for a specified duration
156    /// 
157    /// By switching off radio field, cards in the field
158    /// are beind unpowered and thus reset.
159    /// 
160    /// # Arguments
161    ///
162    /// * `duration` - Number of milliseconds
163    /// to switch off radio field. If set to 0,
164    /// the field will be switched off permanently.
165    /// The field can be switched on again with
166    /// the same command and non-zero duration.
167    /// 
168    /// # Returns
169    /// 
170    /// `Ok(())` on success, otherwise returns an error.
171    /// 
172    /// # Example
173    /// 
174    /// ```
175    /// # use uem_reader::reader::{UemReaderInternal, usb::find_usb_readers};
176    /// # use uem_reader::commands::{UemCommandsTrait, reader::*};
177    /// # let mut uem_readers = find_usb_readers();
178    /// # if uem_readers.is_empty() { return; }
179    /// # let uem_reader = uem_readers.get_mut(0);
180    /// # if uem_reader.is_none() { return; }
181    /// # let uem_reader = uem_reader.unwrap();
182    /// # if uem_reader.open().is_err() { return; }
183    /// // Switch off radio for 10 ms
184    /// if uem_reader.commands().reader()
185    ///     .radio_off_on(10)
186    /// .is_err() {
187    ///     return;
188    /// }
189    /// # if uem_reader.close().is_err() { return; }
190    /// ```
191    pub fn radio_off_on(&mut self, duration: u16) -> UemResult {
192        let mut raw_reader = self.reader.lock().unwrap();
193        raw_reader.send(&vec![0x05, 
194            (duration & 0x00FF) as u8,
195            ((duration & 0xFF00) >> 8) as u8]
196        ).map(|_| ())
197    }
198
199    /// Read reader version
200    /// 
201    /// Reader version is a 6 bytes vector
202    /// 
203    /// # Returns
204    /// 
205    /// `Ok(Vec<u8>)` containing the version,
206    /// otherwise [`UemError`](UemError).
207    /// 
208    /// # Example
209    /// 
210    /// ```
211    /// # use uem_reader::reader::{UemReaderInternal, usb::find_usb_readers};
212    /// # use uem_reader::commands::{UemCommandsTrait, reader::*};
213    /// # let mut uem_readers = find_usb_readers();
214    /// # if uem_readers.is_empty() { return; }
215    /// # let uem_reader = uem_readers.get_mut(0);
216    /// # if uem_reader.is_none() { return; }
217    /// # let uem_reader = uem_reader.unwrap();
218    /// # if uem_reader.open().is_err() { return; }
219    /// match uem_reader.commands().reader()
220    /// .get_version() {
221    ///     Ok(ver) => assert_eq!(ver.len(), 6),
222    ///     Err(err) => {
223    ///         uem_reader.close();
224    ///         println!("{:?}", err);
225    ///         assert!(false);
226    ///     }
227    /// }
228    /// # if uem_reader.close().is_err() { return; }
229    /// ```
230    pub fn get_version(&mut self) -> UemResultVec {
231        let mut raw_reader = self.reader.lock().unwrap();
232        raw_reader.send(&vec![0x64])
233    }
234
235    /// Read reader serial
236    /// 
237    /// Reader serial is a 4 bytes vector
238    /// 
239    /// # Returns
240    /// 
241    /// `Ok(Vec<u8>)` containing the serial,
242    /// otherwise [`UemError`](UemError).
243    /// 
244    /// # Example
245    /// 
246    /// ```
247    /// # use uem_reader::reader::{UemReaderInternal, usb::find_usb_readers};
248    /// # use uem_reader::commands::{UemCommandsTrait, reader::*};
249    /// # let mut uem_readers = find_usb_readers();
250    /// # if uem_readers.is_empty() { return; }
251    /// # let uem_reader = uem_readers.get_mut(0);
252    /// # if uem_reader.is_none() { return; }
253    /// # let uem_reader = uem_reader.unwrap();
254    /// # if uem_reader.open().is_err() { return; }
255    /// match uem_reader.commands().reader()
256    /// .get_serial() {
257    ///     Ok(ser) => assert_eq!(ser.len(), 4),
258    ///     Err(err) => {
259    ///         uem_reader.close();
260    ///         println!("{:?}", err);
261    ///         assert!(false);
262    ///     }
263    /// }
264    /// # if uem_reader.close().is_err() { return; }
265    /// ```
266    pub fn get_serial(&mut self) -> UemResultVec {
267        let mut raw_reader = self.reader.lock().unwrap();
268        raw_reader.send(&vec![0x22])
269    }
270}