#pragma once #include "server.h" #include "servo.h" #include "message.h" #include struct EthernetConfiguration { // The MAC address of the ethernet connection uint8_t macAddress[6]; // The master-in slave-out pin of the SPI connection for the Ethernet module int8_t spiPinMiso; // The master-out slave-in pin of the SPI connection for the Ethernet module int8_t spiPinMosi; // The slave clock pin of the SPI connection for the Ethernet module int8_t spiPinSclk; // The slave-select pin of the SPI connection for the Ethernet module int8_t spiPinSS; unsigned long dhcpLeaseTimeoutMs; unsigned long dhcpLeaseResponseTimeoutMs; // The static IP address to assign if DHCP fails uint8_t manualIp[4]; // The IP address of the DNS server, if DHCP fails uint8_t manualDnsAddress[4]; }; struct KeyConfiguration { const uint8_t* remoteKey; const uint8_t* localKey; uint32_t challengeExpiryMs; }; class SesameController: public ServerConnectionCallbacks { public: SesameController(uint16_t localWebServerPort); void configure(ServoConfiguration servoConfig, ServerConfiguration serverConfig, EthernetConfiguration ethernetConfig, KeyConfiguration keyConfig); void loop(uint32_t millis); private: uint32_t currentTime = 0; ServerConnection server; ServoController servo; AsyncWebServer localWebServer; EthernetConfiguration ethernetConfig; bool ethernetIsConfigured = false; KeyConfiguration keyConfig; bool isReconnecting = false; // Buffer to get local message SignedMessage receivedLocalMessage; uint32_t currentClientChallenge; uint32_t currentChallengeExpiry = 0; uint32_t currentServerChallenge; SignedMessage outgoingMessage; bool hasCurrentChallenge() { return currentChallengeExpiry > currentTime; } void clearCurrentChallenge() { currentClientChallenge = 0; currentServerChallenge = 0; currentChallengeExpiry = 0; } // MARK: Local client callbacks void handleLocalMessage(AsyncWebServerRequest *request); // MARK: Socket Callbacks /** * @brief Callback to send an error back to the server via the web socket. * * This function is called when the socket get's an error. * * @param event The error to report back */ void sendServerError(MessageResult event); void handleServerMessage(uint8_t* payload, size_t length); // MARK: Message processing /** * @brief Process a received message (local or socket). * * @param message The message to process. * * Note: Prepares the response in the outgoing message buffer. */ void processMessage(SignedMessage* message); /** * @brief Checks that the message is valid and prepares a challenge. * * This function is also called when a challenge response arrives too late. * * @param message The message to respond to * * Note: Prepares the response in the outgoing message buffer. */ void checkAndPrepareChallenge(Message* message); /** * @brief Prepare a server challenge for a local or socket message. * * @param message The message to respond to * * Note: Prepares the response in the outgoing message buffer. */ void prepareChallenge(Message* message); /** * @brief Complete an unlock request for a local or socket message. * * @param message The message to respond to * * Note: Prepares the response in the outgoing message buffer. */ void completeUnlockRequest(Message* message); // MARK: Responses /** * @brief Prepare the outgoing message buffer for both socket and local responses. * * @param event The resulting state to transmit * @param message An optional message to echo */ void prepareResponseBuffer(MessageResult event, Message* message = NULL); /** * @brief Send the prepared outgoing message to a locally connected client * * @param request The original request of the client */ void sendPreparedLocalResponse(AsyncWebServerRequest *request); /** * @brief Send the prepared outgoing message to the server */ void sendPreparedResponseToServer(); // MARK: Helper bool convertHexMessageToBinary(const char* str); };