OTA procedure is functional
This commit is contained in:
		@@ -2,15 +2,25 @@
 | 
			
		||||
#include "esp_partition.h"
 | 
			
		||||
#include "esp_ota_ops.h"
 | 
			
		||||
#include "esp_http_client.h"
 | 
			
		||||
#include "esp_app_format.h"
 | 
			
		||||
#include "constants.h"
 | 
			
		||||
 | 
			
		||||
#include "ota.h"
 | 
			
		||||
#include "storage.h"
 | 
			
		||||
#include "secure_api.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
const char *TAG = "ota";
 | 
			
		||||
 | 
			
		||||
#define BUFF_SIZE 1024
 | 
			
		||||
 | 
			
		||||
static void http_cleanup(esp_http_client_handle_t client)
 | 
			
		||||
{
 | 
			
		||||
    esp_http_client_close(client);
 | 
			
		||||
    esp_http_client_cleanup(client);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ota_perform_update(const char *version)
 | 
			
		||||
{
 | 
			
		||||
    const esp_partition_t *configured = esp_ota_get_boot_partition();
 | 
			
		||||
@@ -72,5 +82,151 @@ bool ota_perform_update(const char *version)
 | 
			
		||||
    ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%" PRIx32,
 | 
			
		||||
             update_partition->subtype, update_partition->address);
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
    // OTA update loop
 | 
			
		||||
    int binary_file_length = 0;
 | 
			
		||||
    esp_ota_handle_t update_handle = 0;
 | 
			
		||||
    /*deal with all receive packet*/
 | 
			
		||||
    bool image_header_was_checked = false;
 | 
			
		||||
    char *ota_write_data = calloc(BUFF_SIZE + 1, 1);
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        int data_read = esp_http_client_read(client, ota_write_data, BUFF_SIZE);
 | 
			
		||||
        if (data_read < 0)
 | 
			
		||||
        {
 | 
			
		||||
            ESP_LOGE(TAG, "Error: SSL data read error");
 | 
			
		||||
            http_cleanup(client);
 | 
			
		||||
            free(ota_write_data);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (data_read == 0)
 | 
			
		||||
        {
 | 
			
		||||
            /*
 | 
			
		||||
             * As esp_http_client_read never returns negative error code, we rely on
 | 
			
		||||
             * `errno` to check for underlying transport connectivity closure if any
 | 
			
		||||
             */
 | 
			
		||||
            if (errno == ECONNRESET || errno == ENOTCONN)
 | 
			
		||||
            {
 | 
			
		||||
                ESP_LOGE(TAG, "Connection closed, errno = %d", errno);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            if (esp_http_client_is_complete_data_received(client) == true)
 | 
			
		||||
            {
 | 
			
		||||
                ESP_LOGI(TAG, "Connection closed");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // No data received yet
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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_LOGI(TAG, "New firmware version: %s", new_app_info.version);
 | 
			
		||||
 | 
			
		||||
                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", running_app_info.version);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                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 version with last invalid partition
 | 
			
		||||
                if (last_invalid_app != NULL)
 | 
			
		||||
                {
 | 
			
		||||
                    if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 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);
 | 
			
		||||
                        free(ota_write_data);
 | 
			
		||||
                        secure_api_report_log_message(Error, "New version is the same as last invalid version. Could not perform update!");
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                image_header_was_checked = true;
 | 
			
		||||
 | 
			
		||||
                err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle);
 | 
			
		||||
                if (err != ESP_OK)
 | 
			
		||||
                {
 | 
			
		||||
                    ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
 | 
			
		||||
                    http_cleanup(client);
 | 
			
		||||
                    free(ota_write_data);
 | 
			
		||||
                    esp_ota_abort(update_handle);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                ESP_LOGI(TAG, "esp_ota_begin succeeded");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                ESP_LOGE(TAG, "received package is not fit len");
 | 
			
		||||
                http_cleanup(client);
 | 
			
		||||
                free(ota_write_data);
 | 
			
		||||
                esp_ota_abort(update_handle);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        err = esp_ota_write(update_handle, (const void *)ota_write_data, data_read);
 | 
			
		||||
        if (err != ESP_OK)
 | 
			
		||||
        {
 | 
			
		||||
            http_cleanup(client);
 | 
			
		||||
            free(ota_write_data);
 | 
			
		||||
            esp_ota_abort(update_handle);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        binary_file_length += data_read;
 | 
			
		||||
        ESP_LOGD(TAG, "Written image length %d", binary_file_length);
 | 
			
		||||
    }
 | 
			
		||||
    free(ota_write_data);
 | 
			
		||||
 | 
			
		||||
    ESP_LOGI(TAG, "Total Write binary data length: %d", binary_file_length);
 | 
			
		||||
    if (esp_http_client_is_complete_data_received(client) != true)
 | 
			
		||||
    {
 | 
			
		||||
        ESP_LOGE(TAG, "Error in receiving complete file");
 | 
			
		||||
        http_cleanup(client);
 | 
			
		||||
        esp_ota_abort(update_handle);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err = esp_ota_end(update_handle);
 | 
			
		||||
    if (err != ESP_OK)
 | 
			
		||||
    {
 | 
			
		||||
        if (err == ESP_ERR_OTA_VALIDATE_FAILED)
 | 
			
		||||
        {
 | 
			
		||||
            ESP_LOGE(TAG, "Image validation failed, image is corrupted");
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err));
 | 
			
		||||
        }
 | 
			
		||||
        http_cleanup(client);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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));
 | 
			
		||||
        http_cleanup(client);
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ESP_LOGI(TAG, "End of OTA procedure!");
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user