From 4cb28d3a206ce5dedcc44b2fa860c5945a477769 Mon Sep 17 00:00:00 2001 From: John Varghese <126874846+John-Varghese-EH@users.noreply.github.com> Date: Tue, 3 Jun 2025 21:09:28 +0530 Subject: [PATCH] web_config.cpp --- ESP32CAM-ONVIF/web_config.cpp | 115 +++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 10 deletions(-) diff --git a/ESP32CAM-ONVIF/web_config.cpp b/ESP32CAM-ONVIF/web_config.cpp index 44d771a..2ffc2a3 100644 --- a/ESP32CAM-ONVIF/web_config.cpp +++ b/ESP32CAM-ONVIF/web_config.cpp @@ -1,24 +1,41 @@ #include "web_config.h" #include #include -#include "rtsp_server.h" // For getRTSPUrl() -#include "onvif_server.h" // For ONVIF URL if needed -#include "motion_detection.h" // For motion_detected() +#include "rtsp_server.h" // For getRTSPUrl() +#include "onvif_server.h" // For ONVIF URL if needed +#include "motion_detection.h" // For motion_detected() #include -#include // or LittleFS.h +#include +#include +#include +#include "esp_camera.h" WebServer webConfigServer(80); +// --- Helper: HTTP Basic Auth --- +const char* WEB_USER = "admin"; +const char* WEB_PASS = "esp123"; + +bool isAuthenticated(WebServer &server) { + if (!server.authenticate(WEB_USER, WEB_PASS)) { + server.requestAuthentication(); + return false; + } + return true; +} + void web_config_start() { - // Serve static files (HTML/JS/CSS) from SPIFFS + // Mount SPIFFS for static files if (!SPIFFS.begin(true)) { Serial.println("SPIFFS/LittleFS Mount Failed"); return; } - webConfigServer.serveStatic("/", SPIFFS, "/index.html").setDefaultFile("index.html"); + // Protect static files with authentication + webConfigServer.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html").setAuthentication(WEB_USER, WEB_PASS); // === API ENDPOINTS === webConfigServer.on("/api/status", HTTP_GET, []() { + if (!isAuthenticated(webConfigServer)) return; String json = "{"; json += "\"status\":\"Online\","; json += "\"rtsp\":\"" + getRTSPUrl() + "\","; @@ -28,29 +45,106 @@ void web_config_start() { webConfigServer.send(200, "application/json", json); }); + // --- Change Camera Settings --- webConfigServer.on("/api/config", HTTP_POST, []() { - // Parse JSON and apply camera settings (resolution, brightness, etc.) + if (!isAuthenticated(webConfigServer)) return; + StaticJsonDocument<256> doc; + DeserializationError err = deserializeJson(doc, webConfigServer.arg("plain")); + if (err) { + webConfigServer.send(400, "application/json", "{\"error\":\"Invalid JSON\"}"); + return; + } + sensor_t * s = esp_camera_sensor_get(); + if (doc.containsKey("brightness")) s->set_brightness(s, doc["brightness"]); + if (doc.containsKey("contrast")) s->set_contrast(s, doc["contrast"]); + if (doc.containsKey("saturation")) s->set_saturation(s, doc["saturation"]); + if (doc.containsKey("flip")) s->set_vflip(s, doc["flip"] ? 1 : 0); + if (doc.containsKey("rotate")) s->set_hmirror(s, doc["rotate"] ? 1 : 0); + if (doc.containsKey("resolution")) { + String res = doc["resolution"].as(); + if (res == "VGA") s->set_framesize(s, FRAMESIZE_VGA); + else if (res == "QVGA") s->set_framesize(s, FRAMESIZE_QVGA); + else if (res == "CIF") s->set_framesize(s, FRAMESIZE_CIF); + } webConfigServer.send(200, "application/json", "{\"ok\":1}"); }); + // --- SD Card File List --- + webConfigServer.on("/api/sd/list", HTTP_GET, []() { + if (!isAuthenticated(webConfigServer)) return; + String json = "["; + File root = SD_MMC.open("/"); + File file = root.openNextFile(); + bool first = true; + while(file){ + if (!first) json += ","; + json += "\"" + String(file.name()) + "\""; + file = root.openNextFile(); + first = false; + } + json += "]"; + webConfigServer.send(200, "application/json", json); + }); + + // --- SD Card Download --- + webConfigServer.on("/api/sd/download", HTTP_GET, []() { + if (!isAuthenticated(webConfigServer)) return; + if (!webConfigServer.hasArg("file")) { + webConfigServer.send(400, "text/plain", "Missing file param"); + return; + } + String filename = "/" + webConfigServer.arg("file"); + File file = SD_MMC.open(filename, "r"); + if (!file) { + webConfigServer.send(404, "text/plain", "File not found"); + return; + } + webConfigServer.streamFile(file, "application/octet-stream"); + file.close(); + }); + + // --- SD Card Delete --- + webConfigServer.on("/api/sd/delete", HTTP_POST, []() { + if (!isAuthenticated(webConfigServer)) return; + StaticJsonDocument<128> doc; + DeserializationError err = deserializeJson(doc, webConfigServer.arg("plain")); + if (err || !doc.containsKey("file")) { + webConfigServer.send(400, "application/json", "{\"error\":\"Invalid request\"}"); + return; + } + String filename = "/" + doc["file"].as(); + if (SD_MMC.remove(filename)) { + webConfigServer.send(200, "application/json", "{\"ok\":1}"); + } else { + webConfigServer.send(404, "application/json", "{\"error\":\"Delete failed\"}"); + } + }); + + // --- SD Recording Trigger (stub) --- webConfigServer.on("/api/record", HTTP_POST, []() { - // Start/stop SD recording logic + if (!isAuthenticated(webConfigServer)) return; + // Start/stop SD recording logic here webConfigServer.send(200, "application/json", "{\"ok\":1}"); }); + // --- Reboot --- webConfigServer.on("/api/reboot", HTTP_POST, []() { + if (!isAuthenticated(webConfigServer)) return; webConfigServer.send(200, "application/json", "{\"ok\":1}"); ESP.restart(); }); + // --- Factory Reset (stub) --- webConfigServer.on("/api/factory_reset", HTTP_POST, []() { - // Reset settings logic + if (!isAuthenticated(webConfigServer)) return; + // Reset settings logic here webConfigServer.send(200, "application/json", "{\"ok\":1}"); ESP.restart(); }); // === STREAM ENDPOINT === webConfigServer.on("/stream", HTTP_GET, []() { + if (!isAuthenticated(webConfigServer)) return; WiFiClient client = webConfigServer.client(); String response = "HTTP/1.1 200 OK\r\n"; response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n"; @@ -67,8 +161,9 @@ void web_config_start() { } }); - // Optional: Snapshot endpoint + // --- Snapshot endpoint --- webConfigServer.on("/snapshot", HTTP_GET, []() { + if (!isAuthenticated(webConfigServer)) return; camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { webConfigServer.send(500, "text/plain", "Camera Error");