From b1d1e37f8723de0cf083a3a268bab421178c60bc Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 6 Nov 2018 11:09:32 +0800 Subject: [PATCH] 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 a6b61623e2..9749eef588 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 b30234c955..aadbfb72a0 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 3daf5ab8d0..9623f04d81 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 7506d96142..0000000000 --- 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 9dbefb45d6..0000000000 --- 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 0000000000..f5e737d203 --- /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 0000000000..4472bb4743 --- /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 0000000000..408ce7a820 --- /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 9da5230315..aff87e362d 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 97672aedf2..6267ee37d9 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 0000000000..a2a2e1a728 --- /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 9176e76e44..2091e1b509 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 08996d9de3..7b2c4e4b3f 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 e1b402aa39..3019c25a3f 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 2868696ac7..b728811ef2 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 0000000000..ff7847b286 --- /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 d3f5b3216c..3953984264 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 b51eb8fa88..c350b899cb 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): -- 2.40.0