#pragma once #include #include #include #include #include #include #include "activities/ActivityWithSubactivity.h" #include "network/CrossPointWebServer.h" #include "NetworkModeSelectionActivity.h" // Web server activity states enum class WebServerActivityState { MODE_SELECTION, // Choosing between Join Network and Create Hotspot WIFI_SELECTION, // WiFi selection subactivity is active (for Join Network mode) AP_STARTING, // Starting Access Point mode SERVER_RUNNING, // Web server is running and handling requests SHUTTING_DOWN // Shutting down server and WiFi }; /** * CrossPointWebServerActivity is the entry point for file transfer functionality. * It: * - First presents a choice between "Join a Network" (STA) and "Create Hotspot" (AP) * - For STA mode: Launches WifiSelectionActivity to connect to an existing network * - For AP mode: Creates an Access Point that clients can connect to * - Starts the CrossPointWebServer when connected * - Handles client requests in its loop() function * - Cleans up the server and shuts down WiFi on exit */ class CrossPointWebServerActivity final : public ActivityWithSubactivity { TaskHandle_t displayTaskHandle = nullptr; SemaphoreHandle_t renderingMutex = nullptr; bool updateRequired = false; WebServerActivityState state = WebServerActivityState::MODE_SELECTION; const std::function onGoBack; // Network mode NetworkMode networkMode = NetworkMode::JOIN_NETWORK; bool isApMode = false; // Web server - owned by this activity std::unique_ptr webServer; // Server status std::string connectedIP; std::string connectedSSID; // For STA mode: network name, For AP mode: AP name // Performance monitoring unsigned long lastHandleClientTime = 0; static void taskTrampoline(void* param); [[noreturn]] void displayTaskLoop(); void render() const; void renderServerRunning() const; void onNetworkModeSelected(NetworkMode mode); void onWifiSelectionComplete(bool connected); void startAccessPoint(); void startWebServer(); void stopWebServer(); public: explicit CrossPointWebServerActivity(GfxRenderer& renderer, InputManager& inputManager, const std::function& onGoBack) : ActivityWithSubactivity("CrossPointWebServer", renderer, inputManager), onGoBack(onGoBack) {} void onEnter() override; void onExit() override; void loop() override; bool skipLoopDelay() override { return webServer && webServer->isRunning(); } };