Wed, 03 Jul 2019 10:39:58 +0200
Removed unused file.
/** * @file task_wifi.c * @brief WiFi task. Connects to a known Access Point. If we know more then * one AP, try to connect all of them until it succeeds (Not yet written). */ #include "config.h" static const char *TAG = "task_wifi"; SemaphoreHandle_t xSemaphoreWiFi = NULL; ///< Semaphore WiFi task. EventGroupHandle_t xEventGroupWifi; ///< Events WiFi task. uint16_t ap_num = MAX_AP_NUM; ///< Scan counter. wifi_ap_record_t *accessp_records; ///< [MAX_AP_NUM] records array with scan results. 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 bool _wifi_ScanDone = false; ///< Scan ready uint16_t _wifi_Scanned = 0; ///< Total scanned APs. extern int Main_Screen; ///< Current Screen number. extern sButton Buttons[MAXBUTTONS]; ///< Buttons definitions. extern uint32_t TimeSpent; ///< Counter that is increased each second. extern bool System_TimeOk; extern time_t now; extern char strftime_buf[64]; extern struct tm timeinfo; const int TASK_WIFI_REQUEST_WIFI_SCAN = BIT0; ///< When set, means a client requested to scan wireless networks. const int TASK_WIFI_REQUEST_STA_DISCONNECT = BIT1; ///< When set, means a client requested to disconnect from currently connected AP. const int TASK_WIFI_REQUEST_STA_CONNECT = BIT2; ///< When set, means a client requested to connect to an access point. const int TASK_WIFI_HAS_IP = BIT3; ///< Indicate that we have an IP address const int TASK_WIFI_AP_STARTED = BIT4; ///< Indicate that the SoftAP is started const int TASK_WIFI_STA_FAILED = BIT5; ///< Indicate that we could not get a connection to AP as station. const int TASK_WIFI_STA_DISCONNECTED = BIT6; ///< Indicate that we are disconnected from an ap station. const int TASK_WIFI_STA_CONNECTED = BIT7; ///< Indicate that we are connected to AP as station, flip of BIT6. /** * @brief Local function, save station configuration. * @return Esp error code. */ esp_err_t SaveStaConfig(void); /** * @brief Local function, fetch last connected station configuration. * @return True if there was a last connection, false if there was not. */ bool FetchStaConfig(void); /** * @brief Local function, WiFi event handler. * @param ctx Context * @param event The event * @return Esp error code. */ esp_err_t task_wifi_EventHandler(void *ctx, system_event_t *event); /** * @brief local callback function. Is called when the timesync is valid * from a timeserver. Sets the global boolean System_TimeOk value. * @param tv is the received time. Not used. */ void time_sync_notification_cb(struct timeval *tv); /** * @brief Array with AP security names */ const char *apsec[] = { "Open", "WEP", "WPA", "WPA2", "WPA WPA2", "Enterprise" }; /****************************************************************************/ esp_err_t SaveStaConfig(void) { int record; if (task_wifi_ConfigSTA && strlen((char *)task_wifi_ConfigSTA->sta.ssid)) { /* * Store in /spiffs/stations.conf if it's a new station. */ record = read_station(task_wifi_ConfigSTA->sta.ssid); if (record == -1) { add_station(task_wifi_ConfigSTA->sta.ssid, task_wifi_ConfigSTA->sta.password); } /* * Update main configuration if needed. */ if (strcmp(config.lastSSID, (char *)task_wifi_ConfigSTA->sta.ssid)) { sprintf(config.lastSSID, "%s", task_wifi_ConfigSTA->sta.ssid); write_config(); } // ESP_LOGI(TAG, "SaveStaConfig %s, record %d", wifiStation.SSID, record); } return ESP_OK; } bool FetchStaConfig(void) { if (task_wifi_ConfigSTA == NULL) { task_wifi_ConfigSTA = (wifi_config_t*)malloc(sizeof(wifi_config_t)); } memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); /* * Search last connected AP as station. */ if (strlen(config.lastSSID) && (read_station((uint8_t *)config.lastSSID) >= 0)) { /* ssid */ size_t sz = sizeof(task_wifi_ConfigSTA->sta.ssid); memcpy(task_wifi_ConfigSTA->sta.ssid, wifiStation.SSID, sz); /* password */ sz = sizeof(task_wifi_ConfigSTA->sta.password); memcpy(task_wifi_ConfigSTA->sta.password, wifiStation.Password, sz); ESP_LOGI(TAG, "FetchStaConfig: last connected to ssid: %s", task_wifi_ConfigSTA->sta.ssid); return task_wifi_ConfigSTA->sta.ssid[0] != '\0'; } ESP_LOGI(TAG, "FetchStaConfig: no last connection found"); return false; } esp_err_t task_wifi_EventHandler(void *ctx, system_event_t *event) { switch(event->event_id) { case SYSTEM_EVENT_SCAN_DONE: // Get the results so the memory used is freed. ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_num, accessp_records)); _wifi_Scanned = ap_num; _wifi_ScanDone = true; break; case SYSTEM_EVENT_STA_START: // 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: { 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) { wifi_state->STA_connected = true; wifi_state->STA_rssi = ap_info.rssi; sprintf(wifi_state->STA_ssid, "%s", ap_info.ssid); xSemaphoreGive(xSemaphoreWiFi); } 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; 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; wifi_state->STA_rssi = 0; xSemaphoreGive(xSemaphoreWiFi); } 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; } /* * 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); tcpip_adapter_ip_info_t ip; memset(&ip, 0, sizeof(tcpip_adapter_ip_info_t)); if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip) == 0) { if (xSemaphoreTake(xSemaphoreWiFi, 10) == pdTRUE) { wifi_state->STA_online = true; snprintf(wifi_state->STA_ip, 16, IPSTR, IP2STR(&ip.ip)); snprintf(wifi_state->STA_nm, 16, IPSTR, IP2STR(&ip.netmask)); snprintf(wifi_state->STA_gw, 16, IPSTR, IP2STR(&ip.gw)); xSemaphoreGive(xSemaphoreWiFi); } } /* * There doesn't seem to be support for configuring NTP via DHCP so * we need to hardcode the ntp servers. The preffered server can be * set via the setup screen. It should be on your LAN, else leave it * empty. And if you are on a different lan someday, there is no extra * delay because the hostname will not be found. */ sntp_stop(); if (strlen(config.ntp_server)) sntp_setservername(0, config.ntp_server); sntp_setservername(1, (char *)"pool.ntp.org"); // Will get you servers nearby 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: ESP_LOGI(TAG, "Lost IP address"); xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_HAS_IP); if (xSemaphoreTake(xSemaphoreWiFi, 10) == pdTRUE) { wifi_state->STA_ip[0] = '\0'; wifi_state->STA_nm[0] = '\0'; wifi_state->STA_gw[0] = '\0'; wifi_state->STA_online = false; xSemaphoreGive(xSemaphoreWiFi); } sntp_stop(); break; // SYSTEM_EVENT_STA_WPS_ER_SUCCESS 9 // SYSTEM_EVENT_STA_WPS_ER_FAILED 10 // SYSTEM_EVENT_STA_WPS_ER_TIMEOUT 11 // SYSTEM_EVENT_STA_WPS_ER_PIN 12 case SYSTEM_EVENT_AP_START: xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_AP_STARTED); if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { wifi_state->AP_active = true; wifi_state->AP_clients = 0; xSemaphoreGive(xSemaphoreWiFi); } break; case SYSTEM_EVENT_AP_STOP: xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_AP_STARTED); if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { wifi_state->AP_active = false; wifi_state->AP_clients = 0; xSemaphoreGive(xSemaphoreWiFi); } break; case SYSTEM_EVENT_AP_STACONNECTED: { if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { wifi_state->AP_clients++; xSemaphoreGive(xSemaphoreWiFi); } 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: { if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { if (wifi_state->AP_clients > 0) wifi_state->AP_clients--; else wifi_state->AP_clients = 0; xSemaphoreGive(xSemaphoreWiFi); } 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_STAIPASSIGNED: break; // 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); break; } return ESP_OK; } void time_sync_notification_cb(struct timeval *tv) { int rc = sntp_get_sync_status(); if (rc == SNTP_SYNC_STATUS_COMPLETED) { time(&now); localtime_r(&now, &timeinfo); System_TimeOk = true; strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); ESP_LOGI(TAG, "NTP time is set: %s", strftime_buf); } else { ESP_LOGI(TAG, "NTP unknown time sync event rc=%d", rc); } } void task_wifi( void * pvParameters ) { esp_err_t ret; ESP_LOGI(TAG, "Starting WiFi"); /* * Initialize NVS */ ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); /* event handler and event group for the wifi driver */ xEventGroupWifi = xEventGroupCreate(); /* initialize the tcp stack */ tcpip_adapter_init(); ESP_ERROR_CHECK(esp_event_loop_init(task_wifi_EventHandler, NULL)); /* * memory allocation of objects used by the task */ accessp_records = (wifi_ap_record_t*)malloc(sizeof(wifi_ap_record_t) * MAX_AP_NUM); task_wifi_ConfigSTA = (wifi_config_t*)malloc(sizeof(wifi_config_t)); memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); xSemaphoreWiFi = xSemaphoreCreateMutex(); wifi_state = malloc(sizeof(WIFI_State)); wifi_state->AP_clients = 0; wifi_state->AP_active = false; wifi_state->STA_connected = false; wifi_state->STA_online = false; wifi_state->STA_rssi = 0; /* * start the softAP access point * stop DHCP server */ ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)); /* * Assign a static IP to the AP network interface */ tcpip_adapter_ip_info_t info; memset(&info, 0x00, sizeof(info)); IP4_ADDR(&info.ip, 192, 168, 1, 1); IP4_ADDR(&info.gw, 192, 168, 1, 1); IP4_ADDR(&info.netmask, 255, 255, 255, 0); ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info)); /* start dhcp server */ ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP)); ESP_LOGI(TAG, "AP start dhcps ip: 192.168.1.1 nm: 255.255.255.0 gw: 192.168.1.1"); /* start dhcp client */ ESP_ERROR_CHECK(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA)); /* * init wifi as station + access point */ wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config)); ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA)); ESP_ERROR_CHECK(esp_wifi_set_bandwidth(WIFI_IF_AP, config.ap_bandwidth)); // configure the softAP and start it */ wifi_config_t ap_config = { .ap = { .ssid_len = 0, .channel = config.ap_channel, .authmode = WIFI_AUTH_WPA2_PSK, .ssid_hidden = config.ap_ssid_hidden, .max_connection = AP_MAX_CONNECTIONS, .beacon_interval = 100, }, }; memcpy(ap_config.ap.ssid, config.ap_ssid , sizeof(config.ap_ssid)); memcpy(ap_config.ap.password, config.ap_pwd, sizeof(config.ap_pwd)); ret = esp_wifi_set_config(WIFI_IF_AP, &ap_config); if (ret != ESP_OK) { ESP_LOGE(TAG, "esp_wifi_set_config(WIFI_IF_AP, nnn) rc=%d", ret); } ESP_ERROR_CHECK(esp_wifi_start()); 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"); /* * try to get access to previously saved wifi */ if (FetchStaConfig()) { xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); } /* * Wait for access point to start */ xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_AP_STARTED, pdFALSE, pdTRUE, portMAX_DELAY ); EventBits_t uxBits; for(;;) { /* 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 ); if (uxBits & TASK_WIFI_REQUEST_STA_DISCONNECT) { /* * user requested a disconnect, this will in effect disconnect the wifi but also erase NVS memory */ ESP_LOGI(TAG, "Request STA disconnect"); sntp_stop(); ESP_ERROR_CHECK(esp_wifi_disconnect()); xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); /* * erase configuration */ if (task_wifi_ConfigSTA) { memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); } config.lastSSID[0] = '\0'; write_config(); /* finally: release the scan request bit */ xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); } else if (uxBits & TASK_WIFI_REQUEST_STA_CONNECT) { //someone requested a connection! ESP_LOGI(TAG, "Request STA connect `%s'", task_wifi_ConfigSTA->sta.ssid); /* set the new config and connect - reset the failed bit first as it is later tested */ xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, task_wifi_ConfigSTA)); esp_err_t wifierror = esp_wifi_connect(); if (wifierror != ESP_OK) { ESP_LOGE(TAG, "esp_wifi_connect() rc=%04x", (int)wifierror); xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); } /* * 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_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_STA_CONNECTED | TASK_WIFI_STA_FAILED)) { /* * only save the config if the connection was successful! */ if (uxBits & TASK_WIFI_STA_CONNECTED) { /* save wifi config */ SaveStaConfig(); } else { ESP_LOGI(TAG, "Connection failed"); /* failed attempt to connect regardles of the reason */ /* otherwise: reset the config */ memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); } xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); } else { /* hit 10 seconds timeout */ ESP_LOGI(TAG, "Connection timeout"); xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); vTaskDelay(100 / portTICK_PERIOD_MS); xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); } } else if (uxBits & TASK_WIFI_REQUEST_WIFI_SCAN) { /* safe guard against overflow */ ap_num = MAX_AP_NUM; ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false)); /* finally: release the scan request bit */ xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_WIFI_SCAN); } } /* for(;;) */ vTaskDelay( (TickType_t)10); } /** * @brief Show an AP station as a button. The buttons are already defined. * @param idx The index position on the display, 1 to 7. * @param ap The AP information from the WiFi scan. * @param show How to display. 0 is blank, 1 is unknown, 2 is known, 3 is a connected AP. */ void Show_AP(uint8_t idx, wifi_ap_record_t ap, int show) { char tmp[33]; if ((idx > 7) || (idx < 1)) return; if (show == 0) { _bg = TFT_BLACK; } else { _bg = (color_t){ 63, 63, 64 }; } TFT_fillRect(Buttons[idx].x, Buttons[idx].y, Buttons[idx].w, Buttons[idx].h, _bg); if (show == 0) return; TFT_drawRect(Buttons[idx].x, Buttons[idx].y, Buttons[idx].w, Buttons[idx].h, TFT_NAVY); if (show == 3) { _fg = TFT_WHITE; } else if (show == 1) { _fg = TFT_YELLOW; } else { _fg = TFT_CYAN; } TFT_setFont(DEJAVU18_FONT, NULL); sprintf(tmp, "%s", ap.ssid); TFT_print(tmp, Buttons[idx].x + 5, Buttons[idx].y + 6); sprintf(tmp, "%d", ap.rssi); TFT_setFont(DEF_SMALL_FONT, NULL); TFT_print(tmp, Buttons[idx].x + Buttons[idx].w - (TFT_getStringWidth(tmp) + 5), Buttons[idx].y + 4); sprintf(tmp, "%s", apsec[ap.authmode]); TFT_print(tmp, Buttons[idx].x + Buttons[idx].w - (TFT_getStringWidth(tmp) + 5), Buttons[idx].y + 15); } bool WiFi_Init(void) { char pwd[65], pmpt[96]; switch (Main_Screen) { case MAIN_TOOLS_SETUP_WIFI: TopMessage((char *)"WiFi"); TFT_setFont(DEJAVU24_FONT, NULL); _fg = TFT_WHITE; TFT_print((char *)"Momentje ..", CENTER, CENTER); _wifi_ScanAPs = true; _wifi_ScanDone = false; Buttons_Add(260, 200, 60, 40, (char *)"Ok", 0); Buttons[0].dark = true; Buttons_Show(); // Now add the buttons we draw manually. Buttons_Add( 0, 30, 250, 30, (char *)"", 1); Buttons_Add( 0, 60, 250, 30, (char *)"", 2); Buttons_Add( 0, 90, 250, 30, (char *)"", 3); Buttons_Add( 0,120, 250, 30, (char *)"", 4); Buttons_Add( 0,150, 250, 30, (char *)"", 5); Buttons_Add( 0,180, 250, 30, (char *)"", 6); Buttons_Add( 0,210, 250, 30, (char *)"", 7); break; case MAIN_TOOLS_SETUP_WIFI_CUR: TopMessage((char *)"WiFi verbinding"); // Get extra information. wifi_ap_record_t ap_info; esp_wifi_sta_get_ap_info(&ap_info); wifi_config_t *wconfig = task_wifi_ConfigSTA /*task_wifi_GetWifiStaConfig( ) */; if (wconfig) { tcpip_adapter_ip_info_t ip_info; ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info)); char ip[IP4ADDR_STRLEN_MAX]; char gw[IP4ADDR_STRLEN_MAX]; char netmask[IP4ADDR_STRLEN_MAX]; strcpy(ip, ip4addr_ntoa(&ip_info.ip)); strcpy(netmask, ip4addr_ntoa(&ip_info.netmask)); strcpy(gw, ip4addr_ntoa(&ip_info.gw)); TFT_setFont(DEFAULT_FONT, NULL); _fg = TFT_WHITE; TFT_print((char *)"SSID", 155 - TFT_getStringWidth((char *)"SSID"), 40); TFT_print((char *)"Kanaal", 155 - TFT_getStringWidth((char *)"Kanaal"), 60); TFT_print((char *)"Rssi", 155 - TFT_getStringWidth((char *)"Rssi"), 80); TFT_print((char *)"Mode", 155 - TFT_getStringWidth((char *)"Mode"), 100); TFT_print((char *)"IP adres", 155 - TFT_getStringWidth((char *)"IP adres"), 120); TFT_print((char *)"Netmask", 155 - TFT_getStringWidth((char *)"Netmask"), 140); TFT_print((char *)"Gateway", 155 - TFT_getStringWidth((char *)"Gateway"), 160); _fg = TFT_YELLOW; TFT_print((char*)wconfig->sta.ssid, 165, 40); sprintf(pmpt, "%d", ap_info.primary); TFT_print(pmpt, 165, 60); sprintf(pmpt, "%d", ap_info.rssi); TFT_print(pmpt, 165, 80); sprintf(pmpt, "%s%s%s", ap_info.phy_11b ? "b":"", ap_info.phy_11g ? "g":"", ap_info.phy_11n ? "n":""); TFT_print(pmpt, 165, 100); TFT_print((char*)ip, 165, 120); TFT_print((char*)netmask, 165, 140); TFT_print((char*)gw, 165, 160); } Buttons_Add(130, 200, 60, 40, (char *)"Ok", 0); Buttons[0].dark = true; Buttons_Show(); break; case MAIN_TOOLS_SETUP_WIFI_CON: TopMessage((char *)"WiFi verbinden"); TFT_setFont(DEJAVU18_FONT, NULL); _fg = TFT_WHITE; TFT_print((char *)"SSID", 155 - TFT_getStringWidth((char *)"SSID"), 70); _fg = TFT_YELLOW; TFT_print((char*)_wifi_ssid, 165, 70); Buttons_Add( 0, 200, 100, 40, (char *)"Annuleer", 0); Buttons_Add(110, 200, 100, 40, (char *)"Vergeet", 1); Buttons_Add(220, 200, 100, 40, (char *)"Verbind", 2); Buttons_Show(); Buttons[0].dark = true; break; case MAIN_TOOLS_SETUP_WIFI_NEW: TopMessage((char *)"WiFi nieuw"); snprintf(pmpt, 95, "Password for %s", _wifi_ssid); pwd[0] = '\0'; EditTextMin(pmpt, pwd, 64, 8); /* * Disconnect first */ _bg = TFT_BLACK; TFT_fillScreen(_bg); TFT_setFont(DEJAVU24_FONT, NULL); _fg = TFT_WHITE; TFT_print((char *)"Momentje ..", CENTER, CENTER); xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); vTaskDelay(100 / portTICK_PERIOD_MS); xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); /* * Setup new connection */ if (strlen(pwd)) { wifi_config_t* config = task_wifi_ConfigSTA; memset(config, 0x00, sizeof(wifi_config_t)); memcpy(config->sta.ssid, _wifi_ssid, strlen((char*)_wifi_ssid)); memcpy(config->sta.password, pwd, strlen(pwd)); ESP_LOGI(TAG, "new AP %s %s", _wifi_ssid, pwd); xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); } else { // TODO: what about WPS, it works but how to insert it in this app. return true; } // We must wait here for the result. break; default: break; } return false; } bool WiFi_Loop(void) { uint8_t idx; int Choice; static int AP[8]; wifi_ap_record_t ap; switch (Main_Screen) { case MAIN_TOOLS_SETUP_WIFI: if (_wifi_ScanAPs) { xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_WIFI_SCAN); _wifi_ScanAPs = false; TimeSpent = 0; } if (_wifi_ScanDone) { /* * Show scan results. There is room for 7 entries. If we have a connection, * the first one is that connection followed by available Access Points. * If there is no connection yet, there is only a iist of available Access * points. * The list is sorted by signal strength and is filled by the eventhandler. */ idx = 1; _wifi_ScanDone = false; if ((xEventGroupGetBits(xEventGroupWifi) & TASK_WIFI_STA_CONNECTED) == TASK_WIFI_STA_CONNECTED) { // We are connected. Search and display this one. if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { for (int i = 0; i < _wifi_Scanned; i++) { ap = accessp_records[i]; if (strcmp(wifi_state->STA_ssid, (char *)ap.ssid) == 0) { AP[idx] = i; Show_AP(idx, ap, 3); idx++; break; } } xSemaphoreGive(xSemaphoreWiFi); } } // Display available Access Points. for (int i = 0; i < _wifi_Scanned; i++) { // The connected AP can be somewhere in this list, don't display it again. ap = accessp_records[i]; if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { if (strcmp(wifi_state->STA_ssid, (char *)ap.ssid) == 0) { xSemaphoreGive(xSemaphoreWiFi); continue; // Skip connected AP, already on top of the list. } xSemaphoreGive(xSemaphoreWiFi); } // Check if we know this AP in the database. if ((read_station(ap.ssid) == -1)) { Show_AP(idx, ap, 2); // Unknown } else { if (wifiStation.hide) { continue; // Blacklisted. } Show_AP(idx, ap, 1); // We know this one. } AP[idx] = i; idx++; if (idx == 8) break; } if (idx < 7) { for (int i = idx; i < 8; i++) { Show_AP(i, ap, 0); AP[i] = 0; } } } Choice = Buttons_Scan(); if ((Choice >= 1) && (Choice <= 7)) { ap = accessp_records[AP[Choice]]; sprintf((char *)_wifi_ssid, "%s", ap.ssid); // Save selected SSID. } if ((Choice == 1) && ((xEventGroupGetBits(xEventGroupWifi) & TASK_WIFI_STA_CONNECTED) == TASK_WIFI_STA_CONNECTED)) { Main_Screen = MAIN_TOOLS_SETUP_WIFI_CUR; // Cancel a possible scan. ESP_ERROR_CHECK(esp_wifi_scan_stop()); } else if ((Choice >= 1) && (Choice <= 7)) { if ((read_station(_wifi_ssid) != -1)) { Main_Screen = MAIN_TOOLS_SETUP_WIFI_CON; } else { Main_Screen = MAIN_TOOLS_SETUP_WIFI_NEW; } 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; } break; case MAIN_TOOLS_SETUP_WIFI_CUR: if (Buttons_Scan() == 0) { Main_Screen = MAIN_TOOLS_SETUP_WIFI; } break; case MAIN_TOOLS_SETUP_WIFI_CON: switch (Buttons_Scan()) { case 0: // Cancel choice Main_Screen = MAIN_TOOLS_SETUP_WIFI; break; case 1: // Forget connection remove_station(_wifi_ssid); Main_Screen = MAIN_TOOLS_SETUP_WIFI; break; case 2: // Connect _bg = TFT_BLACK; TFT_fillScreen(_bg); TFT_setFont(DEJAVU24_FONT, NULL); _fg = TFT_WHITE; TFT_print((char *)"Momentje ..", CENTER, CENTER); /* * Disconnect old connections and wait until it's gone. */ xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); vTaskDelay(100 / portTICK_PERIOD_MS); xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); /* * Setup new connection. */ if ((read_station(_wifi_ssid) != -1)) { 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)); xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); vTaskDelay(1000 / portTICK_PERIOD_MS); } Main_Screen = MAIN_TOOLS_SETUP_WIFI; break; default: break; } break; case MAIN_TOOLS_SETUP_WIFI_NEW: // All work is already done, jump to the base screen. Main_Screen = MAIN_TOOLS_SETUP_WIFI; break; default: break; } return false; }