network_wifi.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960
  1. #ifdef NETWORK_WIFI_LOG_LEVEL
  2. #define LOG_LOCAL_LEVEL NETWORK_WIFI_LOG_LEVEL
  3. #endif
  4. #include "network_wifi.h"
  5. #include "cJSON.h"
  6. #include "dns_server.h"
  7. #include "esp_event.h"
  8. #include "esp_log.h"
  9. #include "esp_system.h"
  10. #include "esp_wifi.h"
  11. #include "esp_wifi_types.h"
  12. #include "lwip/sockets.h"
  13. #include "messaging.h"
  14. #include "network_status.h"
  15. #include <string.h>
  16. #pragma message("fixme: search for TODO in the code below")
  17. #include "platform_esp32.h"
  18. #include "tools.h"
  19. #include "trace.h"
  20. #include "accessors.h"
  21. static void network_wifi_event_handler(
  22. void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
  23. static char* get_disconnect_code_desc(uint8_t reason);
  24. esp_err_t network_wifi_get_blob(void* target, size_t size, const char* key);
  25. static inline const char* ssid_string(const wifi_sta_config_t* sta);
  26. static inline const char* password_string(const wifi_sta_config_t* sta);
  27. static const char* status_file_name = "status.bin";
  28. #define MAX_CREDENTIALS sizeof(platform->net.credentials) / sizeof(sys_WifiSTAEntry)
  29. static const char TAG[] = "network_wifi";
  30. esp_netif_t* wifi_netif;
  31. esp_netif_t* wifi_ap_netif;
  32. extern sys_Status status;
  33. #define UINT_TO_STRING(val) \
  34. static char loc[sizeof(val) + 1]; \
  35. memset(loc, 0x00, sizeof(loc)); \
  36. strlcpy(loc, (char*)val, sizeof(loc)); \
  37. return loc;
  38. static inline const char* ssid_string(const wifi_sta_config_t* sta) { UINT_TO_STRING(sta->ssid); }
  39. static inline const char* password_string(const wifi_sta_config_t* sta) {
  40. UINT_TO_STRING(sta->password);
  41. }
  42. static inline const char* ap_ssid_string(const wifi_ap_record_t* ap) { UINT_TO_STRING(ap->ssid); }
  43. bool network_wifi_reset_rssi() {
  44. ESP_LOGD(TAG,"Resetting RSSI");
  45. if (network_status_lock_structure(pdMS_TO_TICKS(1000))) {
  46. for (int index = 0; index < platform->net.credentials_count - 1; index++) {
  47. platform->net.credentials[index].rssi = 0;
  48. }
  49. network_status_unlock_structure();
  50. return true;
  51. }
  52. return false;
  53. }
  54. bool network_wifi_reset_connected() {
  55. ESP_LOGD(TAG,"Resetting Connected");
  56. if (network_status_lock_structure(pdMS_TO_TICKS(1000))) {
  57. for (int index = 0; index < platform->net.credentials_count - 1; index++) {
  58. platform->net.credentials[index].connected = false;
  59. }
  60. network_status_unlock_structure();
  61. return true;
  62. }
  63. return false;
  64. }
  65. void network_wifi_format_bssid(char* buffer, size_t len, const uint8_t* bssid) {
  66. snprintf(buffer, len, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3],
  67. bssid[4], bssid[5]);
  68. }
  69. int network_wifi_get_ap_entry_index(const char* ssid) {
  70. for (int i = 0; i < platform->net.credentials_count; i++) {
  71. if (strcmp(platform->net.credentials[i].ssid, ssid) == 0) {
  72. // found the SSID.
  73. return i;
  74. }
  75. }
  76. return -1;
  77. }
  78. sys_WifiSTAEntry * network_wifi_get_ap_entry(const char * ssid){
  79. sys_WifiSTAEntry * result = NULL;
  80. int index = network_wifi_get_ap_entry_index(ssid);
  81. if(index>=0 && index < platform->net.credentials_count){
  82. result = &platform->net.credentials[index];
  83. }
  84. return result;
  85. }
  86. void network_wifi_update_connected(const char * ssid){
  87. if(!ssid || strlen(ssid) == 0){
  88. ESP_LOGE(TAG, "Unable to update connected SSID. No ssid received");
  89. return;
  90. }
  91. sys_WifiSTAEntry * sta = network_wifi_get_ap_entry(ssid);
  92. if (sta && network_status_lock_structure(pdMS_TO_TICKS(1000))) {
  93. sta->connected = true;
  94. network_status_unlock_structure();
  95. platform->net.has_last_connected = true;
  96. memcpy(&platform->net.last_connected, sta,sizeof(platform->net.last_connected));
  97. }
  98. }
  99. size_t network_wifi_get_known_count(){
  100. size_t result = 0;
  101. for (int i = 0; i < platform->net.credentials_count; i++) {
  102. if(strlen(platform->net.credentials[i].ssid)>0) result ++;
  103. }
  104. return result;
  105. }
  106. bool network_wifi_remove_credentials(int index) {
  107. int cur_index = 0;
  108. if (index == -1 || index >= platform->net.credentials_count) {
  109. ESP_LOGW(TAG, "ssid not found or erorr finding SSID");
  110. return false;
  111. }
  112. if (network_status_lock_structure(pdMS_TO_TICKS(1000))) {
  113. for (cur_index = index; cur_index < platform->net.credentials_count - 1; cur_index++) {
  114. // Shift following ssid's starting at this slot.
  115. memcpy(&platform->net.credentials[cur_index], &platform->net.credentials[cur_index + 1],
  116. sizeof(sys_WifiSTAEntry));
  117. }
  118. memset(&platform->net.credentials[cur_index + 1], 0x00, sizeof(sys_WifiSTAEntry));
  119. platform->net.credentials_count--;
  120. network_status_unlock_structure();
  121. return true;
  122. }
  123. return false;
  124. }
  125. bool network_wifi_remove_ap_entry(const char* ssid) {
  126. int index = network_wifi_get_ap_entry_index(ssid);
  127. return network_wifi_remove_credentials(index);
  128. }
  129. void network_wifi_sort_last_seen() {
  130. sys_NetworkConfig* config = NULL;
  131. if (!SYS_NET(config)) return;
  132. if (network_status_lock_structure(pdMS_TO_TICKS(1000))) {
  133. bool swapped;
  134. do {
  135. swapped = false;
  136. for (int i = 0; i < config->credentials_count - 1; i++) {
  137. if (config->credentials[i].last_seen.seconds < config->credentials[i + 1].last_seen.seconds) {
  138. sys_WifiSTAEntry temp = config->credentials[i];
  139. config->credentials[i] = config->credentials[i + 1];
  140. config->credentials[i + 1] = temp;
  141. swapped = true;
  142. }
  143. }
  144. } while (swapped);
  145. network_status_unlock_structure();
  146. }
  147. }
  148. void network_wifi_sort_strength() {
  149. sys_NetworkConfig* config = platform->has_net ? &platform->net : NULL;
  150. if (!config) return;
  151. if (network_status_lock_structure(pdMS_TO_TICKS(1000))) {
  152. bool swapped;
  153. do {
  154. swapped = false;
  155. for (int i = 0; i < config->credentials_count - 1; i++) {
  156. if (config->credentials[i].rssi < config->credentials[i + 1].rssi) {
  157. sys_WifiSTAEntry temp = config->credentials[i];
  158. config->credentials[i] = config->credentials[i + 1];
  159. config->credentials[i + 1] = temp;
  160. swapped = true;
  161. }
  162. }
  163. } while (swapped);
  164. network_status_unlock_structure();
  165. }
  166. }
  167. void network_wifi_empty_known_list() {
  168. sys_WifiSTAEntry defaultWifi = sys_WifiSTAEntry_init_default;
  169. sys_NetworkConfig* config = platform->has_net ? &platform->net : NULL;
  170. if (!config) return;
  171. for (int i = 0; i < config->credentials_count - 1; i++) {
  172. memcpy(&config->credentials[i], &defaultWifi, sizeof(config->credentials[i]));
  173. }
  174. config->credentials_count = 0;
  175. }
  176. const wifi_sta_config_t* network_wifi_get_active_config() {
  177. static wifi_config_t config;
  178. esp_err_t err = ESP_OK;
  179. memset(&config, 0x00, sizeof(config));
  180. if ((err = esp_wifi_get_config(WIFI_IF_STA, &config)) == ESP_OK) {
  181. return &config.sta;
  182. } else {
  183. ESP_LOGD(TAG, "Could not get wifi STA config: %s", esp_err_to_name(err));
  184. }
  185. return NULL;
  186. }
  187. sys_WifiSTAEntry* network_wifi_get_free_ssid() {
  188. for (int i = 0; i < MAX_CREDENTIALS; i++) {
  189. if (strlen(platform->net.credentials[i].ssid) == 0) {
  190. return &platform->net.credentials[i];
  191. }
  192. }
  193. return NULL;
  194. }
  195. bool network_wifi_add_ap(sys_WifiSTAEntry* item) {
  196. sys_WifiSTAEntry* entry = network_wifi_get_free_ssid();
  197. if (!entry) {
  198. network_wifi_sort_last_seen();
  199. network_wifi_remove_credentials(MAX_CREDENTIALS - 1);
  200. platform->net.credentials_count--;
  201. entry = network_wifi_get_free_ssid();
  202. }
  203. if (!entry) {
  204. ESP_LOGE(TAG, "Unable to find free slot to store wifi");
  205. return false;
  206. }
  207. memcpy(entry, item, sizeof(sys_WifiSTAEntry));
  208. platform->net.credentials_count++;
  209. return true;
  210. }
  211. sys_WifiSTAEntry* network_wifi_get_ssid_info(const char* ssid) {
  212. if (!ssid || strlen(ssid) == 0) return NULL;
  213. for (int i = 0; i < status.net.wifi.scan_result_count; i++) {
  214. if (strcmp(status.net.wifi.scan_result[i].ssid, ssid) == 0) {
  215. return &status.net.wifi.scan_result[i];
  216. }
  217. }
  218. return NULL;
  219. }
  220. wifi_auth_mode_t network_wifi_get_auth_mode(sys_WifiAuthTypeEnum auth_type) {
  221. switch (auth_type) {
  222. case sys_WifiAuthTypeEnum_AUTH_OPEN:
  223. return WIFI_AUTH_OPEN;
  224. case sys_WifiAuthTypeEnum_AUTH_WEP:
  225. return WIFI_AUTH_WEP;
  226. case sys_WifiAuthTypeEnum_AUTH_WPA_PSK:
  227. return WIFI_AUTH_WPA_PSK;
  228. case sys_WifiAuthTypeEnum_AUTH_WPA2_PSK:
  229. return WIFI_AUTH_WPA2_PSK;
  230. case sys_WifiAuthTypeEnum_AUTH_WPA_WPA2_PSK:
  231. return WIFI_AUTH_WPA_WPA2_PSK;
  232. case sys_WifiAuthTypeEnum_AUTH_WPA2_ENTERPRISE:
  233. return WIFI_AUTH_WPA2_ENTERPRISE;
  234. case sys_WifiAuthTypeEnum_AUTH_WPA3_PSK:
  235. return WIFI_AUTH_WPA3_PSK;
  236. case sys_WifiAuthTypeEnum_AUTH_WPA2_WPA3_PSK:
  237. return WIFI_AUTH_WPA2_WPA3_PSK;
  238. case sys_WifiAuthTypeEnum_AUTH_WAPI_PSK:
  239. return WIFI_AUTH_WAPI_PSK;
  240. default:
  241. return WIFI_AUTH_OPEN; // Default case
  242. }
  243. }
  244. sys_WifiAuthTypeEnum network_wifi_get_auth_type(const wifi_auth_mode_t mode) {
  245. switch (mode) {
  246. case WIFI_AUTH_OPEN:
  247. return sys_WifiAuthTypeEnum_AUTH_OPEN;
  248. case WIFI_AUTH_WEP:
  249. return sys_WifiAuthTypeEnum_AUTH_WEP;
  250. case WIFI_AUTH_WPA_PSK:
  251. return sys_WifiAuthTypeEnum_AUTH_WPA_PSK;
  252. case WIFI_AUTH_WPA2_PSK:
  253. return sys_WifiAuthTypeEnum_AUTH_WPA2_PSK;
  254. case WIFI_AUTH_WPA_WPA2_PSK:
  255. return sys_WifiAuthTypeEnum_AUTH_WPA_WPA2_PSK;
  256. case WIFI_AUTH_WPA2_ENTERPRISE:
  257. return sys_WifiAuthTypeEnum_AUTH_WPA2_ENTERPRISE;
  258. case WIFI_AUTH_WPA3_PSK:
  259. return sys_WifiAuthTypeEnum_AUTH_WPA3_PSK;
  260. case WIFI_AUTH_WPA2_WPA3_PSK:
  261. return sys_WifiAuthTypeEnum_AUTH_WPA2_WPA3_PSK;
  262. case WIFI_AUTH_WAPI_PSK:
  263. return sys_WifiAuthTypeEnum_AUTH_WAPI_PSK;
  264. case WIFI_AUTH_MAX:
  265. return sys_WifiAuthTypeEnum_AUTH_OPEN;
  266. }
  267. return sys_WifiAuthTypeEnum_AUTH_UNKNOWN;
  268. }
  269. sys_WifiRadioTypesEnum network_wifi_get_radio_type(const wifi_ap_record_t* sta) {
  270. if (sta == NULL) {
  271. return sys_WifiRadioTypesEnum_PHY_UNKNOWN;
  272. }
  273. // Check each bit field and return the corresponding enum value
  274. if (sta->phy_11b) {
  275. return sys_WifiRadioTypesEnum_PHY_11B;
  276. } else if (sta->phy_11g) {
  277. return sys_WifiRadioTypesEnum_PHY_11G;
  278. } else if (sta->phy_11n) {
  279. return sys_WifiRadioTypesEnum_PHY_11N;
  280. } else if (sta->phy_lr) {
  281. return sys_WifiRadioTypesEnum_PHY_LR;
  282. } else if (sta->wps) {
  283. return sys_WifiRadioTypesEnum_PHY_WPS;
  284. } else if (sta->ftm_responder) {
  285. return sys_WifiRadioTypesEnum_PHY_FTM_RESPONDER;
  286. } else if (sta->ftm_initiator) {
  287. return sys_WifiRadioTypesEnum_PHY_FTM_INITIATOR;
  288. }
  289. return sys_WifiRadioTypesEnum_PHY_UNKNOWN;
  290. }
  291. esp_err_t network_wifi_add_update_ap_from_sta_copy(const wifi_sta_config_t* sta) {
  292. esp_err_t err = ESP_OK;
  293. if (!sta) {
  294. ESP_LOGE(TAG, "Invalid access point entry");
  295. return ESP_ERR_INVALID_ARG;
  296. }
  297. if (!sta->ssid || strlen((char*)sta->ssid) == 0) {
  298. ESP_LOGE(TAG, "Invalid access point ssid");
  299. return ESP_ERR_INVALID_ARG;
  300. }
  301. sys_WifiSTAEntry item = sys_WifiSTAEntry_init_default;
  302. strncpy(item.ssid, ssid_string(sta), sizeof(item.ssid));
  303. strncpy(item.password, password_string(sta), sizeof(item.ssid));
  304. network_wifi_format_bssid(item.bssid, sizeof(item.bssid), sta->bssid);
  305. item.channel = sta->channel;
  306. sys_WifiSTAEntry* seen = network_wifi_get_ssid_info(item.ssid);
  307. if (seen) {
  308. item.auth_type = seen->auth_type;
  309. item.radio_type = seen->radio_type;
  310. }
  311. err = network_wifi_add_ap(&item);
  312. return err;
  313. }
  314. bool network_wifi_is_known_ap(const char* ssid) { return network_wifi_get_ap_entry(ssid) != NULL; }
  315. bool network_wifi_str2mac(const char* mac, uint8_t* values) {
  316. if (6 == sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &values[0], &values[1], &values[2],
  317. &values[3], &values[4], &values[5])) {
  318. return true;
  319. } else {
  320. return false;
  321. }
  322. }
  323. esp_err_t network_wifi_erase_known_ap() {
  324. network_wifi_empty_known_list();
  325. return ESP_OK;
  326. }
  327. esp_netif_t* network_wifi_get_interface() { return wifi_netif; }
  328. esp_netif_t* network_wifi_get_ap_interface() { return wifi_ap_netif; }
  329. esp_err_t network_wifi_set_sta_mode() {
  330. if (!wifi_netif) {
  331. ESP_LOGE(TAG, "Wifi not initialized. Cannot set sta mode");
  332. return ESP_ERR_INVALID_STATE;
  333. }
  334. ESP_LOGD(TAG, "Set Mode to STA");
  335. esp_err_t err = esp_wifi_set_mode(WIFI_MODE_STA);
  336. if (err != ESP_OK) {
  337. ESP_LOGE(TAG, "Error setting mode to STA: %s", esp_err_to_name(err));
  338. } else {
  339. ESP_LOGI(TAG, "Starting wifi");
  340. err = esp_wifi_start();
  341. if (err != ESP_OK) {
  342. ESP_LOGE(TAG, "Error starting wifi: %s", esp_err_to_name(err));
  343. }
  344. }
  345. return err;
  346. }
  347. esp_netif_t* network_wifi_start() {
  348. MEMTRACE_PRINT_DELTA_MESSAGE("Starting wifi interface as STA mode");
  349. if (!wifi_netif) {
  350. MEMTRACE_PRINT_DELTA_MESSAGE("Init STA mode - creating default interface. ");
  351. wifi_netif = esp_netif_create_default_wifi_sta();
  352. MEMTRACE_PRINT_DELTA_MESSAGE("Initializing Wifi. ");
  353. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  354. ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_init(&cfg));
  355. MEMTRACE_PRINT_DELTA_MESSAGE("Registering wifi Handlers");
  356. // network_wifi_register_handlers();
  357. ESP_ERROR_CHECK_WITHOUT_ABORT(esp_event_handler_instance_register(
  358. WIFI_EVENT, ESP_EVENT_ANY_ID, &network_wifi_event_handler, NULL, NULL));
  359. MEMTRACE_PRINT_DELTA_MESSAGE("Setting up wifi Storage");
  360. ESP_ERROR_CHECK_WITHOUT_ABORT(esp_wifi_set_storage(WIFI_STORAGE_RAM));
  361. }
  362. MEMTRACE_PRINT_DELTA_MESSAGE("Setting up wifi mode as STA");
  363. network_wifi_set_sta_mode();
  364. MEMTRACE_PRINT_DELTA_MESSAGE("Setting hostname");
  365. network_set_hostname(wifi_netif);
  366. MEMTRACE_PRINT_DELTA_MESSAGE("Done starting wifi interface");
  367. return wifi_netif;
  368. }
  369. void destroy_network_wifi() {
  370. }
  371. bool network_wifi_sta_config_changed() {
  372. bool changed = true;
  373. const wifi_sta_config_t* sta = network_wifi_get_active_config();
  374. if (!sta || strlen(ssid_string(sta)) == 0) return false;
  375. sys_WifiSTAEntry* known = network_wifi_get_ap_entry(ssid_string(sta));
  376. if (known && strcmp(known->ssid, ssid_string(sta)) == 0 &&
  377. strcmp((char*)known->password, password_string(sta)) == 0) {
  378. changed = false;
  379. } else {
  380. ESP_LOGI(TAG, "New network configuration found");
  381. }
  382. return changed;
  383. }
  384. static void network_wifi_event_handler(
  385. void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
  386. if (event_base != WIFI_EVENT) return;
  387. switch (event_id) {
  388. case WIFI_EVENT_WIFI_READY:
  389. ESP_LOGD(TAG, "WIFI_EVENT_WIFI_READY");
  390. break;
  391. case WIFI_EVENT_SCAN_DONE:
  392. ESP_LOGD(TAG, "WIFI_EVENT_SCAN_DONE");
  393. network_async_scan_done();
  394. break;
  395. case WIFI_EVENT_STA_AUTHMODE_CHANGE:
  396. ESP_LOGD(TAG, "WIFI_EVENT_STA_AUTHMODE_CHANGE");
  397. break;
  398. case WIFI_EVENT_AP_START:
  399. ESP_LOGD(TAG, "WIFI_EVENT_AP_START");
  400. break;
  401. case WIFI_EVENT_AP_STOP:
  402. ESP_LOGD(TAG, "WIFI_EVENT_AP_STOP");
  403. break;
  404. case WIFI_EVENT_AP_PROBEREQRECVED: {
  405. wifi_event_ap_probe_req_rx_t* s = (wifi_event_ap_probe_req_rx_t*)event_data;
  406. char* mac = network_manager_alloc_get_mac_string(s->mac);
  407. if (mac) {
  408. ESP_LOGD(
  409. TAG, "WIFI_EVENT_AP_PROBEREQRECVED. RSSI: %d, MAC: %s", s->rssi, STR_OR_BLANK(mac));
  410. }
  411. FREE_AND_NULL(mac);
  412. } break;
  413. case WIFI_EVENT_STA_WPS_ER_SUCCESS:
  414. ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_SUCCESS");
  415. break;
  416. case WIFI_EVENT_STA_WPS_ER_FAILED:
  417. ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_FAILED");
  418. break;
  419. case WIFI_EVENT_STA_WPS_ER_TIMEOUT:
  420. ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_TIMEOUT");
  421. break;
  422. case WIFI_EVENT_STA_WPS_ER_PIN:
  423. ESP_LOGD(TAG, "WIFI_EVENT_STA_WPS_ER_PIN");
  424. break;
  425. case WIFI_EVENT_AP_STACONNECTED: {
  426. wifi_event_ap_staconnected_t* stac = (wifi_event_ap_staconnected_t*)event_data;
  427. char* mac = network_manager_alloc_get_mac_string(stac->mac);
  428. if (mac) {
  429. ESP_LOGD(
  430. TAG, "WIFI_EVENT_AP_STACONNECTED. aid: %d, mac: %s", stac->aid, STR_OR_BLANK(mac));
  431. }
  432. FREE_AND_NULL(mac);
  433. } break;
  434. case WIFI_EVENT_AP_STADISCONNECTED:
  435. ESP_LOGD(TAG, "WIFI_EVENT_AP_STADISCONNECTED");
  436. break;
  437. case WIFI_EVENT_STA_START:
  438. ESP_LOGD(TAG, "WIFI_EVENT_STA_START");
  439. break;
  440. case WIFI_EVENT_STA_STOP:
  441. ESP_LOGD(TAG, "WIFI_EVENT_STA_STOP");
  442. break;
  443. case WIFI_EVENT_STA_CONNECTED: {
  444. ESP_LOGD(TAG, "WIFI_EVENT_STA_CONNECTED. ");
  445. wifi_event_sta_connected_t* s = (wifi_event_sta_connected_t*)event_data;
  446. char* bssid = network_manager_alloc_get_mac_string(s->bssid);
  447. char* ssid = strdup_psram((char*)s->ssid);
  448. if (bssid && ssid) {
  449. ESP_LOGD(TAG, "WIFI_EVENT_STA_CONNECTED. Channel: %d, Access point: %s, BSSID: %s ",
  450. s->channel, STR_OR_BLANK(ssid), (bssid));
  451. network_wifi_update_connected(ssid);
  452. }
  453. FREE_AND_NULL(bssid);
  454. FREE_AND_NULL(ssid);
  455. network_async(EN_CONNECTED);
  456. } break;
  457. case WIFI_EVENT_STA_DISCONNECTED: {
  458. // structwifi_event_sta_disconnected_t
  459. // Argument structure for WIFI_EVENT_STA_DISCONNECTED event
  460. //
  461. // Public Members
  462. //
  463. // uint8_t ssid[32]
  464. // SSID of disconnected AP
  465. //
  466. // uint8_t ssid_len
  467. // SSID length of disconnected AP
  468. //
  469. // uint8_t bssid[6]
  470. // BSSID of disconnected AP
  471. //
  472. // uint8_t reason
  473. // reason of disconnection
  474. wifi_event_sta_disconnected_t* s = (wifi_event_sta_disconnected_t*)event_data;
  475. char* bssid = network_manager_alloc_get_mac_string(s->bssid);
  476. ESP_LOGW(TAG, "WIFI_EVENT_STA_DISCONNECTED. From BSSID: %s, reason code: %d (%s)",
  477. STR_OR_BLANK(bssid), s->reason, get_disconnect_code_desc(s->reason));
  478. FREE_AND_NULL(bssid);
  479. if (s->reason == WIFI_REASON_ROAMING) {
  480. ESP_LOGI(TAG, "WiFi Roaming to new access point");
  481. } else {
  482. network_async_lost_connection((wifi_event_sta_disconnected_t*)event_data);
  483. }
  484. } break;
  485. default:
  486. break;
  487. }
  488. }
  489. void network_wifi_write_file(const char * filename, sys_Status * status_struct){
  490. FILE* file = open_file("wb", filename);
  491. pb_ostream_t filestream = {&out_file_binding, file, SIZE_MAX, 0};
  492. ESP_LOGD(TAG, "Starting encode");
  493. if (!pb_encode(&filestream, sys_Config_fields, (void*)&status)) {
  494. ESP_LOGE(TAG, "Encoding failed: %s\n", PB_GET_ERROR(&filestream));
  495. }
  496. fclose(file);
  497. }
  498. void network_wifi_global_init() {
  499. pb_istream_t istream =PB_ISTREAM_EMPTY;
  500. ESP_LOGD(TAG, "Loading existing wifi configuration (if any)");
  501. FILE* file = open_file("rb", status_file_name);
  502. if (!file) {
  503. network_wifi_write_file(status_file_name,&status);
  504. file = open_file("rb", status_file_name);
  505. }
  506. if (!file) {
  507. ESP_LOGE(TAG, "Unable to read status file");
  508. return;
  509. }
  510. istream.callback = &in_file_binding;
  511. istream.state = file;
  512. pb_decode(&istream, &sys_Status_msg, &status);
  513. fclose(file);
  514. }
  515. esp_netif_t* network_wifi_config_ap() {
  516. esp_netif_ip_info_t info;
  517. esp_err_t err = ESP_OK;
  518. wifi_config_t ap_config = {
  519. .ap = {.ssid_len = 0,
  520. .authmode = AP_AUTHMODE,
  521. .ssid_hidden = DEFAULT_AP_SSID_HIDDEN,
  522. .max_connection = DEFAULT_AP_MAX_CONNECTIONS,
  523. .beacon_interval = DEFAULT_AP_BEACON_INTERVAL
  524. },
  525. };
  526. ESP_LOGI(TAG, "Configuring Access Point.");
  527. if (!wifi_ap_netif) {
  528. wifi_ap_netif = esp_netif_create_default_wifi_ap();
  529. }
  530. if (platform->has_net && platform->net.has_ap && platform->net.ap.has_ip) {
  531. inet_pton(AF_INET, platform->net.ap.ip.ip,
  532. (ip4_addr_t*)&info.ip); /* access point is on a static IP */
  533. inet_pton(AF_INET, platform->net.ap.ip.gw,
  534. (ip4_addr_t*)&info.gw); /* access point is on a static IP */
  535. inet_pton(AF_INET, platform->net.ap.ip.netmask,
  536. (ip4_addr_t*)&info.netmask); /* access point is on a static IP */
  537. } else {
  538. inet_pton(
  539. AF_INET, DEFAULT_AP_IP, (ip4_addr_t*)&info.ip); /* access point is on a static IP */
  540. inet_pton(AF_INET, CONFIG_DEFAULT_AP_GATEWAY,
  541. (ip4_addr_t*)&info.gw); /* access point is on a static IP */
  542. inet_pton(AF_INET, CONFIG_DEFAULT_AP_NETMASK,
  543. (ip4_addr_t*)&info.netmask); /* access point is on a st */
  544. }
  545. /* In order to change the IP info structure, we have to first stop
  546. * the DHCP server on the new interface
  547. */
  548. network_start_stop_dhcps(wifi_ap_netif, false);
  549. ESP_LOGD(TAG, "Setting tcp_ip info for access point");
  550. if ((err = esp_netif_set_ip_info(wifi_ap_netif, &info)) != ESP_OK) {
  551. ESP_LOGE(TAG, "Setting tcp_ip info for interface TCPIP_ADAPTER_IF_AP. Error %s",
  552. esp_err_to_name(err));
  553. return wifi_ap_netif;
  554. }
  555. network_start_stop_dhcps(wifi_ap_netif, true);
  556. /*
  557. * Set Access Point configuration
  558. */
  559. const char* ap_ssid = CONFIG_DEFAULT_AP_SSID;
  560. if (platform->has_names && strlen(platform->names.wifi_ap_name) > 0) {
  561. ap_ssid = platform->names.wifi_ap_name;
  562. }
  563. const char* ap_password = DEFAULT_AP_PASSWORD;
  564. ap_config.ap.channel = CONFIG_DEFAULT_AP_CHANNEL;
  565. if (platform->has_net && platform->net.has_ap) {
  566. if (strlen(platform->net.ap.password) > 0) {
  567. ap_password = platform->net.ap.password;
  568. }
  569. if (platform->net.ap.channel > 0) {
  570. ap_config.ap.channel = platform->net.ap.channel;
  571. }
  572. if (platform->net.ap.auth_mode != sys_WifiAuthTypeEnum_AUTH_UNKNOWN) {
  573. ap_config.ap.authmode = network_wifi_get_auth_mode(platform->net.ap.auth_mode);
  574. }
  575. ap_config.ap.ssid_hidden = platform->net.ap.hidden;
  576. if (platform->net.ap.max_connection > 0) {
  577. ap_config.ap.max_connection = platform->net.ap.max_connection;
  578. }
  579. if (platform->net.ap.beacon_interval > 0) {
  580. ap_config.ap.beacon_interval = platform->net.ap.beacon_interval;
  581. }
  582. }
  583. strlcpy((char*)ap_config.ap.ssid, ap_ssid, sizeof(ap_config.ap.ssid));
  584. strlcpy((char*)ap_config.ap.password, ap_password, sizeof(ap_config.ap.password));
  585. ESP_LOGI(TAG,
  586. "AP SSID: %s, PASSWORD: %s Auth Mode: %d SSID: %s Max Connections: %d Beacon interval: %d",
  587. (char*)ap_config.ap.ssid, (char*)ap_config.ap.password, ap_config.ap.authmode,
  588. ap_config.ap.ssid_hidden ? "HIDDEN" : "VISIBLE", ap_config.ap.max_connection,
  589. ap_config.ap.beacon_interval);
  590. const char* msg = "Setting wifi mode as WIFI_MODE_APSTA";
  591. ESP_LOGD(TAG, "%s", msg);
  592. if ((err = esp_wifi_set_mode(WIFI_MODE_APSTA)) != ESP_OK) {
  593. ESP_LOGE(TAG, "%s. Error %s", msg, esp_err_to_name(err));
  594. return wifi_ap_netif;
  595. }
  596. msg = "Setting wifi AP configuration for WIFI_IF_AP";
  597. ESP_LOGD(TAG, "%s", msg);
  598. if ((err = esp_wifi_set_config(WIFI_IF_AP, &ap_config)) != ESP_OK) /* stop AP DHCP server */
  599. {
  600. ESP_LOGE(TAG, "%s . Error %s", msg, esp_err_to_name(err));
  601. return wifi_ap_netif;
  602. }
  603. msg = "Setting wifi bandwidth";
  604. ESP_LOGD(TAG, "%s (%d)", msg, DEFAULT_AP_BANDWIDTH);
  605. if ((err = esp_wifi_set_bandwidth(WIFI_IF_AP, DEFAULT_AP_BANDWIDTH)) != ESP_OK) /* stop AP
  606. DHCP server */
  607. {
  608. ESP_LOGE(TAG, "%s failed. Error %s", msg, esp_err_to_name(err));
  609. return wifi_ap_netif;
  610. }
  611. msg = "Setting wifi power save";
  612. ESP_LOGD(TAG, "%s (%d)", msg, DEFAULT_STA_POWER_SAVE);
  613. if ((err = esp_wifi_set_ps(DEFAULT_STA_POWER_SAVE)) != ESP_OK) /* stop AP DHCP server */
  614. {
  615. ESP_LOGE(TAG, "%s failed. Error %s", msg, esp_err_to_name(err));
  616. return wifi_ap_netif;
  617. }
  618. ESP_LOGD(TAG, "Done configuring Soft Access Point");
  619. return wifi_ap_netif;
  620. }
  621. void network_wifi_filter_unique(wifi_ap_record_t* aplist, uint16_t* aps) {
  622. int total_unique;
  623. wifi_ap_record_t* first_free;
  624. total_unique = *aps;
  625. first_free = NULL;
  626. for (int i = 0; i < *aps - 1; i++) {
  627. wifi_ap_record_t* ap = &aplist[i];
  628. /* skip the previously removed APs */
  629. if (ap->ssid[0] == 0) continue;
  630. /* remove the identical SSID+authmodes */
  631. for (int j = i + 1; j < *aps; j++) {
  632. wifi_ap_record_t* ap1 = &aplist[j];
  633. if ((strcmp((const char*)ap->ssid, (const char*)ap1->ssid) == 0) &&
  634. (ap->authmode == ap1->authmode)) { /* same SSID, different auth mode is skipped */
  635. /* save the rssi for the display */
  636. if ((ap1->rssi) > (ap->rssi)) ap->rssi = ap1->rssi;
  637. /* clearing the record */
  638. memset(ap1, 0, sizeof(wifi_ap_record_t));
  639. }
  640. }
  641. }
  642. /* reorder the list so APs follow each other in the list */
  643. for (int i = 0; i < *aps; i++) {
  644. wifi_ap_record_t* ap = &aplist[i];
  645. /* skipping all that has no name */
  646. if (ap->ssid[0] == 0) {
  647. /* mark the first free slot */
  648. if (first_free == NULL) first_free = ap;
  649. total_unique--;
  650. continue;
  651. }
  652. if (first_free != NULL) {
  653. memcpy(first_free, ap, sizeof(wifi_ap_record_t));
  654. memset(ap, 0, sizeof(wifi_ap_record_t));
  655. /* find the next free slot */
  656. for (int j = 0; j < *aps; j++) {
  657. if (aplist[j].ssid[0] == 0) {
  658. first_free = &aplist[j];
  659. break;
  660. }
  661. }
  662. }
  663. }
  664. /* update the length of the list */
  665. *aps = total_unique;
  666. }
  667. void network_wifi_clear_scan_results() {
  668. if (!status.net.wifi.scan_result || status.net.wifi.scan_result_count == 0) {
  669. return;
  670. }
  671. free(status.net.wifi.scan_result);
  672. status.net.wifi.scan_result = NULL;
  673. status.net.wifi.scan_result_count = 0;
  674. }
  675. sys_WifiSTAEntry* network_wifi_alloc_scan_results(uint16_t count) {
  676. network_wifi_clear_scan_results();
  677. status.net.wifi.scan_result = malloc_init_external(count * sizeof(sys_WifiSTAEntry));
  678. status.net.wifi.scan_result_count = count;
  679. return status.net.wifi.scan_result;
  680. }
  681. void network_wifi_esp_sta_to_sta(wifi_ap_record_t* scan_res, sys_WifiSTAEntry* sta_entry) {
  682. if(!sta_entry){
  683. return;
  684. }
  685. sta_entry->radio_type = network_wifi_get_radio_type(scan_res);
  686. sta_entry->auth_type = network_wifi_get_auth_type(scan_res->authmode);
  687. network_wifi_format_bssid(sta_entry->bssid, sizeof(sta_entry->bssid), scan_res->bssid);
  688. sta_entry->channel = scan_res->primary;
  689. gettimeofday((struct timeval*)&sta_entry->last_seen, NULL);
  690. sta_entry->rssi = scan_res->rssi;
  691. strncpy(sta_entry->ssid, ap_ssid_string(scan_res), sizeof(sta_entry->ssid));
  692. // also update any existing credential entry if any
  693. network_wifi_esp_sta_to_sta(scan_res,network_wifi_get_ap_entry(sta_entry->ssid));
  694. }
  695. bool network_wifi_update_scan_list(wifi_ap_record_t* accessp_records, uint16_t count) {
  696. if (!network_wifi_alloc_scan_results(count)) {
  697. ESP_LOGE(TAG, "Error allocating memory to store scan results");
  698. return false;
  699. }
  700. // reset RSSI values. This will help when choosing the
  701. // strongest signal to connect to
  702. network_wifi_reset_rssi();
  703. for (int i = 0; i < status.net.wifi.scan_result_count; i++) {
  704. network_wifi_esp_sta_to_sta(&accessp_records[i], &status.net.wifi.scan_result[i]);
  705. }
  706. network_wifi_sort_strength();
  707. return true;
  708. }
  709. esp_err_t wifi_scan_done() {
  710. esp_err_t err = ESP_OK;
  711. wifi_ap_record_t* accessp_records = NULL;
  712. /* As input param, it stores max AP number ap_records can hold. As output param, it receives the
  713. * actual AP number this API returns. As a consequence, ap_num MUST be reset to MAX_AP_NUM at
  714. * every scan */
  715. ESP_LOGD(TAG, "Getting AP list records");
  716. uint16_t ap_num = MAX_AP_NUM;
  717. if ((err = esp_wifi_scan_get_ap_num(&ap_num)) != ESP_OK) {
  718. ESP_LOGE(TAG, "Failed to retrieve scan results count. Error %s", esp_err_to_name(err));
  719. return err;
  720. }
  721. if (ap_num <= 0) {
  722. ESP_LOGI(TAG, "No AP found during scan");
  723. return err;
  724. }
  725. accessp_records = (wifi_ap_record_t*)malloc_init_external(sizeof(wifi_ap_record_t) * ap_num);
  726. if (!accessp_records) {
  727. ESP_LOGE(TAG, "Alloc failed for scan results");
  728. return ESP_FAIL;
  729. }
  730. if ((err = esp_wifi_scan_get_ap_records(&ap_num, accessp_records)) != ESP_OK) {
  731. ESP_LOGE(TAG, "Failed to retrieve scan results list. Error %s", esp_err_to_name(err));
  732. } else {
  733. /* make sure the http server isn't trying to access the list while it gets refreshed */
  734. ESP_LOGD(TAG, "Retrieving scan list");
  735. /* Will remove the duplicate SSIDs from the list and update ap_num */
  736. network_wifi_filter_unique(accessp_records, &ap_num);
  737. if (network_status_lock_structure(pdMS_TO_TICKS(1000))) {
  738. network_wifi_update_scan_list(accessp_records, ap_num);
  739. network_status_unlock_structure();
  740. ESP_LOGD(TAG, "Done retrieving scan list");
  741. } else {
  742. ESP_LOGE(TAG, "could not get access to json mutex in wifi_scan");
  743. err = ESP_FAIL;
  744. }
  745. }
  746. free(accessp_records);
  747. return err;
  748. }
  749. bool is_wifi_up() { return wifi_netif != NULL; }
  750. esp_err_t network_wifi_start_scan() {
  751. wifi_scan_config_t scan_config = {.ssid = 0,
  752. .bssid = 0,
  753. .channel = 0,
  754. .scan_type = WIFI_SCAN_TYPE_ACTIVE,
  755. .show_hidden = true};
  756. esp_err_t err = ESP_OK;
  757. ESP_LOGI(TAG, "Initiating wifi network scan");
  758. if (!is_wifi_up()) {
  759. messaging_post_message(
  760. MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Cannot scan");
  761. return ESP_FAIL;
  762. }
  763. /* if a scan is already in progress this message is simply ignored thanks to the
  764. * WIFI_MANAGER_SCAN_BIT uxBit */
  765. if ((err = esp_wifi_scan_start(&scan_config, false)) != ESP_OK) {
  766. ESP_LOGW(TAG, "Unable to start scan; %s ", esp_err_to_name(err));
  767. // set_status_message(WARNING, "Wifi Connecting. Cannot start scan.");
  768. messaging_post_message(
  769. MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Scanning failed: %s", esp_err_to_name(err));
  770. }
  771. return err;
  772. }
  773. bool network_wifi_is_ap_mode() {
  774. wifi_mode_t mode;
  775. /* update config to latest and attempt connection */
  776. return esp_wifi_get_mode(&mode) == ESP_OK && mode == WIFI_MODE_AP;
  777. }
  778. bool network_wifi_is_sta_mode() {
  779. wifi_mode_t mode;
  780. /* update config to latest and attempt connection */
  781. return esp_wifi_get_mode(&mode) == ESP_OK && mode == WIFI_MODE_STA;
  782. }
  783. bool network_wifi_is_ap_sta_mode() {
  784. wifi_mode_t mode;
  785. /* update config to latest and attempt connection */
  786. return esp_wifi_get_mode(&mode) == ESP_OK && mode == WIFI_MODE_APSTA;
  787. }
  788. esp_err_t network_wifi_connect(const char* ssid, const char* password) {
  789. esp_err_t err = ESP_OK;
  790. wifi_config_t config;
  791. memset(&config, 0x00, sizeof(config));
  792. ESP_LOGD(TAG, "network_wifi_connect");
  793. network_wifi_reset_connected();
  794. if (!is_wifi_up()) {
  795. messaging_post_message(
  796. MESSAGING_WARNING, MESSAGING_CLASS_SYSTEM, "Wifi not started. Cannot connect");
  797. return ESP_FAIL;
  798. }
  799. if (!ssid || !password || strlen(ssid) == 0) {
  800. ESP_LOGE(TAG, "Cannot connect wifi. wifi config is null!");
  801. return ESP_ERR_INVALID_ARG;
  802. }
  803. wifi_mode_t wifi_mode;
  804. err = esp_wifi_get_mode(&wifi_mode);
  805. if (err == ESP_ERR_WIFI_NOT_INIT) {
  806. ESP_LOGW(TAG, "Wifi not initialized. Attempting to start sta mode");
  807. network_wifi_start();
  808. } else if (err != ESP_OK) {
  809. ESP_LOGE(TAG, "Could not retrieve wifi mode : %s", esp_err_to_name(err));
  810. } else if (wifi_mode != WIFI_MODE_STA && wifi_mode != WIFI_MODE_APSTA) {
  811. ESP_LOGD(TAG, "Changing wifi mode to STA");
  812. err = network_wifi_set_sta_mode();
  813. if (err != ESP_OK) {
  814. ESP_LOGE(TAG, "Could not set mode to STA. Cannot connect to SSID %s", ssid);
  815. return err;
  816. }
  817. }
  818. // copy configuration and connect
  819. strlcpy((char*)config.sta.ssid, ssid, sizeof(config.sta.ssid));
  820. if (password) {
  821. strlcpy((char*)config.sta.password, password, sizeof(config.sta.password));
  822. }
  823. // First Disconnect
  824. esp_wifi_disconnect();
  825. config.sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
  826. if ((err = esp_wifi_set_config(WIFI_IF_STA, &config)) != ESP_OK) {
  827. ESP_LOGE(TAG, "Failed to set STA configuration. Error %s", esp_err_to_name(err));
  828. }
  829. if (err == ESP_OK) {
  830. ESP_LOGI(TAG, "Wifi Connecting to %s...", ssid);
  831. if ((err = esp_wifi_connect()) != ESP_OK) {
  832. ESP_LOGE(TAG, "Failed to initiate wifi connection. Error %s", esp_err_to_name(err));
  833. }
  834. }
  835. return err;
  836. }
  837. esp_err_t network_wifi_connect_ssid(const char* ssid) {
  838. sys_WifiSTAEntry* item = network_wifi_get_ssid_info(ssid);
  839. if (item) {
  840. gettimeofday((struct timeval*)&item->last_try, NULL);
  841. return network_wifi_connect(item->ssid, item->password);
  842. }
  843. return ESP_FAIL;
  844. }
  845. esp_err_t network_wifi_connect_active_ssid() {
  846. sys_WifiSTAEntry*connected = NULL;
  847. if(status.has_net && platform->net.has_last_connected && strlen(platform->net.last_connected.ssid)>0){
  848. connected = &platform->net.last_connected.ssid;
  849. return network_wifi_connect(connected->ssid,connected->password);
  850. }
  851. return ESP_FAIL;
  852. }
  853. void network_wifi_clear_config() {
  854. /* erase configuration */
  855. const wifi_sta_config_t* sta = network_wifi_get_active_config();
  856. network_wifi_remove_ap_entry(ssid_string(sta));
  857. esp_err_t err = ESP_OK;
  858. if ((err = esp_wifi_disconnect()) != ESP_OK) {
  859. ESP_LOGW(TAG, "Could not disconnect from deleted network : %s", esp_err_to_name(err));
  860. }
  861. }
  862. char* get_disconnect_code_desc(uint8_t reason) {
  863. switch (reason) {
  864. ENUM_TO_STRING(WIFI_REASON_UNSPECIFIED);
  865. ENUM_TO_STRING(WIFI_REASON_AUTH_EXPIRE);
  866. ENUM_TO_STRING(WIFI_REASON_AUTH_LEAVE);
  867. ENUM_TO_STRING(WIFI_REASON_ASSOC_EXPIRE);
  868. ENUM_TO_STRING(WIFI_REASON_ASSOC_TOOMANY);
  869. ENUM_TO_STRING(WIFI_REASON_NOT_AUTHED);
  870. ENUM_TO_STRING(WIFI_REASON_NOT_ASSOCED);
  871. ENUM_TO_STRING(WIFI_REASON_ASSOC_LEAVE);
  872. ENUM_TO_STRING(WIFI_REASON_ASSOC_NOT_AUTHED);
  873. ENUM_TO_STRING(WIFI_REASON_DISASSOC_PWRCAP_BAD);
  874. ENUM_TO_STRING(WIFI_REASON_DISASSOC_SUPCHAN_BAD);
  875. ENUM_TO_STRING(WIFI_REASON_IE_INVALID);
  876. ENUM_TO_STRING(WIFI_REASON_MIC_FAILURE);
  877. ENUM_TO_STRING(WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT);
  878. ENUM_TO_STRING(WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT);
  879. ENUM_TO_STRING(WIFI_REASON_IE_IN_4WAY_DIFFERS);
  880. ENUM_TO_STRING(WIFI_REASON_GROUP_CIPHER_INVALID);
  881. ENUM_TO_STRING(WIFI_REASON_PAIRWISE_CIPHER_INVALID);
  882. ENUM_TO_STRING(WIFI_REASON_AKMP_INVALID);
  883. ENUM_TO_STRING(WIFI_REASON_UNSUPP_RSN_IE_VERSION);
  884. ENUM_TO_STRING(WIFI_REASON_INVALID_RSN_IE_CAP);
  885. ENUM_TO_STRING(WIFI_REASON_802_1X_AUTH_FAILED);
  886. ENUM_TO_STRING(WIFI_REASON_CIPHER_SUITE_REJECTED);
  887. ENUM_TO_STRING(WIFI_REASON_INVALID_PMKID);
  888. ENUM_TO_STRING(WIFI_REASON_BEACON_TIMEOUT);
  889. ENUM_TO_STRING(WIFI_REASON_NO_AP_FOUND);
  890. ENUM_TO_STRING(WIFI_REASON_AUTH_FAIL);
  891. ENUM_TO_STRING(WIFI_REASON_ASSOC_FAIL);
  892. ENUM_TO_STRING(WIFI_REASON_HANDSHAKE_TIMEOUT);
  893. ENUM_TO_STRING(WIFI_REASON_CONNECTION_FAIL);
  894. ENUM_TO_STRING(WIFI_REASON_AP_TSF_RESET);
  895. ENUM_TO_STRING(WIFI_REASON_ROAMING);
  896. }
  897. return "";
  898. }