-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.ino
142 lines (116 loc) · 3.41 KB
/
client.ino
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
/**
* DOORBOT
* (c)2011-2013 Ohm Base Hackerspace (ohmbase.org)
*/
#include <Arduino.h>
#include <SPI.h>
#include <String.h>
#include <EEPROM.h>
#include <SoftwareSerial.h>
#include <Ethernet.h>
#include <sha256.h>
#include "config.h"
#include "pin_config.h"
#include "fail_codes.h"
#include "ParallaxRFID.h"
#include "AuthCache.h"
#include "Key.h"
#include "BaseClient.h"
#include "DoorbotClient.h"
DoorbotClient client(CLIENT_ID, CLIENT_KEY);
byte mac[] = CLIENT_MAC;
boolean ethernet_initialized = false;
#ifndef USE_DHCP
IPAddress gateway_ip = GATEWAY_IP;
IPAddress client_ip = CLIENT_IP;
byte subnet[] = SUBNET_MASK;
#endif // ifndef USE_DHCP
void setup() {
// Initialize hardware serial
Serial.begin(9600);
// Initialize the RFID reader
ParallaxRFID.begin();
// Set up door pin
pinMode(DOOR_PIN, OUTPUT);
#ifdef CLEAR_CACHE_ON_BOOT
AuthCache.clear();
#end
}
inline void fail(int code) {
//Serial.print('!');
//Serial.println(code, HEX);
}
void loop() {
/// Initialize ethernet (if not intialized) /////////////////////////
if (!ethernet_initialized) {
#ifdef USE_DHCP
// .. using DHCP
ethernet_initialized = !(Ethernet.begin(mac) == 0);
#else
// .. using fixed settings
Ethernet.begin(mac, client_ip, gateway_ip, gateway_ip, subnet);
ethernet_initialized = true;
#endif // ifdef USE_DHCP
if (!ethernet_initialized) {
fail(FAIL_ETHERNET_BEGIN);
}
}
// Connect to server ////////////////////////////////////////////////
// Force clean-up if there is data to be read (FIXME)
if (ethernet_initialized && client.available()) {
client.shutdown();
}
if (ethernet_initialized && !client.connected()) {
// Connect to server (trying CONNECT_RETRY_COUNT times)
int attempt = 0;
while(attempt++ < CONNECT_RETRY_COUNT) {
if (!client.connect(SERVER_IP, SERVER_PORT)) {
// failed to connect...
fail(FAIL_ETHERNET_CONNECT);
client.shutdown();
delay(CONNECT_RETRY_DELAY);
else {
// connected!
break;
}
}
// Perform handshake
if (!client.handshake()) {
fail(FAIL_ETHERNET_HANDSHAKE);
client.shutdown();
}
}
// Update cache /////////////////////////////////////////////////////
if (ethernet_initialized && client.connected()) {
client.refreshCache();
}
// Wait for RFID to be scanned (hoping TCP connection stays alive)
String rfid_token = ParallaxRFID.read();
if (rfid_token.length() == PX_RFID_LENGTH) {
// Hash RFID value to get an "auth" token
uint8_t auth_token[DOORBOT_AUTH_TOKEN_LENGTH] = {0};
Sha256.init();
Sha256.print(rfid_token);
memcpy(auth_token, Sha256.result(), DOORBOT_AUTH_TOKEN_LENGTH);
// Check authentication token against server
if (client.authenticateRFID(auth_token)) {
// Token request succeeded, cache token
AuthCache.save(auth_token);
// Unlock the door
digitalWrite(DOOR_PIN, HIGH);
// Wait an acceptible time for the door to be opened
delay(DOOR_OPEN_DELAY);
// Lock the door
digitalWrite(DOOR_PIN, LOW);
}
else {
// Token request failed, flush cache of token
AuthCache.remove(token);
}
}
// Clean up the client if there was a problem...
if (ethernet_initialized && (client.available() || !client.connected())) {
client.shutdown();
}
delay(LOOP_DELAY); // Limit loop time
}