ESP32 / modnetwork / .status() is not reliable
HW: ESP32 device
SW:
>>> os.uname()
(sysname='esp32', nodename='esp32', release='1.19.1', version='v1.19.1 on 2022-06-18', machine='ESP32 module (spiram) with ESP32')
Issue: polling WLAN(STA_IF).status() does not always provide an adequate response. Example:
>>> import socket
>>> s = socket.socket()
>>> s.connect(("192.168.1.136", 33567))
>>> WLAN(STA_IF).status()
1001
>>> s.read(18)
b'NBDMAGICIHAVEOPT\x00\x03'
>>> WLAN(STA_IF).status()
1001
In other words, sockets operate just fine while .status() == 1001 == STAT_CONNECTING. Instead, it should return .status() == 1010 == STAT_CONNECTED. Sniffing the router shows that ESP is, at least, aware of its assigned IP:

I expect that the flag wifi_sta_connected is not set properly.
https://github.com/micropython/micropython/blob/2bcd88d55645f2ea702ff70336b33be4661c97a8/ports/esp32/network_wlan.c#L280-L302
Reproducing: loop over connecting and disconnecting to the same wireless network. At some point the issue pops up.
ESP32 STA_IF reconnect loop
In a nutshell
If the ESP32 is connected to a network (such as a regular network or even a hotspot), and let's say the hotspot gets turned off or goes away... the logic in modnetwork.c will try to reconnect, which is not incorrect but there's the problem...
It will continue to try and reconnect forever, and at any point if you query the status it will be STAT_GOT_IP, I have narrowed it down to being wifi_sta_connected boolean in the event handler.
For WIFI_REASON_BEACON_TIMEOUT and WIFI_REASON_NO_AP_FOUND:
it will reconnect... which is ok, but watch:
esp_err_t e = esp_wifi_connect();
if (e != ESP_OK) {
ESP_LOGI("wifi", "error attempting to reconnect: 0x%04x", e);
} else {
reconnected = true;
}
and finally:
if (wifi_sta_connected && !reconnected) {
// If already connected and we fail to reconnect
wifi_sta_connected = false;
}
Since esp_err_t e = esp_wifi_connect(); would obviously be an async process, I think we're getting the success of dispatching the connect request. wifi_sta_connected = false never gets executed since for an AP that has gone away it'll just keep asking to reconnect, which is not incorrect... but neither do we get an accurate status. ifconfig() does however return MORE useful information.
It is good to reconnect, although the AP may be gone... perhaps the status should be set to connecting? To this end I propose that we could set the status to connecting, and it may still do its reconnect attempt, but the status would be more use.
I will need to rebuild and test if setting the status to connecting for reconnected == true, my hypothesis is that the true status will be known via another event handler.