diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c
index db35eb2da..78b6ae7bc 100644
--- a/src/httpserver/http_fns.c
+++ b/src/httpserver/http_fns.c
@@ -382,6 +382,82 @@ int http_fn_cfg_webapp_set(http_request_t *request) {
+
+int http_fn_cfg_ping(http_request_t *request) {
+ char tmpA[128];
+ const char *tmp;
+ int i;
+ int bChanged;
+
+ http_setup(request, httpMimeTypeHTML);
+ poststr(request,htmlHeader);
+ poststr(request,g_header);
+ bChanged = 0;
+ poststr(request,"
Ping watchdog (backup reconnect mechanism)
");
+ poststr(request," By default, all OpenBeken devices automatically tries to reconnect to WiFi when a connection is lost.");
+ poststr(request," I have tested the reconnect mechanism many times by restarting my router and it always worked reliably.");
+ 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
");
+ 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))) {
+ 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!
");
+ bChanged = 1;
+ }
+ if(http_getArg(request->url,"clear",tmpA,sizeof(tmpA))) {
+ CFG_SetPingDisconnectedSecondsToRestart(0);
+ CFG_SetPingIntervalSeconds(0);
+ CFG_SetPingHost("");
+ poststr(request," Ping watchdog disabled!
");
+ bChanged = 1;
+ }
+ if(bChanged) {
+ poststr(request," Changes will be applied after restarting
");
+ }
+ poststr(request," ");
+ poststr(request," Use this to enable pinger
");
+ poststr(request," ");
+ poststr(request,htmlReturnToCfg);
+ HTTP_AddBuildFooter(request);
+ poststr(request,htmlEnd);
+
+ poststr(request, NULL);
+ return 0;
+}
int http_fn_cfg_wifi(http_request_t *request) {
// for a test, show password as well...
const char *cur_ssid, *cur_pass;
@@ -1020,6 +1096,7 @@ int http_fn_cfg(http_request_t *request) {
poststr(request,"");
poststr(request,"");
poststr(request,"");
+ poststr(request,"");
poststr(request,"");
poststr(request,"");
poststr(request,"");
diff --git a/src/httpserver/http_fns.h b/src/httpserver/http_fns.h
index ba11026d6..78056b54e 100644
--- a/src/httpserver/http_fns.h
+++ b/src/httpserver/http_fns.h
@@ -21,6 +21,7 @@ int http_fn_cfg_quick(http_request_t *request);
int http_fn_cfg_ha(http_request_t *request);
int http_fn_cfg(http_request_t *request);
int http_fn_cfg_pins(http_request_t *request);
+int http_fn_cfg_ping(http_request_t *request);
int http_fn_index(http_request_t *request);
int http_fn_ota_exec(http_request_t *request);
int http_fn_ota(http_request_t *request);
diff --git a/src/httpserver/new_http.c b/src/httpserver/new_http.c
index 973d118f9..ae68e76d1 100644
--- a/src/httpserver/new_http.c
+++ b/src/httpserver/new_http.c
@@ -531,6 +531,7 @@ int HTTP_ProcessPacket(http_request_t *request) {
if(http_checkUrlBase(urlStr,"cfg")) return http_fn_cfg(request);
if(http_checkUrlBase(urlStr,"cfg_pins")) return http_fn_cfg_pins(request);
+ if(http_checkUrlBase(urlStr,"cfg_ping")) return http_fn_cfg_ping(request);
if(http_checkUrlBase(urlStr,"ota")) return http_fn_ota(request);
if(http_checkUrlBase(urlStr,"ota_exec")) return http_fn_ota_exec(request);
diff --git a/src/new_cfg.c b/src/new_cfg.c
index 8455e1cc3..ede9eeebb 100644
--- a/src/new_cfg.c
+++ b/src/new_cfg.c
@@ -17,9 +17,47 @@ int g_cfg_pendingChanges = 0;
#define CFG_IDENT_1 'F'
#define CFG_IDENT_2 'G'
-#define MAIN_CFG_VERSION 1
+#define MAIN_CFG_VERSION 2
-static byte CFG_CalcChecksum(mainConfig_t *inf) {
+// version v1
+// Version v2 is now flexible and doesnt have to be duplicated
+// in order to support previous versions any more
+typedef struct mainConfig_v1_s {
+ byte ident0;
+ byte ident1;
+ byte ident2;
+ byte crc;
+ int version;
+ // unused
+ int genericFlags;
+ // unused
+ int genericFlags2;
+ unsigned short changeCounter;
+ unsigned short otaCounter;
+ // target wifi credentials
+ char wifi_ssid[64];
+ char wifi_pass[64];
+ // MQTT information for Home Assistant
+ char mqtt_host[256];
+ char mqtt_brokerName[64];
+ char mqtt_userName[64];
+ char mqtt_pass[128];
+ int mqtt_port;
+ // addon JavaScript panel is hosted on external server
+ char webappRoot[64];
+ // TODO?
+ byte mac[6];
+ // TODO?
+ char shortDeviceName[32];
+ char longDeviceName[64];
+ pinsState_t pins;
+ byte unusedSectorA[256];
+ byte unusedSectorB[128];
+ byte unusedSectorC[128];
+ char initCommandLine[512];
+} mainConfig_v1_t;
+
+static byte CFG_CalcChecksum_V1(mainConfig_v1_t *inf) {
byte crc = 0;
crc ^= Tiny_CRC8((const char*)&inf->version,sizeof(inf->version));
crc ^= Tiny_CRC8((const char*)&inf->changeCounter,sizeof(inf->changeCounter));
@@ -45,6 +83,25 @@ static byte CFG_CalcChecksum(mainConfig_t *inf) {
return crc;
}
+static byte CFG_CalcChecksum(mainConfig_t *inf) {
+ int header_size;
+ int remaining_size;
+ byte crc;
+
+ if(inf->version <= 1) {
+ return CFG_CalcChecksum_V1((mainConfig_v1_t *)inf);
+ }
+ header_size = ((byte*)&inf->version)-((byte*)inf);
+ remaining_size = sizeof(mainConfig_t) - header_size;
+
+ ADDLOG_DEBUG(LOG_FEATURE_CFG, "CFG_CalcChecksum: header size %i, total size %i, rem size %i\n",
+ header_size, sizeof(mainConfig_t), remaining_size);
+
+ // This is more flexible method and won't be affected by field offsets
+ crc = Tiny_CRC8((const char*)&inf->version,remaining_size);
+
+ return crc;
+}
static void CFG_SetDefaultConfig() {
// must be unsigned, else print below prints negatives as e.g. FFFFFFFe
unsigned char mac[6] = { 0 };
@@ -58,10 +115,12 @@ static void CFG_SetDefaultConfig() {
g_configInitialized = 1;
memset(&g_cfg,0,sizeof(mainConfig_t));
+ g_cfg.version = MAIN_CFG_VERSION;
g_cfg.mqtt_port = 1883;
g_cfg.ident0 = CFG_IDENT_0;
g_cfg.ident1 = CFG_IDENT_1;
g_cfg.ident2 = CFG_IDENT_2;
+ strcpy(g_cfg.ping_host,"192.168.0.1");
strcpy(g_cfg.mqtt_host, "192.168.0.113");
strcpy(g_cfg.mqtt_brokerName, "test");
strcpy(g_cfg.mqtt_userName, "homeassistant");
@@ -84,8 +143,37 @@ const char *CFG_GetWebappRoot(){
const char *CFG_GetShortStartupCommand() {
return g_cfg.initCommandLine;
}
-
+const char *CFG_GetPingHost() {
+ return g_cfg.ping_host;
+}
+int CFG_GetPingDisconnectedSecondsToRestart() {
+ return g_cfg.ping_seconds;
+}
+int CFG_GetPingIntervalSeconds() {
+ return g_cfg.ping_interval;
+}
+void CFG_SetPingHost(const char *s) {
+ // this will return non-zero if there were any changes
+ if(strcpy_safe_checkForChanges(g_cfg.ping_host, s,sizeof(g_cfg.ping_host))) {
+ // mark as dirty (value has changed)
+ g_cfg_pendingChanges++;
+ }
+}
+void CFG_SetPingDisconnectedSecondsToRestart(int i) {
+ if(g_cfg.ping_seconds != i) {
+ g_cfg.ping_seconds = i;
+ // mark as dirty (value has changed)
+ g_cfg_pendingChanges++;
+ }
+}
+void CFG_SetPingIntervalSeconds(int i) {
+ if(g_cfg.ping_interval != i) {
+ g_cfg.ping_interval = i;
+ // mark as dirty (value has changed)
+ g_cfg_pendingChanges++;
+ }
+}
void CFG_SetShortStartupCommand_AndExecuteNow(const char *s) {
CFG_SetShortStartupCommand(s);
CMD_ExecuteCommand(s);
@@ -222,6 +310,7 @@ void CFG_IncrementOTACount() {
}
void CFG_Save_IfThereArePendingChanges() {
if(g_cfg_pendingChanges > 0) {
+ g_cfg.version = MAIN_CFG_VERSION;
g_cfg.changeCounter++;
g_cfg.crc = CFG_CalcChecksum(&g_cfg);
HAL_Configuration_SaveConfigMemory(&g_cfg,sizeof(g_cfg));
diff --git a/src/new_cfg.h b/src/new_cfg.h
index c8b1e6bb0..6456d393e 100644
--- a/src/new_cfg.h
+++ b/src/new_cfg.h
@@ -36,6 +36,12 @@ void CFG_IncrementOTACount();
void CFG_SetShortStartupCommand(const char *s);
void CFG_SetShortStartupCommand_AndExecuteNow(const char *s);
const char *CFG_GetShortStartupCommand();
+const char *CFG_GetPingHost();
+int CFG_GetPingDisconnectedSecondsToRestart();
+int CFG_GetPingIntervalSeconds();
+void CFG_SetPingHost(const char *s);
+void CFG_SetPingDisconnectedSecondsToRestart(int i);
+void CFG_SetPingIntervalSeconds(int i);
diff --git a/src/new_common.h b/src/new_common.h
index df377a01d..afa90c4cd 100644
--- a/src/new_common.h
+++ b/src/new_common.h
@@ -197,6 +197,8 @@ int strcat_safe(char *tg, const char *src, int tgMaxLen);
int strcpy_safe(char *tg, const char *src, int tgMaxLen);
int strcpy_safe_checkForChanges(char *tg, const char *src, int tgMaxLen);
void urldecode2_safe(char *dst, const char *srcin, int maxDstLen);
+
+// user_main.c
int Time_getUpTimeSeconds();
char Tiny_CRC8(const char *data,int length);
void RESET_ScheduleModuleReset(int delSeconds);
@@ -207,6 +209,11 @@ void Main_OnEverySecond();
int Main_GetLastRebootBootFailures();
void Main_OnPingCheckerReply(int ms);
+// new_ping.c
+void Main_SetupPingWatchDog(const char *target, int delayBetweenPings);
+
+
+
diff --git a/src/new_ping.c b/src/new_ping.c
index 68f0195c5..0df94dd26 100644
--- a/src/new_ping.c
+++ b/src/new_ping.c
@@ -6,7 +6,8 @@
*/
//
// TODO: convert it to structure-based code instead of using global variables
-// so we can have multiple ping instances running
+// so we can have multiple ping instances running.
+// One ping for "ping watchdog", second ran from console by user, etc etc
//
#include "lwip/mem.h"
@@ -156,10 +157,12 @@ static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_a
return 0; /* don't eat the packet */
}
-void ping_raw_init(void){
+
+void Main_SetupPingWatchDog(const char *target, int delayBetweenPings) {
///ipaddr_aton("192.168.0.1",&ping_target)
- ipaddr_aton("8.8.8.8",&ping_target);
+ //ipaddr_aton("8.8.8.8",&ping_target);
+ ipaddr_aton(target,&ping_target);
ping_pcb = raw_new(IP_PROTO_ICMP);
LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);
diff --git a/src/new_pins.h b/src/new_pins.h
index 574c52e62..97e2b9127 100644
--- a/src/new_pins.h
+++ b/src/new_pins.h
@@ -104,7 +104,10 @@ typedef struct mainConfig_s {
pinsState_t pins;
byte unusedSectorA[256];
byte unusedSectorB[128];
- byte unusedSectorC[128];
+ byte unusedSectorC[56];
+ int ping_interval;
+ int ping_seconds;
+ char ping_host[64];
char initCommandLine[512];
} mainConfig_t;
diff --git a/src/user_main.c b/src/user_main.c
index f832421dc..f65ab8952 100644
--- a/src/user_main.c
+++ b/src/user_main.c
@@ -350,6 +350,16 @@ 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");
}