1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - esp32 wifi -> lws_netdev_wifi 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 15d4afb5ceSopenharmony_ci * 16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 23d4afb5ceSopenharmony_ci * 24d4afb5ceSopenharmony_ci * 25d4afb5ceSopenharmony_ci * These are the esp platform wifi-specific netdev pieces. Nothing else should 26d4afb5ceSopenharmony_ci * know any esp-specific apis. 27d4afb5ceSopenharmony_ci * 28d4afb5ceSopenharmony_ci * Operations happen via the generic lws_detdev instantiation for the platform 29d4afb5ceSopenharmony_ci * wifi device, which point in here for operations. We also set up native OS 30d4afb5ceSopenharmony_ci * event hooks per device for wifi and IP stack events, and post them as lws_smd 31d4afb5ceSopenharmony_ci * NETWORK events on the if in the "platform private" namespace. We then 32d4afb5ceSopenharmony_ci * service the events in the lws event loop thread context, which may again 33d4afb5ceSopenharmony_ci * generate lws_smd NETWORK events in the public namespace depending on what 34d4afb5ceSopenharmony_ci * happened. 35d4afb5ceSopenharmony_ci * 36d4afb5ceSopenharmony_ci * Scan requests go through a sul to make sure we don't get "piling on" from 37d4afb5ceSopenharmony_ci * scheduled, timed scans. Scan results go through the lws_smd "washing" and 38d4afb5ceSopenharmony_ci * are actually parsed in lws thread context, where they are converted to lws 39d4afb5ceSopenharmony_ci * netdev scan results and processed by generic code. 40d4afb5ceSopenharmony_ci */ 41d4afb5ceSopenharmony_ci 42d4afb5ceSopenharmony_ci#include "private-lib-core.h" 43d4afb5ceSopenharmony_ci 44d4afb5ceSopenharmony_ci#include "esp_system.h" 45d4afb5ceSopenharmony_ci#include "esp_spi_flash.h" 46d4afb5ceSopenharmony_ci#include "esp_wifi.h" 47d4afb5ceSopenharmony_ci#include <nvs_flash.h> 48d4afb5ceSopenharmony_ci#include <esp_netif.h> 49d4afb5ceSopenharmony_ci 50d4afb5ceSopenharmony_ci/* 51d4afb5ceSopenharmony_ci * lws_netdev_instance_t: 52d4afb5ceSopenharmony_ci * lws_netdev_instance_wifi_t: 53d4afb5ceSopenharmony_ci * lws_netdev_instance_wifi_esp32_t 54d4afb5ceSopenharmony_ci */ 55d4afb5ceSopenharmony_ci 56d4afb5ceSopenharmony_citypedef struct lws_netdev_instance_wifi_esp32 { 57d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_t wnd; 58d4afb5ceSopenharmony_ci esp_event_handler_instance_t instance_any_id; 59d4afb5ceSopenharmony_ci esp_event_handler_instance_t instance_got_ip; 60d4afb5ceSopenharmony_ci wifi_config_t sta_config; 61d4afb5ceSopenharmony_ci} lws_netdev_instance_wifi_esp32_t; 62d4afb5ceSopenharmony_ci 63d4afb5ceSopenharmony_ci/* 64d4afb5ceSopenharmony_cistatic wifi_config_t config = { 65d4afb5ceSopenharmony_ci .ap = { 66d4afb5ceSopenharmony_ci .channel = 6, 67d4afb5ceSopenharmony_ci .authmode = WIFI_AUTH_OPEN, 68d4afb5ceSopenharmony_ci .max_connection = 1, 69d4afb5ceSopenharmony_ci } }; 70d4afb5ceSopenharmony_ci */ 71d4afb5ceSopenharmony_ci 72d4afb5ceSopenharmony_ci/* 73d4afb5ceSopenharmony_ci * Platform-specific connect / associate 74d4afb5ceSopenharmony_ci */ 75d4afb5ceSopenharmony_ci 76d4afb5ceSopenharmony_ciint 77d4afb5ceSopenharmony_cilws_netdev_wifi_connect_plat(lws_netdev_instance_t *nd, const char *ssid, 78d4afb5ceSopenharmony_ci const char *passphrase, uint8_t *bssid) 79d4afb5ceSopenharmony_ci{ 80d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_esp32_t *wnde32 = 81d4afb5ceSopenharmony_ci (lws_netdev_instance_wifi_esp32_t *)nd; 82d4afb5ceSopenharmony_ci 83d4afb5ceSopenharmony_ci wnde32->wnd.inst.ops->up(&wnde32->wnd.inst); 84d4afb5ceSopenharmony_ci 85d4afb5ceSopenharmony_ci wnde32->wnd.flags |= LNDIW_MODE_STA; 86d4afb5ceSopenharmony_ci esp_wifi_set_mode(WIFI_MODE_STA); 87d4afb5ceSopenharmony_ci 88d4afb5ceSopenharmony_ci#if 0 89d4afb5ceSopenharmony_ci /* we will do our own dhcp */ 90d4afb5ceSopenharmony_ci tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA); 91d4afb5ceSopenharmony_ci#endif 92d4afb5ceSopenharmony_ci 93d4afb5ceSopenharmony_ci lws_strncpy((char *)wnde32->sta_config.sta.ssid, ssid, 94d4afb5ceSopenharmony_ci sizeof(wnde32->sta_config.sta.ssid)); 95d4afb5ceSopenharmony_ci lws_strncpy((char *)wnde32->sta_config.sta.password, passphrase, 96d4afb5ceSopenharmony_ci sizeof(wnde32->sta_config.sta.password)); 97d4afb5ceSopenharmony_ci 98d4afb5ceSopenharmony_ci esp_wifi_set_config(WIFI_IF_STA, &wnde32->sta_config); 99d4afb5ceSopenharmony_ci esp_wifi_connect(); 100d4afb5ceSopenharmony_ci 101d4afb5ceSopenharmony_ci return 0; 102d4afb5ceSopenharmony_ci} 103d4afb5ceSopenharmony_ci 104d4afb5ceSopenharmony_ci/* 105d4afb5ceSopenharmony_ci * This is called from the SMD / lws thread context, after we heard there were 106d4afb5ceSopenharmony_ci * scan results on this netdev 107d4afb5ceSopenharmony_ci */ 108d4afb5ceSopenharmony_ci 109d4afb5ceSopenharmony_cistatic void 110d4afb5ceSopenharmony_cilws_esp32_scan_update(lws_netdev_instance_wifi_t *wnd) 111d4afb5ceSopenharmony_ci{ 112d4afb5ceSopenharmony_ci// lws_netdevs_t *netdevs = lws_netdevs_from_ndi(&wnd->inst); 113d4afb5ceSopenharmony_ci wifi_ap_record_t ap_records[LWS_WIFI_MAX_SCAN_TRACK], *ar; 114d4afb5ceSopenharmony_ci uint32_t now = lws_now_secs(); 115d4afb5ceSopenharmony_ci uint16_t count_ap_records; 116d4afb5ceSopenharmony_ci int n; 117d4afb5ceSopenharmony_ci 118d4afb5ceSopenharmony_ci count_ap_records = LWS_ARRAY_SIZE(ap_records); 119d4afb5ceSopenharmony_ci if (esp_wifi_scan_get_ap_records(&count_ap_records, ap_records)) { 120d4afb5ceSopenharmony_ci lwsl_err("%s: failed\n", __func__); 121d4afb5ceSopenharmony_ci return; 122d4afb5ceSopenharmony_ci } 123d4afb5ceSopenharmony_ci 124d4afb5ceSopenharmony_ci if (!count_ap_records) 125d4afb5ceSopenharmony_ci return; 126d4afb5ceSopenharmony_ci 127d4afb5ceSopenharmony_ci if (wnd->state != LWSNDVWIFI_STATE_SCAN) 128d4afb5ceSopenharmony_ci return; 129d4afb5ceSopenharmony_ci 130d4afb5ceSopenharmony_ci /* 131d4afb5ceSopenharmony_ci * ... let's collect the OS-specific scan results, and convert then to 132d4afb5ceSopenharmony_ci * lws_netdev sorted by rssi. If we already have it in the scan list, 133d4afb5ceSopenharmony_ci * keep it and keep a little ringbuffer of its rssi along with an 134d4afb5ceSopenharmony_ci * averaging. If it's new, add it into the linked-list sorted by rssi. 135d4afb5ceSopenharmony_ci */ 136d4afb5ceSopenharmony_ci 137d4afb5ceSopenharmony_ci ar = &ap_records[0]; 138d4afb5ceSopenharmony_ci for (n = 0; n < count_ap_records; n++) { 139d4afb5ceSopenharmony_ci lws_wifi_sta_t *w; 140d4afb5ceSopenharmony_ci int m; 141d4afb5ceSopenharmony_ci 142d4afb5ceSopenharmony_ci m = strlen((const char *)ar->ssid); 143d4afb5ceSopenharmony_ci if (!m) 144d4afb5ceSopenharmony_ci goto next; 145d4afb5ceSopenharmony_ci 146d4afb5ceSopenharmony_ci /* 147d4afb5ceSopenharmony_ci * We know this guy from before? 148d4afb5ceSopenharmony_ci */ 149d4afb5ceSopenharmony_ci 150d4afb5ceSopenharmony_ci w = lws_netdev_wifi_scan_find(wnd, (const char *)ar->ssid, 151d4afb5ceSopenharmony_ci ar->bssid); 152d4afb5ceSopenharmony_ci if (!w) { 153d4afb5ceSopenharmony_ci w = lws_zalloc(sizeof(*w) + m + 1, __func__); 154d4afb5ceSopenharmony_ci if (!w) 155d4afb5ceSopenharmony_ci goto next; 156d4afb5ceSopenharmony_ci 157d4afb5ceSopenharmony_ci w->ssid = (char *)&w[1]; 158d4afb5ceSopenharmony_ci memcpy(w->ssid, ar->ssid, m + 1); 159d4afb5ceSopenharmony_ci w->ssid_len = m; 160d4afb5ceSopenharmony_ci 161d4afb5ceSopenharmony_ci memcpy(w->bssid, ar->bssid, 6); 162d4afb5ceSopenharmony_ci 163d4afb5ceSopenharmony_ci lws_dll2_add_sorted(&w->list, &wnd->scan, 164d4afb5ceSopenharmony_ci lws_netdev_wifi_rssi_sort_compare); 165d4afb5ceSopenharmony_ci } 166d4afb5ceSopenharmony_ci 167d4afb5ceSopenharmony_ci if (w->rssi_count == LWS_ARRAY_SIZE(w->rssi)) 168d4afb5ceSopenharmony_ci w->rssi_avg -= w->rssi[w->rssi_next]; 169d4afb5ceSopenharmony_ci else 170d4afb5ceSopenharmony_ci w->rssi_count++; 171d4afb5ceSopenharmony_ci w->rssi[w->rssi_next] = ar->rssi; 172d4afb5ceSopenharmony_ci w->rssi_avg += w->rssi[w->rssi_next++]; 173d4afb5ceSopenharmony_ci w->rssi_next = w->rssi_next & (LWS_ARRAY_SIZE(w->rssi) - 1); 174d4afb5ceSopenharmony_ci 175d4afb5ceSopenharmony_ci w->ch = ar->primary; 176d4afb5ceSopenharmony_ci w->authmode = ar->authmode; 177d4afb5ceSopenharmony_ci w->last_seen = now; 178d4afb5ceSopenharmony_ci 179d4afb5ceSopenharmony_cinext: 180d4afb5ceSopenharmony_ci ar++; 181d4afb5ceSopenharmony_ci } 182d4afb5ceSopenharmony_ci 183d4afb5ceSopenharmony_ci /* 184d4afb5ceSopenharmony_ci * We can do the rest of it using the generic scan list and credentials 185d4afb5ceSopenharmony_ci */ 186d4afb5ceSopenharmony_ci 187d4afb5ceSopenharmony_ci lws_netdev_wifi_scan_select(wnd); 188d4afb5ceSopenharmony_ci} 189d4afb5ceSopenharmony_ci 190d4afb5ceSopenharmony_cistatic wifi_scan_config_t scan_config = { 191d4afb5ceSopenharmony_ci .ssid = 0, 192d4afb5ceSopenharmony_ci .bssid = 0, 193d4afb5ceSopenharmony_ci .channel = 0, 194d4afb5ceSopenharmony_ci .show_hidden = true 195d4afb5ceSopenharmony_ci}; 196d4afb5ceSopenharmony_ci 197d4afb5ceSopenharmony_civoid 198d4afb5ceSopenharmony_cilws_netdev_wifi_scan_plat(lws_netdev_instance_t *nd) 199d4afb5ceSopenharmony_ci{ 200d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)nd; 201d4afb5ceSopenharmony_ci 202d4afb5ceSopenharmony_ci if (esp_wifi_scan_start(&scan_config, false)) 203d4afb5ceSopenharmony_ci lwsl_err("%s: %s scan failed\n", __func__, wnd->inst.name); 204d4afb5ceSopenharmony_ci} 205d4afb5ceSopenharmony_ci 206d4afb5ceSopenharmony_ci/* 207d4afb5ceSopenharmony_ci * Platform-private interface events turn up here after going through SMD and 208d4afb5ceSopenharmony_ci * passed down by matching network interface name via generic lws_netdev. All 209d4afb5ceSopenharmony_ci * that messing around gets us from an OS-specific thread with an event to back 210d4afb5ceSopenharmony_ci * here in lws event loop thread context, with the same event bound to a the 211d4afb5ceSopenharmony_ci * netdev it belongs to. 212d4afb5ceSopenharmony_ci */ 213d4afb5ceSopenharmony_ci 214d4afb5ceSopenharmony_ciint 215d4afb5ceSopenharmony_cilws_netdev_wifi_event_plat(struct lws_netdev_instance *nd, lws_usec_t timestamp, 216d4afb5ceSopenharmony_ci void *buf, size_t len) 217d4afb5ceSopenharmony_ci{ 218d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)nd; 219d4afb5ceSopenharmony_ci struct lws_context *ctx = netdev_instance_to_ctx(&wnd->inst); 220d4afb5ceSopenharmony_ci size_t al; 221d4afb5ceSopenharmony_ci 222d4afb5ceSopenharmony_ci /* 223d4afb5ceSopenharmony_ci * netdev-private sync messages? 224d4afb5ceSopenharmony_ci */ 225d4afb5ceSopenharmony_ci 226d4afb5ceSopenharmony_ci if (!lws_json_simple_strcmp(buf, len, "\"type\":", "priv")) { 227d4afb5ceSopenharmony_ci const char *ev = lws_json_simple_find(buf, len, "\"ev\":", &al); 228d4afb5ceSopenharmony_ci 229d4afb5ceSopenharmony_ci if (!ev) 230d4afb5ceSopenharmony_ci return 0; 231d4afb5ceSopenharmony_ci 232d4afb5ceSopenharmony_ci lwsl_notice("%s: smd priv ev %.*s\n", __func__, (int)al, ev); 233d4afb5ceSopenharmony_ci 234d4afb5ceSopenharmony_ci switch (atoi(ev)) { 235d4afb5ceSopenharmony_ci case WIFI_EVENT_STA_START: 236d4afb5ceSopenharmony_ci wnd->state = LWSNDVWIFI_STATE_INITIAL; 237d4afb5ceSopenharmony_ci if (!lws_netdev_wifi_redo_last(wnd)) 238d4afb5ceSopenharmony_ci break; 239d4afb5ceSopenharmony_ci 240d4afb5ceSopenharmony_ci /* 241d4afb5ceSopenharmony_ci * if the "try last successful" one fails, start the 242d4afb5ceSopenharmony_ci * scan by falling through 243d4afb5ceSopenharmony_ci */ 244d4afb5ceSopenharmony_ci 245d4afb5ceSopenharmony_ci case WIFI_EVENT_STA_DISCONNECTED: 246d4afb5ceSopenharmony_ci lws_smd_msg_printf(ctx, LWSSMDCL_NETWORK, 247d4afb5ceSopenharmony_ci "{\"type\":\"linkdown\"," 248d4afb5ceSopenharmony_ci "\"if\":\"%s\"}", wnd->inst.name); 249d4afb5ceSopenharmony_ci wnd->state = LWSNDVWIFI_STATE_SCAN; 250d4afb5ceSopenharmony_ci /* 251d4afb5ceSopenharmony_ci * We do it via the sul so we don't get timed scans 252d4afb5ceSopenharmony_ci * on top of each other 253d4afb5ceSopenharmony_ci */ 254d4afb5ceSopenharmony_ci lws_sul_schedule(ctx, 0, &wnd->sul_scan, 255d4afb5ceSopenharmony_ci lws_netdev_wifi_scan, 1); 256d4afb5ceSopenharmony_ci break; 257d4afb5ceSopenharmony_ci 258d4afb5ceSopenharmony_ci case WIFI_EVENT_STA_CONNECTED: 259d4afb5ceSopenharmony_ci lws_smd_msg_printf(ctx, LWSSMDCL_NETWORK, 260d4afb5ceSopenharmony_ci "{\"type\":\"linkup\"," 261d4afb5ceSopenharmony_ci "\"if\":\"%s\"}", wnd->inst.name); 262d4afb5ceSopenharmony_ci break; 263d4afb5ceSopenharmony_ci 264d4afb5ceSopenharmony_ci case WIFI_EVENT_SCAN_DONE: 265d4afb5ceSopenharmony_ci lws_esp32_scan_update(wnd); 266d4afb5ceSopenharmony_ci break; 267d4afb5ceSopenharmony_ci default: 268d4afb5ceSopenharmony_ci return 0; 269d4afb5ceSopenharmony_ci } 270d4afb5ceSopenharmony_ci 271d4afb5ceSopenharmony_ci return 0; 272d4afb5ceSopenharmony_ci } 273d4afb5ceSopenharmony_ci 274d4afb5ceSopenharmony_ci return 0; 275d4afb5ceSopenharmony_ci} 276d4afb5ceSopenharmony_ci 277d4afb5ceSopenharmony_ci/* 278d4afb5ceSopenharmony_ci * This is coming from a thread context unrelated to lws... the first order is 279d4afb5ceSopenharmony_ci * to turn these into lws_smd events synchronized on lws thread, since we want 280d4afb5ceSopenharmony_ci * to change correspsonding lws netdev object states without locking. 281d4afb5ceSopenharmony_ci */ 282d4afb5ceSopenharmony_ci 283d4afb5ceSopenharmony_cistatic void 284d4afb5ceSopenharmony_ci_event_handler_wifi(void *arg, esp_event_base_t event_base, int32_t event_id, 285d4afb5ceSopenharmony_ci void *event_data) 286d4afb5ceSopenharmony_ci{ 287d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)arg; 288d4afb5ceSopenharmony_ci struct lws_context *ctx = netdev_instance_to_ctx(&wnd->inst); 289d4afb5ceSopenharmony_ci 290d4afb5ceSopenharmony_ci switch (event_id) { 291d4afb5ceSopenharmony_ci case WIFI_EVENT_STA_START: 292d4afb5ceSopenharmony_ci case WIFI_EVENT_STA_DISCONNECTED: 293d4afb5ceSopenharmony_ci case WIFI_EVENT_SCAN_DONE: 294d4afb5ceSopenharmony_ci case WIFI_EVENT_STA_CONNECTED: 295d4afb5ceSopenharmony_ci /* 296d4afb5ceSopenharmony_ci * These are events in the platform's private namespace, 297d4afb5ceSopenharmony_ci * interpreted only by the lws_smd handler above, ** in the lws 298d4afb5ceSopenharmony_ci * event thread context **. The point of this is to requeue the 299d4afb5ceSopenharmony_ci * event in the lws thread context like a bottom-half. 300d4afb5ceSopenharmony_ci * 301d4afb5ceSopenharmony_ci * To save on registrations, the context's NETWORK smd 302d4afb5ceSopenharmony_ci * participant passes messages to lws_netdev, who passes ones 303d4afb5ceSopenharmony_ci * that have if matching the netdev name to that netdev's 304d4afb5ceSopenharmony_ci * (*event) handler. 305d4afb5ceSopenharmony_ci * 306d4afb5ceSopenharmony_ci * The other handler may emit generic network state SMD events 307d4afb5ceSopenharmony_ci * for other things to consume. 308d4afb5ceSopenharmony_ci */ 309d4afb5ceSopenharmony_ci 310d4afb5ceSopenharmony_ci lws_smd_msg_printf(ctx, LWSSMDCL_NETWORK, 311d4afb5ceSopenharmony_ci "{\"type\":\"priv\",\"if\":\"%s\",\"ev\":%d}", 312d4afb5ceSopenharmony_ci wnd->inst.name, (int)event_id); 313d4afb5ceSopenharmony_ci break; 314d4afb5ceSopenharmony_ci default: 315d4afb5ceSopenharmony_ci return; 316d4afb5ceSopenharmony_ci } 317d4afb5ceSopenharmony_ci} 318d4afb5ceSopenharmony_ci 319d4afb5ceSopenharmony_ci#if 0 320d4afb5ceSopenharmony_cistatic int 321d4afb5ceSopenharmony_ciespip_to_sa46(lws_sockaddr46 *sa46, esp_ip_addr_t *eip) 322d4afb5ceSopenharmony_ci{ 323d4afb5ceSopenharmony_ci memset(sa46, 0, sizeof(sa46)); 324d4afb5ceSopenharmony_ci 325d4afb5ceSopenharmony_ci switch (eip->type) { 326d4afb5ceSopenharmony_ci case ESP_IPADDR_TYPE_V4: 327d4afb5ceSopenharmony_ci sa46->sa4.sin_family = AF_INET; 328d4afb5ceSopenharmony_ci memcpy(sa46->sa4.sin_addr, &eip->u_addr.ip4.addr, ); 329d4afb5ceSopenharmony_ci return; 330d4afb5ceSopenharmony_ci case ESP_IPADDR_TYPE_V6: 331d4afb5ceSopenharmony_ci } 332d4afb5ceSopenharmony_ci} 333d4afb5ceSopenharmony_ci#endif 334d4afb5ceSopenharmony_ci 335d4afb5ceSopenharmony_ci/* 336d4afb5ceSopenharmony_ci * This is coming from a thread context unrelated to lws 337d4afb5ceSopenharmony_ci */ 338d4afb5ceSopenharmony_ci 339d4afb5ceSopenharmony_cistatic void 340d4afb5ceSopenharmony_ci_event_handler_ip(void *arg, esp_event_base_t event_base, int32_t event_id, 341d4afb5ceSopenharmony_ci void *event_data) 342d4afb5ceSopenharmony_ci{ 343d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_t *wnd = (lws_netdev_instance_wifi_t *)arg; 344d4afb5ceSopenharmony_ci lws_netdevs_t *netdevs = lws_netdevs_from_ndi(&wnd->inst); 345d4afb5ceSopenharmony_ci struct lws_context *ctx = lws_context_from_netdevs(netdevs); 346d4afb5ceSopenharmony_ci 347d4afb5ceSopenharmony_ci if (event_id == IP_EVENT_STA_GOT_IP) { 348d4afb5ceSopenharmony_ci ip_event_got_ip_t *e = (ip_event_got_ip_t *)event_data; 349d4afb5ceSopenharmony_ci char ip[16]; 350d4afb5ceSopenharmony_ci#if 0 351d4afb5ceSopenharmony_ci tcpip_adapter_dns_info_t e32ip; 352d4afb5ceSopenharmony_ci 353d4afb5ceSopenharmony_ci /* 354d4afb5ceSopenharmony_ci * Since atm we get this via DHCP, presumably we can get ahold 355d4afb5ceSopenharmony_ci * of related info set by the router 356d4afb5ceSopenharmony_ci */ 357d4afb5ceSopenharmony_ci 358d4afb5ceSopenharmony_ci if (tcpip_adapter_get_dns_info(TCPIP_ADAPTER_IF_STA, 359d4afb5ceSopenharmony_ci TCPIP_ADAPTER_DNS_MAIN, 360d4afb5ceSopenharmony_ci /* also _BACKUP, _FALLBACK */ 361d4afb5ceSopenharmony_ci &e32ip)) { 362d4afb5ceSopenharmony_ci lwsl_err("%s: there's no dns server set\n", __func__); 363d4afb5ceSopenharmony_ci e32ip.ip.u_addr.ipv4 = 0x08080808; 364d4afb5ceSopenharmony_ci e32ip.ip.type = ESP_IPADDR_TYPE_V4; 365d4afb5ceSopenharmony_ci } 366d4afb5ceSopenharmony_ci 367d4afb5ceSopenharmony_ci netdevs->sa46_dns_resolver. 368d4afb5ceSopenharmony_ci#endif 369d4afb5ceSopenharmony_ci 370d4afb5ceSopenharmony_ci lws_write_numeric_address((void *)&e->ip_info.ip, 4, ip, 371d4afb5ceSopenharmony_ci sizeof(ip)); 372d4afb5ceSopenharmony_ci lws_smd_msg_printf(ctx, LWSSMDCL_NETWORK, 373d4afb5ceSopenharmony_ci "{\"type\":\"ipacq\",\"if\":\"%s\"," 374d4afb5ceSopenharmony_ci "\"ipv4\":\"%s\"}", wnd->inst.name, ip); 375d4afb5ceSopenharmony_ci } 376d4afb5ceSopenharmony_ci} 377d4afb5ceSopenharmony_ci 378d4afb5ceSopenharmony_ci/* 379d4afb5ceSopenharmony_ci * This is the platform (esp-idf) init for any kind of networking to be 380d4afb5ceSopenharmony_ci * available at all 381d4afb5ceSopenharmony_ci */ 382d4afb5ceSopenharmony_ciint 383d4afb5ceSopenharmony_cilws_netdev_plat_init(void) 384d4afb5ceSopenharmony_ci{ 385d4afb5ceSopenharmony_ci nvs_flash_init(); 386d4afb5ceSopenharmony_ci esp_netif_init(); 387d4afb5ceSopenharmony_ci ESP_ERROR_CHECK(esp_event_loop_create_default()); 388d4afb5ceSopenharmony_ci 389d4afb5ceSopenharmony_ci return 0; 390d4afb5ceSopenharmony_ci} 391d4afb5ceSopenharmony_ci 392d4afb5ceSopenharmony_ci/* 393d4afb5ceSopenharmony_ci * This is the platform (esp-idf) init for any wifi to be available at all 394d4afb5ceSopenharmony_ci */ 395d4afb5ceSopenharmony_ciint 396d4afb5ceSopenharmony_cilws_netdev_plat_wifi_init(void) 397d4afb5ceSopenharmony_ci{ 398d4afb5ceSopenharmony_ci wifi_init_config_t wic = WIFI_INIT_CONFIG_DEFAULT(); 399d4afb5ceSopenharmony_ci int n; 400d4afb5ceSopenharmony_ci 401d4afb5ceSopenharmony_ci esp_netif_create_default_wifi_sta(); 402d4afb5ceSopenharmony_ci 403d4afb5ceSopenharmony_ci n = esp_wifi_init(&wic); 404d4afb5ceSopenharmony_ci if (n) { 405d4afb5ceSopenharmony_ci lwsl_err("%s: wifi init fail: %d\n", __func__, n); 406d4afb5ceSopenharmony_ci return 1; 407d4afb5ceSopenharmony_ci } 408d4afb5ceSopenharmony_ci 409d4afb5ceSopenharmony_ci return 0; 410d4afb5ceSopenharmony_ci} 411d4afb5ceSopenharmony_ci 412d4afb5ceSopenharmony_ci 413d4afb5ceSopenharmony_cistruct lws_netdev_instance * 414d4afb5ceSopenharmony_cilws_netdev_wifi_create_plat(struct lws_context *ctx, 415d4afb5ceSopenharmony_ci const lws_netdev_ops_t *ops, 416d4afb5ceSopenharmony_ci const char *name, void *platinfo) 417d4afb5ceSopenharmony_ci{ 418d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_esp32_t *wnde32 = lws_zalloc( 419d4afb5ceSopenharmony_ci sizeof(*wnde32), __func__); 420d4afb5ceSopenharmony_ci 421d4afb5ceSopenharmony_ci if (!wnde32) 422d4afb5ceSopenharmony_ci return NULL; 423d4afb5ceSopenharmony_ci 424d4afb5ceSopenharmony_ci wnde32->wnd.inst.type = LWSNDTYP_WIFI; 425d4afb5ceSopenharmony_ci lws_netdev_instance_create(&wnde32->wnd.inst, ctx, ops, name, platinfo); 426d4afb5ceSopenharmony_ci 427d4afb5ceSopenharmony_ci return &wnde32->wnd.inst; 428d4afb5ceSopenharmony_ci} 429d4afb5ceSopenharmony_ci 430d4afb5ceSopenharmony_ciint 431d4afb5ceSopenharmony_cilws_netdev_wifi_configure_plat(struct lws_netdev_instance *nd, 432d4afb5ceSopenharmony_ci lws_netdev_config_t *config) 433d4afb5ceSopenharmony_ci{ 434d4afb5ceSopenharmony_ci return 0; 435d4afb5ceSopenharmony_ci} 436d4afb5ceSopenharmony_ci 437d4afb5ceSopenharmony_ciint 438d4afb5ceSopenharmony_cilws_netdev_wifi_up_plat(struct lws_netdev_instance *nd) 439d4afb5ceSopenharmony_ci{ 440d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_esp32_t *wnde32 = 441d4afb5ceSopenharmony_ci (lws_netdev_instance_wifi_esp32_t *)nd; 442d4afb5ceSopenharmony_ci struct lws_context *ctx = netdev_instance_to_ctx(&wnde32->wnd.inst); 443d4afb5ceSopenharmony_ci 444d4afb5ceSopenharmony_ci if (wnde32->wnd.flags & LNDIW_UP) 445d4afb5ceSopenharmony_ci return 0; 446d4afb5ceSopenharmony_ci 447d4afb5ceSopenharmony_ci ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, 448d4afb5ceSopenharmony_ci IP_EVENT_STA_GOT_IP, &_event_handler_ip, nd, 449d4afb5ceSopenharmony_ci &wnde32->instance_got_ip)); 450d4afb5ceSopenharmony_ci 451d4afb5ceSopenharmony_ci ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, 452d4afb5ceSopenharmony_ci ESP_EVENT_ANY_ID, &_event_handler_wifi, nd, 453d4afb5ceSopenharmony_ci &wnde32->instance_any_id)); 454d4afb5ceSopenharmony_ci 455d4afb5ceSopenharmony_ci esp_wifi_start(); 456d4afb5ceSopenharmony_ci wnde32->wnd.flags |= LNDIW_UP; 457d4afb5ceSopenharmony_ci 458d4afb5ceSopenharmony_ci lws_smd_msg_printf(ctx, LWSSMDCL_NETWORK, 459d4afb5ceSopenharmony_ci "{\"type\":\"up\",\"if\":\"%s\"}", 460d4afb5ceSopenharmony_ci wnde32->wnd.inst.name); 461d4afb5ceSopenharmony_ci 462d4afb5ceSopenharmony_ci return 0; 463d4afb5ceSopenharmony_ci} 464d4afb5ceSopenharmony_ci 465d4afb5ceSopenharmony_ciint 466d4afb5ceSopenharmony_cilws_netdev_wifi_down_plat(struct lws_netdev_instance *nd) 467d4afb5ceSopenharmony_ci{ 468d4afb5ceSopenharmony_ci lws_netdev_instance_wifi_esp32_t *wnde32 = 469d4afb5ceSopenharmony_ci (lws_netdev_instance_wifi_esp32_t *)nd; 470d4afb5ceSopenharmony_ci struct lws_context *ctx = netdev_instance_to_ctx(&wnde32->wnd.inst); 471d4afb5ceSopenharmony_ci 472d4afb5ceSopenharmony_ci if (!(wnde32->wnd.flags & LNDIW_UP)) 473d4afb5ceSopenharmony_ci return 0; 474d4afb5ceSopenharmony_ci 475d4afb5ceSopenharmony_ci lws_smd_msg_printf(ctx, LWSSMDCL_NETWORK, 476d4afb5ceSopenharmony_ci "{\"type\":\"down\",\"if\":\"%s\"}", 477d4afb5ceSopenharmony_ci wnde32->wnd.inst.name); 478d4afb5ceSopenharmony_ci 479d4afb5ceSopenharmony_ci esp_wifi_stop(); 480d4afb5ceSopenharmony_ci 481d4afb5ceSopenharmony_ci esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, 482d4afb5ceSopenharmony_ci &wnde32->instance_got_ip); 483d4afb5ceSopenharmony_ci esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, 484d4afb5ceSopenharmony_ci &wnde32->instance_any_id); 485d4afb5ceSopenharmony_ci 486d4afb5ceSopenharmony_ci wnde32->wnd.flags &= ~LNDIW_UP; 487d4afb5ceSopenharmony_ci 488d4afb5ceSopenharmony_ci return 0; 489d4afb5ceSopenharmony_ci} 490d4afb5ceSopenharmony_ci 491d4afb5ceSopenharmony_civoid 492d4afb5ceSopenharmony_cilws_netdev_wifi_destroy_plat(struct lws_netdev_instance **pnd) 493d4afb5ceSopenharmony_ci{ 494d4afb5ceSopenharmony_ci lws_free(*pnd); 495d4afb5ceSopenharmony_ci *pnd = NULL; 496d4afb5ceSopenharmony_ci} 497