#pragma once #include "server.h" #include "servo.h" #include "message.h" #include "configurations/EthernetConfiguration.h" #include "configurations/KeyConfiguration.h" class SesameController: public ServerConnectionCallbacks { public: SesameController(); void configure(ServoConfiguration servoConfig, ServerConfiguration serverConfig, EthernetConfiguration ethernetConfig, KeyConfiguration keyConfig); void loop(uint32_t millis); private: uint32_t currentTime = 0; ServerConnection server; ServoController servo; // UDP // An EthernetUDP instance to send and receive packets over UDP EthernetUDP udp; 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 checkLocalMessage(); // 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, bool shouldPerformUnlock); /** * @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, bool shouldPerformUnlock); // 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 Read a message from the UDP port * */ bool readLocalMessage(); /** * @brief Send the prepared outgoing message to a locally connected client * * @param request The original request of the client */ void sendPreparedLocalResponse(); /** * @brief Send the prepared outgoing message to the server */ void sendPreparedResponseToServer(); // MARK: Helper bool convertHexMessageToBinary(const char* str); };