|
@@ -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);
|
|
|
|