Sun, 17 Nov 2019 12:58:39 +0100
Temporary white splash screen. Select DS18B20 sensor per unit. Changed units result logging
/** * @file updates.c * @brief Updates management. It can download and install new firmware * downloaded from the internet. */ #include "config.h" #define BUFFSIZE 1024 ///< Download buffer size static char ota_write_data[BUFFSIZE + 1] = { 0 }; static const char *TAG = "update"; int update_running = 0; ///< Not zero if update is running. extern u8g2_t u8g2; ///< Structure for the display. extern int Main_Loop1; static void http_cleanup(esp_http_client_handle_t client) { esp_http_client_close(client); esp_http_client_cleanup(client); } /** * @brief Run binary update procedure */ void bin_update(void) { char temp[64]; esp_err_t err; const esp_partition_t *update_partition = NULL; esp_ota_handle_t update_handle = 0; int timeout = 600; ESP_LOGI(TAG, "Update begin"); update_running = 1; screen_updating("Stop meten", NULL); for (;;) { vTaskDelay(100 / portTICK_PERIOD_MS); if (Main_Loop1 == ML1_DONE) break; if (timeout) timeout--; else { ESP_LOGE(TAG, "Timout request stop"); goto updateerr; } } screen_updating("Stop meten", "Start WiFi"); requestWiFi_user(true); timeout = 600; for (;;) { vTaskDelay(100 / portTICK_PERIOD_MS); if (ready_WiFi()) break; if (timeout) timeout--; else { ESP_LOGE(TAG, "Timout request WiFi"); goto updateerr; } } ESP_LOGI(TAG, "System is ready for update"); screen_updating("Verbonden", NULL); const esp_partition_t *running = esp_ota_get_running_partition(); /* * Don't use https because it costs more then 100K memory. */ esp_http_client_config_t update = { .url = "http://update.mbse.eu/ap2/fw/co2meter.bin", }; esp_http_client_handle_t client = esp_http_client_init(&update); if (client == NULL) { ESP_LOGI(TAG, "Failed to init HTTP connection"); goto updateerr; } err = esp_http_client_open(client, 0); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err)); esp_http_client_cleanup(client); goto updateerr; } int content_length = esp_http_client_fetch_headers(client); int status_code = esp_http_client_get_status_code(client); if (status_code != 200) { ESP_LOGE(TAG, "GET %s error %d", update.url, status_code); esp_http_client_cleanup(client); goto updateerr; } update_partition = esp_ota_get_next_update_partition(NULL); if (update_partition == NULL) { ESP_LOGE(TAG, "No update partition"); esp_http_client_cleanup(client); goto updateerr; } ESP_LOGI(TAG, "Update to partition subtype %d at offset 0x%x", update_partition->subtype, update_partition->address); 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; } screen_updating("Begin download", NULL); 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) { ESP_LOGE(TAG, "Error: data read error"); 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) { screen_updating("Geen nieuwe versie", NULL); 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); } else if (data_read == 0) { break; } } 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; } snprintf(temp, 63, "Ok %d bytes", binary_file_length); screen_updating("Begin download", temp); /* * Here we have new version, install and boot it. */ err = esp_ota_set_boot_partition(update_partition); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); goto updateerr; } ESP_LOGI(TAG, "Prepare to restart system!"); screen_updating("Herstar ...", "... Herstart"); vTaskDelay(1000 / portTICK_PERIOD_MS); update_running = 0; esp_restart(); return; updateerr: screen_updating("** FOUT **", "Update mislukt"); updateok: update_running = 0; requestWiFi_user(false); vTaskDelay(3000 / portTICK_PERIOD_MS); }