Version 0.3.2, if WiFi connection is lost or AP is not available at startup, scan form another known AP and connect to that AP.

Sun, 19 May 2019 21:05:07 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 19 May 2019 21:05:07 +0200
changeset 53
cf91a3a20d0d
parent 52
4b5b28b0ad42
child 54
7b134c27fadb

Version 0.3.2, if WiFi connection is lost or AP is not available at startup, scan form another known AP and connect to that AP.

Makefile file | annotate | diff | comparison | revisions
main/brewboard.c file | annotate | diff | comparison | revisions
main/task_wifi.c file | annotate | diff | comparison | revisions
--- a/Makefile	Sat May 18 23:01:16 2019 +0200
+++ b/Makefile	Sun May 19 21:05:07 2019 +0200
@@ -3,7 +3,7 @@
 # project subdirectory.
 #
 
-PROJECT_VER := "0.3.1"
+PROJECT_VER := "0.3.2"
 PROJECT_NAME := brewboard
 
 include $(IDF_PATH)/make/project.mk
--- a/main/brewboard.c	Sat May 18 23:01:16 2019 +0200
+++ b/main/brewboard.c	Sun May 19 21:05:07 2019 +0200
@@ -136,10 +136,10 @@
 
     int wait = 20;
     while (wait) {
-	vTaskDelay(500 / portTICK_PERIOD_MS);
+	vTaskDelay(750 / portTICK_PERIOD_MS);
 	TFT_print(".", LASTX, LASTY);
     	if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
-	    if (wifi_state->STA_online == true)
+	    if (wifi_state->STA_connected == true)
 		wait = 0;
 	    else
 		wait--;
--- a/main/task_wifi.c	Sat May 18 23:01:16 2019 +0200
+++ b/main/task_wifi.c	Sun May 19 21:05:07 2019 +0200
@@ -18,6 +18,12 @@
 wifi_config_t			*task_wifi_ConfigSTA = NULL;	///< Current STA configuration.
 WIFI_State			*wifi_state = NULL;		///< Public state for other tasks.
 
+wifi_scan_config_t scan_config = {				///< WiFi scanner configuration.
+	.ssid = 0,
+	.bssid = 0,
+	.channel = 0,
+	.show_hidden = false
+};
 
 uint8_t				_wifi_ssid[33];			///< Current SSID
 bool				_wifi_ScanAPs = false;		///< Scanning
@@ -70,6 +76,11 @@
  */
 void time_sync_notification_cb(struct timeval *tv);
 
+/**
+ * @brief Array with AP security names
+ */
+const char *apsec[] = { "Open", "WEP", "WPA", "WPA2", "WPA WPA2", "Enterprise" };
+
 
 /****************************************************************************/
 
@@ -95,7 +106,7 @@
 	    sprintf(config.lastSSID, "%s", task_wifi_ConfigSTA->sta.ssid);
 	    write_config();
 	}
-	ESP_LOGI(TAG, "SaveStaConfig %s, record %d", wifiStation.SSID, record);
+//	ESP_LOGI(TAG, "SaveStaConfig %s, record %d", wifiStation.SSID, record);
     }
 
     return ESP_OK;
@@ -144,15 +155,16 @@
 		break;
 
 	case SYSTEM_EVENT_STA_START:
-		ESP_LOGD(TAG, "Event STA started");
 		// Set the configured hostname for the dhcp client.
 		ESP_ERROR_CHECK(tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, config.hostname));   
 		esp_wifi_connect();
 		break;
 
 	//   SYSTEM_EVENT_STA_STOP		3
-	case SYSTEM_EVENT_STA_CONNECTED:
-		ESP_LOGI(TAG, "Event STA connected");
+	case SYSTEM_EVENT_STA_CONNECTED: {
+		const system_event_sta_connected_t *connected = &event->event_info.connected;
+            	ESP_LOGI(TAG, "Event STA connected, ssid:%s, ssid_len:%d, bssid:" MACSTR ", channel:%d, authmode:%s",
+                       connected->ssid, connected->ssid_len, MAC2STR(connected->bssid), connected->channel, apsec[connected->authmode]);
 		wifi_ap_record_t ap_info;
 		esp_wifi_sta_get_ap_info(&ap_info);
 		if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
@@ -164,9 +176,13 @@
 		xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED);
 		xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED);
 		break;
