esp32/network_wlan: Wait for STA/AP START/STOP event in wlan.active.

This is a fix for commit bccbaa92b1fc6237f0f49a7f07cc194835fbf4e3:
- Should only wait for WIFI_EVENT_STA_START when invoked on the STA_IF
  interface.
- The WIFI_EVENT_STA_START event is generated every time the STA_IF
  interface is set active(True) and it was previously inactive, ie. not
  only after calling esp_wifi_start().
- Also wait for WIFI_EVENT_STA_STOP when deactivating the interface.
- Also wait for relevant AP events.

Fixes issue #11910.

Signed-off-by: Glenn Moloney <glenn.moloney@gmail.com>
Signed-off-by: Damien George <damien@micropython.org>
diff --git a/ports/esp32/network_wlan.c b/ports/esp32/network_wlan.c
index 3c88f8d..8287731 100644
--- a/ports/esp32/network_wlan.c
+++ b/ports/esp32/network_wlan.c
@@ -76,7 +76,7 @@
 #endif
 
 static uint8_t conf_wifi_sta_reconnects = 0;
-static volatile uint8_t wifi_sta_reconnects;
+static uint8_t wifi_sta_reconnects;
 
 // This function is called by the system-event task and so runs in a different
 // thread to the main MicroPython task.  It must not raise any Python exceptions.
@@ -84,9 +84,14 @@
     switch (event_id) {
         case WIFI_EVENT_STA_START:
             ESP_LOGI("wifi", "STA_START");
+            wlan_sta_obj.active = true;
             wifi_sta_reconnects = 0;
             break;
 
+        case WIFI_EVENT_STA_STOP:
+            wlan_sta_obj.active = false;
+            break;
+
         case WIFI_EVENT_STA_CONNECTED:
             ESP_LOGI("network", "CONNECTED");
             break;
@@ -140,6 +145,15 @@
             }
             break;
         }
+
+        case WIFI_EVENT_AP_START:
+            wlan_ap_obj.active = true;
+            break;
+
+        case WIFI_EVENT_AP_STOP:
+            wlan_ap_obj.active = false;
+            break;
+
         default:
             break;
     }
@@ -184,10 +198,12 @@
         wlan_sta_obj.base.type = &esp_network_wlan_type;
         wlan_sta_obj.if_id = ESP_IF_WIFI_STA;
         wlan_sta_obj.netif = esp_netif_create_default_wifi_sta();
+        wlan_sta_obj.active = false;
 
         wlan_ap_obj.base.type = &esp_network_wlan_type;
         wlan_ap_obj.if_id = ESP_IF_WIFI_AP;
         wlan_ap_obj.netif = esp_netif_create_default_wifi_ap();
+        wlan_ap_obj.active = false;
 
         wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
         ESP_LOGD("modnetwork", "Initializing WiFi");
@@ -237,16 +253,15 @@
         } else {
             esp_exceptions(esp_wifi_set_mode(mode));
             if (!wifi_started) {
-                // WIFI_EVENT_STA_START must be received before esp_wifi_connect() can be called.
-                // Use the `wifi_sta_reconnects` variable to detect that event.
-                wifi_sta_reconnects = 1;
                 esp_exceptions(esp_wifi_start());
                 wifi_started = true;
-                while (wifi_sta_reconnects != 0) {
-                    MICROPY_EVENT_POLL_HOOK;
-                }
             }
         }
+
+        // Wait for the interface to be in the correct state.
+        while (self->active != active) {
+            MICROPY_EVENT_POLL_HOOK;
+        }
     }
 
     return (mode & bit) ? mp_const_true : mp_const_false;