diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp index 5db70e5..47d85b5 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp @@ -73,9 +73,7 @@ bool ESPMegaPRO::begin() esp_restart(); } } - // Recovery Mode - recovery.bindFRAM(&fram, 600); - recovery.begin(); + return true; } @@ -91,7 +89,6 @@ void ESPMegaPRO::loop() { inputs.loop(); outputs.loop(); - recovery.loop(); for (int i = 0; i < 255; i++) { if (cardInstalled[i]) diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp index 4b6bd14..b20f1ce 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp @@ -15,7 +15,6 @@ #include #include #include -#include // ESPMega Pro R3 Board Address #define FRAM_ADDRESS 0x56 @@ -83,11 +82,6 @@ class ESPMegaPRO { * @note You must call enableWebServer() before using this component. */ ESPMegaWebServer *webServer; - /** - * @brief This component is used to enter recovery mode when the ESPMegaPRO board is in a bootloop. - * @typedef ESPMegaRecovery - */ - ESPMegaRecovery recovery; private: bool iotEnabled = false; bool internalDisplayEnabled = false; diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaRecovery.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaRecovery.cpp deleted file mode 100644 index f6fe70e..0000000 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaRecovery.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include -ESPMegaRecovery::ESPMegaRecovery() -{ - // Initialize all the pointers to null - this->fram = nullptr; - this->fram_address = 0; - this->bootloop_counter = 0; - this->recovery_mode = false; - this->web_server = nullptr; - this->iot = nullptr; -} -void ESPMegaRecovery::begin() { - // Retrieve the bootloop counter from the FRAM - if(this->fram != nullptr) { - this->bootloop_counter = this->fram->read8(this->fram_address); - } - // Inclement the bootloop counter - this->inclementBootloopCounter(); - ESP_LOGV("ESPMegaRecovery", "Bootloop counter: %d", this->getBootloopCounter()); - // If the bootloop counter is greater than 5, enter recovery mode - if(this->getBootloopCounter() > 5) { - ESP_LOGE("ESPMegaRecovery", "Bootloop detected"); - // Reset the bootloop counter to prevent re-entering recovery mode - // The device might unintentionally restart multiple times - // By resetting the counter, the user can press reset once in recovery mode to exit - ESP_LOGD("ESPMegaRecovery", "Resetting bootloop counter"); - this->resetBootloopCounter(); - ESP_LOGW("ESPMegaRecovery", "Entering recovery mode"); - this->enterRecoveryMode(); - this->loop(); - } -} -void ESPMegaRecovery::loop() { - // If the device is in recovery mode, block all other tasks - if(this->isRecoveryMode()) { - int i = 0; - while(true) { - if (i%10 == 0) { - ESP_LOGV("ESPMegaRecovery", "System is in recovery mode, no tasks will be executed"); - ESP_LOGV("ESPMegaRecovery", "Please upload a new firmware to exit recovery mode"); - } - // This code will become the new loop - delay(1000); - i++; - } - } - // Watchdog timer - static bool booted = false; - static uint32_t boot_time = millis(); - if(!booted) { - if(millis() - boot_time > RECOVERY_WATCHDOG_TIMEOUT * 1000) { - ESP_LOGI("ESPMegaRecovery", "System booted successfully, resetting bootloop counter"); - this->resetBootloopCounter(); - booted = true; - } - } -} -void ESPMegaRecovery::enterRecoveryMode() { - // Set the recovery mode flag - this->recovery_mode = true; - // Enabling the IoT module - ESP_LOGI("ESPMegaRecovery", "Enabling the IoT module"); - this->iot = new ESPMegaIoT(); - this->iot->bindFRAM(this->fram); - ETH.begin(); - this->iot->bindEthernetInterface(Ð); - ESP_LOGI("ESPMegaRecovery", "Loading network configuration"); - this->iot->loadNetworkConfig(); - ESP_LOGI("ESPMegaRecovery", "Attempting to connect to the network"); - this->iot->connectNetwork(); - // Start the web server - ESP_LOGI("ESPMegaRecovery", "Starting the web server"); - this->web_server = new ESPMegaWebServer(80, this->iot); - this->web_server->bindFRAM(this->fram); - this->web_server->loadCredentialsFromFRAM(); - ESP_LOGI("ESPMegaRecovery", "Aquiring the web server instance"); - AsyncWebServer *server = this->web_server->getServer(); - server->begin(); - // Add OTA update and restart endpoint - ESP_LOGI("ESPMegaRecovery", "Adding OTA update and reboot endpoints"); - auto bindedDashboardHandler = std::bind(&ESPMegaWebServer::dashboardHandler, this->web_server, std::placeholders::_1); - auto bindedOtaRequestHandler = std::bind(&ESPMegaWebServer::otaRequestHandler, this->web_server, std::placeholders::_1); - auto bindedOtaUploadHandler = std::bind(&ESPMegaWebServer::otaUploadHandler, this->web_server, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6); - auto bindedDeviceInfoHandler = std::bind(&ESPMegaRecovery::getDeviceInfoHandler, this, std::placeholders::_1); - auto bindedConfigHandler = std::bind(&ESPMegaRecovery::configHandler, this, std::placeholders::_1); - server->on("/", HTTP_GET, bindedDashboardHandler); - server->on("/ota_update", HTTP_POST, bindedOtaRequestHandler, bindedOtaUploadHandler); - server->on("/reboot", HTTP_GET, std::bind(&ESPMegaWebServer::rebootHandler, this->web_server, std::placeholders::_1)); - server->on("/get_device_info", HTTP_GET, bindedDeviceInfoHandler); - server->on("/config", HTTP_GET, bindedConfigHandler); -} -void ESPMegaRecovery::bindFRAM(FRAM *fram, uint32_t address) { - this->fram = fram; - this->fram_address = address; -} -uint8_t ESPMegaRecovery::getBootloopCounter() { - return this->bootloop_counter; -} -void ESPMegaRecovery::inclementBootloopCounter() { - this->bootloop_counter++; - if(this->fram != nullptr) { - this->fram->write8(this->fram_address, this->bootloop_counter); - } -} -void ESPMegaRecovery::resetBootloopCounter() { - this->bootloop_counter = 0; - if(this->fram != nullptr) { - this->fram->write8(this->fram_address, this->bootloop_counter); - } -} -bool ESPMegaRecovery::isRecoveryMode() { - return this->recovery_mode; -} - -void ESPMegaRecovery::getDeviceInfoHandler(AsyncWebServerRequest *request) { - if (!request->authenticate(this->web_server->getWebUsername(), this->web_server->getWebPassword())) - { - return request->requestAuthentication(); - } - StaticJsonDocument<512> doc; - doc["hostname"] = this->iot->getNetworkConfig()->hostname; - doc["ip_address"] = this->iot->getIp().toString(); - doc["mac_address"] = this->iot->getMac(); - doc["model"] = BOARD_MODEL; - doc["mqtt_server"] = "Recovery"; - doc["mqtt_port"] = "Mode"; - doc["base_topic"] = "Recovery Mode"; - doc["mqtt_connected"] = "Recovery Mode"; - doc["software_version"] = "EMG-SAFE-1.0.0"; - doc["sdk_version"] = SDK_VESRION; - doc["idf_version"] = IDF_VER; - char buffer[512]; - serializeJson(doc, buffer); - request->send(200, "application/json", buffer); -} - -void ESPMegaRecovery::configHandler(AsyncWebServerRequest *request){ - // Say Not Available in Recovery Mode - // Wait 3s then redirect to / - request->send(500, "text/html", "

RECOVERY MODE

Configuration is not available in recovery mode

"); -} \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaRecovery.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaRecovery.hpp deleted file mode 100644 index 407e3eb..0000000 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaRecovery.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -/** - * @brief Recovery mode for ESPMega - * Recovery mode is a mode that is entered when the device is in a bootloop - * In this mode, the device will block all other tasks and wait for a new firmware to be uploaded over the air - * To exit recovery mode, the device must be restarted or a new firmware must be uploaded - * This is useful when the device is in a bootloop and the user can't access the device to upload a new firmware (ota bricking) - * The device is considered to be in a bootloop when it is restarted before RECOVERY_WATCHDOG_TIMEOUT seconds for 5 consecutive times - * The timer is started when the device's initialization is complete (enter loop) - */ - -#define RECOVERY_WATCHDOG_TIMEOUT 15 // The time in seconds to wait for a restart before considering it a bootloop - -class ESPMegaRecovery { -public: - ESPMegaRecovery(); - void begin(); - void loop(); - void enterRecoveryMode(); // Enter recovery mode, Block all other tasks, start OTA server - void bindFRAM(FRAM* fram, uint32_t address); // Bind the FRAM block to store the bootloop counter - uint8_t getBootloopCounter(); // Get the bootloop counter - void inclementBootloopCounter(); // Increment the bootloop counter - void resetBootloopCounter(); // Reset the bootloop counter - bool isRecoveryMode(); // Check if the device is in recovery mode -private: - void getDeviceInfoHandler(AsyncWebServerRequest *request); - void configHandler(AsyncWebServerRequest *request); - FRAM* fram; - uint32_t fram_address; - uint8_t bootloop_counter; - ESPMegaIoT* iot; - ESPMegaWebServer* web_server; - bool recovery_mode; -}; \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.hpp index 386f91d..f6356e2 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.hpp @@ -35,17 +35,6 @@ class ESPMegaWebServer void saveCredentialsToFRAM(); AsyncWebServer* getServer(); bool checkAuthentication(AsyncWebServerRequest *request); - // Endpoints Handlers - void dashboardHandler(AsyncWebServerRequest *request); - void configHandler(AsyncWebServerRequest *request); - AsyncCallbackJsonWebHandler *saveConfigHandler; - void saveConfigJSONHandler(AsyncWebServerRequest *request, JsonVariant &json); - void getConfigHandler(AsyncWebServerRequest *request); - void getDeviceInfoHandler(AsyncWebServerRequest *request); - void otaRequestHandler(AsyncWebServerRequest *request); - void otaUploadHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); - void restAPIHandler(AsyncWebServerRequest *request); - void rebootHandler(AsyncWebServerRequest *request); private: // FRAM FRAM *fram; @@ -57,4 +46,15 @@ class ESPMegaWebServer uint16_t port; // ESPMegaIoT ESPMegaIoT *iot; + // Endpoints Handlers + void dashboardHandler(AsyncWebServerRequest *request); + void configHandler(AsyncWebServerRequest *request); + AsyncCallbackJsonWebHandler *saveConfigHandler; + void saveConfigJSONHandler(AsyncWebServerRequest *request, JsonVariant &json); + void getConfigHandler(AsyncWebServerRequest *request); + void getDeviceInfoHandler(AsyncWebServerRequest *request); + void otaRequestHandler(AsyncWebServerRequest *request); + void otaUploadHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); + void restAPIHandler(AsyncWebServerRequest *request); + void rebootHandler(AsyncWebServerRequest *request); }; \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/src/main.cpp b/ESPMegaPRO-OS-SDK/src/main.cpp index e8e43af..10419de 100644 --- a/ESPMegaPRO-OS-SDK/src/main.cpp +++ b/ESPMegaPRO-OS-SDK/src/main.cpp @@ -14,7 +14,7 @@ // #define FRAM_DEBUG // #define MQTT_DEBUG -#define WRITE_DEFAULT_NETCONF +// #define WRITE_DEFAULT_NETCONF //#define CLIMATE_CARD_ENABLE #define MQTT_CARD_REGISTER #define DISPLAY_ENABLE