From 2fe7af9ebb4b572339f9b7d2f3005fd1a17ef321 Mon Sep 17 00:00:00 2001 From: SevenW Date: Mon, 30 Nov 2020 21:56:22 +0100 Subject: [PATCH 1/3] solve unexpected restarts of ESP due to race condition in MQTT ping timing evaluation --- src/mqtt.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 6c71707..c9b5673 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -11,10 +11,10 @@ int mqTopicLen = 0; // strlen(mqTopic) // keep-alive stuff #define MQ_TIMEOUT (60*1000) // in milliseconds -static uint32_t mqLast = 0x100000; // when we last received something -static uint32_t mqPing = 0; // when we last sent a ping -static uint32_t mqPingRx = 0; // when we last received a ping response -uint32_t mqPingMs = 0; // timeing of last ping +static volatile uint32_t mqLast = 0x100000; // when we last received something +static volatile uint32_t mqPing = 0; // when we last sent a ping +static volatile uint32_t mqPingRx = 0; // when we last received a ping response +uint32_t volatile mqPingMs = 0; // timeing of last ping // helper to subscribe to our own pings static void mqttSubPing() { @@ -100,22 +100,32 @@ void mqttConnect() { mqttClient.connect(); } +// + void mqttLoop() { - if (millis() - mqPingRx > 20*MQ_TIMEOUT) { - printf("*** No MQTT response in %d seconds - resetting\n", (millis()-mqPingRx)/1000); + uint32_t cachemqPingRx = mqPingRx; + if (millis() - cachemqPingRx > 2 * MQ_TIMEOUT) + { + printf("*** No MQTT response in %lu seconds - resetting\n", (millis() - cachemqPingRx) / 1000); ESP.restart(); } if (!WiFi.isConnected()) return; + uint32_t cachemqLast = mqLast; if (!mqttClient.connected()) { - if (millis() - mqLast > 10000) { + if (millis() - cachemqLast > 10000) + { mqttConnect(); mqLast = millis(); } - } else if (millis() - mqLast > MQ_TIMEOUT) { + } + else if (millis() - cachemqLast > MQ_TIMEOUT) + { //printf("Reconnecting to MQTT\n"); mqttConnect(); mqLast = millis(); - } else if (millis() - mqLast > MQ_TIMEOUT/2 && millis() - mqPing > MQ_TIMEOUT/2) { + } + else if (millis() - cachemqLast > MQ_TIMEOUT / 2 && millis() - mqPing > MQ_TIMEOUT / 2) + { char topic[41+6]; strcpy(topic, mqTopic); strcat(topic, "/ping"); From f52dfc8fafc467660f211002efda2045a277fba9 Mon Sep 17 00:00:00 2001 From: SevenW Date: Mon, 30 Nov 2020 21:59:40 +0100 Subject: [PATCH 2/3] solve unexpected restarts of ESP due to race condition in MQTT ping timing evaluation --- src/mqtt.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index c9b5673..918a5d0 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -12,8 +12,8 @@ int mqTopicLen = 0; // strlen(mqTopic) // keep-alive stuff #define MQ_TIMEOUT (60*1000) // in milliseconds static volatile uint32_t mqLast = 0x100000; // when we last received something -static volatile uint32_t mqPing = 0; // when we last sent a ping -static volatile uint32_t mqPingRx = 0; // when we last received a ping response +static volatile uint32_t mqPing = 0; // when we last sent a ping +static volatile uint32_t mqPingRx = 0; // when we last received a ping response uint32_t volatile mqPingMs = 0; // timeing of last ping // helper to subscribe to our own pings @@ -100,8 +100,6 @@ void mqttConnect() { mqttClient.connect(); } -// - void mqttLoop() { uint32_t cachemqPingRx = mqPingRx; if (millis() - cachemqPingRx > 2 * MQ_TIMEOUT) From 038a515d26a8cb58014bbb89d013c0539f75c761 Mon Sep 17 00:00:00 2001 From: SevenW Date: Mon, 30 Nov 2020 22:01:22 +0100 Subject: [PATCH 3/3] solve unexpected restarts of ESP due to race condition in MQTT ping timing evaluation --- src/mqtt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 918a5d0..18cb3fd 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -14,7 +14,7 @@ int mqTopicLen = 0; // strlen(mqTopic) static volatile uint32_t mqLast = 0x100000; // when we last received something static volatile uint32_t mqPing = 0; // when we last sent a ping static volatile uint32_t mqPingRx = 0; // when we last received a ping response -uint32_t volatile mqPingMs = 0; // timeing of last ping +volatile uint32_t mqPingMs = 0; // timeing of last ping // helper to subscribe to our own pings static void mqttSubPing() {