fix: defer ESP32 OTA server startup from web command
This commit is contained in:
1 parent
01fd229b21
commit
1fb68263cd
4 files changed
+52
-22
No files matched your search
@@ -182,6 +182,7 @@ Notes:
|
||||
- commands run with the same care as if you typed them into the repeater CLI directly
|
||||
- this is intended for local admin use on a trusted network
|
||||
- `start ota` releases the local HTTP redirect listener on port `80` so the OTA HTTP listener can take over without stopping the rest of the repeater services, regardless of whether the command is run from the web panel, serial CLI, or a remote companion/app CLI session
|
||||
- `start ota` uses the repeater's existing Wi-Fi address when already connected, or starts the `MeshCore-OTA` access point when Wi-Fi is not connected
|
||||
- the `/app` Regions shortcut runs the existing MeshCore region commands in sequence: `region put au`, `region put au-STATE`, `region allowf au`, `region allowf au-STATE`, then `region save`
|
||||
|
||||
## Companion Wi-Fi Rescue Commands
|
||||
|
||||
@@ -340,8 +340,11 @@ On mobile:
|
||||
|
||||
1. Press `Start OTA`.
|
||||
2. Confirm the action.
|
||||
3. The local HTTP redirect listener on port `80` is released so OTA can take over that port.
|
||||
4. Continue with your normal OTA workflow.
|
||||
3. The panel starts OTA, then opens the returned `http://.../update` URL.
|
||||
4. The local HTTP redirect listener on port `80` is released so OTA can take over that port.
|
||||
5. Continue with your normal OTA workflow.
|
||||
|
||||
If the repeater is already connected to Wi-Fi, OTA uses the existing LAN address. If Wi-Fi is not connected, the repeater starts the `MeshCore-OTA` access point and returns that OTA address instead.
|
||||
|
||||
If an older build sends you through a strange redirect after `start ota`, use the web `Start OTA` button to begin the upgrade. This redirect issue is fixed in `observer-eastmesh-v1.3.11`.
|
||||
|
||||
|
||||
+42
-20
@@ -10,6 +10,40 @@
|
||||
|
||||
#include <SPIFFS.h>
|
||||
|
||||
namespace {
|
||||
AsyncWebServer* ota_server = nullptr;
|
||||
char ota_id_buf[60];
|
||||
char ota_home_buf[90];
|
||||
volatile bool ota_start_pending = false;
|
||||
|
||||
void startOTAServerNow() {
|
||||
if (ota_server != nullptr) {
|
||||
delete ota_server;
|
||||
ota_server = nullptr;
|
||||
}
|
||||
|
||||
ota_server = new AsyncWebServer(80);
|
||||
|
||||
ota_server->on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
request->send(200, "text/html", ota_home_buf);
|
||||
});
|
||||
ota_server->on("/log", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/packet_log", "text/plain");
|
||||
});
|
||||
|
||||
AsyncElegantOTA.setID(ota_id_buf);
|
||||
AsyncElegantOTA.begin(ota_server); // Start ElegantOTA
|
||||
ota_server->begin();
|
||||
}
|
||||
|
||||
void startOTAServerTask(void*) {
|
||||
vTaskDelay(pdMS_TO_TICKS(750));
|
||||
startOTAServerNow();
|
||||
ota_start_pending = false;
|
||||
vTaskDelete(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool ESP32Board::startOTAUpdate(const char* id, char reply[]) {
|
||||
inhibit_sleep = true; // prevent sleep during OTA
|
||||
|
||||
@@ -28,28 +62,16 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[]) {
|
||||
sprintf(reply, "Started: http://%s/update", ota_ip.toString().c_str());
|
||||
MESH_DEBUG_PRINTLN("startOTAUpdate: %s", reply);
|
||||
|
||||
static char id_buf[60];
|
||||
snprintf(id_buf, sizeof(id_buf), "%s (%s)", id, getManufacturerName());
|
||||
static char home_buf[90];
|
||||
snprintf(home_buf, sizeof(home_buf), "<H2>Hi! I am a MeshCore Repeater. ID: %s</H2>", id);
|
||||
snprintf(ota_id_buf, sizeof(ota_id_buf), "%s (%s)", id, getManufacturerName());
|
||||
snprintf(ota_home_buf, sizeof(ota_home_buf), "<H2>Hi! I am a MeshCore Repeater. ID: %s</H2>", id);
|
||||
|
||||
static AsyncWebServer* server = nullptr;
|
||||
if (server != nullptr) {
|
||||
delete server;
|
||||
server = nullptr;
|
||||
if (!ota_start_pending) {
|
||||
ota_start_pending = true;
|
||||
if (xTaskCreate(startOTAServerTask, "ota-start", 4096, nullptr, 1, nullptr) != pdPASS) {
|
||||
startOTAServerNow();
|
||||
ota_start_pending = false;
|
||||
}
|
||||
}
|
||||
server = new AsyncWebServer(80);
|
||||
|
||||
server->on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
request->send(200, "text/html", home_buf);
|
||||
});
|
||||
server->on("/log", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/packet_log", "text/plain");
|
||||
});
|
||||
|
||||
AsyncElegantOTA.setID(id_buf);
|
||||
AsyncElegantOTA.begin(server); // Start ElegantOTA
|
||||
server->begin();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2678,10 +2678,14 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
};
|
||||
document.getElementById("otaBtn").onclick = async () => {
|
||||
if (confirm("Start OTA mode now?")) {
|
||||
const otaBtn = document.getElementById("otaBtn");
|
||||
otaBtn.disabled = true;
|
||||
const result = await runCommand("start ota");
|
||||
const match = result.text && result.text.match(/https?:\/\/\S+/);
|
||||
if (result.ok && match) {
|
||||
window.location.href = match[0];
|
||||
} else {
|
||||
otaBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user