Browse Source

esp32, wifi: try making AP mode a bit less cantankerous

Try to make the AP mode a bit more reliable during an STA failure. It
would reconnect too much and effectively kill AP functionality.
H. Peter Anvin 2 years ago
parent
commit
2f96fcf476

+ 64 - 31
esp32/max80/wifi.cpp

@@ -14,12 +14,41 @@
 static const char *ssid, *password, *hostname, *dnsserver;
 static TimerHandle_t sta_failure_timer;
 
-static bool sta_timeout_enabled;
+enum connected {
+    CON_STA = 1,
+    CON_ETH = 2,
+    CON_AP  = 4
+};
+static volatile bool sta_timeout_enabled;
+static volatile unsigned int sta_timeout_count;
+static unsigned int connected;
+
+static void sta_bounce(void)
+{
+    if (!ssid)
+	return;
+
+    if (WiFi.status() != WL_CONNECTED) {
+	WiFi.disconnect();
+	WiFi.begin();
+    }
+}
 
 static void sta_timeout(void)
 {
-    // Enable the AP if the STA doesn't connect after a timeout
-    WiFi.enableAP(true);
+    unsigned int count = ++sta_timeout_count;
+
+    if (connected & CON_STA)
+	return;
+
+    // Try to ping the STA even if there are AP clients every
+    // 15 seconds (if an SSID is configured)
+    sta_bounce();
+
+    if (!(connected & (CON_AP|CON_STA)) && (count >= 2)) {
+	// Enable the AP if the STA doesn't connect after 30s
+	WiFi.enableAP(true);
+    }
 }
 
 static void sta_timeout_enable(void)
@@ -27,8 +56,8 @@ static void sta_timeout_enable(void)
     if (!sta_failure_timer || sta_timeout_enabled)
 	return;
 
-    sta_timeout_enabled =
-	xTimerStart(sta_failure_timer, 1);
+    sta_timeout_enabled = xTimerStart(sta_failure_timer, 1);
+    sta_timeout_count = 0;
 }
 
 static void sta_timeout_disable(void)
@@ -36,8 +65,7 @@ static void sta_timeout_disable(void)
     if (!sta_failure_timer || !sta_timeout_enabled)
 	return;
 
-    sta_timeout_enabled =
-	!xTimerStop(sta_failure_timer, 1);
+    sta_timeout_enabled = !xTimerStop(sta_failure_timer, 1);
 }
 
 static void sntp_sync_cb(struct timeval *tv)
@@ -83,6 +111,7 @@ static void stop_services(void)
 {
     if (services_started) {
 	esp_unregister_shutdown_handler(stop_services);
+	printf("[WIFI] Stopping network services\n");
 	my_httpd_stop();
 	services_started = false;
     }
@@ -163,6 +192,7 @@ static void start_services(void)
     /* Only run on first start */
     if (!services_started) {
 	services_started = true;
+	printf("[WIFI] Starting network services\n");
 	my_httpd_start();
 	esp_register_shutdown_handler(stop_services);
     }
@@ -186,14 +216,8 @@ static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
 {
     bool retry_sta  = false;
     bool is_connect = false;
-    enum connected {
-	CON_STA = 1,
-	CON_ETH = 2,
-	CON_AP  = 4
-    };
-    static unsigned int connected;
     unsigned int prev_connected = connected;
-    static int ap_clients = 0;
+    static int ap_clients;
     int prev_ap_clients = ap_clients;
     IPAddress wifi_local_ip = WiFi.localIP();
     const char *local_ip = ip_str(wifi_local_ip);
@@ -206,10 +230,10 @@ static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
 	printf("[WIFI] Completed scan for access points\n");
 	break;
     case ARDUINO_EVENT_WIFI_STA_START:
-	printf("[WIFI] Client started\n");
+	printf("[WIFI] Client mode started\n");
 	break;
     case ARDUINO_EVENT_WIFI_STA_STOP:
-	printf("[WIFI] Clients stopped\n");
+	printf("[WIFI] Client mode stopped\n");
 	connected &= ~CON_STA;
 	break;
     case ARDUINO_EVENT_WIFI_STA_CONNECTED:
@@ -262,21 +286,26 @@ static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
 	break;
     case ARDUINO_EVENT_WIFI_AP_STACONNECTED:
 	printf("[WIFI] Client connected\n");
-	ap_clients++;
+	ap_clients = WiFi.softAPgetStationNum();
 	break;
     case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED:
 	printf("[WIFI] Client disconnected\n");
-	ap_clients--;
+	ap_clients = WiFi.softAPgetStationNum();
 	break;
     case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED:
 	printf("[WIFI] Assigned IP address %s to client\n",
 	       inet_ntoa(info.wifi_ap_staipassigned.ip));
+	ap_clients = WiFi.softAPgetStationNum();
+	is_connect = true;
 	break;
     case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED:
 	printf("[WIFI] Received probe request\n");
+	ap_clients = WiFi.softAPgetStationNum();
 	break;
     case ARDUINO_EVENT_WIFI_AP_GOT_IP6:
 	printf("[WIFI] AP IPv6 is preferred\n");
+	ap_clients = WiFi.softAPgetStationNum();
+	is_connect = true;
 	break;
     case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
 	printf("[WIFI] STA IPv6 is preferred\n");
@@ -312,8 +341,9 @@ static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
 
     if (connected & ~CON_AP) {
 	sta_timeout_disable();
-	if (!ap_clients)
+	if (!ap_clients) {
 	    WiFi.enableAP(false);
+	}
     } else if (ssid) {
 	sta_timeout_enable();
     }
@@ -356,9 +386,12 @@ static void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
     if (ap_clients != prev_ap_clients)
 	setenv_ul("status.net.ap.clients", ap_clients);
 
-    if (retry_sta) {
-	WiFi.disconnect();
-	WiFi.begin();
+    /*
+     * Don't keep retrying if there are AP clients - makes the AP
+     * too unreliable to use.
+     */
+    if (retry_sta && !ap_clients) {
+	sta_bounce();
     }
 }
 
@@ -401,14 +434,14 @@ static void wifi_config_ap(void)
     printf("WiFi.softAPConfig\n");
     WiFi.softAPConfig(AP_IP, AP_Gateway, AP_Netmask);
     printf("WiFi.softAPsetHostname\n");
-    WiFi.softAPsetHostname(ap_ssid);
+    WiFi.softAPsetHostname("max80");
 
     // Conservative setting: 20 MHz (single channel) only; this is for
     // reliability, not performance.
     printf("esp_wifi_set_bandwidth\n");
     esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_AP, WIFI_BW_HT20);
 
-    // Enable unconditionally if no SSID
+    // Enable AP immediately if no SSID configured
     printf("WiFi.enableAP\n");
     WiFi.enableAP(!ssid);
 }
@@ -430,20 +463,18 @@ static void wifi_config_sta(void)
     }
 
     printf("xTimerCreate\n");
-    sta_failure_timer = xTimerCreate("wifi_sta", configTICK_RATE_HZ*30,
-				     pdFALSE, NULL,
+    sta_failure_timer = xTimerCreate("wifi_sta", configTICK_RATE_HZ*15,
+				     pdTRUE, NULL,
 				     (TimerCallbackFunction_t)sta_timeout);
     printf("sta_timeout_enable\n");
     sta_timeout_enable();
 
-    printf("WiFi.begin(%s,%s)\n", ssid, password);
-    WiFi.begin(ssid, password);
-    printf("WiFi.setAutoConnect\n");
-    WiFi.setAutoConnect(true);
     printf("WiFi.setAutoReconnect\n");
-    WiFi.setAutoReconnect(true);
+    WiFi.setAutoReconnect(false); // We are doing this "ourselves"
     printf("WiFi.enableSTA\n");
     WiFi.enableSTA(true);
+    printf("WiFi.begin(%s)\n", ssid);
+    WiFi.begin(ssid, password);
 }
 
 static const char *getenv_notempty(const char *env)
@@ -468,6 +499,8 @@ static void wifi_config(void)
     printf("WiFi.setSleep\n");
     WiFi.setSleep(false);
 
+    WiFi.setTxPower(WIFI_POWER_19_5dBm);
+
     if (hostname)
 	WiFi.hostname(hostname);
 

BIN
esp32/output/max80.ino.bin


BIN
fpga/output/bypass.rpd.gz


BIN
fpga/output/max80.fw


BIN
fpga/output/v1.fw


BIN
fpga/output/v1.rpd.gz


BIN
fpga/output/v2.fw


BIN
fpga/output/v2.rpd.gz