diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 0a05ce8b8..b11d0ce44 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -73,3 +73,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add Zigbee support for Xiaomi Aqara Vibration Sensor and Presence Sensor by Stefan Hadinger - Add Shutter functions ramp up/down and MQTT reporting by Stefan Bode - Add fallback support from version 8.x +- Add restriction if fallback firmware is incompatible with settings resulting in unreachable device diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index a7fcd5217..622645aa8 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -13,6 +13,7 @@ - Add Zigbee send automatic ZigbeeRead after sending a command - Add Zigbee improving Occupancy:false detection for Aqara sensor - Add fallback support from version 8.x +- Add restriction if fallback firmware is incompatible with settings resulting in unreachable device ### 7.1.2.5 20191213 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index fed6930d7..1844dd44b 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -635,4 +635,8 @@ const char S_INFORMATION[] PROGMEM = D_INFORMATION; const char S_RESTART[] PROGMEM = D_RESTART; #endif // USE_WEBSERVER +const uint32_t MARKER_START = 0x5AA55AA5; +const uint32_t MARKER_END = 0xA55AA55A; +const uint32_t VERSION_MARKER[] PROGMEM = { MARKER_START, VERSION, MARKER_END }; + #endif // _I18N_H_ diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg-BG.h index 1f18d8efb..251a840e8 100644 --- a/tasmota/language/bg-BG.h +++ b/tasmota/language/bg-BG.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Грешка при изтриване на RF чипа" #define D_UPLOAD_ERR_12 "Грешка при записване в RF чипа" #define D_UPLOAD_ERR_13 "Грешка при декодиране на RF фърмуера" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Код на грешка при зареждането" #define D_ENTER_COMMAND "Въвеждане на команда" diff --git a/tasmota/language/cs-CZ.h b/tasmota/language/cs-CZ.h index 1d7c6f381..79ba068ab 100644 --- a/tasmota/language/cs-CZ.h +++ b/tasmota/language/cs-CZ.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Chyba smazání RF chipu" #define D_UPLOAD_ERR_12 "Chyba při zápisu do RF chipu" #define D_UPLOAD_ERR_13 "Chyba dekódování RF firmwaru" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Chyba nahrávání" #define D_ENTER_COMMAND "Vlož příkaz" diff --git a/tasmota/language/de-DE.h b/tasmota/language/de-DE.h index 6569dd232..3cb7786af 100644 --- a/tasmota/language/de-DE.h +++ b/tasmota/language/de-DE.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "RF Chip löschen fehlgeschlagen" #define D_UPLOAD_ERR_12 "RF Chip beschreiben fehlgeschlagen" #define D_UPLOAD_ERR_13 "RF Firmware ungültig" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Upload Fehler Nummer" #define D_ENTER_COMMAND "Befehl eingeben" diff --git a/tasmota/language/el-GR.h b/tasmota/language/el-GR.h index f8b9c9614..3bea69d8f 100644 --- a/tasmota/language/el-GR.h +++ b/tasmota/language/el-GR.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Αποτυχία σβησίματος στο RF chip" #define D_UPLOAD_ERR_12 "Αποτυχία εγγραφής στο RF chip" #define D_UPLOAD_ERR_13 "Failed to decode RF firmware" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Κωδικός λάθους στη μεταφόρτωση" #define D_ENTER_COMMAND "Εισαγωγή εντολής" diff --git a/tasmota/language/en-GB.h b/tasmota/language/en-GB.h index 257a34c86..d64632603 100644 --- a/tasmota/language/en-GB.h +++ b/tasmota/language/en-GB.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v6.2.1.11 + * Updated until v8.0.0.0 \*********************************************************************/ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Failed to erase RF chip" #define D_UPLOAD_ERR_12 "Failed to write to RF chip" #define D_UPLOAD_ERR_13 "Failed to decode RF firmware" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Upload error code" #define D_ENTER_COMMAND "Enter command" diff --git a/tasmota/language/es-ES.h b/tasmota/language/es-ES.h index 7527bb77a..b0c9477de 100644 --- a/tasmota/language/es-ES.h +++ b/tasmota/language/es-ES.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "No se pudo borrar en el chip RF" #define D_UPLOAD_ERR_12 "No se puedo escribir en el chip RF" #define D_UPLOAD_ERR_13 "No se pudo decodificar firmware RF" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Código de error de carga" #define D_ENTER_COMMAND "Ingresar comando" diff --git a/tasmota/language/fr-FR.h b/tasmota/language/fr-FR.h index e107409e3..48576002e 100644 --- a/tasmota/language/fr-FR.h +++ b/tasmota/language/fr-FR.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Erreur d'effacement du chip RF" #define D_UPLOAD_ERR_12 "Erreur d'accès en écriture au chip RF" #define D_UPLOAD_ERR_13 "Erreur de décodage du firmware RF" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Code d'erreur téléchargement" #define D_ENTER_COMMAND "Saisir une commande" diff --git a/tasmota/language/he-HE.h b/tasmota/language/he-HE.h index ac4dadb8e..1d4a1b549 100644 --- a/tasmota/language/he-HE.h +++ b/tasmota/language/he-HE.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "נכשלה RF מחיקת שבב" #define D_UPLOAD_ERR_12 "נכשלה RF כתיבת שבב" #define D_UPLOAD_ERR_13 "נכשלה RF קידוד קושחת שבב" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "שגיאת קוד העלאה" #define D_ENTER_COMMAND "הקש פקודה" diff --git a/tasmota/language/hu-HU.h b/tasmota/language/hu-HU.h index 62806fa46..111558516 100644 --- a/tasmota/language/hu-HU.h +++ b/tasmota/language/hu-HU.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Az RF chip törlése sikertelen" #define D_UPLOAD_ERR_12 "Az RF chip írása sikertelen" #define D_UPLOAD_ERR_13 "Az RF firmware dekódolása sikertelen" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Feltöltési hibakód" #define D_ENTER_COMMAND "Kérem a parancsot..." diff --git a/tasmota/language/it-IT.h b/tasmota/language/it-IT.h index 0585c12d8..edf9b92c2 100644 --- a/tasmota/language/it-IT.h +++ b/tasmota/language/it-IT.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Cancellazione fallita del chip RF" #define D_UPLOAD_ERR_12 "Scrittura fallita del chip RF" #define D_UPLOAD_ERR_13 "Decodifica fallita del firmware RF" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Codice errore invio" #define D_ENTER_COMMAND "Inserire comando" diff --git a/tasmota/language/ko-KO.h b/tasmota/language/ko-KO.h index bff508474..4e20860f5 100644 --- a/tasmota/language/ko-KO.h +++ b/tasmota/language/ko-KO.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "RF 칩 삭제 실패" #define D_UPLOAD_ERR_12 "RF 칩 쓰기 실패" #define D_UPLOAD_ERR_13 "RF 펌웨어 decode 실패" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "업로드 에러 코드" #define D_ENTER_COMMAND "커맨드 입력" diff --git a/tasmota/language/nl-NL.h b/tasmota/language/nl-NL.h index 75d841ddc..e49b71ca1 100644 --- a/tasmota/language/nl-NL.h +++ b/tasmota/language/nl-NL.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Wissen RF chip mislukt" #define D_UPLOAD_ERR_12 "Opwaarderen RF chip mislukt" #define D_UPLOAD_ERR_13 "Decoderen RF bestand mislukt" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Opwaardeer foutcode" #define D_ENTER_COMMAND "Geef opdracht" diff --git a/tasmota/language/pl-PL.h b/tasmota/language/pl-PL.h index 8f5af6813..a2aada42b 100644 --- a/tasmota/language/pl-PL.h +++ b/tasmota/language/pl-PL.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Błąd kasowania układu RF" #define D_UPLOAD_ERR_12 "Błąd zapisu układu RF" #define D_UPLOAD_ERR_13 "Błąd dekodowania oprrogramowania układu RF" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Błąd wgrywania" #define D_ENTER_COMMAND "Wprowadź polecenie" diff --git a/tasmota/language/pt-BR.h b/tasmota/language/pt-BR.h index 0efa57789..ae808ef9e 100644 --- a/tasmota/language/pt-BR.h +++ b/tasmota/language/pt-BR.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Falha ao apagar o chip RF" #define D_UPLOAD_ERR_12 "Falha ao escrever o chip RF" #define D_UPLOAD_ERR_13 "Falha ao decodificar o firmware de RF" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Código de erro do envio" #define D_ENTER_COMMAND "Inserir comando" diff --git a/tasmota/language/pt-PT.h b/tasmota/language/pt-PT.h index a6299c0c8..e6684232c 100644 --- a/tasmota/language/pt-PT.h +++ b/tasmota/language/pt-PT.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Falha ao apagar o chip de RF" #define D_UPLOAD_ERR_12 "Falha ao escrever no chip de RF" #define D_UPLOAD_ERR_13 "Falha ao descodificar o firmware RF" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Código de erro do envio" #define D_ENTER_COMMAND "Inserir comando" diff --git a/tasmota/language/ru-RU.h b/tasmota/language/ru-RU.h index 3bd788ede..cd5c072aa 100644 --- a/tasmota/language/ru-RU.h +++ b/tasmota/language/ru-RU.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Failed to erase RF chip" #define D_UPLOAD_ERR_12 "Failed to write to RF chip" #define D_UPLOAD_ERR_13 "Failed to decode RF firmware" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Код ошибки загрузки" #define D_ENTER_COMMAND "Введите команду" diff --git a/tasmota/language/sk-SK.h b/tasmota/language/sk-SK.h index a64e49e01..ef16212ca 100644 --- a/tasmota/language/sk-SK.h +++ b/tasmota/language/sk-SK.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Chyba zmazania RF chipu" #define D_UPLOAD_ERR_12 "Chyba pri zápise do RF chipu" #define D_UPLOAD_ERR_13 "Chyba dekódovania RF firmwaru" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Chyba nahrávania" #define D_ENTER_COMMAND "Vlož príkaz" diff --git a/tasmota/language/sv-SE.h b/tasmota/language/sv-SE.h index 51ffc2ae3..971ee42b1 100644 --- a/tasmota/language/sv-SE.h +++ b/tasmota/language/sv-SE.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Misslyckades rensa RF chip" #define D_UPLOAD_ERR_12 "Misslyckades skriva till RF chip" #define D_UPLOAD_ERR_13 "Misslyckades avkoda RF firmware" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Uppladdningsfelkod" #define D_ENTER_COMMAND "Ange kommando" diff --git a/tasmota/language/tr-TR.h b/tasmota/language/tr-TR.h index 6bc48c40f..67400d1cc 100644 --- a/tasmota/language/tr-TR.h +++ b/tasmota/language/tr-TR.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Failed to erase RF chip" #define D_UPLOAD_ERR_12 "Failed to write to RF chip" #define D_UPLOAD_ERR_13 "Failed to decode RF firmware" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Upload error code" #define D_ENTER_COMMAND "Komut girişi" diff --git a/tasmota/language/uk-UK.h b/tasmota/language/uk-UK.h index b4a314630..b81f30012 100644 --- a/tasmota/language/uk-UK.h +++ b/tasmota/language/uk-UK.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Помилка стирання чипу RF" #define D_UPLOAD_ERR_12 "Помилка запису чипу RF" #define D_UPLOAD_ERR_13 "Помилка розкодування прошивки RF" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "Код помилки завантаження" #define D_ENTER_COMMAND "Уведіть команду" diff --git a/tasmota/language/zh-CN.h b/tasmota/language/zh-CN.h index 21aa63be3..665f39fc3 100644 --- a/tasmota/language/zh-CN.h +++ b/tasmota/language/zh-CN.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "擦除 RF 芯片失败" #define D_UPLOAD_ERR_12 "写入 RF 芯片失败" #define D_UPLOAD_ERR_13 "解码 RF 固件失败" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "上传错误代码" #define D_ENTER_COMMAND "输入命令" diff --git a/tasmota/language/zh-TW.h b/tasmota/language/zh-TW.h index 1d78f181e..6f56e03df 100644 --- a/tasmota/language/zh-TW.h +++ b/tasmota/language/zh-TW.h @@ -353,6 +353,7 @@ #define D_UPLOAD_ERR_11 "Failed to erase RF chip" #define D_UPLOAD_ERR_12 "Failed to write to RF chip" #define D_UPLOAD_ERR_13 "Failed to decode RF firmware" +#define D_UPLOAD_ERR_14 "Not compatible" #define D_UPLOAD_ERROR_CODE "上傳錯誤代碼" #define D_ENTER_COMMAND "輸入命令" diff --git a/tasmota/settings.ino b/tasmota/settings.ino index d921e4957..b572ca645 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -343,6 +343,44 @@ void SetFlashModeDout(void) delete[] _buffer; } +uint32_t OtaVersion(void) +{ + eboot_command ebcmd; + eboot_command_read(&ebcmd); + uint32_t start_address = ebcmd.args[0]; + uint32_t end_address = start_address + (ebcmd.args[2] & 0xFFFFF000) + FLASH_SECTOR_SIZE; + uint32_t* buffer = new uint32_t[FLASH_SECTOR_SIZE / 4]; + + uint32_t version[3] = { 0 }; + bool found = false; + for (uint32_t address = start_address; address < end_address; address = address + FLASH_SECTOR_SIZE) { + ESP.flashRead(address, (uint32_t*)buffer, FLASH_SECTOR_SIZE); + for (uint32_t i = 0; i < (FLASH_SECTOR_SIZE / 4); i++) { + version[0] = version[1]; + version[1] = version[2]; + version[2] = buffer[i]; + if ((version[0] == MARKER_START) && (version[2] == MARKER_END)) { + found = true; + break; + } + } + if (found) { break; } + } + delete[] buffer; + + if (!found) { version[1] = 0; } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("OTA: Version 0x%08X, Compatible 0x%08X"), version[1], VERSION_COMPATIBLE); + + return version[1]; +} + +void AbandonOta(void) +{ + uint32_t eboot_magic = 0; + ESP.rtcUserMemoryWrite(0, (uint32_t*)&eboot_magic, sizeof(eboot_magic)); +} + void SettingsBufferFree(void) { if (settings_buffer != nullptr) { diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 0935d9a28..08b898efb 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -866,13 +866,21 @@ void Every250mSeconds(void) } if (90 == ota_state_flag) { // Allow MQTT to reconnect ota_state_flag = 0; + Response_P(PSTR("{\"" D_CMND_UPGRADE "\":\"")); if (ota_result) { // SetFlashModeDout(); // Force DOUT for both ESP8266 and ESP8285 - Response_P(PSTR(D_JSON_SUCCESSFUL ". " D_JSON_RESTARTING)); + if (OtaVersion() < VERSION_COMPATIBLE) { + AbandonOta(); + ResponseAppend_P(PSTR(D_JSON_FAILED " " D_UPLOAD_ERR_14)); + } else { + ResponseAppend_P(PSTR(D_JSON_SUCCESSFUL ". " D_JSON_RESTARTING)); + restart_flag = 2; + } } else { - Response_P(PSTR(D_JSON_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str()); + ResponseAppend_P(PSTR(D_JSON_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str()); } - restart_flag = 2; // Restart anyway to keep memory clean webserver + ResponseAppend_P(PSTR("\"}")); +// restart_flag = 2; // Restart anyway to keep memory clean webserver MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_UPGRADE)); } } diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 3b9e64a25..67be9d35f 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -334,6 +334,8 @@ void setup(void) AddLog_P2(LOG_LEVEL_INFO, PSTR(D_WARNING_MINIMAL_VERSION)); #endif // FIRMWARE_MINIMAL + memcpy_P(log_data, VERSION_MARKER, 1); // Dummy for compiler saving VERSION_MARKER + RtcInit(); #ifdef USE_ARDUINO_OTA diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 8fe799b5b..9c9b7b189 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -22,4 +22,7 @@ const uint32_t VERSION = 0x07020000; +// Lowest compatible version +const uint32_t VERSION_COMPATIBLE = 0x06000000; + #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 9c8131ad3..fe10e4cd3 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -511,6 +511,8 @@ const char kUploadErrors[] PROGMEM = D_UPLOAD_ERR_1 "|" D_UPLOAD_ERR_2 "|" D_UPLOAD_ERR_3 "|" D_UPLOAD_ERR_4 "|" D_UPLOAD_ERR_5 "|" D_UPLOAD_ERR_6 "|" D_UPLOAD_ERR_7 "|" D_UPLOAD_ERR_8 "|" D_UPLOAD_ERR_9 #ifdef USE_RF_FLASH "|" D_UPLOAD_ERR_10 "|" D_UPLOAD_ERR_11 "|" D_UPLOAD_ERR_12 "|" D_UPLOAD_ERR_13 +#else + "|" D_UPLOAD_ERR_14 #endif ; @@ -2137,12 +2139,11 @@ void HandleUploadDone(void) WSContentSendStyle(); WSContentSend_P(PSTR("
" D_UPLOAD " " D_FAILED "

")); WSContentSend_P(PSTR("%06x'>" D_FAILED "

"), WebColor(COL_TEXT_WARNING)); #ifdef USE_RF_FLASH if (Web.upload_error < 14) { #else - if (Web.upload_error < 10) { + if (Web.upload_error < 11) { #endif GetTextIndexed(error, sizeof(error), Web.upload_error -1, kUploadErrors); } else { @@ -2376,6 +2377,11 @@ void HandleUploadLoop(void) Web.upload_error = 6; // Upload failed. Enable logging 3 return; } + if (OtaVersion() < VERSION_COMPATIBLE) { + AbandonOta(); + Web.upload_error = 10; // Not compatible + return; + } } if (!Web.upload_error) { AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_UPLOAD D_SUCCESSFUL " %u bytes. " D_RESTARTING), upload.totalSize);