1. 优化了cpp_json的内容,使其更modern
2. 稍微优化了一下系统配置类 3. 增加了系统版本号,便于区分系统版本,方便OTA 4. 重写OTA的逻辑,完成了Cpp的OTA封装,测试通过
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
//
|
||||
// Created by misaki on 2025/9/24.
|
||||
//
|
||||
#pragma once
|
||||
#include <esp_https_ota.h>
|
||||
#include <esp_ota_ops.h>
|
||||
#include <esp_log.h>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include "ThreadManager.h"
|
||||
|
||||
class HttpOtaUpdater {
|
||||
public:
|
||||
// OTA状态枚举
|
||||
enum class OtaState {
|
||||
IDLE, // 空闲状态
|
||||
CONNECTING, // 连接中
|
||||
DOWNLOADING, // 下载中
|
||||
VERIFYING, // 验证中
|
||||
SUCCESS, // 成功
|
||||
FAILED // 失败
|
||||
};
|
||||
|
||||
// 进度回调函数类型
|
||||
using ProgressCallback = std::function<void(int progress, int total)>;
|
||||
// 状态回调函数类型
|
||||
using StateCallback = std::function<void(OtaState state, const std::string& message)>;
|
||||
// 完成回调函数类型
|
||||
using FinishCallback = std::function<void(bool success, const std::string& message)>;
|
||||
|
||||
/**
|
||||
* @brief 构造函数
|
||||
*/
|
||||
HttpOtaUpdater();
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~HttpOtaUpdater();
|
||||
|
||||
/**
|
||||
* @brief 开始OTA升级
|
||||
* @param url HTTP下载链接
|
||||
* @return true-成功开始升级,false-失败
|
||||
*/
|
||||
bool start(const std::string& url);
|
||||
|
||||
/**
|
||||
* @brief 停止OTA升级
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* @brief 检查是否正在升级
|
||||
* @return true-正在升级,false-空闲
|
||||
*/
|
||||
[[nodiscard]] bool isUpdating() const;
|
||||
|
||||
/**
|
||||
* @brief 设置进度回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void setProgressCallback(const ProgressCallback &callback);
|
||||
|
||||
/**
|
||||
* @brief 设置状态回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void setStateCallback(const StateCallback &callback);
|
||||
|
||||
/**
|
||||
* @brief 设置完成回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void setFinishCallback(const FinishCallback &callback);
|
||||
|
||||
/**
|
||||
* @brief 设置CA证书(用于HTTPS,保留供后期使用)
|
||||
* @param cert_pem PEM格式的证书内容
|
||||
*/
|
||||
void setCACert(const char* cert_pem);
|
||||
|
||||
/**
|
||||
* @brief 跳过证书通用名检查(仅用于测试,保留供后期使用)
|
||||
* @param skip true-跳过检查,false-不跳过
|
||||
*/
|
||||
void skipCertCommonNameCheck(bool skip);
|
||||
|
||||
/**
|
||||
* @brief 获取当前状态
|
||||
* @return 当前OTA状态
|
||||
*/
|
||||
[[nodiscard]] OtaState getCurrentState() const;
|
||||
|
||||
/**
|
||||
* @brief 获取错误信息
|
||||
* @return 错误信息字符串
|
||||
*/
|
||||
[[nodiscard]] std::string getErrorMessage() const;
|
||||
|
||||
// 禁止拷贝和赋值
|
||||
HttpOtaUpdater(const HttpOtaUpdater&) = delete;
|
||||
HttpOtaUpdater& operator=(const HttpOtaUpdater&) = delete;
|
||||
private:
|
||||
/**
|
||||
* @brief OTA任务主函数
|
||||
*/
|
||||
void otaTask();
|
||||
|
||||
/**
|
||||
* @brief 执行OTA升级
|
||||
* @param url 下载链接
|
||||
*/
|
||||
void performOta(const std::string& url);
|
||||
|
||||
/**
|
||||
* @brief 更新状态
|
||||
* @param state 新状态
|
||||
* @param message 状态信息
|
||||
*/
|
||||
void updateState(OtaState state, const std::string& message = "");
|
||||
|
||||
/**
|
||||
* @brief HTTPS OTA事件处理函数
|
||||
* @param event 事件
|
||||
*/
|
||||
static esp_err_t httpEventHandle(esp_http_client_event_t* event);
|
||||
|
||||
// 成员变量
|
||||
std::string m_url; ///<! 下载链接
|
||||
OtaState m_currentState; ///<! 当前状态
|
||||
std::string m_errorMessage; ///<! 错误信息
|
||||
bool m_isUpdating; ///<! 是否正在升级
|
||||
std::thread m_otaThread; ///<! OTA线程
|
||||
|
||||
// HTTP配置(保留供后期使用)
|
||||
const char* m_cert_pem; ///<! CA证书
|
||||
bool m_skip_cert_common_name_check; ///<! 跳过证书通用名检查
|
||||
|
||||
// 回调函数
|
||||
ProgressCallback m_progressCallback;///<! 进度回调
|
||||
StateCallback m_stateCallback; ///<! 状态回调
|
||||
FinishCallback m_finishCallback; ///<! 完成回调
|
||||
|
||||
// 进度相关变量
|
||||
int m_totalSize; ///<! 总大小
|
||||
int m_downloadedSize; ///<! 已下载大小
|
||||
|
||||
// 日志标签
|
||||
static constexpr auto TAG = "HttpOtaUpdater";
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** 使用示例
|
||||
// 创建全局OTA更新器实例
|
||||
HttpOtaUpdater otaUpdater;
|
||||
|
||||
void setupOtaCallbacks() {
|
||||
// 设置进度回调
|
||||
otaUpdater.setProgressCallback([](int progress, int total) {
|
||||
ESP_LOGI("OTA", "Progress: %d%%", progress);
|
||||
});
|
||||
|
||||
// 设置状态回调
|
||||
otaUpdater.setStateCallback([](HttpOtaUpdater::OtaState state, const std::string& message) {
|
||||
const char* stateNames[] = {
|
||||
"IDLE", "CONNECTING", "DOWNLOADING", "VERIFYING", "SUCCESS", "FAILED"
|
||||
};
|
||||
ESP_LOGI("OTA", "State: %s - %s", stateNames[static_cast<int>(state)], message.c_str());
|
||||
});
|
||||
|
||||
// 设置完成回调
|
||||
otaUpdater.setFinishCallback([](bool success, const std::string& message) {
|
||||
if (success) {
|
||||
ESP_LOGI("OTA", "Completed successfully: %s", message.c_str());
|
||||
} else {
|
||||
ESP_LOGE("OTA", "Failed: %s", message.c_str());
|
||||
}
|
||||
});
|
||||
|
||||
// 如果需要HTTPS,可以在这里设置证书(保留供后期使用)
|
||||
// otaUpdater.setCACert(my_ca_cert_pem);
|
||||
// otaUpdater.skipCertCommonNameCheck(true); // 仅用于测试
|
||||
}
|
||||
|
||||
// 在websocket消息处理函数中调用
|
||||
void onOtaUrlReceived(const std::string& otaUrl) {
|
||||
ESP_LOGI("OTA", "Received OTA URL: %s", otaUrl.c_str());
|
||||
|
||||
if (otaUpdater.isUpdating()) {
|
||||
ESP_LOGW("OTA", "OTA update is already in progress");
|
||||
return;
|
||||
}
|
||||
|
||||
if (otaUpdater.start(otaUrl)) {
|
||||
ESP_LOGI("OTA", "OTA update started successfully");
|
||||
} else {
|
||||
ESP_LOGE("OTA", "Failed to start OTA update");
|
||||
}
|
||||
}
|
||||
|
||||
// 检查OTA状态
|
||||
void checkOtaStatus() {
|
||||
if (otaUpdater.isUpdating()) {
|
||||
ESP_LOGI("OTA", "OTA update in progress, state: %d",
|
||||
static_cast<int>(otaUpdater.getCurrentState()));
|
||||
} else {
|
||||
ESP_LOGI("OTA", "No OTA update in progress");
|
||||
}
|
||||
|
||||
std::string error = otaUpdater.getErrorMessage();
|
||||
if (!error.empty()) {
|
||||
ESP_LOGE("OTA", "Last error: %s", error.c_str());
|
||||
}
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user