diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index d53687938..0750b4d06 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,5 +1,6 @@ /* 6.3.0.3 20181105 * Fix hardware serial pin configuration. To keep using hardware serial swap current Rx/Tx pin configuration only (#4280) + * Add more strict checks for GPIO selections * * 6.3.0.2 20181101 * Add minutes to commands Timezone to allow all possible world timezones diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 7a3948382..09e029a15 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -869,13 +869,20 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) mytmplt cmodule; memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule)); if ((GPIO_USER == ValidGPIO(index, cmodule.gp.io[index])) && (payload >= 0) && (payload < GPIO_SENSOR_END)) { - for (byte i = 0; i < MAX_GPIO_PIN; i++) { - if ((GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) && (Settings.my_gp.io[i] == payload)) { - Settings.my_gp.io[i] = 0; - } + bool present = false; + for (byte i = 0; i < sizeof(kGpioNiceList); i++) { + uint8_t midx = pgm_read_byte(kGpioNiceList + i); + if (midx == payload) { present = true; } + } + if (present) { + for (byte i = 0; i < MAX_GPIO_PIN; i++) { + if ((GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) && (Settings.my_gp.io[i] == payload)) { + Settings.my_gp.io[i] = 0; + } + } + Settings.my_gp.io[index] = payload; + restart_flag = 2; } - Settings.my_gp.io[index] = payload; - restart_flag = 2; } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{")); for (byte i = 0; i < MAX_GPIO_PIN; i++) { @@ -895,16 +902,19 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) else if (CMND_GPIOS == command_code) { mytmplt cmodule; memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule)); - for (byte i = 0; i < GPIO_SENSOR_END; i++) { - if (!GetUsedInModule(i, cmodule.gp.io)) { + uint8_t midx; + for (byte i = 0; i < sizeof(kGpioNiceList); i++) { + midx = pgm_read_byte(kGpioNiceList + i); + if (!GetUsedInModule(midx, cmodule.gp.io)) { + if (!jsflg) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_GPIOS "%d\":["), lines); } else { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data); } jsflg = 1; - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, i, GetTextIndexed(stemp1, sizeof(stemp1), i, kSensorNames)); - if ((strlen(mqtt_data) > (LOGSZ - TOPSZ)) || (i == GPIO_SENSOR_END -1)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, midx, GetTextIndexed(stemp1, sizeof(stemp1), midx, kSensorNames)); + if ((strlen(mqtt_data) > (LOGSZ - TOPSZ)) || (i == sizeof(kGpioNiceList) -1)) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]}"), mqtt_data); MqttPublishPrefixTopic_P(RESULT_OR_STAT, type); jsflg = 0; @@ -912,6 +922,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) } } } + mqtt_data[0] = '\0'; } else if ((CMND_PWM == command_code) && pwm_present && (index > 0) && (index <= MAX_PWMS)) { diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 036e2400d..eb4d910d0 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -267,7 +267,7 @@ typedef struct MYTMPLT { myio gp; } mytmplt; -const uint8_t kGpioNiceList[GPIO_SENSOR_END] PROGMEM = { +const uint8_t kGpioNiceList[] PROGMEM = { GPIO_NONE, // Not used GPIO_KEY1, // Buttons GPIO_KEY1_NP, @@ -335,48 +335,96 @@ const uint8_t kGpioNiceList[GPIO_SENSOR_END] PROGMEM = { GPIO_CNTR3_NP, GPIO_CNTR4, GPIO_CNTR4_NP, +#ifdef USE_I2C GPIO_I2C_SCL, // I2C SCL GPIO_I2C_SDA, // I2C SDA +#endif +#ifdef USE_SPI GPIO_SPI_CS, // SPI Chip Select GPIO_SPI_DC, // SPI Data Direction +#endif +#ifdef USE_DISPLAY GPIO_BACKLIGHT, // Display backlight control +#endif GPIO_DHT11, // DHT11 GPIO_DHT22, // DHT21, DHT22, AM2301, AM2302, AM2321 GPIO_SI7021, // iTead SI7021 GPIO_DSB, // Single wire DS18B20 or DS18S20 +#ifdef USE_WS2812 GPIO_WS2812, // WS2812 Led string +#endif +#ifdef USE_IR_REMOTE GPIO_IRSEND, // IR remote +#ifdef USE_IR_RECEIVE GPIO_IRRECV, // IR receiver +#endif +#endif +#ifdef USE_RC_SWITCH GPIO_RFSEND, // RF transmitter GPIO_RFRECV, // RF receiver +#endif +#ifdef USE_SR04 GPIO_SR04_TRIG, // SR04 Trigger pin GPIO_SR04_ECHO, // SR04 Echo pin +#endif +#ifdef USE_TM1638 GPIO_TM16CLK, // TM1638 Clock GPIO_TM16DIO, // TM1638 Data I/O GPIO_TM16STB, // TM1638 Strobe +#endif +#ifdef USE_HX711 GPIO_HX711_SCK, // HX711 Load Cell clock GPIO_HX711_DAT, // HX711 Load Cell data +#endif +#ifdef USE_SERIAL_BRIDGE GPIO_SBR_TX, // Serial Bridge Serial interface GPIO_SBR_RX, // Serial Bridge Serial interface +#endif +#ifdef USE_MHZ19 GPIO_MHZ_TXD, // MH-Z19 Serial interface GPIO_MHZ_RXD, // MH-Z19 Serial interface +#endif +#ifdef USE_SENSEAIR GPIO_SAIR_TX, // SenseAir Serial interface GPIO_SAIR_RX, // SenseAir Serial interface +#endif +#ifdef USE_NOVA_SDS GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface +#endif +#if defined(USE_PZEM004T) || defined(USE_PZEM_AC) || defined(USE_PZEM_DC) GPIO_PZEM0XX_TX, // PZEM0XX Serial interface +#endif +#ifdef USE_PZEM004T GPIO_PZEM004_RX, // PZEM004T Serial interface +#endif +#ifdef USE_PZEM_AC GPIO_PZEM016_RX, // PZEM-014,016 Serial Modbus interface +#endif +#ifdef USE_PZEM_DC GPIO_PZEM017_RX, // PZEM-003,017 Serial Modbus interface +#endif +#ifdef USE_SDM120 GPIO_SDM120_TX, // SDM120 Serial interface GPIO_SDM120_RX, // SDM120 Serial interface +#endif +#ifdef USE_SDM630 GPIO_SDM630_TX, // SDM630 Serial interface GPIO_SDM630_RX, // SDM630 Serial interface +#endif +#ifdef USE_PMS5003 GPIO_PMS5003, // Plantower PMS5003 Serial interface +#endif +#ifdef USE_TX20_WIND_SENSOR GPIO_TX20_TXD_BLACK, // TX20 Transmission Pin +#endif +#ifdef USE_MP3_PLAYER GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface +#endif +#ifdef USE_TUYA_DIMMER GPIO_TUYA_TX, // Tuya Serial interface GPIO_TUYA_RX // Tuya Serial interface +#endif }; const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { diff --git a/sonoff/support.ino b/sonoff/support.ino index ba7ae0d6e..c2856a782 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -646,89 +646,20 @@ boolean GetUsedInModule(byte val, uint8_t *arr) int offset = 0; if (!val) { return false; } // None -#ifndef USE_I2C - if (GPIO_I2C_SCL == val) { return true; } - if (GPIO_I2C_SDA == val) { return true; } -#endif -#ifndef USE_WS2812 - if (GPIO_WS2812 == val) { return true; } -#endif -#ifndef USE_IR_REMOTE - if (GPIO_IRSEND == val) { return true; } -#ifndef USE_IR_RECEIVE - if (GPIO_IRRECV == val) { return true; } -#endif -#endif -#ifndef USE_MHZ19 - if (GPIO_MHZ_TXD == val) { return true; } - if (GPIO_MHZ_RXD == val) { return true; } -#endif - int pzem = 3; -#ifndef USE_PZEM004T - pzem--; - if (GPIO_PZEM004_RX == val) { return true; } -#endif -#ifndef USE_PZEM_AC - pzem--; - if (GPIO_PZEM016_RX == val) { return true; } -#endif -#ifndef USE_PZEM_DC - pzem--; - if (GPIO_PZEM017_RX == val) { return true; } -#endif - if (!pzem && (GPIO_PZEM0XX_TX == val)) { return true; } + if ((val >= GPIO_KEY1) && (val < GPIO_KEY1 + MAX_KEYS)) { + offset = (GPIO_KEY1_NP - GPIO_KEY1); + } + if ((val >= GPIO_KEY1_NP) && (val < GPIO_KEY1_NP + MAX_KEYS)) { + offset = -(GPIO_KEY1_NP - GPIO_KEY1); + } -#ifndef USE_SENSEAIR - if (GPIO_SAIR_TX == val) { return true; } - if (GPIO_SAIR_RX == val) { return true; } -#endif -#ifndef USE_SPI - if (GPIO_SPI_CS == val) { return true; } - if (GPIO_SPI_DC == val) { return true; } -#endif -#ifndef USE_DISPLAY - if (GPIO_BACKLIGHT == val) { return true; } -#endif -#ifndef USE_PMS5003 - if (GPIO_PMS5003 == val) { return true; } -#endif -#ifndef USE_NOVA_SDS - if (GPIO_SDS0X1_TX == val) { return true; } - if (GPIO_SDS0X1_RX == val) { return true; } -#endif -#ifndef USE_SERIAL_BRIDGE - if (GPIO_SBR_TX == val) { return true; } - if (GPIO_SBR_RX == val) { return true; } -#endif -#ifndef USE_SR04 - if (GPIO_SR04_TRIG == val) { return true; } - if (GPIO_SR04_ECHO == val) { return true; } -#endif -#ifndef USE_SDM120 - if (GPIO_SDM120_TX == val) { return true; } - if (GPIO_SDM120_RX == val) { return true; } -#endif -#ifndef USE_SDM630 - if (GPIO_SDM630_TX == val) { return true; } - if (GPIO_SDM630_RX == val) { return true; } -#endif -#ifndef USE_TM1638 - if (GPIO_TM16CLK == val) { return true; } - if (GPIO_TM16DIO == val) { return true; } - if (GPIO_TM16STB == val) { return true; } -#endif -#ifndef USE_HX711 - if (GPIO_HX711_SCK == val) { return true; } - if (GPIO_HX711_DAT == val) { return true; } -#endif -#ifndef USE_TX20_WIND_SENSOR - if (GPIO_TX20_TXD_BLACK == val) { return true; } -#endif -#ifndef USE_RC_SWITCH - if (GPIO_RFSEND == val) { return true; } - if (GPIO_RFRECV == val) { return true; } -#endif + if ((val >= GPIO_SWT1) && (val < GPIO_SWT1 + MAX_SWITCHES)) { + offset = (GPIO_SWT1_NP - GPIO_SWT1); + } + if ((val >= GPIO_SWT1_NP) && (val < GPIO_SWT1_NP + MAX_SWITCHES)) { + offset = -(GPIO_SWT1_NP - GPIO_SWT1); + } if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) { offset = (GPIO_REL1_INV - GPIO_REL1); @@ -750,6 +681,14 @@ boolean GetUsedInModule(byte val, uint8_t *arr) if ((val >= GPIO_PWM1_INV) && (val < GPIO_PWM1_INV + MAX_PWMS)) { offset = -(GPIO_PWM1_INV - GPIO_PWM1); } + + if ((val >= GPIO_CNTR1) && (val < GPIO_CNTR1 + MAX_COUNTERS)) { + offset = (GPIO_CNTR1_NP - GPIO_CNTR1); + } + if ((val >= GPIO_CNTR1_NP) && (val < GPIO_CNTR1_NP + MAX_COUNTERS)) { + offset = -(GPIO_CNTR1_NP - GPIO_CNTR1); + } + for (byte i = 0; i < MAX_GPIO_PIN; i++) { if (arr[i] == val) { return true; } if (arr[i] == val + offset) { return true; } diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 8f7bcdefb..e7327b769 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -773,7 +773,7 @@ void HandleModuleConfiguration() mytmplt cmodule; memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule)); - for (byte j = 0; j < GPIO_SENSOR_END; j++) { + for (byte j = 0; j < sizeof(kGpioNiceList); j++) { midx = pgm_read_byte(kGpioNiceList + j); if (!GetUsedInModule(midx, cmodule.gp.io)) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, midx, midx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames));