Create time class

This commit is contained in:
Christoph Hagen 2023-08-09 13:25:19 +02:00
parent 67169240f9
commit d13bf67443
5 changed files with 93 additions and 68 deletions

View File

@ -4,12 +4,13 @@
#include "servo.h"
#include "message.h"
#include "storage.h"
#include "fresh.h"
#include <ESPAsyncWebServer.h>
class SesameController: public ServerConnectionCallbacks {
public:
SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, uint8_t remoteDeviceCount);
SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, TimeCheck* timeCheck, uint8_t remoteDeviceCount);
void configure();
@ -18,6 +19,7 @@ private:
ServerConnection* server;
ServoController* servo;
AsyncWebServer* local;
TimeCheck* timeCheck;
Storage storage;
// The buffer to hold a received message while it is read

View File

@ -3,6 +3,24 @@
#include <stdint.h>
#include "config.h"
class TimeCheck {
public:
/**
* @brief Create a time checker instance
*
* Specify the allowed discrepancy between the time of a received message
* and the device time (in seconds).
*
* A stricter (lower) value better prevents against replay attacks,
* but may lead to issues when dealing with slow networks and other
* routing delays.
*
* @param offset The allowed time discrepancy in both directions (seconds)
*/
TimeCheck(uint32_t allowedTimeOffset = 60);
/**
* @brief Configure an NTP server to get the current time
*
@ -50,3 +68,16 @@ void setMessageTimeAllowedOffset(uint32_t offset);
* @return false The message time is invalid
*/
bool isMessageTimeAcceptable(uint32_t messageTime);
private:
/**
* @brief The allowed discrepancy between the time of a received message
* and the device time (in seconds)
*
* A stricter (lower) value better prevents against replay attacks,
* but may lead to issues when dealing with slow networks and other
* routing delays.
*/
uint32_t allowedOffset;
};

View File

@ -3,8 +3,8 @@
#include "fresh.h"
#include "crypto.h"
SesameController::SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, uint8_t remoteDeviceCount) :
server(server), servo(servo), local(local), storage(remoteDeviceCount) {
SesameController::SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, TimeCheck* timeCheck, uint8_t remoteDeviceCount) :
server(server), servo(servo), local(local), timeCheck(timeCheck), storage(remoteDeviceCount) {
// Set up response buffer
responseStatus = (SesameEvent*) responseBuffer;
@ -99,7 +99,7 @@ SesameEvent SesameController::verifyAndProcessReceivedMessage(AuthenticatedMessa
if (!storage.isMessageCounterValid(message->message.id, message->message.device)) {
return SesameEvent::MessageCounterInvalid;
}
if (!isMessageTimeAcceptable(message->message.time)) {
if (!timeCheck->isMessageTimeAcceptable(message->message.time)) {
return SesameEvent::MessageTimeMismatch;
}
@ -127,7 +127,7 @@ uint16_t SesameController::prepareResponseBuffer(SesameEvent event, uint8_t devi
if (!allowMessageResponse(event)) {
return 1;
}
responseMessage->message.time = getEpochTime();
responseMessage->message.time = timeCheck->getEpochTime();
responseMessage->message.id = storage.getNextMessageCounter(deviceId);
responseMessage->message.device = deviceId;
if (!authenticateMessage(responseMessage, localKey, keySize)) {

View File

@ -1,27 +1,17 @@
#include "fresh.h"
#include <Arduino.h>
#include <Arduino.h> // configTime()
#include <time.h>
/**
* @brief The allowed discrepancy between the time of a received message
* and the device time (in seconds)
*
* A stricter (lower) value better prevents against replay attacks,
* but may lead to issues when dealing with slow networks and other
* routing delays.
*/
uint32_t allowedOffset = 60;
void setMessageTimeAllowedOffset(uint32_t offset) {
allowedOffset = offset;
TimeCheck::TimeCheck(uint32_t allowedTimeOffset) {
allowedOffset = allowedTimeOffset;
}
void configureNTP(int32_t offsetToGMT, int32_t offsetDaylightSavings, const char* serverUrl) {
void TimeCheck::configureNTP(int32_t offsetToGMT, int32_t offsetDaylightSavings, const char* serverUrl) {
configTime(offsetToGMT, offsetDaylightSavings, serverUrl);
}
void printLocalTime() {
void TimeCheck::printLocalTime() {
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
Serial.println(&timeinfo, "[INFO] Time is %A, %d. %B %Y %H:%M:%S");
@ -30,7 +20,7 @@ void printLocalTime() {
}
}
uint32_t getEpochTime() {
uint32_t TimeCheck::getEpochTime() {
time_t now;
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
@ -41,7 +31,7 @@ uint32_t getEpochTime() {
return now;
}
bool isMessageTimeAcceptable(uint32_t t) {
bool TimeCheck::isMessageTimeAcceptable(uint32_t t) {
uint32_t localTime = getEpochTime();
if (localTime == 0) {
Serial.println("No epoch time available");

View File

@ -19,13 +19,15 @@
/* Global variables */
TimeCheck timeCheck{};
ServerConnection server(serverUrl, serverPort, serverPath);
ServoController servo(pwmTimer, servoFrequency, servoPin);
AsyncWebServer local(localPort);
SesameController controller(&server, &servo, &local, remoteDeviceCount);
SesameController controller(&server, &servo, &local, &timeCheck, remoteDeviceCount);
// Forward declare monitoring functions
void ensureWiFiConnection(uint32_t time);
@ -75,8 +77,8 @@ void ensureWebSocketConnection(uint32_t time) {
Serial.println(WiFi.localIP());
Serial.println("[INFO] WiFi connected, opening socket");
server.connect(serverAccessKey);
configureNTP(timeOffsetToGMT, timeOffsetDaylightSavings, ntpServerUrl);
printLocalTime();
timeCheck.configureNTP(timeOffsetToGMT, timeOffsetDaylightSavings, ntpServerUrl);
timeCheck.printLocalTime();
local.begin();
}
}