Files
DigiRadio/Software/components/net/include/net/SetupWebServer.hpp
T
micheleandClaude Sonnet 5 6f7b6dd12c Add internet radio streaming with runtime API, modernize web UI, remove auto-tune/beep at boot
Streaming (main feature this session):
- New WebRadioConfig/WebRadioJson core types, ISecureStore-backed persistence
- New webradio::WebRadioService (thread-safe live config) + GET/POST /api/streaming
- web_radio_stream task now runtime-toggleable (no reboot), no hardcoded URL
- Content-Type diagnostic: warns clearly when a URL is a webpage, not an audio stream

Boot cleanup:
- Removed boot-time auto FM/DAB tune, auto-beep, and the (now-concluded) Si4684
  crystal IBIAS/CTUN empirical sweep from main.cpp — tuning/beep are on-demand
  via the existing REST API only

Web UI:
- Modernized styling (cards, gradients, toggle switches, light/dark theme)
- New Stream tab wired to /api/streaming

Fixes found via real idf.py build (not just clangd):
- Restored wrongly-removed si4684/Si4684Tuner.hpp include in main.cpp
- Fixed MP3Decode() argument types in web_radio_stream.cpp (unsigned char**/int*)

Quality-gate fixes:
- Host-test stub headers (esp_log.h, freertos/*) so TunerService.cpp's
  scanForStation logging/pacing compiles for station_service_test /
  integration_service_test instead of running stale binaries
- Added WifiScanner and WebRadioService manual sections; filled in missing
  Doxygen docs on BluetoothService, i2s_sdata_probe, test_firmware, Bt1035At
- Ignore clangd's .cache/ index directory

Also includes prior uncommitted work carried in the tree: Wi-Fi/Bluetooth
device scan REST API and UI (WifiScanner, BT scan), SigmaStudio TCP bridge,
and the current ADAU1701 SigmaStudio DSP program export.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-08 21:15:22 +02:00

192 lines
6.1 KiB
C++

/**
* @file SetupWebServer.hpp
* @brief HTTP server for setup UI, health, and Wi-Fi provisioning API.
*
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
*
* Copyright 2026 Michele Bigi
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* @author Michele Bigi
* @date 2026-07-06
*/
#pragma once
#include "core/CompanionChipStatus.hpp"
#include "core/DeviceIdentity.hpp"
#include "core/ISecureStore.hpp"
#include "net/NetError.hpp"
#include "net/NetState.hpp"
#include "esp_http_server.h"
#include <expected>
namespace audio {
class AudioService;
} // namespace audio
namespace bluetooth {
class BluetoothService;
} // namespace bluetooth
namespace station {
class StationService;
} // namespace station
namespace integration {
class IntegrationService;
} // namespace integration
namespace ota {
class OtaService;
} // namespace ota
namespace tuner {
class TunerService;
} // namespace tuner
namespace webradio {
class WebRadioService;
} // namespace webradio
struct httpd_handle;
namespace net {
/**
* @brief HttpRouteContext — dependencies injected into HTTP handlers.
*
* @dname HttpRouteContext
* @return n/a (type)
* @pubstate Borrows store and tuner for the lifetime of SetupWebServer.
* Passed as esp_http_server user_ctx (no file-scope globals).
*
* @author Michele Bigi
* @date 2026-07-06
*/
struct HttpRouteContext {
core::ISecureStore* store; ///< Secure store for Wi-Fi provisioning.
tuner::TunerService* tuner; ///< Tuner service for tuner REST routes.
audio::AudioService* audio; ///< Audio service for ADAU1701 REST routes.
bluetooth::BluetoothService* bluetooth; ///< Bluetooth pairing REST routes.
station::StationService* stations; ///< Preset list REST routes.
integration::IntegrationService* integration; ///< Preset recall orchestration.
ota::OtaService* ota; ///< Firmware OTA streaming.
webradio::WebRadioService* webRadio; ///< Streaming config REST routes.
core::CompanionChipStatus companionChips; ///< Boot flags for /api/health.
core::DeviceIdentity deviceIdentity; ///< EEPROM-derived unit identity.
};
/**
* @brief SetupWebServer — setup UI, health, and Wi-Fi provisioning API.
*
* @dname SetupWebServer
* @return n/a (type)
* @pubstate Owns server_ and borrows store_ while running. Routes delegate
* JSON work to the pure core.
*
* @author Michele Bigi
* @date 2026-07-06
*/
class SetupWebServer {
public:
/**
* @brief SetupWebServer — construct an unstarted server.
*
* @dname SetupWebServer
* @pubstate clears server_, store_, and netState_.
*
* @author Michele Bigi
* @date 2026-07-06
*/
SetupWebServer();
/**
* @brief ~SetupWebServer — stop the HTTP server if running.
*
* @dname ~SetupWebServer
* @pubstate stops server_ when non-null.
*
* @author Michele Bigi
* @date 2026-07-06
*/
~SetupWebServer();
SetupWebServer(const SetupWebServer&) = delete;
SetupWebServer& operator=(const SetupWebServer&) = delete;
/**
* @brief SetupWebServer — move-construct, transferring the handle.
*
* @dname SetupWebServer
* @param other Source server; left stopped after the move.
* @pubstate takes ownership of other.server_ and copies store pointer.
*
* @author Michele Bigi
* @date 2026-07-06
*/
SetupWebServer(SetupWebServer&& other) noexcept;
/**
* @brief operator= — move-assign, transferring the handle.
*
* @dname operator=
* @param other Source server; left stopped after the move.
* @return Reference to this instance.
* @pubstate takes ownership of other.server_ and copies store pointer.
*
* @author Michele Bigi
* @date 2026-07-06
*/
SetupWebServer& operator=(SetupWebServer&& other) noexcept;
/**
* @brief start — register routes and listen on port 80.
*
* @dname start
* @param store Secure store for POST /api/wifi persistence.
* @param netState Active network phase exposed to handlers.
* @param tuner Tuner service for the tuner REST routes.
* @param audio Audio service for the audio REST routes.
* @param bluetooth Bluetooth service for pairing REST routes.
* @param stations Station preset service for list REST routes.
* @param integration Application orchestration for preset recall.
* @param ota Firmware OTA service for POST /api/system/ota.
* @param webRadio Streaming config for GET/POST /api/streaming.
* @param companionChips Boot flags for GET /api/health.
* @param deviceIdentity Unit identity for /api/health serialNumber.
* @return Ok on success, or NetError::HttpServerStartFailed.
* @pubstate writes server_, store_, netState_, and service pointers on success.
*
* @author Michele Bigi
* @date 2026-07-06
*/
[[nodiscard]] std::expected<void, NetError> start(
core::ISecureStore& store, NetState netState,
tuner::TunerService& tuner, audio::AudioService& audio,
bluetooth::BluetoothService& bluetooth,
station::StationService& stations,
integration::IntegrationService& integration,
ota::OtaService& ota,
webradio::WebRadioService& webRadio,
core::CompanionChipStatus companionChips,
const core::DeviceIdentity& deviceIdentity);
private:
httpd_handle_t server_;
core::ISecureStore* store_;
NetState netState_;
tuner::TunerService* tuner_;
audio::AudioService* audio_;
bluetooth::BluetoothService* bluetooth_;
station::StationService* stations_;
integration::IntegrationService* integration_;
};
} // namespace net