Create storage class

This commit is contained in:
Christoph Hagen
2023-08-09 13:13:38 +02:00
parent a4cab0931f
commit 67169240f9
8 changed files with 162 additions and 130 deletions

View File

@ -3,12 +3,18 @@
#include "fresh.h"
#include "crypto.h"
SesameController::SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local) :
server(server), servo(servo), local(local) {
SesameController::SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, uint8_t remoteDeviceCount) :
server(server), servo(servo), local(local), storage(remoteDeviceCount) {
// Set up response buffer
responseStatus = (SesameEvent*) responseBuffer;
responseMessage = (AuthenticatedMessage*) (responseBuffer + 1);
}
void SesameController::configure() {
// Prepare EEPROM for reading and writing
storage.configure();
// Direct messages and errors over the websocket to the controller
server->setCallbackHandler(this);
@ -17,6 +23,9 @@ server(server), servo(servo), local(local) {
this->handleLocalMessage(request);
this->sendPreparedLocalResponse(request);
});
//storage.resetMessageCounters();
storage.printMessageCounters();
}
// MARK: Local
@ -84,17 +93,17 @@ SesameEvent SesameController::verifyAndProcessReceivedMessage(AuthenticatedMessa
if (!isAuthenticMessage(message, remoteKey, keySize)) {
return SesameEvent::MessageAuthenticationFailed;
}
if (!isDeviceIdValid(message->message.device)) {
if (!storage.isDeviceIdValid(message->message.device)) {
return SesameEvent::MessageDeviceInvalid;
}
if (!isMessageCounterValid(message->message.id, message->message.device)) {
if (!storage.isMessageCounterValid(message->message.id, message->message.device)) {
return SesameEvent::MessageCounterInvalid;
}
if (!isMessageTimeAcceptable(message->message.time)) {
return SesameEvent::MessageTimeMismatch;
}
didUseMessageCounter(message->message.id, message->message.device);
storage.didUseMessageCounter(message->message.id, message->message.device);
// Move servo
servo->pressButton();
Serial.printf("[Info] Accepted message %d\n", message->message.id);
@ -119,7 +128,7 @@ uint16_t SesameController::prepareResponseBuffer(SesameEvent event, uint8_t devi
return 1;
}
responseMessage->message.time = getEpochTime();
responseMessage->message.id = getNextMessageCounter(deviceId);
responseMessage->message.id = storage.getNextMessageCounter(deviceId);
responseMessage->message.device = deviceId;
if (!authenticateMessage(responseMessage, localKey, keySize)) {
*responseStatus = SesameEvent::InvalidResponseAuthentication;

View File

@ -2,7 +2,6 @@
#include <Arduino.h>
#include <time.h>
#include <EEPROM.h>
/**
* @brief The allowed discrepancy between the time of a received message
@ -55,54 +54,4 @@ bool isMessageTimeAcceptable(uint32_t t) {
return false;
}
return true;
}
void prepareMessageCounterUsage() {
EEPROM.begin(MESSAGE_COUNTER_SIZE * remoteDeviceCount);
}
uint32_t getNextMessageCounter(uint8_t deviceId) {
int offset = deviceId * MESSAGE_COUNTER_SIZE;
uint32_t counter = (uint32_t) EEPROM.read(offset + 0) << 24;
counter += (uint32_t) EEPROM.read(offset + 1) << 16;
counter += (uint32_t) EEPROM.read(offset + 2) << 8;
counter += (uint32_t) EEPROM.read(offset + 3);
return counter;
}
void printMessageCounters() {
Serial.print("[INFO] Next message numbers:");
for (uint8_t i = 0; i < remoteDeviceCount; i += 1) {
Serial.printf(" %u", getNextMessageCounter(i));
}
Serial.println("");
}
bool isDeviceIdValid(uint8_t deviceId) {
return deviceId < remoteDeviceCount;
}
bool isMessageCounterValid(uint32_t counter, uint8_t deviceId) {
return counter >= getNextMessageCounter(deviceId);
}
void setMessageCounter(uint32_t counter, uint8_t deviceId) {
int offset = deviceId * MESSAGE_COUNTER_SIZE;
EEPROM.write(offset + 0, (counter >> 24) & 0xFF);
EEPROM.write(offset + 1, (counter >> 16) & 0xFF);
EEPROM.write(offset + 2, (counter >> 8) & 0xFF);
EEPROM.write(offset + 3, counter & 0xFF);
EEPROM.commit();
}
void didUseMessageCounter(uint32_t counter, uint8_t deviceId) {
// Store the next counter, so that resetting starts at 0
setMessageCounter(counter+1, deviceId);
}
void resetMessageCounters() {
for (uint8_t i = 0; i < remoteDeviceCount; i += 1) {
setMessageCounter(0, i);
}
Serial.println("[WARN] Message counters reset");
}
}

View File

@ -25,7 +25,7 @@ ServoController servo(pwmTimer, servoFrequency, servoPin);
AsyncWebServer local(localPort);
SesameController controller(&server, &servo, &local);
SesameController controller(&server, &servo, &local, remoteDeviceCount);
// Forward declare monitoring functions
void ensureWiFiConnection(uint32_t time);
@ -41,9 +41,7 @@ void setup() {
servo.configure(lockOpeningDuration, servoPressedState, servoReleasedState);
Serial.println("[INFO] Servo configured");
prepareMessageCounterUsage();
//resetMessageCounters();
printMessageCounters();
controller.configure();
}
void loop() {

53
src/storage.cpp Normal file
View File

@ -0,0 +1,53 @@
#include "storage.h"
#include "message.h"
#include <EEPROM.h>
void Storage::configure() {
EEPROM.begin(messageCounterSize * remoteDeviceCount);
}
bool Storage::isDeviceIdValid(uint8_t deviceId) {
return deviceId < remoteDeviceCount;
}
bool Storage::isMessageCounterValid(uint32_t counter, uint8_t deviceId) {
return counter >= getNextMessageCounter(deviceId);
}
void Storage::didUseMessageCounter(uint32_t counter, uint8_t deviceId) {
// Store the next counter, so that resetting starts at 0
setMessageCounter(counter+1, deviceId);
}
void Storage::setMessageCounter(uint32_t counter, uint8_t deviceId) {
int offset = deviceId * messageCounterSize;
EEPROM.write(offset + 0, (counter >> 24) & 0xFF);
EEPROM.write(offset + 1, (counter >> 16) & 0xFF);
EEPROM.write(offset + 2, (counter >> 8) & 0xFF);
EEPROM.write(offset + 3, counter & 0xFF);
EEPROM.commit();
}
uint32_t Storage::getNextMessageCounter(uint8_t deviceId) {
int offset = deviceId * messageCounterSize;
uint32_t counter = (uint32_t) EEPROM.read(offset + 0) << 24;
counter += (uint32_t) EEPROM.read(offset + 1) << 16;
counter += (uint32_t) EEPROM.read(offset + 2) << 8;
counter += (uint32_t) EEPROM.read(offset + 3);
return counter;
}
void Storage::printMessageCounters() {
Serial.print("[INFO] Next message numbers:");
for (uint8_t i = 0; i < remoteDeviceCount; i += 1) {
Serial.printf(" %u", getNextMessageCounter(i));
}
Serial.println("");
}
void Storage::resetMessageCounters() {
for (uint8_t i = 0; i < remoteDeviceCount; i += 1) {
setMessageCounter(0, i);
}
Serial.println("[WARN] Message counters reset");
}