better handle the 304 and 400 case

This commit is contained in:
nick-4711
2024-04-25 16:11:49 +07:00
parent 1c8d7b04e9
commit b2c55c38dc

View File

@ -9,6 +9,13 @@
#define OTA_BUF_SIZE 512 #define OTA_BUF_SIZE 512
#define URL_BUF_SIZE 256 #define URL_BUF_SIZE 256
enum OtaUpdateOutcome {
UPDATE_PERFORMED,
ALREADY_UP_TO_DATE,
UPDATE_FAILED,
UDPATE_SKIPPED
};
class OtaHandler { class OtaHandler {
public: public:
@ -20,45 +27,54 @@ public:
url += GIT_VERSION; url += GIT_VERSION;
char urlAsChar[URL_BUF_SIZE]; char urlAsChar[URL_BUF_SIZE];
url.toCharArray(urlAsChar, URL_BUF_SIZE); url.toCharArray(urlAsChar, URL_BUF_SIZE);
Serial.printf("checking for new ota @ %s\n", urlAsChar); Serial.printf("checking for new OTA update @ %s\n", urlAsChar);
esp_http_client_config_t config = {}; esp_http_client_config_t config = {};
config.url = urlAsChar; config.url = urlAsChar;
esp_err_t ret = attemptToPerformOta(&config); esp_err_t ret = attemptToPerformOta(&config);
Serial.println(ret); Serial.println(ret);
if (ret == 0) { if (ret == OtaUpdateOutcome::UPDATE_PERFORMED) {
Serial.println("OTA completed"); Serial.println("OTA update performed, restarting ...");
esp_restart(); esp_restart();
} else {
Serial.println("OTA failed, maybe already up to date");
} }
} }
private: private:
int attemptToPerformOta(const esp_http_client_config_t *config) { OtaUpdateOutcome attemptToPerformOta(const esp_http_client_config_t *config) {
esp_http_client_handle_t client = esp_http_client_init(config); esp_http_client_handle_t client = esp_http_client_init(config);
if (client == NULL) { if (client == NULL) {
Serial.println("Failed to initialize HTTP connection"); Serial.println("Failed to initialize HTTP connection");
return -1; return OtaUpdateOutcome::UPDATE_FAILED;
} }
esp_err_t err = esp_http_client_open(client, 0); esp_err_t err = esp_http_client_open(client, 0);
if (err != ESP_OK) { if (err != ESP_OK) {
esp_http_client_cleanup(client); esp_http_client_cleanup(client);
Serial.printf("Failed to open HTTP connection: %s\n", esp_err_to_name(err)); Serial.printf("Failed to open HTTP connection: %s\n", esp_err_to_name(err));
return -1; return OtaUpdateOutcome::UPDATE_FAILED;
} }
esp_http_client_fetch_headers(client); esp_http_client_fetch_headers(client);
int httpStatusCode = esp_http_client_get_status_code(client);
if (httpStatusCode == 304) {
Serial.println("Firmware is already up to date");
cleanupHttp(client);
return OtaUpdateOutcome::ALREADY_UP_TO_DATE;
} else if (httpStatusCode != 200) {
Serial.printf("Firmware update skipped, the server returned %d\n", httpStatusCode);
cleanupHttp(client);
return OtaUpdateOutcome::UDPATE_SKIPPED;
}
esp_ota_handle_t update_handle = 0; esp_ota_handle_t update_handle = 0;
const esp_partition_t *update_partition = NULL; const esp_partition_t *update_partition = NULL;
Serial.println("Starting OTA ..."); Serial.println("Starting OTA update ...");
update_partition = esp_ota_get_next_update_partition(NULL); update_partition = esp_ota_get_next_update_partition(NULL);
if (update_partition == NULL) { if (update_partition == NULL) {
Serial.println("Passive OTA partition not found"); Serial.println("Passive OTA partition not found");
cleanupHttp(client); cleanupHttp(client);
return ESP_FAIL; return OtaUpdateOutcome::UPDATE_FAILED;
} }
Serial.printf("Writing to partition subtype %d at offset 0x%x\n", Serial.printf("Writing to partition subtype %d at offset 0x%x\n",
update_partition->subtype, update_partition->address); update_partition->subtype, update_partition->address);
@ -67,14 +83,14 @@ private:
if (err != ESP_OK) { if (err != ESP_OK) {
Serial.printf("esp_ota_begin failed, error=%d\n", err); Serial.printf("esp_ota_begin failed, error=%d\n", err);
cleanupHttp(client); cleanupHttp(client);
return err; return OtaUpdateOutcome::UPDATE_FAILED;
} }
esp_err_t ota_write_err = ESP_OK; esp_err_t ota_write_err = ESP_OK;
char *upgrade_data_buf = (char *)malloc(OTA_BUF_SIZE); char *upgrade_data_buf = (char *)malloc(OTA_BUF_SIZE);
if (!upgrade_data_buf) { if (!upgrade_data_buf) {
Serial.println("Couldn't allocate memory for data buffer"); Serial.println("Couldn't allocate memory for data buffer");
return ESP_ERR_NO_MEM; return OtaUpdateOutcome::UPDATE_FAILED;
} }
int binary_file_len = 0; int binary_file_len = 0;
@ -104,18 +120,18 @@ private:
esp_err_t ota_end_err = esp_ota_end(update_handle); esp_err_t ota_end_err = esp_ota_end(update_handle);
if (ota_write_err != ESP_OK) { if (ota_write_err != ESP_OK) {
Serial.printf("Error: esp_ota_write failed! err=0x%d\n", err); Serial.printf("Error: esp_ota_write failed! err=0x%d\n", err);
return ota_write_err; return OtaUpdateOutcome::UPDATE_FAILED;
} else if (ota_end_err != ESP_OK) { } else if (ota_end_err != ESP_OK) {
Serial.printf("Error: esp_ota_end failed! err=0x%d. Image is invalid", ota_end_err); Serial.printf("Error: esp_ota_end failed! err=0x%d. Image is invalid", ota_end_err);
return ota_end_err; return OtaUpdateOutcome::UPDATE_FAILED;
} }
err = esp_ota_set_boot_partition(update_partition); err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK) { if (err != ESP_OK) {
Serial.printf("esp_ota_set_boot_partition failed! err=0x%d\n", err); Serial.printf("esp_ota_set_boot_partition failed! err=0x%d\n", err);
return err; return OtaUpdateOutcome::UPDATE_FAILED;
} }
return 0; return OtaUpdateOutcome::UPDATE_PERFORMED;
} }
void cleanupHttp(esp_http_client_handle_t client) { void cleanupHttp(esp_http_client_handle_t client) {