This repository has been archived by the owner on Oct 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRFID.cpp
198 lines (168 loc) · 5.32 KB
/
RFID.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
$Id$
OpenDoorControl
Copyright (c) 2012 The Perth Artifactory by
Brett R. Downing <[email protected]>
Daniel Harmsworth <[email protected]>
Sebastian Southen <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "OpenDoorControl.h"
#include "RFID.h"
#include "SDfiles.h"
#include "control.h"
//#define DEBUG
void pollRFIDbuffer() {
static int i = 0; // position within the raw string
static char rfidString[RFIDSTRINGLENGTH + 1]; // the raw string off the RFID reader, +null term
while (Serial1.available() > 0) {
rfidString[i] = Serial1.read();
i++;
if ((rfidString[i-1] == 0x0D) ||
(rfidString[i-1] == 0x0A) ||
(rfidString[i-1] == 0x03) ||
(rfidString[i-1] == 0x02)) {
i = 0;
}
if (i >= RFIDSTRINGLENGTH) { // about to overwrite the null byte
if (checksumValid(rfidString)) { // check the checksum
char cardUID[RFIDLENGTH + 1]; // copy just the card UID
for (int j = 0; j < RFIDLENGTH; j++) {
cardUID[j] = rfidString[j];
}
cardUID[RFIDLENGTH] = '\0';
char *cardHash = hashThis(cardUID);
checksumOk(cardHash);// the function executed when the checksum is ok
}
else {
checksumfailed(rfidString);
}
i = 0;
}
}
}
void checksumOk(char *cardHash) { // when the checksum is ok
// Serial.print("checksum valid, hash = ");
// Serial.println(cardHash);
bool shouldOpenSpace = false; // Not all authentication successes should open the space.
MemberType result = authCard(cardHash);
if (result != 0) {
fileWrite(logFile, "Authentication Success: ", cardHash, true);
slowTimers[TIMERLCDTIME].start = theTime;
lcd.setCursor(0, 1);
switch (result) {
case MEMBERTYPE_FULL:
lcd.print("Member Card");
shouldOpenSpace = true;
openTheDoor();
break;
case MEMBERTYPE_RESTRICTED:
lcd.print("Restricted Card");
shouldOpenSpace = true;
openTheDoor();
break;
case MEMBERTYPE_RESTRICTED_OUT_OF_HOURS:
fileWrite(logFile, "Restricted card out of hours", "", true);
DoorStatus(1, 1, 0); // Flash yellow to indicate out-of-hours access attempt
break;
case MEMBERTYPE_RESTRICTED_NO_RTC:
fileWrite(logFile, "Restricted card, No RTC", "", true);
shouldOpenSpace = true;
openTheDoor();
break;
case MEMBERTYPE_ASSOCIATE:
if (spaceOpen) {
fileWrite(logFile, "Associate Card", "", false);
openTheDoor();
}
else {
fileWrite(logFile, "Associate card, space not open.", "", false);
DoorStatus(1, 1, 0);
}
break;
default:
lcd.print("Ow! Ow! Ow! Ow!"); // This should never happen
break;
}
if ( ( !spaceOpen ) && ( shouldOpenSpace ) ) {
openSpace(); // does logging itself
}
}
else {
fileWrite(logFile, "Authentication Failure: ", cardHash, true);
lcd.clear();
lcd.setCursor(0, 0);
//lcd.print("Who are you?!");
lcd.print("Auth Failure");
slowTimers[TIMERLCDTIME].start = theTime;
DoorStatus(1, 0, 0);
}
}
void checksumfailed(char *rfidString){ //when the checksum is ok
fileWrite(logFile, "checksum failed: ", rfidString, true);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Read Error");
slowTimers[TIMERLCDTIME].start = theTime;
}
bool checksumValid(char *rfidString){
byte val = 0;
byte highByte = 0;
byte code[6];
byte checksum = 0;
for (int i = 0; i < RFIDSTRINGLENGTH; i++) { // hex converter
val = rfidString[i];
if ((val >= '0') && (val <= '9')) { // If val is between 0 and 9
val = val - '0'; // convert to a 4 bit number
}
else if ((val >= 'A') && (val <= 'F')) { // If val is between A and F
val = 10 + val - 'A'; // Convert to a 4 bit number
} // We now have a 4 bit val
if (i & 1 == 1) { // every second char
code[i >> 1] = ((highByte << 4) | val); // Now we generate an 8 bit number
}
else { // or
highByte = val; // Store the 4 bit number for the next cycle
}
}
for (int i = 0; i < 5; i++) {
checksum ^= code[i]; //byte XOR
}
return (checksum == code[5]);
}
MemberType authCard(char *cardHash) {
MemberType retVal = MEMBERTYPE_NONE;
// Checks the cardHash against the full member hash file
if (cardInFile(fullFile, cardHash) == 0) {
retVal = MEMBERTYPE_FULL;
}
else if (cardInFile(assocFile, cardHash) == 0) {
retVal = MEMBERTYPE_ASSOCIATE;
}
else {
int schedStatus = cardInFile(restFile, cardHash);
#ifdef DEBUG
Serial.print("Card Return Value: ");
Serial.println(schedStatus);
#endif
if (schedStatus == 0) {
retVal = MEMBERTYPE_RESTRICTED;
}
else if (schedStatus == 2) {
retVal = MEMBERTYPE_RESTRICTED_OUT_OF_HOURS;
}
else if (schedStatus == 3) {
retVal = MEMBERTYPE_RESTRICTED_NO_RTC;
}
}
return retVal;
}