Grow_r502_a_fingerprint_sensor/
lib.rs1use serialport;
2use std::time::Duration;
4
5pub mod fingerprint {
6 use super::*;
7
8 pub fn send_packet(port: &mut dyn serialport::SerialPort, payload: &[u8]) -> std::io::Result<Vec<u8>> {
9 let mut packet: Vec<u8> = vec![
10 0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, ((payload.len() + 2) >> 8) as u8, ((payload.len() + 2) & 0xFF) as u8, ];
16
17 packet.extend_from_slice(payload);
18
19 let checksum: u16 = packet[6..].iter().map(|&b| b as u16).sum();
20 packet.push((checksum >> 8) as u8); packet.push((checksum & 0xFF) as u8); port.write_all(&packet)?;
24
25 let mut buf = [0u8; 64];
26 let n = port.read(&mut buf)?;
27 Ok(buf[..n].to_vec())
28 }
29
30 pub fn enroll_fingerprint(port: &mut dyn serialport::SerialPort, id: u16) -> std::io::Result<()> {
31 println!("Place finger on sensor...");
32
33 loop {
34 let resp = send_packet(port, &[0x01])?; if resp.get(9) == Some(&0x00) {
36 break;
37 }
38 }
39
40 println!("Image taken. Converting...");
41 let conv1 = send_packet(port, &[0x02, 0x01])?; if conv1.get(9) != Some(&0x00) {
43 println!("Failed to convert first image.");
44 return Ok(());
45 }
46
47 println!("Remove finger...");
48 std::thread::sleep(Duration::from_secs(2));
49
50 loop {
51 let resp = send_packet(port, &[0x01])?;
52 if resp.get(9) == Some(&0x02) {
53 break;
54 }
55 }
56
57 println!("Place same finger again...");
58 loop {
59 let resp = send_packet(port, &[0x01])?;
60 if resp.get(9) == Some(&0x00) {
61 break;
62 }
63 }
64
65 let conv2 = send_packet(port, &[0x02, 0x02])?;
66 if conv2.get(9) != Some(&0x00) {
67 println!("Failed to convert second image.");
68 return Ok(());
69 }
70
71 let model = send_packet(port, &[0x05])?;
72 if model.get(9) != Some(&0x00) {
73 println!("Fingerprints did not match.");
74 return Ok(());
75 }
76
77 let id_high = (id >> 8) as u8;
78 let id_low = (id & 0xFF) as u8;
79 let store = send_packet(port, &[0x06, 0x01, id_high, id_low])?;
80 if store.get(9) == Some(&0x00) {
81 println!("Fingerprint stored at ID {}", id);
82 } else {
83 println!("Failed to store fingerprint.");
84 }
85
86 Ok(())
87 }
88
89 pub fn verify_fingerprint(port: &mut dyn serialport::SerialPort) -> std::io::Result<()> {
90 println!("Waiting for finger...");
91
92 loop {
93 let resp = send_packet(port, &[0x01])?;
94 if resp.get(9) == Some(&0x00) {
95 break;
96 }
97 }
98
99 let conv = send_packet(port, &[0x02, 0x01])?;
100 if conv.get(9) != Some(&0x00) {
101 println!("Failed to convert image.");
102 return Ok(());
103 }
104
105 let search = send_packet(port, &[0x04, 0x01, 0x00, 0x00, 0x00, 0xFF])?;
106 if search.len() >= 14 && search[9] == 0x00 {
107 let id = ((search[10] as u16) << 8) | search[11] as u16;
108 let score = ((search[12] as u16) << 8) | search[13] as u16;
109 println!("Match found! ID: {}, Score: {}", id, score);
110 } else {
111 println!("No match found.");
112 }
113
114 Ok(())
115 }
116
117 pub fn list_fingerprints(port: &mut dyn serialport::SerialPort) -> std::io::Result<()> {
118 println!("Checking stored fingerprints...");
119
120 let mut used_ids = Vec::new();
121
122 for page in 0..=7 {
123 let resp = send_packet(port, &[0x1F, page])?;
124
125 if resp.get(9) != Some(&0x00) {
126 println!("Failed to retrieve template index for page {}", page);
127 continue;
128 }
129
130 if resp.len() >= 42 {
131 for (i, byte) in resp[10..42].iter().enumerate() {
132 for bit in 0..8 {
133 if byte & (1 << bit) != 0 {
134 let id = page as u16 * 16 + (i as u16 * 8 + bit);
135 if id < 128 {
136 used_ids.push(id);
137 }
138 }
139 }
140 }
141 }
142 }
143
144 if used_ids.is_empty() {
145 println!("No fingerprints stored.");
146 } else {
147 println!("Stored fingerprint IDs: {:?}", used_ids);
148 }
149
150 Ok(())
151 }
152
153 pub fn delete_fingerprint(port: &mut dyn serialport::SerialPort, id: u16) -> std::io::Result<()> {
154 println!("Attempting to delete fingerprint with ID {}...", id);
155
156 let id_high = (id >> 8) as u8;
157 let id_low = (id & 0xFF) as u8;
158 let resp = send_packet(port, &[0x0C, id_high, id_low, 0x00, 0x01])?;
159
160 if resp.get(9) == Some(&0x00) {
161 println!("Successfully deleted fingerprint ID {}.", id);
162 } else {
163 println!("Failed to delete fingerprint ID {}.", id);
164 }
165
166 Ok(())
167 }
168}