| 224 | } |
| 225 | |
| 226 | void CrossPointWebServer::stop() { |
| 227 | if (!running || !server) { |
| 228 | LOG_DBG("WEB", "stop() called but already stopped (running=%d, server=%p)", running, server.get()); |
| 229 | return; |
| 230 | } |
| 231 | |
| 232 | LOG_DBG("WEB", "STOP INITIATED - setting running=false first"); |
| 233 | running = false; // Set this FIRST to prevent handleClient from using server |
| 234 | |
| 235 | LOG_DBG("WEB", "[MEM] Free heap before stop: %d bytes", ESP.getFreeHeap()); |
| 236 | |
| 237 | // Close any in-progress WebSocket upload and remove partial file |
| 238 | if (wsUploadInProgress && wsUploadFile) { |
| 239 | abortWsUpload("WEB"); |
| 240 | } |
| 241 | |
| 242 | // Stop WebSocket server |
| 243 | if (wsServer) { |
| 244 | LOG_DBG("WEB", "Stopping WebSocket server..."); |
| 245 | wsServer->close(); |
| 246 | wsServer.reset(); |
| 247 | wsInstance = nullptr; |
| 248 | LOG_DBG("WEB", "WebSocket server stopped"); |
| 249 | } |
| 250 | |
| 251 | if (udpActive) { |
| 252 | udp.stop(); |
| 253 | udpActive = false; |
| 254 | } |
| 255 | |
| 256 | // Brief delay to allow any in-flight handleClient() calls to complete |
| 257 | delay(20); |
| 258 | |
| 259 | server->stop(); |
| 260 | LOG_DBG("WEB", "[MEM] Free heap after server->stop(): %d bytes", ESP.getFreeHeap()); |
| 261 | |
| 262 | // Brief delay before deletion |
| 263 | delay(10); |
| 264 | |
| 265 | server.reset(); |
| 266 | LOG_DBG("WEB", "Web server stopped and deleted"); |
| 267 | LOG_DBG("WEB", "[MEM] Free heap after delete server: %d bytes", ESP.getFreeHeap()); |
| 268 | |
| 269 | // Note: Static upload variables (uploadFileName, uploadPath, uploadError) are declared |
| 270 | // later in the file and will be cleared when they go out of scope or on next upload |
| 271 | LOG_DBG("WEB", "[MEM] Free heap final: %d bytes", ESP.getFreeHeap()); |
| 272 | } |
| 273 | |
| 274 | void CrossPointWebServer::handleClient() { |
| 275 | static unsigned long lastDebugPrint = 0; |
no test coverage detected