forked from xiaozhi/xiaozhi-esp32
Allow force OTA upgrade to a previous version
This commit is contained in:
@@ -10,7 +10,7 @@ dependencies:
|
|||||||
78/esp_lcd_nv3023: "~1.0.0"
|
78/esp_lcd_nv3023: "~1.0.0"
|
||||||
78/esp-wifi-connect: "~2.3.2"
|
78/esp-wifi-connect: "~2.3.2"
|
||||||
78/esp-opus-encoder: "~2.3.1"
|
78/esp-opus-encoder: "~2.3.1"
|
||||||
78/esp-ml307: "~1.8.1"
|
78/esp-ml307: "~1.9.0"
|
||||||
78/xiaozhi-fonts: "~1.3.2"
|
78/xiaozhi-fonts: "~1.3.2"
|
||||||
espressif/led_strip: "^2.4.1"
|
espressif/led_strip: "^2.4.1"
|
||||||
espressif/esp_codec_dev: "~1.3.2"
|
espressif/esp_codec_dev: "~1.3.2"
|
||||||
|
|||||||
61
main/ota.cc
61
main/ota.cc
@@ -10,7 +10,9 @@
|
|||||||
#include <esp_app_format.h>
|
#include <esp_app_format.h>
|
||||||
#include <esp_efuse.h>
|
#include <esp_efuse.h>
|
||||||
#include <esp_efuse_table.h>
|
#include <esp_efuse_table.h>
|
||||||
|
#ifdef SOC_HMAC_SUPPORTED
|
||||||
#include <esp_hmac.h>
|
#include <esp_hmac.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -23,6 +25,7 @@
|
|||||||
Ota::Ota() {
|
Ota::Ota() {
|
||||||
SetCheckVersionUrl(CONFIG_OTA_VERSION_URL);
|
SetCheckVersionUrl(CONFIG_OTA_VERSION_URL);
|
||||||
|
|
||||||
|
#ifdef ESP_EFUSE_BLOCK_USR_DATA
|
||||||
// Read Serial Number from efuse user_data
|
// Read Serial Number from efuse user_data
|
||||||
uint8_t serial_number[33] = {0};
|
uint8_t serial_number[33] = {0};
|
||||||
if (esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA, serial_number, 32 * 8) == ESP_OK) {
|
if (esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA, serial_number, 32 * 8) == ESP_OK) {
|
||||||
@@ -33,6 +36,7 @@ Ota::Ota() {
|
|||||||
has_serial_number_ = true;
|
has_serial_number_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Ota::~Ota() {
|
Ota::~Ota() {
|
||||||
@@ -89,7 +93,6 @@ bool Ota::CheckVersion() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data = http->GetBody();
|
data = http->GetBody();
|
||||||
http->Close();
|
|
||||||
delete http;
|
delete http;
|
||||||
|
|
||||||
// Response: { "firmware": { "version": "1.0.0", "url": "http://" } }
|
// Response: { "firmware": { "version": "1.0.0", "url": "http://" } }
|
||||||
@@ -164,36 +167,34 @@ bool Ota::CheckVersion() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
has_new_version_ = false;
|
||||||
cJSON *firmware = cJSON_GetObjectItem(root, "firmware");
|
cJSON *firmware = cJSON_GetObjectItem(root, "firmware");
|
||||||
if (firmware == NULL) {
|
if (firmware != NULL) {
|
||||||
ESP_LOGE(TAG, "Failed to get firmware object");
|
cJSON *version = cJSON_GetObjectItem(firmware, "version");
|
||||||
cJSON_Delete(root);
|
if (version != NULL) {
|
||||||
return false;
|
firmware_version_ = version->valuestring;
|
||||||
}
|
}
|
||||||
cJSON *version = cJSON_GetObjectItem(firmware, "version");
|
cJSON *url = cJSON_GetObjectItem(firmware, "url");
|
||||||
if (version == NULL) {
|
if (url != NULL) {
|
||||||
ESP_LOGE(TAG, "Failed to get version object");
|
firmware_url_ = url->valuestring;
|
||||||
cJSON_Delete(root);
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cJSON *url = cJSON_GetObjectItem(firmware, "url");
|
|
||||||
if (url == NULL) {
|
|
||||||
ESP_LOGE(TAG, "Failed to get url object");
|
|
||||||
cJSON_Delete(root);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
firmware_version_ = version->valuestring;
|
if (version != NULL && url != NULL) {
|
||||||
firmware_url_ = url->valuestring;
|
// Check if the version is newer, for example, 0.1.0 is newer than 0.0.1
|
||||||
|
has_new_version_ = IsNewVersionAvailable(current_version_, firmware_version_);
|
||||||
|
if (has_new_version_) {
|
||||||
|
ESP_LOGI(TAG, "New version available: %s", firmware_version_.c_str());
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "Current is the latest version");
|
||||||
|
}
|
||||||
|
// If the force flag is set to 1, the given version is forced to be installed
|
||||||
|
cJSON *force = cJSON_GetObjectItem(firmware, "force");
|
||||||
|
if (force != NULL && force->valueint == 1) {
|
||||||
|
has_new_version_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
|
|
||||||
// Check if the version is newer, for example, 0.1.0 is newer than 0.0.1
|
|
||||||
has_new_version_ = IsNewVersionAvailable(current_version_, firmware_version_);
|
|
||||||
if (has_new_version_) {
|
|
||||||
ESP_LOGI(TAG, "New version available: %s", firmware_version_.c_str());
|
|
||||||
} else {
|
|
||||||
ESP_LOGI(TAG, "Current is the latest version");
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,6 +367,8 @@ std::string Ota::GetActivationPayload() {
|
|||||||
return "{}";
|
return "{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string hmac_hex;
|
||||||
|
#ifdef SOC_HMAC_SUPPORTED
|
||||||
uint8_t hmac_result[32]; // SHA-256 输出为32字节
|
uint8_t hmac_result[32]; // SHA-256 输出为32字节
|
||||||
|
|
||||||
// 使用Key0计算HMAC
|
// 使用Key0计算HMAC
|
||||||
@@ -375,12 +378,12 @@ std::string Ota::GetActivationPayload() {
|
|||||||
return "{}";
|
return "{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string hmac_hex;
|
|
||||||
for (size_t i = 0; i < sizeof(hmac_result); i++) {
|
for (size_t i = 0; i < sizeof(hmac_result); i++) {
|
||||||
char buffer[3];
|
char buffer[3];
|
||||||
sprintf(buffer, "%02x", hmac_result[i]);
|
sprintf(buffer, "%02x", hmac_result[i]);
|
||||||
hmac_hex += buffer;
|
hmac_hex += buffer;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
cJSON *payload = cJSON_CreateObject();
|
cJSON *payload = cJSON_CreateObject();
|
||||||
cJSON_AddStringToObject(payload, "algorithm", "hmac-sha256");
|
cJSON_AddStringToObject(payload, "algorithm", "hmac-sha256");
|
||||||
|
|||||||
Reference in New Issue
Block a user