123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990 |
- #include "network_wifi.h"
- #include <string.h>
- #include "cJSON.h"
- #include "dns_server.h"
- #include "esp_event.h"
- #include "esp_log.h"
- #include "esp_system.h"
- #include "esp_wifi.h"
- #include "esp_wifi_types.h"
- #include "globdefs.h"
- #include "lwip/sockets.h"
- #include "messaging.h"
- #include "network_status.h"
- #include "nvs.h"
- #include "nvs_flash.h"
- #include "platform_config.h"
- #include "platform_esp32.h"
- #include "tools.h"
- #include "trace.h"
- static void network_wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
- static void network_manager_wifi_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) ;
- static char* get_disconnect_code_desc(uint8_t reason);
- cJSON* accessp_cjson = NULL;
- wifi_config_t* wifi_manager_config_sta = NULL;
- static const char TAG[] = "network_wifi";
- const char wifi_manager_nvs_namespace[] = "config";
- uint16_t ap_num = MAX_AP_NUM;
- esp_netif_t *wifi_netif;
- wifi_ap_record_t* accessp_records = NULL;
- /* wifi scanner config */
- wifi_scan_config_t scan_config = {
- .ssid = 0,
- .bssid = 0,
- .channel = 0,
- .show_hidden = true};
- #ifndef STR_OR_BLANK
- #define STR_OR_BLANK(p) p == NULL ? "" : p
- #endif
- esp_netif_t *network_wifi_get_interface(){
- return wifi_netif;
- }
- void init_network_wifi() {
- ESP_LOGD(TAG, "WIFI Starting.");
- accessp_cjson = NULL;
- accessp_cjson = wifi_manager_clear_ap_list_json(&accessp_cjson);
- wifi_manager_config_sta = (wifi_config_t*)malloc(sizeof(wifi_config_t));
- memset(wifi_manager_config_sta, 0x00, sizeof(wifi_config_t));
- ESP_LOGD(TAG, "Init. ");
- wifi_netif = esp_netif_create_default_wifi_sta();
- wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
- ESP_ERROR_CHECK(esp_wifi_init(&cfg));
- ESP_LOGD(TAG, "Handlers");
- //wifi_manager_register_handlers();
- ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
- ESP_EVENT_ANY_ID,
- &network_wifi_event_handler,
- NULL,
- NULL));
- esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &network_manager_wifi_ip_event_handler, NULL);
- ESP_LOGD(TAG, "Storage");
- ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
- ESP_LOGD(TAG, "Set Mode");
- ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
- ESP_LOGD(TAG, "Start");
- ESP_ERROR_CHECK(esp_wifi_start());
- }
- void destroy_network_wifi() {
- cJSON_Delete(accessp_cjson);
- accessp_cjson = NULL;
- FREE_AND_NULL(wifi_manager_config_sta);
- }
- bool network_wifi_sta_config_changed() {
- bool changed = true;
- wifi_config_t wifi_manager_config_sta_existing;
- if(wifi_manager_config_sta && wifi_manager_load_wifi_sta_config(&wifi_manager_config_sta_existing )){
- changed = strcmp( (char *)wifi_manager_config_sta_existing.sta.ssid,(char *)wifi_manager_config_sta->sta.ssid ) !=0 ||
- strcmp((char *) wifi_manager_config_sta_existing.sta.password,(char *)wifi_manager_config_sta->sta.password ) !=0;
- }
- return changed;
-
- }
- esp_err_t network_wifi_save_sta_config() {
- nvs_handle handle;
- esp_err_t esp_err;
- ESP_LOGD(TAG, "Config Save");
- if (wifi_manager_config_sta) {
- esp_err = nvs_open(wifi_manager_nvs_namespace, NVS_READWRITE, &handle);
- if (esp_err != ESP_OK) {
- ESP_LOGE(TAG, "%s failure. Error %s", wifi_manager_nvs_namespace, esp_err_to_name(esp_err));
- return esp_err;
- }
- esp_err = nvs_set_blob(handle, "ssid", wifi_manager_config_sta->sta.ssid, sizeof(wifi_manager_config_sta->sta.ssid));
- if (esp_err != ESP_OK) {
- ESP_LOGE(TAG, "ssid (%s). Error %s", wifi_manager_nvs_namespace, esp_err_to_name(esp_err));
- return esp_err;
- }
- esp_err = nvs_set_blob(handle, "password", wifi_manager_config_sta->sta.password, sizeof(wifi_manager_config_sta->sta.password));
- if (esp_err != ESP_OK) {
- ESP_LOGE(TAG, "pass (%s). Error %s", wifi_manager_nvs_namespace, esp_err_to_name(esp_err));
- return esp_err;
- }
- esp_err = nvs_commit(handle);
- if (esp_err != ESP_OK) {
- ESP_LOGE(TAG, "Commit error: %s", esp_err_to_name(esp_err));
- messaging_post_message(MESSAGING_ERROR, MESSAGING_CLASS_SYSTEM, "Unable to save wifi credentials. %s", esp_err_to_name(esp_err));
- return esp_err;
- }
- nvs_close(handle);
- ESP_LOGD(TAG, "saved: ssid:%s password:%s", wifi_manager_config_sta->sta.ssid, wifi_manager_config_sta->sta.password);
- }
- return ESP_OK;
- }
- bool wifi_manager_load_wifi_sta_config(wifi_config_t* config ){
- nvs_handle handle;
- esp_err_t esp_err;
- ESP_LOGD(TAG, "Fetching wifi sta config.");
- esp_err = nvs_open(wifi_manager_nvs_namespace, NVS_READONLY, &handle);
- if (esp_err == ESP_OK) {
- /* ssid */
- ESP_LOGD(TAG, "Fetching value for ssid.");
- size_t sz = sizeof(config->sta.ssid);
- uint8_t* buff = (uint8_t*)malloc(sizeof(uint8_t) * sz);
- memset(buff, 0x00, sizeof(uint8_t) * sz);
- esp_err = nvs_get_blob(handle, "ssid", buff, &sz);
- if (esp_err != ESP_OK) {
- ESP_LOGD(TAG, "No ssid found in nvs.");
- FREE_AND_NULL(buff);
- nvs_close(handle);
- return false;
- }
- memcpy(config->sta.ssid, buff, sizeof(config->sta.ssid));
- FREE_AND_NULL(buff);
- ESP_LOGD(TAG, "wifi_manager_fetch_wifi_sta_config: ssid:%s ", config->sta.ssid);
- /* password */
- sz = sizeof(config->sta.password);
- buff = (uint8_t*)malloc(sizeof(uint8_t) * sz);
- memset(buff, 0x00, sizeof(uint8_t) * sz);
- esp_err = nvs_get_blob(handle, "password", buff, &sz);
- if (esp_err != ESP_OK) {
- // Don't take this as an error. This could be an opened access point?
- ESP_LOGW(TAG, "No wifi password found in nvs");
- } else {
- memcpy(config->sta.password, buff, sizeof(config->sta.password));
- ESP_LOGD(TAG, "wifi_manager_fetch_wifi_sta_config: password:%s", config->sta.password);
- }
- FREE_AND_NULL(buff);
- nvs_close(handle);
- config->sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
- return config->sta.ssid[0] != '\0';
- } else {
- ESP_LOGW(TAG, "wifi manager has no previous configuration. %s", esp_err_to_name(esp_err));
- return false;
- }
- }
- bool wifi_manager_fetch_wifi_sta_config() {
- if (wifi_manager_config_sta == NULL) {
- ESP_LOGD(TAG, "Allocating memory for structure.");
- wifi_manager_config_sta = (wifi_config_t*)malloc(sizeof(wifi_config_t));
- }
- memset(wifi_manager_config_sta, 0x00, sizeof(wifi_config_t));
- return wifi_manager_load_wifi_sta_config(wifi_manager_config_sta);
- }
- wifi_config_t* wifi_manager_get_wifi_sta_config() {
- return wifi_manager_config_sta;
- }
- // void wifi_manager_register_handlers() {
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_WIFI_READY, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_SCAN_DONE, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_AUTHMODE_CHANGE, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_START, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_STOP, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_PROBEREQRECVED, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_TIMEOUT, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PIN, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_STACONNECTED, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_STADISCONNECTED, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_START, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_STOP, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &network_wifi_event_handler, NULL));
- // ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &network_wifi_event_handler, NULL));
- // }
- #define LOCAL_MAC_SIZE 20
- char* get_mac_string(uint8_t mac[6]) {
- char* macStr = malloc(LOCAL_MAC_SIZE);
- memset(macStr, 0x00, LOCAL_MAC_SIZE);
- snprintf(macStr, LOCAL_MAC_SIZE, MACSTR, MAC2STR(mac));
- return macStr;
- }
- static void network_wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
- if (event_base != WIFI_EVENT)
- return;
- switch (event_id) {
- case WIFI_EVENT_WIFI_READY:
- ESP_LOGD(TAG, "WIFI_EVENT_WIFI_READY");
- break;
- case WIFI_EVENT_SCAN_DONE:
- ESP_LOGD(TAG, "WIFI_EVENT_SCAN_DONE");
- network_manager_async_scan_done();
- break;
- case WIFI_EVENT_STA_AUTHMODE_CHANGE:
- ESP_LOGD(TAG, "WIFI_EVENT_STA_AUTHMODE_CHANGE");
- break;
- case WIFI_EVENT_AP_START:
- ESP_LOGD(TAG, "WIFI_EVENT_AP_START");
- break;
- case WIFI_EVENT_AP_STOP:
- ESP_LOGD(TAG, "WIFI_EVENT_AP_STOP");
- break;
- case WIFI_EVENT_AP_PROBEREQRECVED: {
- // wifi_event_ap_probe_req_rx_t
- // Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event
- //
- // Public Members
- //
- // int rssi
- // Received probe request signal strength
- //
- // uint8_t mac[6]
- // MAC address of the station which send probe request
- wifi_event_ap_probe_req_rx_t* s = (wifi_event_ap_probe_req_rx_t*)event_data;
- char* mac = get_mac_string(s->mac);
- ESP_LOGD(TAG, "WIFI_EVENT_AP_PROBEREQRECVED. RSSI: %d, MAC: %s", s->rssi, STR_OR_BLANK(mac));
- FREE_AND_NULL(mac);
- } break;
- case WIFI_EVENT_STA_WPS_ER_SUCCESS:
- ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_SUCCESS");
- break;
- case WIFI_EVENT_STA_WPS_ER_FAILED:
- ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_FAILED");
- break;
- case WIFI_EVENT_STA_WPS_ER_TIMEOUT:
- ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_TIMEOUT");
- break;
- case WIFI_EVENT_STA_WPS_ER_PIN:
- ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_PIN");
- break;
- case WIFI_EVENT_AP_STACONNECTED: {
- wifi_event_ap_staconnected_t* stac = (wifi_event_ap_staconnected_t*)event_data;
- char* mac = get_mac_string(stac->mac);
- ESP_LOGD(TAG, "WIFI_EVENT_AP_STACONNECTED. aid: %d, mac: %s", stac->aid, STR_OR_BLANK(mac));
- FREE_AND_NULL(mac);
- } break;
- case WIFI_EVENT_AP_STADISCONNECTED:
- ESP_LOGD(TAG, "WIFI_EVENT_AP_STADISCONNECTED");
- break;
- case WIFI_EVENT_STA_START:
- ESP_LOGD(TAG, "WIFI_EVENT_STA_START");
- break;
- case WIFI_EVENT_STA_STOP:
- ESP_LOGD(TAG, "WIFI_EVENT_STA_STOP");
- break;
- case WIFI_EVENT_STA_CONNECTED: {
- // structwifi_event_sta_connected_t
- // Argument structure for WIFI_EVENT_STA_CONNECTED event
- //
- // Public Members
- //
- // uint8_t ssid[32]
- // SSID of connected AP
- //
- // uint8_t ssid_len
- // SSID length of connected AP
- //
- // uint8_t bssid[6]
- // BSSID of connected AP
- //
- // uint8_t channel
- // channel of connected AP
- //
- // wifi_auth_mode_tauthmode
- // authentication mode used by AP
- //, get_mac_string(EVENT_HANDLER_ARG_FIELD(wifi_event_ap_probe_req_rx_t, mac)));
- ESP_LOGD(TAG, "WIFI_EVENT_STA_CONNECTED. ");
- wifi_event_sta_connected_t* s = (wifi_event_sta_connected_t*)event_data;
- char* bssid = get_mac_string(s->bssid);
- char* ssid = strdup((char*)s->ssid);
- ESP_LOGD(TAG, "WIFI_EVENT_STA_CONNECTED. Channel: %d, Access point: %s, BSSID: %s ", s->channel, STR_OR_BLANK(ssid), (bssid));
- FREE_AND_NULL(bssid);
- FREE_AND_NULL(ssid);
- network_manager_async_success();
- } break;
- case WIFI_EVENT_STA_DISCONNECTED: {
- // structwifi_event_sta_disconnected_t
- // Argument structure for WIFI_EVENT_STA_DISCONNECTED event
- //
- // Public Members
- //
- // uint8_t ssid[32]
- // SSID of disconnected AP
- //
- // uint8_t ssid_len
- // SSID length of disconnected AP
- //
- // uint8_t bssid[6]
- // BSSID of disconnected AP
- //
- // uint8_t reason
- // reason of disconnection
- wifi_event_sta_disconnected_t* s = (wifi_event_sta_disconnected_t*)event_data;
- char* bssid = get_mac_string(s->bssid);
- ESP_LOGD(TAG, "WIFI_EVENT_STA_DISCONNECTED. From BSSID: %s, reason code: %d (%s)", STR_OR_BLANK(bssid), s->reason, get_disconnect_code_desc(s->reason));
- FREE_AND_NULL(bssid);
-
- /* if a DISCONNECT message is posted while a scan is in progress this scan will NEVER end, causing scan to never work again. For this reason SCAN_BIT is cleared too */
- // todo: check for implementation of this: network_manager_clear_flag(WIFI_MANAGER_WIFI_CONNECTED_BIT | WIFI_MANAGER_SCAN_BIT);
- wifi_event_sta_disconnected_t * disconnected_event = malloc(sizeof(wifi_event_sta_disconnected_t));
- memcpy(disconnected_event, event_data, sizeof(wifi_event_sta_disconnected_t));
- network_manager_async_lost_connection(disconnected_event);
- } break;
- default:
- break;
- }
- }
- cJSON* wifi_manager_get_new_array_json(cJSON** old) {
- ESP_LOGV(TAG, "wifi_manager_get_new_array_json called");
- cJSON* root = *old;
- if (root != NULL) {
- cJSON_Delete(root);
- *old = NULL;
- }
- ESP_LOGV(TAG, "wifi_manager_get_new_array_json done");
- return cJSON_CreateArray();
- }
- void wifi_manager_generate_access_points_json(cJSON** ap_list) {
- *ap_list = wifi_manager_get_new_array_json(ap_list);
- if (*ap_list == NULL)
- return;
- for (int i = 0; i < ap_num; i++) {
- cJSON* ap = cJSON_CreateObject();
- if (ap == NULL) {
- ESP_LOGE(TAG, "Unable to allocate memory for access point entry #%d", i);
- return;
- }
- cJSON* radio = cJSON_CreateObject();
- if (radio == NULL) {
- ESP_LOGE(TAG, "Unable to allocate memory for access point entry #%d", i);
- cJSON_Delete(ap);
- return;
- }
- wifi_ap_record_t ap_rec = accessp_records[i];
- cJSON_AddNumberToObject(ap, "chan", ap_rec.primary);
- cJSON_AddNumberToObject(ap, "rssi", ap_rec.rssi);
- cJSON_AddNumberToObject(ap, "auth", ap_rec.authmode);
- cJSON_AddItemToObject(ap, "ssid", cJSON_CreateString((char*)ap_rec.ssid));
- char* bssid = get_mac_string(ap_rec.bssid);
- cJSON_AddItemToObject(ap, "bssid", cJSON_CreateString(STR_OR_BLANK(bssid)));
- FREE_AND_NULL(bssid);
- cJSON_AddNumberToObject(radio, "b", ap_rec.phy_11b ? 1 : 0);
- cJSON_AddNumberToObject(radio, "g", ap_rec.phy_11g ? 1 : 0);
- cJSON_AddNumberToObject(radio, "n", ap_rec.phy_11n ? 1 : 0);
- cJSON_AddNumberToObject(radio, "low_rate", ap_rec.phy_lr ? 1 : 0);
- cJSON_AddItemToObject(ap, "radio", radio);
- cJSON_AddItemToArray(*ap_list, ap);
- char* ap_json = cJSON_PrintUnformatted(ap);
- if (ap_json != NULL) {
- ESP_LOGD(TAG, "New access point found: %s", ap_json);
- free(ap_json);
- }
- }
- char* ap_list_json = cJSON_PrintUnformatted(*ap_list);
- if (ap_list_json != NULL) {
- ESP_LOGV(TAG, "Full access point list: %s", ap_list_json);
- free(ap_list_json);
- }
- }
- void wifi_manager_set_ipv4val(const char* key, char* default_value, ip4_addr_t * target) {
- char* value = config_alloc_get_default(NVS_TYPE_STR, key, default_value, 0);
- if (value != NULL) {
- ESP_LOGD(TAG, "%s: %s", key, value);
- inet_pton(AF_INET, value, target); /* access point is on a static IP */
- }
- FREE_AND_NULL(value);
- }
- void wifi_manager_config_ap() {
- tcpip_adapter_ip_info_t info;
- esp_err_t err = ESP_OK;
- char* value = NULL;
- wifi_config_t ap_config = {
- .ap = {
- .ssid_len = 0,
- },
- };
- ESP_LOGI(TAG, "Configuring Access Point.");
- wifi_netif = esp_netif_create_default_wifi_ap();
- /* In order to change the IP info structure, we have to first stop
- * the DHCP server on the new interface
- */
- esp_netif_dhcps_stop(wifi_netif);
- // tcpip_adapter_dhcps_get_status(TCPIP_ADAPTER_IF_AP, &dhcp_status);
- // if (dhcp_status == TCPIP_ADAPTER_DHCP_STARTED) {
- // ESP_LOGD(TAG, "Stopping DHCP on interface so we can ");
- // if ((err = tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)) != ESP_OK) /* stop AP DHCP server */
- // {
- // ESP_LOGW(TAG, "Stopping DHCP failed. Error %s", esp_err_to_name(err));
- // }
- // }
- /*
- * Set access point mode IP adapter configuration
- */
- wifi_manager_set_ipv4val("ap_ip_address", DEFAULT_AP_IP, &info.ip);
- wifi_manager_set_ipv4val("ap_ip_gateway", CONFIG_DEFAULT_AP_GATEWAY, &info.gw);
- wifi_manager_set_ipv4val("ap_ip_netmask", CONFIG_DEFAULT_AP_NETMASK, &info.netmask);
- ESP_LOGD(TAG, "Setting tcp_ip info for interface TCPIP_ADAPTER_IF_AP");
- if ((err = esp_netif_set_ip_info(wifi_netif, &info)) != ESP_OK) {
- ESP_LOGE(TAG, "Setting tcp_ip info for interface TCPIP_ADAPTER_IF_AP. Error %s", esp_err_to_name(err));
- return;
- }
- /*
- * Set Access Point configuration
- */
- value = config_alloc_get_default(NVS_TYPE_STR, "ap_ssid", CONFIG_DEFAULT_AP_SSID, 0);
- if (value != NULL) {
- strlcpy((char*)ap_config.ap.ssid, value, sizeof(ap_config.ap.ssid));
- ESP_LOGI(TAG, "AP SSID: %s", (char*)ap_config.ap.ssid);
- }
- FREE_AND_NULL(value);
- value = config_alloc_get_default(NVS_TYPE_STR, "ap_pwd", DEFAULT_AP_PASSWORD, 0);
- if (value != NULL) {
- strlcpy((char*)ap_config.ap.password, value, sizeof(ap_config.ap.password));
- ESP_LOGI(TAG, "AP Password: %s", (char*)ap_config.ap.password);
- }
- FREE_AND_NULL(value);
- value = config_alloc_get_default(NVS_TYPE_STR, "ap_channel", STR(CONFIG_DEFAULT_AP_CHANNEL), 0);
- if (value != NULL) {
- ESP_LOGD(TAG, "Channel: %s", value);
- ap_config.ap.channel = atoi(value);
- }
- FREE_AND_NULL(value);
- ap_config.ap.authmode = AP_AUTHMODE;
- ap_config.ap.ssid_hidden = DEFAULT_AP_SSID_HIDDEN;
- ap_config.ap.max_connection = DEFAULT_AP_MAX_CONNECTIONS;
- ap_config.ap.beacon_interval = DEFAULT_AP_BEACON_INTERVAL;
- ESP_LOGD(TAG, "Auth Mode: %d", ap_config.ap.authmode);
- ESP_LOGD(TAG, "SSID Hidden: %d", ap_config.ap.ssid_hidden);
- ESP_LOGD(TAG, "Max Connections: %d", ap_config.ap.max_connection);
- ESP_LOGD(TAG, "Beacon interval: %d", ap_config.ap.beacon_interval);
- const char* msg = "Setting wifi mode as WIFI_MODE_APSTA";
- ESP_LOGD(TAG, "%s",msg);
- if ((err = esp_wifi_set_mode(WIFI_MODE_APSTA)) != ESP_OK) {
- ESP_LOGE(TAG, "%s. Error %s",msg, esp_err_to_name(err));
- return;
- }
- msg = "Setting wifi AP configuration for WIFI_IF_AP";
- ESP_LOGD(TAG, "%s", msg);
- if ((err = esp_wifi_set_config(WIFI_IF_AP, &ap_config)) != ESP_OK) /* stop AP DHCP server */
- {
- ESP_LOGE(TAG, "%s . Error %s", msg, esp_err_to_name(err));
- return;
- }
- msg = "Setting wifi bandwidth";
- ESP_LOGD(TAG, "%s (%d)", msg, DEFAULT_AP_BANDWIDTH);
- if ((err = esp_wifi_set_bandwidth(WIFI_IF_AP, DEFAULT_AP_BANDWIDTH)) != ESP_OK) /* stop AP DHCP server */
- {
- ESP_LOGE(TAG, "%s failed. Error %s", msg, esp_err_to_name(err));
- return;
- }
- msg = "Setting wifi power save";
- ESP_LOGD(TAG, "%s (%d)", msg, DEFAULT_STA_POWER_SAVE);
- if ((err = esp_wifi_set_ps(DEFAULT_STA_POWER_SAVE)) != ESP_OK) /* stop AP DHCP server */
- {
- ESP_LOGE(TAG, "%s failed. Error %s", msg, esp_err_to_name(err));
- return;
- }
- esp_netif_dhcps_start(wifi_netif);
- ESP_LOGD(TAG, "Done configuring Soft Access Point");
- dns_server_start();
- }
- void wifi_manager_filter_unique(wifi_ap_record_t* aplist, uint16_t* aps) {
- int total_unique;
- wifi_ap_record_t* first_free;
- total_unique = *aps;
- first_free = NULL;
- for (int i = 0; i < *aps - 1; i++) {
- wifi_ap_record_t* ap = &aplist[i];
- /* skip the previously removed APs */
- if (ap->ssid[0] == 0)
- continue;
- /* remove the identical SSID+authmodes */
- for (int j = i + 1; j < *aps; j++) {
- wifi_ap_record_t* ap1 = &aplist[j];
- if ((strcmp((const char*)ap->ssid, (const char*)ap1->ssid) == 0) &&
- (ap->authmode == ap1->authmode)) { /* same SSID, different auth mode is skipped */
- /* save the rssi for the display */
- if ((ap1->rssi) > (ap->rssi))
- ap->rssi = ap1->rssi;
- /* clearing the record */
- memset(ap1, 0, sizeof(wifi_ap_record_t));
- }
- }
- }
- /* reorder the list so APs follow each other in the list */
- for (int i = 0; i < *aps; i++) {
- wifi_ap_record_t* ap = &aplist[i];
- /* skipping all that has no name */
- if (ap->ssid[0] == 0) {
- /* mark the first free slot */
- if (first_free == NULL)
- first_free = ap;
- total_unique--;
- continue;
- }
- if (first_free != NULL) {
- memcpy(first_free, ap, sizeof(wifi_ap_record_t));
- memset(ap, 0, sizeof(wifi_ap_record_t));
- /* find the next free slot */
- for (int j = 0; j < *aps; j++) {
- if (aplist[j].ssid[0] == 0) {
- first_free = &aplist[j];
- break;
- }
- }
- }
- }
- /* update the length of the list */
- *aps = total_unique;
- }
- char* wifi_manager_alloc_get_ap_list_json() {
- return cJSON_PrintUnformatted(accessp_cjson);
- }
- cJSON* wifi_manager_clear_ap_list_json(cJSON** old) {
- ESP_LOGV(TAG, "wifi_manager_clear_ap_list_json called");
- cJSON* root = wifi_manager_get_new_array_json(old);
- ESP_LOGV(TAG, "wifi_manager_clear_ap_list_json done");
- return root;
- }
- esp_err_t wifi_scan_done(queue_message* msg) {
- esp_err_t err = ESP_OK;
- /* As input param, it stores max AP number ap_records can hold. As output param, it receives the actual AP number this API returns.
- * As a consequence, ap_num MUST be reset to MAX_AP_NUM at every scan */
- ESP_LOGD(TAG, "Getting AP list records");
- if ((err = esp_wifi_scan_get_ap_num(&ap_num)) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to retrieve scan results count. Error %s", esp_err_to_name(err));
- return err;
- }
- if (ap_num > 0) {
- accessp_records = (wifi_ap_record_t*)malloc(sizeof(wifi_ap_record_t) * ap_num);
- if ((err = esp_wifi_scan_get_ap_records(&ap_num, accessp_records)) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to retrieve scan results list. Error %s", esp_err_to_name(err));
- return err;
- }
- /* make sure the http server isn't trying to access the list while it gets refreshed */
- ESP_LOGD(TAG, "Preparing to build ap JSON list");
- if (wifi_manager_lock_json_buffer(pdMS_TO_TICKS(1000))) {
- /* Will remove the duplicate SSIDs from the list and update ap_num */
- wifi_manager_filter_unique(accessp_records, &ap_num);
- wifi_manager_generate_access_points_json(&accessp_cjson);
- wifi_manager_unlock_json_buffer();
- ESP_LOGD(TAG, "Done building ap JSON list");
- } else {
- ESP_LOGE(TAG, "could not get access to json mutex in wifi_scan");
- err = ESP_FAIL;
- }
- free(accessp_records);
- } else {
- //
- ESP_LOGD(TAG, "No AP Found. Emptying the list.");
- accessp_cjson = wifi_manager_get_new_array_json(&accessp_cjson);
- }
- return err;
- }
- bool is_wifi_up(){
- return wifi_netif!=NULL;
- }
- esp_err_t network_wifi_start_scan(queue_message* msg) {
- esp_err_t err = ESP_OK;
- ESP_LOGD(TAG, "MESSAGE: ORDER_START_WIFI_SCAN");
- if(!is_wifi_up()) {
- messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Cannot scan");
- return ESP_FAIL;
- }
- /* if a scan is already in progress this message is simply ignored thanks to the WIFI_MANAGER_SCAN_BIT uxBit */
- if (!network_manager_is_flag_set(WIFI_MANAGER_SCAN_BIT)) {
- if ((err = esp_wifi_scan_start(&scan_config, false)) != ESP_OK) {
- ESP_LOGW(TAG, "Unable to start scan; %s ", esp_err_to_name(err));
- // set_status_message(WARNING, "Wifi Connecting. Cannot start scan.");
- messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Scanning failed: %s", esp_err_to_name(err));
- } else {
- network_manager_set_flag(WIFI_MANAGER_SCAN_BIT);
- }
- } else {
- ESP_LOGW(TAG, "Scan already in progress!");
- }
- return err;
- }
- static void polling_STA(void* timer_id) {
- network_manager_async_connect(wifi_manager_get_wifi_sta_config());
- }
- void set_host_name() {
- esp_err_t err;
- ESP_LOGD(TAG, "Retrieving host name from nvs");
- char* host_name = (char*)config_alloc_get(NVS_TYPE_STR, "host_name");
- if (host_name == NULL) {
- ESP_LOGE(TAG, "Could not retrieve host name from nvs");
- } else {
- ESP_LOGD(TAG, "Setting host name to : %s", host_name);
- if ((err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, host_name)) != ESP_OK) {
- ESP_LOGE(TAG, "Unable to set host name. Error: %s", esp_err_to_name(err));
- }
- // if((err=tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_AP, host_name)) !=ESP_OK){
- // ESP_LOGE(TAG, "Unable to set host name. Error: %s",esp_err_to_name(err));
- // }
- free(host_name);
- }
- }
- esp_err_t network_wifi_connect(wifi_config_t * cfg){
- esp_err_t err = ESP_OK;
- ESP_LOGD(TAG, "network_wifi_connect");
- if(!is_wifi_up()) {
- messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Cannot connect");
- return ESP_FAIL;
- }
- tcpip_adapter_dhcp_status_t status;
- ESP_LOGD(TAG, "wifi_manager: Checking if DHCP client for STA interface is running");
- ESP_ERROR_CHECK_WITHOUT_ABORT(tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &status));
- if (status != TCPIP_ADAPTER_DHCP_STARTED) {
- ESP_LOGD(TAG, "wifi_manager: Start DHCP client for STA interface");
- ESP_ERROR_CHECK_WITHOUT_ABORT(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA));
- }
- wifi_mode_t mode;
- /* update config to latest and attempt connection */
- esp_wifi_get_mode(&mode);
- if (WIFI_MODE_APSTA != mode && WIFI_MODE_STA != mode) {
- // the soft ap is not started, so let's set the WiFi mode to STA
- ESP_LOGD(TAG, "MESSAGE: network_wifi_connect_existing - setting mode WIFI_MODE_STA");
- if ((err = esp_wifi_set_mode(WIFI_MODE_STA)) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to set wifi mode to STA. Error %s", esp_err_to_name(err));
- return err;
- }
- }
-
- if ((err = esp_wifi_set_config(WIFI_IF_STA, cfg)) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to set STA configuration. Error %s", esp_err_to_name(err));
- return err;
- }
- set_host_name();
- ESP_LOGI(TAG, "Wifi Connecting...");
- if ((err = esp_wifi_connect()) != ESP_OK) {
- ESP_LOGE(TAG, "Failed to initiate wifi connection. Error %s", esp_err_to_name(err));
- return err;
- }
- return err;
- }
- void network_wifi_clear_config(){
-
- /* erase configuration */
- if (wifi_manager_config_sta) {
- ESP_LOGI(TAG, "Erasing WiFi Configuration.");
- memset(wifi_manager_config_sta, 0x00, sizeof(wifi_config_t));
- /* save NVS memory */
- network_wifi_save_sta_config();
- }
- }
- // esp_err_t network_wifi_disconnected(queue_message* msg) {
- // esp_err_t err = ESP_OK;
- // wifi_event_sta_disconnected_t disc_event;
- // // ESP_LOGD(TAG, "MESSAGE: EVENT_STA_DISCONNECTED");
- // // if (msg->param == NULL) {
- // // ESP_LOGE(TAG, "MESSAGE: EVENT_STA_DISCONNECTED - expected parameter not found!");
- // // } else {
- // // memcpy(&disc_event, (wifi_event_sta_disconnected_t*)msg->param, sizeof(disc_event));
- // // free(msg->param);
- // // ESP_LOGD(TAG, "MESSAGE: EVENT_STA_DISCONNECTED with Reason code: %d (%s)", disc_event.reason, get_disconnect_code_desc(disc_event.reason));
- // // }
- // /* this even can be posted in numerous different conditions
- // *
- // * 1. SSID password is wrong
- // * 2. Manual disconnection ordered
- // * 3. Connection lost
- // *
- // * Having clear understand as to WHY the event was posted is key to having an efficient wifi manager
- // *
- // * With wifi_manager, we determine:
- // * If WIFI_MANAGER_REQUEST_STA_CONNECT_BIT is set, We consider it's a client that requested the connection.
- // * When SYSTEM_EVENT_STA_DISCONNECTED is posted, it's probably a password/something went wrong with the handshake.
- // *
- // * If WIFI_MANAGER_REQUEST_STA_CONNECT_BIT is set, it's a disconnection that was ASKED by the client (clicking disconnect in the app)
- // * When SYSTEM_EVENT_STA_DISCONNECTED is posted, saved wifi is erased from the NVS memory.
- // *
- // * If WIFI_MANAGER_REQUEST_STA_CONNECT_BIT and WIFI_MANAGER_REQUEST_STA_CONNECT_BIT are NOT set, it's a lost connection
- // *
- // * In this version of the software, reason codes are not used. They are indicated here for potential future usage.
- // *
- // * REASON CODE:
- // * 1 UNSPECIFIED
- // * 2 AUTH_EXPIRE auth no longer valid, this smells like someone changed a password on the AP
- // * 3 AUTH_LEAVE
- // * 4 ASSOC_EXPIRE
- // * 5 ASSOC_TOOMANY too many devices already connected to the AP => AP fails to respond
- // * 6 NOT_AUTHED
- // * 7 NOT_ASSOCED
- // * 8 ASSOC_LEAVE
- // * 9 ASSOC_NOT_AUTHED
- // * 10 DISASSOC_PWRCAP_BAD
- // * 11 DISASSOC_SUPCHAN_BAD
- // * 12 <n/a>
- // * 13 IE_INVALID
- // * 14 MIC_FAILURE
- // * 15 4WAY_HANDSHAKE_TIMEOUT wrong password! This was personnaly tested on my home wifi with a wrong password.
- // * 16 GROUP_KEY_UPDATE_TIMEOUT
- // * 17 IE_IN_4WAY_DIFFERS
- // * 18 GROUP_CIPHER_INVALID
- // * 19 PAIRWISE_CIPHER_INVALID
- // * 20 AKMP_INVALID
- // * 21 UNSUPP_RSN_IE_VERSION
- // * 22 INVALID_RSN_IE_CAP
- // * 23 802_1X_AUTH_FAILED wrong password?
- // * 24 CIPHER_SUITE_REJECTED
- // * 200 BEACON_TIMEOUT
- // * 201 NO_AP_FOUND
- // * 202 AUTH_FAIL
- // * 203 ASSOC_FAIL
- // * 204 HANDSHAKE_TIMEOUT
- // *
- // * */
- // /* reset saved sta IP */
- // wifi_manager_safe_reset_sta_ip_string();
- // if (network_manager_is_flag_set(WIFI_MANAGER_REQUEST_STA_CONNECT_BIT)) {
- // network_manager_clear_flag(WIFI_MANAGER_REQUEST_STA_CONNECT_BIT);
- // ESP_LOGW(TAG, "WiFi Disconnected while processing user connect request. Wrong password?");
- // /* there are no retries when it's a user requested connection by design. This avoids a user hanging too much
- // * in case they typed a wrong password for instance. Here we simply clear the request bit and move on */
-
- // wifi_mode_t mode;
- // esp_wifi_get_mode(&mode);
- // if (WIFI_MODE_STA == mode) {
- // network_manager_set_flag(WIFI_MANAGER_REQUEST_STA_CONNECT_FAILED_BIT);
- // // if wifi was STA, attempt to reload the previous network connection
- // ESP_LOGW(TAG, "Attempting to restore previous network");
- // wifi_manager_send_message(ORDER_LOAD_AND_RESTORE_STA, NULL);
- // }
- // } else if (network_manager_is_flag_set(WIFI_MANAGER_REQUEST_DISCONNECT_BIT)) {
- // // ESP_LOGD(TAG, "WiFi disconnected by user");
- // // /* user manually requested a disconnect so the lost connection is a normal event. Clear the flag and restart the AP */
- // // network_manager_clear_flag(WIFI_MANAGER_REQUEST_DISCONNECT_BIT);
- // // wifi_manager_generate_ip_info_json(UPDATE_USER_DISCONNECT, wifi_netif,false);
- // // /* erase configuration */
- // // if (wifi_manager_config_sta) {
- // // ESP_LOGI(TAG, "Erasing WiFi Configuration.");
- // // memset(wifi_manager_config_sta, 0x00, sizeof(wifi_config_t));
- // // /* save NVS memory */
- // // network_wifi_save_sta_config();
- // // }
- // // /* start SoftAP */
- // // ESP_LOGD(TAG, "Disconnect processing complete. Ordering an AP start.");
- // // wifi_manager_send_message(ORDER_START_AP, NULL);
- // } else {
- // /* lost connection ? */
- // // ESP_LOGE(TAG, "WiFi Connection lost.");
- // // messaging_post_message(MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "WiFi Connection lost");
- // // wifi_manager_generate_ip_info_json(UPDATE_LOST_CONNECTION, wifi_netif,false);
- // // if (retries < WIFI_MANAGER_MAX_RETRY) {
- // // ESP_LOGD(TAG, "Issuing ORDER_CONNECT_STA to retry connection.");
- // // retries++;
- // // wifi_manager_send_message(ORDER_CONNECT_STA, (void*)CONNECTION_REQUEST_AUTO_RECONNECT);
- // // } else {
- // // /* In this scenario the connection was lost beyond repair: kick start the AP! */
- // // retries = 0;
- // // wifi_mode_t mode;
- // // ESP_LOGW(TAG, "All connect retry attempts failed.");
- // // /* put us in softAP mode first */
- // // esp_wifi_get_mode(&mode);
- // // /* if it was a restore attempt connection, we clear the bit */
- // // network_manager_clear_flag(WIFI_MANAGER_REQUEST_RESTORE_STA_BIT);
- // // if (WIFI_MODE_APSTA != mode) {
- // // STA_duration = STA_POLLING_MIN;
- // // wifi_manager_send_message(ORDER_CONNECT_STA, (void*)CONNECTION_REQUEST_MAX_FAILED);
- // // } else if (STA_duration < STA_POLLING_MAX) {
- // // STA_duration *= 1.25;
- // // }
- // // xTimerChangePeriod(STA_timer, pdMS_TO_TICKS(STA_duration), portMAX_DELAY);
- // // xTimerStart(STA_timer, portMAX_DELAY);
- // // ESP_LOGD(TAG, "STA search slow polling of %d", STA_duration);
- // // }
- // }
- // return err;
- // }
- char* get_disconnect_code_desc(uint8_t reason) {
- switch (reason) {
- case 1:
- return "UNSPECIFIED";
- break;
- case 2:
- return "AUTH_EXPIRE";
- break;
- case 3:
- return "AUTH_LEAVE";
- break;
- case 4:
- return "ASSOC_EXPIRE";
- break;
- case 5:
- return "ASSOC_TOOMANY";
- break;
- case 6:
- return "NOT_AUTHED";
- break;
- case 7:
- return "NOT_ASSOCED";
- break;
- case 8:
- return "ASSOC_LEAVE";
- break;
- case 9:
- return "ASSOC_NOT_AUTHED";
- break;
- case 10:
- return "DISASSOC_PWRCAP_BAD";
- break;
- case 11:
- return "DISASSOC_SUPCHAN_BAD";
- break;
- case 12:
- return "<n/a>";
- break;
- case 13:
- return "IE_INVALID";
- break;
- case 14:
- return "MIC_FAILURE";
- break;
- case 15:
- return "4WAY_HANDSHAKE_TIMEOUT";
- break;
- case 16:
- return "GROUP_KEY_UPDATE_TIMEOUT";
- break;
- case 17:
- return "IE_IN_4WAY_DIFFERS";
- break;
- case 18:
- return "GROUP_CIPHER_INVALID";
- break;
- case 19:
- return "PAIRWISE_CIPHER_INVALID";
- break;
- case 20:
- return "AKMP_INVALID";
- break;
- case 21:
- return "UNSUPP_RSN_IE_VERSION";
- break;
- case 22:
- return "INVALID_RSN_IE_CAP";
- break;
- case 23:
- return "802_1X_AUTH_FAILED";
- break;
- case 24:
- return "CIPHER_SUITE_REJECTED";
- break;
- case 200:
- return "BEACON_TIMEOUT";
- break;
- case 201:
- return "NO_AP_FOUND";
- break;
- case 202:
- return "AUTH_FAIL";
- break;
- case 203:
- return "ASSOC_FAIL";
- break;
- case 204:
- return "HANDSHAKE_TIMEOUT";
- break;
- default:
- return "UNKNOWN";
- break;
- }
- return "";
- }
- static void network_manager_wifi_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
- ip_event_got_ip_t* s = NULL;
- tcpip_adapter_if_t index;
- esp_netif_ip_info_t* ip_info = NULL;
- if (event_base != IP_EVENT)
- return;
- switch (event_id) {
- case IP_EVENT_ETH_GOT_IP:
- case IP_EVENT_STA_GOT_IP:
- s = (ip_event_got_ip_t*)event_data;
- //tcpip_adapter_if_t index = s->if_index;
- network_manager_async_got_ip();
- ip_info = &s->ip_info;
- index = s->if_index;
- ESP_LOGI(TAG, "Got an IP address from interface #%i. IP=" IPSTR ", Gateway=" IPSTR ", NetMask=" IPSTR ", %s",
- index,
- IP2STR(&ip_info->ip),
- IP2STR(&ip_info->gw),
- IP2STR(&ip_info->netmask),
- s->ip_changed ? "Address was changed" : "Address unchanged");
-
- break;
- case IP_EVENT_STA_LOST_IP:
- ESP_LOGD(TAG, "IP_EVENT_STA_LOST_IP");
- break;
- case IP_EVENT_AP_STAIPASSIGNED:
- ESP_LOGD(TAG, "IP_EVENT_AP_STAIPASSIGNED");
- break;
- case IP_EVENT_GOT_IP6:
- ESP_LOGD(TAG, "IP_EVENT_GOT_IP6");
- break;
- default:
- break;
- }
- }
|