#pragma once #include class Storage { public: Storage(uint8_t remoteDeviceCount) : remoteDeviceCount(remoteDeviceCount) { }; /** * @brief Initialize the use of the message counter API * * The message counter is stored in EEPROM, which must be initialized before use. * * @note The ESP32 does not have a true EEPROM, * which is emulated using a section of the flash memory. */ void configure(); /** * @brief Check if a device ID is allowed * * @param deviceId The ID to check * @return true The id is valid * @return false The id is invalid */ bool isDeviceIdValid(uint8_t deviceId); /** * @brief Check if a received counter is valid * * The counter is valid if it is larger than the previous counter * (larger or equal to the next expected counter). * * @param counter The counter to check * @return true The counter is valid * @return false The counter belongs to an old message */ bool isMessageCounterValid(uint32_t counter, uint8_t deviceId); /** * @brief Mark a counter of a message as used. * * The counter value is stored in EEPROM to persist across restarts. * * All messages with counters lower than the given one will become invalid. * * @param counter The counter used in the last message. */ void didUseMessageCounter(uint32_t counter, uint8_t deviceId); /** * @brief Get the expected count for the next message. * * The counter is stored in EEPROM to persist across restarts * * @return The next counter to use by the remote */ uint32_t getNextMessageCounter(uint8_t deviceId); /** * @brief Print info about the current message counter to the serial output * */ void printMessageCounters(); /** * @brief Reset the message counter. * * @warning The counter should never be reset in production environments, * and only together with a new secret key. Otherwise old messages may be * used for replay attacks. * */ void resetMessageCounters(); private: uint8_t remoteDeviceCount; void setMessageCounter(uint32_t counter, uint8_t deviceId); };