Skip to main content

Grow_r502_a_fingerprint_sensor/
lib.rs

1use serialport;
2// use std::io::{Read, Write};
3use 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,                         // Packet Header
11            0xFF, 0xFF, 0xFF, 0xFF,             // Module Address (default)
12            0x01,                               // Packet Identifier: Command Packet
13            ((payload.len() + 2) >> 8) as u8,   // Length High
14            ((payload.len() + 2) & 0xFF) as u8, // Length Low
15        ];
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);    // Checksum high
21        packet.push((checksum & 0xFF) as u8);  // Checksum low
22
23        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])?; // GetImage
35            if resp.get(9) == Some(&0x00) {
36                break;
37            }
38        }
39
40        println!("Image taken. Converting...");
41        let conv1 = send_packet(port, &[0x02, 0x01])?; // image2Tz buffer 1
42        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}