+	}
+	case SYSTEM_EVENT_STA_DISCONNECTED: {
+		const system_event_sta_disconnected_t *disconnected = &event->event_info.disconnected;
+		wifi_ap_record_t    ap;
 
-	case SYSTEM_EVENT_STA_DISCONNECTED:
-		ESP_LOGI(TAG, "Event STA disconnected");
+            	ESP_LOGI(TAG, "Event STA disconnected, ssid:%s, ssid_len:%d, bssid:" MACSTR ", reason:%d",
+                       disconnected->ssid, disconnected->ssid_len, MAC2STR(disconnected->bssid), disconnected->reason);
 		if (xSemaphoreTake(xSemaphoreWiFi, 10) == pdTRUE) {
 		    wifi_state->STA_connected = false;
 		    wifi_state->STA_online = false;
@@ -176,15 +192,47 @@
 		xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED);
 		xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED);
 		sntp_stop();
+		
+		if (disconnected->reason == WIFI_REASON_NO_AP_FOUND && ! _wifi_ScanAPs) {
+		    ESP_LOGI(TAG, "Request scan for another AP");
+		    _wifi_ScanAPs = true;
+                    _wifi_ScanDone = false;
+                    ap_num = MAX_AP_NUM;
+                    ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false));
+		    xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT);	// Keep looping active.
+		    break;
+		}
+		if (disconnected->reason == WIFI_REASON_NO_AP_FOUND && _wifi_ScanAPs && _wifi_ScanDone) {
+//		    ESP_LOGI(TAG, "Scan completed, look for another AP, found:%d", _wifi_Scanned);
+		    _wifi_ScanAPs = false;
+                    _wifi_ScanDone = false;
+		    for (int i = 0; i < _wifi_Scanned; i++) {
+			ap = accessp_records[i];
+			if ((read_station(ap.ssid) != -1)) {
+			    if (wifiStation.hide) {
+				continue;               // Blacklisted.
+                            }
+			    /* We know this one */
+			    wifi_config_t* config = task_wifi_ConfigSTA;
+                            memset(config, 0x00, sizeof(wifi_config_t));
+                            memcpy(config->sta.ssid, wifiStation.SSID, strlen(wifiStation.SSID));
+                            memcpy(config->sta.password, wifiStation.Password, strlen(wifiStation.Password));
+//			ESP_LOGI(TAG, "new AP %s %s", wifiStation.SSID, wifiStation.Password);
+                            xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT);
+			    break;
+			}
+                    }
+		    break;
+		}
 
 		/*
-		 * Meanwhile, try to reconnect.
+		 * Reconnect previous AP.
 		 */
 		if (FetchStaConfig()) {
 		    xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT);
 		}
 		break;
-
+	}
 	//   SYSTEM_EVENT_STA_AUTHMODE_CHANGE	6
 	case SYSTEM_EVENT_STA_GOT_IP:
 		xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_HAS_IP);
@@ -213,9 +261,11 @@
                 sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED);
                 sntp_set_time_sync_notification_cb(time_sync_notification_cb);
                 sntp_init();
+#if 0
 		if (strlen(config.ntp_server))
                     ESP_LOGI(TAG, "NTP server %s", sntp_getservername(0));
 		ESP_LOGI(TAG, "NTP server %s", sntp_getservername(1));
+#endif
 		break;
 
 	case SYSTEM_EVENT_STA_LOST_IP:
@@ -237,7 +287,6 @@
 	//   SYSTEM_EVENT_STA_WPS_ER_PIN	12
 
     	case SYSTEM_EVENT_AP_START:
-		ESP_LOGD(TAG, "Event AP started");
     		xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_AP_STARTED);
 		if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
 		    wifi_state->AP_active = true;
@@ -247,7 +296,6 @@
 		break;
 
 	case SYSTEM_EVENT_AP_STOP:
-		ESP_LOGD(TAG, "Event AP stopped");
 		xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_AP_STARTED);
 		if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
 		    wifi_state->AP_active = false;
@@ -256,15 +304,17 @@
 		}
 		break;
 
-    	case SYSTEM_EVENT_AP_STACONNECTED:
+    	case SYSTEM_EVENT_AP_STACONNECTED: {
 		if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
 		    wifi_state->AP_clients++;
 		    xSemaphoreGive(xSemaphoreWiFi);
 		}
-		ESP_LOGI(TAG, "Event AP new client, %d connections", wifi_state->AP_clients);
+		const system_event_ap_staconnected_t *staconnected = &event->event_info.sta_connected;
+            	ESP_LOGI(TAG, "Event AP connected, mac:" MACSTR ", aid:%d, conns:%d",
+                       MAC2STR(staconnected->mac), staconnected->aid, wifi_state->AP_clients);
 		break;
-
-    	case SYSTEM_EVENT_AP_STADISCONNECTED:
+	}
+    	case SYSTEM_EVENT_AP_STADISCONNECTED: {
 		if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
 		    if (wifi_state->AP_clients > 0)
 		    	wifi_state->AP_clients--;
@@ -272,18 +322,21 @@
 		    	wifi_state->AP_clients = 0;
 		    xSemaphoreGive(xSemaphoreWiFi);
 		}
-		ESP_LOGI(TAG, "Event AP client disconnect, %d connections", wifi_state->AP_clients);
+		const system_event_ap_stadisconnected_t *stadisconnected = &event->event_info.sta_disconnected;
+            	ESP_LOGI(TAG, "Event AP disconnected, mac:" MACSTR ", aid:%d, conns:%d",
+                       MAC2STR(stadisconnected->mac), stadisconnected->aid, wifi_state->AP_clients);
 		break;
-
-	case SYSTEM_EVENT_AP_PROBEREQRECVED:
+	}
+	case SYSTEM_EVENT_AP_STAIPASSIGNED:
 		break;
 
-	//   SYSTEM_EVENT_GOT_IP6		18
-	//   SYSTEM_EVENT_ETH_START		19
-	//   SYSTEM_EVENT_ETH_STOP		20
-	//   SYSTEM_EVENT_ETH_CONNECTED		21
-	//   SYSTEM_EVENT_ETH_DISCONNECTED	22
-	//   SYSTEM_EVENT_ETH_GOT_IP		23
+	//   SYSTEM_EVENT_AP_PROBEREQRECVED	18
+	//   SYSTEM_EVENT_GOT_IP6		19
+	//   SYSTEM_EVENT_ETH_START		20
+	//   SYSTEM_EVENT_ETH_STOP		21
+	//   SYSTEM_EVENT_ETH_CONNECTED		22
+	//   SYSTEM_EVENT_ETH_DISCONNECTED	23
+	//   SYSTEM_EVENT_ETH_GOT_IP		24
 
 	default:
 		printf("Unknown event %d\n", event->event_id);
@@ -303,9 +356,9 @@
         localtime_r(&now, &timeinfo);
 	System_TimeOk = true;
         strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
-        ESP_LOGI(TAG, "System time is set: %s", strftime_buf);
+        ESP_LOGI(TAG, "NTP time is set: %s", strftime_buf);
     } else {
-    	ESP_LOGI(TAG, "Notification of unknown time synchronization event rc=%d", rc);
+    	ESP_LOGI(TAG, "NTP unknown time sync event rc=%d", rc);
     }
 }
 
@@ -348,14 +401,6 @@
     wifi_state->STA_online = false;
     wifi_state->STA_rssi = 0;
 
-    /* wifi scanner config */
-    wifi_scan_config_t scan_config = {
-	.ssid = 0,
-	.bssid = 0,
-	.channel = 0,
-	.show_hidden = false
-    };
-
     /*
      * start the softAP access point
      * stop DHCP server
@@ -378,7 +423,6 @@
 
     /* start dhcp client */
     ESP_ERROR_CHECK(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA));
-    ESP_LOGI(TAG, "Start DHCP client for STA interface.");
 
     /*
      * init wifi as station + access point
@@ -408,7 +452,7 @@
     }
     ESP_ERROR_CHECK(esp_wifi_start());
 
-    ESP_LOGI(TAG, "SoftAP start ssid: `%s' pwd: `%s' channel: %d, hidden: %s", 
+    ESP_LOGI(TAG, "AP start ssid:`%s' pwd:`%s' channel:%d, hidden:%s", 
 		    ap_config.ap.ssid, ap_config.ap.password, ap_config.ap.channel, ap_config.ap.ssid_hidden ? "yes":"no");
 
     /*
@@ -427,12 +471,10 @@
 
     for(;;) {
 
-//	ESP_LOGI(TAG, "1 wait for %08x", TASK_WIFI_REQUEST_STA_CONNECT | TASK_WIFI_REQUEST_WIFI_SCAN | TASK_WIFI_REQUEST_STA_DISCONNECT);
 	/* actions that can trigger: request a connection, a scan, or a disconnection */
 	uxBits = xEventGroupWaitBits(xEventGroupWifi, 
 		                     TASK_WIFI_REQUEST_STA_CONNECT | TASK_WIFI_REQUEST_WIFI_SCAN | TASK_WIFI_REQUEST_STA_DISCONNECT,
 		                     pdFALSE, pdFALSE, portMAX_DELAY );
