Fix parameter exceptions (#5555)

Fix parameter exceptions (#5555)
This commit is contained in:
Theo Arends 2019-03-31 13:06:42 +02:00
parent f7c30250c1
commit b9a0581280

View File

@ -26,6 +26,8 @@
#include <IRremoteESP8266.h> #include <IRremoteESP8266.h>
enum IrErrors { IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND, IE_SYNTAX_IRHVAC };
enum IrRemoteCommands { CMND_IRSEND, CMND_IRHVAC }; enum IrRemoteCommands { CMND_IRSEND, CMND_IRHVAC };
const char kIrRemoteCommands[] PROGMEM = D_CMND_IRSEND "|" D_CMND_IRHVAC ; const char kIrRemoteCommands[] PROGMEM = D_CMND_IRSEND "|" D_CMND_IRHVAC ;
@ -180,7 +182,7 @@ void IrReceiveCheck(void)
TOSHIBA TOSHIBA
********************/ ********************/
bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp) uint8_t IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
{ {
uint16_t rawdata[2 + 2 * 8 * HVAC_TOSHIBA_DATALEN + 2]; uint16_t rawdata[2 + 2 * 8 * HVAC_TOSHIBA_DATALEN + 2];
uint8_t data[HVAC_TOSHIBA_DATALEN] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00}; uint8_t data[HVAC_TOSHIBA_DATALEN] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00};
@ -195,7 +197,7 @@ bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0])); p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
} }
if (!p) { if (!p) {
return true; return IE_SYNTAX_IRHVAC;
} }
data[6] = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00 data[6] = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
@ -210,7 +212,7 @@ bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0])); p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
} }
if (!p) { if (!p) {
return true; return IE_SYNTAX_IRHVAC;
} }
mode = p - kFanSpeedOptions + 1; mode = p - kFanSpeedOptions + 1;
if ((1 == mode) || (7 == mode)) { if ((1 == mode) || (7 == mode)) {
@ -267,7 +269,7 @@ bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
irsend->sendRaw(rawdata, i, 38); irsend->sendRaw(rawdata, i, 38);
// interrupts(); // interrupts();
return false; return IE_NO_ERROR;
} }
@ -275,7 +277,7 @@ bool IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
MITSUBISHI MITSUBISHI
********************/ ********************/
bool IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp) uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
{ {
char *p; char *p;
uint8_t mode; uint8_t mode;
@ -289,7 +291,7 @@ bool IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0])); p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
} }
if (!p) { if (!p) {
return true; return IE_SYNTAX_IRHVAC;
} }
mode = (p - kHvacModeOptions + 1) << 3; // HOT = 0x08, DRY = 0x10, COOL = 0x18, AUTO = 0x20 mode = (p - kHvacModeOptions + 1) << 3; // HOT = 0x08, DRY = 0x10, COOL = 0x18, AUTO = 0x20
mitsubir->setMode(mode); mitsubir->setMode(mode);
@ -303,7 +305,7 @@ bool IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0])); p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
} }
if (!p) { if (!p) {
return true; return IE_SYNTAX_IRHVAC;
} }
mode = p - kFanSpeedOptions; // AUTO = 0, SPEED = 1 .. 5, SILENT = 6 mode = p - kFanSpeedOptions; // AUTO = 0, SPEED = 1 .. 5, SILENT = 6
mitsubir->setFan(mode); mitsubir->setFan(mode);
@ -315,7 +317,7 @@ bool IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"), // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"),
// mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane()); // mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane());
return false; return IE_NO_ERROR;
} }
@ -323,7 +325,7 @@ bool IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
LG LG
********************/ ********************/
bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp) uint8_t IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
{ {
uint32_t LG_Code; uint32_t LG_Code;
uint8_t data[HVAC_LG_DATALEN]; uint8_t data[HVAC_LG_DATALEN];
@ -356,7 +358,7 @@ bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power,
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0])); p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
} }
if (!p) { if (!p) {
return true; return IE_SYNTAX_IRHVAC;
} }
mode = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00 mode = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
switch (mode) { switch (mode) {
@ -400,7 +402,7 @@ bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power,
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0])); p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
} }
if (!p) { if (!p) {
return true; return IE_SYNTAX_IRHVAC;
} }
mode = p - kFanSpeedOptions; mode = p - kFanSpeedOptions;
if ((mode == 0) || (mode > 3)) { if ((mode == 0) || (mode > 3)) {
@ -431,7 +433,7 @@ bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power,
irsend->sendLG(LG_Code, 28); irsend->sendLG(LG_Code, 28);
// interrupts(); // interrupts();
return false; return IE_NO_ERROR;
} }
@ -439,7 +441,7 @@ bool IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power,
Fujitsu Fujitsu
********************/ ********************/
bool IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp) uint8_t IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
{ {
const char kFujitsuHvacModeOptions[] = "HDCAF"; const char kFujitsuHvacModeOptions[] = "HDCAF";
@ -452,7 +454,7 @@ bool IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
if (0 == HVAC_Power) { if (0 == HVAC_Power) {
ac.off(); ac.off();
ac.send(); ac.send();
return false; return IE_NO_ERROR;
} }
uint8_t modes[5] = {FUJITSU_AC_MODE_HEAT, FUJITSU_AC_MODE_DRY, FUJITSU_AC_MODE_COOL, FUJITSU_AC_MODE_AUTO, FUJITSU_AC_MODE_FAN}; uint8_t modes[5] = {FUJITSU_AC_MODE_HEAT, FUJITSU_AC_MODE_DRY, FUJITSU_AC_MODE_COOL, FUJITSU_AC_MODE_AUTO, FUJITSU_AC_MODE_FAN};
@ -468,7 +470,7 @@ bool IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
p = strchr(kFujitsuHvacModeOptions, toupper(HVAC_Mode[0])); p = strchr(kFujitsuHvacModeOptions, toupper(HVAC_Mode[0]));
} }
if (!p) { if (!p) {
return true; return IE_SYNTAX_IRHVAC;
} }
ac.setMode(modes[p - kFujitsuHvacModeOptions]); ac.setMode(modes[p - kFujitsuHvacModeOptions]);
@ -479,14 +481,14 @@ bool IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Po
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0])); p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
} }
if (!p) { if (!p) {
return true; return IE_SYNTAX_IRHVAC;
} }
ac.setFanSpeed(fanModes[p - kFanSpeedOptions]); ac.setFanSpeed(fanModes[p - kFanSpeedOptions]);
ac.setTemp(HVAC_Temp); ac.setTemp(HVAC_Temp);
ac.send(); ac.send();
return false; return IE_NO_ERROR;
} }
#endif // USE_IR_HVAC #endif // USE_IR_HVAC
@ -507,7 +509,7 @@ bool IrSendCommand(void)
{ {
char command [CMDSZ]; char command [CMDSZ];
bool serviced = true; bool serviced = true;
bool error = false; uint8_t error = IE_NO_ERROR;
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kIrRemoteCommands); int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kIrRemoteCommands);
if (-1 == command_code) { if (-1 == command_code) {
@ -521,12 +523,17 @@ bool IrSendCommand(void)
// IRSend frequency, rawdata, rawdata ... // IRSend frequency, rawdata, rawdata ...
char *p; char *p;
char *str = strtok_r(XdrvMailbox.data, ", ", &p); char *str = strtok_r(XdrvMailbox.data, ", ", &p);
if (p == nullptr) {
error = IE_INVALID_RAWDATA;
} else {
uint16_t freq = atoi(str); uint16_t freq = atoi(str);
if (!freq) { freq = 38000; } // Default to 38kHz if (!freq) { freq = 38000; } // Default to 38kHz
uint16_t count = 0; uint16_t count = 0;
char *q = p; char *q = p;
for (; *q; count += (*q++ == ',')); for (; *q; count += (*q++ == ','));
if (count) { // At least two raw data values if (0 == count) {
error = IE_INVALID_RAWDATA;
} else { // At least two raw data values
count++; count++;
uint16_t raw_array[count]; // It's safe to use stack for up to 240 packets (limited by mqtt_data length) uint16_t raw_array[count]; // It's safe to use stack for up to 240 packets (limited by mqtt_data length)
uint8_t i = 0; uint8_t i = 0;
@ -542,19 +549,19 @@ bool IrSendCommand(void)
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_FAILED); Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_FAILED);
} }
} }
else {
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_RAWDATA);
} }
} } else {
else {
char dataBufUc[XdrvMailbox.data_len]; char dataBufUc[XdrvMailbox.data_len];
UpperCase(dataBufUc, XdrvMailbox.data); UpperCase(dataBufUc, XdrvMailbox.data);
RemoveSpace(dataBufUc);
if (strlen(dataBufUc) < 8) {
error = IE_INVALID_JSON;
} else {
StaticJsonBuffer<128> jsonBuf; StaticJsonBuffer<128> jsonBuf;
JsonObject &root = jsonBuf.parseObject(dataBufUc); JsonObject &root = jsonBuf.parseObject(dataBufUc);
if (!root.success()) { if (!root.success()) {
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON); error = IE_INVALID_JSON;
} } else {
else {
// IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 } // IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
char parm_uc[10]; char parm_uc[10];
const char *protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_PROTOCOL))]; const char *protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_PROTOCOL))];
@ -589,18 +596,14 @@ bool IrSendCommand(void)
irsend_active = false; irsend_active = false;
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_PROTOCOL_NOT_SUPPORTED); Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_PROTOCOL_NOT_SUPPORTED);
} }
} } else {
else { error = IE_SYNTAX_IRSEND;
error = true;
} }
} }
} }
} }
else { } else {
error = true; error = IE_SYNTAX_IRSEND;
}
if (error) {
Response_P(PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_NO " " D_JSON_IR_PROTOCOL ", " D_JSON_IR_BITS " " D_JSON_OR " " D_JSON_IR_DATA "\"}"));
} }
} }
#ifdef USE_IR_HVAC #ifdef USE_IR_HVAC
@ -614,12 +617,15 @@ bool IrSendCommand(void)
if (XdrvMailbox.data_len) { if (XdrvMailbox.data_len) {
char dataBufUc[XdrvMailbox.data_len]; char dataBufUc[XdrvMailbox.data_len];
UpperCase(dataBufUc, XdrvMailbox.data); UpperCase(dataBufUc, XdrvMailbox.data);
RemoveSpace(dataBufUc);
if (strlen(dataBufUc) < 8) {
error = IE_INVALID_JSON;
} else {
StaticJsonBuffer<164> jsonBufer; StaticJsonBuffer<164> jsonBufer;
JsonObject &root = jsonBufer.parseObject(dataBufUc); JsonObject &root = jsonBufer.parseObject(dataBufUc);
if (!root.success()) { if (!root.success()) {
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON); error = IE_INVALID_JSON;
} } else {
else {
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE); Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
HVAC_Vendor = root[D_JSON_IRHVAC_VENDOR]; HVAC_Vendor = root[D_JSON_IRHVAC_VENDOR];
HVAC_Power = root[D_JSON_IRHVAC_POWER]; HVAC_Power = root[D_JSON_IRHVAC_POWER];
@ -627,7 +633,7 @@ bool IrSendCommand(void)
HVAC_FanMode = root[D_JSON_IRHVAC_FANSPEED]; HVAC_FanMode = root[D_JSON_IRHVAC_FANSPEED];
HVAC_Temp = root[D_JSON_IRHVAC_TEMP]; HVAC_Temp = root[D_JSON_IRHVAC_TEMP];
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Received Vendor %s, Power %d, Mode %s, FanSpeed %s, Temp %d"), HVAC_Vendor, HVAC_Power, HVAC_Mode, HVAC_FanMode, HVAC_Temp); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Received Vendor %s, Power %d, Mode %s, FanSpeed %s, Temp %d"), HVAC_Vendor, HVAC_Power, HVAC_Mode, HVAC_FanMode, HVAC_Temp);
char vendor[20]; char vendor[20];
int vendor_code = GetCommandCode(vendor, sizeof(vendor), HVAC_Vendor, kIrHvacVendors); int vendor_code = GetCommandCode(vendor, sizeof(vendor), HVAC_Vendor, kIrHvacVendors);
@ -641,20 +647,35 @@ bool IrSendCommand(void)
case VNDR_FUJITSU: case VNDR_FUJITSU:
error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break; error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
default: default:
error = true; error = IE_SYNTAX_IRHVAC;
}
} }
} }
} }
else { else {
error = true; error = IE_SYNTAX_IRHVAC;
}
if (error) {
Response_P(PSTR("{\"" D_CMND_IRHVAC "\":\"" D_JSON_WRONG " " D_JSON_IRHVAC_VENDOR ", " D_JSON_IRHVAC_MODE " " D_JSON_OR " " D_JSON_IRHVAC_FANSPEED "\"}"));
} }
} }
#endif // USE_IR_HVAC #endif // USE_IR_HVAC
else serviced = false; // Unknown command else serviced = false; // Unknown command
switch (error) {
case IE_INVALID_RAWDATA:
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_RAWDATA);
break;
case IE_INVALID_JSON:
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON);
break;
case IE_SYNTAX_IRSEND:
Response_P(PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_NO " " D_JSON_IR_PROTOCOL ", " D_JSON_IR_BITS " " D_JSON_OR " " D_JSON_IR_DATA "\"}"));
break;
#ifdef USE_IR_HVAC
case IE_SYNTAX_IRHVAC:
Response_P(PSTR("{\"" D_CMND_IRHVAC "\":\"" D_JSON_WRONG " " D_JSON_IRHVAC_VENDOR ", " D_JSON_IRHVAC_MODE " " D_JSON_OR " " D_JSON_IRHVAC_FANSPEED "\"}"));
break;
#endif // USE_IR_HVAC
}
return serviced; return serviced;
} }