From 3c43a1b97df254f08f474148617df1a0ddd00090 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 12 Jan 2024 23:26:57 +0100 Subject: [PATCH 1/3] [Core] String optimizations --- src/src/DataTypes/ESPEasyFileType.cpp | 2 +- src/src/Helpers/ESPEasy_Storage.cpp | 130 ++++++++------------------ 2 files changed, 38 insertions(+), 94 deletions(-) diff --git a/src/src/DataTypes/ESPEasyFileType.cpp b/src/src/DataTypes/ESPEasyFileType.cpp index 9a2c060c57..a8b3bf4bc0 100644 --- a/src/src/DataTypes/ESPEasyFileType.cpp +++ b/src/src/DataTypes/ESPEasyFileType.cpp @@ -25,7 +25,7 @@ bool isProtectedFileType(const String& filename) const int8_t mPerc = mask.indexOf('%'); if ((mPerc > -1) && fname.startsWith(mask.substring(0, mPerc))) { - for (uint8_t n = 0; n < TASKS_MAX && !isTaskSpecificConfig; n++) { + for (uint8_t n = 0; n < TASKS_MAX && !isTaskSpecificConfig; ++n) { isTaskSpecificConfig |= (fname.equalsIgnoreCase(strformat(mask, n + 1))); } } diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index 21008e2a96..e941789d20 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -867,10 +867,8 @@ bool getAndLogSettingsParameters(bool read, SettingsType::Enum settingsType, int if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) { String log = read ? F("Read") : F("Write"); - log += F(" settings: "); - log += SettingsType::getSettingsTypeString(settingsType); - log += F(" index: "); - log += index; + log += concat(F(" settings: "), SettingsType::getSettingsTypeString(settingsType)); + log += concat(F(" index: "), index); addLogMove(LOG_LEVEL_DEBUG_DEV, log); } #endif // ifndef BUILD_NO_DEBUG @@ -943,8 +941,7 @@ String LoadStringArray(SettingsType::Enum settingsType, int index, String string } if ((!tmpString.isEmpty()) && (stringCount < nrStrings)) { - result += F("Incomplete custom settings for index "); - result += (index + 1); + result += concat(F("Incomplete custom settings for index "), index + 1); move_special(strings[stringCount], std::move(tmpString)); } return result; @@ -1234,11 +1231,7 @@ String SaveCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t } String getCustomTaskSettingsError(uint8_t varNr) { - String error = F("Error: Text too long for line "); - - error += varNr + 1; - error += '\n'; - return error; + return strformat(F("Error: Text too long for line %d\n"), varNr + 1); } /********************************************************************************************\ @@ -1501,10 +1494,7 @@ String doSaveToFile(const char *fname, int index, const uint8_t *memAddress, int #ifndef ESP32 if (allocatedOnStack(memAddress)) { - String log = F("SaveToFile: "); - log += fname; - log += F(" ERROR, Data allocated on stack"); - addLog(LOG_LEVEL_ERROR, log); + addLog(LOG_LEVEL_ERROR, strformat(F("SaveToFile: %s ERROR, Data allocated on stack"), fname)); // return log; // FIXME TD-er: Should this be considered a breaking error? } @@ -1513,11 +1503,9 @@ String doSaveToFile(const char *fname, int index, const uint8_t *memAddress, int if (index < 0) { #ifndef BUILD_NO_DEBUG - String log = F("SaveToFile: "); - log += fname; - log += F(" ERROR, invalid position in file"); + const String log = strformat(F("SaveToFile: %s ERROR, invalid position in file"), fname); #else - String log = F("Save error"); + const String log = F("Save error"); #endif addLog(LOG_LEVEL_ERROR, log); return log; @@ -1564,24 +1552,14 @@ String doSaveToFile(const char *fname, int index, const uint8_t *memAddress, int f.close(); #ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log; - log.reserve(48); - log += F("FILE : Saved "); - log += fname; - log += F(" offset: "); - log += index; - log += F(" size: "); - log += datasize; - addLogMove(LOG_LEVEL_INFO, log); + addLogMove(LOG_LEVEL_INFO, strformat(F("FILE : Saved %s offset: %d size: %d"), fname, index, datasize)); } #endif } else { #ifndef BUILD_NO_DEBUG - String log = F("SaveToFile: "); - log += fname; - log += F(" ERROR, Cannot save to file"); + const String log = strformat(F("SaveToFile: %s ERROR, Cannot save to file"), fname); #else - String log = F("Save error"); + const String log = F("Save error"); #endif addLog(LOG_LEVEL_ERROR, log); @@ -1605,11 +1583,9 @@ String ClearInFile(const char *fname, int index, int datasize) { if (index < 0) { #ifndef BUILD_NO_DEBUG - String log = F("ClearInFile: "); - log += fname; - log += F(" ERROR, invalid position in file"); + const String log = strformat(F("ClearInFile: %s ERROR, invalid position in file"), fname); #else - String log = F("Save error"); + const String log = F("Save error"); #endif addLog(LOG_LEVEL_ERROR, log); @@ -1635,11 +1611,9 @@ String ClearInFile(const char *fname, int index, int datasize) f.close(); } else { #ifndef BUILD_NO_DEBUG - String log = F("ClearInFile: "); - log += fname; - log += F(" ERROR, Cannot save to file"); + const String log = strformat(F("ClearInFile: %s ERROR, Cannot save to file"), fname); #else - String log = F("Save error"); + const String log = F("Save error"); #endif addLog(LOG_LEVEL_ERROR, log); return log; @@ -1656,11 +1630,9 @@ String LoadFromFile(const char *fname, int offset, uint8_t *memAddress, int data { if (offset < 0) { #ifndef BUILD_NO_DEBUG - String log = F("LoadFromFile: "); - log += fname; - log += F(" ERROR, invalid position in file"); + const String log = strformat(F("LoadFromFile: %s ERROR, invalid position in file"), fname); #else - String log = F("Load error"); + const String log = F("Load error"); #endif addLog(LOG_LEVEL_ERROR, log); return log; @@ -1700,15 +1672,12 @@ String LoadFromFile(const char *fname, int offset, uint8_t *memAddress, int data \*********************************************************************************************/ String getSettingsFileIndexRangeError(bool read, SettingsType::Enum settingsType, int index) { if (settingsType >= SettingsType::Enum::SettingsType_MAX) { - String error = F("Unknown settingsType: "); - error += static_cast(settingsType); - return error; + return concat(F("Unknown settingsType: "), static_cast(settingsType)); } String error = read ? F("Load") : F("Save"); #ifndef BUILD_NO_DEBUG error += SettingsType::getSettingsTypeString(settingsType); - error += F(" index out of range: "); - error += index; + error += concat(F(" index out of range: "), index); #else error += F(" error"); #endif @@ -1719,13 +1688,7 @@ String getSettingsFileDatasizeError(bool read, SettingsType::Enum settingsType, String error = read ? F("Load") : F("Save"); #ifndef BUILD_NO_DEBUG error += SettingsType::getSettingsTypeString(settingsType); - error += '('; - error += index; - error += F(") datasize("); - error += datasize; - error += F(") > max_size("); - error += max_size; - error += ')'; + error += strformat(F("(%d) datasize(%d) > max_size(%d)"), index, datasize, max_size); #else error += F(" error"); #endif @@ -1996,9 +1959,7 @@ String createCacheFilename(unsigned int count) { #ifdef ESP32 fname = '/'; #endif // ifdef ESP32 - fname += F("cache_"); - fname += String(count); - fname += F(".bin"); + fname += strformat(F("cache_%d.bin"), count); return fname; } @@ -2103,9 +2064,7 @@ String getPartitionType(uint8_t pType, uint8_t pSubType) { if (partitionType == ESP_PARTITION_TYPE_APP) { if ((partitionSubType >= ESP_PARTITION_SUBTYPE_APP_OTA_MIN) && (partitionSubType < ESP_PARTITION_SUBTYPE_APP_OTA_MAX)) { - String result = F("OTA partition "); - result += (partitionSubType - ESP_PARTITION_SUBTYPE_APP_OTA_MIN); - return result; + return concat(F("OTA partition "), partitionSubType - ESP_PARTITION_SUBTYPE_APP_OTA_MIN); } switch (partitionSubType) { @@ -2136,26 +2095,12 @@ String getPartitionType(uint8_t pType, uint8_t pSubType) { default: break; } } - String result = F("Unknown("); - result += partitionSubType; - result += ')'; - return result; + return strformat(F("Unknown(%d)"), partitionSubType); } String getPartitionTableHeader(const String& itemSep, const String& lineEnd) { - String result; - - result += F("Address"); - result += itemSep; - result += F("Size"); - result += itemSep; - result += F("Label"); - result += itemSep; - result += F("Partition Type"); - result += itemSep; - result += F("Encrypted"); - result += lineEnd; - return result; + return strformat(F("Address%sSize%sLabel%sPartition Type%sEncrypted%s"), + itemSep.c_str(), itemSep.c_str(), itemSep.c_str(), itemSep.c_str(), lineEnd.c_str()); } String getPartitionTable(uint8_t pType, const String& itemSep, const String& lineEnd) { @@ -2166,16 +2111,17 @@ String getPartitionTable(uint8_t pType, const String& itemSep, const String& lin if (_mypartiterator) { do { const esp_partition_t *_mypart = esp_partition_get(_mypartiterator); - result += formatToHex(_mypart->address); - result += itemSep; - result += formatToHex_decimal(_mypart->size, 1024); - result += itemSep; - result += _mypart->label; - result += itemSep; - result += getPartitionType(_mypart->type, _mypart->subtype); - result += itemSep; - result += (_mypart->encrypted ? F("Yes") : F("-")); - result += lineEnd; + result += strformat(F("%x%s%s%s%s%s%s%s%s%s"), + _mypart->address, + itemSep, + formatToHex_decimal(_mypart->size, 1024), + itemSep, + _mypart->label, + itemSep, + getPartitionType(_mypart->type, _mypart->subtype).c_str(), + itemSep, + String(_mypart->encrypted ? F("Yes") : F("-")).c_str(), + lineEnd); } while ((_mypartiterator = esp_partition_next(_mypartiterator)) != nullptr); } esp_partition_iterator_release(_mypartiterator); @@ -2206,8 +2152,7 @@ String downloadFileType(const String& url, const String& user, const String& pas } } else { if (fileExists(filename)) { - String filename_bak = filename; - filename_bak += F("_bak"); + const String filename_bak = strformat(F("%s_bak"), filename.c_str()); if (fileExists(filename_bak)) { if (!ResetFactoryDefaultPreference.delete_Bak_Files() || !tryDeleteFile(filename_bak)) { return F("Could not rename to _bak"); @@ -2215,8 +2160,7 @@ String downloadFileType(const String& url, const String& user, const String& pas } // Must download it to a tmp file. - String tmpfile = filename; - tmpfile += F("_tmp"); + const String tmpfile = strformat(F("%s_tmp"),filename.c_str()); if (!downloadFile(fullUrl, tmpfile, user, pass, error)) { return error; From a8247caba0ec05378d1ed4f292463aadd8772c9c Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 1 Apr 2024 14:43:21 +0200 Subject: [PATCH 2/3] [Storage] Use correct parameter-type for strformat() --- src/src/Helpers/ESPEasy_Storage.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index 3720f1f189..a42422b3b5 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -2129,15 +2129,15 @@ String getPartitionTable(uint8_t pType, const String& itemSep, const String& lin const esp_partition_t *_mypart = esp_partition_get(_mypartiterator); result += strformat(F("%x%s%s%s%s%s%s%s%s%s"), _mypart->address, - itemSep, + itemSep.c_str(), formatToHex_decimal(_mypart->size, 1024), - itemSep, + itemSep.c_str(), _mypart->label, - itemSep, + itemSep.c_str(), getPartitionType(_mypart->type, _mypart->subtype).c_str(), - itemSep, + itemSep.c_str(), String(_mypart->encrypted ? F("Yes") : F("-")).c_str(), - lineEnd); + lineEnd.c_str()); } while ((_mypartiterator = esp_partition_next(_mypartiterator)) != nullptr); } esp_partition_iterator_release(_mypartiterator); From 5a402acd16978f91eb3f98dab2a00bdbc1f29dea Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 1 Apr 2024 15:01:07 +0200 Subject: [PATCH 3/3] [Storage] Use correct parameter-type for strformat() --- src/src/Helpers/ESPEasy_Storage.cpp | 599 +++++++++++++++++----------- 1 file changed, 361 insertions(+), 238 deletions(-) diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index a42422b3b5..5941a5f6b2 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -12,8 +12,8 @@ #include "../DataTypes/SPI_options.h" #if FEATURE_MQTT -#include "../ESPEasyCore/Controller.h" -#endif +# include "../ESPEasyCore/Controller.h" +#endif // if FEATURE_MQTT #include "../ESPEasyCore/ESPEasy_Log.h" #include "../ESPEasyCore/ESPEasyNetwork.h" #include "../ESPEasyCore/ESPEasyWifi.h" @@ -53,11 +53,11 @@ #if FEATURE_RTC_CACHE_STORAGE # include "../Globals/C016_ControllerCache.h" -#endif +#endif // if FEATURE_RTC_CACHE_STORAGE #ifdef ESP32 -#include -#endif +# include +#endif // ifdef ESP32 #ifdef ESP32 String patch_fname(const String& fname) { @@ -66,7 +66,8 @@ String patch_fname(const String& fname) { } return String('/') + fname; } -#endif + +#endif // ifdef ESP32 /********************************************************************************************\ file system error handling @@ -75,6 +76,7 @@ String patch_fname(const String& fname) { String FileError(int line, const char *fname) { String log = strformat(F("FS : Error while reading/writing %s in %d"), fname, line); + addLog(LOG_LEVEL_ERROR, log); return log; } @@ -95,7 +97,7 @@ String flashGuard() { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("flashGuard")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER if (RTC.flashDayCounter > MAX_FLASHWRITES_PER_DAY) { @@ -125,7 +127,7 @@ String appendToFile(const String& fname, const uint8_t *data, unsigned int size) return EMPTY_STRING; } -bool fileExists(const __FlashStringHelper * fname) +bool fileExists(const __FlashStringHelper *fname) { return fileExists(String(fname)); } @@ -133,30 +135,35 @@ bool fileExists(const __FlashStringHelper * fname) bool fileExists(const String& fname) { #ifdef USE_SECOND_HEAP HeapSelectDram ephemeral; - #endif + #endif // ifdef USE_SECOND_HEAP const String patched_fname = patch_fname(fname); - auto search = Cache.fileExistsMap.find(patched_fname); + auto search = Cache.fileExistsMap.find(patched_fname); + if (search != Cache.fileExistsMap.end()) { return search->second; } bool res = ESPEASY_FS.exists(patched_fname); #if FEATURE_SD + if (!res) { res = SD.exists(patched_fname); } - #endif + #endif // if FEATURE_SD + // Only keep track of existing files or non-existing filenames that may be requested several times. // Not the non-existing files from the cache controller #if FEATURE_RTC_CACHE_STORAGE - if (res || !isCacheFile(patched_fname)) - #endif + + if (res || !isCacheFile(patched_fname)) + #endif // if FEATURE_RTC_CACHE_STORAGE { Cache.fileExistsMap.emplace( std::make_pair( - patched_fname, + patched_fname, res)); } + if (Cache.fileCacheClearMoment == 0) { if (node_time.timeSource == timeSource_t::No_time_source) { // use some random value as we don't have a time yet @@ -171,6 +178,7 @@ bool fileExists(const String& fname) { fs::File tryOpenFile(const String& fname, const String& mode, FileDestination_e destination) { START_TIMER; fs::File f; + if (fname.isEmpty() || equals(fname, '/')) { return f; } @@ -183,15 +191,16 @@ fs::File tryOpenFile(const String& fname, const String& mode, FileDestination_e } clearFileCaches(); } + if ((destination == FileDestination_e::ANY) || (destination == FileDestination_e::FLASH)) { f = ESPEASY_FS.open(patch_fname(fname), mode.c_str()); } - # if FEATURE_SD + #if FEATURE_SD if (!f && ((destination == FileDestination_e::ANY) || (destination == FileDestination_e::SD))) { f = SD.open(patch_fname(fname).c_str(), mode.c_str()); } - # endif // if FEATURE_SD + #endif // if FEATURE_SD STOP_TIMER(TRY_OPEN_FILE); @@ -200,11 +209,13 @@ fs::File tryOpenFile(const String& fname, const String& mode, FileDestination_e bool fileMatchesTaskSettingsType(const String& fname) { const String config_dat_file = patch_fname(getFileName(FileType::CONFIG_DAT)); + return config_dat_file.equalsIgnoreCase(patch_fname(fname)); } bool tryRenameFile(const String& fname_old, const String& fname_new, FileDestination_e destination) { clearFileCaches(); + if (fileExists(fname_old) && !fileExists(fname_new)) { if (fileMatchesTaskSettingsType(fname_old)) { clearAllCaches(); @@ -212,10 +223,12 @@ bool tryRenameFile(const String& fname_old, const String& fname_new, FileDestina clearAllButTaskCaches(); } bool res = false; + if ((destination == FileDestination_e::ANY) || (destination == FileDestination_e::FLASH)) { res = ESPEASY_FS.rename(patch_fname(fname_old), patch_fname(fname_new)); } #if FEATURE_SD && defined(ESP32) // FIXME ESP8266 SDClass doesn't support rename + if (!res && ((destination == FileDestination_e::ANY) || (destination == FileDestination_e::SD))) { res = SD.rename(patch_fname(fname_old), patch_fname(fname_new)); } @@ -229,24 +242,28 @@ bool tryDeleteFile(const String& fname, FileDestination_e destination) { if (fname.length() > 0) { #if FEATURE_RTC_CACHE_STORAGE + if (isCacheFile(fname)) { ControllerCache.closeOpenFiles(); } - #endif + #endif // if FEATURE_RTC_CACHE_STORAGE + if (fileMatchesTaskSettingsType(fname)) { clearAllCaches(); } else { clearAllButTaskCaches(); } bool res = false; + if ((destination == FileDestination_e::ANY) || (destination == FileDestination_e::FLASH)) { res = ESPEASY_FS.remove(patch_fname(fname)); } #if FEATURE_SD + if (!res && ((destination == FileDestination_e::ANY) || (destination == FileDestination_e::SD))) { res = SD.remove(patch_fname(fname)); } - #endif + #endif // if FEATURE_SD // A call to GarbageCollection() will at most erase a single block. (e.g. 8k block size) // A deleted file may have covered more than a single block, so try to clear multiple blocks. @@ -271,7 +288,7 @@ bool BuildFixes() } #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("BuildFixes")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER serialPrintln(F("\nBuild changed!")); if (Settings.Build < 145) @@ -283,7 +300,7 @@ bool BuildFixes() { #ifdef LIMIT_BUILD_SIZE serialPrintln(F("Fix reset Pin")); - #endif + #endif // ifdef LIMIT_BUILD_SIZE Settings.Pin_Reset = -1; } @@ -292,10 +309,10 @@ bool BuildFixes() // Have to patch settings to make sure no bogus data is being used. #ifdef LIMIT_BUILD_SIZE serialPrintln(F("Fix settings with uninitalized data or corrupted by switching between versions")); - #endif - Settings.UseRTOSMultitasking = false; - Settings.Pin_Reset = -1; - Settings.SyslogFacility = DEFAULT_SYSLOG_FACILITY; + #endif // ifdef LIMIT_BUILD_SIZE + Settings.UseRTOSMultitasking = false; + Settings.Pin_Reset = -1; + Settings.SyslogFacility = DEFAULT_SYSLOG_FACILITY; Settings.MQTTUseUnitNameAsClientId_unused = DEFAULT_MQTT_USE_UNITNAME_AS_CLIENTID; } @@ -303,27 +320,33 @@ bool BuildFixes() Settings.ResetFactoryDefaultPreference = 0; Settings.OldRulesEngine(DEFAULT_RULES_OLDENGINE); } + if (Settings.Build < 20105) { Settings.I2C_clockSpeed = DEFAULT_I2C_CLOCK_SPEED; } + if (Settings.Build <= 20106) { // ClientID is now defined in the controller settings. #if FEATURE_MQTT controllerIndex_t controller_idx = firstEnabledMQTT_ControllerIndex(); + if (validControllerIndex(controller_idx)) { - MakeControllerSettings(ControllerSettings); //-V522 + MakeControllerSettings(ControllerSettings); // -V522 + if (AllocatedControllerSettings()) { LoadControllerSettings(controller_idx, *ControllerSettings); String clientid; + if (Settings.MQTTUseUnitNameAsClientId_unused) { clientid = F("%sysname%"); + if (Settings.appendUnitToHostname()) { clientid += F("_%unit%"); } } else { - clientid = F("ESPClient_%mac%"); + clientid = F("ESPClient_%mac%"); } safe_strncpy(ControllerSettings->ClientID, clientid, sizeof(ControllerSettings->ClientID)); @@ -334,50 +357,62 @@ bool BuildFixes() } #endif // if FEATURE_MQTT } + if (Settings.Build < 20107) { Settings.WebserverPort = 80; } + if (Settings.Build < 20108) { #ifdef ESP32 - // Ethernet related settings are never used on ESP8266 + + // Ethernet related settings are never used on ESP8266 Settings.ETH_Phy_Addr = DEFAULT_ETH_PHY_ADDR; Settings.ETH_Pin_mdc_cs = DEFAULT_ETH_PIN_MDC; Settings.ETH_Pin_mdio_irq = DEFAULT_ETH_PIN_MDIO; Settings.ETH_Pin_power_rst = DEFAULT_ETH_PIN_POWER; Settings.ETH_Phy_Type = DEFAULT_ETH_PHY_TYPE; Settings.ETH_Clock_Mode = DEFAULT_ETH_CLOCK_MODE; -#endif - Settings.NetworkMedium = DEFAULT_NETWORK_MEDIUM; +#endif // ifdef ESP32 + Settings.NetworkMedium = DEFAULT_NETWORK_MEDIUM; } + if (Settings.Build < 20109) { Settings.SyslogPort = 514; } + if (Settings.Build < 20110) { - Settings.I2C_clockSpeed_Slow = DEFAULT_I2C_CLOCK_SPEED_SLOW; + Settings.I2C_clockSpeed_Slow = DEFAULT_I2C_CLOCK_SPEED_SLOW; Settings.I2C_Multiplexer_Type = I2C_MULTIPLEXER_NONE; Settings.I2C_Multiplexer_Addr = -1; + for (taskIndex_t x = 0; x < TASKS_MAX; x++) { Settings.I2C_Multiplexer_Channel[x] = -1; } Settings.I2C_Multiplexer_ResetPin = -1; } + if (Settings.Build < 20111) { #ifdef ESP32 constexpr uint8_t maxStatesesp32 = NR_ELEMENTS(Settings.PinBootStates_ESP32); + for (uint8_t i = 0; i < maxStatesesp32; ++i) { Settings.PinBootStates_ESP32[i] = 0; } - #endif + #endif // ifdef ESP32 } + if (Settings.Build < 20112) { - Settings.WiFi_TX_power = 70; // 70 = 17.5dBm. unit: 0.25 dBm - Settings.WiFi_sensitivity_margin = 3; // Margin in dBm on top of sensitivity. + Settings.WiFi_TX_power = 70; // 70 = 17.5dBm. unit: 0.25 dBm + Settings.WiFi_sensitivity_margin = 3; // Margin in dBm on top of sensitivity. } + if (Settings.Build < 20113) { Settings.NumberExtraWiFiScans = 0; } + if (Settings.Build < 20114) { #ifdef USES_P003 + // P003_Pulse was always using the pull-up, now it is a setting. constexpr pluginID_t PLUGIN_ID_P003_PULSE(3); @@ -386,8 +421,9 @@ bool BuildFixes() Settings.TaskDevicePin1PullUp[taskIndex] = true; } } - #endif + #endif // ifdef USES_P003 } + if (Settings.Build < 20115) { if (Settings.InitSPI != static_cast(SPI_Options_e::UserDefined)) { // User-defined SPI pins set to None Settings.SPI_SCLK_pin = -1; @@ -396,6 +432,7 @@ bool BuildFixes() } } #ifdef USES_P053 + if (Settings.Build < 20116) { // Added PWR button, init to "-none-" constexpr pluginID_t PLUGIN_ID_P053_PMSx003(53); @@ -405,15 +442,16 @@ bool BuildFixes() Settings.TaskDevicePluginConfig[taskIndex][3] = -1; } } + // Remove PeriodicalScanWiFi // Reset to default 0 for future use. Settings.VariousBits_1.unused_15 = 0; } - #endif + #endif // ifdef USES_P053 // Starting 2022/08/18 // Use get_build_nr() value for settings transitions. - // This value will also be shown when building using PlatformIO, when showing the Compile time defines + // This value will also be shown when building using PlatformIO, when showing the Compile time defines Settings.Build = get_build_nr(); Settings.StructSize = sizeof(Settings); @@ -431,26 +469,29 @@ void fileSystemCheck() { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("fileSystemCheck")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER addLog(LOG_LEVEL_INFO, F("FS : Mounting...")); #if defined(ESP32) && defined(USE_LITTLEFS) - if (getPartionCount(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS) != 0 + + if ((getPartionCount(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS) != 0) && ESPEASY_FS.begin()) -#else +#else // if defined(ESP32) && defined(USE_LITTLEFS) + if (ESPEASY_FS.begin()) -#endif +#endif // if defined(ESP32) && defined(USE_LITTLEFS) { clearAllCaches(); + if (loglevelActiveFor(LOG_LEVEL_INFO)) { addLogMove(LOG_LEVEL_INFO, strformat( - F("FS : " + F("FS : " #ifdef USE_LITTLEFS - "LittleFS" -#else - "SPIFFS" -#endif - " mount successful, used %u bytes of %u"), - SpiffsUsedBytes(), SpiffsTotalBytes())); + "LittleFS" +#else // ifdef USE_LITTLEFS + "SPIFFS" +#endif // ifdef USE_LITTLEFS + " mount successful, used %u bytes of %u"), + SpiffsUsedBytes(), SpiffsTotalBytes())); } // Run garbage collection before any file is open. @@ -461,15 +502,16 @@ void fileSystemCheck() } fs::File f = tryOpenFile(SettingsType::getSettingsFileName(SettingsType::Enum::BasicSettings_Type), "r"); - if (f) { - f.close(); + + if (f) { + f.close(); } else { ResetFactory(false); } } else { - const __FlashStringHelper * log = F("FS : Mount failed"); + const __FlashStringHelper *log = F("FS : Mount failed"); serialPrintln(log); addLog(LOG_LEVEL_ERROR, log); ResetFactory(); @@ -488,6 +530,7 @@ bool FS_format() { // #endif // #else return ESPEASY_FS.format(); + // #endif } @@ -497,7 +540,7 @@ bool FS_format() { int getPartionCount(uint8_t pType, uint8_t pSubType) { esp_partition_type_t partitionType = static_cast(pType); - esp_partition_subtype_t subtype = static_cast(pSubType); + esp_partition_subtype_t subtype = static_cast(pSubType); esp_partition_iterator_t _mypartiterator = esp_partition_find(partitionType, subtype, NULL); int nrPartitions = 0; @@ -510,19 +553,18 @@ int getPartionCount(uint8_t pType, uint8_t pSubType) { return nrPartitions; } - -#endif +#endif // ifdef ESP32 #ifdef ESP8266 bool clearPartition(ESP8266_partition_type ptype) { uint32_t address; - int32_t size; - int32_t sector = getPartitionInfo(ESP8266_partition_type::rf_cal, address, size); + int32_t size; + int32_t sector = getPartitionInfo(ESP8266_partition_type::rf_cal, address, size); + while (size > 0) { - if (!ESP.flashEraseSector(sector)) return false; + if (!ESP.flashEraseSector(sector)) { return false; } ++sector; size -= SPI_FLASH_SEC_SIZE; - } return true; } @@ -535,7 +577,7 @@ bool clearWiFiSDKpartition() { return clearPartition(ESP8266_partition_type::wifi); } -#endif +#endif // ifdef ESP8266 /********************************************************************************************\ @@ -548,9 +590,9 @@ bool GarbageCollection() { START_TIMER; if (ESPEASY_FS.gc()) { -#ifndef BUILD_NO_DEBUG +# ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_INFO, F("FS : Success garbage collection")); -#endif +# endif // ifndef BUILD_NO_DEBUG STOP_TIMER(FS_GC_SUCCESS); return true; } @@ -570,8 +612,8 @@ String SaveSettings(bool forFactoryReset) { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SaveSettings")); - #endif - String err; + #endif // ifndef BUILD_NO_RAM_TRACKER + String err; { Settings.StructSize = sizeof(Settings); @@ -585,21 +627,25 @@ String SaveSettings(bool forFactoryReset) } if (!COMPUTE_STRUCT_CHECKSUM_UPDATE(SettingsStruct, Settings) - /* - computeChecksum( - Settings.md5, - reinterpret_cast(&Settings), - sizeof(SettingsStruct), - offsetof(SettingsStruct, md5)) - */ + + /* + computeChecksum( + Settings.md5, + reinterpret_cast(&Settings), + sizeof(SettingsStruct), + offsetof(SettingsStruct, md5)) + */ ) { - err = SaveToFile(SettingsType::getSettingsFileName(SettingsType::Enum::BasicSettings_Type).c_str(), 0, reinterpret_cast(&Settings), sizeof(Settings)); - } -#ifndef BUILD_NO_DEBUG + err = SaveToFile(SettingsType::getSettingsFileName(SettingsType::Enum::BasicSettings_Type).c_str(), + 0, + reinterpret_cast(&Settings), + sizeof(Settings)); + } +#ifndef BUILD_NO_DEBUG else { addLog(LOG_LEVEL_INFO, F("Skip saving settings, not changed")); } -#endif +#endif // ifndef BUILD_NO_DEBUG } if (err.length()) { @@ -607,10 +653,11 @@ String SaveSettings(bool forFactoryReset) } #ifndef BUILD_MINIMAL_OTA + // Must check this after saving, or else it is not possible to fix multiple // issues which can only corrected on different pages. if (!SettingsCheck(err)) { return err; } -#endif +#endif // ifndef BUILD_MINIMAL_OTA // } @@ -620,7 +667,7 @@ String SaveSettings(bool forFactoryReset) } String SaveSecuritySettings(bool forFactoryReset) { - String err; + String err; SecuritySettings.validate(); memcpy(SecuritySettings.ProgmemMd5, CRCValues.runTimeMD5, 16); @@ -631,23 +678,26 @@ String SaveSecuritySettings(bool forFactoryReset) { if (SecuritySettings.updateChecksum()) { // Settings have changed, save to file. - err = SaveToFile(SettingsType::getSettingsFileName(SettingsType::Enum::SecuritySettings_Type).c_str(), 0, reinterpret_cast(&SecuritySettings), sizeof(SecuritySettings)); + err = SaveToFile(SettingsType::getSettingsFileName(SettingsType::Enum::SecuritySettings_Type).c_str(), + 0, + reinterpret_cast(&SecuritySettings), + sizeof(SecuritySettings)); // Security settings are saved, may be update of WiFi settings or hostname. if (!forFactoryReset && !NetworkConnected()) { - if (SecuritySettings.hasWiFiCredentials() && active_network_medium == NetworkMedium_t::WIFI) { + if (SecuritySettings.hasWiFiCredentials() && (active_network_medium == NetworkMedium_t::WIFI)) { WiFiEventData.wifiConnectAttemptNeeded = true; WiFi_AP_Candidates.force_reload(); // Force reload of the credentials and found APs from the last scan resetWiFi(); AttemptWiFiConnect(); } } - } + } #ifndef BUILD_NO_DEBUG else { addLog(LOG_LEVEL_INFO, F("Skip saving SecuritySettings, not changed")); } -#endif +#endif // ifndef BUILD_NO_DEBUG // FIXME TD-er: How to check if these have changed? if (forFactoryReset) { @@ -655,13 +705,16 @@ String SaveSecuritySettings(bool forFactoryReset) { } ExtendedControllerCredentials.save(); - if (!forFactoryReset) + + if (!forFactoryReset) { afterloadSettings(); + } return err; } void afterloadSettings() { ExtraTaskSettings.clear(); // make sure these will not contain old settings. + if ((Settings.Version != VERSION) || (Settings.PID != ESP_PROJECT_PID)) { // Not valid settings, so do not continue return; @@ -670,7 +723,9 @@ void afterloadSettings() { // Load ResetFactoryDefaultPreference from provisioning.dat if available. // FIXME TD-er: Must actually move content of Provisioning.dat to NVS and then delete file uint32_t pref_temp = Settings.ResetFactoryDefaultPreference; + #ifdef ESP32 + if (pref_temp == 0) { if (ResetFactoryDefaultPreference.getPreference() == 0) { // Try loading from NVS @@ -679,25 +734,30 @@ void afterloadSettings() { pref_temp = ResetFactoryDefaultPreference.getPreference(); } } - #endif + #endif // ifdef ESP32 #if FEATURE_CUSTOM_PROVISIONING + if (fileExists(getFileName(FileType::PROVISIONING_DAT))) { MakeProvisioningSettings(ProvisioningSettings); + if (ProvisioningSettings.get()) { loadProvisioningSettings(*ProvisioningSettings); + if (ProvisioningSettings->matchingFlashSize()) { - if (pref_temp == 0 && ProvisioningSettings->ResetFactoryDefaultPreference.getPreference() != 0) + if ((pref_temp == 0) && (ProvisioningSettings->ResetFactoryDefaultPreference.getPreference() != 0)) { pref_temp = ProvisioningSettings->ResetFactoryDefaultPreference.getPreference(); + } } } } - #endif + #endif // if FEATURE_CUSTOM_PROVISIONING // TODO TD-er: Try to get the information from more locations to make it more persistent // Maybe EEPROM location? ResetFactoryDefaultPreference_struct pref(pref_temp); + if (modelMatchingFlashSize(pref.getDeviceModel())) { ResetFactoryDefaultPreference = pref_temp; } @@ -705,7 +765,7 @@ void afterloadSettings() { Scheduler.setEcoMode(Settings.EcoPowerMode()); #ifdef ESP32 setCpuFrequencyMhz(Settings.EcoPowerMode() ? getCPU_MinFreqMHz() : getCPU_MaxFreqMHz()); - #endif + #endif // ifdef ESP32 if (!Settings.UseRules) { eventQueue.clear(); @@ -721,15 +781,19 @@ String LoadSettings() clearAllButTaskCaches(); #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("LoadSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER uint8_t oldSettingsChecksum[16] = { 0 }; memcpy(oldSettingsChecksum, Settings.md5, 16); - String err; + String err; - err = LoadFromFile(SettingsType::getSettingsFileName(SettingsType::Enum::BasicSettings_Type).c_str(), 0, reinterpret_cast(&Settings), sizeof(SettingsStruct)); + err = + LoadFromFile(SettingsType::getSettingsFileName(SettingsType::Enum::BasicSettings_Type).c_str(), + 0, + reinterpret_cast(&Settings), + sizeof(SettingsStruct)); if (memcmp(oldSettingsChecksum, Settings.md5, 16) != 0) { // File has changed, so need to flush all task caches. @@ -741,22 +805,27 @@ String LoadSettings() } if (!BuildFixes()) { - #ifndef BUILD_NO_DEBUG + if (COMPUTE_STRUCT_CHECKSUM(SettingsStruct, Settings)) { - addLog(LOG_LEVEL_INFO, concat(F("CRC : Settings CRC"), F("...OK"))); - } else{ + addLog(LOG_LEVEL_INFO, concat(F("CRC : Settings CRC"), F("...OK"))); + } else { addLog(LOG_LEVEL_ERROR, concat(F("CRC : Settings CRC"), F("...FAIL"))); } - #endif + #endif // ifndef BUILD_NO_DEBUG } Settings.validate(); initSerial(); - err = LoadFromFile(SettingsType::getSettingsFileName(SettingsType::Enum::SecuritySettings_Type).c_str(), 0, reinterpret_cast(&SecuritySettings), sizeof(SecurityStruct)); + err = + LoadFromFile(SettingsType::getSettingsFileName(SettingsType::Enum::SecuritySettings_Type).c_str(), + 0, + reinterpret_cast(&SecuritySettings), + sizeof(SecurityStruct)); #ifndef BUILD_NO_DEBUG + if (SecuritySettings.checksumMatch()) { addLog(LOG_LEVEL_INFO, concat(F("CRC : SecuritySettings CRC"), F("...OK "))); @@ -767,7 +836,7 @@ String LoadSettings() else { addLog(LOG_LEVEL_ERROR, concat(F("CRC : SecuritySettings CRC"), F("...FAIL"))); } -#endif +#endif // ifndef BUILD_NO_DEBUG ExtendedControllerCredentials.load(); @@ -778,8 +847,6 @@ String LoadSettings() return err; } - - /********************************************************************************************\ Disable Plugin, based on bootFailedCount \*********************************************************************************************/ @@ -801,16 +868,16 @@ uint8_t disablePlugin(uint8_t bootFailedCount) { uint8_t disableAllPlugins(uint8_t bootFailedCount) { if (bootFailedCount > 0) { --bootFailedCount; + for (taskIndex_t i = 0; i < TASKS_MAX; ++i) { - // Disable temporarily as unit crashed - // FIXME TD-er: Should this be stored? - Settings.TaskDeviceEnabled[i] = false; + // Disable temporarily as unit crashed + // FIXME TD-er: Should this be stored? + Settings.TaskDeviceEnabled[i] = false; } } return bootFailedCount; } - /********************************************************************************************\ Disable Controller, based on bootFailedCount \*********************************************************************************************/ @@ -830,6 +897,7 @@ uint8_t disableController(uint8_t bootFailedCount) { uint8_t disableAllControllers(uint8_t bootFailedCount) { if (bootFailedCount > 0) { --bootFailedCount; + for (controllerIndex_t i = 0; i < CONTROLLER_MAX; ++i) { Settings.ControllerEnabled[i] = false; } @@ -837,7 +905,6 @@ uint8_t disableAllControllers(uint8_t bootFailedCount) { return bootFailedCount; } - /********************************************************************************************\ Disable Notification, based on bootFailedCount \*********************************************************************************************/ @@ -858,13 +925,15 @@ uint8_t disableNotification(uint8_t bootFailedCount) { uint8_t disableAllNotifications(uint8_t bootFailedCount) { if (bootFailedCount > 0) { --bootFailedCount; + for (uint8_t i = 0; i < NOTIFICATION_MAX; ++i) { - Settings.NotificationEnabled[i] = false; + Settings.NotificationEnabled[i] = false; } } return bootFailedCount; } -#endif + +#endif // if FEATURE_NOTIFIER /********************************************************************************************\ Disable Rules, based on bootFailedCount @@ -877,7 +946,6 @@ uint8_t disableRules(uint8_t bootFailedCount) { return bootFailedCount; } - bool getAndLogSettingsParameters(bool read, SettingsType::Enum settingsType, int index, int& offset, int& max_size) { #ifndef BUILD_NO_DEBUG @@ -891,21 +959,26 @@ bool getAndLogSettingsParameters(bool read, SettingsType::Enum settingsType, int return SettingsType::getSettingsParameters(settingsType, index, offset, max_size); } - /********************************************************************************************\ Load array of Strings from Custom settings Use maxStringLength = 0 to optimize for size (strings will be concatenated) \*********************************************************************************************/ -String LoadStringArray(SettingsType::Enum settingsType, int index, String strings[], uint16_t nrStrings, uint16_t maxStringLength, uint32_t offset_in_block) +String LoadStringArray(SettingsType::Enum settingsType, + int index, + String strings[], + uint16_t nrStrings, + uint16_t maxStringLength, + uint32_t offset_in_block) { int offset, max_size; + if (!SettingsType::getSettingsParameters(settingsType, index, offset, max_size)) { #ifndef BUILD_NO_DEBUG return F("Invalid index for custom settings"); - #else + #else // ifndef BUILD_NO_DEBUG return F("Save error"); - #endif + #endif // ifndef BUILD_NO_DEBUG } const uint32_t bufferSize = 128; @@ -913,7 +986,7 @@ String LoadStringArray(SettingsType::Enum settingsType, int index, String string // FIXME TD-er: For now stack allocated, may need to be heap allocated? if (maxStringLength >= bufferSize) { return F("Max 128 chars allowed"); } - char buffer[bufferSize] = {0}; + char buffer[bufferSize] = { 0 }; String result; uint32_t readPos = offset_in_block; @@ -921,16 +994,16 @@ String LoadStringArray(SettingsType::Enum settingsType, int index, String string uint32_t stringCount = 0; const uint16_t estimatedStringSize = maxStringLength > 0 ? maxStringLength : bufferSize; - String tmpString; + String tmpString; tmpString.reserve(estimatedStringSize); { while (stringCount < nrStrings && static_cast(readPos) < max_size) { const uint32_t readSize = std::min(bufferSize, max_size - readPos); result += LoadFromFile(settingsType, - index, - reinterpret_cast(&buffer), - readSize, - readPos); + index, + reinterpret_cast(&buffer), + readSize, + readPos); for (uint32_t i = 0; i < readSize && stringCount < nrStrings; ++i) { const uint32_t curPos = readPos + i; @@ -967,25 +1040,32 @@ String LoadStringArray(SettingsType::Enum settingsType, int index, String string Save array of Strings from Custom settings Use maxStringLength = 0 to optimize for size (strings will be concatenated) \*********************************************************************************************/ -String SaveStringArray(SettingsType::Enum settingsType, int index, const String strings[], uint16_t nrStrings, uint16_t maxStringLength, uint32_t posInBlock) +String SaveStringArray(SettingsType::Enum settingsType, + int index, + const String strings[], + uint16_t nrStrings, + uint16_t maxStringLength, + uint32_t posInBlock) { // FIXME TD-er: Must add some check to see if the existing data has changed before saving. int offset, max_size; + if (!SettingsType::getSettingsParameters(settingsType, index, offset, max_size)) { #ifndef BUILD_NO_DEBUG return F("Invalid index for custom settings"); - #else + #else // ifndef BUILD_NO_DEBUG return F("Save error"); - #endif + #endif // ifndef BUILD_NO_DEBUG } #ifdef ESP8266 uint16_t bufferSize = 256; - #endif + #endif // ifdef ESP8266 #ifdef ESP32 uint16_t bufferSize = 1024; - #endif + #endif // ifdef ESP32 + if (bufferSize > max_size) { bufferSize = max_size; } @@ -1015,7 +1095,8 @@ String SaveStringArray(SettingsType::Enum settingsType, int index, const String } int bufpos = 0; - for ( ; bufpos < bufferSize && stringCount < nrStrings; ++bufpos) { + + for (; bufpos < bufferSize && stringCount < nrStrings; ++bufpos) { if (stringReadPos == 0) { // We're at the start of a string curStringLength = strings[stringCount].length(); @@ -1057,6 +1138,7 @@ String SaveStringArray(SettingsType::Enum settingsType, int index, const String } #if FEATURE_EXTENDED_CUSTOM_SETTINGS + if ((SettingsType::Enum::CustomTaskSettings_Type == settingsType) && ((writePos - posInBlock) <= DAT_TASKS_CUSTOM_SIZE)) { // Not needed, so can be deleted DeleteExtendedCustomTaskSettingsFile(settingsType, index); @@ -1069,8 +1151,6 @@ String SaveStringArray(SettingsType::Enum settingsType, int index, const String return result; } - - /********************************************************************************************\ Save Task settings to file system \*********************************************************************************************/ @@ -1078,14 +1158,14 @@ String SaveTaskSettings(taskIndex_t TaskIndex) { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SaveTaskSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER if (ExtraTaskSettings.TaskIndex != TaskIndex) { #ifndef BUILD_NO_DEBUG return F("SaveTaskSettings taskIndex does not match"); - #else + #else // ifndef BUILD_NO_DEBUG return F("Save error"); - #endif + #endif // ifndef BUILD_NO_DEBUG } START_TIMER @@ -1094,32 +1174,34 @@ String SaveTaskSettings(taskIndex_t TaskIndex) if (!Cache.matchChecksumExtraTaskSettings(TaskIndex, ExtraTaskSettings.computeChecksum())) { // Clear task device value names before saving, will generate again when loading them later. ExtraTaskSettings.clearDefaultTaskDeviceValueNames(); - ExtraTaskSettings.validate(); // Validate before saving will reduce nr of saves as it is more likely to not have changed the next time it will be saved. + ExtraTaskSettings.validate(); // Validate before saving will reduce nr of saves as it is more likely to not have changed the next time + // it will be saved. // Call to validate() may have changed the content, so re-compute the checksum. - // This is how it is now stored, so we can now also update the + // This is how it is now stored, so we can now also update the // ExtraTaskSettings cache. This may prevent a reload. Cache.updateExtraTaskSettingsCache_afterLoad_Save(); err = SaveToFile(SettingsType::Enum::TaskSettings_Type, - TaskIndex, - reinterpret_cast(&ExtraTaskSettings), - sizeof(struct ExtraTaskSettingsStruct)); + TaskIndex, + reinterpret_cast(&ExtraTaskSettings), + sizeof(struct ExtraTaskSettingsStruct)); #if !defined(PLUGIN_BUILD_MINIMAL_OTA) && !defined(ESP8266_1M) + if (err.isEmpty()) { err = checkTaskSettings(TaskIndex); } -#endif +#endif // if !defined(PLUGIN_BUILD_MINIMAL_OTA) && !defined(ESP8266_1M) + // FIXME TD-er: Is this still needed as it is also cleared on PLUGIN_INIT and PLUGIN_EXIT? UserVar.clear_computed(ExtraTaskSettings.TaskIndex); - } + } #ifndef LIMIT_BUILD_SIZE else { addLog(LOG_LEVEL_INFO, F("Skip saving task settings, not changed")); - } -#endif +#endif // ifndef LIMIT_BUILD_SIZE STOP_TIMER(SAVE_TASK_SETTINGS); return err; } @@ -1132,6 +1214,7 @@ String LoadTaskSettings(taskIndex_t TaskIndex) if (ExtraTaskSettings.TaskIndex == TaskIndex) { return EMPTY_STRING; // already loaded } + if (!validTaskIndex(TaskIndex)) { return EMPTY_STRING; // Un-initialized task index. } @@ -1139,24 +1222,26 @@ String LoadTaskSettings(taskIndex_t TaskIndex) ExtraTaskSettings.clear(); const deviceIndex_t DeviceIndex = getDeviceIndex_from_TaskIndex(TaskIndex); + if (!validDeviceIndex(DeviceIndex)) { // No need to load from storage, as there is no plugin assigned to this task. ExtraTaskSettings.TaskIndex = TaskIndex; // Needed when an empty task was requested // FIXME TD-er: Do we need to keep a cache of an empty task? - // Maybe better to do this? - Cache.clearTaskCache(TaskIndex); -// Cache.updateExtraTaskSettingsCache_afterLoad_Save(); + // Maybe better to do this? + Cache.clearTaskCache(TaskIndex); + + // Cache.updateExtraTaskSettingsCache_afterLoad_Save(); return EMPTY_STRING; } #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("LoadTaskSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER const String result = LoadFromFile( - SettingsType::Enum::TaskSettings_Type, - TaskIndex, - reinterpret_cast(&ExtraTaskSettings), + SettingsType::Enum::TaskSettings_Type, + TaskIndex, + reinterpret_cast(&ExtraTaskSettings), sizeof(struct ExtraTaskSettingsStruct)); // After loading, some settings may need patching. @@ -1166,10 +1251,10 @@ String LoadTaskSettings(taskIndex_t TaskIndex) // Nr of decimals cannot be configured, so set them to 0 just to be sure. for (uint8_t i = 0; i < VARS_PER_TASK; ++i) { ExtraTaskSettings.TaskDeviceValueDecimals[i] = 0; - } + } } loadDefaultTaskValueNames_ifEmpty(TaskIndex); - + ExtraTaskSettings.validate(); Cache.updateExtraTaskSettingsCache_afterLoad_Save(); STOP_TIMER(LOAD_TASK_SETTINGS); @@ -1183,7 +1268,7 @@ bool _CDN_url_loaded = false; String get_CDN_url_custom() { if (!_CDN_url_loaded) { - String strings[] = {EMPTY_STRING}; + String strings[] = { EMPTY_STRING }; LoadStringArray( SettingsType::Enum::CdnSettings_Type, 0, @@ -1194,9 +1279,10 @@ String get_CDN_url_custom() { return _CDN_url_cache; } -void set_CDN_url_custom(const String &url) { +void set_CDN_url_custom(const String& url) { _CDN_url_cache = url; _CDN_url_cache.trim(); + if (!_CDN_url_cache.isEmpty() && !_CDN_url_cache.endsWith(F("/"))) { _CDN_url_cache.concat('/'); } @@ -1219,6 +1305,7 @@ void set_CDN_url_custom(const String &url) { SettingsType::Enum::CdnSettings_Type, 0, strings, NR_ELEMENTS(strings), 255, 0); } + #endif // if FEATURE_ALTERNATIVE_CDN_URL /********************************************************************************************\ @@ -1228,7 +1315,7 @@ String SaveCustomTaskSettings(taskIndex_t TaskIndex, const uint8_t *memAddress, { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SaveCustomTaskSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER return SaveToFile(SettingsType::Enum::CustomTaskSettings_Type, TaskIndex, memAddress, datasize, posInBlock); } @@ -1240,7 +1327,7 @@ String SaveCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SaveCustomTaskSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER return SaveStringArray( SettingsType::Enum::CustomTaskSettings_Type, TaskIndex, strings, nrStrings, maxStringLength, posInBlock); @@ -1267,7 +1354,7 @@ String LoadCustomTaskSettings(taskIndex_t TaskIndex, uint8_t *memAddress, int da START_TIMER; #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("LoadCustomTaskSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER String result = LoadFromFile(SettingsType::Enum::CustomTaskSettings_Type, TaskIndex, memAddress, datasize, offset_in_block); STOP_TIMER(LOAD_CUSTOM_TASK_STATS); return result; @@ -1282,10 +1369,10 @@ String LoadCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t START_TIMER; #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("LoadCustomTaskSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER String result = LoadStringArray(SettingsType::Enum::CustomTaskSettings_Type, - TaskIndex, - strings, nrStrings, maxStringLength, offset_in_block); + TaskIndex, + strings, nrStrings, maxStringLength, offset_in_block); STOP_TIMER(LOAD_CUSTOM_TASK_STATS); return result; } @@ -1297,7 +1384,7 @@ String SaveControllerSettings(controllerIndex_t ControllerIndex, ControllerSetti { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SaveControllerSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER START_TIMER; @@ -1308,16 +1395,16 @@ String SaveControllerSettings(controllerIndex_t ControllerIndex, ControllerSetti if (checksum == (Cache.controllerSettings_checksums[ControllerIndex])) { #ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_INFO, concat(F("Skip saving ControllerSettings: "), checksum.toString())); -#endif +#endif // ifndef BUILD_NO_DEBUG return EMPTY_STRING; } const String res = SaveToFile(SettingsType::Enum::ControllerSettings_Type, ControllerIndex, - reinterpret_cast(&controller_settings), sizeof(controller_settings)); + reinterpret_cast(&controller_settings), sizeof(controller_settings)); Cache.controllerSettings_checksums[ControllerIndex] = checksum; #ifdef ESP32 Cache.setControllerSettings(ControllerIndex, controller_settings); - #endif + #endif // ifdef ESP32 STOP_TIMER(SAVE_CONTROLLER_SETTINGS); return res; @@ -1329,14 +1416,15 @@ String SaveControllerSettings(controllerIndex_t ControllerIndex, ControllerSetti String LoadControllerSettings(controllerIndex_t ControllerIndex, ControllerSettingsStruct& controller_settings) { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("LoadControllerSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER START_TIMER #ifdef ESP32 + if (Cache.getControllerSettings(ControllerIndex, controller_settings)) { STOP_TIMER(LOAD_CONTROLLER_SETTINGS_C); return EMPTY_STRING; } - #endif + #endif // ifdef ESP32 String result = LoadFromFile(SettingsType::Enum::ControllerSettings_Type, ControllerIndex, reinterpret_cast(&controller_settings), sizeof(controller_settings)); @@ -1346,7 +1434,7 @@ String LoadControllerSettings(controllerIndex_t ControllerIndex, ControllerSetti Cache.controllerSettings_checksums[ControllerIndex] = controller_settings.computeChecksum(); #ifdef ESP32 Cache.setControllerSettings(ControllerIndex, controller_settings); - #endif + #endif // ifdef ESP32 STOP_TIMER(LOAD_CONTROLLER_SETTINGS); return result; } @@ -1358,7 +1446,7 @@ String ClearCustomControllerSettings(controllerIndex_t ControllerIndex) { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("ClearCustomControllerSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER // addLog(LOG_LEVEL_DEBUG, F("Clearing custom controller settings")); return ClearInFile(SettingsType::Enum::CustomControllerSettings_Type, ControllerIndex); @@ -1371,7 +1459,7 @@ String SaveCustomControllerSettings(controllerIndex_t ControllerIndex, const uin { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SaveCustomControllerSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER return SaveToFile(SettingsType::Enum::CustomControllerSettings_Type, ControllerIndex, memAddress, datasize); } @@ -1382,25 +1470,27 @@ String LoadCustomControllerSettings(controllerIndex_t ControllerIndex, uint8_t * { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("LoadCustomControllerSettings")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER return LoadFromFile(SettingsType::Enum::CustomControllerSettings_Type, ControllerIndex, memAddress, datasize); } - #if FEATURE_CUSTOM_PROVISIONING + /********************************************************************************************\ Save Provisioning Settings \*********************************************************************************************/ String saveProvisioningSettings(ProvisioningStruct& ProvisioningSettings) { - String err; + String err; ProvisioningSettings.validate(); memcpy(ProvisioningSettings.ProgmemMd5, CRCValues.runTimeMD5, 16); + if (!COMPUTE_STRUCT_CHECKSUM_UPDATE(ProvisioningStruct, ProvisioningSettings)) { // Settings have changed, save to file. - err = SaveToFile_trunc(getFileName(FileType::PROVISIONING_DAT, 0).c_str(), 0, (uint8_t *)&ProvisioningSettings, sizeof(ProvisioningStruct)); + err = + SaveToFile_trunc(getFileName(FileType::PROVISIONING_DAT, 0).c_str(), 0, (uint8_t *)&ProvisioningSettings, sizeof(ProvisioningStruct)); } return err; } @@ -1410,8 +1500,13 @@ String saveProvisioningSettings(ProvisioningStruct& ProvisioningSettings) \*********************************************************************************************/ String loadProvisioningSettings(ProvisioningStruct& ProvisioningSettings) { - String err = LoadFromFile(getFileName(FileType::PROVISIONING_DAT, 0).c_str(), 0, (uint8_t *)&ProvisioningSettings, sizeof(ProvisioningStruct)); -#ifndef BUILD_NO_DEBUG + String err = LoadFromFile(getFileName(FileType::PROVISIONING_DAT, 0).c_str(), + 0, + (uint8_t *)&ProvisioningSettings, + sizeof(ProvisioningStruct)); + +# ifndef BUILD_NO_DEBUG + if (COMPUTE_STRUCT_CHECKSUM(ProvisioningStruct, ProvisioningSettings)) { addLog(LOG_LEVEL_INFO, F("CRC : ProvisioningSettings CRC ...OK ")); @@ -1423,22 +1518,23 @@ String loadProvisioningSettings(ProvisioningStruct& ProvisioningSettings) else { addLog(LOG_LEVEL_ERROR, F("CRC : ProvisioningSettings CRC ...FAIL")); } -#endif +# endif // ifndef BUILD_NO_DEBUG ProvisioningSettings.validate(); return err; } -#endif +#endif // if FEATURE_CUSTOM_PROVISIONING #if FEATURE_NOTIFIER + /********************************************************************************************\ Save Controller settings to file system \*********************************************************************************************/ String SaveNotificationSettings(int NotificationIndex, const uint8_t *memAddress, int datasize) { - #ifndef BUILD_NO_RAM_TRACKER + # ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SaveNotificationSettings")); - #endif + # endif // ifndef BUILD_NO_RAM_TRACKER return SaveToFile(SettingsType::Enum::NotificationSettings_Type, NotificationIndex, memAddress, datasize); } @@ -1447,12 +1543,14 @@ String SaveNotificationSettings(int NotificationIndex, const uint8_t *memAddress \*********************************************************************************************/ String LoadNotificationSettings(int NotificationIndex, uint8_t *memAddress, int datasize) { - #ifndef BUILD_NO_RAM_TRACKER + # ifndef BUILD_NO_RAM_TRACKER checkRAM(F("LoadNotificationSettings")); - #endif + # endif // ifndef BUILD_NO_RAM_TRACKER return LoadFromFile(SettingsType::Enum::NotificationSettings_Type, NotificationIndex, memAddress, datasize); } -#endif + +#endif // if FEATURE_NOTIFIER + /********************************************************************************************\ Init a file with zeros on file system \*********************************************************************************************/ @@ -1460,7 +1558,7 @@ String InitFile(const String& fname, int datasize) { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("InitFile")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER FLASH_GUARD(); fs::File f = tryOpenFile(fname, "w"); @@ -1486,7 +1584,7 @@ String InitFile(SettingsType::Enum settingsType) String InitFile(SettingsType::SettingsFileEnum file_type) { - return InitFile(SettingsType::getSettingsFileName(file_type), + return InitFile(SettingsType::getSettingsFileName(file_type), SettingsType::getInitFileSize(file_type)); } @@ -1507,36 +1605,37 @@ String SaveToFile_trunc(const char *fname, int index, const uint8_t *memAddress, String doSaveToFile(const char *fname, int index, const uint8_t *memAddress, int datasize, const char *mode) { #ifndef BUILD_NO_DEBUG -#ifndef ESP32 +# ifndef ESP32 if (allocatedOnStack(memAddress)) { addLog(LOG_LEVEL_ERROR, strformat(F("SaveToFile: %s ERROR, Data allocated on stack"), fname)); // return log; // FIXME TD-er: Should this be considered a breaking error? } -#endif // ifndef ESP32 -#endif +# endif // ifndef ESP32 +#endif // ifndef BUILD_NO_DEBUG if (index < 0) { #ifndef BUILD_NO_DEBUG const String log = strformat(F("SaveToFile: %s ERROR, invalid position in file"), fname); - #else + #else // ifndef BUILD_NO_DEBUG const String log = F("Save error"); - #endif + #endif // ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_ERROR, log); return log; } START_TIMER; #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SaveToFile")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER FLASH_GUARD(); - + #ifndef BUILD_NO_DEBUG + if (loglevelActiveFor(LOG_LEVEL_INFO)) { addLog(LOG_LEVEL_INFO, concat(F("SaveToFile: free stack: "), getCurrentFreeStack())); } - #endif + #endif // ifndef BUILD_NO_DEBUG delay(1); unsigned long timer = millis() + 50; fs::File f = tryOpenFile(fname, mode); @@ -1567,26 +1666,28 @@ String doSaveToFile(const char *fname, int index, const uint8_t *memAddress, int } f.close(); #ifndef BUILD_NO_DEBUG + if (loglevelActiveFor(LOG_LEVEL_INFO)) { addLogMove(LOG_LEVEL_INFO, strformat(F("FILE : Saved %s offset: %d size: %d"), fname, index, datasize)); } - #endif + #endif // ifndef BUILD_NO_DEBUG } else { #ifndef BUILD_NO_DEBUG const String log = strformat(F("SaveToFile: %s ERROR, Cannot save to file"), fname); - #else + #else // ifndef BUILD_NO_DEBUG const String log = F("Save error"); - #endif + #endif // ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_ERROR, log); return log; } STOP_TIMER(SAVEFILE_STATS); #ifndef BUILD_NO_DEBUG + if (loglevelActiveFor(LOG_LEVEL_INFO)) { addLogMove(LOG_LEVEL_INFO, concat(F("SaveToFile: free stack after: "), getCurrentFreeStack())); } - #endif + #endif // ifndef BUILD_NO_DEBUG // OK return EMPTY_STRING; @@ -1600,9 +1701,9 @@ String ClearInFile(const char *fname, int index, int datasize) if (index < 0) { #ifndef BUILD_NO_DEBUG const String log = strformat(F("ClearInFile: %s ERROR, invalid position in file"), fname); - #else + #else // ifndef BUILD_NO_DEBUG const String log = F("Save error"); - #endif + #endif // ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_ERROR, log); return log; @@ -1610,7 +1711,7 @@ String ClearInFile(const char *fname, int index, int datasize) #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("ClearInFile")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER FLASH_GUARD(); fs::File f = tryOpenFile(fname, "r+"); @@ -1628,9 +1729,9 @@ String ClearInFile(const char *fname, int index, int datasize) } else { #ifndef BUILD_NO_DEBUG const String log = strformat(F("ClearInFile: %s ERROR, Cannot save to file"), fname); - #else + #else // ifndef BUILD_NO_DEBUG const String log = F("Save error"); - #endif + #endif // ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_ERROR, log); return log; } @@ -1647,9 +1748,9 @@ String LoadFromFile(const char *fname, int offset, uint8_t *memAddress, int data if (offset < 0) { #ifndef BUILD_NO_DEBUG const String log = strformat(F("LoadFromFile: %s ERROR, invalid position in file"), fname); - #else + #else // ifndef BUILD_NO_DEBUG const String log = F("Load error"); - #endif + #endif // ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_ERROR, log); return log; } @@ -1657,14 +1758,15 @@ String LoadFromFile(const char *fname, int offset, uint8_t *memAddress, int data START_TIMER; #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("LoadFromFile")); - #endif - + #endif // ifndef BUILD_NO_RAM_TRACKER + fs::File f = tryOpenFile(fname, "r"); - SPIFFS_CHECK(f, fname); + SPIFFS_CHECK(f, fname); const int fileSize = f.size(); + if (fileSize > offset) { - SPIFFS_CHECK(f.seek(offset, fs::SeekSet), fname); - + SPIFFS_CHECK(f.seek(offset, fs::SeekSet), fname); + if (fileSize < (offset + datasize)) { const int newdatasize = datasize + offset - fileSize; @@ -1691,24 +1793,26 @@ String getSettingsFileIndexRangeError(bool read, SettingsType::Enum settingsType return concat(F("Unknown settingsType: "), static_cast(settingsType)); } String error = read ? F("Load") : F("Save"); + #ifndef BUILD_NO_DEBUG error += SettingsType::getSettingsTypeString(settingsType); error += concat(F(" index out of range: "), index); - #else + #else // ifndef BUILD_NO_DEBUG error += F(" error"); - #endif + #endif // ifndef BUILD_NO_DEBUG return error; } String getSettingsFileDatasizeError(bool read, SettingsType::Enum settingsType, int index, int datasize, int max_size) { String error = read ? F("Load") : F("Save"); + #ifndef BUILD_NO_DEBUG error += SettingsType::getSettingsTypeString(settingsType); error += strformat(F("(%d) datasize(%d) > max_size(%d)"), index, datasize, max_size); - #else + #else // ifndef BUILD_NO_DEBUG error += F(" error"); - #endif - + #endif // ifndef BUILD_NO_DEBUG + return error; } @@ -1757,7 +1861,7 @@ String LoadFromFile(SettingsType::Enum settingsType, int index, uint8_t *memAddr #if FEATURE_EXTENDED_CUSTOM_SETTINGS , taskIndex #endif // if FEATURE_EXTENDED_CUSTOM_SETTINGS - ); + ); return LoadFromFile(fname.c_str(), (offset + offset_in_block), memAddress + dataOffset, datasize); } @@ -1776,7 +1880,7 @@ String SaveToFile(SettingsType::Enum settingsType, int index, const uint8_t *mem int dataOffset = 0; #if FEATURE_EXTENDED_CUSTOM_SETTINGS - int taskIndex = INVALID_TASK_INDEX; // Use base filename + int taskIndex = INVALID_TASK_INDEX; // Use base filename if ((SettingsType::Enum::CustomTaskSettings_Type == settingsType) && (posInBlock + datasize > (DAT_TASKS_CUSTOM_SIZE))) { // max_size already handled above @@ -1785,8 +1889,9 @@ String SaveToFile(SettingsType::Enum settingsType, int index, const uint8_t *mem dataOffset = (DAT_TASKS_CUSTOM_SIZE - posInBlock); // Bytes to keep 'local' # ifndef BUILD_NO_DEBUG const String styp = SettingsType::getSettingsTypeString(settingsType); + if (loglevelActiveFor(LOG_LEVEL_INFO)) { - addLog(LOG_LEVEL_INFO, strformat(F("ExtraSaveToFile: %s file: %s size: %d pos: %d"), + addLog(LOG_LEVEL_INFO, strformat(F("ExtraSaveToFile: %s file: %s size: %d pos: %d"), styp.c_str(), fname.c_str(), dataOffset, posInBlock)); } # endif // ifndef BUILD_NO_DEBUG @@ -1808,24 +1913,27 @@ String SaveToFile(SettingsType::Enum settingsType, int index, const uint8_t *mem #if FEATURE_EXTENDED_CUSTOM_SETTINGS , taskIndex #endif // if FEATURE_EXTENDED_CUSTOM_SETTINGS - ); + ); + if (!fileExists(fname)) { #if FEATURE_EXTENDED_CUSTOM_SETTINGS + if (!validTaskIndex(taskIndex)) { #endif // if FEATURE_EXTENDED_CUSTOM_SETTINGS - InitFile(settingsType); + InitFile(settingsType); #if FEATURE_EXTENDED_CUSTOM_SETTINGS - } else { - InitFile(fname, DAT_TASKS_CUSTOM_EXTENSION_SIZE); // Initialize task-specific file - } + } else { + InitFile(fname, DAT_TASKS_CUSTOM_EXTENSION_SIZE); // Initialize task-specific file + } #endif // if FEATURE_EXTENDED_CUSTOM_SETTINGS } #ifndef BUILD_NO_DEBUG + if (loglevelActiveFor(LOG_LEVEL_INFO)) { addLog(LOG_LEVEL_INFO, concat(F("SaveToFile: "), SettingsType::getSettingsTypeString(settingsType)) + strformat(F(" file: %s task: %d"), fname.c_str(), index + 1)); } - #endif + #endif // ifndef BUILD_NO_DEBUG return SaveToFile(fname.c_str(), offset + posInBlock, memAddress + dataOffset, datasize); } @@ -1837,6 +1945,7 @@ String ClearInFile(SettingsType::Enum settingsType, int index) { return getSettingsFileIndexRangeError(read, settingsType, index); } #if FEATURE_EXTENDED_CUSTOM_SETTINGS + if (SettingsType::Enum::CustomTaskSettings_Type == settingsType) { max_size = DAT_TASKS_CUSTOM_SIZE; // Don't also wipe the external size inside the config.dat file... DeleteExtendedCustomTaskSettingsFile(settingsType, index); @@ -1855,6 +1964,7 @@ bool DeleteExtendedCustomTaskSettingsFile(SettingsType::Enum settingsType, int i if (fileExists(fname)) { const bool deleted = tryDeleteFile(fname); // Don't need the extension file anymore, so delete it # ifndef BUILD_NO_DEBUG + if (loglevelActiveFor(LOG_LEVEL_INFO)) { addLog(LOG_LEVEL_INFO, concat(F("CustomTaskSettings: Removing no longer needed file: "), fname)); } @@ -1864,7 +1974,9 @@ bool DeleteExtendedCustomTaskSettingsFile(SettingsType::Enum settingsType, int i } return false; } + #endif // if FEATURE_EXTENDED_CUSTOM_SETTINGS + /********************************************************************************************\ Check file system area settings \*********************************************************************************************/ @@ -1872,7 +1984,7 @@ int SpiffsSectors() { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("SpiffsSectors")); - #endif + #endif // ifndef BUILD_NO_RAM_TRACKER #if defined(ESP8266) # ifdef CORE_POST_2_6_0 uint32_t _sectorStart = ((uint32_t)&_FS_start - 0x40200000) / SPI_FLASH_SEC_SIZE; @@ -1905,6 +2017,7 @@ size_t SpiffsUsedBytes() { size_t SpiffsTotalBytes() { static size_t result = 1; // Do not output 0, this may be used in divisions. + if (result == 1) { #ifdef ESP32 result = ESPEASY_FS.totalBytes(); @@ -1920,9 +2033,10 @@ size_t SpiffsTotalBytes() { size_t SpiffsBlocksize() { static size_t result = 1; + if (result == 1) { #ifdef ESP32 - result = 8192; // Just assume 8k, since we cannot query it + result = 8192; // Just assume 8k, since we cannot query it #endif // ifdef ESP32 #ifdef ESP8266 fs::FSInfo fs_info; @@ -1935,9 +2049,10 @@ size_t SpiffsBlocksize() { size_t SpiffsPagesize() { static size_t result = 1; + if (result == 1) { #ifdef ESP32 - result = 256; // Just assume 256, since we cannot query it + result = 256; // Just assume 256, since we cannot query it #endif // ifdef ESP32 #ifdef ESP8266 fs::FSInfo fs_info; @@ -1949,7 +2064,7 @@ size_t SpiffsPagesize() { } size_t SpiffsFreeSpace() { - int freeSpace = SpiffsTotalBytes() - SpiffsUsedBytes(); + int freeSpace = SpiffsTotalBytes() - SpiffsUsedBytes(); const size_t blocksize = SpiffsBlocksize(); if (freeSpace < static_cast(2 * blocksize)) { @@ -1965,6 +2080,7 @@ bool SpiffsFull() { } #if FEATURE_RTC_CACHE_STORAGE + /********************************************************************************************\ Handling cached data \*********************************************************************************************/ @@ -1972,16 +2088,16 @@ String createCacheFilename(unsigned int count) { String fname; fname.reserve(16); - #ifdef ESP32 + # ifdef ESP32 fname = '/'; - #endif // ifdef ESP32 + # endif // ifdef ESP32 fname += strformat(F("cache_%d.bin"), count); return fname; } // Match string with an integer between '_' and ".bin" int getCacheFileCountFromFilename(const String& fname) { - if (!isCacheFile(fname)) return -1; + if (!isCacheFile(fname)) { return -1; } int startpos = fname.indexOf('_'); if (startpos < 0) { return -1; } @@ -2008,7 +2124,7 @@ bool getCacheFileCounters(uint16_t& lowest, uint16_t& highest, size_t& filesizeH lowest = 65535; highest = 0; filesizeHighest = 0; -#ifdef ESP8266 +# ifdef ESP8266 fs::Dir dir = ESPEASY_FS.openDir(F("cache")); while (dir.next()) { @@ -2026,8 +2142,8 @@ bool getCacheFileCounters(uint16_t& lowest, uint16_t& highest, size_t& filesizeH } } } -#endif // ESP8266 -#ifdef ESP32 +# endif // ESP8266 +# ifdef ESP32 fs::File root = ESPEASY_FS.open(F("/")); fs::File file = root.openNextFile(); @@ -2035,6 +2151,7 @@ bool getCacheFileCounters(uint16_t& lowest, uint16_t& highest, size_t& filesizeH { if (!file.isDirectory()) { const String fname(file.name()); + if (fname.startsWith(F("/cache")) || fname.startsWith(F("cache"))) { int count = getCacheFileCountFromFilename(fname); @@ -2047,18 +2164,18 @@ bool getCacheFileCounters(uint16_t& lowest, uint16_t& highest, size_t& filesizeH highest = count; filesizeHighest = file.size(); } -#ifndef BUILD_NO_DEBUG +# ifndef BUILD_NO_DEBUG } else { if (loglevelActiveFor(LOG_LEVEL_INFO)) { addLog(LOG_LEVEL_INFO, concat(F("RTC : Cannot get count from: "), fname)); } -#endif +# endif // ifndef BUILD_NO_DEBUG } } } file = root.openNextFile(); } -#endif // ESP32 +# endif // ESP32 if (lowest <= highest) { return true; @@ -2067,7 +2184,8 @@ bool getCacheFileCounters(uint16_t& lowest, uint16_t& highest, size_t& filesizeH highest = 0; return false; } -#endif + +#endif // if FEATURE_RTC_CACHE_STORAGE /********************************************************************************************\ Get partition table information @@ -2102,12 +2220,12 @@ String getPartitionType(uint8_t pType, uint8_t pSubType) { case ESP_PARTITION_SUBTYPE_DATA_COREDUMP: return F("COREDUMP"); case ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD: return F("ESPHTTPD"); case ESP_PARTITION_SUBTYPE_DATA_FAT: return F("FAT"); - case ESP_PARTITION_SUBTYPE_DATA_SPIFFS: - #ifdef USE_LITTLEFS + case ESP_PARTITION_SUBTYPE_DATA_SPIFFS: + # ifdef USE_LITTLEFS return F("LittleFS"); - #else + # else // ifdef USE_LITTLEFS return F("SPIFFS"); - #endif + # endif // ifdef USE_LITTLEFS default: break; } } @@ -2115,8 +2233,10 @@ String getPartitionType(uint8_t pType, uint8_t pSubType) { } String getPartitionTableHeader(const String& itemSep, const String& lineEnd) { + const char *itemSep_str = itemSep.c_str(); + return strformat(F("Address%sSize%sLabel%sPartition Type%sEncrypted%s"), - itemSep.c_str(), itemSep.c_str(), itemSep.c_str(), itemSep.c_str(), lineEnd.c_str()); + itemSep_str, itemSep_str, itemSep_str, itemSep_str, lineEnd.c_str()); } String getPartitionTable(uint8_t pType, const String& itemSep, const String& lineEnd) { @@ -2127,15 +2247,16 @@ String getPartitionTable(uint8_t pType, const String& itemSep, const String& lin if (_mypartiterator) { do { const esp_partition_t *_mypart = esp_partition_get(_mypartiterator); + const char *itemSep_str = itemSep.c_str(); result += strformat(F("%x%s%s%s%s%s%s%s%s%s"), _mypart->address, - itemSep.c_str(), - formatToHex_decimal(_mypart->size, 1024), - itemSep.c_str(), + itemSep_str, + formatToHex_decimal(_mypart->size, 1024).c_str(), + itemSep_str, _mypart->label, - itemSep.c_str(), + itemSep_str, getPartitionType(_mypart->type, _mypart->subtype).c_str(), - itemSep.c_str(), + itemSep_str, String(_mypart->encrypted ? F("Yes") : F("-")).c_str(), lineEnd.c_str()); } while ((_mypartiterator = esp_partition_next(_mypartiterator)) != nullptr); @@ -2155,7 +2276,7 @@ String downloadFileType(const String& url, const String& user, const String& pas } String filename = getFileName(filetype, filenr); - String fullUrl = joinUrlFilename(url, filename); + String fullUrl = joinUrlFilename(url, filename); String error; if (ResetFactoryDefaultPreference.deleteFirst()) { @@ -2169,6 +2290,7 @@ String downloadFileType(const String& url, const String& user, const String& pas } else { if (fileExists(filename)) { const String filename_bak = strformat(F("%s_bak"), filename.c_str()); + if (fileExists(filename_bak)) { if (!ResetFactoryDefaultPreference.delete_Bak_Files() || !tryDeleteFile(filename_bak)) { return F("Could not rename to _bak"); @@ -2176,7 +2298,7 @@ String downloadFileType(const String& url, const String& user, const String& pas } // Must download it to a tmp file. - const String tmpfile = strformat(F("%s_tmp"),filename.c_str()); + const String tmpfile = strformat(F("%s_tmp"), filename.c_str()); if (!downloadFile(fullUrl, tmpfile, user, pass, error)) { return error; @@ -2234,6 +2356,7 @@ String downloadFileType(FileType::Enum filetype, unsigned int filenr) } } String res = downloadFileType(url, user, pass, filetype, filenr); + clearAllCaches(); return res; }