From 47f41847ac4f91fe5efa68f4f27bc834f52fc5f0 Mon Sep 17 00:00:00 2001 From: "Valentin V. Bartenev" Date: Fri, 8 May 2026 03:49:35 +0300 Subject: [PATCH] Improve OTA behaviour when WiFi is already connected When startOTAUpdate() was called while the device was already connected as a STA (web panel or MQTT active), it would bring up an open "MeshCore-OTA" AP alongside the existing connection and report its IP (softAPIP, typically 192.168.4.1) in the reply. The OTA AsyncWebServer also listens on the STA interface, so the update page was reachable via the existing network IP, but that address was not reported. Two problems with the old behaviour: - Raising an open AP while a STA connection is active is a security concern. - The reported AP address is not useful to a user who is already on the same network as the device; they would naturally try the STA IP. New behaviour: - If the device is already connected as a STA (WiFi.status() == WL_CONNECTED), skip softAP() entirely and report WiFi.localIP() in the reply. The OTA server is already reachable on that address. - If there is no STA connection, keep the original behaviour: bring up the "MeshCore-OTA" AP and report softAPIP(). In both cases the reply now includes the network name so the user knows which interface to connect to: STA: "Started: http:///update (WiFi: )" AP: "Started: http:///update (AP: MeshCore-OTA)" If a user specifically wants to perform OTA via the dedicated AP, they can disable the current WiFi interface first, after which startOTAUpdate will fall into the AP path as before. --- src/helpers/ESP32Board.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/helpers/ESP32Board.cpp b/src/helpers/ESP32Board.cpp index a34cf5e2..63469976 100644 --- a/src/helpers/ESP32Board.cpp +++ b/src/helpers/ESP32Board.cpp @@ -12,13 +12,20 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[]) { inhibit_sleep = true; // prevent sleep during OTA - WiFi.mode(WIFI_AP_STA); - if (!WiFi.softAP("MeshCore-OTA", NULL)) { - strcpy(reply, "Error - OTA AP start failed"); - return false; + + if (WiFi.status() != WL_CONNECTED) { + WiFi.mode(WIFI_AP_STA); + if (!WiFi.softAP("MeshCore-OTA", NULL)) { + strcpy(reply, "Error - OTA AP start failed"); + return false; + } + sprintf(reply, "Started: http://%s/update (AP: MeshCore-OTA)", + WiFi.softAPIP().toString().c_str()); + } else { + sprintf(reply, "Started: http://%s/update (WiFi: %s)", + WiFi.localIP().toString().c_str(), WiFi.SSID().c_str()); } - sprintf(reply, "Started: http://%s/update", WiFi.softAPIP().toString().c_str()); MESH_DEBUG_PRINTLN("startOTAUpdate: %s", reply); static char id_buf[60];