From e37b0ad648483df05fde9ab0a3944ea25ee57026 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 19 Nov 2018 16:54:57 +0800 Subject: [PATCH 01/13] esp_event: move trailing semicolons out of defines --- components/esp_event/include/esp_event_base.h | 4 ++-- examples/peripherals/uart/nmea0183_parser/main/nmea_parser.c | 2 +- examples/peripherals/uart/nmea0183_parser/main/nmea_parser.h | 2 +- examples/system/esp_event/default_event_loop/main/main.c | 4 ++-- examples/system/esp_event/user_event_loops/main/main.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/components/esp_event/include/esp_event_base.h b/components/esp_event/include/esp_event_base.h index d2fd38042..73bc73be8 100644 --- a/components/esp_event/include/esp_event_base.h +++ b/components/esp_event/include/esp_event_base.h @@ -20,8 +20,8 @@ extern "C" { #endif // Defines for declaring and defining event base -#define ESP_EVENT_DECLARE_BASE(id) extern esp_event_base_t id; -#define ESP_EVENT_DEFINE_BASE(id) esp_event_base_t id = #id; +#define ESP_EVENT_DECLARE_BASE(id) extern esp_event_base_t id +#define ESP_EVENT_DEFINE_BASE(id) esp_event_base_t id = #id // Event loop library types typedef const char* esp_event_base_t; /**< unique pointer to a subsystem that exposes events */ diff --git a/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.c b/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.c index eaa69d278..0dc244afe 100644 --- a/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.c +++ b/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.c @@ -33,7 +33,7 @@ * @brief Define of NMEA Parser Event base * */ -ESP_EVENT_DEFINE_BASE(ESP_NMEA_EVENT) +ESP_EVENT_DEFINE_BASE(ESP_NMEA_EVENT); static const char *GPS_TAG = "nmea_parser"; diff --git a/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.h b/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.h index 498b2e6f9..aaf802ef6 100644 --- a/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.h +++ b/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.h @@ -30,7 +30,7 @@ extern "C" { * @brief Declare of NMEA Parser Event base * */ -ESP_EVENT_DECLARE_BASE(ESP_NMEA_EVENT) +ESP_EVENT_DECLARE_BASE(ESP_NMEA_EVENT); /** * @brief GPS fix type diff --git a/examples/system/esp_event/default_event_loop/main/main.c b/examples/system/esp_event/default_event_loop/main/main.c index 5af9e52c9..0564be641 100644 --- a/examples/system/esp_event/default_event_loop/main/main.c +++ b/examples/system/esp_event/default_event_loop/main/main.c @@ -96,7 +96,7 @@ static void timer_stopped_handler(void* handler_args, esp_event_base_t base, int } /* Event source task related definitions */ -ESP_EVENT_DEFINE_BASE(TASK_EVENTS) +ESP_EVENT_DEFINE_BASE(TASK_EVENTS); static void task_iteration_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data) { @@ -115,7 +115,7 @@ static void task_event_source(void* args) // that data passed during event posting is a deep copy of the original data. ESP_ERROR_CHECK(esp_event_post(TASK_EVENTS, TASK_ITERATION_EVENT, &iteration, sizeof(iteration), portMAX_DELAY)); - if (iteration == TASK_ITERATIONS_UNREGISTER){ + if (iteration == TASK_ITERATIONS_UNREGISTER) { ESP_LOGI(TAG, "%s:%s: unregistering task_iteration_handler", TASK_EVENTS, get_id_string(TASK_EVENTS, TASK_ITERATION_EVENT)); ESP_ERROR_CHECK(esp_event_handler_unregister(TASK_EVENTS, TASK_ITERATION_EVENT, task_iteration_handler)); } diff --git a/examples/system/esp_event/user_event_loops/main/main.c b/examples/system/esp_event/user_event_loops/main/main.c index a604ff051..b47fed581 100644 --- a/examples/system/esp_event/user_event_loops/main/main.c +++ b/examples/system/esp_event/user_event_loops/main/main.c @@ -31,7 +31,7 @@ static void application_task(void* args) } /* Event source task related definitions */ -ESP_EVENT_DEFINE_BASE(TASK_EVENTS) +ESP_EVENT_DEFINE_BASE(TASK_EVENTS); TaskHandle_t g_task; From 8b57fe9515da72933d33a11094a45194eb99121b Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 23 Aug 2018 17:50:16 +0800 Subject: [PATCH 02/13] wifi: add event declarations --- components/esp_wifi/include/esp_wifi_types.h | 92 ++++++++++++++++++++ components/esp_wifi/src/wifi_init.c | 1 + 2 files changed, 93 insertions(+) diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index f78df8e04..30c3d80db 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -21,6 +21,7 @@ #include "sys/queue.h" #include "esp_err.h" #include "esp_interface.h" +#include "esp_event_base.h" #ifdef __cplusplus extern "C" { @@ -492,6 +493,97 @@ typedef enum { WIFI_PHY_RATE_MAX, } wifi_phy_rate_t; + +/** WiFi event declarations */ +typedef enum { + WIFI_EVENT_WIFI_READY = 0, /**< ESP32 WiFi ready */ + WIFI_EVENT_SCAN_DONE, /**< ESP32 finish scanning AP */ + WIFI_EVENT_STA_START, /**< ESP32 station start */ + WIFI_EVENT_STA_STOP, /**< ESP32 station stop */ + WIFI_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */ + WIFI_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */ + WIFI_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP32 station changed */ + + WIFI_EVENT_STA_WPS_ER_SUCCESS, /**< ESP32 station wps succeeds in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_FAILED, /**< ESP32 station wps fails in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP32 station wps timeout in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_PIN, /**< ESP32 station wps pin code in enrollee mode */ + + WIFI_EVENT_AP_START, /**< ESP32 soft-AP start */ + WIFI_EVENT_AP_STOP, /**< ESP32 soft-AP stop */ + WIFI_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */ + WIFI_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */ + + WIFI_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ +} wifi_event_t; + +/** @cond **/ +/** @brief WiFi event base declaration */ +ESP_EVENT_DECLARE_BASE(WIFI_EVENT); +/** @endcond **/ + +/** Argument structure for WIFI_EVENT_SCAN_DONE event */ +typedef struct { + uint32_t status; /**< status of scanning APs: 0 — success, 1 - failure */ + uint8_t number; /**< number of scan results */ + uint8_t scan_id; /**< scan sequence number, used for block scan */ +} wifi_event_sta_scan_done_t; + +/** Argument structure for WIFI_EVENT_STA_CONNECTED event */ +typedef struct { + 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_t authmode;/**< authentication mode used by AP*/ +} wifi_event_sta_connected_t; + +/** Argument structure for WIFI_EVENT_STA_DISCONNECTED event */ +typedef struct { + 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; + +/** Argument structure for WIFI_EVENT_STA_AUTHMODE_CHANGE event */ +typedef struct { + wifi_auth_mode_t old_mode; /**< the old auth mode of AP */ + wifi_auth_mode_t new_mode; /**< the new auth mode of AP */ +} wifi_event_sta_authmode_change_t; + +/** Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event */ +typedef struct { + uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */ +} wifi_event_sta_wps_er_pin_t; + +/** Argument structure for WIFI_EVENT_STA_WPS_ER_FAILED event */ +typedef enum { + WPS_FAIL_REASON_NORMAL = 0, /**< ESP32 WPS normal fail reason */ + WPS_FAIL_REASON_RECV_M2D, /**< ESP32 WPS receive M2D frame */ + WPS_FAIL_REASON_MAX +} wifi_event_sta_wps_fail_reason_t; + +/** Argument structure for WIFI_EVENT_AP_STACONNECTED event */ +typedef struct { + uint8_t mac[6]; /**< MAC address of the station connected to ESP32 soft-AP */ + uint8_t aid; /**< the aid that ESP32 soft-AP gives to the station connected to */ +} wifi_event_ap_staconnected_t; + +/** Argument structure for WIFI_EVENT_AP_STADISCONNECTED event */ +typedef struct { + uint8_t mac[6]; /**< MAC address of the station disconnects to ESP32 soft-AP */ + uint8_t aid; /**< the aid that ESP32 soft-AP gave to the station disconnects to */ +} wifi_event_ap_stadisconnected_t; + +/** Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event */ +typedef struct { + 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; + + + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 2115dc614..9176e76e4 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -22,6 +22,7 @@ /* mesh event callback handler */ mesh_event_cb_t g_mesh_event_cb = NULL; +ESP_EVENT_DEFINE_BASE(WIFI_EVENT); #ifdef CONFIG_PM_ENABLE static esp_pm_lock_handle_t s_wifi_modem_sleep_lock; From c00155302783ada2b1ab9b686833489841124fba Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 23 Aug 2018 17:50:29 +0800 Subject: [PATCH 03/13] ethernet: add event declarations --- components/ethernet/emac_main.c | 1 + components/ethernet/include/esp_eth.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/components/ethernet/emac_main.c b/components/ethernet/emac_main.c index 2b78663f9..e1b402aa3 100644 --- a/components/ethernet/emac_main.c +++ b/components/ethernet/emac_main.c @@ -79,6 +79,7 @@ static bool pause_send = false; #ifdef CONFIG_PM_ENABLE static esp_pm_lock_handle_t s_pm_lock; #endif +ESP_EVENT_DEFINE_BASE(ETH_EVENT); static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par); esp_err_t emac_post(emac_sig_t sig, emac_par_t par); diff --git a/components/ethernet/include/esp_eth.h b/components/ethernet/include/esp_eth.h index ccbc59d04..5fe712928 100644 --- a/components/ethernet/include/esp_eth.h +++ b/components/ethernet/include/esp_eth.h @@ -19,6 +19,9 @@ extern "C" { #endif +#include +#include +#include "esp_event_base.h" #include "esp_types.h" #include "esp_err.h" @@ -130,6 +133,17 @@ typedef struct { uint32_t reset_timeout_ms; /*!< timeout value for reset emac */ } eth_config_t; +/** Ethernet event declarations */ +typedef enum { + ETHERNET_EVENT_START, /**< ESP32 ethernet start */ + ETHERNET_EVENT_STOP, /**< ESP32 ethernet stop */ + ETHERNET_EVENT_CONNECTED, /**< ESP32 ethernet phy link up */ + ETHERNET_EVENT_DISCONNECTED, /**< ESP32 ethernet phy link down */ +} eth_event_t; + +/** @brief Ethernet event base declaration */ +ESP_EVENT_DECLARE_BASE(ETH_EVENT); + /** * @brief Init ethernet mac * From 1872e34115cfb896b5e84569dd33276e76c7280c Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 25 Dec 2018 15:28:56 +0800 Subject: [PATCH 04/13] tcpip_adapter: add event declarations --- .../tcpip_adapter/include/tcpip_adapter.h | 25 +++++++++++++++++++ components/tcpip_adapter/tcpip_adapter_lwip.c | 2 ++ 2 files changed, 27 insertions(+) diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index 43e6e2421..d3f5b3216 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -143,6 +143,31 @@ typedef enum{ /* Deprecated name for tcpip_adapter_dhcp_option_id_t, to remove after ESP-IDF V4.0 */ typedef tcpip_adapter_dhcp_option_id_t tcpip_adapter_option_id_t; +/** IP event declarations */ +typedef enum { + IP_EVENT_STA_GOT_IP, /*!< ESP32 station got IP from connected AP */ + IP_EVENT_STA_LOST_IP, /*!< ESP32 station lost IP and the IP is reset to 0 */ + IP_EVENT_AP_STAIPASSIGNED, /*!< ESP32 soft-AP assign an IP to a connected station */ + IP_EVENT_GOT_IP6, /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */ + IP_EVENT_ETH_GOT_IP, /*!< ESP32 ethernet got IP from connected AP */ +} ip_event_t; + +/** @brief IP event base declaration */ +ESP_EVENT_DECLARE_BASE(IP_EVENT); + +/** Event structure for IP_EVENT_STA_GOT_IP, IP_EVENT_ETH_GOT_IP events */ +typedef struct { + tcpip_adapter_if_t if_index; /*!< Interface for which the event is received */ + tcpip_adapter_ip_info_t ip_info; /*!< IP address, netmask, gatway IP address */ + bool ip_changed; /*!< Whether the assigned IP has changed or not */ +} ip_event_got_ip_t; + +/** Event structure for IP_EVENT_GOT_IP6 event */ +typedef struct { + tcpip_adapter_if_t if_index; /*!< Interface for which the event is received */ + tcpip_adapter_ip6_info_t ip6_info; /*!< IPv6 address of the interface */ +} ip_event_got_ip6_t; + /** * @brief Initialize the underlying TCP/IP stack * diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 443fa54bb..0d77bb5ac 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -70,6 +70,8 @@ static sys_sem_t api_lock_sem = NULL; extern sys_thread_t g_lwip_task; static const char* TAG = "tcpip_adapter"; +ESP_EVENT_DEFINE_BASE(IP_EVENT); + static void tcpip_adapter_api_cb(void* api_msg) { tcpip_adapter_api_msg_t *msg = (tcpip_adapter_api_msg_t*)api_msg; From b1d1e37f8723de0cf083a3a268bab421178c60bc Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 6 Nov 2018 11:09:32 +0800 Subject: [PATCH 05/13] event loop: re-implement based on esp_event library Includes ds2ds unit test fix, iperf example test fix --- components/esp32/CMakeLists.txt | 1 + components/esp_event/CMakeLists.txt | 6 +- components/esp_event/default_event_loop.c | 4 + components/esp_event/event_default_handlers.c | 484 ------------------ components/esp_event/event_loop.c | 126 ----- components/esp_event/event_loop_legacy.c | 101 ++++ components/esp_event/event_send.c | 52 ++ components/esp_event/event_send_compat.inc | 262 ++++++++++ .../esp_event/include/esp_event_legacy.h | 236 +++++---- components/esp_event/include/esp_event_loop.h | 82 +-- components/esp_wifi/src/mesh_event.c | 36 ++ components/esp_wifi/src/wifi_init.c | 10 +- components/esp_wifi/test/test_wifi.c | 6 + components/ethernet/emac_main.c | 2 +- components/tcpip_adapter/CMakeLists.txt | 3 +- components/tcpip_adapter/event_handlers.c | 310 +++++++++++ .../tcpip_adapter/include/tcpip_adapter.h | 40 ++ examples/wifi/iperf/iperf_test.py | 2 +- 18 files changed, 952 insertions(+), 811 deletions(-) delete mode 100644 components/esp_event/event_default_handlers.c delete mode 100644 components/esp_event/event_loop.c create mode 100644 components/esp_event/event_loop_legacy.c create mode 100644 components/esp_event/event_send.c create mode 100644 components/esp_event/event_send_compat.inc create mode 100644 components/esp_wifi/src/mesh_event.c create mode 100644 components/tcpip_adapter/event_handlers.c diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index a6b61623e..9749eef58 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -24,6 +24,7 @@ else() "hw_random.c" "int_wdt.c" "intr_alloc.c" + "mesh_event.c" "panic.c" "pm_esp32.c" "pm_trace.c" diff --git a/components/esp_event/CMakeLists.txt b/components/esp_event/CMakeLists.txt index b30234c95..aadbfb72a 100644 --- a/components/esp_event/CMakeLists.txt +++ b/components/esp_event/CMakeLists.txt @@ -1,13 +1,15 @@ set(COMPONENT_SRCS "default_event_loop.c" "esp_event.c" "esp_event_private.c" - "event_loop.c" - "event_default_handlers.c") + "event_loop_legacy.c" + "event_send.c") + set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_PRIV_INCLUDEDIRS "private_include") set(COMPONENT_REQUIRES log tcpip_adapter) set(COMPONENT_PRIV_REQUIRES ethernet) +set(COMPONENT_REQUIRES log tcpip_adapter ethernet) set(COMPONENT_ADD_LDFRAGMENTS linker.lf) diff --git a/components/esp_event/default_event_loop.c b/components/esp_event/default_event_loop.c index 3daf5ab8d..9623f04d8 100644 --- a/components/esp_event/default_event_loop.c +++ b/components/esp_event/default_event_loop.c @@ -113,3 +113,7 @@ esp_err_t esp_event_loop_delete_default() } +/* Include the code to forward legacy system_event_t events to the this default + * event loop. + */ +#include "event_send_compat.inc" diff --git a/components/esp_event/event_default_handlers.c b/components/esp_event/event_default_handlers.c deleted file mode 100644 index 7506d9614..000000000 --- a/components/esp_event/event_default_handlers.c +++ /dev/null @@ -1,484 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include -#include - -#include "esp_err.h" -#include "esp_wifi.h" -#include "esp_private/wifi.h" -#include "esp_event.h" -#include "esp_event_loop.h" -#include "esp_task.h" -#include "esp_eth.h" -#include "esp_system.h" - -#include "esp32/rom/ets_sys.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" - -#include "tcpip_adapter.h" -#include "esp_log.h" - -static const char* TAG = "event"; - -#define WIFI_API_CALL_CHECK(info, api_call, ret) \ -do{\ - esp_err_t __err = (api_call);\ - if ((ret) != __err) {\ - ESP_LOGE(TAG, "%s %d %s ret=0x%X", __FUNCTION__, __LINE__, (info), __err);\ - return __err;\ - }\ -} while(0) - -typedef struct { - int err; - const char *reason; -} wifi_reason_t; - -static const wifi_reason_t wifi_reason[] = -{ - {0, "wifi reason: other reason"}, - {WIFI_REASON_UNSPECIFIED, "wifi reason: unspecified"}, - {WIFI_REASON_AUTH_EXPIRE, "wifi reason: auth expire"}, - {WIFI_REASON_AUTH_LEAVE, "wifi reason: auth leave"}, - {WIFI_REASON_ASSOC_EXPIRE, "wifi reason: assoc expire"}, - {WIFI_REASON_ASSOC_TOOMANY, "wifi reason: assoc too many"}, - {WIFI_REASON_NOT_AUTHED, "wifi reason: not authed"}, - {WIFI_REASON_NOT_ASSOCED, "wifi reason: not assoced"}, - {WIFI_REASON_ASSOC_LEAVE, "wifi reason: assoc leave"}, - {WIFI_REASON_ASSOC_NOT_AUTHED, "wifi reason: assoc not authed"}, - {WIFI_REASON_BEACON_TIMEOUT, "wifi reason: beacon timeout"}, - {WIFI_REASON_NO_AP_FOUND, "wifi reason: no ap found"}, - {WIFI_REASON_AUTH_FAIL, "wifi reason: auth fail"}, - {WIFI_REASON_ASSOC_FAIL, "wifi reason: assoc fail"}, - {WIFI_REASON_HANDSHAKE_TIMEOUT, "wifi reason: hanshake timeout"}, - {WIFI_REASON_DISASSOC_PWRCAP_BAD, "wifi reason: bad Power Capability, disassoc"}, - {WIFI_REASON_DISASSOC_SUPCHAN_BAD, "wifi reason: bad Supported Channels, disassoc"}, - {WIFI_REASON_IE_INVALID, "wifi reason: invalid IE"}, - {WIFI_REASON_MIC_FAILURE, "wifi reason: MIC failure"}, - {WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT, "wifi reason: 4-way keying handshake timeout"}, - {WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT, "wifi reason: Group key handshake"}, - {WIFI_REASON_IE_IN_4WAY_DIFFERS, "wifi reason: IE in 4-way differs"}, - {WIFI_REASON_GROUP_CIPHER_INVALID, "wifi reason: invalid group cipher"}, - {WIFI_REASON_PAIRWISE_CIPHER_INVALID, "wifi reason: invalid pairwise cipher"}, - {WIFI_REASON_AKMP_INVALID, "wifi reason: invalid AKMP"}, - {WIFI_REASON_UNSUPP_RSN_IE_VERSION, "wifi reason: unsupported RSN IE version"}, - {WIFI_REASON_INVALID_RSN_IE_CAP, "wifi reason: invalid RSN IE capability"}, - {WIFI_REASON_802_1X_AUTH_FAILED, "wifi reason: 802.1x auth failed"}, - {WIFI_REASON_CIPHER_SUITE_REJECTED, "wifi reason: cipher suite rejected"} -}; - -const char* wifi_get_reason(int err) -{ - int i=0; - - for (i=0; i< sizeof(wifi_reason)/sizeof(wifi_reason_t); i++){ - if (err == wifi_reason[i].err){ - return wifi_reason[i].reason; - } - } - - return wifi_reason[0].reason; -} - -typedef esp_err_t (*system_event_handler_t)(system_event_t *e); - -static esp_err_t system_event_ap_start_handle_default(system_event_t *event); -static esp_err_t system_event_ap_stop_handle_default(system_event_t *event); -static esp_err_t system_event_sta_start_handle_default(system_event_t *event); -static esp_err_t system_event_sta_stop_handle_default(system_event_t *event); -static esp_err_t system_event_sta_connected_handle_default(system_event_t *event); -static esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event); -static esp_err_t system_event_sta_got_ip_default(system_event_t *event); -static esp_err_t system_event_sta_lost_ip_default(system_event_t *event); - -static esp_err_t system_event_eth_start_handle_default(system_event_t *event); -static esp_err_t system_event_eth_stop_handle_default(system_event_t *event); -static esp_err_t system_event_eth_connected_handle_default(system_event_t *event); -static esp_err_t system_event_eth_disconnected_handle_default(system_event_t *event); -static esp_err_t system_event_eth_got_ip_default(system_event_t *event); - -/* Default event handler functions - - Any entry in this table which is disabled by config will have a NULL handler. -*/ -static system_event_handler_t default_event_handlers[SYSTEM_EVENT_MAX] = { 0 }; - -esp_err_t system_event_eth_start_handle_default(system_event_t *event) -{ - tcpip_adapter_ip_info_t eth_ip; - uint8_t eth_mac[6]; - - esp_eth_get_mac(eth_mac); - tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, ð_ip); - tcpip_adapter_eth_start(eth_mac, ð_ip); - - return ESP_OK; -} - -esp_err_t system_event_eth_stop_handle_default(system_event_t *event) -{ - tcpip_adapter_stop(TCPIP_ADAPTER_IF_ETH); - - return ESP_OK; -} - -esp_err_t system_event_eth_connected_handle_default(system_event_t *event) -{ - tcpip_adapter_dhcp_status_t status; - - tcpip_adapter_up(TCPIP_ADAPTER_IF_ETH); - - tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &status); - - if (status == TCPIP_ADAPTER_DHCP_INIT) { - tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH); - } else if (status == TCPIP_ADAPTER_DHCP_STOPPED) { - tcpip_adapter_ip_info_t eth_ip; - - tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, ð_ip); - - if (!(ip4_addr_isany_val(eth_ip.ip) || ip4_addr_isany_val(eth_ip.netmask))) { - system_event_t evt; - - //notify event - evt.event_id = SYSTEM_EVENT_ETH_GOT_IP; - memcpy(&evt.event_info.got_ip.ip_info, ð_ip, sizeof(tcpip_adapter_ip_info_t)); - - esp_event_send(&evt); - } else { - ESP_LOGE(TAG, "invalid static ip"); - } - } - - return ESP_OK; -} - -esp_err_t system_event_eth_disconnected_handle_default(system_event_t *event) -{ - tcpip_adapter_down(TCPIP_ADAPTER_IF_ETH); - return ESP_OK; -} - -static esp_err_t system_event_eth_got_ip_default(system_event_t *event) -{ - ESP_LOGI(TAG, "eth ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, - IP2STR(&event->event_info.got_ip.ip_info.ip), - IP2STR(&event->event_info.got_ip.ip_info.netmask), - IP2STR(&event->event_info.got_ip.ip_info.gw)); - - return ESP_OK; -} - -static esp_err_t system_event_sta_got_ip_default(system_event_t *event) -{ - WIFI_API_CALL_CHECK("esp_wifi_internal_set_sta_ip", esp_wifi_internal_set_sta_ip(), ESP_OK); - - ESP_LOGI(TAG, "sta ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, - IP2STR(&event->event_info.got_ip.ip_info.ip), - IP2STR(&event->event_info.got_ip.ip_info.netmask), - IP2STR(&event->event_info.got_ip.ip_info.gw)); - - return ESP_OK; -} - -static esp_err_t system_event_sta_lost_ip_default(system_event_t *event) -{ - ESP_LOGI(TAG, "station ip lost"); - return ESP_OK; -} - -esp_err_t system_event_ap_start_handle_default(system_event_t *event) -{ - tcpip_adapter_ip_info_t ap_ip; - uint8_t ap_mac[6]; - - WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, (wifi_rxcb_t)tcpip_adapter_ap_input), ESP_OK); - WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_AP, ap_mac), ESP_OK); - - tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ap_ip); - tcpip_adapter_ap_start(ap_mac, &ap_ip); - - return ESP_OK; -} - -esp_err_t system_event_ap_stop_handle_default(system_event_t *event) -{ - WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, NULL), ESP_OK); - - tcpip_adapter_stop(TCPIP_ADAPTER_IF_AP); - - return ESP_OK; -} - -esp_err_t system_event_sta_start_handle_default(system_event_t *event) -{ - tcpip_adapter_ip_info_t sta_ip; - uint8_t sta_mac[6]; - - WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_STA, sta_mac), ESP_OK); - tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); - tcpip_adapter_sta_start(sta_mac, &sta_ip); - - return ESP_OK; -} - -esp_err_t system_event_sta_stop_handle_default(system_event_t *event) -{ - tcpip_adapter_stop(TCPIP_ADAPTER_IF_STA); - - return ESP_OK; -} - -esp_err_t system_event_sta_connected_handle_default(system_event_t *event) -{ - tcpip_adapter_dhcp_status_t status; - - WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK); - - tcpip_adapter_up(TCPIP_ADAPTER_IF_STA); - - tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &status); - - if (status == TCPIP_ADAPTER_DHCP_INIT) { - tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA); - } else if (status == TCPIP_ADAPTER_DHCP_STOPPED) { - tcpip_adapter_ip_info_t sta_ip; - tcpip_adapter_ip_info_t sta_old_ip; - - tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); - tcpip_adapter_get_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_old_ip); - - if (!(ip4_addr_isany_val(sta_ip.ip) || ip4_addr_isany_val(sta_ip.netmask))) { - system_event_t evt; - - evt.event_id = SYSTEM_EVENT_STA_GOT_IP; - evt.event_info.got_ip.ip_changed = false; - - if (memcmp(&sta_ip, &sta_old_ip, sizeof(sta_ip))) { - evt.event_info.got_ip.ip_changed = true; - } - - memcpy(&evt.event_info.got_ip.ip_info, &sta_ip, sizeof(tcpip_adapter_ip_info_t)); - tcpip_adapter_set_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); - - esp_event_send(&evt); - ESP_LOGD(TAG, "static ip: ip changed=%d", evt.event_info.got_ip.ip_changed); - } else { - ESP_LOGE(TAG, "invalid static ip"); - } - } - - return ESP_OK; -} - -esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event) -{ - tcpip_adapter_down(TCPIP_ADAPTER_IF_STA); - WIFI_API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, NULL), ESP_OK); - return ESP_OK; -} - -static esp_err_t esp_system_event_debug(system_event_t *event) -{ - if (event == NULL) { - ESP_LOGE(TAG, "event is null!"); - return ESP_FAIL; - } - - switch (event->event_id) { - case SYSTEM_EVENT_WIFI_READY: { - ESP_LOGD(TAG, "SYSTEM_EVENT_WIFI_READY"); - break; - } - case SYSTEM_EVENT_SCAN_DONE: { - system_event_sta_scan_done_t *scan_done = &event->event_info.scan_done; - ESP_LOGD(TAG, "SYSTEM_EVENT_SCAN_DONE, status:%d, number:%d", scan_done->status, scan_done->number); - break; - } - case SYSTEM_EVENT_STA_START: { - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_START"); - break; - } - case SYSTEM_EVENT_STA_STOP: { - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_STOP"); - break; - } - case SYSTEM_EVENT_STA_CONNECTED: { - system_event_sta_connected_t *connected = &event->event_info.connected; - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_CONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", channel:%d, authmode:%d", \ - connected->ssid, connected->ssid_len, MAC2STR(connected->bssid), connected->channel, connected->authmode); - break; - } - case SYSTEM_EVENT_STA_DISCONNECTED: { - system_event_sta_disconnected_t *disconnected = &event->event_info.disconnected; - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", reason:%d,%s", \ - disconnected->ssid, disconnected->ssid_len, MAC2STR(disconnected->bssid), disconnected->reason, wifi_get_reason(disconnected->reason)); - break; - } - case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: { - system_event_sta_authmode_change_t *auth_change = &event->event_info.auth_change; - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_AUTHMODE_CHNAGE, old_mode:%d, new_mode:%d", auth_change->old_mode, auth_change->new_mode); - break; - } - case SYSTEM_EVENT_STA_GOT_IP: { - system_event_sta_got_ip_t *got_ip = &event->event_info.got_ip; - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_GOT_IP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR, - IP2STR(&got_ip->ip_info.ip), - IP2STR(&got_ip->ip_info.netmask), - IP2STR(&got_ip->ip_info.gw)); - break; - } - case SYSTEM_EVENT_STA_LOST_IP: { - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_LOST_IP"); - break; - } - case SYSTEM_EVENT_STA_WPS_ER_SUCCESS: { - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_SUCCESS"); - break; - } - case SYSTEM_EVENT_STA_WPS_ER_FAILED: { - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_FAILED"); - break; - } - case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT: { - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_TIMEOUT"); - break; - } - case SYSTEM_EVENT_STA_WPS_ER_PIN: { - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_PIN"); - break; - } - case SYSTEM_EVENT_AP_START: { - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_START"); - break; - } - case SYSTEM_EVENT_AP_STOP: { - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STOP"); - break; - } - case SYSTEM_EVENT_AP_STACONNECTED: { - system_event_ap_staconnected_t *staconnected = &event->event_info.sta_connected; - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STACONNECTED, mac:" MACSTR ", aid:%d", \ - MAC2STR(staconnected->mac), staconnected->aid); - break; - } - case SYSTEM_EVENT_AP_STADISCONNECTED: { - system_event_ap_stadisconnected_t *stadisconnected = &event->event_info.sta_disconnected; - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STADISCONNECTED, mac:" MACSTR ", aid:%d", \ - MAC2STR(stadisconnected->mac), stadisconnected->aid); - break; - } - case SYSTEM_EVENT_AP_STAIPASSIGNED: { - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STAIPASSIGNED"); - break; - } - case SYSTEM_EVENT_AP_PROBEREQRECVED: { - system_event_ap_probe_req_rx_t *ap_probereqrecved = &event->event_info.ap_probereqrecved; - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_PROBEREQRECVED, rssi:%d, mac:" MACSTR, \ - ap_probereqrecved->rssi, \ - MAC2STR(ap_probereqrecved->mac)); - break; - } - case SYSTEM_EVENT_GOT_IP6: { - ip6_addr_t *addr = &event->event_info.got_ip6.ip6_info.ip; - ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STA_GOT_IP6 address %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", - IP6_ADDR_BLOCK1(addr), - IP6_ADDR_BLOCK2(addr), - IP6_ADDR_BLOCK3(addr), - IP6_ADDR_BLOCK4(addr), - IP6_ADDR_BLOCK5(addr), - IP6_ADDR_BLOCK6(addr), - IP6_ADDR_BLOCK7(addr), - IP6_ADDR_BLOCK8(addr)); - break; - } - case SYSTEM_EVENT_ETH_START: { - ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_START"); - break; - } - case SYSTEM_EVENT_ETH_STOP: { - ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_STOP"); - break; - } - case SYSTEM_EVENT_ETH_CONNECTED: { - ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_CONNECETED"); - break; - } - case SYSTEM_EVENT_ETH_DISCONNECTED: { - ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_DISCONNECETED"); - break; - } - case SYSTEM_EVENT_ETH_GOT_IP: { - ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_GOT_IP"); - break; - } - - default: { - ESP_LOGW(TAG, "unexpected system event %d!", event->event_id); - break; - } - } - - return ESP_OK; -} - -esp_err_t esp_event_process_default(system_event_t *event) -{ - if (event == NULL) { - ESP_LOGE(TAG, "Error: event is null!"); - return ESP_FAIL; - } - - esp_system_event_debug(event); - if ((event->event_id < SYSTEM_EVENT_MAX)) { - if (default_event_handlers[event->event_id] != NULL) { - ESP_LOGV(TAG, "enter default callback"); - default_event_handlers[event->event_id](event); - ESP_LOGV(TAG, "exit default callback"); - } - } else { - ESP_LOGE(TAG, "mismatch or invalid event, id=%d", event->event_id); - return ESP_FAIL; - } - return ESP_OK; -} - -void esp_event_set_default_wifi_handlers() -{ - default_event_handlers[SYSTEM_EVENT_STA_START] = system_event_sta_start_handle_default; - default_event_handlers[SYSTEM_EVENT_STA_STOP] = system_event_sta_stop_handle_default; - default_event_handlers[SYSTEM_EVENT_STA_CONNECTED] = system_event_sta_connected_handle_default; - default_event_handlers[SYSTEM_EVENT_STA_DISCONNECTED] = system_event_sta_disconnected_handle_default; - default_event_handlers[SYSTEM_EVENT_STA_GOT_IP] = system_event_sta_got_ip_default; - default_event_handlers[SYSTEM_EVENT_STA_LOST_IP] = system_event_sta_lost_ip_default; - default_event_handlers[SYSTEM_EVENT_AP_START] = system_event_ap_start_handle_default; - default_event_handlers[SYSTEM_EVENT_AP_STOP] = system_event_ap_stop_handle_default; - - esp_register_shutdown_handler((shutdown_handler_t)esp_wifi_stop); -} - -void esp_event_set_default_eth_handlers() -{ - default_event_handlers[SYSTEM_EVENT_ETH_START] = system_event_eth_start_handle_default; - default_event_handlers[SYSTEM_EVENT_ETH_STOP] = system_event_eth_stop_handle_default; - default_event_handlers[SYSTEM_EVENT_ETH_CONNECTED] = system_event_eth_connected_handle_default; - default_event_handlers[SYSTEM_EVENT_ETH_DISCONNECTED] = system_event_eth_disconnected_handle_default; - default_event_handlers[SYSTEM_EVENT_ETH_GOT_IP] = system_event_eth_got_ip_default; -} diff --git a/components/esp_event/event_loop.c b/components/esp_event/event_loop.c deleted file mode 100644 index 9dbefb45d..000000000 --- a/components/esp_event/event_loop.c +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include -#include - -#include "esp_err.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_event_legacy.h" -#include "esp_task.h" -#include "esp_mesh.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" - -#include "esp_log.h" -#include "sdkconfig.h" - - -static const char* TAG = "event"; -static bool s_event_init_flag = false; -static QueueHandle_t s_event_queue = NULL; -static system_event_cb_t s_event_handler_cb = NULL; -static void *s_event_ctx = NULL; - -static esp_err_t esp_event_post_to_user(system_event_t *event) -{ - if (s_event_handler_cb) { - return (*s_event_handler_cb)(s_event_ctx, event); - } - return ESP_OK; -} - -static void esp_event_loop_task(void *pvParameters) -{ - while (1) { - system_event_t evt; - if (xQueueReceive(s_event_queue, &evt, portMAX_DELAY) == pdPASS) { - esp_err_t ret = esp_event_process_default(&evt); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "default event handler failed!"); - } - ret = esp_event_post_to_user(&evt); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "post event to user fail!"); - } - } - } -} - -system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx) -{ - system_event_cb_t old_cb = s_event_handler_cb; - s_event_handler_cb = cb; - s_event_ctx = ctx; - return old_cb; -} - -esp_err_t esp_event_send(system_event_t *event) -{ - if (s_event_queue == NULL) { - ESP_LOGE(TAG, "Event loop not initialized via esp_event_loop_init, but esp_event_send called"); - return ESP_ERR_INVALID_STATE; - } - - if (event->event_id == SYSTEM_EVENT_STA_GOT_IP || event->event_id == SYSTEM_EVENT_STA_LOST_IP) { - if (g_mesh_event_cb) { - mesh_event_t mevent; - if (event->event_id == SYSTEM_EVENT_STA_GOT_IP) { - mevent.id = MESH_EVENT_ROOT_GOT_IP; - memcpy(&mevent.info.got_ip, &event->event_info.got_ip, sizeof(system_event_sta_got_ip_t)); - } else { - mevent.id = MESH_EVENT_ROOT_LOST_IP; - } - g_mesh_event_cb(mevent); - } - } - - portBASE_TYPE ret = xQueueSendToBack(s_event_queue, event, 0); - if (ret != pdPASS) { - if (event) { - ESP_LOGE(TAG, "e=%d f", event->event_id); - } else { - ESP_LOGE(TAG, "e null"); - } - return ESP_FAIL; - } - return ESP_OK; -} - -QueueHandle_t esp_event_loop_get_queue(void) -{ - return s_event_queue; -} - -esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx) -{ - if (s_event_init_flag) { - return ESP_FAIL; - } - s_event_handler_cb = cb; - s_event_ctx = ctx; - s_event_queue = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t)); - - xTaskCreatePinnedToCore(esp_event_loop_task, "eventTask", - ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0); - - s_event_init_flag = true; - return ESP_OK; -} - diff --git a/components/esp_event/event_loop_legacy.c b/components/esp_event/event_loop_legacy.c new file mode 100644 index 000000000..f5e737d20 --- /dev/null +++ b/components/esp_event/event_loop_legacy.c @@ -0,0 +1,101 @@ +// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "esp_err.h" +#include "esp_log.h" +#include "esp_event_legacy.h" +#include "esp_event.h" + +#include "sdkconfig.h" + +static const char* TAG = "event"; + +static system_event_cb_t s_event_handler_cb; +static void *s_event_ctx; +static bool s_initialized; + +ESP_EVENT_DEFINE_BASE(SYSTEM_EVENT); + +static void esp_event_post_to_user(void* arg, esp_event_base_t base, int32_t id, void* data) +{ + if (s_event_handler_cb) { + system_event_t* event = (system_event_t*) data; + (*s_event_handler_cb)(s_event_ctx, event); + } +} + +system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx) +{ + system_event_cb_t old_cb = s_event_handler_cb; + s_event_handler_cb = cb; + s_event_ctx = ctx; + return old_cb; +} + +esp_err_t esp_event_send_legacy(system_event_t *event) +{ + if (!s_initialized) { + ESP_LOGE(TAG, "system event loop not initialized via esp_event_loop_init"); + return ESP_ERR_INVALID_STATE; + } + + return esp_event_post(SYSTEM_EVENT, event->event_id, event, sizeof(*event), 0); +} + +esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx) +{ + if (s_initialized) { + ESP_LOGE(TAG, "system event loop already initialized"); + return ESP_ERR_INVALID_STATE; + } + + esp_err_t err = esp_event_loop_create_default(); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + return err; + } + + err = esp_event_handler_register(SYSTEM_EVENT, ESP_EVENT_ANY_ID, esp_event_post_to_user, NULL); + if (err != ESP_OK) { + return err; + } + + s_initialized = true; + s_event_handler_cb = cb; + s_event_ctx = ctx; + return ESP_OK; +} + +esp_err_t esp_event_loop_deinit() +{ + if (!s_initialized) { + ESP_LOGE(TAG, "system event loop not initialized"); + return ESP_ERR_INVALID_STATE; + } + + esp_err_t err = esp_event_handler_unregister(SYSTEM_EVENT, ESP_EVENT_ANY_ID, esp_event_post_to_user); + if (err != ESP_OK) { + return err; + } + + err = esp_event_loop_delete_default(); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + return err; + } + + s_initialized = false; + s_event_handler_cb = NULL; + s_event_ctx = NULL; + return ESP_OK; +} + diff --git a/components/esp_event/event_send.c b/components/esp_event/event_send.c new file mode 100644 index 000000000..4472bb474 --- /dev/null +++ b/components/esp_event/event_send.c @@ -0,0 +1,52 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#include "esp_event.h" +#include "esp_event_legacy.h" + +esp_err_t esp_event_send_noop(system_event_t *event); + +extern esp_err_t esp_event_send_legacy(system_event_t *event) __attribute__((weak, alias("esp_event_send_noop"))); +extern esp_err_t esp_event_send_to_default_loop(system_event_t *event) __attribute((weak, alias("esp_event_send_noop"))); +extern esp_err_t esp_event_mesh_hook(system_event_t* event) __attribute__((weak, alias("esp_event_send_noop"))); + + +esp_err_t esp_event_send_noop(system_event_t *event) +{ + return ESP_OK; +} + +esp_err_t esp_event_send(system_event_t *event) +{ + // send the event to the new style event loop + esp_err_t err = esp_event_send_to_default_loop(event); + if (err != ESP_OK) { + return err; + } + + // send the event to the legacy event loop + err = esp_event_send_legacy(event); + if (err != ESP_OK) { + return err; + } + + // send the event to mesh hook + err = esp_event_mesh_hook(event); + if (err != ESP_OK) { + return err; + } + + return ESP_OK; +} diff --git a/components/esp_event/event_send_compat.inc b/components/esp_event/event_send_compat.inc new file mode 100644 index 000000000..408ce7a82 --- /dev/null +++ b/components/esp_event/event_send_compat.inc @@ -0,0 +1,262 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "esp_event.h" +#include "esp_log.h" +#include "esp_event_legacy.h" +#include "esp_wifi_types.h" +#include "tcpip_adapter.h" +#include "esp_eth.h" + +/** + * The purpose of this file is to provide an "esp_event_send_to_default_loop" + * function, which is used to forward legacy events (system_event_t) sent using + * esp_event_send, to the new default event loop (esp_event_post). + * + * For each of the events in system_event_id_t, we extract the event data from + * the corresponding system_event_info_t member, and forward that to + * esp_event_post function. + * + * Some macros are used to reduce the amount of boilerplate. + * + * Note that this function only needs to be included into the output file if + * the new default event loop is used. This function is in a separate file for + * readability reasons. In order to be linked if the contents of + * default_event_loop.c is linked, this file is #include-ed into default_event_loop.c. + */ + +//#if LOG_LOCAL_LEVEL >= 4 /* ESP_LOG_DEBUG */ +#if 1 +#define WITH_EVENT_DEBUG +#endif + +#ifdef WITH_EVENT_DEBUG +static void esp_system_event_debug(const system_event_t* event); +#endif + +#define HANDLE_SYS_EVENT(base_, name_) \ + case SYSTEM_EVENT_ ## name_: \ + return esp_event_post(base_ ## _EVENT, base_ ## _EVENT_ ## name_, \ + NULL, 0, send_timeout) + +#define HANDLE_SYS_EVENT_ARG(base_, name_, member_) \ + case SYSTEM_EVENT_ ## name_: \ + return esp_event_post(base_ ## _EVENT, base_ ## _EVENT_ ## name_, \ + &event->event_info.member_, sizeof(event->event_info.member_), \ + send_timeout) + +esp_err_t esp_event_send_to_default_loop(system_event_t *event) +{ +#ifdef WITH_EVENT_DEBUG + esp_system_event_debug(event); +#endif // WITH_EVENT_DEBUG + + const TickType_t send_timeout = 0; + switch (event->event_id) { + /* Wi-Fi common events */ + HANDLE_SYS_EVENT(WIFI, WIFI_READY); + HANDLE_SYS_EVENT_ARG(WIFI, SCAN_DONE, scan_done); + HANDLE_SYS_EVENT(WIFI, STA_START); + HANDLE_SYS_EVENT(WIFI, STA_STOP); + + /* STA events */ + HANDLE_SYS_EVENT_ARG(WIFI, STA_CONNECTED, connected); + HANDLE_SYS_EVENT_ARG(WIFI, STA_DISCONNECTED, disconnected); + HANDLE_SYS_EVENT_ARG(WIFI, STA_AUTHMODE_CHANGE, auth_change); + + /* WPS events */ + HANDLE_SYS_EVENT(WIFI, STA_WPS_ER_SUCCESS); + HANDLE_SYS_EVENT(WIFI, STA_WPS_ER_TIMEOUT); + HANDLE_SYS_EVENT_ARG(WIFI, STA_WPS_ER_FAILED, sta_er_fail_reason); + HANDLE_SYS_EVENT_ARG(WIFI, STA_WPS_ER_PIN, sta_er_pin); + + /* AP events */ + HANDLE_SYS_EVENT(WIFI, AP_START); + HANDLE_SYS_EVENT(WIFI, AP_STOP); + HANDLE_SYS_EVENT_ARG(WIFI, AP_STACONNECTED, sta_connected); + HANDLE_SYS_EVENT_ARG(WIFI, AP_STADISCONNECTED, sta_disconnected); + HANDLE_SYS_EVENT_ARG(WIFI, AP_PROBEREQRECVED, ap_probereqrecved); + + /* Ethernet events */ + /* Some extra defines to fit the old naming scheme... */ +#define ETH_EVENT_ETH_START ETHERNET_EVENT_START +#define ETH_EVENT_ETH_STOP ETHERNET_EVENT_STOP +#define ETH_EVENT_ETH_CONNECTED ETHERNET_EVENT_CONNECTED +#define ETH_EVENT_ETH_DISCONNECTED ETHERNET_EVENT_DISCONNECTED + + HANDLE_SYS_EVENT(ETH, ETH_START); + HANDLE_SYS_EVENT(ETH, ETH_STOP); + HANDLE_SYS_EVENT(ETH, ETH_CONNECTED); + HANDLE_SYS_EVENT(ETH, ETH_DISCONNECTED); + + /* IP events */ + HANDLE_SYS_EVENT_ARG(IP, STA_GOT_IP, got_ip); + HANDLE_SYS_EVENT_ARG(IP, ETH_GOT_IP, got_ip); + HANDLE_SYS_EVENT(IP, STA_LOST_IP); + HANDLE_SYS_EVENT_ARG(IP, GOT_IP6, got_ip6); + HANDLE_SYS_EVENT(IP, AP_STAIPASSIGNED); + default: + return ESP_ERR_NOT_SUPPORTED; + } +} + +#ifdef WITH_EVENT_DEBUG + +static const char* TAG = "system_event"; + +static void esp_system_event_debug(const system_event_t* event) +{ + if (event == NULL) { + return; + } + + switch (event->event_id) { + case SYSTEM_EVENT_WIFI_READY: { + ESP_LOGD(TAG, "SYSTEM_EVENT_WIFI_READY"); + break; + } + case SYSTEM_EVENT_SCAN_DONE: { + const system_event_sta_scan_done_t *scan_done = &event->event_info.scan_done; + ESP_LOGD(TAG, "SYSTEM_EVENT_SCAN_DONE, status:%d, number:%d", scan_done->status, scan_done->number); + break; + } + case SYSTEM_EVENT_STA_START: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_START"); + break; + } + case SYSTEM_EVENT_STA_STOP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_STOP"); + break; + } + case SYSTEM_EVENT_STA_CONNECTED: { + const system_event_sta_connected_t *connected = &event->event_info.connected; + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_CONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", channel:%d, authmode:%d", \ + connected->ssid, connected->ssid_len, MAC2STR(connected->bssid), connected->channel, connected->authmode); + break; + } + case SYSTEM_EVENT_STA_DISCONNECTED: { + const system_event_sta_disconnected_t *disconnected = &event->event_info.disconnected; + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", reason:%d", \ + disconnected->ssid, disconnected->ssid_len, MAC2STR(disconnected->bssid), disconnected->reason); + break; + } + case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: { + const system_event_sta_authmode_change_t *auth_change = &event->event_info.auth_change; + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_AUTHMODE_CHNAGE, old_mode:%d, new_mode:%d", auth_change->old_mode, auth_change->new_mode); + break; + } + case SYSTEM_EVENT_STA_GOT_IP: { + const system_event_sta_got_ip_t *got_ip = &event->event_info.got_ip; + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_GOT_IP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR, + IP2STR(&got_ip->ip_info.ip), + IP2STR(&got_ip->ip_info.netmask), + IP2STR(&got_ip->ip_info.gw)); + break; + } + case SYSTEM_EVENT_STA_LOST_IP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_LOST_IP"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_SUCCESS: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_SUCCESS"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_FAILED: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_FAILED"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_TIMEOUT"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_PIN: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_PIN"); + break; + } + case SYSTEM_EVENT_AP_START: { + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_START"); + break; + } + case SYSTEM_EVENT_AP_STOP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STOP"); + break; + } + case SYSTEM_EVENT_AP_STACONNECTED: { + const system_event_ap_staconnected_t *staconnected = &event->event_info.sta_connected; + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STACONNECTED, mac:" MACSTR ", aid:%d", \ + MAC2STR(staconnected->mac), staconnected->aid); + break; + } + case SYSTEM_EVENT_AP_STADISCONNECTED: { + const system_event_ap_stadisconnected_t *stadisconnected = &event->event_info.sta_disconnected; + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STADISCONNECTED, mac:" MACSTR ", aid:%d", \ + MAC2STR(stadisconnected->mac), stadisconnected->aid); + break; + } + case SYSTEM_EVENT_AP_STAIPASSIGNED: { + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STAIPASSIGNED"); + break; + } + case SYSTEM_EVENT_AP_PROBEREQRECVED: { + const system_event_ap_probe_req_rx_t *ap_probereqrecved = &event->event_info.ap_probereqrecved; + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_PROBEREQRECVED, rssi:%d, mac:" MACSTR, \ + ap_probereqrecved->rssi, \ + MAC2STR(ap_probereqrecved->mac)); + break; + } + case SYSTEM_EVENT_GOT_IP6: { + const ip6_addr_t *addr = &event->event_info.got_ip6.ip6_info.ip; + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STA_GOT_IP6 address %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", + IP6_ADDR_BLOCK1(addr), + IP6_ADDR_BLOCK2(addr), + IP6_ADDR_BLOCK3(addr), + IP6_ADDR_BLOCK4(addr), + IP6_ADDR_BLOCK5(addr), + IP6_ADDR_BLOCK6(addr), + IP6_ADDR_BLOCK7(addr), + IP6_ADDR_BLOCK8(addr)); + break; + } + case SYSTEM_EVENT_ETH_START: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_START"); + break; + } + case SYSTEM_EVENT_ETH_STOP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_STOP"); + break; + } + case SYSTEM_EVENT_ETH_CONNECTED: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_CONNECETED"); + break; + } + case SYSTEM_EVENT_ETH_DISCONNECTED: { + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_DISCONNECETED"); + break; + } + case SYSTEM_EVENT_ETH_GOT_IP: { + const system_event_sta_got_ip_t *got_ip = &event->event_info.got_ip; + ESP_LOGD(TAG, "SYSTEM_EVENT_ETH_GOT_IP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR, + IP2STR(&got_ip->ip_info.ip), + IP2STR(&got_ip->ip_info.netmask), + IP2STR(&got_ip->ip_info.gw)); + break; + } + default: { + ESP_LOGW(TAG, "unexpected system event %d!", event->event_id); + break; + } + } +} + +#endif // WITH_EVENT_DEBUG diff --git a/components/esp_event/include/esp_event_legacy.h b/components/esp_event/include/esp_event_legacy.h index 9da523031..aff87e362 100644 --- a/components/esp_event/include/esp_event_legacy.h +++ b/components/esp_event/include/esp_event_legacy.h @@ -1,9 +1,9 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at - +// // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef __ESP_EVENT_H__ -#define __ESP_EVENT_H__ +#pragma once #include #include @@ -26,33 +25,34 @@ extern "C" { #endif +/** System event types enumeration */ typedef enum { - SYSTEM_EVENT_WIFI_READY = 0, /**< ESP32 WiFi ready */ - SYSTEM_EVENT_SCAN_DONE, /**< ESP32 finish scanning AP */ - SYSTEM_EVENT_STA_START, /**< ESP32 station start */ - SYSTEM_EVENT_STA_STOP, /**< ESP32 station stop */ - SYSTEM_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */ - SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */ - SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP32 station changed */ - SYSTEM_EVENT_STA_GOT_IP, /**< ESP32 station got IP from connected AP */ - SYSTEM_EVENT_STA_LOST_IP, /**< ESP32 station lost IP and the IP is reset to 0 */ - SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /**< ESP32 station wps succeeds in enrollee mode */ - SYSTEM_EVENT_STA_WPS_ER_FAILED, /**< ESP32 station wps fails in enrollee mode */ - SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP32 station wps timeout in enrollee mode */ - SYSTEM_EVENT_STA_WPS_ER_PIN, /**< ESP32 station wps pin code in enrollee mode */ - SYSTEM_EVENT_AP_START, /**< ESP32 soft-AP start */ - SYSTEM_EVENT_AP_STOP, /**< ESP32 soft-AP stop */ - SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */ - SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */ - SYSTEM_EVENT_AP_STAIPASSIGNED, /**< ESP32 soft-AP assign an IP to a connected station */ - SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ - SYSTEM_EVENT_GOT_IP6, /**< ESP32 station or ap or ethernet interface v6IP addr is preferred */ - SYSTEM_EVENT_ETH_START, /**< ESP32 ethernet start */ - SYSTEM_EVENT_ETH_STOP, /**< ESP32 ethernet stop */ - SYSTEM_EVENT_ETH_CONNECTED, /**< ESP32 ethernet phy link up */ - SYSTEM_EVENT_ETH_DISCONNECTED, /**< ESP32 ethernet phy link down */ - SYSTEM_EVENT_ETH_GOT_IP, /**< ESP32 ethernet got IP from connected AP */ - SYSTEM_EVENT_MAX + SYSTEM_EVENT_WIFI_READY = 0, /*!< ESP32 WiFi ready */ + SYSTEM_EVENT_SCAN_DONE, /*!< ESP32 finish scanning AP */ + SYSTEM_EVENT_STA_START, /*!< ESP32 station start */ + SYSTEM_EVENT_STA_STOP, /*!< ESP32 station stop */ + SYSTEM_EVENT_STA_CONNECTED, /*!< ESP32 station connected to AP */ + SYSTEM_EVENT_STA_DISCONNECTED, /*!< ESP32 station disconnected from AP */ + SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /*!< the auth mode of AP connected by ESP32 station changed */ + SYSTEM_EVENT_STA_GOT_IP, /*!< ESP32 station got IP from connected AP */ + SYSTEM_EVENT_STA_LOST_IP, /*!< ESP32 station lost IP and the IP is reset to 0 */ + SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /*!< ESP32 station wps succeeds in enrollee mode */ + SYSTEM_EVENT_STA_WPS_ER_FAILED, /*!< ESP32 station wps fails in enrollee mode */ + SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /*!< ESP32 station wps timeout in enrollee mode */ + SYSTEM_EVENT_STA_WPS_ER_PIN, /*!< ESP32 station wps pin code in enrollee mode */ + SYSTEM_EVENT_AP_START, /*!< ESP32 soft-AP start */ + SYSTEM_EVENT_AP_STOP, /*!< ESP32 soft-AP stop */ + SYSTEM_EVENT_AP_STACONNECTED, /*!< a station connected to ESP32 soft-AP */ + SYSTEM_EVENT_AP_STADISCONNECTED, /*!< a station disconnected from ESP32 soft-AP */ + SYSTEM_EVENT_AP_STAIPASSIGNED, /*!< ESP32 soft-AP assign an IP to a connected station */ + SYSTEM_EVENT_AP_PROBEREQRECVED, /*!< Receive probe request packet in soft-AP interface */ + SYSTEM_EVENT_GOT_IP6, /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */ + SYSTEM_EVENT_ETH_START, /*!< ESP32 ethernet start */ + SYSTEM_EVENT_ETH_STOP, /*!< ESP32 ethernet stop */ + SYSTEM_EVENT_ETH_CONNECTED, /*!< ESP32 ethernet phy link up */ + SYSTEM_EVENT_ETH_DISCONNECTED, /*!< ESP32 ethernet phy link down */ + SYSTEM_EVENT_ETH_GOT_IP, /*!< ESP32 ethernet got IP from connected AP */ + SYSTEM_EVENT_MAX /*!< Number of members in this enum */ } system_event_id_t; /* add this macro define for compatible with old IDF version */ @@ -60,98 +60,74 @@ typedef enum { #define SYSTEM_EVENT_AP_STA_GOT_IP6 SYSTEM_EVENT_GOT_IP6 #endif -typedef enum { - WPS_FAIL_REASON_NORMAL = 0, /**< ESP32 WPS normal fail reason */ - WPS_FAIL_REASON_RECV_M2D, /**< ESP32 WPS receive M2D frame */ - WPS_FAIL_REASON_MAX -}system_event_sta_wps_fail_reason_t; -typedef struct { - uint32_t status; /**< status of scanning APs */ - uint8_t number; - uint8_t scan_id; -} system_event_sta_scan_done_t; -typedef struct { - 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_t authmode; -} system_event_sta_connected_t; +/** Argument structure of SYSTEM_EVENT_STA_WPS_ER_FAILED event */ +typedef wifi_event_sta_wps_fail_reason_t system_event_sta_wps_fail_reason_t; -typedef struct { - 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 */ -} system_event_sta_disconnected_t; +/** Argument structure of SYSTEM_EVENT_SCAN_DONE event */ +typedef wifi_event_sta_scan_done_t system_event_sta_scan_done_t; -typedef struct { - wifi_auth_mode_t old_mode; /**< the old auth mode of AP */ - wifi_auth_mode_t new_mode; /**< the new auth mode of AP */ -} system_event_sta_authmode_change_t; +/** Argument structure of SYSTEM_EVENT_STA_CONNECTED event */ +typedef wifi_event_sta_connected_t system_event_sta_connected_t; -typedef struct { - tcpip_adapter_ip_info_t ip_info; - bool ip_changed; -} system_event_sta_got_ip_t; +/** Argument structure of SYSTEM_EVENT_STA_DISCONNECTED event */ +typedef wifi_event_sta_disconnected_t system_event_sta_disconnected_t; -typedef struct { - uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */ -} system_event_sta_wps_er_pin_t; +/** Argument structure of SYSTEM_EVENT_STA_AUTHMODE_CHANGE event */ +typedef wifi_event_sta_authmode_change_t system_event_sta_authmode_change_t; -typedef struct { - tcpip_adapter_if_t if_index; - tcpip_adapter_ip6_info_t ip6_info; -} system_event_got_ip6_t; +/** Argument structure of SYSTEM_EVENT_STA_WPS_ER_PIN event */ +typedef wifi_event_sta_wps_er_pin_t system_event_sta_wps_er_pin_t; -typedef struct { - uint8_t mac[6]; /**< MAC address of the station connected to ESP32 soft-AP */ - uint8_t aid; /**< the aid that ESP32 soft-AP gives to the station connected to */ -} system_event_ap_staconnected_t; +/** Argument structure of event */ +typedef wifi_event_ap_staconnected_t system_event_ap_staconnected_t; -typedef struct { - uint8_t mac[6]; /**< MAC address of the station disconnects to ESP32 soft-AP */ - uint8_t aid; /**< the aid that ESP32 soft-AP gave to the station disconnects to */ -} system_event_ap_stadisconnected_t; +/** Argument structure of event */ +typedef wifi_event_ap_stadisconnected_t system_event_ap_stadisconnected_t; -typedef struct { - int rssi; /**< Received probe request signal strength */ - uint8_t mac[6]; /**< MAC address of the station which send probe request */ -} system_event_ap_probe_req_rx_t; +/** Argument structure of event */ +typedef wifi_event_ap_probe_req_rx_t system_event_ap_probe_req_rx_t; -typedef struct { - ip4_addr_t ip; -} system_event_ap_staipassigned_t; +/** Argument structure of event */ +typedef ip_event_ap_staipassigned_t system_event_ap_staipassigned_t; +/** Argument structure of event */ +typedef ip_event_got_ip_t system_event_sta_got_ip_t; + +/** Argument structure of event */ +typedef ip_event_got_ip6_t system_event_got_ip6_t; + +/** Union of all possible system_event argument structures */ typedef union { - system_event_sta_connected_t connected; /**< ESP32 station connected to AP */ - system_event_sta_disconnected_t disconnected; /**< ESP32 station disconnected to AP */ - system_event_sta_scan_done_t scan_done; /**< ESP32 station scan (APs) done */ - system_event_sta_authmode_change_t auth_change; /**< the auth mode of AP ESP32 station connected to changed */ - system_event_sta_got_ip_t got_ip; /**< ESP32 station got IP, first time got IP or when IP is changed */ - system_event_sta_wps_er_pin_t sta_er_pin; /**< ESP32 station WPS enrollee mode PIN code received */ - system_event_sta_wps_fail_reason_t sta_er_fail_reason;/**< ESP32 station WPS enrollee mode failed reason code received */ - system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP32 soft-AP */ - system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP32 soft-AP */ - system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP32 soft-AP receive probe request packet */ + system_event_sta_connected_t connected; /*!< ESP32 station connected to AP */ + system_event_sta_disconnected_t disconnected; /*!< ESP32 station disconnected to AP */ + system_event_sta_scan_done_t scan_done; /*!< ESP32 station scan (APs) done */ + system_event_sta_authmode_change_t auth_change; /*!< the auth mode of AP ESP32 station connected to changed */ + system_event_sta_got_ip_t got_ip; /*!< ESP32 station got IP, first time got IP or when IP is changed */ + system_event_sta_wps_er_pin_t sta_er_pin; /*!< ESP32 station WPS enrollee mode PIN code received */ + system_event_sta_wps_fail_reason_t sta_er_fail_reason; /*!< ESP32 station WPS enrollee mode failed reason code received */ + system_event_ap_staconnected_t sta_connected; /*!< a station connected to ESP32 soft-AP */ + system_event_ap_stadisconnected_t sta_disconnected; /*!< a station disconnected to ESP32 soft-AP */ + system_event_ap_probe_req_rx_t ap_probereqrecved; /*!< ESP32 soft-AP receive probe request packet */ system_event_ap_staipassigned_t ap_staipassigned; /**< ESP32 soft-AP assign an IP to the station*/ - system_event_got_ip6_t got_ip6; /**< ESP32 station or ap or ethernet ipv6 addr state change to preferred */ + system_event_got_ip6_t got_ip6; /*!< ESP32 station or ap or ethernet ipv6 addr state change to preferred */ } system_event_info_t; +/** Event, as a tagged enum */ typedef struct { - system_event_id_t event_id; /**< event ID */ - system_event_info_t event_info; /**< event information */ + system_event_id_t event_id; /*!< event ID */ + system_event_info_t event_info; /*!< event information */ } system_event_t; +/** Event handler function type */ typedef esp_err_t (*system_event_handler_t)(system_event_t *event); /** * @brief Send a event to event task * - * @attention 1. Other task/modules, such as the TCPIP module, can call this API to send an event to event task + * Other task/modules, such as the tcpip_adapter, can call this API to send an event to event task * - * @param system_event_t * event : event + * @param event Event to send * * @return ESP_OK : succeed * @return others : fail @@ -159,18 +135,18 @@ typedef esp_err_t (*system_event_handler_t)(system_event_t *event); esp_err_t esp_event_send(system_event_t *event); /** - * @brief Default event handler for system events - * - * This function performs default handling of system events. - * When using esp_event_loop APIs, it is called automatically before invoking the user-provided - * callback function. - * - * Applications which implement a custom event loop must call this function - * as part of event processing. - * - * @param event pointer to event to be handled - * @return ESP_OK if an event was handled successfully - */ + * @brief Default event handler for system events + * + * This function performs default handling of system events. + * When using esp_event_loop APIs, it is called automatically before invoking the user-provided + * callback function. + * + * Applications which implement a custom event loop must call this function + * as part of event processing. + * + * @param event pointer to event to be handled + * @return ESP_OK if an event was handled successfully + */ esp_err_t esp_event_process_default(system_event_t *event); /** @@ -185,8 +161,46 @@ void esp_event_set_default_eth_handlers(); */ void esp_event_set_default_wifi_handlers(); +/** + * @brief Application specified event callback function + * + * @param ctx reserved for user + * @param event event type defined in this file + * + * @return + * - ESP_OK: succeed + * - others: fail + */ +typedef esp_err_t (*system_event_cb_t)(void *ctx, system_event_t *event); + +/** + * @brief Initialize event loop + * + * Create the event handler and task + * + * @param cb application specified event callback, it can be modified by call esp_event_set_cb + * @param ctx reserved for user + * + * @return + * - ESP_OK: succeed + * - others: fail + */ +esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx); + +/** + * @brief Set application specified event callback function + * + * @attention 1. If cb is NULL, means application don't need to handle + * If cb is not NULL, it will be call when an event is received, after the default event callback is completed + * + * @param cb application callback function + * @param ctx argument to be passed to callback + * + * @return old callback + */ +system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx); + #ifdef __cplusplus } #endif -#endif /* __ESP_EVENT_H__ */ diff --git a/components/esp_event/include/esp_event_loop.h b/components/esp_event/include/esp_event_loop.h index 97672aedf..6267ee37d 100644 --- a/components/esp_event/include/esp_event_loop.h +++ b/components/esp_event/include/esp_event_loop.h @@ -1,81 +1 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef __ESP_EVENT_LOOP_H__ -#define __ESP_EVENT_LOOP_H__ - -#include -#include - -#include "esp_err.h" -#include "esp_event.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Application specified event callback function - * - * @param void *ctx : reserved for user - * @param system_event_t *event : event type defined in this file - * - * @return ESP_OK : succeed - * @return others : fail - */ -typedef esp_err_t (*system_event_cb_t)(void *ctx, system_event_t *event); - -/** - * @brief Initialize event loop - * Create the event handler and task - * - * @param system_event_cb_t cb : application specified event callback, it can be modified by call esp_event_set_cb - * @param void *ctx : reserved for user - * - * @return ESP_OK : succeed - * @return others : fail - */ -esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx); - -/** - * @brief Set application specified event callback function - * - * @attention 1. If cb is NULL, means application don't need to handle - * If cb is not NULL, it will be call when an event is received, after the default event callback is completed - * - * @param system_event_cb_t cb : callback - * @param void *ctx : reserved for user - * - * @return system_event_cb_t : old callback - */ -system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx); - -/** - * @brief Get the queue used by event loop - * - * @attention : currently this API is used to initialize "q" parameter - * of wifi_init structure. - * - * @return QueueHandle_t : event queue handle - */ -QueueHandle_t esp_event_loop_get_queue(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* __ESP_EVENT_LOOP_H__ */ +#include "esp_event_legacy.h" diff --git a/components/esp_wifi/src/mesh_event.c b/components/esp_wifi/src/mesh_event.c new file mode 100644 index 000000000..a2a2e1a72 --- /dev/null +++ b/components/esp_wifi/src/mesh_event.c @@ -0,0 +1,36 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "esp_event.h" +#include "esp_mesh.h" + +/* mesh event callback handler */ +mesh_event_cb_t g_mesh_event_cb = NULL; + +void esp_event_mesh_hook(system_event_t* event) +{ + if (event->event_id == SYSTEM_EVENT_STA_GOT_IP || event->event_id == SYSTEM_EVENT_STA_LOST_IP) { + if (g_mesh_event_cb) { + mesh_event_t mevent; + if (event->event_id == SYSTEM_EVENT_STA_GOT_IP) { + mevent.id = MESH_EVENT_ROOT_GOT_IP; + memcpy(&mevent.info.got_ip, &event->event_info.got_ip, sizeof(system_event_sta_got_ip_t)); + } else { + mevent.id = MESH_EVENT_ROOT_LOST_IP; + } + g_mesh_event_cb(mevent); + } + } +} diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 9176e76e4..2091e1b50 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -18,10 +18,7 @@ #include "esp_private/wifi.h" #include "esp_pm.h" #include "soc/rtc.h" -#include "esp_mesh.h" -/* mesh event callback handler */ -mesh_event_cb_t g_mesh_event_cb = NULL; ESP_EVENT_DEFINE_BASE(WIFI_EVENT); #ifdef CONFIG_PM_ENABLE @@ -31,6 +28,8 @@ static esp_pm_lock_handle_t s_wifi_modem_sleep_lock; /* Callback function to update WiFi MAC time */ wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb = NULL; +static const char* TAG = "wifi_init"; + static void __attribute__((constructor)) s_set_default_wifi_log_level() { /* WiFi libraries aren't compiled to know CONFIG_LOG_DEFAULT_LEVEL, @@ -99,7 +98,10 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) } } #endif - esp_event_set_default_wifi_handlers(); + esp_err_t err = tcpip_adapter_set_default_wifi_handlers(); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to set default Wi-Fi event handlers (0x%x)", err); + } esp_err_t result = esp_wifi_init_internal(config); if (result == ESP_OK) { esp_wifi_set_debug_log(); diff --git a/components/esp_wifi/test/test_wifi.c b/components/esp_wifi/test/test_wifi.c index 08996d9de..7b2c4e4b3 100644 --- a/components/esp_wifi/test/test_wifi.c +++ b/components/esp_wifi/test/test_wifi.c @@ -142,9 +142,15 @@ TEST_CASE("wifi stop and deinit","[wifi]") TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of tcpip_adapter and event_loop."); } +static esp_err_t event_send_dummy(system_event_t *event) +{ + return ESP_OK; +} + static void start_wifi_as_softap(void) { wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + cfg.event_handler = &event_send_dummy; cfg.nvs_enable = false; wifi_config_t w_config = { diff --git a/components/ethernet/emac_main.c b/components/ethernet/emac_main.c index e1b402aa3..3019c25a3 100644 --- a/components/ethernet/emac_main.c +++ b/components/ethernet/emac_main.c @@ -1068,7 +1068,7 @@ esp_err_t IRAM_ATTR emac_post(emac_sig_t sig, emac_par_t par) esp_err_t esp_eth_init(eth_config_t *config) { - esp_event_set_default_eth_handlers(); + tcpip_adapter_set_default_eth_handlers(); return esp_eth_init_internal(config); } diff --git a/components/tcpip_adapter/CMakeLists.txt b/components/tcpip_adapter/CMakeLists.txt index 2868696ac..b728811ef 100644 --- a/components/tcpip_adapter/CMakeLists.txt +++ b/components/tcpip_adapter/CMakeLists.txt @@ -1,4 +1,5 @@ -set(COMPONENT_SRCS "tcpip_adapter_lwip.c") +set(COMPONENT_SRCS "event_handlers.c" + "tcpip_adapter_lwip.c") set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_REQUIRES lwip) diff --git a/components/tcpip_adapter/event_handlers.c b/components/tcpip_adapter/event_handlers.c new file mode 100644 index 000000000..ff7847b28 --- /dev/null +++ b/components/tcpip_adapter/event_handlers.c @@ -0,0 +1,310 @@ +// Copyright 2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "tcpip_adapter.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_private/wifi.h" +#include "esp_eth.h" +#include "esp_err.h" +#include "esp_log.h" + +static const char* TAG = "tcpip_adapter"; + +#define API_CALL_CHECK(info, api_call, ret) \ +do{\ + esp_err_t __err = (api_call);\ + if ((ret) != __err) {\ + ESP_LOGE(TAG, "%s %d %s ret=0x%X", __FUNCTION__, __LINE__, (info), __err);\ + return;\ + }\ +} while(0) + +typedef esp_err_t (*system_event_handler_t)(system_event_t *e); + +static void handle_ap_start(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_ap_stop(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_sta_start(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_sta_stop(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_sta_connected(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_sta_disconnected(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_sta_got_ip(void* arg, esp_event_base_t base, int32_t event_id, void* data); + +static void handle_eth_start(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_eth_stop(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_eth_connected(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_eth_disconnected(void* arg, esp_event_base_t base, int32_t event_id, void* data); +static void handle_eth_got_ip(void* arg, esp_event_base_t base, int32_t event_id, void* data); + +static void handle_eth_start(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_ip_info_t eth_ip; + uint8_t eth_mac[6]; + + esp_eth_get_mac(eth_mac); + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, ð_ip); + tcpip_adapter_eth_start(eth_mac, ð_ip); +} + +static void handle_eth_stop(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_stop(TCPIP_ADAPTER_IF_ETH); +} + +static void handle_eth_connected(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_dhcp_status_t status; + + tcpip_adapter_up(TCPIP_ADAPTER_IF_ETH); + + tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &status); + + if (status == TCPIP_ADAPTER_DHCP_INIT) { + tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH); + } else if (status == TCPIP_ADAPTER_DHCP_STOPPED) { + tcpip_adapter_ip_info_t eth_ip; + + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, ð_ip); + + if (!(ip4_addr_isany_val(eth_ip.ip) || ip4_addr_isany_val(eth_ip.netmask))) { + system_event_t evt; + + //notify event + evt.event_id = SYSTEM_EVENT_ETH_GOT_IP; + memcpy(&evt.event_info.got_ip.ip_info, ð_ip, sizeof(tcpip_adapter_ip_info_t)); + + esp_event_send(&evt); + } else { + ESP_LOGE(TAG, "invalid static ip"); + } + } +} + +static void handle_eth_disconnected(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_down(TCPIP_ADAPTER_IF_ETH); +} + +static void handle_sta_got_ip(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + API_CALL_CHECK("esp_wifi_internal_set_sta_ip", esp_wifi_internal_set_sta_ip(), ESP_OK); + + const ip_event_got_ip_t* event= (const ip_event_got_ip_t*) data; + ESP_LOGI(TAG, "sta ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, + IP2STR(&event->ip_info.ip), + IP2STR(&event->ip_info.netmask), + IP2STR(&event->ip_info.gw)); +} + +static void handle_eth_got_ip(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + const ip_event_got_ip_t* event= (const ip_event_got_ip_t*) data; + ESP_LOGI(TAG, "eth ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, + IP2STR(&event->ip_info.ip), + IP2STR(&event->ip_info.netmask), + IP2STR(&event->ip_info.gw)); +} + +static void handle_ap_start(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_ip_info_t ap_ip; + uint8_t ap_mac[6]; + + API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, (wifi_rxcb_t)tcpip_adapter_ap_input), ESP_OK); + API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_AP, ap_mac), ESP_OK); + + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ap_ip); + tcpip_adapter_ap_start(ap_mac, &ap_ip); +} + +static void handle_ap_stop(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, NULL), ESP_OK); + + tcpip_adapter_stop(TCPIP_ADAPTER_IF_AP); +} + +static void handle_sta_start(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_ip_info_t sta_ip; + uint8_t sta_mac[6]; + + API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_STA, sta_mac), ESP_OK); + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); + tcpip_adapter_sta_start(sta_mac, &sta_ip); +} + +static void handle_sta_stop(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_stop(TCPIP_ADAPTER_IF_STA); +} + +static void handle_sta_connected(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_dhcp_status_t status; + + API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK); + + tcpip_adapter_up(TCPIP_ADAPTER_IF_STA); + + tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &status); + + if (status == TCPIP_ADAPTER_DHCP_INIT) { + tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA); + } else if (status == TCPIP_ADAPTER_DHCP_STOPPED) { + tcpip_adapter_ip_info_t sta_ip; + tcpip_adapter_ip_info_t sta_old_ip; + + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); + tcpip_adapter_get_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_old_ip); + + if (!(ip4_addr_isany_val(sta_ip.ip) || ip4_addr_isany_val(sta_ip.netmask))) { + system_event_t evt; + + evt.event_id = SYSTEM_EVENT_STA_GOT_IP; + evt.event_info.got_ip.ip_changed = false; + + if (memcmp(&sta_ip, &sta_old_ip, sizeof(sta_ip))) { + evt.event_info.got_ip.ip_changed = true; + } + + memcpy(&evt.event_info.got_ip.ip_info, &sta_ip, sizeof(tcpip_adapter_ip_info_t)); + tcpip_adapter_set_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); + + esp_event_send(&evt); + ESP_LOGD(TAG, "static ip: ip changed=%d", evt.event_info.got_ip.ip_changed); + } else { + ESP_LOGE(TAG, "invalid static ip"); + } + } +} + +static void handle_sta_disconnected(void* arg, esp_event_base_t base, int32_t event_id, void* data) +{ + tcpip_adapter_down(TCPIP_ADAPTER_IF_STA); + API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, NULL), ESP_OK); +} + + +esp_err_t tcpip_adapter_set_default_wifi_handlers() +{ + esp_err_t err; + err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_START, handle_sta_start, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_STOP, handle_sta_stop, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, handle_sta_connected, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, handle_sta_disconnected, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_START, handle_ap_start, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_STOP, handle_ap_stop, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, handle_sta_got_ip, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, handle_eth_got_ip, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_register_shutdown_handler((shutdown_handler_t)esp_wifi_stop); + if (err != ESP_OK) { + goto fail; + } + + return ESP_OK; + +fail: + tcpip_adapter_clear_default_wifi_handlers(); + return err; +} + +esp_err_t tcpip_adapter_clear_default_wifi_handlers() +{ + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_START, handle_sta_start); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP, handle_sta_stop); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, handle_sta_connected); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, handle_sta_disconnected); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_AP_START, handle_ap_start); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_AP_STOP, handle_ap_stop); + esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, handle_sta_got_ip); + esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, handle_eth_got_ip); + + /* TODO: introduce esp_unregister_shutdown_handler or similar, call it here */ + + return ESP_OK; +} + +esp_err_t tcpip_adapter_set_default_eth_handlers() +{ + esp_err_t err; + err = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_START, handle_eth_start, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_STOP, handle_eth_stop, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, handle_eth_connected, NULL); + if (err != ESP_OK) { + goto fail; + } + + err = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, handle_eth_disconnected, NULL); + if (err != ESP_OK) { + goto fail; + } + + return ESP_OK; + +fail: + tcpip_adapter_clear_default_eth_handlers(); + return err; +} + +esp_err_t tcpip_adapter_clear_default_eth_handlers() +{ + esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_START, handle_eth_start); + esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_STOP, handle_eth_stop); + esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, handle_eth_connected); + esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, handle_eth_disconnected); + + return ESP_OK; +} diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index d3f5b3216..395398426 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -168,6 +168,12 @@ typedef struct { tcpip_adapter_ip6_info_t ip6_info; /*!< IPv6 address of the interface */ } ip_event_got_ip6_t; +/** Event structure for IP_EVENT_AP_STAIPASSIGNED event */ +typedef struct { + ip4_addr_t ip; /*!< IP address which was assigned to the station */ +} ip_event_ap_staipassigned_t; + + /** * @brief Initialize the underlying TCP/IP stack * @@ -686,6 +692,40 @@ esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif); */ bool tcpip_adapter_is_netif_up(tcpip_adapter_if_t tcpip_if); + +/** + * @brief Install default event handlers for Ethernet interface + * @return + * - ESP_OK on success + * - one of the errors from esp_event on failure + */ +esp_err_t tcpip_adapter_set_default_eth_handlers(); + +/** + * @brief Uninstall default event handlers for Ethernet interface + * @return + * - ESP_OK on success + * - one of the errors from esp_event on failure + */ +esp_err_t tcpip_adapter_clear_default_eth_handlers(); + +/** + * @brief Install default event handlers for Wi-Fi interfaces (station and AP) + * @return + * - ESP_OK on success + * - one of the errors from esp_event on failure + */ +esp_err_t tcpip_adapter_set_default_wifi_handlers(); + +/** + * @brief Uninstall default event handlers for Wi-Fi interfaces (station and AP) + * @return + * - ESP_OK on success + * - one of the errors from esp_event on failure + */ +esp_err_t tcpip_adapter_clear_default_wifi_handlers(); + + #ifdef __cplusplus } #endif diff --git a/examples/wifi/iperf/iperf_test.py b/examples/wifi/iperf/iperf_test.py index b51eb8fa8..c350b899c 100644 --- a/examples/wifi/iperf/iperf_test.py +++ b/examples/wifi/iperf/iperf_test.py @@ -336,7 +336,7 @@ class IperfTestUtility(object): else: raise AssertionError("Failed to scan AP") self.dut.write("sta {} {}".format(self.ap_ssid, self.ap_password)) - dut_ip = self.dut.expect(re.compile(r"event: sta ip: ([\d.]+), mask: ([\d.]+), gw: ([\d.]+)"))[0] + dut_ip = self.dut.expect(re.compile(r"sta ip: ([\d.]+), mask: ([\d.]+), gw: ([\d.]+)"))[0] return dut_ip, rssi def _save_test_result(self, test_case, raw_data, att, rssi, heap_size): From a2d59525e53099ee1ad63c3d60ff853f573ab535 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 21 Nov 2018 13:46:45 +0800 Subject: [PATCH 06/13] mdns: use esp_event library to handle events --- components/esp32/CMakeLists.txt | 1 - components/esp_wifi/CMakeLists.txt | 1 + components/mdns/mdns.c | 142 ++++++++++++------ .../mdns/private_include/mdns_networking.h | 3 +- .../mdns/private_include/mdns_private.h | 5 +- .../protocols/mdns/main/mdns_example_main.c | 2 +- 6 files changed, 100 insertions(+), 54 deletions(-) diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 9749eef58..a6b61623e 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -24,7 +24,6 @@ else() "hw_random.c" "int_wdt.c" "intr_alloc.c" - "mesh_event.c" "panic.c" "pm_esp32.c" "pm_trace.c" diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index 433d20f72..63ec85038 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -2,6 +2,7 @@ set(COMPONENT_SRCS "src/coexist.c" "src/fast_crypto_ops.c" "src/lib_printf.c" + "src/mesh_event.c" "src/phy_init.c" "src/restore.c" "src/wifi_init.c") diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 0f52ecf8e..8c9767942 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -3048,56 +3048,69 @@ void _mdns_disable_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protoc /** * @brief Dispatch interface changes based on system events */ -void _mdns_handle_system_event(system_event_id_t event, tcpip_adapter_if_t interface) +static void _mdns_handle_system_event(esp_event_base_t event_base, + int32_t event_id, tcpip_adapter_if_t interface) { if (!_mdns_server) { return; } - + tcpip_adapter_dhcp_status_t dcst; - switch(event) { - case SYSTEM_EVENT_STA_CONNECTED: - if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &dcst)) { - if (dcst != TCPIP_ADAPTER_DHCP_STARTED) { + if (event_base == WIFI_EVENT) { + switch(event_id) { + case WIFI_EVENT_STA_CONNECTED: + if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &dcst)) { + if (dcst != TCPIP_ADAPTER_DHCP_STARTED) { + _mdns_enable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4); + } + } + break; + case WIFI_EVENT_STA_DISCONNECTED: + _mdns_disable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4); + _mdns_disable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V6); + break; + case WIFI_EVENT_AP_START: + _mdns_enable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V4); + break; + case WIFI_EVENT_AP_STOP: + _mdns_disable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V4); + _mdns_disable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V6); + break; + default: + break; + } + } else if (event_base == ETH_EVENT) { + switch (event_id) { + case ETHERNET_EVENT_CONNECTED: + if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &dcst)) { + if (dcst != TCPIP_ADAPTER_DHCP_STARTED) { + _mdns_enable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4); + } + } + break; + case ETHERNET_EVENT_DISCONNECTED: + _mdns_disable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4); + _mdns_disable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V6); + break; + default: + break; + } + } else if (event_base == IP_EVENT) { + switch (event_id) { + case IP_EVENT_STA_GOT_IP: _mdns_enable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4); - } - } - break; - case SYSTEM_EVENT_STA_GOT_IP: - _mdns_enable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4); - _mdns_announce_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V6, NULL, 0, true); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - _mdns_disable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4); - _mdns_disable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V6); - break; - case SYSTEM_EVENT_AP_START: - _mdns_enable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V4); - break; - case SYSTEM_EVENT_AP_STOP: - _mdns_disable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V4); - _mdns_disable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V6); - break; - case SYSTEM_EVENT_GOT_IP6: - _mdns_enable_pcb(interface, MDNS_IP_PROTOCOL_V6); - _mdns_announce_pcb(interface, MDNS_IP_PROTOCOL_V4, NULL, 0, true); - break; - case SYSTEM_EVENT_ETH_CONNECTED: - if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &dcst)) { - if (dcst != TCPIP_ADAPTER_DHCP_STARTED) { + _mdns_announce_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V6, NULL, 0, true); + break; + case IP_EVENT_ETH_GOT_IP: _mdns_enable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4); - } + break; + case IP_EVENT_GOT_IP6: + _mdns_enable_pcb(interface, MDNS_IP_PROTOCOL_V6); + _mdns_announce_pcb(interface, MDNS_IP_PROTOCOL_V4, NULL, 0, true); + break; + default: + break; } - break; - case SYSTEM_EVENT_ETH_GOT_IP: - _mdns_enable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4); - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - _mdns_disable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4); - _mdns_disable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V6); - break; - default: - break; } } @@ -3709,7 +3722,8 @@ static void _mdns_execute_action(mdns_action_t * action) switch(action->type) { case ACTION_SYSTEM_EVENT: - _mdns_handle_system_event(action->data.sys_event.event_id, action->data.sys_event.interface); + _mdns_handle_system_event(action->data.sys_event.event_base, + action->data.sys_event.event_id, action->data.sys_event.interface); break; case ACTION_HOSTNAME_SET: _mdns_send_final_bye(true); @@ -4098,23 +4112,34 @@ static esp_err_t _mdns_service_task_stop() * */ esp_err_t mdns_handle_system_event(void *ctx, system_event_t *event) +{ + /* no-op, kept for compatibility */ + return ESP_OK; +} + +static void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { if (!_mdns_server) { - return ESP_OK; + return; } - mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); + mdns_action_t * action = (mdns_action_t *)calloc(1, sizeof(mdns_action_t)); if (!action) { HOOK_MALLOC_FAILED; - return ESP_OK; + return; } action->type = ACTION_SYSTEM_EVENT; - action->data.sys_event.event_id = event->event_id; - action->data.sys_event.interface = (event->event_id == SYSTEM_EVENT_GOT_IP6)?event->event_info.got_ip6.if_index:0; + action->data.sys_event.event_base = event_base; + action->data.sys_event.event_id = event_id; + if (event_base == IP_EVENT && event_id == IP_EVENT_GOT_IP6) { + ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data; + action->data.sys_event.interface = event->if_index; + } + if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) { free(action); - } - return ESP_OK; + } } esp_err_t mdns_init() @@ -4144,6 +4169,16 @@ esp_err_t mdns_init() goto free_lock; } + if ((err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) { + goto free_event_handlers; + } + if ((err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) { + goto free_event_handlers; + } + if ((err = esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) { + goto free_event_handlers; + } + uint8_t i; ip6_addr_t tmp_addr6; tcpip_adapter_ip_info_t if_ip_info; @@ -4170,6 +4205,10 @@ free_all_and_disable_pcbs: _mdns_disable_pcb(i, MDNS_IP_PROTOCOL_V6); _mdns_disable_pcb(i, MDNS_IP_PROTOCOL_V4); } +free_event_handlers: + esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler); + esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler); + esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler); vQueueDelete(_mdns_server->action_queue); free_lock: vSemaphoreDelete(_mdns_server->lock); @@ -4215,6 +4254,9 @@ void mdns_free() free(h); } vSemaphoreDelete(_mdns_server->lock); + esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler); + esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler); + esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler); free(_mdns_server); _mdns_server = NULL; } diff --git a/components/mdns/private_include/mdns_networking.h b/components/mdns/private_include/mdns_networking.h index 5b56f8066..1d13e308f 100644 --- a/components/mdns/private_include/mdns_networking.h +++ b/components/mdns/private_include/mdns_networking.h @@ -20,7 +20,8 @@ #include "esp_wifi.h" #include "esp_system.h" #include "esp_timer.h" -#include "esp_event_loop.h" +#include "esp_event.h" +#include "esp_eth.h" /** diff --git a/components/mdns/private_include/mdns_private.h b/components/mdns/private_include/mdns_private.h index a7383c03d..a5b0747aa 100644 --- a/components/mdns/private_include/mdns_private.h +++ b/components/mdns/private_include/mdns_private.h @@ -14,6 +14,8 @@ #ifndef MDNS_PRIVATE_H_ #define MDNS_PRIVATE_H_ +#include "esp_event_base.h" + //#define MDNS_ENABLE_DEBUG #ifdef MDNS_ENABLE_DEBUG @@ -346,7 +348,8 @@ typedef struct { char * hostname; char * instance; struct { - system_event_id_t event_id; + esp_event_base_t event_base; + int32_t event_id; tcpip_adapter_if_t interface; } sys_event; struct { diff --git a/examples/protocols/mdns/main/mdns_example_main.c b/examples/protocols/mdns/main/mdns_example_main.c index 27d7d2b43..20cdbc3b0 100644 --- a/examples/protocols/mdns/main/mdns_example_main.c +++ b/examples/protocols/mdns/main/mdns_example_main.c @@ -247,8 +247,8 @@ static void mdns_example_task(void *pvParameters) void app_main() { ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_mdns(); initialise_wifi(); + initialise_mdns(); initialise_button(); xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL); } From 6890ea09cdda310cf6ba4892b1c263ff09fcc3be Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 21 Nov 2018 15:56:06 +0800 Subject: [PATCH 07/13] docs: add event handling API guide --- .../esp_event/include/esp_event_legacy.h | 17 +- docs/Doxyfile | 7 +- docs/en/api-guides/event-handling.rst | 145 ++++++++++++++ docs/en/api-guides/index.rst | 1 + docs/en/api-guides/wifi.rst | 177 +++++++++--------- docs/en/api-reference/network/esp_mesh.rst | 2 + docs/en/api-reference/system/esp_event.rst | 12 +- .../api-reference/system/esp_event_legacy.rst | 7 + docs/zh_CN/api-guides/event-handling.rst | 1 + docs/zh_CN/api-guides/index.rst | 1 + .../api-reference/system/esp_event_legacy.rst | 1 + 11 files changed, 274 insertions(+), 97 deletions(-) create mode 100644 docs/en/api-guides/event-handling.rst create mode 100644 docs/en/api-reference/system/esp_event_legacy.rst create mode 100644 docs/zh_CN/api-guides/event-handling.rst create mode 100644 docs/zh_CN/api-reference/system/esp_event_legacy.rst diff --git a/components/esp_event/include/esp_event_legacy.h b/components/esp_event/include/esp_event_legacy.h index aff87e362..7748f69a0 100644 --- a/components/esp_event/include/esp_event_legacy.h +++ b/components/esp_event/include/esp_event_legacy.h @@ -125,6 +125,8 @@ typedef esp_err_t (*system_event_handler_t)(system_event_t *event); /** * @brief Send a event to event task * + * @note This API is part of the legacy event system. New code should use event library API in esp_event.h + * * Other task/modules, such as the tcpip_adapter, can call this API to send an event to event task * * @param event Event to send @@ -137,6 +139,8 @@ esp_err_t esp_event_send(system_event_t *event); /** * @brief Default event handler for system events * + * @note This API is part of the legacy event system. New code should use event library API in esp_event.h + * * This function performs default handling of system events. * When using esp_event_loop APIs, it is called automatically before invoking the user-provided * callback function. @@ -152,18 +156,24 @@ esp_err_t esp_event_process_default(system_event_t *event); /** * @brief Install default event handlers for Ethernet interface * + * @note This API is part of the legacy event system. New code should use event library API in esp_event.h + * */ void esp_event_set_default_eth_handlers(); /** * @brief Install default event handlers for Wi-Fi interfaces (station and AP) * + * @note This API is part of the legacy event system. New code should use event library API in esp_event.h */ void esp_event_set_default_wifi_handlers(); /** * @brief Application specified event callback function * + * @note This API is part of the legacy event system. New code should use event library API in esp_event.h + * + * * @param ctx reserved for user * @param event event type defined in this file * @@ -175,7 +185,9 @@ typedef esp_err_t (*system_event_cb_t)(void *ctx, system_event_t *event); /** * @brief Initialize event loop - * + * + * @note This API is part of the legacy event system. New code should use event library API in esp_event.h + * * Create the event handler and task * * @param cb application specified event callback, it can be modified by call esp_event_set_cb @@ -190,12 +202,15 @@ esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx); /** * @brief Set application specified event callback function * + * @note This API is part of the legacy event system. New code should use event library API in esp_event.h + * * @attention 1. If cb is NULL, means application don't need to handle * If cb is not NULL, it will be call when an event is received, after the default event callback is completed * * @param cb application callback function * @param ctx argument to be passed to callback * + * * @return old callback */ system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx); diff --git a/docs/Doxyfile b/docs/Doxyfile index 5e91f268c..8190b866c 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -30,6 +30,10 @@ INPUT = \ ../../components/esp_wifi/include/esp_now.h \ ## Mesh - API Reference ../../components/esp_wifi/include/esp_mesh.h \ + ## Event loop - API Reference + ../../components/esp_event/include/esp_event.h \ + ../../components/esp_event/include/esp_event_base.h \ + ../../components/esp_event/include/esp_event_legacy.h \ ## Bluetooth - API Reference ## Controller && VHCI ../../components/bt/include/esp_bt.h \ @@ -233,7 +237,8 @@ PREDEFINED = \ configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS=1 \ configNUM_THREAD_LOCAL_STORAGE_POINTERS=1 \ configUSE_APPLICATION_TASK_TAG=1 \ - configTASKLIST_INCLUDE_COREID=1 + configTASKLIST_INCLUDE_COREID=1 \ + "ESP_EVENT_DECLARE_BASE(x)=extern esp_event_base_t x" ## Do not complain about not having dot ## diff --git a/docs/en/api-guides/event-handling.rst b/docs/en/api-guides/event-handling.rst new file mode 100644 index 000000000..1fdcb94ac --- /dev/null +++ b/docs/en/api-guides/event-handling.rst @@ -0,0 +1,145 @@ +Event Handling +============== + +Several ESP-IDF components use *events* to inform application about state changes, such as connection or disconnection. This document gives an overview of these event mechanisms. + +Wi-Fi, Ethernet, and IP Events +------------------------------ + +Before the introduction of :doc:`esp_event library<../api-reference/system/esp_event>`, events from Wi-Fi driver, Ethernet driver, and TCP/IP stack were dispatched using the so-called *legacy event loop*. The following sections explain each of the methods. + +esp_event Library Event Loop +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +esp_event library is designed to supersede the legacy event loop for the purposes of event handling in ESP-IDF. In the legacy event loop, all possible event types and event data structures had to be defined in :cpp:type:`system_event_id_t` enumeration and :cpp:type:`system_event_info_t` union, which made it impossible to send custom events to the event loop, and use the event loop for other kinds of events (e.g. Mesh). Legacy event loop also supported only one event handler function, therefore application components could not handle some of Wi-Fi or IP events themselves, and required application to forward these events from its event handler function. + +See :doc:`esp_event library API reference<../api-reference/system/esp_event>` for general information on using this library. Wi-Fi, Ethernet, and IP events are sent to the :ref:`default event loop ` provided by this library. + +.. _legacy-event-loop: + +Legacy Event Loop +~~~~~~~~~~~~~~~~~ + +This event loop implementation is started using :cpp:func:`esp_event_loop_init` function. Application typically supplies an *event handler*, a function with the following signature:: + + esp_err_t event_handler(void *ctx, system_event_t *event) + { + } + +Both the pointer to event handler function, and an arbitrary context pointer are passed to :cpp:func:`esp_event_loop_init`. + +When Wi-Fi, Ethernet, or IP stack generate an event, this event is sent to a high-priority ``event`` task via a queue. Application-provided event handler function is called in the context of this task. Event task stack size and event queue size can be adjusted using :ref:`CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE` and :ref:`CONFIG_SYSTEM_EVENT_QUEUE_SIZE` options, respectively. + +Event handler receives a pointer to the event structure (:cpp:type:`system_event_t`) which describes current event. This structure follows a *tagged union* pattern: ``event_id`` member indicates the type of event, and ``event_info`` member is a union of description structures. Application event handler will typically use ``switch(event->event_id)`` to handle different kinds of events. + +If application event handler needs to relay the event to some other task, it is important to note that event pointer passed to the event handler is a pointer to temporary structure. To pass the event to another task, application has to make a copy of the entire structure. + + +Event IDs and Corresponding Data Structures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++------------------------------------+-----------------------------------------------+ +| Event ID | Event data structure | +| (legacy event ID) | | ++------------------------------------+-----------------------------------------------+ +| **Wi-Fi** | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_WIFI_READY | n/a | +| (SYSTEM_EVENT_WIFI_READY) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_SCAN_DONE | :cpp:class:`wifi_event_sta_scan_done_t` | +| (SYSTEM_EVENT_SCAN_DONE) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_START | n/a | +| (SYSTEM_EVENT_STA_START) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_STOP | n/a | +| (SYSTEM_EVENT_STA_STOP) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_CONNECTED | :cpp:class:`wifi_event_sta_connected_t` | +| (SYSTEM_EVENT_STA_CONNECTED) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_DISCONNECTED | :cpp:class:`wifi_event_sta_disconnected_t` | +| (SYSTEM_EVENT_STA_DISCONNECTED) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_AUTHMODE_CHANGE | :cpp:class:`wifi_event_sta_authmode_change_t` | +| (SYSTEM_EVENT_STA_AUTHMODE_CHANGE) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_WPS_ER_SUCCESS | n/a | +| (SYSTEM_EVENT_STA_WPS_ER_SUCCESS) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_WPS_ER_FAILED | :cpp:type:`wifi_event_sta_wps_fail_reason_t` | +| (SYSTEM_EVENT_STA_WPS_ER_FAILED) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_WPS_ER_TIMEOUT | n/a | +| (SYSTEM_EVENT_STA_WPS_ER_TIMEOUT) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_STA_WPS_ER_PIN | :cpp:class:`wifi_event_sta_wps_er_pin_t` | +| (SYSTEM_EVENT_STA_WPS_ER_PIN) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_AP_START | n/a | +| (SYSTEM_EVENT_AP_START) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_AP_STOP | n/a | +| (SYSTEM_EVENT_AP_STOP) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_AP_STACONNECTED | :cpp:class:`wifi_event_ap_staconnected_t` | +| (SYSTEM_EVENT_AP_STACONNECTED) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_AP_STADISCONNECTED | :cpp:class:`wifi_event_ap_stadisconnected_t` | +| (SYSTEM_EVENT_AP_STADISCONNECTED) | | ++------------------------------------+-----------------------------------------------+ +| WIFI_EVENT_AP_PROBEREQRECVED | :cpp:class:`wifi_event_ap_probe_req_rx_t` | +| (SYSTEM_EVENT_AP_PROBEREQRECVED) | | ++------------------------------------+-----------------------------------------------+ +| **Ethernet** | ++------------------------------------+-----------------------------------------------+ +| ETHERNET_EVENT_START | n/a | +| (SYSTEM_EVENT_ETH_START) | | ++------------------------------------+-----------------------------------------------+ +| ETHERNET_EVENT_STOP | n/a | +| (SYSTEM_EVENT_ETH_STOP) | | ++------------------------------------+-----------------------------------------------+ +| ETHERNET_EVENT_CONNECTED | n/a | +| (SYSTEM_EVENT_ETH_CONNECTED) | | ++------------------------------------+-----------------------------------------------+ +| ETHERNET_EVENT_DISCONNECTED | n/a | +| (SYSTEM_EVENT_ETH_DISCONNECTED) | | ++------------------------------------+-----------------------------------------------+ +| **IP** | ++------------------------------------+-----------------------------------------------+ +| IP_EVENT_STA_GOT_IP | :cpp:class:`ip_event_got_ip_t` | +| (SYSTEM_EVENT_STA_GOT_IP) | | ++------------------------------------+-----------------------------------------------+ +| IP_EVENT_STA_LOST_IP | n/a | +| (SYSTEM_EVENT_STA_LOST_IP) | | ++------------------------------------+-----------------------------------------------+ +| IP_EVENT_AP_STAIPASSIGNED | n/a | +| (SYSTEM_EVENT_AP_STAIPASSIGNED) | | ++------------------------------------+-----------------------------------------------+ +| IP_EVENT_GOT_IP6 | :cpp:class:`ip_event_got_ip6_t` | +| (SYSTEM_EVENT_GOT_IP6) | | ++------------------------------------+-----------------------------------------------+ +| IP_EVENT_ETH_GOT_IP | :cpp:class:`ip_event_got_ip_t` | +| (SYSTEM_EVENT_ETH_GOT_IP) | | ++------------------------------------+-----------------------------------------------+ + +Mesh Events +----------- + +ESP-MESH uses a system similar to the :ref:`legacy-event-loop` to deliver events to the application. See :ref:`mesh-events` for details. + +Bluetooth Events +---------------- + +Various modules of the Bluetooth stack deliver events to applications via dedicated callback functions. Callback functions receive the event type (enumerated value) and event data (union of structures for each event type). The following list gives the registration API name, event enumeration type, and event parameters type. + +* BLE GAP: :cpp:func:`esp_ble_gap_register_callback`, :cpp:type:`esp_gap_ble_cb_event_t`, :cpp:type:`esp_ble_gap_cb_param_t`. +* BT GAP: :cpp:func:`esp_bt_gap_register_callback`, :cpp:type:`esp_bt_gap_cb_event_t`, :cpp:type:`esp_bt_gap_cb_param_t`. +* GATTC: :cpp:func:`esp_ble_gattc_register_callback`, :cpp:type:`esp_bt_gattc_cb_event_t`, :cpp:type:`esp_bt_gattc_cb_param_t`. +* GATTS: :cpp:func:`esp_ble_gatts_register_callback`, :cpp:type:`esp_bt_gatts_cb_event_t`, :cpp:type:`esp_bt_gatts_cb_param_t`. +* SPP: :cpp:func:`esp_spp_register_callback`, :cpp:type:`esp_spp_cb_event_t`, :cpp:type:`esp_spp_cb_param_t`. +* Blufi: :cpp:func:`esp_blufi_register_callbacks`, :cpp:type:`esp_blufi_cb_event_t`, :cpp:type:`esp_blufi_cb_param_t`. +* A2DP: :cpp:func:`esp_a2d_register_callback`, :cpp:type:`esp_a2d_cb_event_t`, :cpp:type:`esp_a2d_cb_param_t`. +* AVRC: :cpp:func:`esp_avrc_ct_register_callback`, :cpp:type:`esp_avrc_ct_cb_event_t`, :cpp:type:`esp_avrc_ct_cb_param_t`. +* HFP Client: :cpp:func:`esp_hf_client_register_callback`, :cpp:type:`esp_hf_client_cb_event_t`, :cpp:type:`esp_hf_client_cb_param_t`. diff --git a/docs/en/api-guides/index.rst b/docs/en/api-guides/index.rst index 17be4f178..17ab34fed 100644 --- a/docs/en/api-guides/index.rst +++ b/docs/en/api-guides/index.rst @@ -10,6 +10,7 @@ API Guides Build System (CMake) Error Handling Fatal Errors + Event Handling Deep Sleep Wake Stubs ESP32 Core Dump Flash Encryption <../security/flash-encryption> diff --git a/docs/en/api-guides/wifi.rst b/docs/en/api-guides/wifi.rst index d25ba605b..209f27223 100644 --- a/docs/en/api-guides/wifi.rst +++ b/docs/en/api-guides/wifi.rst @@ -37,7 +37,7 @@ Refer to <`ESP32 Wi-Fi Station General Scenario`_>, <`ESP32 Wi-Fi AP General Sce Event-Handling ++++++++++++++ -Generally, it is easy to write code in "sunny-day" scenarios, such as <`SYSTEM_EVENT_STA_START`_>, <`SYSTEM_EVENT_STA_CONNECTED`_> etc. The hard part is to write routines in "rainy-day" scenarios, such as <`SYSTEM_EVENT_STA_DISCONNECTED`_> etc. Good handling of "rainy-day" scenarios is fundamental to robust Wi-Fi applications. Refer to <`ESP32 Wi-Fi Event Description`_>, <`ESP32 Wi-Fi Station General Scenario`_>, <`ESP32 Wi-Fi AP General Scenario`_> +Generally, it is easy to write code in "sunny-day" scenarios, such as <`WIFI_EVENT_STA_START`_>, <`WIFI_EVENT_STA_CONNECTED`_> etc. The hard part is to write routines in "rainy-day" scenarios, such as <`WIFI_EVENT_STA_DISCONNECTED`_> etc. Good handling of "rainy-day" scenarios is fundamental to robust Wi-Fi applications. Refer to <`ESP32 Wi-Fi Event Description`_>, <`ESP32 Wi-Fi Station General Scenario`_>, <`ESP32 Wi-Fi AP General Scenario`_>. See also :doc:`an overview of event handling in ESP-IDF`. Write Error-Recovery Routines Correctly at All Times ++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -72,8 +72,10 @@ When initializing struct parameters for the API, one of two approaches should be Initializing or getting the entire structure is very important because most of the time the value 0 indicates the default value is used. More fields may be added to the struct in the future and initializing these to zero ensures the application will still work correctly after IDF is updated to a new release. +.. _wifi-programming-model: + ESP32 Wi-Fi Programming Model ------------------------------- +----------------------------- The ESP32 Wi-Fi programming model is depicted as follows: .. blockdiag:: @@ -118,29 +120,18 @@ The ESP32 Wi-Fi programming model is depicted as follows: } -The Wi-Fi driver can be considered a black box that knows nothing about high-layer code, such as the -TCPIP stack, application task, event task, etc. All the Wi-Fi driver can do is receive API calls from the high layer, -or post an event-queue to a specified queue which is initialized by API esp_wifi_init(). +The Wi-Fi driver can be considered a black box that knows nothing about high-layer code, such as the TCP/IP stack, application task, event task, etc. The application task (code) generally calls :doc:`Wi-Fi driver APIs <../api-reference/network/esp_wifi>` to initialize Wi-Fi and handles Wi-Fi events when necessary. Wi-Fi driver receives API calls, handles them, and post events to the application. -The event task is a daemon task which receives events from the Wi-Fi driver or from other subsystems, such -as the TCPIP stack. The event task will call the default callback function upon receiving the event. For example, -upon receiving SYSTEM_EVENT_STA_CONNECTED, it will call tcpip_adapter_start() to start the DHCP -client in its default handler. - -An application can register its own event callback function by using API esp_event_init. Then, the application callback -function will be called after the default callback. Also, if the application does not want to execute the callback -in the event task, it needs to post the relevant event to the application task in the application callback function. - -The application task (code) generally mixes all these things together: it calls APIs to initialize the system/Wi-Fi and -handle the events when necessary. +Wi-Fi event handling is based on the :doc:`esp_event library <../api-reference/system/esp_event>`. Events are sent by the Wi-Fi driver to the :ref:`default event loop `. Application may handle these events in callbacks registered using :cpp:func:`esp_event_handler_register`. Wi-Fi events are also handled by :doc:`tcpip_adapter component <../api-reference/network/tcpip_adapter>` to provide a set of default behaviors. For example, when Wi-Fi station connects to an AP, tcpip_adapter will automatically start the DHCP client. ESP32 Wi-Fi Event Description ------------------------------------ -SYSTEM_EVENT_WIFI_READY + +WIFI_EVENT_WIFI_READY ++++++++++++++++++++++++++++++++++++ The Wi-Fi driver will never generate this event, which, as a result, can be ignored by the application event callback. This event may be removed in future releases. -SYSTEM_EVENT_SCAN_DONE +WIFI_EVENT_SCAN_DONE ++++++++++++++++++++++++++++++++++++ The scan-done event is triggered by esp_wifi_scan_start() and will arise in the following scenarios: @@ -156,19 +147,19 @@ The scan-done event will not arise in the following scenarios: Upon receiving this event, the event task does nothing. The application event callback needs to call esp_wifi_scan_get_ap_num() and esp_wifi_scan_get_ap_records() to fetch the scanned AP list and trigger the Wi-Fi driver to free the internal memory which is allocated during the scan **(do not forget to do this)**! Refer to 'ESP32 Wi-Fi Scan' for a more detailed description. -SYSTEM_EVENT_STA_START +WIFI_EVENT_STA_START ++++++++++++++++++++++++++++++++++++ If esp_wifi_start() returns ESP_OK and the current Wi-Fi mode is Station or AP+Station, then this event will arise. Upon receiving this event, the event task will initialize the LwIP network interface (netif). Generally, the application event callback needs to call esp_wifi_connect() to connect to the configured AP. -SYSTEM_EVENT_STA_STOP +WIFI_EVENT_STA_STOP ++++++++++++++++++++++++++++++++++++ If esp_wifi_stop() returns ESP_OK and the current Wi-Fi mode is Station or AP+Station, then this event will arise. Upon receiving this event, the event task will release the station's IP address, stop the DHCP client, remove TCP/UDP-related connections and clear the LwIP station netif, etc. The application event callback generally does not need to do anything. -SYSTEM_EVENT_STA_CONNECTED +WIFI_EVENT_STA_CONNECTED ++++++++++++++++++++++++++++++++++++ If esp_wifi_connect() returns ESP_OK and the station successfully connects to the target AP, the connection event will arise. Upon receiving this event, the event task starts the DHCP client and begins the DHCP process of getting the IP address. Then, the Wi-Fi driver is ready for sending and receiving data. This moment is good for beginning the application work, provided that the application does not depend on LwIP, namely the IP address. However, if the application is LwIP-based, then you need to wait until the *got ip* event comes in. -SYSTEM_EVENT_STA_DISCONNECTED +WIFI_EVENT_STA_DISCONNECTED ++++++++++++++++++++++++++++++++++++ This event can be generated in the following scenarios: @@ -185,17 +176,17 @@ The most common event handle code for this event in application is to call esp_w Another thing deserves our attention is that the default behavior of LwIP is to abort all TCP socket connections on receiving the disconnect. Most of time it is not a problem. However, for some special application, this may not be what they want, consider following scenarios: - The application creates a TCP connection to maintain the application-level keep-alive data that is sent out every 60 seconds. -- Due to certain reasons, the Wi-Fi connection is cut off, and the is raised. According to the current implementation, all TCP connections will be removed and the keep-alive socket will be in a wrong status. However, since the application designer believes that the network layer should NOT care about this error at the Wi-Fi layer, the application does not close the socket. +- Due to certain reasons, the Wi-Fi connection is cut off, and the <`WIFI_EVENT_STA_DISCONNECTED`> is raised. According to the current implementation, all TCP connections will be removed and the keep-alive socket will be in a wrong status. However, since the application designer believes that the network layer should NOT care about this error at the Wi-Fi layer, the application does not close the socket. - Five seconds later, the Wi-Fi connection is restored because esp_wifi_connect() is called in the application event callback function. **Moreover, the station connects to the same AP and gets the same IPV4 address as before**. - Sixty seconds later, when the application sends out data with the keep-alive socket, the socket returns an error and the application closes the socket and re-creates it when necessary. In above scenario, ideally, the application sockets and the network layer should not be affected, since the Wi-Fi connection only fails temporarily and recovers very quickly. The application can enable "Keep TCP connections when IP changed" via LwIP menuconfig. -SYSTEM_EVENT_STA_AUTHMODE_CHANGE +WIFI_EVENT_STA_AUTHMODE_CHANGE ++++++++++++++++++++++++++++++++++++ This event arises when the AP to which the station is connected changes its authentication mode, e.g., from no auth to WPA. Upon receiving this event, the event task will do nothing. Generally, the application event callback does not need to handle this either. -SYSTEM_EVENT_STA_GOT_IP +IP_EVENT_STA_GOT_IP ++++++++++++++++++++++++++++++++++++ This event arises when the DHCP client successfully gets the IPV4 address from the DHCP server, or when the IPV4 address is changed. The event means that everything is ready and the application can begin its tasks (e.g., creating sockets). @@ -205,35 +196,35 @@ The IPV4 may be changed because of the following reasons: - The DHCP client rebinds to a different address. - The static-configured IPV4 address is changed. -Whether the IPV4 address is changed or NOT is indicated by field "ip_change" of system_event_sta_got_ip_t. +Whether the IPV4 address is changed or NOT is indicated by field ``ip_change`` of ``ip_event_got_ip_t``. The socket is based on the IPV4 address, which means that, if the IPV4 changes, all sockets relating to this IPV4 will become abnormal. Upon receiving this event, the application needs to close all sockets and recreate the application when the IPV4 changes to a valid one. -SYSTEM_EVENT_AP_STA_GOT_IP6 +IP_EVENT_GOT_IP6 ++++++++++++++++++++++++++++++++++++ -This event arises when the IPV6 SLAAC supports auto-configures an address for the ESP32, or when this address changes. The event means that everything is ready and the application can begin its tasks (e.g., creating sockets). +This event arises when the IPV6 SLAAC support auto-configures an address for the ESP32, or when this address changes. The event means that everything is ready and the application can begin its tasks (e.g., creating sockets). -SYSTEM_EVENT_STA_LOST_IP +IP_STA_LOST_IP ++++++++++++++++++++++++++++++++++++ This event arises when the IPV4 address become invalid. -SYSTEM_EVENT_STA_LOST_IP doesn't arise immediately after the WiFi disconnects, instead it starts an IPV4 address lost timer, if the IPV4 address is got before ip lost timer expires, SYSTEM_EVENT_STA_LOST_IP doesn't happen. Otherwise, the event arises when IPV4 address lost timer expires. +IP_STA_LOST_IP doesn't arise immediately after the WiFi disconnects, instead it starts an IPV4 address lost timer, if the IPV4 address is got before ip lost timer expires, IP_EVENT_STA_LOST_IP doesn't happen. Otherwise, the event arises when IPV4 address lost timer expires. Generally the application don't need to care about this event, it is just a debug event to let the application know that the IPV4 address is lost. -SYSTEM_EVENT_AP_START +WIFI_EVENT_AP_START ++++++++++++++++++++++++++++++++++++ -Similar to <`SYSTEM_EVENT_STA_START`_>. +Similar to <`WIFI_EVENT_STA_START`_>. -SYSTEM_EVENT_AP_STOP +WIFI_EVENT_AP_STOP ++++++++++++++++++++++++++++++++++++ -Similar to <`SYSTEM_EVENT_STA_STOP`_>. +Similar to <`WIFI_EVENT_STA_STOP`_>. -SYSTEM_EVENT_AP_STACONNECTED +WIFI_EVENT_AP_STACONNECTED ++++++++++++++++++++++++++++++++++++ -Every time a station is connected to ESP32 AP, the <`SYSTEM_EVENT_AP_STACONNECTED`_> will arise. Upon receiving this event, the event task will do nothing, and the application callback can also ignore it. However, you may want to do something, for example, to get the info of the connected STA, etc. +Every time a station is connected to ESP32 AP, the <`WIFI_EVENT_AP_STACONNECTED`_> will arise. Upon receiving this event, the event task will do nothing, and the application callback can also ignore it. However, you may want to do something, for example, to get the info of the connected STA, etc. -SYSTEM_EVENT_AP_STADISCONNECTED +WIFI_EVENT_AP_STADISCONNECTED ++++++++++++++++++++++++++++++++++++ This event can happen in the following scenarios: @@ -243,7 +234,7 @@ This event can happen in the following scenarios: When this event happens, the event task will do nothing, but the application event callback needs to do something, e.g., close the socket which is related to this station, etc. -SYSTEM_EVENT_AP_PROBEREQRECVED +WIFI_EVENT_AP_PROBEREQRECVED ++++++++++++++++++++++++++++++++++++ This event is disabled by default. The application can enable it via API esp_wifi_set_event_mask(). @@ -281,24 +272,24 @@ Below is a "big scenario" which describes some small scenarios in Station mode: MAIN_TASK -> WIFI_TASK [label="2> Configure Wi-Fi"]; === 3. Start Phase === MAIN_TASK -> WIFI_TASK [label="3.1> Start Wi-Fi"]; - EVENT_TASK <- WIFI_TASK [label="3.2> SYSTEM_EVENT_STA_START"]; - APP_TASK <- EVENT_TASK [label="3.3> SYSTEM_EVENT_STA_START"]; + EVENT_TASK <- WIFI_TASK [label="3.2> WIFI_EVENT_STA_START"]; + APP_TASK <- EVENT_TASK [label="3.3> WIFI_EVENT_STA_START"]; === 4. Connect Phase === APP_TASK -> WIFI_TASK [label="4.1> Connect Wi-Fi"]; - EVENT_TASK <- WIFI_TASK [label="4.2> SYSTEM_EVENT_STA_CONNECTED"]; - APP_TASK <- EVENT_TASK [label="4.3> SYSTEM_EVENT_STA_CONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="4.2> WIFI_EVENT_STA_CONNECTED"]; + APP_TASK <- EVENT_TASK [label="4.3> WIFI_EVENT_STA_CONNECTED"]; === 5. Got IP Phase === EVENT_TASK -> LwIP_TASK [label="5.1> Start DHCP client"]; - EVENT_TASK <- LwIP_TASK [label="5.2> SYSTEM_EVENT_STA_GOT_IP"]; - APP_TASK <- EVENT_TASK [label="5.3> SYSTEM_EVENT_STA_GOT_IP"]; + EVENT_TASK <- LwIP_TASK [label="5.2> IP_EVENT_STA_GOT_IP"]; + APP_TASK <- EVENT_TASK [label="5.3> IP_EVENT_STA_GOT_IP"]; APP_TASK -> APP_TASK [label="5.4> socket related init"]; === 6. Disconnect Phase === - EVENT_TASK <- WIFI_TASK [label="6.1> SYSTEM_EVENT_STA_DISCONNECTED"]; - APP_TASK <- EVENT_TASK [label="6.2> SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="6.1> WIFI_EVENT_STA_DISCONNECTED"]; + APP_TASK <- EVENT_TASK [label="6.2> WIFI_EVENT_STA_DISCONNECTED"]; APP_TASK -> APP_TASK [label="6.3> disconnect handling"]; === 7. IP Change Phase === - EVENT_TASK <- LwIP_TASK [label="7.1> SYSTEM_EVENT_STA_GOT_IP"]; - APP_TASK <- EVENT_TASK [label="7.2> SYSTEM_EVENT_STA_GOT_IP"]; + EVENT_TASK <- LwIP_TASK [label="7.1> IP_EVENT_STA_GOT_IP"]; + APP_TASK <- EVENT_TASK [label="7.2> IP_EVENT_STA_GOT_IP"]; APP_TASK -> APP_TASK [label="7.3> Socket error handling"]; === 8. Deinit Phase === APP_TASK -> WIFI_TASK [label="8.1> Disconnect Wi-Fi"]; @@ -330,35 +321,35 @@ If the Wi-Fi NVS flash is enabled by menuconfig, all Wi-Fi configuration in this 3. Wi-Fi Start Phase ++++++++++++++++++++++++++++++++ - s3.1: Call esp_wifi_start to start the Wi-Fi driver. - - s3.2: The Wi-Fi driver posts <`SYSTEM_EVENT_STA_START`_> to the event task; then, the event task will do some common things and will call the application event callback function. - - s3.3: The application event callback function relays the <`SYSTEM_EVENT_STA_START`_> to the application task. We recommend that you call esp_wifi_connect(). However, you can also call esp_wifi_connect() in other phrases after the <`SYSTEM_EVENT_STA_START`_> arises. + - s3.2: The Wi-Fi driver posts <`WIFI_EVENT_STA_START`_> to the event task; then, the event task will do some common things and will call the application event callback function. + - s3.3: The application event callback function relays the <`WIFI_EVENT_STA_START`_> to the application task. We recommend that you call esp_wifi_connect(). However, you can also call esp_wifi_connect() in other phrases after the <`WIFI_EVENT_STA_START`_> arises. 4. Wi-Fi Connect Phase +++++++++++++++++++++++++++++++++ - s4.1: Once esp_wifi_connect() is called, the Wi-Fi driver will start the internal scan/connection process. - - s4.2: If the internal scan/connection process is successful, the <`SYSTEM_EVENT_STA_CONNECTED`_> will be generated. In the event task, it starts the DHCP client, which will finally trigger the DHCP process. + - s4.2: If the internal scan/connection process is successful, the <`WIFI_EVENT_STA_CONNECTED`_> will be generated. In the event task, it starts the DHCP client, which will finally trigger the DHCP process. - s4.3: In the above-mentioned scenario, the application event callback will relay the event to the application task. Generally, the application needs to do nothing, and you can do whatever you want, e.g., print a log, etc. -In step 4.2, the Wi-Fi connection may fail because, for example, the password is wrong, the AP is not found, etc. In a case like this, <`SYSTEM_EVENT_STA_DISCONNECTED`_> will arise and the reason for such a failure will be provided. For handling events that disrupt Wi-Fi connection, please refer to phase 6. +In step 4.2, the Wi-Fi connection may fail because, for example, the password is wrong, the AP is not found, etc. In a case like this, <`WIFI_EVENT_STA_DISCONNECTED`_> will arise and the reason for such a failure will be provided. For handling events that disrupt Wi-Fi connection, please refer to phase 6. 5. Wi-Fi 'Got IP' Phase +++++++++++++++++++++++++++++++++ - s5.1: Once the DHCP client is initialized in step 4.2, the *got IP* phase will begin. - - s5.2: If the IP address is successfully received from the DHCP server, then <`SYSTEM_EVENT_STA_GOT_IP`_> will arise and the event task will perform common handling. - - s5.3: In the application event callback, <`SYSTEM_EVENT_STA_GOT_IP`_> is relayed to the application task. For LwIP-based applications, this event is very special and means that everything is ready for the application to begin its tasks, e.g. creating the TCP/UDP socket, etc. A very common mistake is to initialize the socket before <`SYSTEM_EVENT_STA_GOT_IP`_> is received. **DO NOT start the socket-related work before the IP is received.** + - s5.2: If the IP address is successfully received from the DHCP server, then <`IP_EVENT_STA_GOT_IP`_> will arise and the event task will perform common handling. + - s5.3: In the application event callback, <`IP_EVENT_STA_GOT_IP`_> is relayed to the application task. For LwIP-based applications, this event is very special and means that everything is ready for the application to begin its tasks, e.g. creating the TCP/UDP socket, etc. A very common mistake is to initialize the socket before <`IP_EVENT_STA_GOT_IP`_> is received. **DO NOT start the socket-related work before the IP is received.** 6. Wi-Fi Disconnect Phase +++++++++++++++++++++++++++++++++ - - s6.1: When the Wi-Fi connection is disrupted, e.g. because the AP is powered off, the RSSI is poor, etc., <`SYSTEM_EVENT_STA_DISCONNECTED`_> will arise. This event may also arise in phase 3. Here, the event task will notify the LwIP task to clear/remove all UDP/TCP connections. Then, all application sockets will be in a wrong status. In other words, no socket can work properly when this event happens. - - s6.2: In the scenario described above, the application event callback function relays <`SYSTEM_EVENT_STA_DISCONNECTED`_> to the application task. We recommend that esp_wifi_connect() be called to reconnect the Wi-Fi, close all sockets and re-create them if necessary. Refer to <`SYSTEM_EVENT_STA_DISCONNECTED`_>. + - s6.1: When the Wi-Fi connection is disrupted, e.g. because the AP is powered off, the RSSI is poor, etc., <`WIFI_EVENT_STA_DISCONNECTED`_> will arise. This event may also arise in phase 3. Here, the event task will notify the LwIP task to clear/remove all UDP/TCP connections. Then, all application sockets will be in a wrong status. In other words, no socket can work properly when this event happens. + - s6.2: In the scenario described above, the application event callback function relays <`WIFI_EVENT_STA_DISCONNECTED`_> to the application task. We recommend that esp_wifi_connect() be called to reconnect the Wi-Fi, close all sockets and re-create them if necessary. Refer to <`WIFI_EVENT_STA_DISCONNECTED`_>. 7. Wi-Fi IP Change Phase ++++++++++++++++++++++++++++++++++ - - s7.1: If the IP address is changed, the <`SYSTEM_EVENT_STA_GOT_IP`_> will arise with "ip_change" set to true. + - s7.1: If the IP address is changed, the <`IP_EVENT_STA_GOT_IP`_> will arise with "ip_change" set to true. - s7.2: **This event is important to the application. When it occurs, the timing is good for closing all created sockets and recreating them.** @@ -402,14 +393,14 @@ Below is a "big scenario" which describes some small scenarios in AP mode: MAIN_TASK -> WIFI_TASK [label="2> Configure Wi-Fi"]; === 3. Start Phase === MAIN_TASK -> WIFI_TASK [label="3.1> Start Wi-Fi"]; - EVENT_TASK <- WIFI_TASK [label="3.2> SYSTEM_EVENT_AP_START"]; - APP_TASK <- EVENT_TASK [label="3.3> SYSTEM_EVENT_AP_START"]; + EVENT_TASK <- WIFI_TASK [label="3.2> WIFI_EVENT_AP_START"]; + APP_TASK <- EVENT_TASK [label="3.3> WIFI_EVENT_AP_START"]; === 4. Connect Phase === - EVENT_TASK <- WIFI_TASK [label="4.1> SYSTEM_EVENT_AP_STA_CONNECTED"]; - APP_TASK <- EVENT_TASK [label="4.2> SYSTEM_EVENT_AP_STA_CONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="4.1> WIFI_EVENT_AP_STA_CONNECTED"]; + APP_TASK <- EVENT_TASK [label="4.2> WIFI_EVENT_AP_STA_CONNECTED"]; === 5. Disconnect Phase === - EVENT_TASK <- WIFI_TASK [label="5.1> SYSTEM_EVENT_STA_DISCONNECTED"]; - APP_TASK <- EVENT_TASK [label="5.2> SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="5.1> WIFI_EVENT_STA_DISCONNECTED"]; + APP_TASK <- EVENT_TASK [label="5.2> WIFI_EVENT_STA_DISCONNECTED"]; APP_TASK -> APP_TASK [label="5.3> disconnect handling"]; === 6. Deinit Phase === APP_TASK -> WIFI_TASK [label="6.1> Disconnect Wi-Fi"]; @@ -552,8 +543,8 @@ Scenario: WIFI_TASK -> WIFI_TASK [label="2.2 > Scan channel 2"]; WIFI_TASK -> WIFI_TASK [label="..."]; WIFI_TASK -> WIFI_TASK [label="2.x > Scan channel N"]; - EVENT_TASK <- WIFI_TASK [label="3.1 > SYSTEM_EVENT_SCAN_DONE"]; - APP_TASK <- EVENT_TASK [label="3.2 > SYSTEM_EVENT_SCAN_DONE"]; + EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"]; + APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"]; } @@ -578,8 +569,8 @@ Wi-Fi Driver's Internal Scan Phase Scan-Done Event Handling Phase ********************************* - - s3.1: When all channels are scanned, <`SYSTEM_EVENT_SCAN_DONE`_> will arise. - - s3.2: The application's event callback function notifies the application task that <`SYSTEM_EVENT_SCAN_DONE`_> is received. esp_wifi_scan_get_ap_num() is called to get the number of APs that have been found in this scan. Then, it allocates enough entries and calls esp_wifi_scan_get_ap_records() to get the AP records. Please note that the AP records in the Wi-Fi driver will be freed, once esp_wifi_scan_get_ap_records() is called. Do not call esp_wifi_scan_get_ap_records() twice for a single scan-done event. If esp_wifi_scan_get_ap_records() is not called when the scan-done event occurs, the AP records allocated by the Wi-Fi driver will not be freed. So, make sure you call esp_wifi_scan_get_ap_records(), yet only once. + - s3.1: When all channels are scanned, <`WIFI_EVENT_SCAN_DONE`_> will arise. + - s3.2: The application's event callback function notifies the application task that <`WIFI_EVENT_SCAN_DONE`_> is received. esp_wifi_scan_get_ap_num() is called to get the number of APs that have been found in this scan. Then, it allocates enough entries and calls esp_wifi_scan_get_ap_records() to get the AP records. Please note that the AP records in the Wi-Fi driver will be freed, once esp_wifi_scan_get_ap_records() is called. Do not call esp_wifi_scan_get_ap_records() twice for a single scan-done event. If esp_wifi_scan_get_ap_records() is not called when the scan-done event occurs, the AP records allocated by the Wi-Fi driver will not be freed. So, make sure you call esp_wifi_scan_get_ap_records(), yet only once. Scan All APs on All Channels(background) ++++++++++++++++++++++++++++++++++++++++ @@ -611,8 +602,8 @@ Scenario: WIFI_TASK -> WIFI_TASK [label="..."]; WIFI_TASK -> WIFI_TASK [label="2.x-1 > Scan channel N"]; WIFI_TASK -> WIFI_TASK [label="2.x > Back to home channel H"]; - EVENT_TASK <- WIFI_TASK [label="3.1 > SYSTEM_EVENT_SCAN_DONE"]; - APP_TASK <- EVENT_TASK [label="3.2 > SYSTEM_EVENT_SCAN_DONE"]; + EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"]; + APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"]; } The scenario above is an all-channel background scan. Compared to `Scan All APs In All Channels(foreground)`_ , the difference in the all-channel background scan is that the Wi-Fi driver will scan the back-to-home channel for 30 ms before it switches to the next channel to give the Wi-Fi connection a chance to transmit/receive data. @@ -644,8 +635,8 @@ Scenario: WIFI_TASK -> WIFI_TASK [label="2.2 > Scan channel C2"]; WIFI_TASK -> WIFI_TASK [label="..."]; WIFI_TASK -> WIFI_TASK [label="2.x > Scan channel CN, or the AP is found"]; - EVENT_TASK <- WIFI_TASK [label="3.1 > SYSTEM_EVENT_SCAN_DONE"]; - APP_TASK <- EVENT_TASK [label="3.2 > SYSTEM_EVENT_SCAN_DONE"]; + EVENT_TASK <- WIFI_TASK [label="3.1 > WIFI_EVENT_SCAN_DONE"]; + APP_TASK <- EVENT_TASK [label="3.2 > WIFI_EVENT_SCAN_DONE"]; } This scan is similar to `Scan All APs In All Channels(foreground)`_. The differences are: @@ -660,7 +651,7 @@ You can scan a specific AP, or all of them, in any given channel. These two scen Scan in Wi-Fi Connect +++++++++++++++++++++++++ -When esp_wifi_connect() is called, then the Wi-Fi driver will try to scan the configured AP first. The scan in "Wi-Fi Connect" is the same as `Scan for a Specific AP In All Channels`_, except that no scan-done event will be generated when the scan is completed. If the target AP is found, then the Wi-Fi driver will start the Wi-Fi connection; otherwise, <`SYSTEM_EVENT_STA_DISCONNECTED`_> will be generated. Refer to `Scan for a Specific AP in All Channels`_ +When esp_wifi_connect() is called, then the Wi-Fi driver will try to scan the configured AP first. The scan in "Wi-Fi Connect" is the same as `Scan for a Specific AP In All Channels`_, except that no scan-done event will be generated when the scan is completed. If the target AP is found, then the Wi-Fi driver will start the Wi-Fi connection; otherwise, <`WIFI_EVENT_STA_DISCONNECTED`_> will be generated. Refer to `Scan for a Specific AP in All Channels`_ Scan In Blocked Mode ++++++++++++++++++++ @@ -677,7 +668,7 @@ Scan When Wi-Fi Is Connecting The esp_wifi_scan_start() fails immediately if the Wi-Fi is in connecting process because the connecting has higher priority than the scan. If scan fails because of connecting, the recommended strategy is to delay sometime and retry scan again, the scan will succeed once the connecting is completed. However, the retry/delay strategy may not work all the time. Considering following scenario: -- The station is connecting a non-existed AP or if the station connects the existed AP with a wrong password, it always raises the event <`SYSTEM_EVENT_STA_DISCONNECTED`_>. +- The station is connecting a non-existed AP or if the station connects the existed AP with a wrong password, it always raises the event <`WIFI_EVENT_STA_DISCONNECTED`_>. - The application call esp_wifi_connect() to do reconnection on receiving the disconnect event. - Another application task, e.g. the console task, call esp_wifi_scan_start() to do scan, the scan always fails immediately because the station is keeping connecting. - When scan fails, the application simply delay sometime and retry the scan. @@ -716,27 +707,27 @@ Scenario: === 1. Scan Phase === WIFI_TASK -> WIFI_TASK [label="1.1 > Scan"]; - EVENT_TASK <- WIFI_TASK [label="1.2 > SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="1.2 > WIFI_EVENT_STA_DISCONNECTED"]; === 2. Auth Phase === WIFI_TASK -> AP [label="2.1 > Auth request"]; - EVENT_TASK <- WIFI_TASK [label="2.2 > SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="2.2 > WIFI_EVENT_STA_DISCONNECTED"]; WIFI_TASK <- AP [label="2.3 > Auth response"]; - EVENT_TASK <- WIFI_TASK [label="2.4 > SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="2.4 > WIFI_EVENT_STA_DISCONNECTED"]; === 3. Assoc Phase === WIFI_TASK -> AP [label="3.1 > Assoc request"]; - EVENT_TASK <- WIFI_TASK [label="3.2 > SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="3.2 > WIFI_EVENT_STA_DISCONNECTED"]; WIFI_TASK <- AP [label="3.3 > Assoc response"]; - EVENT_TASK <- WIFI_TASK [label="3.4 > SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="3.4 > WIFI_EVENT_STA_DISCONNECTED"]; === 4. 4-way Handshake Phase === WIFI_TASK -> AP [label="4.1 > 1/4 EAPOL"]; - EVENT_TASK <- WIFI_TASK [label="4.2 > SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="4.2 > WIFI_EVENT_STA_DISCONNECTED"]; WIFI_TASK -> AP [label="4.3 > 2/4 EAPOL"]; - EVENT_TASK <- WIFI_TASK [label="4.4 > SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="4.4 > WIFI_EVENT_STA_DISCONNECTED"]; WIFI_TASK -> AP [label="4.5 > 3/4 EAPOL"]; - EVENT_TASK <- WIFI_TASK [label="4.6 > SYSTEM_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="4.6 > WIFI_EVENT_STA_DISCONNECTED"]; WIFI_TASK -> AP [label="4.7 > 4/4 EAPOL"]; - EVENT_TASK <- WIFI_TASK [label="4.8 > SYSTEM_EVENT_STA_DISCONNECTED"]; - EVENT_TASK <- WIFI_TASK [label="4.9 > SYSTEM_EVENT_STA_CONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="4.8 > WIFI_EVENT_STA_DISCONNECTED"]; + EVENT_TASK <- WIFI_TASK [label="4.9 > WIFI_EVENT_STA_CONNECTED"]; } @@ -744,32 +735,32 @@ Scan Phase +++++++++++++++++++++ - s1.1, The Wi-Fi driver begins scanning in "Wi-Fi Connect". Refer to <`Scan in Wi-Fi Connect`_> for more details. - - s1.2, If the scan fails to find the target AP, <`SYSTEM_EVENT_STA_DISCONNECTED`_> will arise and the reason-code will be WIFI_REASON_NO_AP_FOUND. Refer to <`Wi-Fi Reason Code`_>. + - s1.2, If the scan fails to find the target AP, <`WIFI_EVENT_STA_DISCONNECTED`_> will arise and the reason-code will be WIFI_REASON_NO_AP_FOUND. Refer to <`Wi-Fi Reason Code`_>. Auth Phase +++++++++++++++++++++ - s2.1, The authentication request packet is sent and the auth timer is enabled. - - s2.2, If the authentication response packet is not received before the authentication timer times out, <`SYSTEM_EVENT_STA_DISCONNECTED`_> will arise and the reason-code will be WIFI_REASON_AUTH_EXPIRE. Refer to <`Wi-Fi Reason Code`_>. + - s2.2, If the authentication response packet is not received before the authentication timer times out, <`WIFI_EVENT_STA_DISCONNECTED`_> will arise and the reason-code will be WIFI_REASON_AUTH_EXPIRE. Refer to <`Wi-Fi Reason Code`_>. - s2.3, The auth-response packet is received and the auth-timer is stopped. - - s2.4, The AP rejects authentication in the response and <`SYSTEM_EVENT_STA_DISCONNECTED`_> arises, while the reason-code is WIFI_REASON_AUTH_FAIL or the reasons specified by the AP. Refer to <`Wi-Fi Reason Code`_>. + - s2.4, The AP rejects authentication in the response and <`WIFI_EVENT_STA_DISCONNECTED`_> arises, while the reason-code is WIFI_REASON_AUTH_FAIL or the reasons specified by the AP. Refer to <`Wi-Fi Reason Code`_>. Association Phase +++++++++++++++++++++ - s3.1, The association request is sent and the association timer is enabled. - - s3.2, If the association response is not received before the association timer times out, <`SYSTEM_EVENT_STA_DISCONNECTED`_> will arise and the reason-code will be WIFI_REASON_ASSOC_EXPIRE. Refer to <`Wi-Fi Reason Code`_>. + - s3.2, If the association response is not received before the association timer times out, <`WIFI_EVENT_STA_DISCONNECTED`_> will arise and the reason-code will be WIFI_REASON_ASSOC_EXPIRE. Refer to <`Wi-Fi Reason Code`_>. - s3.3, The association response is received and the association timer is stopped. - - s3.4, The AP rejects the association in the response and <`SYSTEM_EVENT_STA_DISCONNECTED`_> arises, while the reason-code is the one specified in the association response. Refer to <`Wi-Fi Reason Code`_>. + - s3.4, The AP rejects the association in the response and <`WIFI_EVENT_STA_DISCONNECTED`_> arises, while the reason-code is the one specified in the association response. Refer to <`Wi-Fi Reason Code`_>. Four-way Handshake Phase ++++++++++++++++++++++++++ - s4.1, The four-way handshake is sent out and the association timer is enabled. - - s4.2, If the association response is not received before the association timer times out, <`SYSTEM_EVENT_STA_DISCONNECTED`_> will arise and the reason-code will be WIFI_REASON_ASSOC_EXPIRE. Refer to <`Wi-Fi Reason Code`_>. + - s4.2, If the association response is not received before the association timer times out, <`WIFI_EVENT_STA_DISCONNECTED`_> will arise and the reason-code will be WIFI_REASON_ASSOC_EXPIRE. Refer to <`Wi-Fi Reason Code`_>. - s4.3, The association response is received and the association timer is stopped. - - s4.4, The AP rejects the association in the response and <`SYSTEM_EVENT_STA_DISCONNECTED`_> arises and the reason-code will be the one specified in the association response. Refer to <`Wi-Fi Reason Code`_>. + - s4.4, The AP rejects the association in the response and <`WIFI_EVENT_STA_DISCONNECTED`_> arises and the reason-code will be the one specified in the association response. Refer to <`Wi-Fi Reason Code`_>. Wi-Fi Reason Code @@ -1023,13 +1014,13 @@ The table below shows the reason-code defined in ESP32. The first column is the ESP32 Wi-Fi Station Connecting When Multiple APs Are Found --------------------------------------------------------------- -This scenario is similar as <`ESP32 Wi-Fi Station Connecting Scenario`_>, the difference is the station will not raise the event <`SYSTEM_EVENT_STA_DISCONNECTED`_> unless it fails to connect all of the found APs. +This scenario is similar as <`ESP32 Wi-Fi Station Connecting Scenario`_>, the difference is the station will not raise the event <`WIFI_EVENT_STA_DISCONNECTED`_> unless it fails to connect all of the found APs. Wi-Fi Reconnect --------------------------- -The station may disconnect due to many reasons, e.g. the connected AP is restarted etc. It's the application's responsibility to do the reconnect. The recommended reconnect strategy is to call esp_wifi_connect() on receiving event <`SYSTEM_EVENT_STA_DISCONNECTED`_>. +The station may disconnect due to many reasons, e.g. the connected AP is restarted etc. It's the application's responsibility to do the reconnect. The recommended reconnect strategy is to call esp_wifi_connect() on receiving event <`WIFI_EVENT_STA_DISCONNECTED`_>. Sometimes the application needs more complex reconnect strategy: - If the disconnect event is raised because the esp_wifi_disconnect() is called, the application may not want to do reconnect. @@ -1042,7 +1033,7 @@ Wi-Fi Beacon Timeout The beacon timeout mechanism is used by ESP32 station to detect whether the AP is alive or not. If the station continuously loses 60 beacons of the connected AP, the beacon timeout happens. -After the beacon timeout happens, the station sends 5 probe requests to AP, it disconnects the AP and raises the event <`SYSTEM_EVENT_STA_DISCONNECTED`_> if still no probe response or beacon is received from AP. +After the beacon timeout happens, the station sends 5 probe requests to AP, it disconnects the AP and raises the event <`WIFI_EVENT_STA_DISCONNECTED`_> if still no probe response or beacon is received from AP. ESP32 Wi-Fi Configuration --------------------------- diff --git a/docs/en/api-reference/network/esp_mesh.rst b/docs/en/api-reference/network/esp_mesh.rst index e80d7e17d..299a8b952 100644 --- a/docs/en/api-reference/network/esp_mesh.rst +++ b/docs/en/api-reference/network/esp_mesh.rst @@ -37,6 +37,8 @@ The ESP-MESH software stack is built atop the Wi-Fi Driver/FreeRTOS and may use ESP-MESH Software Stack +.. _mesh-events: + System Events ^^^^^^^^^^^^^ diff --git a/docs/en/api-reference/system/esp_event.rst b/docs/en/api-reference/system/esp_event.rst index dd969be70..524ac3de2 100644 --- a/docs/en/api-reference/system/esp_event.rst +++ b/docs/en/api-reference/system/esp_event.rst @@ -15,7 +15,7 @@ Using ``esp_event`` APIs There are two objects of concern for users of this library: events and event loops. -Events are occurences of note. For example, for WiFi, a successful connection to the access point may be an event. +Events are occurrences of note. For example, for WiFi, a successful connection to the access point may be an event. Events are referenced using a two part identifier which are discussed more :ref:`here `. Event loops are the vehicle by which events get posted by event sources and handled by event handler functions. These two appear prominently in the event loop library APIs. @@ -200,7 +200,7 @@ handlers will also get executed in between. Event loop profiling -------------------- -A configuration option :envvar:`CONFIG_EVENT_LOOP_PROFILING` can be enabled in order to activate statistics collection for all event loops created. +A configuration option :ref:`CONFIG_EVENT_LOOP_PROFILING` can be enabled in order to activate statistics collection for all event loops created. The function :cpp:func:`esp_event_dump` can be used to output the collected statistics to a file stream. More details on the information included in the dump can be found in the :cpp:func:`esp_event_dump` API Reference. @@ -218,3 +218,11 @@ API Reference .. include:: /_build/inc/esp_event.inc .. include:: /_build/inc/esp_event_base.inc + +Related Documents +----------------- + +.. toctree:: + :maxdepth: 1 + + Legacy event loop API reference diff --git a/docs/en/api-reference/system/esp_event_legacy.rst b/docs/en/api-reference/system/esp_event_legacy.rst new file mode 100644 index 000000000..744e11e9c --- /dev/null +++ b/docs/en/api-reference/system/esp_event_legacy.rst @@ -0,0 +1,7 @@ +Legacy event loop +================= + +API Reference +------------- + +.. include:: /_build/inc/esp_event_legacy.inc diff --git a/docs/zh_CN/api-guides/event-handling.rst b/docs/zh_CN/api-guides/event-handling.rst new file mode 100644 index 000000000..4c52a3548 --- /dev/null +++ b/docs/zh_CN/api-guides/event-handling.rst @@ -0,0 +1 @@ +.. include:: ../../en/api-guides/event-handling.rst \ No newline at end of file diff --git a/docs/zh_CN/api-guides/index.rst b/docs/zh_CN/api-guides/index.rst index c8d6b49ba..18e1a51a8 100644 --- a/docs/zh_CN/api-guides/index.rst +++ b/docs/zh_CN/api-guides/index.rst @@ -10,6 +10,7 @@ API 指南 构建系统 (CMake) 错误处理 Fatal Errors + Event Handling Deep Sleep Wake Stubs ESP32 Core Dump Flash Encryption <../security/flash-encryption> diff --git a/docs/zh_CN/api-reference/system/esp_event_legacy.rst b/docs/zh_CN/api-reference/system/esp_event_legacy.rst new file mode 100644 index 000000000..80a97df38 --- /dev/null +++ b/docs/zh_CN/api-reference/system/esp_event_legacy.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-reference/system/esp_event_legacy.rst From b94fcb192e2aa016b61867d8b3441231d3f89bf6 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 25 Dec 2018 15:44:14 +0800 Subject: [PATCH 08/13] event: re-add wifi disconnect reason logging (e621e0af) --- components/esp_event/event_send_compat.inc | 53 +++++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/components/esp_event/event_send_compat.inc b/components/esp_event/event_send_compat.inc index 408ce7a82..42b4daf47 100644 --- a/components/esp_event/event_send_compat.inc +++ b/components/esp_event/event_send_compat.inc @@ -115,6 +115,54 @@ esp_err_t esp_event_send_to_default_loop(system_event_t *event) static const char* TAG = "system_event"; +typedef struct { + int err; + const char *reason; +} wifi_reason_t; + +static const wifi_reason_t wifi_reason[] = +{ + {0, "other reason"}, + {WIFI_REASON_UNSPECIFIED, "unspecified"}, + {WIFI_REASON_AUTH_EXPIRE, "auth expire"}, + {WIFI_REASON_AUTH_LEAVE, "auth leave"}, + {WIFI_REASON_ASSOC_EXPIRE, "assoc expire"}, + {WIFI_REASON_ASSOC_TOOMANY, "assoc too many"}, + {WIFI_REASON_NOT_AUTHED, "not authed"}, + {WIFI_REASON_NOT_ASSOCED, "not assoced"}, + {WIFI_REASON_ASSOC_LEAVE, "assoc leave"}, + {WIFI_REASON_ASSOC_NOT_AUTHED, "assoc not authed"}, + {WIFI_REASON_BEACON_TIMEOUT, "beacon timeout"}, + {WIFI_REASON_NO_AP_FOUND, "no ap found"}, + {WIFI_REASON_AUTH_FAIL, "auth fail"}, + {WIFI_REASON_ASSOC_FAIL, "assoc fail"}, + {WIFI_REASON_HANDSHAKE_TIMEOUT, "hanshake timeout"}, + {WIFI_REASON_DISASSOC_PWRCAP_BAD, "bad Power Capability, disassoc"}, + {WIFI_REASON_DISASSOC_SUPCHAN_BAD, "bad Supported Channels, disassoc"}, + {WIFI_REASON_IE_INVALID, "invalid IE"}, + {WIFI_REASON_MIC_FAILURE, "MIC failure"}, + {WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT, "4-way keying handshake timeout"}, + {WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT, "Group key handshake"}, + {WIFI_REASON_IE_IN_4WAY_DIFFERS, "IE in 4-way differs"}, + {WIFI_REASON_GROUP_CIPHER_INVALID, "invalid group cipher"}, + {WIFI_REASON_PAIRWISE_CIPHER_INVALID, "invalid pairwise cipher"}, + {WIFI_REASON_AKMP_INVALID, "invalid AKMP"}, + {WIFI_REASON_UNSUPP_RSN_IE_VERSION, "unsupported RSN IE version"}, + {WIFI_REASON_INVALID_RSN_IE_CAP, "invalid RSN IE capability"}, + {WIFI_REASON_802_1X_AUTH_FAILED, "802.1x auth failed"}, + {WIFI_REASON_CIPHER_SUITE_REJECTED, "cipher suite rejected"} +}; + +static const char* wifi_disconnect_reason_to_str(int err) +{ + for (int i=0; i< sizeof(wifi_reason)/sizeof(wifi_reason[0]); i++){ + if (err == wifi_reason[i].err){ + return wifi_reason[i].reason; + } + } + return wifi_reason[0].reason; +} + static void esp_system_event_debug(const system_event_t* event) { if (event == NULL) { @@ -147,8 +195,9 @@ static void esp_system_event_debug(const system_event_t* event) } case SYSTEM_EVENT_STA_DISCONNECTED: { const system_event_sta_disconnected_t *disconnected = &event->event_info.disconnected; - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", reason:%d", \ - disconnected->ssid, disconnected->ssid_len, MAC2STR(disconnected->bssid), disconnected->reason); + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", reason:%d (%s)", \ + disconnected->ssid, disconnected->ssid_len, MAC2STR(disconnected->bssid), disconnected->reason, + wifi_disconnect_reason_to_str(disconnected->reason)); break; } case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: { From bd309a133fc5fe328cf9d067c11da3aa08d5cbf9 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 8 Apr 2019 19:29:44 +0800 Subject: [PATCH 09/13] system_api: add esp_unregister_shutdown_handler --- components/esp32/system_api.c | 11 +++++++++++ components/esp_common/include/esp_system.h | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c index 120e9ec46..93763e523 100644 --- a/components/esp32/system_api.c +++ b/components/esp32/system_api.c @@ -221,6 +221,17 @@ esp_err_t esp_register_shutdown_handler(shutdown_handler_t handler) return ESP_FAIL; } +esp_err_t esp_unregister_shutdown_handler(shutdown_handler_t handler) +{ + for (int i = 0; i < SHUTDOWN_HANDLERS_NO; i++) { + if (shutdown_handlers[i] == handler) { + shutdown_handlers[i] = NULL; + return ESP_OK; + } + } + return ESP_ERR_INVALID_STATE; +} + void esp_restart_noos() __attribute__ ((noreturn)); void IRAM_ATTR esp_restart(void) diff --git a/components/esp_common/include/esp_system.h b/components/esp_common/include/esp_system.h index 05214c8f5..5de5e5a9a 100644 --- a/components/esp_common/include/esp_system.h +++ b/components/esp_common/include/esp_system.h @@ -83,6 +83,17 @@ typedef void (*shutdown_handler_t)(void); */ esp_err_t esp_register_shutdown_handler(shutdown_handler_t handle); +/** + * @brief Unregister shutdown handler + * + * This function allows you to unregister a handler which was previously + * registered using esp_register_shutdown_handler function. + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if the given handler hasn't been registered before + */ +esp_err_t esp_unregister_shutdown_handler(shutdown_handler_t handle); + + /** * @brief Restart PRO and APP CPUs. * From b1a722b2ca90cb7c16b067081a03554e33de2ff6 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 8 Apr 2019 19:30:07 +0800 Subject: [PATCH 10/13] system_api: return error on repeated registration of shutdown handler --- components/esp32/system_api.c | 17 +++++++++-------- components/esp_common/include/esp_system.h | 5 +++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c index 93763e523..7edb8a699 100644 --- a/components/esp32/system_api.c +++ b/components/esp32/system_api.c @@ -211,14 +211,15 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type) esp_err_t esp_register_shutdown_handler(shutdown_handler_t handler) { - int i; - for (i = 0; i < SHUTDOWN_HANDLERS_NO; i++) { - if (shutdown_handlers[i] == NULL) { - shutdown_handlers[i] = handler; - return ESP_OK; - } - } - return ESP_FAIL; + for (int i = 0; i < SHUTDOWN_HANDLERS_NO; i++) { + if (shutdown_handlers[i] == handler) { + return ESP_ERR_INVALID_STATE; + } else if (shutdown_handlers[i] == NULL) { + shutdown_handlers[i] = handler; + return ESP_OK; + } + } + return ESP_ERR_NO_MEM; } esp_err_t esp_unregister_shutdown_handler(shutdown_handler_t handler) diff --git a/components/esp_common/include/esp_system.h b/components/esp_common/include/esp_system.h index 5de5e5a9a..f73165a1e 100644 --- a/components/esp_common/include/esp_system.h +++ b/components/esp_common/include/esp_system.h @@ -80,6 +80,11 @@ typedef void (*shutdown_handler_t)(void); * * This function allows you to register a handler that gets invoked before * the application is restarted using esp_restart function. + * @param handle function to execute on restart + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if the handler has already been registered + * - ESP_ERR_NO_MEM if no more shutdown handler slots are available */ esp_err_t esp_register_shutdown_handler(shutdown_handler_t handle); From 198d7d47547c296ae4d9a8500410e461fd58ba2e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 8 Apr 2019 19:30:32 +0800 Subject: [PATCH 11/13] =?UTF-8?q?tcpip=5Fadapter:=20unregister=20shutdown?= =?UTF-8?q?=20handlers,=20don=E2=80=99t=20fail=20on=20repeated=20registrat?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/tcpip_adapter/event_handlers.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/tcpip_adapter/event_handlers.c b/components/tcpip_adapter/event_handlers.c index ff7847b28..99e4342a4 100644 --- a/components/tcpip_adapter/event_handlers.c +++ b/components/tcpip_adapter/event_handlers.c @@ -242,7 +242,7 @@ esp_err_t tcpip_adapter_set_default_wifi_handlers() } err = esp_register_shutdown_handler((shutdown_handler_t)esp_wifi_stop); - if (err != ESP_OK) { + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { goto fail; } @@ -263,8 +263,7 @@ esp_err_t tcpip_adapter_clear_default_wifi_handlers() esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_AP_STOP, handle_ap_stop); esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, handle_sta_got_ip); esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, handle_eth_got_ip); - - /* TODO: introduce esp_unregister_shutdown_handler or similar, call it here */ + esp_unregister_shutdown_handler((shutdown_handler_t)esp_wifi_stop); return ESP_OK; } From 74cd8dac9d4e2cd02aefa5e191c3cb8ad6fbfc43 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 8 Apr 2019 19:31:37 +0800 Subject: [PATCH 12/13] =?UTF-8?q?esp=5Fevent:=20don=E2=80=99t=20warn=20if?= =?UTF-8?q?=20no=20handlers=20are=20present=20for=20specific=20event?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/esp_event/esp_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_event/esp_event.c b/components/esp_event/esp_event.c index 19bf1d8cc..d9cca3a88 100644 --- a/components/esp_event/esp_event.c +++ b/components/esp_event/esp_event.c @@ -569,7 +569,7 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick if (!exec) { // No handlers were registered, not even loop/base level handlers - ESP_LOGW(TAG, "no handlers have been registered for event %s:%d posted to loop %p", base, id, event_loop); + ESP_LOGD(TAG, "no handlers have been registered for event %s:%d posted to loop %p", base, id, event_loop); } } From 25784ba87a3e1c1426a36bc47d31c368ebd99736 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 9 Apr 2019 12:09:56 +0800 Subject: [PATCH 13/13] =?UTF-8?q?wifi:=20don=E2=80=99t=20disable=20event?= =?UTF-8?q?=20handling=20for=20SoftAP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Events are needed to initialise the tcpip_adapter and start the DHCP server --- components/esp_wifi/test/test_wifi.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/components/esp_wifi/test/test_wifi.c b/components/esp_wifi/test/test_wifi.c index 7b2c4e4b3..08996d9de 100644 --- a/components/esp_wifi/test/test_wifi.c +++ b/components/esp_wifi/test/test_wifi.c @@ -142,15 +142,9 @@ TEST_CASE("wifi stop and deinit","[wifi]") TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of tcpip_adapter and event_loop."); } -static esp_err_t event_send_dummy(system_event_t *event) -{ - return ESP_OK; -} - static void start_wifi_as_softap(void) { wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - cfg.event_handler = &event_send_dummy; cfg.nvs_enable = false; wifi_config_t w_config = {