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,28 +3,46 @@
#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
*
* @param offsetToGMT The timezone offset in seconds
* @param offsetDaylightSavings The daylight savings offset in seconds
* @param serverUrl The url of the NTP server
*/
void configureNTP(int32_t offsetToGMT, int32_t offsetDaylightSavings, const char* serverUrl);
void configureNTP(int32_t offsetToGMT, int32_t offsetDaylightSavings, const char* serverUrl);
/**
/**
* @brief Print the current time to the serial output
*
* The time must be initialized by calling `configureNTP()` before use.
*/
void printLocalTime();
void printLocalTime();
/**
/**
* Gets the current epoch time
*/
uint32_t getEpochTime();
uint32_t getEpochTime();
/**
/**
* @brief The allowed time discrepancy (in seconds)
*
* Specifies the allowed discrepancy between the time of a received message
@ -36,9 +54,9 @@ uint32_t getEpochTime();
*
* @param offset The offset in both directions (seconds)
*/
void setMessageTimeAllowedOffset(uint32_t offset);
void setMessageTimeAllowedOffset(uint32_t offset);
/**
/**
* @brief Check wether the time of a message is within the allowed bounds regarding freshness.
*
* The timestamp is used to ensure 'freshness' of the messages,
@ -49,4 +67,17 @@ void setMessageTimeAllowedOffset(uint32_t offset);
* @return true The time is within the acceptable offset of the local time
* @return false The message time is invalid
*/
bool isMessageTimeAcceptable(uint32_t messageTime);
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();
}
}