From 3f830137a942f7eb54e27cfd18dadef784ff5654 Mon Sep 17 00:00:00 2001
From: openshwprojects
Date: Mon, 25 Apr 2022 21:31:05 +0200
Subject: [PATCH] Added a ping watchdog, a secondary failsafe mechanism
reconnecting device when a certain host is not reachable. This is needed
because in some very rare cases users reports that devices are not able to
reconnect to wifi after connection in lost (despite of handling disconnect
even in code.... for me it's working, but still)
---
src/httpserver/http_fns.c | 14 +++++----
src/new_common.h | 7 ++++-
src/new_ping.c | 27 ++++++++++-------
src/user_main.c | 60 ++++++++++++++++++++++++++++---------
windowsTest_msvc2008.vcproj | 8 +++--
5 files changed, 84 insertions(+), 32 deletions(-)
diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c
index 78b6ae7bc..8ead4e7a1 100644
--- a/src/httpserver/http_fns.c
+++ b/src/httpserver/http_fns.c
@@ -234,6 +234,10 @@ int http_fn_index(http_request_t *request) {
hprintf128(request,"Cfg size: %i, change counter: %i, ota counter: %i, boot incompletes %i (might change to 0 if you wait to 30 sec)! ",
sizeof(g_cfg),g_cfg.changeCounter,g_cfg.otaCounter,Main_GetLastRebootBootFailures());
+ hprintf128(request,"Ping watchdog - %i lost, %i ok! ",
+ PingWatchDog_GetTotalLost(),PingWatchDog_GetTotalReceived());
+
+
poststr(request,htmlReturnToMenu);
HTTP_AddBuildFooter(request);
poststr(request,htmlEnd);
@@ -399,17 +403,17 @@ int http_fn_cfg_ping(http_request_t *request) {
poststr(request," However, according to some reports, there are still some edge cases when a device fails to reconnect to WIFi.");
poststr(request," This is why this mechanism has been added.
");
poststr(request," This mechanism keeps pinging certain host and reconnects to WiFi if it doesn't respond at all for a certain amount of seconds.
");
- poststr(request," USAGE: For a host, choose the main address of your router and make sure it responds to a pings. Interval can be 2 seconds or so, timeout 60 sec
");
+ poststr(request," USAGE: For a host, choose the main address of your router and make sure it responds to a pings. Interval is 1 second or so, timeout can be set by user, to eg. 60 sec
");
if(http_getArg(request->url,"host",tmpA,sizeof(tmpA))) {
CFG_SetPingHost(tmpA);
poststr(request," New ping host set! ");
bChanged = 1;
}
- if(http_getArg(request->url,"interval",tmpA,sizeof(tmpA))) {
+ /* if(http_getArg(request->url,"interval",tmpA,sizeof(tmpA))) {
CFG_SetPingIntervalSeconds(atoi(tmpA));
poststr(request," New ping interval set! ");
bChanged = 1;
- }
+ }*/
if(http_getArg(request->url,"disconnectTime",tmpA,sizeof(tmpA))) {
CFG_SetPingDisconnectedSecondsToRestart(atoi(tmpA));
poststr(request," New ping disconnectTime set! ");
@@ -436,11 +440,11 @@ int http_fn_cfg_ping(http_request_t *request) {
tmp = CFG_GetPingHost();
poststr(request,tmp);
- poststr(request, "\"> \
+ /* poststr(request, "\"> \
Interval (s) between pings: \
\
Take action after this number of seconds with no reply: \
diff --git a/src/new_common.h b/src/new_common.h
index afa90c4cd..b1cfa4b77 100644
--- a/src/new_common.h
+++ b/src/new_common.h
@@ -210,7 +210,12 @@ int Main_GetLastRebootBootFailures();
void Main_OnPingCheckerReply(int ms);
// new_ping.c
-void Main_SetupPingWatchDog(const char *target, int delayBetweenPings);
+void Main_SetupPingWatchDog(const char *target/*, int delayBetweenPings_Seconds*/);
+int PingWatchDog_GetTotalLost();
+int PingWatchDog_GetTotalReceived();
+
+
+
diff --git a/src/new_ping.c b/src/new_ping.c
index 765b93c07..7df235ed8 100644
--- a/src/new_ping.c
+++ b/src/new_ping.c
@@ -33,11 +33,7 @@
#define PING_DEBUG LWIP_DBG_ON
#endif
-
-/** ping delay - in milliseconds */
-#ifndef PING_DELAY
-#define PING_DELAY 1000
-#endif
+#define PING_DELAY 1000
/** ping identifier - must fit on a u16_t */
#ifndef PING_ID
@@ -60,7 +56,8 @@ static unsigned short ping_seq_num;
static struct raw_pcb *ping_pcb;
static unsigned int ping_lost = 0;
static unsigned int ping_received = 0;
-static int bReceivedLastOneSend = 0;
+static int bReceivedLastOneSend = -1;
+//static int g_delayBetweenPings_MS = 1000;
static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
{
@@ -102,7 +99,7 @@ static void ping_send(struct raw_pcb *raw, const ip_addr_t *addr)
ping_prepare_echo(iecho, (u16_t)ping_size);
if(bReceivedLastOneSend == 0) {
- addLogAdv(LOG_INFO,LOG_FEATURE_MAIN,"Ping lost: (total lost %i, recv %i)\r\n",ping_lost,ping_received);
+ //addLogAdv(LOG_INFO,LOG_FEATURE_MAIN,"Ping lost: (total lost %i, recv %i)\r\n",ping_lost,ping_received);
ping_lost++;
}
bReceivedLastOneSend = 0;
@@ -147,7 +144,9 @@ static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_a
// LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", ms));
ping_received++;
bReceivedLastOneSend = 1;
- addLogAdv(LOG_INFO,LOG_FEATURE_MAIN,"Ping recv: %ims (total lost %i, recv %i)\r\n", ms,ping_lost,ping_received);
+
+ //addLogAdv(LOG_INFO,LOG_FEATURE_MAIN,"Ping recv: %ims (total lost %i, recv %i)\r\n", ms,ping_lost,ping_received);
+
// addLogAdv(LOG_INFO,LOG_FEATURE_MAIN,"Ping recv: %ims\r\n", ms);
Main_OnPingCheckerReply(ms);
PING_RESULT(1);
@@ -161,9 +160,17 @@ static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_a
return 0; /* don't eat the packet */
}
+int PingWatchDog_GetTotalLost() {
+ return ping_lost;
+}
+int PingWatchDog_GetTotalReceived() {
+ return ping_received;
+}
+void Main_SetupPingWatchDog(const char *target/*, int delayBetweenPings_Seconds*/) {
-void Main_SetupPingWatchDog(const char *target, int delayBetweenPings) {
-
+ // none sent yet.
+ bReceivedLastOneSend = -1;
+ //g_delayBetweenPings_MS = delayBetweenPings_Seconds * 1000;
///ipaddr_aton("192.168.0.1",&ping_target)
//ipaddr_aton("8.8.8.8",&ping_target);
ipaddr_aton(target,&ping_target);
diff --git a/src/user_main.c b/src/user_main.c
index f65ab8952..310834094 100644
--- a/src/user_main.c
+++ b/src/user_main.c
@@ -48,9 +48,12 @@ static int g_bOpenAccessPointMode = 0;
static int g_bootFailures = 0;
static int g_saveCfgAfter = 0;
+static int g_startPingWatchDogAfter = 0;
// not really , but rather a loop count, but it doesn't really matter much
static int g_timeSinceLastPingReply = 0;
+// was it ran?
+static int g_bPingWatchDogStarted = 0;
#define LOG_FEATURE LOG_FEATURE_MAIN
@@ -167,7 +170,17 @@ void Main_OnEverySecond()
DRV_OnEverySecond();
#endif
- g_timeSinceLastPingReply++;
+ // some users say that despite our simple reconnect mechanism
+ // there are some rare cases when devices stuck outside network
+ // That is why we can also reconnect them by basing on ping
+ if(g_timeSinceLastPingReply != -1 && g_secondsElapsed > 60) {
+ g_timeSinceLastPingReply++;
+ if(g_timeSinceLastPingReply == CFG_GetPingDisconnectedSecondsToRestart()) {
+ ADDLOGF_INFO("[Ping watchdog] No ping replies within %i seconds. Will try to reconnect.\n",g_timeSinceLastPingReply);
+ g_bHasWiFiConnected = 0;
+ g_connectToWiFi = 10;
+ }
+ }
g_secondsElapsed ++;
@@ -176,8 +189,8 @@ void Main_OnEverySecond()
} else {
safe = "";
}
- ADDLOGF_INFO("%sTime %i, free %d, MQTT %i, bWifi %i\n",
- safe, g_secondsElapsed, xPortGetFreeHeapSize(),bMQTTconnected, g_bHasWiFiConnected);
+ ADDLOGF_INFO("%sTime %i, free %d, MQTT %i, bWifi %i, secondsWithNoPing %i\n",
+ safe, g_secondsElapsed, xPortGetFreeHeapSize(),bMQTTconnected, g_bHasWiFiConnected,g_timeSinceLastPingReply);
// print network info
if (!(g_secondsElapsed % 10)){
@@ -197,6 +210,32 @@ void Main_OnEverySecond()
g_bOpenAccessPointMode = 1;
}
}
+ if(g_startPingWatchDogAfter) {
+ g_startPingWatchDogAfter--;
+ if(0==g_startPingWatchDogAfter) {
+ const char *pingTargetServer;
+ ///int pingInterval;
+ int restartAfterNoPingsSeconds;
+
+ g_bPingWatchDogStarted = 1;
+
+ pingTargetServer = CFG_GetPingHost();
+ //pingInterval = CFG_GetPingIntervalSeconds();
+ restartAfterNoPingsSeconds = CFG_GetPingDisconnectedSecondsToRestart();
+
+ if(*pingTargetServer /* && pingInterval > 0*/ && restartAfterNoPingsSeconds > 0) {
+ // mark as enabled
+ g_timeSinceLastPingReply = 0;
+ // Main_SetupPingWatchDog(pingTargetServer,pingInterval);
+ Main_SetupPingWatchDog(pingTargetServer
+ /*,1*/
+ );
+ } else {
+ // mark as disabled
+ g_timeSinceLastPingReply = -1;
+ }
+ }
+ }
if(g_connectToWiFi){
g_connectToWiFi --;
if(0 == g_connectToWiFi && g_bHasWiFiConnected == 0) {
@@ -210,7 +249,10 @@ void Main_OnEverySecond()
HAL_WiFi_SetupStatusCallback(Main_OnWiFiStatusChange);
ADDLOGF_DEBUG("Registered for wifi changes\r\n");
- //ping_raw_init();
+ // it must be done with a delay
+ if (g_bootFailures < 2 && g_bPingWatchDogStarted == 0){
+ g_startPingWatchDogAfter = 60;
+ }
}
}
@@ -350,16 +392,6 @@ void Main_Init()
CMD_Init();
if (g_bootFailures < 2){
- const char *pingTargetServer;
- int pingInterval;
-
- pingTargetServer = CFG_GetPingHost();
- pingInterval = CFG_GetPingIntervalSeconds();
-
- if(*pingTargetServer && pingInterval > 0) {
- Main_SetupPingWatchDog(pingTargetServer,pingInterval);
- }
-
CMD_ExecuteCommand(CFG_GetShortStartupCommand());
CMD_ExecuteCommand("exec autoexec.bat");
}
diff --git a/windowsTest_msvc2008.vcproj b/windowsTest_msvc2008.vcproj
index 9c907f31b..2c31743f3 100644
--- a/windowsTest_msvc2008.vcproj
+++ b/windowsTest_msvc2008.vcproj
@@ -275,6 +275,10 @@
/>
+
+
@@ -716,7 +720,7 @@
>