144 lines
5.7 KiB
C++
144 lines
5.7 KiB
C++
/*
|
|
* ═══════════════════════════════════════════════════════════════════════════════════
|
|
* OTAMANAGER.HPP - Over-The-Air Update Management System
|
|
* ═══════════════════════════════════════════════════════════════════════════════════
|
|
*
|
|
* 🔄 THE UPDATE ORCHESTRATOR OF VESPER 🔄
|
|
*
|
|
* This class manages over-the-air firmware updates with safe, reliable
|
|
* update mechanisms, version checking, and comprehensive error handling.
|
|
*
|
|
* 📋 VERSION: 2.1 (Enhanced with scheduled checks and full validation)
|
|
* 📅 DATE: 2025
|
|
* 👨💻 AUTHOR: Advanced Bell Systems
|
|
* ═══════════════════════════════════════════════════════════════════════════════════
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <Arduino.h>
|
|
#include <HTTPClient.h>
|
|
#include <Update.h>
|
|
#include <WiFi.h>
|
|
#include <SD.h>
|
|
#include <mbedtls/md.h>
|
|
#include <ArduinoJson.h>
|
|
#include <functional>
|
|
#include <time.h>
|
|
#include "../FileManager/FileManager.hpp"
|
|
|
|
class ConfigManager; // Forward declaration
|
|
class Player; // Forward declaration for idle check
|
|
|
|
class OTAManager {
|
|
public:
|
|
enum class Status {
|
|
IDLE,
|
|
CHECKING_VERSION,
|
|
DOWNLOADING,
|
|
INSTALLING,
|
|
SUCCESS,
|
|
FAILED
|
|
};
|
|
|
|
enum class ErrorCode {
|
|
NONE,
|
|
HTTP_ERROR,
|
|
VERSION_CHECK_FAILED,
|
|
DOWNLOAD_FAILED,
|
|
INSUFFICIENT_SPACE,
|
|
WRITE_FAILED,
|
|
VERIFICATION_FAILED,
|
|
CHECKSUM_MISMATCH,
|
|
METADATA_PARSE_FAILED,
|
|
SIZE_MISMATCH,
|
|
VERSION_TOO_LOW,
|
|
CHANNEL_MISMATCH,
|
|
PLAYER_ACTIVE
|
|
};
|
|
|
|
// Callback types
|
|
using ProgressCallback = std::function<void(size_t current, size_t total)>;
|
|
using StatusCallback = std::function<void(Status status, ErrorCode error)>;
|
|
|
|
explicit OTAManager(ConfigManager& configManager);
|
|
~OTAManager();
|
|
|
|
void begin();
|
|
void setFileManager(FileManager* fm);
|
|
void setPlayer(Player* player); // NEW: Set player reference for idle check
|
|
|
|
void checkForUpdates();
|
|
void checkForUpdates(const String& channel); // Check specific channel
|
|
void checkForEmergencyUpdates(); // NEW: Scheduled emergency-only check
|
|
|
|
void update();
|
|
void update(const String& channel); // Update from specific channel
|
|
void checkFirmwareUpdateFromSD(); // Check SD for firmware update
|
|
bool performManualUpdate(); // Manual update triggered by app
|
|
bool performManualUpdate(const String& channel); // Manual update from specific channel
|
|
|
|
// Hardware identification
|
|
String getHardwareVariant() const;
|
|
void setHardwareVariant(const String& variant); // Deprecated: Use ConfigManager instead
|
|
|
|
// Status and info
|
|
Status getStatus() const { return _status; }
|
|
ErrorCode getLastError() const { return _lastError; }
|
|
float getCurrentVersion() const;
|
|
float getAvailableVersion() const { return _availableVersion; }
|
|
bool isUpdateAvailable() const { return _updateAvailable; }
|
|
|
|
// Callbacks
|
|
void setProgressCallback(ProgressCallback callback) { _progressCallback = callback; }
|
|
void setStatusCallback(StatusCallback callback) { _statusCallback = callback; }
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
// HEALTH CHECK METHOD
|
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
/** @brief Check if OTAManager is in healthy state */
|
|
bool isHealthy() const;
|
|
|
|
private:
|
|
ConfigManager& _configManager;
|
|
FileManager* _fileManager;
|
|
Player* _player; // NEW: Player reference for idle check
|
|
Status _status;
|
|
ErrorCode _lastError;
|
|
float _availableVersion;
|
|
float _minVersion; // NEW: Minimum required version
|
|
size_t _expectedFileSize; // NEW: Expected firmware file size
|
|
bool _updateAvailable;
|
|
String _availableChecksum;
|
|
String _updateChannel;
|
|
bool _isMandatory;
|
|
bool _isEmergency;
|
|
|
|
ProgressCallback _progressCallback;
|
|
StatusCallback _statusCallback;
|
|
|
|
// NEW: Scheduled check timer
|
|
TimerHandle_t _scheduledCheckTimer;
|
|
static void scheduledCheckCallback(TimerHandle_t xTimer);
|
|
|
|
void setStatus(Status status, ErrorCode error = ErrorCode::NONE);
|
|
void notifyProgress(size_t current, size_t total);
|
|
bool checkVersion();
|
|
bool checkVersion(const String& channel);
|
|
bool checkChannelsMetadata();
|
|
bool downloadAndInstall();
|
|
bool downloadAndInstall(const String& channel);
|
|
bool downloadToSD(const String& url, const String& expectedChecksum, size_t expectedSize); // NEW: Added size param
|
|
bool verifyChecksum(const String& filePath, const String& expectedChecksum);
|
|
String calculateSHA256(const String& filePath);
|
|
bool installFromSD(const String& filePath);
|
|
String buildChannelUrl(const String& channel) const;
|
|
String buildMetadataUrl(const String& channel) const;
|
|
String buildFirmwareUrl(const String& channel) const;
|
|
|
|
// NEW: Helper methods
|
|
bool isPlayerActive() const;
|
|
bool checkAvailableSpace(size_t requiredBytes) const;
|
|
};
|