From 1e054097dd2aa6e884cf7a53e1bbcea30a769696 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Tue, 18 Nov 2025 03:03:49 +0100 Subject: [PATCH] Added WiFi host read timeout and automatic disconnect. Added automatic WiFi reconnect in STA mode. Improved host reconnection reliability and responsiveness. --- Remote.h | 61 +++++++++++++++++++++++++++++++++++++++-------------- Utilities.h | 10 +++++++++ 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/Remote.h b/Remote.h index 2c11f69..43eddd7 100644 --- a/Remote.h +++ b/Remote.h @@ -28,12 +28,17 @@ #endif #define WIFI_UPDATE_INTERVAL_MS 500 +#define WR_SOCKET_TIMEOUT 6 +#define WR_READ_TIMEOUT_MS 6500 +#define WR_RECONNECT_INTERVAL_MS 10000 uint32_t wifi_update_interval_ms = WIFI_UPDATE_INTERVAL_MS; uint32_t last_wifi_update = 0; +uint32_t wr_last_connect_try = 0; +uint32_t wr_last_read = 0; WiFiClient connection; -WiFiServer remote_listener(7633); +WiFiServer remote_listener(7633, 1); IPAddress ap_ip(10, 0, 0, 1); IPAddress ap_nm(255, 255, 255, 0); IPAddress wr_device_ip; @@ -41,32 +46,29 @@ char wr_hostname[10]; wl_status_t wr_wifi_status = WL_IDLE_STATUS; uint8_t wifi_mode = WIFI_OFF; -bool wifi_initialized = false; +bool wifi_init_ran = false; +bool wifi_initialized = false; char wr_ssid[33]; char wr_psk[33]; +extern void host_disconnected(); + void wifi_dbg(String msg) { Serial.print("[WiFi] "); Serial.println(msg); } uint8_t wifi_remote_mode() { return wifi_mode; } -void wifi_update_status() { - wr_wifi_status = WiFi.status(); - if (wr_wifi_status == WL_CONNECTED) { wr_device_ip = WiFi.localIP(); } - if (wifi_mode == WR_WIFI_AP && wifi_initialized) { wr_device_ip = WiFi.softAPIP(); wr_wifi_status = WL_CONNECTED; } -} - bool wifi_is_connected() { return (wr_wifi_status == WL_CONNECTED); } bool wifi_host_is_connected() { if (connection) { return true; } else { return false; } } void wifi_remote_start_ap() { WiFi.mode(WIFI_AP); if (wr_ssid[0] != 0x00) { - if (wr_psk[0] != 0x00) { Serial.printf("Starting Access Point: %s / %s\n", wr_ssid, wr_psk); WiFi.softAP(wr_ssid, wr_psk, wr_channel); } - else { Serial.printf("Starting Access Point: %s\n", wr_ssid); WiFi.softAP(wr_ssid, NULL, wr_channel); } + if (wr_psk[0] != 0x00) { WiFi.softAP(wr_ssid, wr_psk, wr_channel); } + else { WiFi.softAP(wr_ssid, NULL, wr_channel); } } else { - if (wr_psk[0] != 0x00) { Serial.printf("Starting Access Point: %s / %s\n", bt_devname, wr_psk); WiFi.softAP(bt_devname, wr_psk, wr_channel); } - else { Serial.printf("Starting Access Point: %s\n", bt_devname); WiFi.softAP(bt_devname, NULL, wr_channel); } + if (wr_psk[0] != 0x00) { WiFi.softAP(bt_devname, wr_psk, wr_channel); } + else { WiFi.softAP(bt_devname, NULL, wr_channel); } } delay(150); WiFi.softAPConfig(ap_ip, ap_ip, ap_nm); @@ -101,6 +103,7 @@ void wifi_remote_start_sta() { delay(500); wr_wifi_status = WiFi.status(); wifi_initialized = true; + wr_last_connect_try = millis(); } void wifi_remote_stop() { @@ -117,6 +120,7 @@ void wifi_remote_start() { if (wifi_initialized == true) { remote_listener.begin(); + remote_listener.setTimeout(WR_SOCKET_TIMEOUT); wr_state = WR_STATE_ON; } else { remote_listener.end(); wr_state = WR_STATE_OFF; } } @@ -135,22 +139,35 @@ void wifi_remote_init() { for (uint8_t i = 0; i < 32; i++) { wr_psk[i] = EEPROM.read(config_addr(ADDR_CONF_PSK+i)); if (wr_psk[i] == 0xFF) { wr_psk[i] = 0x00; } } wr_channel = EEPROM.read(eeprom_addr(ADDR_CONF_WCHN)); if (wr_channel < 1 || wr_channel > 14) { wr_channel = WR_CHANNEL_DEFAULT; } wifi_remote_start(); + wifi_init_ran = true; } void wifi_remote_close_all() { + // wifi_dbg("Close all"); // TODO: Remove debug if (connection) { connection.stop(); } WiFiClient client = remote_listener.available(); while (client) { client.stop(); client = remote_listener.available(); } - connection = NULL; wr_state = WR_STATE_ON; } +void wifi_remote_check_active() { + if (millis()-wr_last_read >= WR_READ_TIMEOUT_MS) { + // wifi_dbg("Connection activity timed out"); // TODO: Remove debug + if (connection && connection.connected()) { + connection.stop(); + wifi_remote_close_all(); + host_disconnected(); + } + } +} + bool wifi_remote_available() { if (connection) { if (connection.connected()) { - if (connection.available()) { return true; } - else { return false; } + if (connection.available()) { wr_last_read = millis(); return true; } + else { wifi_remote_check_active(); return false; } } else { + // wifi_dbg("Client disconnected"); // TODO: Remove debug wifi_remote_close_all(); return false; } @@ -158,8 +175,10 @@ bool wifi_remote_available() { WiFiClient client = remote_listener.available(); if (!client) { return false; } else { + // wifi_dbg("Client connected"); // TODO: Remove debug connection = client; wr_state = WR_STATE_CONNECTED; + wr_last_read = millis(); if (connection.available()) { return true; } else { return false; } } @@ -169,13 +188,23 @@ bool wifi_remote_available() { uint8_t wifi_remote_read() { if (connection && connection.available()) { return connection.read(); } else { + // wifi_dbg("Error: No data to read from TCP socket"); // TODO: Remove debug if (connection) { wifi_remote_close_all(); } - wifi_dbg("Error: No data to read from TCP socket"); return 0x00; + return 0xC0; } } void wifi_remote_write(uint8_t byte) { if (connection) { connection.write(byte); } } +void wifi_update_status() { + wr_wifi_status = WiFi.status(); + if (wr_wifi_status == WL_CONNECTED) { wr_device_ip = WiFi.localIP(); } + if (wifi_mode == WR_WIFI_AP && wifi_initialized) { wr_device_ip = WiFi.softAPIP(); wr_wifi_status = WL_CONNECTED; } + if (wifi_init_ran && wifi_mode == WR_WIFI_STA && wr_wifi_status != WL_CONNECTED) { + if (millis()-wr_last_connect_try >= WR_RECONNECT_INTERVAL_MS) { wifi_remote_init(); } + } +} + void update_wifi() { if (millis()-last_wifi_update >= wifi_update_interval_ms) { wifi_update_status(); diff --git a/Utilities.h b/Utilities.h index 785ef5f..9f1575e 100644 --- a/Utilities.h +++ b/Utilities.h @@ -2009,3 +2009,13 @@ inline void fifo16_init(FIFOBuffer16 *f, uint16_t *buffer, uint16_t size) { inline uint16_t fifo16_len(FIFOBuffer16 *f) { return (f->end - f->begin); } + +extern void stopRadio(); +void host_disconnected() { + stopRadio(); + cable_state = CABLE_STATE_DISCONNECTED; + current_rssi = -292; + last_rssi = -292; + last_rssi_raw = 0x00; + last_snr_raw = 0x80; +} \ No newline at end of file