关于esp32默认事件循环 默认WiFi事件注册和获取事件信息

参考esp-idf V4.0.1中的smart_config例程。
包括默认wifi事件的注册、事件的响应、事件信息的获取。

1.事件的注册

    ESP_ERROR_CHECK(esp_event_loop_create_default());
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));

首先调用esp_event_loop_create_default() 创建默认事件循环。
之后使用esp_event_handler_register() 将事件处理程序注册到系统事件循环。
引用官方手册:

esp_event_handler_register() 
此函数可用于注册以下各项的处理程序:(1)特定事件,(2)某个事件基础的所有事件,或(3)系统事件循环已知的所有事件。

特定事件:指定确切的event_base和event_id
特定基准的所有事件:指定确切的event_base并使用ESP_EVENT_ANY_ID作为event_id
循环已知的所有事件:将ESP_EVENT_ANY_BASE用作event_base,将ESP_EVENT_ANY_ID用作event_id
可以将多个处理程序注册到事件。将单个处理程序注册到多个事件也是可能的。但是,将同一处理程序多次注册到同一事件将导致以前的注册被覆盖。

注意
事件循环库不维护event_handler_arg的副本,因此用户应确保在调用处理程序时event_handler_arg仍指向有效位置
返回
ESP_OK:成功
ESP_ERR_NO_MEM:无法为处理程序分配内存
ESP_ERR_INVALID_ARG:事件库和事件ID的无效组合
其他:失败
参量
event_base:要为其注册处理程序的事件的基本ID
event_id:要为其注册处理程序的事件的ID
event_handler:在调度事件时调用的处理函数
event_handler_arg:除事件数据外,在调用时传递给处理程序的数据

此处使用ESP_EVENT_ANY_ID将WIFI事件和IP事件全部注册到响应函数event_handler,无参数传递。

2.事件的响应

关于响应函数,这里只写了AP模式的WIFI_EVENT_AP_STACONNECTED、WIFI_EVENT_AP_STADISCONNECTED 两个事件部分以做演示。

static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    ESP_LOGI(TAG,"event_base:%s, event_id:%d\r\n",event_base, event_id);
    wifi_event_ap_staconnected_t *wifi_event_data;
    if (event_base == WIFI_EVENT){
        switch (event_id)
        {
            case WIFI_EVENT_STA_START:                  //STA模式启动
                /* code */
                break;
            case WIFI_EVENT_STA_STOP:                   //STA模式关闭
                /* code */
                break;
            case WIFI_EVENT_STA_DISCONNECTED:           //STA模式断开连接
                /* code */
                break;
            case WIFI_EVENT_AP_START:                   //AP模式启动
                /* code */
                break;
            case WIFI_EVENT_AP_STOP:                    //AP模式关闭
                /* code */
                break;
            case WIFI_EVENT_AP_STACONNECTED:            //一台设备连接到esp32
                wifi_event_ap_staconnected_t *AP_STACONNECTED_EVENT_DATA = (wifi_event_ap_staconnected_t *)event_data;  //获取事件信息
                ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", MAC2STR(AP_STACONNECTED_EVENT_DATA->mac), AP_STACONNECTED_EVENT_DATA->aid);
                break;
            case WIFI_EVENT_AP_STADISCONNECTED:         //一台设备断开与esp32的连接
                wifi_event_ap_stadisconnected_t *AP_STADISCONNECTED_EVENT_DATA = (wifi_event_ap_stadisconnected_t *)event_data;  //获取事件信息
                ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", MAC2STR(AP_STADISCONNECTED_EVENT_DATA->mac), AP_STADISCONNECTED_EVENT_DATA->aid);
                break;
            default:
                break;
        }
    }else if(event_base == IP_EVENT){
        switch (event_id)
        {
        case IP_EVENT_STA_GOT_IP:                       //esp32从路由器获取到ip
            /* code */
            break;
        case IP_EVENT_STA_LOST_IP:                      //esp32失去ip
            /* code */
            break;
        case IP_EVENT_AP_STAIPASSIGNED:                 //esp32给设备分配了ip
            /* code */
            break;
        default:
            break;
        }
    }

event事件传入四个参数,分别为
arg:注册时传入的参数
event_base:事件的基础名
event_id:事件的id
event_data:事件的信息

可以通过event_base和event_id获取本次事件类型。

3.事件信息的获取

参照以上响应代码,事件的信息由传入参数event_data中获取。

wifi_event_ap_staconnected_t *AP_STACONNECTED_EVENT_DATA = (wifi_event_ap_staconnected_t *)event_data;  //获取事件信息

不同的事件所获取的信息也不同,强制转换将event_data转换为本次事件的信息结构类型以便获取事件信息。
事件信息结构类型一般命名为“全小写_t”。具体结构类型名在esp-idf的相应.h文件中查找(和事件名定义在同一文件中)。