Add more user input validation

5.13.1c
 * Add more user input validation to commands TimeStd and
TimeDst
This commit is contained in:
Theo Arends 2018-05-15 12:32:53 +02:00
parent 5d55a11110
commit 12ffefe081
7 changed files with 104 additions and 91 deletions

View File

@ -1,5 +1,6 @@
/* 5.13.1c
* Add user entry DST/STD using commands TimeStd and TimeDst with options like 0,0,3,1,2,120 (#2721)
* Add more user input validation to commands TimeStd and TimeDst
*
* 5.13.1a
* Change user_config.h otaurl to http://sonoff.maddox.co.uk/tasmota/sonoff.bin (#2588, #2602)

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 v5.12.0m
* Updated until v5.13.1c
\*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -61,7 +61,7 @@
#define D_BRIGHTLIGHT "Яркост"
#define D_BUTTON "Бутон"
#define D_BY "от" // Written by me
#define D_BYTES "Байт"
#define D_BYTES "Байта"
#define D_CELSIUS "Целзий"
#define D_CO2 "Въглероден диоксид"
#define D_CODE "код" // Button code
@ -75,7 +75,7 @@
#define D_DARKLIGHT "Тъмна"
#define D_DEBUG "Дебъгване"
#define D_DISABLED "Деактивиран"
#define D_DISTANCE "Distance"
#define D_DISTANCE "Разстояние"
#define D_DNS_SERVER "DNS Сървър"
#define D_DONE "Изпълнено"
#define D_DST_TIME "DST"
@ -86,12 +86,12 @@
#define D_ERROR "Грешка"
#define D_FAHRENHEIT "Фаренхайт"
#define D_FAILED "Неуспешно"
#define D_FALLBACK "Обратна връзка"
#define D_FALLBACK_TOPIC "Топик на обратната връзка"
#define D_FALLBACK "Помощен"
#define D_FALLBACK_TOPIC "Помощен топик"
#define D_FALSE "Невярно"
#define D_FILE "Файл"
#define D_FREE_MEMORY "Свободна памет"
#define D_FREQUENCY "Frequency"
#define D_FREQUENCY "Честота"
#define D_GAS "Газ"
#define D_GATEWAY "Шлюз"
#define D_GROUP "Група"
@ -99,10 +99,10 @@
#define D_HOSTNAME "Име на хоста"
#define D_HUMIDITY "Влажност"
#define D_ILLUMINANCE "Осветеност"
#define D_IMMEDIATE "моментален" // Button immediate
#define D_IMMEDIATE "Моментен" // Button immediate
#define D_INDEX "Индекс"
#define D_INFO "Информация"
#define D_INFRARED "Infrared"
#define D_INFRARED "Инфрачервен"
#define D_INITIALIZED "Инициализирано"
#define D_IP_ADDRESS "IP адрес"
#define D_LIGHT "Светлина"
@ -121,9 +121,9 @@
#define D_PORT "Порт"
#define D_POWER_FACTOR "Фактор на мощността"
#define D_POWERUSAGE "Мощност"
#define D_POWERUSAGE_ACTIVE "Active Power"
#define D_POWERUSAGE_APPARENT "Apparent Power"
#define D_POWERUSAGE_REACTIVE "Reactive Power"
#define D_POWERUSAGE_ACTIVE "Активна мощност"
#define D_POWERUSAGE_APPARENT "Пълна мощност"
#define D_POWERUSAGE_REACTIVE "Реактивна мощност"
#define D_PRESSURE "Налягане"
#define D_PRESSUREATSEALEVEL "Налягане на морското ниво"
#define D_PROGRAM_FLASH_SIZE "Размер на флаш паметта за програми"
@ -159,7 +159,7 @@
#define D_UPTIME "Време от стартирането"
#define D_USER "Потребител"
#define D_UTC_TIME "UTC"
#define D_UV_INDEX "UV Index"
#define D_UV_INDEX "UV индекс"
#define D_UV_LEVEL "Ниво на ултравиолетово излъчване"
#define D_VERSION "Версия"
#define D_VOLTAGE "Напрежение"
@ -205,7 +205,7 @@
#define D_ERASED_SECTOR "Изтрит сектор"
// webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Фърмуеър MINIMAL - моля надградете го"
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Минимаен фърмуеър - моля надградете го"
#define D_WEBSERVER_ACTIVE_ON "Уеб сървърът е активен на"
#define D_WITH_IP_ADDRESS "с IP адрес"
#define D_WEBSERVER_STOPPED "Уеб сървърът е спрян"
@ -274,12 +274,12 @@
#define D_OTHER_PARAMETERS "Други параметри"
#define D_WEB_ADMIN_PASSWORD "Парола на уеб администратора"
#define D_MQTT_ENABLE "активиране на MQTT"
#define D_FRIENDLY_NAME "приятелско име"
#define D_MQTT_ENABLE "Активиране на MQTT"
#define D_FRIENDLY_NAME "Приятелско име"
#define D_BELKIN_WEMO "Belkin WeMo"
#define D_HUE_BRIDGE "Hue Bridge"
#define D_SINGLE_DEVICE "единично"
#define D_MULTI_DEVICE "мулти"
#define D_SINGLE_DEVICE "Единично"
#define D_MULTI_DEVICE "Мулти"
#define D_SAVE_CONFIGURATION "Запазване на конфигурацията"
#define D_CONFIGURATION_SAVED "Конфигурацията е запазена"
@ -299,7 +299,7 @@
#define D_MQTT_FULL_TOPIC "MQTT пълен топик"
#define D_MDNS_DISCOVERY "mDNS откриване"
#define D_MDNS_ADVERTISE "mDNS транслация"
#define D_ESP_CHIP_ID "ID на чипа ESP"
#define D_ESP_CHIP_ID "ID на ESP чипа"
#define D_FLASH_CHIP_ID "ID на чипа на флаш паметта"
#define D_FLASH_CHIP_SIZE "Размер на флаш паметта"
#define D_FREE_PROGRAM_SPACE "Свободно пространство за програми"
@ -316,7 +316,7 @@
#define D_UPLOAD_ERR_3 "Magic байтът не е 0xE9"
#define D_UPLOAD_ERR_4 "Размерът на програмата е по-голям от реалния размер на флаш паметта"
#define D_UPLOAD_ERR_5 "Грешка при зареждането в буфера"
#define D_UPLOAD_ERR_6 "Грешка пр зареждането. Включено е ниво 3 на лога"
#define D_UPLOAD_ERR_6 "Грешка при зареждането. Включено е ниво 3 на лога"
#define D_UPLOAD_ERR_7 "Зареждането е прекъснато"
#define D_UPLOAD_ERR_8 "Файлът е невалиден"
#define D_UPLOAD_ERR_9 "Файлът е прекалено голям"
@ -348,7 +348,7 @@
#define D_RESPONSE_SENT "Отговорът е изпратен"
#define D_HUE "Hue"
#define D_HUE_BRIDGE_SETUP "Hue мост настройка"
#define D_HUE_BRIDGE_SETUP "Настройка на Hue bridge"
#define D_HUE_API_NOT_IMPLEMENTED "Hue API не е внедрено"
#define D_HUE_API "Hue API"
#define D_HUE_POST_ARGS "Hue POST аргументи"
@ -413,9 +413,9 @@
// xsns_06_dht.ino
#define D_TIMEOUT_WAITING_FOR "Изтекло време за очакване на"
#define D_START_SIGNAL_LOW "стартов сигнал нисък"
#define D_START_SIGNAL_HIGH "стартов сигнал висок"
#define D_PULSE "импулс"
#define D_START_SIGNAL_LOW "Нисък стартов сигнал"
#define D_START_SIGNAL_HIGH "Висок стартов сигнал"
#define D_PULSE "Импулс"
#define D_CHECKSUM_FAILURE "Грешка в контролната сума"
// xsns_07_sht1x.ino
@ -425,10 +425,10 @@
// xsns_18_pms5003.ino
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
#define D_PARTICALS_BEYOND "Particals"
#define D_PARTICALS_BEYOND "Частици"
// sonoff_template.h
#define D_SENSOR_NONE "няма"
#define D_SENSOR_NONE "Няма"
#define D_SENSOR_DHT11 "DHT11"
#define D_SENSOR_AM2301 "AM2301"
#define D_SENSOR_SI7021 "SI7021"
@ -463,30 +463,30 @@
#define D_SENSOR_SDM120_RX "SDM120 Rx"
// Units
#define D_UNIT_AMPERE "А"
#define D_UNIT_CENTIMETER "см"
#define D_UNIT_AMPERE "A"
#define D_UNIT_CENTIMETER "cm"
#define D_UNIT_HERTZ "Hz"
#define D_UNIT_HOUR "ч"
#define D_UNIT_KILOOHM "кОм"
#define D_UNIT_KILOWATTHOUR "кВт/ч"
#define D_UNIT_LUX "лукс"
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "микрограм/м3"
#define D_UNIT_MICROMETER "микрометър"
#define D_UNIT_MICROSECOND "микросек"
#define D_UNIT_MILLIAMPERE "мА"
#define D_UNIT_MILLISECOND "мсек"
#define D_UNIT_MINUTE "мин"
#define D_UNIT_HOUR "h"
#define D_UNIT_KILOOHM ""
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m3"
#define D_UNIT_MICROMETER "µm"
#define D_UNIT_MICROSECOND "µs"
#define D_UNIT_MILLIAMPERE "mA"
#define D_UNIT_MILLISECOND "ms"
#define D_UNIT_MINUTE "min"
#define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_PRESSURE "хПа"
#define D_UNIT_SECOND "сек"
#define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "s"
#define D_UNIT_SECTORS "сектори"
#define D_UNIT_VA "VA"
#define D_UNIT_VAR "VAr"
#define D_UNIT_VOLT "В"
#define D_UNIT_WATT "Вт"
#define D_UNIT_WATTHOUR "Вт/ч"
#define D_UNIT_VOLT "V"
#define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Wh"
// Log message prefix
#define D_LOG_APPLICATION "APP: " // Application

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 v5.13.1a
* Updated until v5.13.1c
\*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -121,9 +121,9 @@
#define D_PORT "Poort"
#define D_POWER_FACTOR "Arbeidsfactor"
#define D_POWERUSAGE "Vermogen"
#define D_POWERUSAGE_ACTIVE "Active Power"
#define D_POWERUSAGE_APPARENT "Apparent Power"
#define D_POWERUSAGE_REACTIVE "Reactive Power"
#define D_POWERUSAGE_ACTIVE "Werkelijk vermogen"
#define D_POWERUSAGE_APPARENT "Schijnbaar vermogen"
#define D_POWERUSAGE_REACTIVE "Blindvermogen"
#define D_PRESSURE "Luchtdruk"
#define D_PRESSUREATSEALEVEL "ZeeLuchtdruk"
#define D_PROGRAM_FLASH_SIZE "Programma Flash Grootte"

View File

@ -455,7 +455,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
char *blcommand = strtok(dataBuf, ";");
while ((blcommand != NULL) && (backlog_index != bl_pointer)) {
while(true) {
while ((*blcommand != '\0') && (isblank(*blcommand))) { blcommand++; } // Trim leading spaces
blcommand = LTrim(blcommand);
if (!strncasecmp_P(blcommand, PSTR(D_CMND_BACKLOG), strlen(D_CMND_BACKLOG))) {
blcommand += strlen(D_CMND_BACKLOG); // Skip unnecessary command Backlog
} else {
@ -1052,19 +1052,26 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
uint8_t ts = 0;
if (CMND_TIMEDST == command_code) { ts = 1; }
if (data_len > 0) {
if (strstr(dataBuf, ",")) { // Parameter entry
uint8_t tpos = 0;
int value = strtol(dataBuf, &p, 10);
if (strstr(dataBuf, ",")) { // Process parameter entry
uint8_t tpos = 0; // Parameter index
int value = 0;
p = dataBuf; // Parameters like "1, 2,3 , 4 ,5, -120" or ",,,,,+240"
char *q = p; // Value entered flag
while (p && (tpos < 7)) {
tpos++;
if (1 == tpos) { Settings.tflag[ts].hemis = value &1; }
if (2 == tpos) { Settings.tflag[ts].week = (value < 0) ? 0 : (value > 4) ? 4 : value; }
if (3 == tpos) { Settings.tflag[ts].month = (value < 1) ? 1 : (value > 12) ? 12 : value; }
if (4 == tpos) { Settings.tflag[ts].dow = (value < 1) ? 1 : (value > 7) ? 7 : value; }
if (5 == tpos) { Settings.tflag[ts].hour = (value < 0) ? 0 : (value > 23) ? 23 : value; }
if (6 == tpos) { Settings.toffset[ts] = (value < -900) ? -900 : (value > 900) ? 900 : value; }
p++; // Skip comma
if (p > q) { // Any value entered
if (1 == tpos) { Settings.tflag[ts].hemis = value &1; }
if (2 == tpos) { Settings.tflag[ts].week = (value < 0) ? 0 : (value > 4) ? 4 : value; }
if (3 == tpos) { Settings.tflag[ts].month = (value < 1) ? 1 : (value > 12) ? 12 : value; }
if (4 == tpos) { Settings.tflag[ts].dow = (value < 1) ? 1 : (value > 7) ? 7 : value; }
if (5 == tpos) { Settings.tflag[ts].hour = (value < 0) ? 0 : (value > 23) ? 23 : value; }
if (6 == tpos) { Settings.toffset[ts] = (value < -900) ? -900 : (value > 900) ? 900 : value; }
}
p = LTrim(p); // Skip spaces
if (tpos && (*p == ',')) { p++; } // Skip separator
p = LTrim(p); // Skip spaces
q = p; // Reset any value entered flag
value = strtol(p, &p, 10);
tpos++; // Next parameter
}
ntp_force_sync = 1;
} else {

View File

@ -236,6 +236,14 @@ char* UpperCase_P(char* dest, const char* source)
return dest;
}
char* LTrim(char* p)
{
while ((*p != '\0') && (isblank(*p))) {
p++; // Trim leading spaces
}
return p;
}
char* NoAlNumToUnderscore(char* dest, const char* source)
{
char* write = dest;

View File

@ -130,20 +130,20 @@
#define NTP_SERVER3 "0.nl.pool.ntp.org" // [NtpServer3] Select third NTP server by name or IP address (93.94.224.67)
// -- Time - Start Daylight Saving Time and timezone offset from UTC in minutes
#define TIME_DST_HEMISPHERE North // Northern Hemisphere
#define TIME_DST_WEEK Last
#define TIME_DST_DAY Sun
#define TIME_DST_MONTH Mar // Last sunday in march
#define TIME_DST_HOUR 2 // at 02:00
#define TIME_DST_OFFSET +120 // +120 minutes
#define TIME_DST_HEMISPHERE North // [TimeDst] Hemisphere (0 or North, 1 or South)
#define TIME_DST_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth)
#define TIME_DST_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat)
#define TIME_DST_MONTH Mar // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec)
#define TIME_DST_HOUR 2 // Hour (0 to 23)
#define TIME_DST_OFFSET +120 // Offset from UTC in minutes (-780 to +780)
// -- Time - Start Standard Time and timezone offset from UTC in minutes
#define TIME_STD_HEMISPHERE North // Northern Hemisphere
#define TIME_STD_WEEK Last
#define TIME_STD_DAY Sun
#define TIME_STD_MONTH Oct // Last sunday in october
#define TIME_STD_HOUR 3 // at 03:00
#define TIME_STD_OFFSET +60 // +60 minutes
#define TIME_STD_HEMISPHERE North // [TimeStd] Hemisphere (0 or North, 1 or South)
#define TIME_STD_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth)
#define TIME_STD_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat)
#define TIME_STD_MONTH Oct // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec)
#define TIME_STD_HOUR 3 // Hour (0 to 23)
#define TIME_STD_OFFSET +60 // Offset from UTC in minutes (-780 to +780)
// -- Location ------------------------------------
#define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset
@ -291,7 +291,7 @@
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k2 code)
#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
#define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud)
// -- Low level interface devices -----------------

View File

@ -41,12 +41,12 @@ float sdm120_power_factor = 0;
float sdm120_frequency = 0;
float sdm120_energy_total = 0;
bool SDM_ModbusReceiveReady()
bool SDM120_ModbusReceiveReady()
{
return (SDM120Serial->available() > 1);
}
void SDM_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register_count)
void SDM120_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register_count)
{
uint8_t frame[8];
@ -57,7 +57,7 @@ void SDM_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t regi
frame[4] = (uint8_t)(register_count >> 8);
frame[5] = (uint8_t)(register_count);
uint16_t crc = SDM_calculateCRC(frame, 6); // calculate out crc only from first 6 bytes
uint16_t crc = SDM120_calculateCRC(frame, 6); // calculate out crc only from first 6 bytes
frame[6] = lowByte(crc);
frame[7] = highByte(crc);
@ -69,7 +69,7 @@ void SDM_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t regi
SDM120Serial->write(frame, sizeof(frame));
}
uint8_t SDM_ModbusReceive(float *value)
uint8_t SDM120_ModbusReceive(float *value)
{
uint8_t buffer[9];
@ -86,7 +86,7 @@ uint8_t SDM_ModbusReceive(float *value)
if (buffer[0] == 0x01 && buffer[1] == 0x04 && buffer[2] == 4) { // check node number, op code and reply bytes count
if((SDM_calculateCRC(buffer, 7)) == ((buffer[8] << 8) | buffer[7])) { //calculate crc from first 7 bytes and compare with received crc (bytes 7 & 8)
if((SDM120_calculateCRC(buffer, 7)) == ((buffer[8] << 8) | buffer[7])) { //calculate crc from first 7 bytes and compare with received crc (bytes 7 & 8)
((uint8_t*)value)[3] = buffer[3];
((uint8_t*)value)[2] = buffer[4];
@ -101,7 +101,7 @@ uint8_t SDM_ModbusReceive(float *value)
return 0; // SDM_ERR_NO_ERROR
}
uint16_t SDM_calculateCRC(uint8_t *frame, uint8_t num)
uint16_t SDM120_calculateCRC(uint8_t *frame, uint8_t num)
{
uint16_t crc, flag;
crc = 0xFFFF;
@ -121,7 +121,7 @@ uint16_t SDM_calculateCRC(uint8_t *frame, uint8_t num)
/*********************************************************************************************/
const uint16_t sdm_start_addresses[] {
const uint16_t sdm120_start_addresses[] {
0x0000, // SDM120C_VOLTAGE [V]
0x0006, // SDM120C_CURRENT [A]
0x000C, // SDM120C_POWER [W]
@ -129,8 +129,6 @@ const uint16_t sdm_start_addresses[] {
0x0018, // SDM120C_REACTIVE_POWER [VAR]
0x001E, // SDM120C_POWER_FACTOR
0x0046, // SDM120C_FREQUENCY [Hz]
0x0048, // SDM120C_IMPORT_ACTIVE_ENERGY [Wh]
0x004A, // SDM120C_EXPORT_ACTIVE_ENERGY [Wh]
0x0156 // SDM120C_TOTAL_ACTIVE_ENERGY [Wh]
};
@ -144,10 +142,10 @@ void SDM12050ms() // Every 50 mSec
sdm120_state = 0;
float value = 0;
bool data_ready = SDM_ModbusReceiveReady();
bool data_ready = SDM120_ModbusReceiveReady();
if (data_ready) {
uint8_t error = SDM_ModbusReceive(&value);
uint8_t error = SDM120_ModbusReceive(&value);
if (error) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SDM120 response error %d"), error);
AddLog(LOG_LEVEL_DEBUG);
@ -181,14 +179,14 @@ void SDM12050ms() // Every 50 mSec
sdm120_frequency = value;
break;
case 9:
case 7:
sdm120_energy_total = value;
break;
} // end switch
sdm120_read_state++;
if (sizeof(sdm_start_addresses)/2 == sdm120_read_state) {
if (sizeof(sdm120_start_addresses)/2 == sdm120_read_state) {
sdm120_read_state = 0;
}
}
@ -196,7 +194,7 @@ void SDM12050ms() // Every 50 mSec
if (0 == sdm120_send_retry || data_ready) {
sdm120_send_retry = 5;
SDM_ModbusSend(0x04, sdm_start_addresses[sdm120_read_state], 2);
SDM120_ModbusSend(0x04, sdm120_start_addresses[sdm120_read_state], 2);
} else {
sdm120_send_retry--;
}
@ -300,4 +298,3 @@ boolean Xsns23(byte function)
}
#endif // USE_SDM120