main/updates.c

Mon, 22 Oct 2018 21:43:45 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 22 Oct 2018 21:43:45 +0200
changeset 6
e84200edc852
parent 4
6d1f512cd074
child 13
8f01b74bf1dd
permissions
-rw-r--r--

Updated esp-ide. Removed VNC server corre encoding because no clients would use it. Enabled WiFi error logmessages. Write runtime record is now debug logging. Removed recipe.Record number, not usefull and was wrong too. Removed console print of json log data.

/**
 * @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";

extern sButton                  Buttons[MAXBUTTONS];
extern int                      Main_Screen;


static void http_cleanup(esp_http_client_handle_t client)
{
    esp_http_client_close(client);
    esp_http_client_cleanup(client);
}



/**
 * @brief Run update procedure
 */
void run_update(void)
{
    char                        temp[64];
    esp_err_t                   err;
    const esp_partition_t       *update_partition = NULL;
    esp_ota_handle_t            update_handle = 0;

    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, 25);

    /*
     * Don't use https because it costs more then 100K memory.
     */
    esp_http_client_config_t update = {
	.url = "http://seaport.mbse.ym/update/brewboard.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;
    }

    esp_http_client_fetch_headers(client);
    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;
    }

    TFT_print("Begin download.\r\n", 0, LASTY);
    ESP_LOGI(TAG, "Download update %s", update.url);
    int binary_file_length = 0;
    /*deal with all receive packet*/
    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) {
	    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 (esp_ota_end(update_handle) != ESP_OK) {
	ESP_LOGE(TAG, "esp_ota_end failed!");
	goto updateerr;
    }
    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("Already the latest version.\r\n", LASTX, LASTY);
	goto updateok;
    }

    /*
     * Here we have a different and hopefully newer 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!");
    TFT_print("Rebooting ...", 0, LASTY);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    esp_restart();
    return ;

updateerr:
    _fg = TFT_RED;
    TFT_print("Error\r\n", 0, LASTY);

updateok:
    vTaskDelay(3000 / portTICK_PERIOD_MS);
}



/*
 * Files init function, only runs once a new screen is entered.
 */
void Updates_Init(void)
{
    switch (Main_Screen) {
	case MAIN_TOOLS_UPDATES:
			_bg = TFT_BLACK;
			TFT_fillScreen(_bg);
			TopMessage("Update");
			break;

	default:	break;
    }
}



/*
 * Updates management loop, non-blocking.
 */
void Updates_Loop(void)
{
    switch (Main_Screen) {

	case MAIN_TOOLS_UPDATES:
			run_update();
			Main_Screen = MAIN_TOOLS;
			break;

	default:	break;
    }
}

mercurial