#include "web_export_server.h" #include "config.h" #include "flight_logbook.h" #include "sd_mutex.h" #include "airline_filter.h" #include "aircraft_watchlist.h" #include "aircraft_table.h" #include "settings_store.h" #include #include #include #include #include namespace WebExportServer { namespace { constexpr uint8_t MAX_DAYS_QUERIED = 31; WebServer server(80); // Nur reine Dateinamen/Labels aus Formularfeldern akzeptieren - kein // "/" und kein ".." - damit ueber die WebUI kein Ausbruch aus dem // jeweiligen SD-Verzeichnis moeglich ist (Pfad-Traversal). bool isSafeName(const String& name) { if (name.length() == 0 || name.length() > 40) return false; if (name.indexOf('/') >= 0 || name.indexOf('\\') >= 0) return false; if (name.indexOf("..") >= 0) return false; return true; } // Absichtliche Duplikate der gleichnamigen (lokalen/statischen) Funktionen // aus radar_screen.cpp - dort nicht exportiert, und nach der im Projekt // etablierten Konvention "jeder Screen/jedes Modul dupliziert seine // eigenen kleinen Helfer statt eines gemeinsamen Moduls" (siehe z.B. // timeout_screen.cpp) bewusst hier erneut definiert statt radar_screen.cpp // umzubauen. Bei Aenderungen an der Logik in radar_screen.cpp bitte diese // Kopie hier synchron halten, damit das WebUI-Radar dieselben Ringe/ // Markierungen zeigt wie das Geraete-Display. bool isEmergencySquawkWeb(const char* squawk) { if (!squawk[0]) return false; for (uint8_t i = 0; i < Config::EMERGENCY_SQUAWK_COUNT; i++) { if (strcmp(squawk, Config::EMERGENCY_SQUAWKS[i]) == 0) return true; } return false; } // "Auffaellig" (oranger Ring) beschraenkt sich aktuell auf gar nichts - // der Teil ueber Militaer-/Regierungs-Rufzeichen-Praefixe // (Config::NOTABLE_CALLSIGN_PREFIXES) ist NICHT umgesetzt, weil diese // Konstante nirgends im Projekt existiert (auch nicht in // radar_screen.cpp) - das zugehoerige Feature wurde bisher nie // tatsaechlich spezifiziert/implementiert. "notable" wird deshalb unten // in handleRadarJson() fest auf false gesetzt. Sobald es eine echte // Praefixliste gibt, hier eine isNotableCallsignWeb()-Funktion analog zu // isEmergencySquawkWeb() ergaenzen. bool isHeavyCategoryWeb(const char* category) { return category[0] == 'A' && category[1] == '5'; } String htmlHeader(const String& title) { String html; html += ""; html += ""; html += "" + title + ""; html += ""; html += "

" + title + "

"; return html; } // Live-Radar-Ansicht fuer die Startseite: ein , das per JavaScript // alle paar Sekunden /radar.json abruft und die Flugzeuge polar (Peilung/ // Distanz, genau wie auf dem Geraete-Display) zeichnet. Bewusst per // fetch()-Polling statt WebSocket/SSE gehalten - deutlich weniger Code // und Speicherbedarf auf dem ESP32, und fuer eine gelegentlich vom Handy // aus aufgerufene Seite voellig ausreichend. // // Der Reichweiten-Waehler ("; for (uint8_t i = 0; i < Config::RANGE_STEP_COUNT; i++) { bool isDefault = fabsf(Config::RANGE_STEPS_KM[i] - deviceRangeKm) < 0.5f; html += "