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) {
uint32_t localTime = getEpochTime();
if (localTime == 0) {
Serial.println("No epoch time available");
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() {
@ -68,16 +75,14 @@ uint32_t getNextMessageCounter() {
}
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) {
return counter >= getNextMessageCounter();
}
void didUseMessageCounter(uint32_t counter) {
// Store the next counter, so that resetting starts at 0
counter += 1;
void setMessageCounter(uint32_t counter) {
EEPROM.write(0, (counter >> 24) & 0xFF);
EEPROM.write(1, (counter >> 16) & 0xFF);
EEPROM.write(2, (counter >> 8) & 0xFF);
@ -86,7 +91,12 @@ void didUseMessageCounter(uint32_t counter) {
EEPROM.commit();
}
void didUseMessageCounter(uint32_t counter) {
// Store the next counter, so that resetting starts at 0
setMessageCounter(counter+1);
}
void resetMessageCounter() {
didUseMessageCounter(0);
setMessageCounter(0);
Serial.println("[WARN] Message counter reset");
}

View File

@ -48,7 +48,7 @@ constexpr int32_t timeOffsetDaylightSavings = 3600;
// Servo is Emax ES08MA II
// 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
constexpr int pwmTimer = 0;
@ -60,7 +60,7 @@ constexpr int servoPin = 14;
constexpr int servoFrequency = 50;
// 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;
@ -85,26 +85,48 @@ void setup() {
Serial.println("[INFO] Servo configured");
prepareMessageCounterUsage();
//resetMessageCounter();
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);
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() {
uint32_t time = millis();
server.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.
*/
SesameEvent handleReceivedMessage(AuthenticatedMessage* message, AuthenticatedMessage* response) {
SesameEvent event = processMessage(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;
// Only open when message is valid
if (event == SesameEvent::MessageAccepted) {
didUseMessageCounter(message->message.id);
// Move servo
servo.pressButton();
Serial.printf("[Info] Accepted message %d\n", message->message.id);
}
// Create response for all cases
response->message.time = getEpochTime();
response->message.id = getNextMessageCounter();
if (!authenticateMessage(response, localKey, keySize)) {
return SesameEvent::MessageAuthenticationFailed;
}
// Move servo
servo.pressButton();
Serial.printf("[Info] Accepted message %d\n", message->message.id);
return SesameEvent::MessageAccepted;
return event;
}

View File

@ -1,5 +1,9 @@
#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) :
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) {
if (socketIsConnected) {
return;
}
this->key = key;
webSocket.beginSSL(url, port, path);
registerEventCallback();
@ -47,6 +54,7 @@ switch(type) {
socketIsConnected = true;
webSocket.sendTXT(key);
Serial.printf("[INFO] Socket connected to url: %s\n", payload);
webSocket.enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount);
break;
case WStype_TEXT:
sendFailureResponse(SesameEvent::TextReceived);
@ -55,6 +63,7 @@ switch(type) {
processReceivedBytes(payload, length);
break;
case WStype_PONG:
break;
case WStype_PING:
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START: