main/updates.c

changeset 0
b74b0e4902c3
child 1
ad2c8b13eb88
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/updates.c	Sat Oct 20 13:23:15 2018 +0200
@@ -0,0 +1,174 @@
+/**
+ * @file updates.c
+ * @brief Updates management.
+ */
+
+#include "config.h"
+
+
+#define BUFFSIZE 1024
+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);
+}
+
+
+
+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