/** * @file wifi_server.cpp * @brief WiFi Access Point + HTTP WebServer for ESP32 Watch * Provides time sync and notes management via web interface */ #include "app_hal.h" #ifdef ENABLE_WIFI_SERVER #include #include #include #include #include "wifi_server.h" #include "../src/apps/notes/notes_storage.h" /* WiFi AP Configuration */ #define WIFI_SSID "ESP32-Watch" #define WIFI_PASS "12345678" /* External references */ extern ChronosESP32 watch; static WebServer server(80); static bool serverRunning = false; /* ────────────────────────────────────────────── * Embedded HTML Page (PROGMEM) * ────────────────────────────────────────────── */ static const char index_html[] PROGMEM = R"rawliteral( ESP32 Watch Manager

ESP32 Watch Manager

Czas

--:--:--

Notatki


Dodaj notatke

Status

IP: 192.168.4.1 Bateria: --
)rawliteral"; /* ────────────────────────────────────────────── * API Handlers * ────────────────────────────────────────────── */ static void handleRoot() { server.send(200, "text/html", index_html); } static void handleGetNotes() { char *json = notes_storage_get_json(); if (json) { server.send(200, "application/json", json); free(json); } else { server.send(200, "application/json", "[]"); } } static void handlePostNotes() { if (!server.hasArg("plain")) { server.send(400, "application/json", "{\"ok\":false,\"error\":\"no body\"}"); return; } String body = server.arg("plain"); bool ok = notes_storage_save(body.c_str()); if (ok) { server.send(200, "application/json", "{\"ok\":true}"); } else { server.send(500, "application/json", "{\"ok\":false,\"error\":\"write failed\"}"); } } static void handlePostTime() { if (!server.hasArg("plain")) { server.send(400, "application/json", "{\"ok\":false,\"error\":\"no body\"}"); return; } String body = server.arg("plain"); JsonDocument doc; DeserializationError error = deserializeJson(doc, body); if (error) { server.send(400, "application/json", "{\"ok\":false,\"error\":\"invalid json\"}"); return; } int h = doc["h"] | 0; int m = doc["m"] | 0; int s = doc["s"] | 0; int d = doc["d"] | 1; int mo = doc["mo"] | 1; int y = doc["y"] | 2025; watch.setTime(s, m, h, d, mo, y); server.send(200, "application/json", "{\"ok\":true}"); } static void handleGetStatus() { JsonDocument doc; doc["h"] = watch.getHour(true); doc["m"] = watch.getMinute(); doc["s"] = watch.getSecond(); doc["d"] = watch.getDay(); doc["mo"] = watch.getMonth() + 1; doc["y"] = watch.getYear(); doc["bat"] = watch.getPhoneBattery(); String output; serializeJson(doc, output); server.send(200, "application/json", output); } static void handleNotFound() { server.send(404, "text/plain", "Not Found"); } /* ────────────────────────────────────────────── * Public API * ────────────────────────────────────────────── */ extern "C" { void wifi_server_start(void) { if (serverRunning) return; WiFi.mode(WIFI_AP); WiFi.softAP(WIFI_SSID, WIFI_PASS); /* Register endpoints */ server.on("/", HTTP_GET, handleRoot); server.on("/api/notes", HTTP_GET, handleGetNotes); server.on("/api/notes", HTTP_POST, handlePostNotes); server.on("/api/time", HTTP_POST, handlePostTime); server.on("/api/status", HTTP_GET, handleGetStatus); server.onNotFound(handleNotFound); server.begin(); serverRunning = true; } void wifi_server_stop(void) { if (!serverRunning) return; server.stop(); WiFi.softAPdisconnect(true); WiFi.mode(WIFI_OFF); serverRunning = false; } void wifi_server_handle(void) { if (serverRunning) { server.handleClient(); } } bool wifi_server_is_running(void) { return serverRunning; } } /* extern "C" */ #endif /* ENABLE_WIFI_SERVER */