Merge branch 'feature/esp_event_loop_library_compat_base' into 'master'

Implement Wi-Fi, Ethernet, IP event handling based on esp_event library

Closes IDF-37 and IDF-267

See merge request idf/esp-idf!3635
This commit is contained in:
Ivan Grokhotkov 2019-04-12 13:54:18 +08:00
commit 0bca9d20d8
42 changed files with 1545 additions and 976 deletions

View file

@ -211,14 +211,26 @@ 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)
{
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));

View file

@ -80,9 +80,25 @@ 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);
/**
* @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.
*

View file

@ -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)

View file

@ -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"

View file

@ -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);
}
}

View file

@ -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 <stddef.h>
#include <stdlib.h>
#include <string.h>
#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, &eth_ip);
tcpip_adapter_eth_start(eth_mac, &eth_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, &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, &eth_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;
}

View file

@ -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 <stddef.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -0,0 +1,311 @@
// 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";
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) {
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 (%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: {
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

View file

@ -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 */

View file

@ -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 <stdint.h>
#include <stdbool.h>
@ -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,76 @@ 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
* @note This API is part of the legacy event system. New code should use event library API in esp_event.h
*
* @param system_event_t * event : event
* Other task/modules, such as the tcpip_adapter, can call this API to send an event to event task
*
* @param event Event to send
*
* @return ESP_OK : succeed
* @return others : fail
@ -159,34 +137,85 @@ 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
*
* @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.
*
* 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);
/**
* @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
*
* @return
* - ESP_OK: succeed
* - others: fail
*/
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
* @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
*
* @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);
#ifdef __cplusplus
}
#endif
#endif /* __ESP_EVENT_H__ */

View file

@ -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 <stdint.h>
#include <stdbool.h>
#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"

View file

@ -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")

View file

@ -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

View file

@ -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 <string.h>
#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);
}
}
}

View file

@ -18,10 +18,8 @@
#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
static esp_pm_lock_handle_t s_wifi_modem_sleep_lock;
@ -30,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,
@ -98,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();

View file

@ -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);
@ -1067,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);
}

View file

@ -19,6 +19,9 @@
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#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
*

View file

@ -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;
}

View file

@ -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"
/**

View file

@ -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 {

View file

@ -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)

View file

@ -0,0 +1,309 @@
// 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 <string.h>
#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, &eth_ip);
tcpip_adapter_eth_start(eth_mac, &eth_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, &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, &eth_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 && err != ESP_ERR_INVALID_STATE) {
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);
esp_unregister_shutdown_handler((shutdown_handler_t)esp_wifi_stop);
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;
}

View file

@ -143,6 +143,37 @@ 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;
/** 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
*
@ -661,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

View file

@ -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;

View file

@ -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
##

View file

@ -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 <esp-event-default-loops>` 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`.

View file

@ -10,6 +10,7 @@ API Guides
Build System (CMake) <build-system-cmake>
Error Handling <error-handling>
Fatal Errors <fatal-errors>
Event Handling <event-handling>
Deep Sleep Wake Stubs <deep-sleep-stub>
ESP32 Core Dump <core_dump>
Flash Encryption <../security/flash-encryption>

View file

@ -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<event-handling>`.
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 <esp-event-default-loops>`. 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 <SYSTEM_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.
- 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
---------------------------

View file

@ -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
^^^^^^^^^^^^^

View file

@ -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 <esp-event-declaring-defining-events>`.
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 <esp_event_legacy>

View file

@ -0,0 +1,7 @@
Legacy event loop
=================
API Reference
-------------
.. include:: /_build/inc/esp_event_legacy.inc

View file

@ -0,0 +1 @@
.. include:: ../../en/api-guides/event-handling.rst

View file

@ -10,6 +10,7 @@ API 指南
构建系统 (CMake) <build-system-cmake>
错误处理 <error-handling>
Fatal Errors <fatal-errors>
Event Handling <event-handling>
Deep Sleep Wake Stubs <deep-sleep-stub>
ESP32 Core Dump <core_dump>
Flash Encryption <../security/flash-encryption>

View file

@ -0,0 +1 @@
.. include:: ../../../en/api-reference/system/esp_event_legacy.rst

View file

@ -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";

View file

@ -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

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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;

View file

@ -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):