@@ -16,7 +16,7 @@ static const IPAddress AP_IP(200, 200, 200, 1);
1616static const IPAddress AP_GATEWAY (200 , 200 , 200 , 1 );
1717static const IPAddress AP_SUBNET (255 , 255 , 255 , 0 );
1818
19- WiFiManagerESP32::WiFiManagerESP32 (BoardDriver* bd, MoveHistory* mh) : boardDriver(bd), moveHistory(mh), server(HTTP_PORT), boardEvents(nullptr ), gameMode(" 0" ), lichessToken(" " ), botConfig(), scanAllChannels(false ), profileCount(0 ), connectedProfileIndex(-1 ), scanResults(nullptr ), scanResultCount(0 ), currentFen(INITIAL_FEN), hasPendingEdit(false ), hasPendingResign(false ), hasPendingDraw(false ), hasPendingResume(false ), pendingResignColor(' ?' ), promotion{}, boardEvaluation(0 .0f ), otaUpdater(bd), autoOtaEnabled(false ), otaChecked(false ) {
19+ WiFiManagerESP32::WiFiManagerESP32 (BoardDriver* bd, MoveHistory* mh) : boardDriver(bd), moveHistory(mh), server(HTTP_PORT), boardEvents(nullptr ), gameMode(" 0" ), lichessToken(" " ), botConfig(), scanAllChannels(false ), profileCount(0 ), connectedProfileIndex(-1 ), wifiRadioDisabled( false ), scanResults(nullptr ), scanResultCount(0 ), currentFen(INITIAL_FEN), hasPendingEdit(false ), hasPendingResign(false ), hasPendingDraw(false ), hasPendingResume(false ), pendingResignColor(' ?' ), promotion{}, boardEvaluation(0 .0f ), otaUpdater(bd), autoOtaEnabled(false ), otaChecked(false ) {
2020 promotion.reset ();
2121 pendingWiFi.reset ();
2222}
@@ -92,6 +92,7 @@ void WiFiManagerESP32::begin() {
9292 server.on (" /draw" , HTTP_POST, [this ](AsyncWebServerRequest* request) { this ->handleDraw (request); });
9393 server.on (" /wifi" , HTTP_GET, [this ](AsyncWebServerRequest* request) { request->send (200 , " application/json" , this ->getWiFiInfoJSON ()); });
9494 server.on (" /wifi" , HTTP_POST, [this ](AsyncWebServerRequest* request) { this ->handleConnectWiFi (request); });
95+ server.on (" /disable-wifi-radio" , HTTP_POST, [this ](AsyncWebServerRequest* request) { this ->handleDisableWiFiRadio (request); });
9596 server.on (" /gameselect" , HTTP_POST, [this ](AsyncWebServerRequest* request) { this ->handleGameSelection (request); });
9697 server.on (" /lichess" , HTTP_GET, [this ](AsyncWebServerRequest* request) { request->send (200 , " application/json" , this ->getLichessInfoJSON ()); });
9798 server.on (" /lichess" , HTTP_POST, [this ](AsyncWebServerRequest* request) { this ->handleSaveLichessToken (request); });
@@ -246,6 +247,8 @@ void WiFiManagerESP32::handleDraw(AsyncWebServerRequest* request) {
246247}
247248
248249void WiFiManagerESP32::handleConnectWiFi (AsyncWebServerRequest* request) {
250+ if (wifiRadioDisabled) return ;
251+
249252 // Handle scanAllChannels toggle
250253 if (request->hasArg (" scanAllChannels" )) {
251254 bool newScanAll = request->arg (" scanAllChannels" ) == " 1" ;
@@ -320,6 +323,35 @@ void WiFiManagerESP32::handleConnectWiFi(AsyncWebServerRequest* request) {
320323 request->send (400 , " text/plain" , " Missing or invalid parameters" );
321324}
322325
326+ void WiFiManagerESP32::handleDisableWiFiRadio (AsyncWebServerRequest* request) {
327+ request->send (200 , " text/plain" , " WiFi radio disabling now. The WebUI will be unavailable until the ESP32 boots again." );
328+
329+ xTaskCreate (
330+ [](void * param) {
331+ delay (500 );
332+ static_cast <WiFiManagerESP32*>(param)->disableWiFiRadio ();
333+ vTaskDelete (nullptr );
334+ },
335+ " disableWiFiRadioTask" , 2048 , this , 3 , nullptr );
336+ }
337+
338+ void WiFiManagerESP32::disableWiFiRadio () {
339+ webLog.println (" Disabling ESP32 WiFi radio until next boot..." );
340+ wifiRadioDisabled = true ;
341+ pendingWiFi.action = NONE;
342+ connectedProfileIndex = -1 ;
343+
344+ stopCaptivePortal ();
345+ MDNS.end ();
346+ WiFi.scanDelete ();
347+ WiFi.setAutoReconnect (false );
348+ WiFi.disconnect (true , false );
349+ WiFi.softAPdisconnect (true );
350+ WiFi.mode (WIFI_OFF);
351+
352+ webLog.println (" WiFi radio disabled. Reboot the ESP32 to restore WebUI access." );
353+ }
354+
323355void WiFiManagerESP32::handleGameSelection (AsyncWebServerRequest* request) {
324356 int mode = 0 ;
325357 if (request->hasArg (" gamemode" ))
@@ -596,6 +628,8 @@ void WiFiManagerESP32::clearPromotion() {
596628}
597629
598630void WiFiManagerESP32::checkPendingWiFi () {
631+ if (wifiRadioDisabled) return ;
632+
599633 // Auto-reconnect: if we were connected to a network and lost it, try to reconnect
600634 if (connectedProfileIndex >= 0 && WiFi.status () != WL_CONNECTED) {
601635 webLog.println (" WiFi connection lost, attempting reconnect..." );
@@ -704,6 +738,8 @@ void WiFiManagerESP32::checkPendingWiFi() {
704738}
705739
706740bool WiFiManagerESP32::ensureConnected () {
741+ if (wifiRadioDisabled) return false ;
742+
707743 if (WiFi.status () == WL_CONNECTED) return true ;
708744 webLog.println (" WiFi not connected, attempting reconnect..." );
709745 if (connectToSavedProfile ()) return true ;
@@ -1030,6 +1066,8 @@ void WiFiManagerESP32::promoteProfile(int index) {
10301066}
10311067
10321068bool WiFiManagerESP32::waitForConnection (int maxAttempts) {
1069+ if (wifiRadioDisabled) return false ;
1070+
10331071 for (int i = 0 ; i < maxAttempts; i++) {
10341072 boardDriver->showConnectingAnimation ();
10351073 wl_status_t st = WiFi.status ();
@@ -1041,6 +1079,8 @@ bool WiFiManagerESP32::waitForConnection(int maxAttempts) {
10411079}
10421080
10431081bool WiFiManagerESP32::tryConnect (const String& ssid, const String& password, const uint8_t * bssid, uint8_t channel) {
1082+ if (wifiRadioDisabled) return false ;
1083+
10441084 bool isFast = (bssid != nullptr && channel > 0 );
10451085 if (isFast)
10461086 webLog.printf (" Fast connect: SSID=%s, Password=%s, Channel=%d, BSSID=%02X:%02X:%02X:%02X:%02X:%02X\n " , ssid.c_str (), password.c_str (), channel, bssid[0 ], bssid[1 ], bssid[2 ], bssid[3 ], bssid[4 ], bssid[5 ]);
@@ -1113,6 +1153,8 @@ bool WiFiManagerESP32::tryConnectProfile(int index) {
11131153}
11141154
11151155bool WiFiManagerESP32::connectToSavedProfile () {
1156+ if (wifiRadioDisabled) return false ;
1157+
11161158 for (int i = 0 ; i < profileCount; i++) {
11171159 if (tryConnectProfile (i)) {
11181160 promoteProfile (i);
@@ -1124,6 +1166,8 @@ bool WiFiManagerESP32::connectToSavedProfile() {
11241166}
11251167
11261168void WiFiManagerESP32::startAPFallback () {
1169+ if (wifiRadioDisabled) return ;
1170+
11271171 webLog.println (" Starting AP fallback..." );
11281172 WiFi.mode (WIFI_AP);
11291173 if (!WiFi.softAPConfig (AP_IP, AP_GATEWAY, AP_SUBNET))
@@ -1172,6 +1216,8 @@ void WiFiManagerESP32::pendingWiFiBackgroundTask(void* param) {
11721216}
11731217
11741218void WiFiManagerESP32::performScan () {
1219+ if (wifiRadioDisabled) return ;
1220+
11751221 static bool scanInProgress = false ;
11761222 if (scanInProgress) return ;
11771223 scanInProgress = true ;
0 commit comments