diff --git a/src/ESPEasy-Globals.h b/src/ESPEasy-Globals.h index 206bc31d8e..d11a4823d6 100644 --- a/src/ESPEasy-Globals.h +++ b/src/ESPEasy-Globals.h @@ -1198,22 +1198,36 @@ struct ExtraTaskSettingsStruct struct EventStruct { EventStruct() : + Data(NULL), idx(0), Par1(0), Par2(0), Par3(0), Par4(0), Par5(0), Source(0), TaskIndex(TASKS_MAX), ControllerIndex(0), ProtocolIndex(0), NotificationIndex(0), - BaseVarIndex(0), idx(0), sensorType(0), Par1(0), Par2(0), Par3(0), Par4(0), Par5(0), - OriginTaskIndex(0), Data(NULL) {} + BaseVarIndex(0), sensorType(0), OriginTaskIndex(0) {} EventStruct(const struct EventStruct& event): - Source(event.Source), TaskIndex(event.TaskIndex), ControllerIndex(event.ControllerIndex) - , ProtocolIndex(event.ProtocolIndex), NotificationIndex(event.NotificationIndex) - , BaseVarIndex(event.BaseVarIndex), idx(event.idx), sensorType(event.sensorType) - , Par1(event.Par1), Par2(event.Par2), Par3(event.Par3), Par4(event.Par4), Par5(event.Par5) - , OriginTaskIndex(event.OriginTaskIndex) - , String1(event.String1) + String1(event.String1) , String2(event.String2) , String3(event.String3) , String4(event.String4) , String5(event.String5) - , Data(event.Data) {} + , Data(event.Data) + , idx(event.idx) + , Par1(event.Par1), Par2(event.Par2), Par3(event.Par3), Par4(event.Par4), Par5(event.Par5) + , Source(event.Source), TaskIndex(event.TaskIndex), ControllerIndex(event.ControllerIndex) + , ProtocolIndex(event.ProtocolIndex), NotificationIndex(event.NotificationIndex) + , BaseVarIndex(event.BaseVarIndex), sensorType(event.sensorType) + , OriginTaskIndex(event.OriginTaskIndex) + {} + String String1; + String String2; + String String3; + String String4; + String String5; + byte *Data; + int idx; + int Par1; + int Par2; + int Par3; + int Par4; + int Par5; byte Source; byte TaskIndex; // index position in TaskSettings array, 0-11 byte ControllerIndex; // index position in Settings.Controller, 0-3 @@ -1222,20 +1236,8 @@ struct EventStruct //Edwin: Not needed, and wasnt used. We can determine the protocol index with getNotificationProtocolIndex(NotificationIndex) // byte NotificationProtocolIndex; // index position in notification array, depending on which controller plugins are loaded. byte BaseVarIndex; - int idx; byte sensorType; - int Par1; - int Par2; - int Par3; - int Par4; - int Par5; byte OriginTaskIndex; - String String1; - String String2; - String String3; - String String4; - String String5; - byte *Data; }; @@ -1394,16 +1396,16 @@ struct DeviceStruct byte Type; // How the device is connected. e.g. DEVICE_TYPE_SINGLE => connected through 1 datapin byte VType; // Type of value the plugin will return, used only for Domoticz byte Ports; // Port to use when device has multiple I/O pins (N.B. not used much) - byte ValueCount; // The number of output values of a plugin. The value should match the number of keys PLUGIN_VALUENAME1_xxx - boolean PullUpOption; // Allow to set internal pull-up resistors. - boolean InverseLogicOption; // Allow to invert the boolean state (e.g. a switch) - boolean FormulaOption; // Allow to enter a formula to convert values during read. (not possible with Custom enabled) - boolean Custom; - boolean SendDataOption; // Allow to send data to a controller. - boolean GlobalSyncOption; // No longer used. Was used for ESPeasy values sync between nodes - boolean TimerOption; // Allow to set the "Interval" timer for the plugin. - boolean TimerOptional; // When taskdevice timer is not set and not optional, use default "Interval" delay (Settings.Delay) - boolean DecimalsOnly; // Allow to set the number of decimals (otherwise treated a 0 decimals) + byte ValueCount; // The number of output values of a plugin. The value should match the number of keys PLUGIN_VALUENAME1_xxx + bool PullUpOption : 1; // Allow to set internal pull-up resistors. + bool InverseLogicOption : 1; // Allow to invert the boolean state (e.g. a switch) + bool FormulaOption : 1; // Allow to enter a formula to convert values during read. (not possible with Custom enabled) + bool Custom : 1; + bool SendDataOption : 1; // Allow to send data to a controller. + bool GlobalSyncOption : 1; // No longer used. Was used for ESPeasy values sync between nodes + bool TimerOption : 1; // Allow to set the "Interval" timer for the plugin. + bool TimerOptional : 1; // When taskdevice timer is not set and not optional, use default "Interval" delay (Settings.Delay) + bool DecimalsOnly; // Allow to set the number of decimals (otherwise treated a 0 decimals) }; typedef std::vector DeviceVector; DeviceVector Device; @@ -1468,16 +1470,16 @@ NodesMap Nodes; struct systemTimerStruct { systemTimerStruct() : - timer(0), plugin(0), TaskIndex(-1), Par1(0), Par2(0), Par3(0), Par4(0), Par5(0) {} + timer(0), Par1(0), Par2(0), Par3(0), Par4(0), Par5(0), TaskIndex(-1), plugin(0) {} unsigned long timer; - byte plugin; - int16_t TaskIndex; int Par1; int Par2; int Par3; int Par4; int Par5; + int16_t TaskIndex; + byte plugin; }; std::map systemTimers; @@ -1486,11 +1488,11 @@ std::map systemTimers; \*********************************************************************************************/ struct pinStatesStruct { - pinStatesStruct() : plugin(0), index(0), mode(0), value(0) {} + pinStatesStruct() : value(0), plugin(0), index(0), mode(0) {} + uint16_t value; byte plugin; byte index; byte mode; - uint16_t value; } pinStates[PINSTATE_TABLE_MAX]; diff --git a/src/Misc.ino b/src/Misc.ino index afb64f6658..026536bf70 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -445,8 +445,7 @@ void delayBackground(unsigned long delay) void parseCommandString(struct EventStruct *event, const String& string) { checkRAM(F("parseCommandString")); - char TmpStr1[INPUT_COMMAND_SIZE]; - TmpStr1[0] = 0; + char *TmpStr1 = new char[INPUT_COMMAND_SIZE](); event->Par1 = 0; event->Par2 = 0; event->Par3 = 0; @@ -458,6 +457,7 @@ void parseCommandString(struct EventStruct *event, const String& string) if (GetArgv(string.c_str(), TmpStr1, 4)) { event->Par3 = CalculateParam(TmpStr1); } if (GetArgv(string.c_str(), TmpStr1, 5)) { event->Par4 = CalculateParam(TmpStr1); } if (GetArgv(string.c_str(), TmpStr1, 6)) { event->Par5 = CalculateParam(TmpStr1); } + delete[] TmpStr1; } /********************************************************************************************\ @@ -568,6 +568,7 @@ boolean GetArgv(const char *string, char *argv, unsigned int argc) { boolean GetArgv(const char *string, char *argv, unsigned int argv_size, unsigned int argc) { + memset(argv, 0, argv_size); size_t string_len = strlen(string); unsigned int string_pos = 0, argv_pos = 0, argc_pos = 0; char c, d; @@ -2251,6 +2252,7 @@ for (byte x=0; x < RULESETS_MAX; x++){ \*********************************************************************************************/ void rulesProcessing(String& event) { + if (!Settings.UseRules) return; checkRAM(F("rulesProcessing")); unsigned long timer = millis(); if (loglevelActiveFor(LOG_LEVEL_INFO)) { @@ -2290,6 +2292,7 @@ void rulesProcessing(String& event) \*********************************************************************************************/ String rulesProcessingFile(const String& fileName, String& event) { + if (!Settings.UseRules) return ""; checkRAM(F("rulesProcessingFile")); if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV){ Serial.print(F("RuleDebug Processing:")); @@ -2585,7 +2588,7 @@ void processMatchedRule( { String tmpString = event.substring(equalsPos + 1); - char tmpParam[INPUT_COMMAND_SIZE]; + char* tmpParam = new char[INPUT_COMMAND_SIZE]; tmpParam[0] = 0; if (GetArgv(tmpString.c_str(),tmpParam,1)) { @@ -2595,6 +2598,7 @@ void processMatchedRule( if (GetArgv(tmpString.c_str(),tmpParam,2)) action.replace(F("%eventvalue2%"), tmpParam); // substitute %eventvalue2% in actions with the actual value from the event if (GetArgv(tmpString.c_str(),tmpParam,3)) action.replace(F("%eventvalue3%"), tmpParam); // substitute %eventvalue3% in actions with the actual value from the event if (GetArgv(tmpString.c_str(),tmpParam,4)) action.replace(F("%eventvalue4%"), tmpParam); // substitute %eventvalue4% in actions with the actual value from the event + delete[] tmpParam; } } @@ -2896,6 +2900,7 @@ boolean conditionMatch(const String& check) \*********************************************************************************************/ void rulesTimers() { + if (!Settings.UseRules) return; for (byte x = 0; x < RULES_TIMER_MAX; x++) { if (!RulesTimer[x].paused && RulesTimer[x].timestamp != 0L) // timer active? @@ -2918,6 +2923,7 @@ void rulesTimers() void createRuleEvents(byte TaskIndex) { + if (!Settings.UseRules) return; LoadTaskSettings(TaskIndex); byte BaseVarIndex = TaskIndex * VARS_PER_TASK; byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[TaskIndex]); diff --git a/src/WebServer.ino b/src/WebServer.ino index b452869771..6c32d10b1e 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -396,6 +396,7 @@ bool getCheckWebserverArg_int(const String &key, int& value) { return true; } +#define strncpy_webserver_arg(D,N) safe_strncpy(D, WebServer.arg(N).c_str(), sizeof(D)); #define update_whenset_FormItemInt(K,V) { int tmpVal; if (getCheckWebserverArg_int(K, tmpVal)) V=tmpVal;} @@ -1018,10 +1019,6 @@ void handle_config() { String name = WebServer.arg(F("name")); //String password = WebServer.arg(F("password")); - String ssid = WebServer.arg(F("ssid")); - //String key = WebServer.arg(F("key")); - String ssid2 = WebServer.arg(F("ssid2")); - //String key2 = WebServer.arg(F("key2")); String iprangelow = WebServer.arg(F("iprangelow")); String iprangehigh = WebServer.arg(F("iprangehigh")); @@ -1033,6 +1030,7 @@ void handle_config() { String espdns = WebServer.arg(F("espdns")); Settings.Unit = getFormItemInt(F("unit"), Settings.Unit); //String apkey = WebServer.arg(F("apkey")); + String ssid = WebServer.arg(F("ssid")); if (ssid[0] != 0) @@ -1053,7 +1051,7 @@ void handle_config() { copyFormPassword(F("key"), SecuritySettings.WifiKey, sizeof(SecuritySettings.WifiKey)); // SSID 2 - safe_strncpy(SecuritySettings.WifiSSID2, ssid2.c_str(), sizeof(SecuritySettings.WifiSSID2)); + strncpy_webserver_arg(SecuritySettings.WifiSSID2, F("ssid2")); copyFormPassword(F("key2"), SecuritySettings.WifiKey2, sizeof(SecuritySettings.WifiKey2)); // Access point password. @@ -1176,21 +1174,11 @@ void handle_controllers() { String usedns = WebServer.arg(F("usedns")); String controllerip = WebServer.arg(F("controllerip")); - String controllerhostname = WebServer.arg(F("controllerhostname")); const int controllerport = getFormItemInt(F("controllerport"), 0); const int protocol = getFormItemInt(F("protocol"), -1); - String controlleruser = WebServer.arg(F("controlleruser")); - String controllerpassword = WebServer.arg(F("controllerpassword")); - String controllersubscribe = WebServer.arg(F("controllersubscribe")); - String controllerpublish = WebServer.arg(F("controllerpublish")); - String MQTTLwtTopic = WebServer.arg(F("mqttlwttopic")); - String lwtmessageconnect = WebServer.arg(F("lwtmessageconnect")); - String lwtmessagedisconnect = WebServer.arg(F("lwtmessagedisconnect")); const int minimumsendinterval = getFormItemInt(F("minimumsendinterval"), 100); const int maxqueuedepth = getFormItemInt(F("maxqueuedepth"), 10); const int maxretry = getFormItemInt(F("maxretry"), 10); - String deleteoldest = WebServer.arg(F("deleteoldest")); - String mustcheckreply = WebServer.arg(F("mustcheckreply")); const int clienttimeout = getFormItemInt(F("clienttimeout"), CONTROLLER_CLIENTTIMEOUT_DFLT); @@ -1250,7 +1238,7 @@ void handle_controllers() { ControllerSettings.UseDNS = usedns.toInt(); if (ControllerSettings.UseDNS) { - safe_strncpy(ControllerSettings.HostName, controllerhostname.c_str(), sizeof(ControllerSettings.HostName)); + strncpy_webserver_arg(ControllerSettings.HostName, F("controllerhostname")); IPAddress IP; WiFi.hostByName(ControllerSettings.HostName, IP); for (byte x = 0; x < 4; x++) @@ -1264,19 +1252,19 @@ void handle_controllers() { //copy settings to struct Settings.ControllerEnabled[controllerindex] = isFormItemChecked(F("controllerenabled")); ControllerSettings.Port = controllerport; - safe_strncpy(SecuritySettings.ControllerUser[controllerindex], controlleruser.c_str(), sizeof(SecuritySettings.ControllerUser[0])); + strncpy_webserver_arg(SecuritySettings.ControllerUser[controllerindex], F("controlleruser")); //safe_strncpy(SecuritySettings.ControllerPassword[controllerindex], controllerpassword.c_str(), sizeof(SecuritySettings.ControllerPassword[0])); copyFormPassword(F("controllerpassword"), SecuritySettings.ControllerPassword[controllerindex], sizeof(SecuritySettings.ControllerPassword[0])); - safe_strncpy(ControllerSettings.Subscribe, controllersubscribe.c_str(), sizeof(ControllerSettings.Subscribe)); - safe_strncpy(ControllerSettings.Publish, controllerpublish.c_str(), sizeof(ControllerSettings.Publish)); - safe_strncpy(ControllerSettings.MQTTLwtTopic, MQTTLwtTopic.c_str(), sizeof(ControllerSettings.MQTTLwtTopic)); - safe_strncpy(ControllerSettings.LWTMessageConnect, lwtmessageconnect.c_str(), sizeof(ControllerSettings.LWTMessageConnect)); - safe_strncpy(ControllerSettings.LWTMessageDisconnect, lwtmessagedisconnect.c_str(), sizeof(ControllerSettings.LWTMessageDisconnect)); + strncpy_webserver_arg(ControllerSettings.Subscribe, F("controllersubscribe")); + strncpy_webserver_arg(ControllerSettings.Publish, F("controllerpublish")); + strncpy_webserver_arg(ControllerSettings.MQTTLwtTopic, F("mqttlwttopic")); + strncpy_webserver_arg(ControllerSettings.LWTMessageConnect, F("lwtmessageconnect")); + strncpy_webserver_arg(ControllerSettings.LWTMessageDisconnect, F("lwtmessagedisconnect")); ControllerSettings.MinimalTimeBetweenMessages = minimumsendinterval; ControllerSettings.MaxQueueDepth = maxqueuedepth; ControllerSettings.MaxRetry = maxretry; - ControllerSettings.DeleteOldest = deleteoldest.toInt(); - ControllerSettings.MustCheckReply = mustcheckreply.toInt(); + ControllerSettings.DeleteOldest = getFormItemInt(F("deleteoldest"), ControllerSettings.DeleteOldest); + ControllerSettings.MustCheckReply = getFormItemInt(F("mustcheckreply"), ControllerSettings.MustCheckReply); ControllerSettings.ClientTimeout = clienttimeout; @@ -1515,18 +1503,6 @@ void html_TD(int td_cnt) { } } -void html_input(const String& displayStr, const String& intString, int size, const String& value) { - html_TR_TD(); - TXBuffer += displayStr; - TXBuffer += F(":"); -} - //******************************************************************************** // Web Interface notifcations page @@ -1547,18 +1523,6 @@ void handle_notifications() { --notificationindex; const int notification = getFormItemInt(F("notification"), -1); - String domain = WebServer.arg(F("domain")); - String server = WebServer.arg(F("server")); - String sender = WebServer.arg(F("sender")); - String receiver = WebServer.arg(F("receiver")); - String subject = WebServer.arg(F("subject")); - String user = WebServer.arg(F("user")); - String pass = WebServer.arg(F("pass")); - String body = WebServer.arg(F("body")); - String notificationenabled = WebServer.arg(F("notificationenabled")); - - - if (notification != -1 && !notificationindexNotSet) { @@ -1578,14 +1542,15 @@ void handle_notifications() { NotificationSettings.Pin1 = getFormItemInt(F("pin1"), 0); NotificationSettings.Pin2 = getFormItemInt(F("pin2"), 0); Settings.NotificationEnabled[notificationindex] = isFormItemChecked(F("notificationenabled")); - safe_strncpy(NotificationSettings.Domain, domain.c_str(), sizeof(NotificationSettings.Domain)); - safe_strncpy(NotificationSettings.Server, server.c_str(), sizeof(NotificationSettings.Server)); - safe_strncpy(NotificationSettings.Sender, sender.c_str(), sizeof(NotificationSettings.Sender)); - safe_strncpy(NotificationSettings.Receiver, receiver.c_str(), sizeof(NotificationSettings.Receiver)); - safe_strncpy(NotificationSettings.Subject, subject.c_str(), sizeof(NotificationSettings.Subject)); - safe_strncpy(NotificationSettings.User, user.c_str(), sizeof(NotificationSettings.User)); - safe_strncpy(NotificationSettings.Pass, pass.c_str(), sizeof(NotificationSettings.Pass)); - safe_strncpy(NotificationSettings.Body, body.c_str(), sizeof(NotificationSettings.Body)); + strncpy_webserver_arg(NotificationSettings.Domain, F("domain")); + strncpy_webserver_arg(NotificationSettings.Server, F("server")); + strncpy_webserver_arg(NotificationSettings.Sender, F("sender")); + strncpy_webserver_arg(NotificationSettings.Receiver, F("receiver")); + strncpy_webserver_arg(NotificationSettings.Subject, F("subject")); + strncpy_webserver_arg(NotificationSettings.User, F("user")); + strncpy_webserver_arg(NotificationSettings.Pass, F("pass")); + strncpy_webserver_arg(NotificationSettings.Body, F("body")); + } } // Save the settings. @@ -1680,16 +1645,16 @@ void handle_notifications() { if (Notification[NotificationProtocolIndex].usesMessaging) { - html_input(F("Domain"), F("domain"), 64, NotificationSettings.Domain); - html_input(F("Server"), F("server"), 64, NotificationSettings.Server); - html_input(F("Port"), F("port"), 5, String(NotificationSettings.Port)); + addFormTextBox(F("Domain"), F("domain"), NotificationSettings.Domain, sizeof(NotificationSettings.Domain)-1); + addFormTextBox(F("Server"), F("server"), NotificationSettings.Server, sizeof(NotificationSettings.Server)-1); + addFormNumericBox(F("Port"), F("port"), NotificationSettings.Port, 1, 65535); - html_input(F("Sender"), F("sender"), 64, NotificationSettings.Sender); - html_input(F("Receiver"), F("receiver"), 64, NotificationSettings.Receiver); - html_input(F("Subject"), F("subject"), 64, NotificationSettings.Subject); + addFormTextBox(F("Sender"), F("sender"), NotificationSettings.Sender, sizeof(NotificationSettings.Sender)-1); + addFormTextBox(F("Receiver"), F("receiver"), NotificationSettings.Receiver, sizeof(NotificationSettings.Receiver)-1); + addFormTextBox(F("Subject"), F("subject"), NotificationSettings.Subject, sizeof(NotificationSettings.Subject)-1); - html_input(F("User"), F("user"), 48, NotificationSettings.User); - html_input(F("Pass"), F("pass"), 32, NotificationSettings.Pass); + addFormTextBox(F("User"), F("user"), NotificationSettings.User, sizeof(NotificationSettings.User)-1); + addFormTextBox(F("Pass"), F("pass"), NotificationSettings.Pass, sizeof(NotificationSettings.Pass)-1); html_TR_TD(); TXBuffer += F("Body: