Skip to content

Commit d67bf54

Browse files
authored
Implement safe mode handling in web server
Added safe mode handling to the web server, including status and exit endpoints.
1 parent 5d3d596 commit d67bf54

1 file changed

Lines changed: 92 additions & 3 deletions

File tree

‎Arduino/webserver.cpp‎

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
* webserver.cpp
33
* Web server for control and configuration
44
*
5-
* TallyCCU Pro V3.6
5+
* TallyCCU Pro V3.7
66
*/
77

88
#include "WebServer.h"
99
#include "CCUBroadcast.h"
10+
#include "SafeMode.h"
1011
#include <SdFat.h>
1112
#include <avr/wdt.h>
1213

@@ -199,6 +200,12 @@ void WebServer::processRequests() {
199200
void WebServer::processPOSTRequest(const char* reqLine, EthernetClient &client) {
200201
Serial.println(F("[POST] Received"));
201202

203+
// Safe mode exit
204+
if (strstr(reqLine, "POST /safemode-exit") != NULL) {
205+
handleSafeModeExit(client);
206+
return;
207+
}
208+
202209
// Check if savePreset
203210
if (strstr(reqLine, "POST /savePreset") != NULL) {
204211
handleSavePresetPOST(client);
@@ -552,6 +559,30 @@ void WebServer::sendJSONResponse(EthernetClient &client, bool success, const cha
552559

553560
void WebServer::processGETRequest(const char* reqLine, EthernetClient &client) {
554561

562+
// ============================================================
563+
// SAFE MODE HANDLING - CHECK FIRST
564+
// ============================================================
565+
566+
// Safe mode status API (always available)
567+
if (strncmp(reqLine, "GET /safemode-status", 20) == 0) {
568+
handleSafeModeStatus(client);
569+
return;
570+
}
571+
572+
// In safe mode, redirect main pages to diagnostic page
573+
if (SafeMode::isActive()) {
574+
if (strncmp(reqLine, "GET / ", 6) == 0 ||
575+
strncmp(reqLine, "GET /index", 10) == 0 ||
576+
strncmp(reqLine, "GET /ccu", 8) == 0) {
577+
SdUtils::serveFile(client, "safemode.html");
578+
return;
579+
}
580+
}
581+
582+
// ============================================================
583+
// NORMAL REQUEST HANDLING
584+
// ============================================================
585+
555586
// Reboot
556587
if (strncmp(reqLine, "GET /reboot", 11) == 0) {
557588
Serial.println(F("Reboot requested"));
@@ -1042,7 +1073,8 @@ void WebServer::handleListFiles(EthernetClient &client) {
10421073
// Hide system files
10431074
if (strcmp(fileName, "index.html") == 0 ||
10441075
strcmp(fileName, "tally.html") == 0 ||
1045-
strcmp(fileName, "sdcard.html") == 0) {
1076+
strcmp(fileName, "sdcard.html") == 0 ||
1077+
strcmp(fileName, "safemode.html") == 0) {
10461078
entry.close();
10471079
continue;
10481080
}
@@ -1105,7 +1137,8 @@ void WebServer::handleDeleteFile(EthernetClient &client, const char* filename) {
11051137
// Protect system files
11061138
if (strcmp(filename, "index.html") == 0 ||
11071139
strcmp(filename, "tally.html") == 0 ||
1108-
strcmp(filename, "sdcard.html") == 0) {
1140+
strcmp(filename, "sdcard.html") == 0 ||
1141+
strcmp(filename, "safemode.html") == 0) {
11091142
client.println(F("{\"success\":false,\"error\":\"protected\"}"));
11101143
return;
11111144
}
@@ -1296,6 +1329,62 @@ void WebServer::handleUploadFile(EthernetClient &client) {
12961329
sendJSONResponse(client, filename[0] != '\0', filename[0] != '\0' ? filename : "No file");
12971330
}
12981331

1332+
// ============================================================
1333+
// SAFE MODE HANDLERS
1334+
// ============================================================
1335+
1336+
void WebServer::handleSafeModeStatus(EthernetClient &client) {
1337+
// Send headers
1338+
client.println(F("HTTP/1.1 200 OK"));
1339+
client.println(F("Content-Type: application/json"));
1340+
client.println(F("Cache-Control: no-cache"));
1341+
client.println(F("Access-Control-Allow-Origin: *"));
1342+
client.println(F("Connection: close"));
1343+
client.println();
1344+
1345+
// Calculate free RAM
1346+
extern int __heap_start, *__brkval;
1347+
int v;
1348+
int freeRam = (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
1349+
1350+
// Build JSON response
1351+
client.print(F("{"));
1352+
client.print(F("\"safeMode\":"));
1353+
client.print(SafeMode::isActive() ? F("true") : F("false"));
1354+
client.print(F(",\"resetCount\":"));
1355+
client.print(SafeMode::getResetCount());
1356+
client.print(F(",\"resetReason\":\""));
1357+
client.print(SafeMode::getResetReasonString());
1358+
client.print(F("\",\"uptime\":"));
1359+
client.print(SafeMode::getUptime());
1360+
client.print(F(",\"freeRam\":"));
1361+
client.print(freeRam);
1362+
client.print(F(",\"ip\":\""));
1363+
client.print(NetworkManager::getLocalIP());
1364+
client.println(F("\"}"));
1365+
}
1366+
1367+
void WebServer::handleSafeModeExit(EthernetClient &client) {
1368+
// Send response first
1369+
client.println(F("HTTP/1.1 200 OK"));
1370+
client.println(F("Content-Type: application/json"));
1371+
client.println(F("Access-Control-Allow-Origin: *"));
1372+
client.println(F("Connection: close"));
1373+
client.println();
1374+
client.println(F("{\"success\":true,\"message\":\"Restarting...\"}"));
1375+
1376+
// Close connection
1377+
delay(100);
1378+
client.flush();
1379+
client.stop();
1380+
1381+
// Small delay to ensure response is sent
1382+
delay(200);
1383+
1384+
// Exit safe mode (this triggers a restart)
1385+
SafeMode::exitSafeMode();
1386+
}
1387+
12991388
// ============================================================
13001389
// SSE (SERVER-SENT EVENTS) HANDLING
13011390
// ============================================================

0 commit comments

Comments
 (0)