Improve reconnect, logging

This commit is contained in:
Christoph Hagen 2022-04-09 17:40:55 +02:00
parent 49e44f064d
commit e62c34f4df
3 changed files with 73 additions and 36 deletions

View File

@ -50,9 +50,16 @@ uint32_t getEpochTime() {
bool isMessageTimeAcceptable(uint32_t t) { bool isMessageTimeAcceptable(uint32_t t) {
uint32_t localTime = getEpochTime(); uint32_t localTime = getEpochTime();
if (localTime == 0) { if (localTime == 0) {
Serial.println("No epoch time available");
return false; return false;
} }
return t < localTime + allowedOffset && t > localTime - allowedOffset; if (t > localTime + allowedOffset) {
return false;
}
if (t < localTime - allowedOffset) {
return false;
}
return true;
} }
void prepareMessageCounterUsage() { void prepareMessageCounterUsage() {
@ -68,16 +75,14 @@ uint32_t getNextMessageCounter() {
} }
void printMessageCounter() { void printMessageCounter() {
Serial.printf("[INFO] Next message number: %d\n", getNextMessageCounter()); Serial.printf("[INFO] Next message number: %u\n", getNextMessageCounter());
} }
bool isMessageCounterValid(uint32_t counter) { bool isMessageCounterValid(uint32_t counter) {
return counter >= getNextMessageCounter(); return counter >= getNextMessageCounter();
} }
void didUseMessageCounter(uint32_t counter) { void setMessageCounter(uint32_t counter) {
// Store the next counter, so that resetting starts at 0
counter += 1;
EEPROM.write(0, (counter >> 24) & 0xFF); EEPROM.write(0, (counter >> 24) & 0xFF);
EEPROM.write(1, (counter >> 16) & 0xFF); EEPROM.write(1, (counter >> 16) & 0xFF);
EEPROM.write(2, (counter >> 8) & 0xFF); EEPROM.write(2, (counter >> 8) & 0xFF);
@ -86,7 +91,12 @@ void didUseMessageCounter(uint32_t counter) {
EEPROM.commit(); EEPROM.commit();
} }
void didUseMessageCounter(uint32_t counter) {
// Store the next counter, so that resetting starts at 0
setMessageCounter(counter+1);
}
void resetMessageCounter() { void resetMessageCounter() {
didUseMessageCounter(0); setMessageCounter(0);
Serial.println("[WARN] Message counter reset"); Serial.println("[WARN] Message counter reset");
} }

View File

@ -48,7 +48,7 @@ constexpr int32_t timeOffsetDaylightSavings = 3600;
// Servo is Emax ES08MA II // Servo is Emax ES08MA II
// The time (in ms) to keep the door button pressed // The time (in ms) to keep the door button pressed
constexpr uint32_t lockOpeningDuration = 2000; constexpr uint32_t lockOpeningDuration = 1500;
// The timer to use to control the servo // The timer to use to control the servo
constexpr int pwmTimer = 0; constexpr int pwmTimer = 0;
@ -60,7 +60,7 @@ constexpr int servoPin = 14;
constexpr int servoFrequency = 50; constexpr int servoFrequency = 50;
// The microseconds to set the servo to the pressed and released states // The microseconds to set the servo to the pressed and released states
constexpr int servoPressedState = 1600; constexpr int servoPressedState = 1720;//1600;
constexpr int servoReleasedState = 1520; constexpr int servoReleasedState = 1520;
@ -85,26 +85,48 @@ void setup() {
Serial.println("[INFO] Servo configured"); Serial.println("[INFO] Servo configured");
prepareMessageCounterUsage(); prepareMessageCounterUsage();
//resetMessageCounter();
printMessageCounter(); printMessageCounter();
Serial.printf("[INFO] Connecting to WiFi '%s'\n", wifiSSID);
WiFi.begin(wifiSSID, wifiPassword);
while(WiFi.status() != WL_CONNECTED) {
delay(100);
}
Serial.println("[INFO] WiFi connected");
configureNTP(timeOffsetToGMT, timeOffsetDaylightSavings, ntpServerUrl);
printLocalTime();
server.onMessage(handleReceivedMessage); server.onMessage(handleReceivedMessage);
Serial.printf("[INFO] Opening SSL socket %s%s on port %d\n", serverUrl, serverPath, serverPort);
server.connectSSL(serverAccessKey);
} }
uint32_t nextWifiReconnect = 0;
bool isReconnecting = false;
void loop() { void loop() {
uint32_t time = millis();
server.loop(); server.loop();
servo.loop(); servo.loop();
// Reconnect to WiFi
if(time > nextWifiReconnect && WiFi.status() != WL_CONNECTED) {
Serial.println("[INFO] Reconnecting WiFi...");
WiFi.begin(wifiSSID, wifiPassword);
isReconnecting = true;
nextWifiReconnect = time + wifiReconnectInterval;
}
if (isReconnecting && WiFi.status() == WL_CONNECTED) {
isReconnecting = false;
Serial.println("[INFO] WiFi connected, opening socket");
server.connectSSL(serverAccessKey);
configureNTP(timeOffsetToGMT, timeOffsetDaylightSavings, ntpServerUrl);
printLocalTime();
}
}
SesameEvent processMessage(AuthenticatedMessage* message) {
if (!isMessageCounterValid(message->message.id)) {
return SesameEvent::MessageCounterInvalid;
}
if (!isMessageTimeAcceptable(message->message.time)) {
return SesameEvent::MessageTimeMismatch;
}
if (!isAuthenticMessage(message, remoteKey, keySize)) {
return SesameEvent::MessageAuthenticationFailed;
}
return SesameEvent::MessageAccepted;
} }
/** /**
@ -118,25 +140,21 @@ void loop() {
* @return The event to signal to the server. * @return The event to signal to the server.
*/ */
SesameEvent handleReceivedMessage(AuthenticatedMessage* message, AuthenticatedMessage* response) { SesameEvent handleReceivedMessage(AuthenticatedMessage* message, AuthenticatedMessage* response) {
SesameEvent event = processMessage(message);
if (!isMessageCounterValid(message->message.id)) { // Only open when message is valid
return SesameEvent::MessageCounterInvalid; if (event == SesameEvent::MessageAccepted) {
} didUseMessageCounter(message->message.id);
if (!isMessageTimeAcceptable(message->message.time)) { // Move servo
return SesameEvent::MessageTimeMismatch; servo.pressButton();
} Serial.printf("[Info] Accepted message %d\n", message->message.id);
if (!isAuthenticMessage(message, remoteKey, keySize)) {
return SesameEvent::MessageAuthenticationFailed;
} }
// Create response for all cases
response->message.time = getEpochTime(); response->message.time = getEpochTime();
response->message.id = getNextMessageCounter(); response->message.id = getNextMessageCounter();
if (!authenticateMessage(response, localKey, keySize)) { if (!authenticateMessage(response, localKey, keySize)) {
return SesameEvent::MessageAuthenticationFailed; return SesameEvent::MessageAuthenticationFailed;
} }
return event;
// Move servo
servo.pressButton();
Serial.printf("[Info] Accepted message %d\n", message->message.id);
return SesameEvent::MessageAccepted;
} }

View File

@ -1,5 +1,9 @@
#include "server.h" #include "server.h"
constexpr int32_t pingInterval = 10000;
constexpr uint32_t pongTimeout = 5000;
uint8_t disconnectTimeoutCount = 3;
ServerConnection::ServerConnection(const char* url, int port, const char* path) : ServerConnection::ServerConnection(const char* url, int port, const char* path) :
url(url), port(port), path(path) { url(url), port(port), path(path) {
@ -12,6 +16,9 @@ void ServerConnection::connect(const char* key, uint32_t reconnectTime) {
} }
void ServerConnection::connectSSL(const char* key, uint32_t reconnectTime) { void ServerConnection::connectSSL(const char* key, uint32_t reconnectTime) {
if (socketIsConnected) {
return;
}
this->key = key; this->key = key;
webSocket.beginSSL(url, port, path); webSocket.beginSSL(url, port, path);
registerEventCallback(); registerEventCallback();
@ -47,6 +54,7 @@ switch(type) {
socketIsConnected = true; socketIsConnected = true;
webSocket.sendTXT(key); webSocket.sendTXT(key);
Serial.printf("[INFO] Socket connected to url: %s\n", payload); Serial.printf("[INFO] Socket connected to url: %s\n", payload);
webSocket.enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount);
break; break;
case WStype_TEXT: case WStype_TEXT:
sendFailureResponse(SesameEvent::TextReceived); sendFailureResponse(SesameEvent::TextReceived);
@ -55,6 +63,7 @@ switch(type) {
processReceivedBytes(payload, length); processReceivedBytes(payload, length);
break; break;
case WStype_PONG: case WStype_PONG:
break;
case WStype_PING: case WStype_PING:
case WStype_ERROR: case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START: case WStype_FRAGMENT_TEXT_START: