From bc8711516498057a34146f8facc2dc13d8034a58 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 1 May 2022 23:16:21 +0200 Subject: [PATCH] HTTP API to switch to and from factory partition --- tasmota/support_esp.ino | 5 ++++ tasmota/xdrv_01_webserver.ino | 52 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/tasmota/support_esp.ino b/tasmota/support_esp.ino index 24cfd9c12..11f00911c 100644 --- a/tasmota/support_esp.ino +++ b/tasmota/support_esp.ino @@ -299,6 +299,11 @@ bool EspSingleOtaPartition(void) { return (1 == esp_ota_get_app_partition_count()); } +bool EspRunningFactoryPartition(void) { + const esp_partition_t *cur_part = esp_ota_get_running_partition(); + return (cur_part->type == 0 && cur_part->subtype == 0); +} + void EspPrepRestartToSafeMode(void) { // esp_ota_mark_app_invalid_rollback_and_reboot(); // Doesn't work 20220501 const esp_partition_t *otadata_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL); diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index a977b5479..bd4490bf5 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -523,6 +523,9 @@ const WebServerDispatch_t WebServerDispatch[] PROGMEM = { { "u1", HTTP_ANY, HandleUpgradeFirmwareStart }, // OTA { "u2", HTTP_OPTIONS, HandlePreflightRequest }, { "u3", HTTP_ANY, HandleUploadDone }, +#ifdef ESP32 + { "u4", HTTP_GET, HandleSwitchFactory }, +#endif // ESP32 { "mn", HTTP_GET, HandleManagement }, { "cs", HTTP_GET, HandleConsole }, { "cs", HTTP_OPTIONS, HandlePreflightRequest }, @@ -2884,6 +2887,55 @@ void HandlePreflightRequest(void) /*-------------------------------------------------------------------------------------------*/ +#ifdef ESP32 +// Check if we are in single-mode OTA, if so restart to factory mode +// +// Parameter `u4` is either `fct` or `ota` to switch to factory or ota +// +// The page can return the followinf (code 200) +// `false`: the current partition is not the target, but a restart to factory is triggered (polling required) +// `true`: the current partition is the one required +// `none`: there is no factory partition +void HandleSwitchFactory(void) +{ + if (!HttpCheckPriviledgedAccess()) { return; } + + char tmp1[8]; + WebGetArg(PSTR("u4"), tmp1, sizeof(tmp1)); + + bool switch_factory = false; // trigger a restart to factory partition? + bool switch_ota = false; // switch back to OTA partition + + // switch to factory ? + if (EspSingleOtaPartition()) { + if (strcmp("fct", tmp1) == 0 && !EspRunningFactoryPartition()) { + switch_factory = true; + } + // switch to OTA + else if (strcmp("ota", tmp1) == 0 && EspRunningFactoryPartition()) { + switch_ota = true; + } + } + + if (switch_factory || switch_ota) { + SettingsSaveAll(); + if (switch_factory) { + EspPrepRestartToSafeMode(); + } else { + const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr); + esp_ota_set_boot_partition(partition); + } + // display restart page + WebRestart(0); + } else { + Webserver->sendHeader("Location", "/", true); + Webserver->send(302, "text/plain", ""); + } +} +#endif + +/*-------------------------------------------------------------------------------------------*/ + void HandleHttpCommand(void) { if (!HttpCheckPriviledgedAccess(false)) { return; }