#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; }