main/updates.c

changeset 13
8f01b74bf1dd
parent 4
6d1f512cd074
child 42
c6a1a6ca5437
--- a/main/updates.c	Wed Oct 24 11:55:39 2018 +0200
+++ b/main/updates.c	Wed Oct 24 23:15:04 2018 +0200
@@ -24,9 +24,9 @@
 
 
 /**
- * @brief Run update procedure
+ * @brief Run binary update procedure
  */
-void run_update(void)
+void bin_update(void)
 {
     char                        temp[64];
     esp_err_t                   err;
@@ -38,13 +38,13 @@
     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);
+    TFT_print(temp, 0, LASTY);
 
     /*
      * 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",
+	.url = "http://update.mbse.eu/ap1/fw/brewboard.bin",
     };
 
     esp_http_client_handle_t client = esp_http_client_init(&update);
@@ -60,7 +60,13 @@
 	goto updateerr;
     }
 
-    esp_http_client_fetch_headers(client);
+    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");
@@ -77,7 +83,7 @@
     }
 
     TFT_print("Begin download.\r\n", 0, LASTY);
-    ESP_LOGI(TAG, "Download update %s", update.url);
+    ESP_LOGI(TAG, "Download update %s size %d", update.url, content_length);
     int binary_file_length = 0;
     /*deal with all receive packet*/
     while (1) {
@@ -140,6 +146,183 @@
 
 
 
+/**
+ * @brief Download a file to /spiffs
+ * @param filename The name and path of the file to download.
+ * @return Return 0 if ok, negative if errors.
+ */
+int DownloadSpiffs(char *filename)
+{
+    esp_err_t	err;
+    static char	theurl[73], thefile[41];
+    FILE	*f;
+
+//    static char	todel[41];
+//    snprintf(todel, 40, "/spiffs//%s", filename);
+//    unlink(todel);
+//    return 0;
+
+    snprintf(theurl, 72, "http://update.mbse.eu/ap1/image/%s", filename);
+    snprintf(thefile, 40, "/spiffs/%s", filename);
+
+    esp_http_client_config_t update = {
+	.url = theurl,
+    };
+
+    esp_http_client_handle_t client = esp_http_client_init(&update);
+    if (client == NULL) {
+	ESP_LOGE(TAG, "Failed to init HTTP connection");
+	return -1;
+    }
+
+    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);
+	return -1;
+    }
+
+    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);
+	return -1;
+    }
+
+    /*
+     * Remove a possible stale download.
+     */
+    unlink("/spiffs/tmpfile");
+    f = fopen("/spiffs/tmpfile", "w");
+    if (f == NULL) {
+	ESP_LOGE(TAG, "Cannot create /spiffs/tmpfile");
+	esp_http_client_cleanup(client);
+	return -1;
+    }
+
+    int read_length = 0;
+    int write_length = 0;
+    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 %s", theurl);
+	    http_cleanup(client);
+	    return -1;
+	} else if (data_read > 0) {
+	    size_t bytes = fwrite(ota_write_data, 1, data_read, f);
+	    if (bytes != data_read) {
+		ESP_LOGE(TAG, "fwrite %s %d/%d at %d", theurl, bytes, data_read, write_length);
+	    }
+	    write_length += bytes;
+	    read_length += data_read;
+	} else if (data_read == 0) {
+	    break;
+	}
+	vTaskDelay(5 / portTICK_PERIOD_MS);
+    }
+    fclose(f);
+
+    if (content_length != write_length) {
+	ESP_LOGE(TAG, "Download %s size %d but got %d bytes", theurl, content_length, write_length);
+	unlink("/spiffs/tmpfile");
+	return -1;
+    }
+
+    ESP_LOGI(TAG, "Download %s size %d Ok", theurl, content_length);
+    unlink(thefile);
+    rename("/spiffs/tmpfile", thefile);
+    esp_http_client_cleanup(client);
+    return 0;
+}
+
+
+
+/**
+ * @brief Update /spiffs filesystem
+ */
+void spiffs_update(void)
+{
+    int		rc;
+    FILE	*f;
+    char	v1[12], v2[12], fn[41];
+
+    TFT_setFont(DEJAVU18_FONT, NULL);
+    _fg = TFT_CYAN;
+    TFT_print("Update /spiffs ", 0, 25);
+
+    rc = rename("/spiffs/version.txt", "/spiffs/version.old");
+    if ((rc != 0) && (errno == ENOENT)) {
+	/* No old file. */
+	ESP_LOGI(TAG, "No old /spiffs/version.txt");
+	/* Download, install old and new */
+	DownloadSpiffs("version.txt");
+	rename("/spiffs/version.txt", "/spiffs/version.old");
+	DownloadSpiffs("version.txt");
+	goto spiffs_update;
+    }
+
+    if (DownloadSpiffs("version.txt") < 0)
+	goto spiffs_error;
+
+    /* Compare spiffs/version.old and /spiffs/version.txt */
+    v1[0] = '\0';
+    v2[0] = '\0';
+    f = fopen("/spiffs/version.old", "r");
+    if (f) {
+	fgets(v1, 11, f);
+	fclose(f);
+    }
+    f = fopen("/spiffs/version.txt", "r");
+    if (f) {
+	fgets(v2, 11, f);
+	fclose(f);
+    }
+//    ESP_LOG_BUFFER_HEXDUMP(TAG, v1, strlen(v1), ESP_LOG_INFO);
+//    ESP_LOG_BUFFER_HEXDUMP(TAG, v2, strlen(v2), ESP_LOG_INFO);
+    if (strcmp(v1, v2) == 0) {
+	ESP_LOGI(TAG, "/spiffs is up to date");
+	TFT_print("Ok\r\n", LASTX, LASTY);
+	unlink("/spiffs/version.old");
+	return;
+    }
+
+spiffs_update:
+    /*
+     * Run the update, get the filelist.
+     */
+    ESP_LOGI(TAG, "Full /spiffs update");
+    rc = DownloadSpiffs("files.list");
+    if (rc < 0) {
+	unlink("/spiffs/version.txt");
+	rename("/spiffs/version.old", "/spiffs/version.txt");	// So next time we try again.
+	goto spiffs_error;
+    }
+
+    f = fopen("/spiffs/files.list", "r");
+    while (fgets(fn, 40, f)) {
+	fn[strlen(fn)-1] = '\0';
+	rc = DownloadSpiffs(fn);
+	if (rc < 0) {
+	    ESP_LOGE(TAG, "Updates failed");
+	    fclose(f);
+	    goto spiffs_error;
+	}
+//	vTaskDelay(10 / portTICK_PERIOD_MS);
+    }
+    fclose(f);
+    unlink("/spiffs/version.old");
+    TFT_print("updated\r\n", LASTX, LASTY);
+    return;
+
+spiffs_error:
+    _fg = TFT_RED;
+    TFT_print("error\r\n", LASTX, LASTY);
+
+}
+
+
+
 /*
  * Files init function, only runs once a new screen is entered.
  */
@@ -166,7 +349,8 @@
     switch (Main_Screen) {
 
 	case MAIN_TOOLS_UPDATES:
-			run_update();
+			spiffs_update();
+			bin_update();
 			Main_Screen = MAIN_TOOLS;
 			break;
 

mercurial