Improve reconnect, logging
This commit is contained in:
parent
49e44f064d
commit
e62c34f4df
@ -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() {
|
||||||
@ -61,23 +68,21 @@ void prepareMessageCounterUsage() {
|
|||||||
|
|
||||||
uint32_t getNextMessageCounter() {
|
uint32_t getNextMessageCounter() {
|
||||||
uint32_t counter = (uint32_t) EEPROM.read(0) << 24;
|
uint32_t counter = (uint32_t) EEPROM.read(0) << 24;
|
||||||
counter += (uint32_t) EEPROM.read(1) << 16;
|
counter += (uint32_t) EEPROM.read(1) << 16;
|
||||||
counter += (uint32_t) EEPROM.read(2) << 8;
|
counter += (uint32_t) EEPROM.read(2) << 8;
|
||||||
counter += (uint32_t) EEPROM.read(3);
|
counter += (uint32_t) EEPROM.read(3);
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
72
src/main.cpp
72
src/main.cpp
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user