-//	ESP_LOGI(TAG, "1 waitbits %08x", uxBits);
 
 	if (uxBits & TASK_WIFI_REQUEST_STA_DISCONNECT) {
 	    /*
@@ -454,7 +496,6 @@
 
 	    /* finally: release the scan request bit */
 	    xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT);
-	    ESP_LOGI(TAG, "Request disconnect is finished.");
 
 	} else if (uxBits & TASK_WIFI_REQUEST_STA_CONNECT) {
 
@@ -471,23 +512,24 @@
 	    }
 
 	    /* 
-	     * 2 scenarios here: connection is successful and TASK_WIFI_HAS_IP will be posted
+	     * 3 scenarios here: connection is successful and TASK_WIFI_STA_CONNECTED will be posted
 	     * or it's a failure and we get a TASK_WIFI_STA_FAILED with a reason code.
+	     * Or, option 3, the 5 seconds timeout is reached. This happens when the AP is not in range.
 	     * Note that the reason code is not exploited. For all intent and purposes a failure is a failure.
 	     */
-//	    ESP_LOGI(TAG, "2 wait for %08x", TASK_WIFI_HAS_IP | TASK_WIFI_STA_FAILED);
-	    uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_HAS_IP | TASK_WIFI_STA_FAILED, pdFALSE, pdFALSE, 10000 / portTICK_PERIOD_MS);
-//	    ESP_LOGI(TAG, "2 waitbits %08x", uxBits);
+//	    ESP_LOGI(TAG, "2 wait for %08x", TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED);
+	    uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED, pdFALSE, pdFALSE, 5000 / portTICK_PERIOD_MS);
+//	    ESP_LOGI(TAG, "2 waitbits %08x", uxBits & (TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED));
 
-	    if (uxBits & (TASK_WIFI_HAS_IP | TASK_WIFI_STA_FAILED)) {
+	    if (uxBits & (TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED)) {
 		/* 
 		 * only save the config if the connection was successful! 
 		 */
-		if(uxBits & TASK_WIFI_HAS_IP) {
+		if (uxBits & TASK_WIFI_STA_CONNECTED) {
 		    /* save wifi config */
 		    SaveStaConfig();
 		} else {
-		    ESP_LOGI(TAG, "Connection failed");	// TODO: Scan other SSID's for known networks.
+		    ESP_LOGI(TAG, "Connection failed");
 		    /* failed attempt to connect regardles of the reason */
 
 		    /* otherwise: reset the config */
@@ -504,7 +546,6 @@
 
 	} else if (uxBits & TASK_WIFI_REQUEST_WIFI_SCAN) {
 
-	    ESP_LOGI(TAG, "Request WiFi scan");
 	    /* safe guard against overflow */
 	    ap_num = MAX_AP_NUM;
 	    ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false));
@@ -513,21 +554,11 @@
 	    xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_WIFI_SCAN);
 	}
 
-	/*
-	 * Here we should check for reconnect actions.
-	 */
-//	ESP_LOGI(TAG, "check reconnect");
-
     } /* for(;;) */
     vTaskDelay( (TickType_t)10);
 }
 
 
-/**
- * @brief Array with AP security names
- */
-const char *apsec[] = { "Open", "WEP", "WPA", "WPA2", "WPA WPA2", "Enterprise" };
-
 
 /**
  * @brief Show an AP station as a button. The buttons are already defined.
@@ -789,6 +820,8 @@
 			    ESP_ERROR_CHECK(esp_wifi_scan_stop());
 			} else if (Choice == 0) {
 			    Main_Screen = MAIN_TOOLS_SETUP;
+			    _wifi_ScanAPs = false;
+			    _wifi_ScanDone = false;
 			    ESP_ERROR_CHECK(esp_wifi_scan_stop());
 			} else if (TimeSpent > 10) {
 			     _wifi_ScanAPs = true;

mercurial