From 5b6a25a7a00791986a1a0596f4470b933e4e2697 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:52:58 +0200 Subject: [PATCH] Fix driver config backup and restore Fix driver config backup and restore (#18295) --- tasmota/tasmota_support/settings.ino | 69 +++++++++++-------- .../xdrv_03_esp32_energy.ino | 8 +-- .../xdrv_122_file_settings_demo.ino | 8 +-- .../xdrv_27_esp32_shutter.ino | 18 ++--- .../xdrv_86_esp32_sonoff_spm.ino | 8 +-- .../xdrv_87_esp32_sonoff_tm1621.ino | 8 +-- 6 files changed, 58 insertions(+), 61 deletions(-) diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index c4e56179c..0cf7a044d 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -412,21 +412,21 @@ bool SettingsBufferAlloc(uint32_t upload_size) { return false; } settings_size = upload_size; - } else { #ifdef USE_UFILESYS - char filename[14]; - for (uint32_t i = 0; i < 129; i++) { - snprintf_P(filename, sizeof(filename), PSTR(TASM_FILE_DRIVER), i); - uint32_t fsize = TfsFileSize(filename); - if (fsize) { - if (settings_size == sizeof(TSettings)) { - settings_size += 16; // Add tar header for total file size + } else { + char filename[14]; + for (uint32_t i = 0; i < 129; i++) { + snprintf_P(filename, sizeof(filename), PSTR(TASM_FILE_DRIVER), i); + uint32_t fsize = TfsFileSize(filename); + if (fsize) { + if (settings_size == sizeof(TSettings)) { + settings_size += 16; // Add tar header for total file size + } + fsize = ((fsize / 16) * 16) + 16; // Use 16-byte boundary + settings_size += (16 + fsize); // Tar header size is 16 bytes } - fsize = ((fsize / 16) * 16) + 16; // Use 16-byte boundary - settings_size += (16 + fsize); // Tar header size is 16 bytes } - } #endif // USE_UFILESYS } @@ -445,12 +445,11 @@ uint32_t SettingsConfigBackup(void) { #ifdef USE_UFILESYS if (settings_size > sizeof(TSettings)) { + // Add tar header with total file size snprintf_P((char*)filebuf_ptr, 14, PSTR(TASM_FILE_SETTINGS)); // /.settings - filebuf_ptr += 14; - *filebuf_ptr = settings_size; - filebuf_ptr++; - *filebuf_ptr = (settings_size >> 8); - filebuf_ptr++; + filebuf_ptr[14] = settings_size; + filebuf_ptr[15] = settings_size >> 8; + filebuf_ptr += 16; } #endif // USE_UFILESYS @@ -467,14 +466,25 @@ uint32_t SettingsConfigBackup(void) { snprintf_P(filename, sizeof(filename), PSTR(TASM_FILE_DRIVER), i); // /.drvset012 uint32_t fsize = TfsFileSize(filename); if (fsize) { + // Add tar header with file size memcpy(filebuf_ptr, filename, 14); - filebuf_ptr += 14; - *filebuf_ptr = fsize; - filebuf_ptr++; - *filebuf_ptr = (fsize >> 8); - filebuf_ptr++; - AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Backup file %s (%d)"), (char*)filebuf_ptr -16, fsize); - TfsLoadFile((const char*)filebuf_ptr -16, (uint8_t*)filebuf_ptr, fsize); + filebuf_ptr[14] = fsize; + filebuf_ptr[15] = fsize >> 8; + filebuf_ptr += 16; + if (XdrvCallDriver(i, FUNC_RESTORE_SETTINGS)) { // Enabled driver + // Use most relevant config data which might not have been saved to file +// AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Backup driver %d"), i); + memcpy(filebuf_ptr, (uint8_t*)XdrvMailbox.data, fsize); + cfg_crc32 = GetCfgCrc32(filebuf_ptr +4, fsize -4); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918) + filebuf_ptr[0] = cfg_crc32; + filebuf_ptr[1] = cfg_crc32 >> 8; + filebuf_ptr[2] = cfg_crc32 >> 16; + filebuf_ptr[3] = cfg_crc32 >> 24; + } else { // Disabled driver + // As driver is not active just copy file +// AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Backup file %s (%d)"), (char*)filebuf_ptr -16, fsize); + TfsLoadFile((const char*)filebuf_ptr -16, (uint8_t*)filebuf_ptr, fsize); + } filebuf_ptr += ((fsize / 16) * 16) + 16; } } @@ -550,12 +560,17 @@ bool SettingsConfigRestore(void) { uint32_t buffer_crc32 = filebuf_ptr[3] << 24 | filebuf_ptr[2] << 16 | filebuf_ptr[1] << 8 | filebuf_ptr[0]; bool valid_buffer = (GetCfgCrc32(filebuf_ptr +4, fsize -4) == buffer_crc32); if (valid_buffer) { - XdrvMailbox.data = (char*)filebuf_ptr; - XdrvMailbox.index = fsize; if (XdrvCallDriver(driver, FUNC_RESTORE_SETTINGS)) { - AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Restore driver %d"), driver); + // Restore live config data which will be saved to file before restart +// AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Restore driver %d"), driver); + filebuf_ptr[1]++; // Force invalid crc32 to enable auto upgrade after restart + if (fsize > XdrvMailbox.index) { + fsize = XdrvMailbox.index; + } + memcpy((uint8_t*)XdrvMailbox.data, filebuf_ptr, fsize); // Restore version and auto upgrade after restart } else { - AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Restore file %s (%d)"), (char*)filebuf_ptr -16, fsize); + // As driver is not active just copy file +// AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Restore file %s (%d)"), (char*)filebuf_ptr -16, fsize); TfsSaveFile((const char*)filebuf_ptr -16, (uint8_t*)filebuf_ptr, fsize); } } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino index b539c9350..a15b7af82 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_esp32_energy.ino @@ -274,7 +274,7 @@ bool EnergyRtcSettingsValid(void) { * Driver Settings load and save using filesystem \*********************************************************************************************/ -const uint32_t XDRV_03_VERSION = 0x0102; // Latest driver version (See settings deltas below) +const uint16_t XDRV_03_VERSION = 0x0102; // Latest driver version (See settings deltas below) void EnergySettingsLoad(bool erase) { // *** Start init default values in case file is not found *** @@ -373,11 +373,9 @@ void EnergySettingsSave(void) { } bool EnergySettingsRestore(void) { -#ifdef USE_UFILESYS - uint32_t max_size = (XdrvMailbox.index > sizeof(tEnergySettings)) ? sizeof(tEnergySettings) : XdrvMailbox.index; - memcpy((uint8_t*)&Energy->Settings, (uint8_t*)XdrvMailbox.data, max_size); // Restore version and auto upgrade after restart + XdrvMailbox.data = (char*)&Energy->Settings; + XdrvMailbox.index = sizeof(tEnergySettings); return true; -#endif // USE_UFILESYS } /********************************************************************************************/ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_122_file_settings_demo.ino b/tasmota/tasmota_xdrv_driver/xdrv_122_file_settings_demo.ino index e064c6941..cd2cf64c3 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_122_file_settings_demo.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_122_file_settings_demo.ino @@ -34,7 +34,7 @@ #define DRV_DEMO_MAX_DRV_TEXT 16 -const uint32_t DRV_DEMO_VERSION = 0x0101; // Latest driver version (See settings deltas below) +const uint16_t DRV_DEMO_VERSION = 0x0101; // Latest driver version (See settings deltas below) // Demo command line commands const char kDrvDemoCommands[] PROGMEM = "Drv|" // Prefix @@ -157,11 +157,9 @@ void DrvDemoSettingsSave(void) { } bool DrvDemoSettingsRestore(void) { -#ifdef USE_UFILESYS - uint32_t max_size = (XdrvMailbox.index > sizeof(DrvDemoSettings)) ? sizeof(DrvDemoSettings) : XdrvMailbox.index; - memcpy((uint8_t*)&DrvDemoSettings, (uint8_t*)XdrvMailbox.data, max_size); // Restore version and auto upgrade after restart + XdrvMailbox.data = (char*)&DrvDemoSettings; + XdrvMailbox.index = sizeof(DrvDemoSettings); return true; -#endif // USE_UFILESYS } /*********************************************************************************************\ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino index 5e489e29a..f09370ed6 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_27_esp32_shutter.ino @@ -53,7 +53,7 @@ const char HTTP_MSG_SLIDER_SHUTTER[] PROGMEM = "
%s%s
" "
"; -const uint32_t SHUTTER_VERSION = 0x0100; // Latest driver version (See settings deltas below) +const uint16_t SHUTTER_VERSION = 0x0100; // Latest driver version (See settings deltas below) typedef struct { // depreciated 2023-04-28 int8_t pos; @@ -253,9 +253,7 @@ void ShutterSettingsDelta(void) { // Fix possible setting deltas if (ShutterSettings.version != SHUTTER_VERSION) { // Fix version dependent changes - if (ShutterSettings.version < 0x01010100) { - AddLog(LOG_LEVEL_INFO, PSTR("SHT: Update oldest version restore")); - + if (ShutterSettings.version < 0x0100) { for (uint8_t i=0; i < MAX_SHUTTERS_ESP32; i++){ if (ShutterSettings.shutter_startrelay[i] == 0) continue; AddLog(LOG_LEVEL_INFO, PSTR("SHT: %s SHT%d:%d"),D_CMND_SHUTTER_RELAY,i+1,ShutterSettings.shutter_startrelay[i]); @@ -272,14 +270,8 @@ void ShutterSettingsDelta(void) { ShutterSettings.shutter_button[i].position[j].mqtt_broadcast = ShutterSettings.shutter_button_old[i].position[j].mqtt_broadcast; } } - } - // if (ShutterSettings.version < 0x01010101) { - // AddLog(LOG_LEVEL_INFO, PSTR("SHT: Update old version restore")); - - // } - // Set current version and save settings ShutterSettings.version = SHUTTER_VERSION; ShutterSettingsSave(); @@ -342,11 +334,9 @@ void ShutterSettingsSave(void) { } bool ShutterSettingsRestore(void) { -#ifdef USE_UFILESYS - uint32_t max_size = (XdrvMailbox.index > sizeof(ShutterSettings)) ? sizeof(ShutterSettings) : XdrvMailbox.index; - memcpy((uint8_t*)&ShutterSettings, (uint8_t*)XdrvMailbox.data, max_size); // Restore version and auto upgrade after restart + XdrvMailbox.data = (char*)&ShutterSettings; + XdrvMailbox.index = sizeof(ShutterSettings); return true; -#endif // USE_UFILESYS } uint8_t ShutterGetRelayNoFromBitfield(power_t number) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino index 6b1a7a03c..03cc63bf6 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino @@ -308,7 +308,7 @@ TSspm *Sspm = nullptr; * Driver Settings load and save using filesystem \*********************************************************************************************/ -const uint32_t XDRV_86_VERSION = 0x0104; // Latest driver version (See settings deltas below) +const uint16_t XDRV_86_VERSION = 0x0104; // Latest driver version (See settings deltas below) void Xdrv86SettingsLoad(bool erase) { // *** Start init default values in case file is not found *** @@ -374,11 +374,9 @@ void Xdrv86SettingsSave(void) { } bool Xdrv86SettingsRestore(void) { -#ifdef USE_UFILESYS - uint32_t max_size = (XdrvMailbox.index > sizeof(tSspmSettings)) ? sizeof(tSspmSettings) : XdrvMailbox.index; - memcpy((uint8_t*)&Sspm->Settings, (uint8_t*)XdrvMailbox.data, max_size); // Restore version and auto upgrade after restart + XdrvMailbox.data = (char*)&Sspm->Settings; + XdrvMailbox.index = sizeof(tSspmSettings); return true; -#endif // USE_UFILESYS } /*********************************************************************************************/ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino b/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino index 20cc1f986..642f32ce3 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino @@ -85,7 +85,7 @@ struct Tm1621 { * Driver Settings load and save using filesystem \*********************************************************************************************/ -const uint32_t XDRV_87_VERSION = 0x0104; // Latest driver version (See settings deltas below) +const uint16_t XDRV_87_VERSION = 0x0104; // Latest driver version (See settings deltas below) typedef struct { uint32_t crc32; // To detect file changes @@ -163,11 +163,9 @@ void Xdrv87SettingsSave(void) { } bool Xdrv87SettingsRestore(void) { -#ifdef USE_UFILESYS - uint32_t max_size = (XdrvMailbox.index > sizeof(tXdrv87Settings)) ? sizeof(tXdrv87Settings) : XdrvMailbox.index; - memcpy((uint8_t*)&Xdrv87Settings, (uint8_t*)XdrvMailbox.data, max_size); // Restore version and auto upgrade after restart + XdrvMailbox.data = (char*)&Xdrv87Settings; + XdrvMailbox.index = sizeof(tXdrv87Settings); return true; -#endif // USE_UFILESYS } /*********************************************************************************************/