#include "wifi_event_handler.h" #include #include #include #include #include #include #include "ssdp.h" #include "wifi_configuration.h" #define TAG __FILE_NAME__ void event_on_connected(ip_event_got_ip_t *event); void ip_event_handler(void *handler_arg __attribute__((unused)), esp_event_base_t event_base __attribute__((unused)), int32_t event_id, void *event_data) { switch (event_id) { case IP_EVENT_STA_GOT_IP: { ip_event_got_ip_t *event = event_data; printf("STA GOT IP : %s\n", ip4addr_ntoa((const ip4_addr_t *) &event->ip_info.ip)); event_on_connected(event); ssdp_set_ip_gw(&event->ip_info.ip.addr, &event->ip_info.gw.addr); break; } case IP_EVENT_STA_LOST_IP: { printf("sta lost ip\n"); ip4_addr_t ip; ip4_addr_t gw; IP4_ADDR_EXPAND(&ip, WIFI_DEFAULT_AP_IP); IP4_ADDR_EXPAND(&gw, WIFI_DEFAULT_AP_GATEWAY); ssdp_set_ip_gw(&ip.addr, &gw.addr); break; } case IP_EVENT_AP_STAIPASSIGNED: printf("event STAIPASSIGNED\n"); break; case IP_EVENT_GOT_IP6: #ifdef CONFIG_EXAMPLE_IPV6 xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); printf("SYSTEM_EVENT_STA_GOT_IP6\r\n"); char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip); printf("IPv6: %s\r\n", ip6); #endif case IP_EVENT_ETH_GOT_IP: case IP_EVENT_ETH_LOST_IP: case IP_EVENT_PPP_GOT_IP: case IP_EVENT_PPP_LOST_IP: default: break; } } typedef struct wifi_event_ctx_t { /* WIFI scan */ struct { wifi_ap_record_t *ap; wifi_event_scan_done_cb cb; uint16_t number; }; /* WIFI connect */ struct { wifi_event_connect_done_cb cb; void *arg; void (*disconn_handler)(void); uint8_t attempt; } conn; uint8_t is_connected; } wifi_event_ctx_t; static wifi_event_ctx_t event_ctx = { .ap = NULL, .is_connected = 0, .conn.disconn_handler = NULL, }; static void wifi_on_scan_done(wifi_event_sta_scan_done_t *event) { if (!event_ctx.cb || !event_ctx.ap) { event_ctx.number = 0; } else if (event->status == 1) { /* error */ event_ctx.number = 0; } else if (event->number == 0) { /* no ap found on current channel */ event_ctx.number = 0; } esp_wifi_scan_get_ap_records(&event_ctx.number, event_ctx.ap); esp_wifi_clear_ap_list(); int i; for (i = 0; i < event_ctx.number; ++i) { if (event_ctx.ap[i].rssi < -80) break; } event_ctx.number = i; return event_ctx.cb(event_ctx.number, event_ctx.ap); } int wifi_event_trigger_scan(uint8_t channel, wifi_event_scan_done_cb cb, uint16_t number, wifi_ap_record_t *aps) { int err; if (aps == NULL) { return 1; } wifi_scan_config_t config = { .bssid = NULL, .ssid = NULL, .show_hidden = 0, .scan_type = WIFI_SCAN_TYPE_ACTIVE, .scan_time.active.min = 10, .scan_time.active.max = 50, .channel = channel, .home_chan_dwell_time = 0, }; err = esp_wifi_scan_start(&config, 0); if (err) { ESP_LOGE(TAG, "%s", esp_err_to_name(err)); return err; } event_ctx.cb = cb; event_ctx.number = number; event_ctx.ap = aps; return 0; } /* * WIFI EVENT * */ static void reconnect_after_disco(); void wifi_event_handler(void *handler_arg __attribute__((unused)), esp_event_base_t event_base __attribute__((unused)), int32_t event_id, void *event_data) { switch (event_id) { case WIFI_EVENT_WIFI_READY: printf("event: WIFI_EVENT_WIFI_READY\n"); break; case WIFI_EVENT_SCAN_DONE: { wifi_event_sta_scan_done_t *event = event_data; // printf("event: WIFI_EVENT_SCAN_DONE: ok: %lu, nr: %u, seq: %u\n", // event->status, event->number, event->scan_id); wifi_on_scan_done(event); event_ctx.ap = NULL; event_ctx.cb = NULL; break; } case WIFI_EVENT_STA_START: printf("event: WIFI_EVENT_STA_START\n"); break; case WIFI_EVENT_STA_CONNECTED: { wifi_event_sta_connected_t *event = event_data; uint8_t *m = event->bssid; printf("event: WIFI_EVENT_STA_CONNECTED\n"); printf("connected to %02X:%02X:%02X:%02X:%02X:%02X\n", m[0], m[1], m[2], m[3], m[4], m[5]); #ifdef CONFIG_EXAMPLE_IPV6 tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); #endif event_ctx.is_connected = 1; break; } case WIFI_EVENT_STA_DISCONNECTED: { wifi_event_sta_disconnected_t *event = event_data; uint8_t *m = event->bssid; printf("event: WIFI_EVENT_STA_DISCONNECTED "); printf("sta %02X:%02X:%02X:%02X:%02X:%02X disconnect reason %d\n", m[0], m[1], m[2], m[3], m[4], m[5], event->reason); event_ctx.is_connected = 0; reconnect_after_disco(); break; } case WIFI_EVENT_AP_START: printf("event: WIFI_EVENT_AP_START\n"); break; case WIFI_EVENT_AP_STACONNECTED: { wifi_event_ap_staconnected_t *event = event_data; uint8_t *m = event->mac; printf("event: WIFI_EVENT_AP_STACONNECTED\n"); printf("%02X:%02X:%02X:%02X:%02X:%02X is connected\n", m[0], m[1], m[2], m[3], m[4], m[5]); break; } case WIFI_EVENT_AP_STADISCONNECTED: { wifi_event_ap_staconnected_t *event = event_data; uint8_t *m = event->mac; printf("event: WIFI_EVENT_AP_STADISCONNECTED\n"); printf("%02X:%02X:%02X:%02X:%02X:%02X is disconnected\n", m[0], m[1], m[2], m[3], m[4], m[5]); break; } default: break; } } void wifi_event_set_disco_handler(void (*disconn_handler)(void)) { event_ctx.conn.disconn_handler = disconn_handler; } int wifi_event_trigger_connect(uint8_t attempt, wifi_event_connect_done_cb cb, void *arg) { int err; event_ctx.conn.attempt = attempt; event_ctx.conn.cb = cb; event_ctx.conn.arg = arg; if (event_ctx.is_connected) { err = esp_wifi_disconnect(); } else { err = esp_wifi_connect(); } return err; } void event_on_connected(ip_event_got_ip_t *event) { if (event_ctx.conn.cb) { event_ctx.conn.cb(event_ctx.conn.arg, event); } event_ctx.conn.attempt = 0; event_ctx.conn.cb = NULL; event_ctx.conn.arg = NULL; } void reconnect_after_disco() { int err; ESP_LOGI(TAG, "reco... atempt %d", event_ctx.conn.attempt); if (event_ctx.conn.attempt == 0) { goto call; } err = esp_wifi_connect(); if (err) { event_ctx.conn.attempt = 0; /* connect err: stop connect and call cb */ ESP_LOGE(TAG, "wifi connect error %s", esp_err_to_name(err)); goto call; } event_ctx.conn.attempt--; return; call: if (event_ctx.conn.cb) { event_ctx.conn.cb(event_ctx.conn.arg, NULL); } else { /* disconnected from extern environment, notify */ if (event_ctx.conn.disconn_handler) { event_ctx.conn.disconn_handler(); } } event_ctx.conn.cb = NULL; event_ctx.conn.arg = NULL; }