Bump version to 6.6.0.11

Change Settings crc calculation allowing short term backward compatibility
This commit is contained in:
Theo Arends 2019-09-07 18:32:11 +02:00
parent fc2be92478
commit 2e9f06f8bf
4 changed files with 39 additions and 26 deletions

View File

@ -1,4 +1,7 @@
/*********************************************************************************************\ /*********************************************************************************************\
* 6.6.0.11 20190907
* Change Settings crc calculation allowing short term backward compatibility
*
* 6.6.0.10 20190905 * 6.6.0.10 20190905
* Redesign Tuya support by Shantur Rathore (#6353) * Redesign Tuya support by Shantur Rathore (#6353)
* Add command Reset 99 to reset bootcount to zero (#684, #6351) * Add command Reset 99 to reset bootcount to zero (#684, #6351)

View File

@ -274,8 +274,7 @@ const uint32_t SETTINGS_LOCATION = SPIFFS_END; // No need for SPIFFS as it uses
const uint8_t CFG_ROTATES = 8; // Number of flash sectors used (handles uploads) const uint8_t CFG_ROTATES = 8; // Number of flash sectors used (handles uploads)
uint32_t settings_location = SETTINGS_LOCATION; uint32_t settings_location = SETTINGS_LOCATION;
//uint32_t settings_crc32 = 0; uint32_t settings_crc32 = 0;
uint16_t settings_crc = 0;
uint8_t *settings_buffer = nullptr; uint8_t *settings_buffer = nullptr;
/********************************************************************************************/ /********************************************************************************************/
@ -319,27 +318,29 @@ bool SettingsBufferAlloc(void)
return true; return true;
} }
uint16_t GetSettingsCrc(void) uint16_t GetCfgCrc16(uint8_t *bytes, uint32_t size)
{ {
uint16_t crc = 0; uint16_t crc = 0;
uint8_t *bytes = (uint8_t*)&Settings;
// Fix miscalculation if previous Settings was 3584 and current Settings is 4096 as of 0x06060007
uint32_t size = (Settings.version < 0x06060007) ? 3584 : sizeof(SYSCFG);
for (uint32_t i = 0; i < size; i++) { for (uint32_t i = 0; i < size; i++) {
if ((i < 14) || (i > 15)) { crc += bytes[i]*(i+1); } // Skip crc if ((i < 14) || (i > 15)) { crc += bytes[i]*(i+1); } // Skip crc
} }
return crc; return crc;
} }
uint32_t GetSettingsCrc32(void) uint16_t GetSettingsCrc(void)
{
// Fix miscalculation if previous Settings was 3584 and current Settings is 4096 between 0x06060007 and 0x0606000A
uint32_t size = ((Settings.version < 0x06060007) || (Settings.version > 0x0606000A)) ? 3584 : sizeof(SYSCFG);
return GetCfgCrc16((uint8_t*)&Settings, size);
}
uint32_t GetCfgCrc32(uint8_t *bytes, uint32_t size)
{ {
// https://create.stephan-brumme.com/crc32/#bitwise // https://create.stephan-brumme.com/crc32/#bitwise
uint32_t crc = 0; uint32_t crc = 0;
uint8_t *bytes = (uint8_t*)&Settings;
uint32_t length = sizeof(SYSCFG) -4; // Skip crc while (size--) {
while (length--) {
crc ^= *bytes++; crc ^= *bytes++;
for (uint32_t j = 0; j < 8; j++) { for (uint32_t j = 0; j < 8; j++) {
crc = (crc >> 1) ^ (-int(crc & 1) & 0xEDB88320); crc = (crc >> 1) ^ (-int(crc & 1) & 0xEDB88320);
@ -348,6 +349,11 @@ uint32_t GetSettingsCrc32(void)
return ~crc; return ~crc;
} }
uint32_t GetSettingsCrc32(void)
{
return GetCfgCrc32((uint8_t*)&Settings, sizeof(SYSCFG) -4); // Skip crc32
}
void SettingsSaveAll(void) void SettingsSaveAll(void)
{ {
if (Settings.flag.save_state) { if (Settings.flag.save_state) {
@ -380,7 +386,7 @@ void SettingsSave(uint8_t rotate)
* stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1) * stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1)
*/ */
#ifndef FIRMWARE_MINIMAL #ifndef FIRMWARE_MINIMAL
if ((GetSettingsCrc() != settings_crc) || rotate) { if ((GetSettingsCrc32() != settings_crc32) || rotate) {
if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade) if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade)
stop_flash_rotate = 1; stop_flash_rotate = 1;
} }
@ -395,6 +401,7 @@ void SettingsSave(uint8_t rotate)
settings_location = SETTINGS_LOCATION; settings_location = SETTINGS_LOCATION;
} }
} }
Settings.save_flag++; Settings.save_flag++;
if (UtcTime() > START_VALID_TIME) { if (UtcTime() > START_VALID_TIME) {
Settings.cfg_timestamp = UtcTime(); Settings.cfg_timestamp = UtcTime();
@ -402,8 +409,8 @@ void SettingsSave(uint8_t rotate)
Settings.cfg_timestamp++; Settings.cfg_timestamp++;
} }
Settings.cfg_size = sizeof(SYSCFG); Settings.cfg_size = sizeof(SYSCFG);
// Settings.cfg_crc32 = GetSettingsCrc32(); Settings.cfg_crc = GetSettingsCrc(); // Keep for backward compatibility in case of fall-back just after upgrade
Settings.cfg_crc = GetSettingsCrc(); Settings.cfg_crc32 = GetSettingsCrc32();
ESP.flashEraseSector(settings_location); ESP.flashEraseSector(settings_location);
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
@ -417,8 +424,7 @@ void SettingsSave(uint8_t rotate)
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(SYSCFG)); AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(SYSCFG));
settings_crc = Settings.cfg_crc; settings_crc32 = Settings.cfg_crc32;
// settings_crc32 = Settings.cfg_crc32;
} }
#endif // FIRMWARE_MINIMAL #endif // FIRMWARE_MINIMAL
RtcSettingsSave(); RtcSettingsSave();
@ -443,7 +449,10 @@ void SettingsLoad(void)
bool valid = false; bool valid = false;
if (Settings.version > 0x06000000) { if (Settings.version > 0x06000000) {
bool almost_valid = (Settings.cfg_crc == GetSettingsCrc()); bool almost_valid = (Settings.cfg_crc32 == GetSettingsCrc32());
if (Settings.version < 0x0606000B) {
almost_valid = (Settings.cfg_crc == GetSettingsCrc());
}
// Sometimes CRC on pages below FB, overwritten by OTA, is fine but Settings are still invalid. So check cfg_holder too // Sometimes CRC on pages below FB, overwritten by OTA, is fine but Settings are still invalid. So check cfg_holder too
if (almost_valid && (0 == cfg_holder)) { cfg_holder = Settings.cfg_holder; } // At FB always active cfg_holder if (almost_valid && (0 == cfg_holder)) { cfg_holder = Settings.cfg_holder; } // At FB always active cfg_holder
valid = (cfg_holder == Settings.cfg_holder); valid = (cfg_holder == Settings.cfg_holder);
@ -472,7 +481,7 @@ void SettingsLoad(void)
if (!settings_location || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h if (!settings_location || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h
SettingsDefault(); SettingsDefault();
} }
settings_crc = GetSettingsCrc(); settings_crc32 = GetSettingsCrc32();
#endif // FIRMWARE_MINIMAL #endif // FIRMWARE_MINIMAL
RtcSettingsLoad(); RtcSettingsLoad();

View File

@ -20,6 +20,6 @@
#ifndef _SONOFF_VERSION_H_ #ifndef _SONOFF_VERSION_H_
#define _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_
const uint32_t VERSION = 0x0606000A; const uint32_t VERSION = 0x0606000B;
#endif // _SONOFF_VERSION_H_ #endif // _SONOFF_VERSION_H_

View File

@ -1687,8 +1687,8 @@ void HandleBackupConfiguration(void)
WSSend(200, CT_STREAM, ""); WSSend(200, CT_STREAM, "");
uint16_t cfg_crc = Settings.cfg_crc; uint32_t cfg_crc32 = Settings.cfg_crc32;
Settings.cfg_crc = GetSettingsCrc(); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918) Settings.cfg_crc32 = GetSettingsCrc32(); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918)
memcpy(settings_buffer, &Settings, sizeof(Settings)); memcpy(settings_buffer, &Settings, sizeof(Settings));
if (Web.config_xor_on_set) { if (Web.config_xor_on_set) {
@ -1708,7 +1708,7 @@ void HandleBackupConfiguration(void)
SettingsBufferFree(); SettingsBufferFree();
Settings.cfg_crc = cfg_crc; // Restore crc in case savedata = 0 to make sure settings will be noted as changed Settings.cfg_crc32 = cfg_crc32; // Restore crc in case savedata = 0 to make sure settings will be noted as changed
} }
/*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/
@ -2093,12 +2093,13 @@ void HandleUploadLoop(void)
unsigned long buffer_version = settings_buffer[11] << 24 | settings_buffer[10] << 16 | settings_buffer[9] << 8 | settings_buffer[8]; unsigned long buffer_version = settings_buffer[11] << 24 | settings_buffer[10] << 16 | settings_buffer[9] << 8 | settings_buffer[8];
if (buffer_version > 0x06000000) { if (buffer_version > 0x06000000) {
uint32_t buffer_size = settings_buffer[3] << 8 | settings_buffer[2]; uint32_t buffer_size = settings_buffer[3] << 8 | settings_buffer[2];
uint16_t buffer_crc = settings_buffer[15] << 8 | settings_buffer[14]; if (buffer_version > 0x0606000A) {
uint16_t crc = 0; uint32_t buffer_crc32 = settings_buffer[4095] << 24 | settings_buffer[4094] << 16 | settings_buffer[4093] << 8 | settings_buffer[4092];
for (uint32_t i = 0; i < buffer_size; i++) { valid_settings = (GetCfgCrc32(settings_buffer, buffer_size -4) == buffer_crc32);
if ((i < 14) || (i > 15)) { crc += settings_buffer[i]*(i+1); } // Skip crc } else {
uint16_t buffer_crc16 = settings_buffer[15] << 8 | settings_buffer[14];
valid_settings = (GetCfgCrc16(settings_buffer, buffer_size) == buffer_crc16);
} }
valid_settings = (buffer_crc == crc);
} else { } else {
valid_settings = (settings_buffer[0] == CONFIG_FILE_SIGN); valid_settings = (settings_buffer[0] == CONFIG_FILE_SIGN);
} }