diff -r 063a21ca11f7 -r 8f01b74bf1dd main/updates.c --- 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;