Fixed MQTT and WS Routing - w/o SSL

This commit is contained in:
2025-10-13 17:34:54 +03:00
parent f696984cd1
commit 956786321a
29 changed files with 2043 additions and 1210 deletions

View File

@@ -33,7 +33,7 @@
* ✅ Comprehensive logging system
*
* 📡 COMMUNICATION PROTOCOLS:
* • MQTT (Primary control interface)
* • MQTT (SSL/TLS via PubSubClient on Core 0)
* • WebSocket (Real-time web interface)
* • UDP Discovery (Auto-discovery service)
* • HTTP/HTTPS (OTA updates)
@@ -48,12 +48,39 @@
* High-priority FreeRTOS tasks ensure microsecond timing precision.
* Core 1 dedicated to BellEngine for maximum performance.
*
* 📋 VERSION: 1.1
* 📅 DATE: 2025-09-08
* 👨‍💻 AUTHOR: Advanced Bell Systems
* ═══════════════════════════════════════════════════════════════════════════════════
*/
/*
* ═══════════════════════════════════════════════════════════════════════════════
* 📋 VERSION CONFIGURATION
* ═══════════════════════════════════════════════════════════════════════════════
* 📅 DATE: 2025-10-10
* 👨‍💻 AUTHOR: BellSystems bonamin
*/
#define FW_VERSION "0.1"
/*
* ═══════════════════════════════════════════════════════════════════════════════
* 📅 VERSION HISTORY:
* ═══════════════════════════════════════════════════════════════════════════════
* v0.1 - Vesper Launch Beta
* ═══════════════════════════════════════════════════════════════════════════════
*/
// ═══════════════════════════════════════════════════════════════════════════════════
// SYSTEM LIBRARIES - Core ESP32 and Arduino functionality
// ═══════════════════════════════════════════════════════════════════════════════════
@@ -71,7 +98,6 @@
// ═══════════════════════════════════════════════════════════════════════════════════
// NETWORKING LIBRARIES - Advanced networking and communication
// ═══════════════════════════════════════════════════════════════════════════════════
#include <AsyncMqttClient.h> // High-performance async MQTT client
#include <WiFiManager.h> // WiFi configuration portal
#include <ESPAsyncWebServer.h> // Async web server for WebSocket support
#include <AsyncUDP.h> // UDP for discovery service
@@ -98,16 +124,15 @@
#include "src/Telemetry/Telemetry.hpp"
#include "src/OTAManager/OTAManager.hpp"
#include "src/Networking/Networking.hpp"
#include "src/Communication/Communication.hpp"
#include "src/Communication/CommunicationRouter/CommunicationRouter.hpp"
#include "src/ClientManager/ClientManager.hpp"
#include "src/Communication/ResponseBuilder.hpp"
#include "src/Communication/ResponseBuilder/ResponseBuilder.hpp"
#include "src/Player/Player.hpp"
#include "src/BellEngine/BellEngine.hpp"
#include "src/OutputManager/OutputManager.hpp"
#include "src/HealthMonitor/HealthMonitor.hpp"
#include "src/FirmwareValidator/FirmwareValidator.hpp"
#include "src/InputManager/InputManager.hpp"
#include "src/MqttSSL/MqttSSL.hpp"
// Class Constructors
ConfigManager configManager;
@@ -115,13 +140,12 @@ FileManager fileManager(&configManager);
Timekeeper timekeeper;
Telemetry telemetry;
OTAManager otaManager(configManager);
AsyncMqttClient mqttClient;
Player player;
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
AsyncUDP udp;
Networking networking(configManager);
Communication communication(configManager, otaManager, networking, mqttClient, server, ws, udp);
CommunicationRouter communication(configManager, otaManager, networking, server, ws, udp);
HealthMonitor healthMonitor;
FirmwareValidator firmwareValidator;
InputManager inputManager;
@@ -158,7 +182,7 @@ TimerHandle_t schedulerTimer;
void handleFactoryReset() {
if (configManager.factoryReset()) {
if (configManager.resetAllToDefaults()) {
delay(3000);
ESP.restart();
}
@@ -176,21 +200,22 @@ void setup()
SPI.begin(hwConfig.ethSpiSck, hwConfig.ethSpiMiso, hwConfig.ethSpiMosi);
delay(50);
// Initialize Configuration (this loads device identity from SD card)
// Initialize Configuration (loads factory identity from NVS + user settings from SD)
configManager.begin();
inputManager.begin();
inputManager.setFactoryResetLongPressCallback(handleFactoryReset);
// Set factory values:
// ═══════════════════════════════════════════════════════════════════════════════
// REMOVED: Manual device identity setters
// Device identity (UID, hwType, hwVersion) is now READ-ONLY in production firmware
// These values are set by factory firmware and stored permanently in NVS
// Production firmware loads them once at boot and keeps them in RAM
// ═══════════════════════════════════════════════════════════════════════════════
configManager.setDeviceUID("PV202508190002");
configManager.setHwType("BellPlus");
configManager.setHwVersion("1.0");
configManager.setFwVersion("1.1");
LOG_INFO("Device identity initialized");
// Update firmware version (this is the ONLY identity field that can be set)
configManager.setFwVersion(FW_VERSION);
LOG_INFO("Firmware version: %s", FW_VERSION);
// Display device information after configuration is loaded
@@ -277,12 +302,13 @@ void setup()
// BellEngine already initialized and registered earlier for health validation
// Initialize Communication Manager
// Initialize Communication Manager (now with PubSubClient MQTT)
communication.begin();
communication.setPlayerReference(&player);
communication.setFileManagerReference(&fileManager);
communication.setTimeKeeperReference(&timekeeper);
communication.setFirmwareValidatorReference(&firmwareValidator);
player.setDependencies(&communication, &fileManager);
player.setBellEngine(&bellEngine); // Connect the beast!
@@ -294,7 +320,15 @@ void setup()
// Set up network callbacks
networking.setNetworkCallbacks(
[]() { communication.onNetworkConnected(); }, // onConnected
[]() {
communication.onNetworkConnected();
// Start AsyncWebServer when network becomes available
if (networking.getState() != NetworkState::WIFI_PORTAL_MODE) {
LOG_INFO("🚀 Starting AsyncWebServer on port 80...");
server.begin();
LOG_INFO("✅ AsyncWebServer started on http://%s", networking.getLocalIP().c_str());
}
}, // onConnected
[]() { communication.onNetworkDisconnected(); } // onDisconnected
);
@@ -302,6 +336,14 @@ void setup()
if (networking.isConnected()) {
LOG_INFO("Network already connected - triggering MQTT connection");
communication.onNetworkConnected();
// 🔥 CRITICAL: Start AsyncWebServer ONLY when network is ready
// Do NOT start if WiFiManager portal is active (port 80 conflict!)
LOG_INFO("🚀 Starting AsyncWebServer on port 80...");
server.begin();
LOG_INFO("✅ AsyncWebServer started and listening on http://%s", networking.getLocalIP().c_str());
} else {
LOG_WARNING("⚠️ Network not ready - AsyncWebServer will start after connection");
}
delay(500);
@@ -309,6 +351,7 @@ void setup()
// Initialize OTA Manager and check for updates
otaManager.begin();
otaManager.setFileManager(&fileManager);
otaManager.setPlayer(&player); // Set player reference for idle check
// 🔥 CRITICAL: Delay OTA check to avoid UDP socket race with MQTT
// Both MQTT and OTA HTTP use UDP sockets, must sequence them!
@@ -320,8 +363,9 @@ void setup()
// Register OTA Manager with health monitor
healthMonitor.setOTAManager(&otaManager);
// Start the server
server.begin();
// Note: AsyncWebServer will be started by network callbacks when connection is ready
// This avoids port 80 conflicts with WiFiManager's captive portal
// 🔥 START RUNTIME VALIDATION: All subsystems are now initialized
// Begin extended runtime validation if we're in testing mode
@@ -333,6 +377,7 @@ void setup()
LOG_INFO("✅ Firmware already validated - normal operation mode");
}
// ═══════════════════════════════════════════════════════════════════════════════
// INITIALIZATION COMPLETE
// ═══════════════════════════════════════════════════════════════════════════════
@@ -340,7 +385,7 @@ void setup()
// • BellEngine creates high-priority timing task on Core 1
// • Telemetry creates monitoring task for load tracking
// • Player creates duration timer for playback control
// • Communication creates MQTT reconnection timers
// • Communication creates MQTT task on Core 0 with PubSubClient
// • Networking creates connection management timers
// ✅ Bell configuration automatically loaded by ConfigManager
// ✅ System ready for MQTT commands, WebSocket connections, and UDP discovery
@@ -360,7 +405,7 @@ void setup()
* • BellEngine: High-priority task on Core 1 for microsecond timing
* • Telemetry: Background monitoring task for system health
* • Player: Timer-based duration control for melody playback
* • Communication: Event-driven MQTT/WebSocket handling
* • Communication: MQTT task on Core 0 + Event-driven WebSocket
* • Networking: Automatic connection management
*
* The main loop only handles lightweight operations that don't require
@@ -371,26 +416,6 @@ void setup()
*/
void loop()
{
// ═══════════════════════════════════════════════════════════════════════════════
// INTENTIONALLY MINIMAL - ALL WORK DONE BY DEDICATED TASKS
// ═══════════════════════════════════════════════════════════════════════════════
//
// The loop() function is kept empty by design to ensure maximum
// performance for the high-precision BellEngine running on Core 1.
//
// All system functionality is handled by dedicated FreeRTOS tasks:
// • 🔥 BellEngine: Microsecond-precision timing (Core 1, Priority 6)
// • 📊 Telemetry: System monitoring (Background task)
// • 🎵 Player: Duration management (FreeRTOS timers)
// • 📡 Communication: MQTT/WebSocket (Event-driven)
// • 🌐 Networking: Connection management (Timer-based)
//
// If you need to add periodic functionality, consider creating a new
// dedicated task instead of putting it here.
// Uncomment the line below for debugging system status:
// Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
// Feed watchdog only during firmware validation
if (firmwareValidator.isInTestingMode()) {
esp_task_wdt_reset();
@@ -403,6 +428,13 @@ void loop()
}
}
// 🔥 DEBUG: Log every 10 seconds to verify we're still running
static unsigned long lastLog = 0;
if (millis() - lastLog > 10000) {
LOG_DEBUG("❤️ Loop alive, free heap: %d", ESP.getFreeHeap());
lastLog = millis();
}
// Keep the loop responsive but not busy
delay(100); // ⏱️ 100ms delay to prevent busy waiting
}