From 76f45a59275c061f88880a076735a484900b284e Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Wed, 26 Feb 2025 23:56:49 +0100 Subject: [PATCH] Remove html directory on update (#3584) * delete HTML directory on an update * delete HTML directory on an update * rename html folder * swap HTML folders after extracting * . * . * . * . * . * . * move SD card check, SD card directories setup and update to before the PSRAM init. The update should be as early as possible to allow updates even if the PSRAM or cam fails. * . * . * Update Helper.cpp * Update Helper.h * . --------- Co-authored-by: CaCO3 Co-authored-by: SybexX --- .../jomjol_fileserver_ota/server_file.cpp | 11 +++- .../jomjol_fileserver_ota/server_file.h | 2 +- .../jomjol_fileserver_ota/server_ota.cpp | 26 +++++++-- code/components/jomjol_helper/Helper.cpp | 56 +++++++++++++----- code/components/jomjol_helper/Helper.h | 4 +- code/main/main.cpp | 58 +++++++++---------- 6 files changed, 104 insertions(+), 53 deletions(-) diff --git a/code/components/jomjol_fileserver_ota/server_file.cpp b/code/components/jomjol_fileserver_ota/server_file.cpp index 137aeb5f..df396800 100644 --- a/code/components/jomjol_fileserver_ota/server_file.cpp +++ b/code/components/jomjol_fileserver_ota/server_file.cpp @@ -61,7 +61,7 @@ struct file_server_data { using namespace std; -string SUFFIX_ZW = "_0xge"; +string SUFFIX_ZW = "_tmp"; static esp_err_t send_logfile(httpd_req_t *req, bool send_full_file); static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file); @@ -911,7 +911,7 @@ void delete_all_in_directory(std::string _directory) closedir(dir); } -std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main, bool _initial_setup) +std::string unzip_new(std::string _in_zip_file, std::string _html_tmp, std::string _html_final, std::string _target_bin, std::string _main, bool _initial_setup) { int i, sort_iter; mz_bool status; @@ -993,10 +993,15 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st } else { - zw = _target_zip + zw; + zw = _html_tmp + zw; } } + + // files in the html folder shall be redirected to the temporary html folder + if (zw.find(_html_final) == 0) { + FindReplace(zw, _html_final, _html_tmp); + } string filename_zw = zw + SUFFIX_ZW; diff --git a/code/components/jomjol_fileserver_ota/server_file.h b/code/components/jomjol_fileserver_ota/server_file.h index cae83512..3520ae5d 100644 --- a/code/components/jomjol_fileserver_ota/server_file.h +++ b/code/components/jomjol_fileserver_ota/server_file.h @@ -9,7 +9,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path); void unzip(std::string _in_zip_file, std::string _target_directory); -std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main = "/sdcard/", bool _initial_setup = false); +std::string unzip_new(std::string _in_zip_file, std::string _html_tmp, std::string _html_final, std::string _target_bin, std::string _main = "/sdcard/", bool _initial_setup = false); void delete_all_in_directory(std::string _directory); diff --git a/code/components/jomjol_fileserver_ota/server_ota.cpp b/code/components/jomjol_fileserver_ota/server_ota.cpp index 52393978..1ec21936 100644 --- a/code/components/jomjol_fileserver_ota/server_ota.cpp +++ b/code/components/jomjol_fileserver_ota/server_ota.cpp @@ -76,20 +76,35 @@ void task_do_Update_ZIP(void *pvParameter) LogFile.WriteToFile(ESP_LOG_INFO, TAG, "File: " + _file_name_update + " Filetype: " + filetype); - if (filetype == "ZIP") { - std::string in, out, outbin, zw, retfirmware; + std::string in, outHtml, outHtmlTmp, outHtmlOld, outbin, zw, retfirmware; - out = "/sdcard/html"; + outHtml = "/sdcard/html"; + outHtmlTmp = "/sdcard/html_tmp"; + outHtmlOld = "/sdcard/html_old"; outbin = "/sdcard/firmware"; - retfirmware = unzip_new(_file_name_update, out+"/", outbin+"/", "/sdcard/", initial_setup); + /* Remove the old and tmp html folder in case they still exist */ + removeFolder(outHtmlTmp.c_str(), TAG); + removeFolder(outHtmlOld.c_str(), TAG); + + /* Extract the ZIP file. The content of the html folder gets extracted to the temporar folder html-temp. */ + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Extracting ZIP file " + _file_name_update + "..."); + retfirmware = unzip_new(_file_name_update, outHtmlTmp+"/", outHtml+"/", outbin+"/", "/sdcard/", initial_setup); LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Files unzipped."); + /* ZIP file got extracted, replace the old html folder with the new one */ + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Renaming folder " + outHtml + " to " + outHtmlOld + "..."); + RenameFolder(outHtml, outHtmlOld); + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Renaming folder " + outHtmlTmp + " to " + outHtml + "..."); + RenameFolder(outHtmlTmp, outHtml); + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Deleting folder " + outHtmlOld + "..."); + removeFolder(outHtmlOld.c_str(), TAG); + if (retfirmware.length() > 0) { - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Found firmware.bin"); + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Found firmware.bin"); ota_update_task(retfirmware); } @@ -434,7 +449,6 @@ esp_err_t handler_ota_update(httpd_req_t *req) return ESP_OK; } - if ((filetype == "TFLITE") || (filetype == "TFL")) { std::string out = "/sdcard/config/" + getFileFullFileName(fn); diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index 78d359e3..967c9fb9 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -365,19 +365,35 @@ size_t findDelimiterPos(string input, string delimiter) bool RenameFile(string from, string to) { - // ESP_LOGI(logTag, "Deleting file: %s", fn.c_str()); - /* Delete file */ + // ESP_LOGI(logTag, "Renaming File: %s", from.c_str()); FILE *fpSourceFile = fopen(from.c_str(), "rb"); - // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + // Sourcefile does not exist otherwise there is a mistake when renaming! if (!fpSourceFile) { - ESP_LOGE(TAG, "DeleteFile: File %s existiert nicht!", from.c_str()); + ESP_LOGE(TAG, "RenameFile: File %s does not exist!", from.c_str()); return false; } fclose(fpSourceFile); + rename(from.c_str(), to.c_str()); + return true; +} + +bool RenameFolder(string from, string to) +{ + // ESP_LOGI(logTag, "Renaming Folder: %s", from.c_str()); + DIR *fpSourceFolder = opendir(from.c_str()); + + // Sourcefolder does not exist otherwise there is a mistake when renaming! + if (!fpSourceFolder) + { + ESP_LOGE(TAG, "RenameFolder: Folder %s does not exist!", from.c_str()); + return false; + } + + closedir(fpSourceFolder); rename(from.c_str(), to.c_str()); return true; @@ -387,7 +403,7 @@ bool FileExists(string filename) { FILE *fpSourceFile = fopen(filename.c_str(), "rb"); - // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + // Sourcefile does not exist if (!fpSourceFile) { return false; @@ -398,22 +414,36 @@ bool FileExists(string filename) return true; } -bool DeleteFile(string fn) +bool FolderExists(string foldername) { - // ESP_LOGI(logTag, "Deleting file: %s", fn.c_str()); - /* Delete file */ - FILE *fpSourceFile = fopen(fn.c_str(), "rb"); + DIR *fpSourceFolder = opendir(foldername.c_str()); - // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + // Sourcefolder does not exist + if (!fpSourceFolder) + { + return false; + } + + closedir(fpSourceFolder); + + return true; +} + +bool DeleteFile(string filename) +{ + // ESP_LOGI(logTag, "Deleting file: %s", filename.c_str()); + /* Delete file */ + FILE *fpSourceFile = fopen(filename.c_str(), "rb"); + + // Sourcefile does not exist otherwise there is a mistake in copying! if (!fpSourceFile) { - ESP_LOGD(TAG, "DeleteFile: File %s existiert nicht!", fn.c_str()); + ESP_LOGD(TAG, "DeleteFile: File %s existiert nicht!", filename.c_str()); return false; } fclose(fpSourceFile); - - unlink(fn.c_str()); + unlink(filename.c_str()); return true; } diff --git a/code/components/jomjol_helper/Helper.h b/code/components/jomjol_helper/Helper.h index ac6e3391..a408c096 100644 --- a/code/components/jomjol_helper/Helper.h +++ b/code/components/jomjol_helper/Helper.h @@ -16,10 +16,12 @@ std::size_t file_size(const std::string& file_name); void FindReplace(std::string& line, std::string& oldString, std::string& newString); bool CopyFile(string input, string output); -bool DeleteFile(string fn); +bool DeleteFile(string filename); bool RenameFile(string from, string to); +bool RenameFolder(string from, string to); bool MakeDir(std::string _what); bool FileExists(string filename); +bool FolderExists(string foldername); string RundeOutput(double _in, int _anzNachkomma); diff --git a/code/main/main.cpp b/code/main/main.cpp index e615b2c2..0c494ef9 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -254,6 +254,35 @@ extern "C" void app_main(void) LogFile.WriteToFile(ESP_LOG_INFO, TAG, "==================== Start ======================"); LogFile.WriteToFile(ESP_LOG_INFO, TAG, "================================================="); + // SD card: basic R/W check + // ******************************************** + int iSDCardStatus = SDCardCheckRW(); + if (iSDCardStatus < 0) { + if (iSDCardStatus <= -1 && iSDCardStatus >= -2) { // write error + StatusLED(SDCARD_CHECK, 1, true); + } + else if (iSDCardStatus <= -3 && iSDCardStatus >= -5) { // read error + StatusLED(SDCARD_CHECK, 2, true); + } + else if (iSDCardStatus == -6) { // delete error + StatusLED(SDCARD_CHECK, 3, true); + } + setSystemStatusFlag(SYSTEM_STATUS_SDCARD_CHECK_BAD); // reduced web interface going to be loaded + } + + // SD card: Create further mandatory directories (if not already existing) + // Correct creation of these folders will be checked with function "SDCardCheckFolderFilePresence" + // ******************************************** + MakeDir("/sdcard/firmware"); // mandatory for OTA firmware update + MakeDir("/sdcard/img_tmp"); // mandatory for setting up alignment marks + MakeDir("/sdcard/demo"); // mandatory for demo mode + MakeDir("/sdcard/config/certs"); // mandatory for mqtt certificates + + // Check for updates + // ******************************************** + CheckOTAUpdate(); + CheckUpdate(); + // Init external PSRAM // ******************************************** esp_err_t PSRAMStatus = esp_psram_init(); @@ -352,22 +381,6 @@ extern "C" void app_main(void) } } - // SD card: basic R/W check - // ******************************************** - int iSDCardStatus = SDCardCheckRW(); - if (iSDCardStatus < 0) { - if (iSDCardStatus <= -1 && iSDCardStatus >= -2) { // write error - StatusLED(SDCARD_CHECK, 1, true); - } - else if (iSDCardStatus <= -3 && iSDCardStatus >= -5) { // read error - StatusLED(SDCARD_CHECK, 2, true); - } - else if (iSDCardStatus == -6) { // delete error - StatusLED(SDCARD_CHECK, 3, true); - } - setSystemStatusFlag(SYSTEM_STATUS_SDCARD_CHECK_BAD); // reduced web interface going to be loaded - } - // Migrate parameter in config.ini to new naming (firmware 15.0 and newer) // ******************************************** migrateConfiguration(); @@ -380,19 +393,6 @@ extern "C" void app_main(void) // ******************************************** setCpuFrequency(); - // SD card: Create further mandatory directories (if not already existing) - // Correct creation of these folders will be checked with function "SDCardCheckFolderFilePresence" - // ******************************************** - MakeDir("/sdcard/firmware"); // mandatory for OTA firmware update - MakeDir("/sdcard/img_tmp"); // mandatory for setting up alignment marks - MakeDir("/sdcard/demo"); // mandatory for demo mode - MakeDir("/sdcard/config/certs"); // mandatory for mqtt certificates - - // Check for updates - // ******************************************** - CheckOTAUpdate(); - CheckUpdate(); - // Start SoftAP for initial remote setup // Note: Start AP if no wlan.ini and/or config.ini available, e.g. SD card empty; function does not exit anymore until reboot // ********************************************