diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7cacefa47..8cf1a0022 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -104,6 +104,12 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren | USE_RF_FLASH | - | - | x | x | x | ## Changelog +Version 6.2.1 20180905 + * Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) + * Fix Wemo emulation to select the first relay when more than one relay is present (#3657) + * Fix possible exception due to buffer overflow (#3659) + * Fix lost energy today and total energy value after power cycle (#3689) + Version 6.2.0 20180901 * Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561) * Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index b95a6ce0e..101ab2f61 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,10 @@ -/* 6.2.0 20180901 +/* 6.2.1 20180905 + * Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) + * Fix Wemo emulation to select the first relay when more than one relay is present (#3657) + * Fix possible exception due to buffer overflow (#3659) + * Fix lost energy today and total energy value after power cycle (#3689) + * + * 6.2.0 20180901 * Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561) * Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554) * Change DS18B20 driver to provide better instant results diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 6421441b7..b1ecd6fa6 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.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.1.1.5 + * Updated until v6.2.0.1 \*********************************************************************/ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -60,10 +60,12 @@ #define D_BLINKOFF "Мигане изкл." #define D_BOOT_COUNT "Брой на стартиранията" #define D_BRIGHTLIGHT "Яркост" +#define D_BSSID "BSSId" #define D_BUTTON "Бутон" #define D_BY "от" // Written by me #define D_BYTES "Байта" #define D_CELSIUS "Целзий" +#define D_CHANNEL "Канал" #define D_CO2 "Въглероден диоксид" #define D_CODE "код" // Button code #define D_COLDLIGHT "Хладна" @@ -438,12 +440,12 @@ #define D_PARTICALS_BEYOND "Частици" // xsns_32_mpu6050.ino -#define D_AX_AXIS "Accel. X-Axis" -#define D_AY_AXIS "Accel. Y-Axis" -#define D_AZ_AXIS "Accel. Z-Axis" -#define D_GX_AXIS "Gyro X-Axis" -#define D_GY_AXIS "Gyro Y-Axis" -#define D_GZ_AXIS "Gyro Z-Axis" +#define D_AX_AXIS "Ускорение - ос X" +#define D_AY_AXIS "Ускорение - ос Y" +#define D_AZ_AXIS "Ускорение - ос Z" +#define D_GX_AXIS "Жироскоп - ос X" +#define D_GY_AXIS "Жироскоп - ос Y" +#define D_GZ_AXIS "Жироскоп - ос Z" // sonoff_template.h #define D_SENSOR_NONE "Няма" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 68e9141ea..986b9507f 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.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.1.1c + * Updated until v6.2.0.1 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -60,10 +60,12 @@ #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Conteo Reinicios" #define D_BRIGHTLIGHT "Brillante" +#define D_BSSID "BSSId" #define D_BUTTON "Botón" #define D_BY "por" // Written by me #define D_BYTES "Bytes" #define D_CELSIUS "Celsius" +#define D_CHANNEL "Canal" #define D_CO2 "CO2" #define D_CODE "código" // Button code #define D_COLDLIGHT "Fría" @@ -460,7 +462,7 @@ #define D_SENSOR_RELAY "Relé" // Suffix "1i" #define D_SENSOR_LED "Led" // Suffix "1i" #define D_SENSOR_PWM "PWM" // Suffix "1" -#define D_SENSOR_COUNTER "Counter" // Suffix "1" +#define D_SENSOR_COUNTER "Contador" // Suffix "1" #define D_SENSOR_IRRECV "IR RX" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" diff --git a/sonoff/settings.h b/sonoff/settings.h index ded2c140b..3876baf60 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -333,6 +333,12 @@ struct SYSCFG { // E00 - FFF free locations } Settings; +struct RTCRBT { + uint16_t valid; // 000 + uint8_t fast_reboot_count; // 002 + uint8_t free_003[1]; // 003 +} RtcReboot; + struct RTCMEM { uint16_t valid; // 000 byte oswatch_blocked_loop; // 002 @@ -341,9 +347,7 @@ struct RTCMEM { unsigned long energy_kWhtotal; // 008 unsigned long pulse_counter[MAX_COUNTERS]; // 00C power_t power; // 01C - uint16_t extended_valid; // 020 Extended valid flag (v6.1.1.14) - uint8_t fast_reboot_count; // 022 - uint8_t free_023[57]; // 023 + uint8_t free_020[60]; // 020 // 05C next free location (64 (=core) + 100 (=tasmota offset) + 92 (=0x5C RTCMEM struct) = 256 bytes (max = 512)) } RtcSettings; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index cba043696..5626f862b 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -84,7 +84,6 @@ void RtcSettingsSave() { if (GetRtcSettingsCrc() != rtc_settings_crc) { RtcSettings.valid = RTC_MEM_VALID; - RtcSettings.extended_valid = RTC_MEM_VALID; ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); rtc_settings_crc = GetRtcSettingsCrc(); #ifdef DEBUG_THEO @@ -104,14 +103,12 @@ void RtcSettingsLoad() if (RtcSettings.valid != RTC_MEM_VALID) { memset(&RtcSettings, 0, sizeof(RTCMEM)); RtcSettings.valid = RTC_MEM_VALID; - RtcSettings.extended_valid = RTC_MEM_VALID; RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday; RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal; for (byte i = 0; i < MAX_COUNTERS; i++) { RtcSettings.pulse_counter[i] = Settings.pulse_counter[i]; } RtcSettings.power = Settings.power; -// RtcSettings.fast_reboot_count = 0; // Explicit by memset RtcSettingsSave(); } rtc_settings_crc = GetRtcSettingsCrc(); @@ -122,9 +119,45 @@ boolean RtcSettingsValid() return (RTC_MEM_VALID == RtcSettings.valid); } -boolean RtcSettingsExtendedValid() +/********************************************************************************************/ + +uint32_t rtc_reboot_crc = 0; + +uint32_t GetRtcRebootCrc() { - return (RTC_MEM_VALID == RtcSettings.extended_valid); + uint32_t crc = 0; + uint8_t *bytes = (uint8_t*)&RtcReboot; + + for (uint16_t i = 0; i < sizeof(RTCRBT); i++) { + crc += bytes[i]*(i+1); + } + return crc; +} + +void RtcRebootSave() +{ + if (GetRtcRebootCrc() != rtc_reboot_crc) { + RtcReboot.valid = RTC_MEM_VALID; + ESP.rtcUserMemoryWrite(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); + rtc_reboot_crc = GetRtcRebootCrc(); + } +} + +void RtcRebootLoad() +{ + ESP.rtcUserMemoryRead(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); + if (RtcReboot.valid != RTC_MEM_VALID) { + memset(&RtcReboot, 0, sizeof(RTCRBT)); + RtcReboot.valid = RTC_MEM_VALID; +// RtcReboot.fast_reboot_count = 0; // Explicit by memset + RtcRebootSave(); + } + rtc_reboot_crc = GetRtcRebootCrc(); +} + +boolean RtcRebootValid() +{ + return (RTC_MEM_VALID == RtcReboot.valid); } /*********************************************************************************************\ diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 254f88184..f99262d90 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -442,7 +442,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) ShowFreeMem(PSTR("MqttDataHandler")); - strncpy(topicBuf, topic, sizeof(topicBuf)); + strlcpy(topicBuf, topic, sizeof(topicBuf)); for (i = 0; i < data_len; i++) { if (!isspace(data[i])) break; } @@ -1568,8 +1568,8 @@ void PerformEverySecond() uptime++; if (BOOT_LOOP_TIME == uptime) { - RtcSettings.fast_reboot_count = 0; - RtcSettingsSave(); + RtcReboot.fast_reboot_count = 0; + RtcRebootSave(); } if ((4 == uptime) && (SONOFF_IFAN02 == Settings.module)) { // Microcontroller needs 3 seconds before accepting commands @@ -2491,10 +2491,10 @@ void setup() { byte idx; - RtcSettingsLoad(); - if (!RtcSettingsExtendedValid()) { RtcSettings.fast_reboot_count = 0; } - RtcSettings.fast_reboot_count++; - RtcSettingsSave(); + RtcRebootLoad(); + if (!RtcRebootValid()) { RtcReboot.fast_reboot_count = 0; } + RtcReboot.fast_reboot_count++; + RtcRebootSave(); Serial.begin(baudrate); delay(10); @@ -2528,26 +2528,26 @@ void setup() sleep = Settings.sleep; // Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts) - if (RtcSettings.fast_reboot_count > 1) { // Restart twice + if (RtcReboot.fast_reboot_count > 1) { // Restart twice Settings.flag3.user_esp8285_enable = 0; // Disable ESP8285 Generic GPIOs interfering with flash SPI - if (RtcSettings.fast_reboot_count > 2) { // Restart 3 times + if (RtcReboot.fast_reboot_count > 2) { // Restart 3 times for (byte i = 0; i < MAX_RULE_SETS; i++) { if (bitRead(Settings.rule_stop, i)) { bitWrite(Settings.rule_enabled, i, 0); // Disable rules causing boot loop } } } - if (RtcSettings.fast_reboot_count > 3) { // Restarted 4 times + if (RtcReboot.fast_reboot_count > 3) { // Restarted 4 times Settings.rule_enabled = 0; // Disable all rules } - if (RtcSettings.fast_reboot_count > 4) { // Restarted 5 times + if (RtcReboot.fast_reboot_count > 4) { // Restarted 5 times Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic Settings.last_module = SONOFF_BASIC; for (byte i = 0; i < MAX_GPIO_PIN; i++) { Settings.my_gp.io[i] = GPIO_NONE; // Reset user defined GPIO disabling sensors } } - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcSettings.fast_reboot_count); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count); AddLog(LOG_LEVEL_DEBUG); } diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 1bf322288..a8d4d4141 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06020000 +#define VERSION 0x06020100 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support.ino b/sonoff/support.ino index 8cc064fe5..8aaeabf88 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -143,7 +143,7 @@ char* subStr(char* dest, char* str, const char *delim, int index) int i; // Since strtok consumes the first arg, make a copy - strncpy(dest, str, strlen(str)); + strlcpy(dest, str, strlen(str)); for (i = 1, act = dest; i <= index; i++, act = NULL) { sub = strtok_r(act, delim, &ptr); if (sub == NULL) break; @@ -157,7 +157,7 @@ double CharToDouble(char *str) // simple ascii to double, because atof or strtod are too large char strbuf[24]; - strcpy(strbuf, str); + strlcpy(strbuf, str, sizeof(strbuf)); char *pt; double left = atoi(strbuf); double right = 0; @@ -561,13 +561,13 @@ int GetStateNumber(char *state_text) char command[CMDSZ]; int state_number = -1; - if ((GetCommandCode(command, sizeof(command), state_text, kOptionOff) >= 0) || !strcasecmp(state_text, Settings.state_text[0])) { + if (GetCommandCode(command, sizeof(command), state_text, kOptionOff) >= 0) { state_number = 0; } - else if ((GetCommandCode(command, sizeof(command), state_text, kOptionOn) >= 0) || !strcasecmp(state_text, Settings.state_text[1])) { + else if (GetCommandCode(command, sizeof(command), state_text, kOptionOn) >= 0) { state_number = 1; } - else if ((GetCommandCode(command, sizeof(command), state_text, kOptionToggle) >= 0) || !strcasecmp(state_text, Settings.state_text[2])) { + else if (GetCommandCode(command, sizeof(command), state_text, kOptionToggle) >= 0) { state_number = 2; } else if (GetCommandCode(command, sizeof(command), state_text, kOptionBlink) >= 0) { diff --git a/sonoff/xdrv_02_webserver.ino b/sonoff/xdrv_02_webserver.ino index c919c8f43..db0124a31 100644 --- a/sonoff/xdrv_02_webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -372,8 +372,7 @@ long ajax_token = 1; static void WebGetArg(const char* arg, char* out, size_t max) { String s = WebServer->arg(arg); - strncpy(out, s.c_str(), max); - out[max-1] = '\0'; // Ensure terminating NUL + strlcpy(out, s.c_str(), max); } void ShowWebSource(int source) diff --git a/sonoff/xplg_wemohue.ino b/sonoff/xplg_wemohue.ino index 9a7cdeec7..93912bc76 100644 --- a/sonoff/xplg_wemohue.ino +++ b/sonoff/xplg_wemohue.ino @@ -386,11 +386,16 @@ void HandleUpnpEvent() String state_xml = FPSTR(WEMO_RESPONSE_STATE_SOAP); //differentiate get and set state if (request.indexOf(F("SetBinaryState")) > 0) { + uint8_t power = POWER_TOGGLE; if (request.indexOf(F("State>1 0) { - ExecuteCommandPower(devices_present, POWER_ON, SRC_WEMO); + power = POWER_ON; } else if (request.indexOf(F("State>0 0) { - ExecuteCommandPower(devices_present, POWER_OFF, SRC_WEMO); + power = POWER_OFF; + } + if (power != POWER_TOGGLE) { + uint8_t device = (light_type) ? devices_present : 1; // Select either a configured light or relay1 + ExecuteCommandPower(device, power, SRC_WEMO); } } else if(request.indexOf(F("GetBinaryState")) > 0){ diff --git a/sonoff/xsns_01_counter.ino b/sonoff/xsns_01_counter.ino index 069d5b3e7..b5822cac7 100644 --- a/sonoff/xsns_01_counter.ino +++ b/sonoff/xsns_01_counter.ino @@ -111,7 +111,7 @@ void CounterShow(boolean json) } header++; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"C%d\":%s"), mqtt_data, stemp, i +1, counter); - strcpy(stemp, ","); + strlcpy(stemp, ",", sizeof(stemp)); #ifdef USE_DOMOTICZ if ((0 == tele_period) && (1 == dsxflg)) { DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]); diff --git a/sonoff/xsns_05_ds18x20_legacy.ino b/sonoff/xsns_05_ds18x20_legacy.ino index 156312104..03754bbe1 100644 --- a/sonoff/xsns_05_ds18x20_legacy.ino +++ b/sonoff/xsns_05_ds18x20_legacy.ino @@ -186,7 +186,7 @@ void Ds18x20Show(boolean json) dsxflg++; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"DS%d\":{\"" D_JSON_TYPE "\":\"%s\",\"" D_JSON_ADDRESS "\":\"%s\",\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, stemp, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), temperature); - strcpy(stemp, ","); + strlcpy(stemp, ",", sizeof(stemp)); #ifdef USE_DOMOTICZ if ((0 == tele_period) && (1 == dsxflg)) { DomoticzSensor(DZ_TEMP, temperature); diff --git a/sonoff/xsns_12_ads1115.ino b/sonoff/xsns_12_ads1115.ino index f1279a732..bcfb6dfad 100644 --- a/sonoff/xsns_12_ads1115.ino +++ b/sonoff/xsns_12_ads1115.ino @@ -191,7 +191,7 @@ void Ads1115Show(boolean json) } dsxflg++; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value); - strcpy(stemp, ","); + strlcpy(stemp, ",", sizeof(stemp)); #ifdef USE_WEBSERVER } else { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value); diff --git a/sonoff/xsns_12_ads1115_i2cdev.ino b/sonoff/xsns_12_ads1115_i2cdev.ino index d3748ec7a..588a37ac5 100644 --- a/sonoff/xsns_12_ads1115_i2cdev.ino +++ b/sonoff/xsns_12_ads1115_i2cdev.ino @@ -111,7 +111,7 @@ void Ads1115Show(boolean json) } dsxflg++; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value); - strcpy(stemp, ","); + strlcpy(stemp, ",", sizeof(stemp)); #ifdef USE_WEBSERVER } else { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value);