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
|
/**
*
* Simple RFID lock controller, based on:
* RFID Eval 13.56MHz Shield example sketch v10
* Aaron Weiss, aaron at sparkfun dot com
* OSHW license: http://freedomdefined.org/OSHW
*
* @note Works with 13.56MHz MiFare 1k tags.
* @note RFID Reset attached to D13 (aka status LED)
* @note Be sure include the NewSoftSerial lib, http://arduiniana.org/libraries/newsoftserial/
* @note Sha256 library is required, http://code.google.com/p/cryptosuite/
*/
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <sha256.h>
#include "config.h"
#include "keypad.h"
#include "pc.h"
#include "rf.h"
#include "emem.h"
// Global var
/** Used to pass current command hash **/
unsigned char g_Hash[EMEM_HASH_SIZE];
/** Door control pin. */
#define DOOR_CTRN (4)
// From pc.cpp
/** Flag set when next scan should send mid. */
extern boolean pc_send_flag;
/** Setup function. */
void setup() {
Serial.begin(19200);
keypad_init();
delay(10);
rf_halt();
pinMode(DOOR_CTRN, OUTPUT);
#ifdef DEBUG
Serial.println("Ready");
#endif //DEBUG
}
/** Idle. */
#define STATE_IDLE 0
/** Waiting for pin code. */
#define STATE_PIN 1
/** Waiting for mifare. */
#define STATE_MIFARE 2
/** State variable. */
int state=STATE_IDLE;
/** Start time for timeout calculation. */
unsigned long state_time=0;
/** Timeout value. */
#define STATE_TIMEOUT 20000
/** Defines how long door should be open in ms. */
#define STATE_DOORTIME 4000
/** Main loop. */
void loop(){
unsigned long pin=0;
unsigned long rfid=0;
unsigned long current_time;
while (1) {
switch (state){
case STATE_PIN:
if (keypad_pin_get(&pin)){
//Pin code was read
//Check if authorised
char str[8+1+8+1];
for(int ii=0;ii<8+1+8+1;ii++) str[ii]=0;
snprintf(str,8+1+8+1,"%08lx:%08lx",pin,rfid);
#ifdef DEBUG
Serial.print("Got pin: ");
Serial.print(pin);
Serial.print(" and rfid: ");
Serial.println(rfid);
Serial.print("Rfid and pin: ");
Serial.println(str);
#endif //DEBUG
Sha256.init();
Sha256.print(str);
uint8_t * hash=Sha256.result();
#ifdef DEBUG
pc_print_hash(hash);
Serial.println();
#endif //DEBUG
//react
unsigned int fid = emem_find_data(hash);
if (pc_send_flag){
pc_send_flag = false;
pc_print('s',fid,hash);
}
if(fid!=EMEM_INV_ADR) {
//"success" beep
keypad_pin_ok();
//open door
#ifdef DEBUG
Serial.println("Door opened");
#endif //DEBUG
digitalWrite(DOOR_CTRN, HIGH);
delay(STATE_DOORTIME);
digitalWrite(DOOR_CTRN, LOW);
#ifdef DEBUG
Serial.println("Door closed");
#endif //DEBUG
} else {
//"error" beep
keypad_pin_wrong();
#ifdef DEBUG
Serial.println("Wrong rfid or pin");
#endif //DEBUG
}
pin=0;
rfid=0;
state=STATE_IDLE;
continue;
}
current_time=millis();
if (state_time<current_time){
if (current_time-state_time>STATE_TIMEOUT){
//turn keypad off
keypad_off();
#ifdef DEBUG
Serial.println("Keyboard timeout");
#endif //DEBUG
pin=0;
rfid=0;
state=STATE_IDLE;
continue;
}
} else {
if (state_time-current_time>STATE_TIMEOUT){
//turn keypad off
keypad_off();
#ifdef DEBUG
Serial.println("Keyboard timeout");
#endif //DEBUG
pin=0;
rfid=0;
state=STATE_IDLE;
continue;
}
}
break;
case STATE_MIFARE:
if (rf_comm(&rfid)){
#ifdef DEBUG
Serial.println("Got rfid: ");
Serial.println(rfid,HEX);
#endif //DEBUG
//Rfid was read
state=STATE_PIN;
state_time=millis();
}
break;
case STATE_IDLE:
default:
pin=0;
rfid=0;
state=STATE_MIFARE;
break;
}
//Communication with PC (optional).
pc_comm();
}
}
|