Commit | Line | Data |
---|---|---|
bb5fbbec JM |
1 | #include <MFRC522.h> |
2 | #include <FS.h> | |
3 | #include "config.h" | |
4 | ||
5 | typedef uint8_t byte_t; | |
6 | ||
7 | static const char * hex = "0123456789ABCDEF"; | |
8 | ||
9 | ||
10 | int hexto(char c) | |
11 | { | |
12 | if (c >= '0' && c <='9') return c - '0'; | |
13 | if (c >= 'a' && c <= 'f') return 10 + (c - 'a'); | |
14 | if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); | |
15 | } | |
16 | ||
17 | static const char * cardid(const byte_t uid[], byte_t len) | |
18 | { | |
19 | static char text[21]; | |
20 | if (len > 10) return NULL; | |
21 | ||
22 | char * p = text; | |
23 | *(p++) = hex[ len ]; //DEBUG | |
24 | *(p++) = ':'; //DEBUG | |
25 | for (int i=0; i<len; i++) { | |
26 | *(p++) = hex[ uid[i] >> 4 ]; | |
27 | *(p++) = hex[ uid[i] & 15 ]; | |
28 | } | |
29 | *p = 0; | |
30 | return text; | |
31 | } | |
32 | ||
33 | const char * uid_print(const MFRC522::Uid uid) | |
34 | { | |
35 | return cardid(uid.uidByte, uid.size); | |
36 | } | |
37 | ||
38 | void uid_copy(MFRC522::Uid &a, const MFRC522::Uid b) | |
39 | { | |
40 | a.size = b.size; | |
41 | memcpy(a.uidByte, b.uidByte, b.size); | |
42 | } | |
43 | ||
44 | bool uid_compare(const MFRC522::Uid a, const MFRC522::Uid b) | |
45 | { | |
46 | if (a.size != b.size) return 0; | |
47 | if (a.size == 0 || b.size == 0) return 0; | |
48 | return memcmp(a.uidByte, b.uidByte, a.size)==0?true:false; | |
49 | } | |
50 | ||
51 | void uid_zero(MFRC522::Uid &uid) | |
52 | { | |
53 | uid.size = 0; | |
54 | } | |
55 | ||
56 | /* is this card id permitted */ | |
57 | bool uid_auth(const MFRC522::Uid uid) | |
58 | { | |
59 | // TODO: everything | |
60 | // return card_auth(cardid(uid.uidByte, uid.size)); | |
61 | return true; | |
62 | } | |
63 | ||
64 | bool uid_isset(const MFRC522::Uid uid) | |
65 | { | |
66 | return (uid.size!=0); | |
67 | } | |
68 | ||
69 | bool uid_visible(MFRC522 &reader, const MFRC522::Uid master) | |
70 | { | |
71 | MFRC522::Uid uid; | |
72 | ||
73 | // no tag given | |
74 | if (master.size == 0) return false; | |
75 | ||
76 | byte bufferATQA[2]; | |
77 | byte bufferSize = sizeof(bufferATQA); | |
78 | byte status = 0; | |
79 | ||
80 | SPI.begin(); | |
81 | ||
82 | // no tags in range to wakeup | |
83 | if (reader.PICC_WakeupA(bufferATQA, &bufferSize) == MFRC522::STATUS_TIMEOUT) { | |
84 | return false; | |
85 | } | |
86 | ||
87 | bool found = false; | |
88 | ||
89 | uid_copy(uid, master); | |
90 | if (reader.PICC_Select(&uid, uid.size * 8) == MFRC522::STATUS_OK) { | |
91 | // something answered, but was it the right one | |
92 | if (uid_compare(uid, master)) { | |
93 | // yes, match | |
94 | found=true; | |
95 | } else { | |
96 | // uid did not match | |
97 | } | |
98 | } else { | |
99 | // nothing answered | |
100 | } | |
101 | reader.PICC_HaltA(); | |
102 | return found; | |
103 | } | |
104 | ||
105 | ||
106 | bool uid_fetch(MFRC522 &reader, MFRC522::Uid &uid, int count) | |
107 | { | |
108 | SPI.begin(); | |
109 | ||
110 | byte bufferATQA[2]; | |
111 | byte bufferSize = sizeof(bufferATQA); | |
112 | byte status = 0; | |
113 | ||
114 | if (count == 0) { | |
115 | status = reader.PICC_WakeupA(bufferATQA, &bufferSize); | |
116 | } else { | |
117 | status = reader.PICC_RequestA(bufferATQA, &bufferSize); | |
118 | } | |
119 | ||
120 | uid_zero(uid); | |
121 | if (status != MFRC522::STATUS_OK && status != MFRC522::STATUS_COLLISION) { | |
122 | if (status == MFRC522::STATUS_TIMEOUT) { | |
123 | // Nobody listening | |
124 | return false; | |
125 | } | |
126 | } | |
127 | ||
128 | bool result = false; | |
129 | if ( (status = reader.PICC_Select(&uid, 0)) == MFRC522::STATUS_OK ) { | |
130 | result=true; | |
131 | } | |
132 | reader.PICC_HaltA(); | |
133 | ||
134 | return result; | |
135 | } | |
136 | ||
137 | ||
138 | bool uid_read(File &f, MFRC522::Uid &uid) | |
139 | { | |
140 | char line[40]; | |
141 | ||
142 | int len = f.readBytesUntil('\n', line, 40); | |
143 | if (len < 0 || len > 24) { | |
144 | Serial.print("Invalid read: "); | |
145 | Serial.println(len); | |
146 | return false; | |
147 | } | |
148 | line[len]=0; | |
149 | ||
150 | uid_zero(uid); | |
151 | if (len == 0) { | |
152 | // end of file | |
153 | return false; | |
154 | } | |
155 | ||
156 | // minimum length is 4 bytes == 10 chars | |
157 | if (len < 10) { | |
158 | Serial.print(F("Read Card: bad line length=")); | |
159 | Serial.print(len); | |
160 | Serial.print(" '"); | |
161 | Serial.print(line); | |
162 | Serial.println("'"); | |
163 | return false; | |
164 | } | |
165 | ||
166 | // invalid format | |
167 | if (line[1] != ':') { | |
168 | Serial.print(F("Read Card: bad format '")); | |
169 | Serial.print(line); | |
170 | Serial.println("'"); | |
171 | return false; | |
172 | } | |
173 | ||
174 | int bytes = hexto(line[0]); | |
175 | ||
176 | // invalid lengths: 4, 7, and 10 are the standards | |
177 | if (bytes != 4 && bytes != 7 && bytes != 10) { | |
178 | Serial.print(F("Read Card: bad size=")); | |
179 | Serial.print(bytes); | |
180 | Serial.print(" '"); | |
181 | Serial.print(line); | |
182 | Serial.println("'"); | |
183 | return false; | |
184 | } | |
185 | ||
186 | if (len < (bytes*2)+2) { | |
187 | Serial.print(F("Read card: line too short. len=")); | |
188 | Serial.print(len); | |
189 | Serial.print(F(" size=")); | |
190 | Serial.print(bytes); | |
191 | Serial.print(" '"); | |
192 | Serial.print(line); | |
193 | Serial.println("'"); | |
194 | return false; | |
195 | } | |
196 | ||
197 | uid.size = bytes; | |
198 | byte * p = uid.uidByte; | |
199 | int in = 2; | |
200 | ||
201 | for (;bytes > 0;bytes--) { | |
202 | int a,b; | |
203 | a = hexto(line[in++]); | |
204 | b = hexto(line[in++]); | |
205 | if (a == -1 || b == -1) { | |
206 | uid_zero(uid); | |
207 | ||
208 | Serial.print(F("Read Card: Non Hex char in line '")); | |
209 | Serial.print(line); | |
210 | Serial.println("'"); | |
211 | return false; | |
212 | } | |
213 | *(p++) = a<<4 | b; | |
214 | } | |
215 | ||
216 | #ifdef DEBUG | |
217 | Serial.print(F("Loaded card '")); | |
218 | Serial.print(line); | |
219 | Serial.print("' as "); | |
220 | Serial.println(uid_print(uid)); | |
221 | #endif | |
222 | ||
223 | return true; | |
224 | } | |
225 | ||
226 | bool uid_valid(MFRC522::Uid &uid) | |
227 | { | |
228 | #ifdef DEBUG | |
229 | Serial.print(F("Opening file ")); | |
230 | Serial.println(KEYS_FILE); | |
231 | #endif | |
232 | ||
233 | File f = SPIFFS.open(KEYS_FILE, "r"); | |
234 | // cant open the file, so card isnt there | |
235 | if (!f) { | |
236 | Serial.println(F("Cannot open cards file")); | |
237 | return false; | |
238 | } | |
239 | ||
240 | MFRC522::Uid entry; | |
241 | while ( uid_read(f, entry) ) { | |
242 | if (uid_compare(uid, entry)) { | |
243 | f.close(); | |
244 | #ifdef DEBUG | |
245 | Serial.println(F("Found card")); | |
246 | #endif | |
247 | return true; | |
248 | } | |
249 | } | |
250 | ||
251 | #ifdef DEBUG | |
252 | Serial.println(F("Card not found")); | |
253 | #endif | |
254 | f.close(); | |
255 | return false; | |
256 | } | |
257 |