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)
This commit is contained in:
Theo Arends 2018-09-05 10:58:56 +02:00
parent 45ffd2cdc3
commit 28e3773113
15 changed files with 101 additions and 44 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 "Няма"

View File

@ -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"

View File

@ -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;

View File

@ -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);
}
/*********************************************************************************************\

View File

@ -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);
}

View File

@ -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"

View File

@ -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) {

View File

@ -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)

View File

@ -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</Binary")) > 0) {
ExecuteCommandPower(devices_present, POWER_ON, SRC_WEMO);
power = POWER_ON;
}
else if (request.indexOf(F("State>0</Binary")) > 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){

View File

@ -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]);

View File

@ -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);

View File

@ -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);

View File

@ -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);