| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- #include "OTAUpdater.h"
- // 使用 extern 声明全局变量
- extern String serverAddress;
- extern String deviceID;
- OTAUpdater::OTAUpdater(uint16_t port, const String& currentVersion)
- : _port(port), _currentVersion(currentVersion) {} // 移除 _serverUrl 初始化
- void OTAUpdater::checkForUpdates() {
- // 添加调试信息,打印设备ID
- Serial.println("设备ID: " + deviceID); // 确保设备ID被正确传递
- // 检查 WiFi 连接状态
- while (true) {
- // 尝试连接 WiFi,超时时间为 30 秒
- if (connectWiFiWithTimeout(30000)) {
- Serial.println("[信息] Wi-Fi 连接成功。");
- break; // 连接成功,退出循环
- } else {
- Serial.println("[信息] Wi-Fi 连接失败,进入配置模式...");
- setupWiFiConfig(); // 进入配置模式,超时时间为 60 秒
- }
- }
- Serial.println("正在检查更新...");
- // 构建完整的 OTA 服务器 URL,使用全局变量 serverAddress 和 _port
- String fullServerUrl = "http://" + serverAddress + ":" + otaPort;
- Serial.println("OTA 服务器地址: " + fullServerUrl);
- // 向服务器发送设备ID和当前固件版本,检查是否有更新
- HTTPClient http;
- String checkUpdateUrl = fullServerUrl + "/check-update";
- http.begin(checkUpdateUrl);
- http.addHeader("Content-Type", "application/json");
- // 构建JSON请求体
- String json = "{\"device_id\":\"" + deviceID + "\",\"version\":\"" + _currentVersion + "\"}";
- http.addHeader("Content-Type", "application/json");
- int httpCode = http.POST(json);
-
- // 处理响应
- if (httpCode == HTTP_CODE_OK) {
- String response = http.getString();
- if (response == "update") {
- Serial.println("发现新固件,开始下载...");
- if (downloadAndUpdateFirmware()) {
- Serial.println("固件更新成功,即将重启...");
- delay(1000);
- Serial.println("1秒后重启...");
- delay(1000);
- ESP.restart();
- }
- } else {
- Serial.println("无可用更新");
- }
- } else {
- Serial.println("检查更新失败,HTTP错误代码: " + String(httpCode));
- }
- http.end();
- }
- bool OTAUpdater::downloadAndUpdateFirmware() {
- // 构建完整的 OTA 服务器 URL,使用全局变量 serverAddress 和 _port
- String fullServerUrl = "http://" + serverAddress + ":" + otaPort;
- String firmwareUrl = fullServerUrl + "/firmware";
- HTTPClient http;
- http.begin(firmwareUrl);
- // 设置 HTTP 超时时间(单位:毫秒)
- http.setTimeout(20000); // 20秒超时
- int httpCode = http.GET();
- if (httpCode == HTTP_CODE_OK) {
- // 获取固件文件大小
- int contentLength = http.getSize();
- if (contentLength <= 0) {
- Serial.println("无效的固件文件大小。");
- http.end();
- return false;
- }
- // 开始更新
- if (Update.begin(contentLength)) {
- // 获取数据流
- WiFiClient* stream = http.getStreamPtr();
- // 设置数据流超时时间(单位:毫秒)
- stream->setTimeout(20000); // 20秒超时
- // 记录下载开始时间
- unsigned long startTime = millis();
- size_t written = 0;
- // 分块下载固件数据
- while (written < contentLength) {
- // 检查是否超时
- if (millis() - startTime > 20000) { // 20秒超时
- Serial.println("下载超时,中断更新。");
- http.end();
- Update.end(false); // 结束更新并标记为失败
- return false;
- }
- // 读取数据块
- size_t available = stream->available();
- if (available > 0) {
- uint8_t buffer[128]; // 缓冲区大小
- size_t read = stream->readBytes(buffer, min(sizeof(buffer), available));
- written += Update.write(buffer, read);
- } else {
- // 如果没有数据,等待一段时间
- delay(100);
- }
- }
- // 检查是否下载完成
- if (written == contentLength) {
- Serial.println("固件写入成功。");
- } else {
- Serial.println("固件写入失败。");
- http.end();
- Update.end(false); // 结束更新并标记为失败
- return false;
- }
- // 结束更新
- if (Update.end()) {
- Serial.println("固件更新完成。");
- http.end();
- return true;
- } else {
- Serial.println("固件更新结束失败。");
- http.end();
- return false;
- }
- } else {
- Serial.println("空间不足,无法开始OTA更新。");
- http.end();
- return false;
- }
- } else {
- Serial.println("下载固件失败,HTTP错误代码: " + String(httpCode));
- http.end();
- return false;
- }
- http.end();
- return false;
- }
|