Use the sha256 in the application version to see if it's a different version. Stop the upgrade download if it's not a new version.

Fri, 05 Jul 2019 20:06:31 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Fri, 05 Jul 2019 20:06:31 +0200
changeset 67
4badc7e7d629
parent 65
dd7019356c8c
child 68
24bd8f7e386e

Use the sha256 in the application version to see if it's a different version. Stop the upgrade download if it's not a new version.

main/updates.c file | annotate | diff | comparison | revisions
--- a/main/updates.c	Fri Jul 05 16:14:58 2019 +0200
+++ b/main/updates.c	Fri Jul 05 20:06:31 2019 +0200
@@ -36,9 +36,9 @@
     TFT_setFont(DEJAVU18_FONT, NULL);
     _fg = TFT_CYAN;
     const esp_partition_t       *running = esp_ota_get_running_partition();
-    snprintf(temp, 63, "Running part.type %d sub %d,\r\nat offset 0x%08x\r\n",
-		running->type, running->subtype, running->address);
-    TFT_print(temp, 0, LASTY);
+//    snprintf(temp, 63, "Running part.type %d sub %d,\r\nat offset 0x%08x\r\n",
+//		running->type, running->subtype, running->address);
+//    TFT_print(temp, 0, LASTY);
 
     /*
      * Don't use https because it costs more then 100K memory.
@@ -82,10 +82,11 @@
 	goto updateerr;
     }
 
-    TFT_print((char *)"Begin download.\r\n", 0, LASTY);
+    TFT_print((char *)"Begin firmware download.\r\n", 0, LASTY);
     ESP_LOGI(TAG, "Download update %s size %d", update.url, content_length);
     int binary_file_length = 0;
     /*deal with all receive packet*/
+    bool image_header_was_checked = false;
     while (1) {
 	int data_read = esp_http_client_read(client, ota_write_data, BUFFSIZE);
 	if (data_read < 0) {
@@ -93,13 +94,62 @@
 	    http_cleanup(client);
 	    goto updateerr;;
 	} else if (data_read > 0) {
+	    if (image_header_was_checked == false) {
+		esp_app_desc_t new_app_info;
+                if (data_read > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) {
+                    // check current version with downloading
+                    memcpy(&new_app_info, &ota_write_data[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t));
+
+                    esp_app_desc_t running_app_info;
+                    if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) {
+                        ESP_LOGI(TAG, "Running firmware version: %s, %s %s", running_app_info.version, running_app_info.date, running_app_info.time);
+                    }
+
+                    const esp_partition_t* last_invalid_app = esp_ota_get_last_invalid_partition();
+                    esp_app_desc_t invalid_app_info;
+                    if (esp_ota_get_partition_description(last_invalid_app, &invalid_app_info) == ESP_OK) {
+                        ESP_LOGI(TAG, "Last invalid firmware version: %s", invalid_app_info.version);
+                    }
+
+                    // check current sha256 with last invalid partition
+                    if (last_invalid_app != NULL) {
+                        if (memcmp(invalid_app_info.app_elf_sha256, new_app_info.app_elf_sha256, 32) == 0) {
+                            ESP_LOGW(TAG, "New version is the same as invalid version.");
+                            ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version);
+                            ESP_LOGW(TAG, "The firmware has been rolled back to the previous version.");
+                            http_cleanup(client);
+			    goto updateok;
+                        }
+                    }
+
+		    if (memcmp(new_app_info.app_elf_sha256, running_app_info.app_elf_sha256, 32) == 0) {
+                        ESP_LOGI(TAG, "Current running version is the same as a new.");
+                        http_cleanup(client);
+			goto updateok;
+                    }
+
+                    image_header_was_checked = true;
+
+                    err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
+                    if (err != ESP_OK) {
+                        ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
+                        http_cleanup(client);
+			goto updateerr;
+                    }
+                    ESP_LOGI(TAG, "Continue upgrade application");
+                } else {
+                    ESP_LOGE(TAG, "Received package is not fit len");
+                    http_cleanup(client);
+		    goto updateerr;
+                }
+	    }
 	    err = esp_ota_write( update_handle, (const void *)ota_write_data, data_read);
 	    if (err != ESP_OK) {
 		http_cleanup(client);
 		goto updateerr;;
 	    }
 	    binary_file_length += data_read;
-//	    ESP_LOGD(TAG, "Written image length %d", binary_file_length);
+	    ESP_LOGD(TAG, "Written image length %d", binary_file_length);
 	} else if (data_read == 0) {
 	    break;
 	}
@@ -108,6 +158,10 @@
     ESP_LOGI(TAG, "Download complete, binary data length: %d", binary_file_length);
     http_cleanup(client);
 
+    if (binary_file_length != content_length) {
+	ESP_LOGE(TAG, "Incomplete file");
+	goto updateerr;
+    }
     if (esp_ota_end(update_handle) != ESP_OK) {
 	ESP_LOGE(TAG, "esp_ota_end failed!");
 	goto updateerr;
@@ -115,14 +169,8 @@
     snprintf(temp, 63, "Received image %d bytes\r\n", binary_file_length);
     TFT_print(temp, 0, LASTY);
 
-    if (esp_partition_check_identity(esp_ota_get_running_partition(), update_partition) == true) {
-	ESP_LOGI(TAG, "Already the latest version");
-	TFT_print((char *)"Already the latest version.\r\n", LASTX, LASTY);
-	goto updateok;
-    }
-
     /*
-     * Here we have a different and hopefully newer version, install and boot it.
+     * Here we have new version, install and boot it.
      */
     err = esp_ota_set_boot_partition(update_partition);
     if (err != ESP_OK) {
@@ -134,7 +182,7 @@
     TFT_print((char *)"Rebooting ...", 0, LASTY);
     vTaskDelay(1000 / portTICK_PERIOD_MS);
     esp_restart();
-    return ;
+    return;
 
 updateerr:
     _fg = TFT_RED;
@@ -306,7 +354,6 @@
 	    fclose(f);
 	    goto spiffs_error;
 	}
-//	vTaskDelay(10 / portTICK_PERIOD_MS);
     }
     fclose(f);
     unlink("/spiffs/version.old");
@@ -316,7 +363,6 @@
 spiffs_error:
     _fg = TFT_RED;
     TFT_print((char *)"error\r\n", LASTX, LASTY);
-
 }
 
 

mercurial