Merge branch 'feature/add_esp_event' into 'master'

esp_event: add esp_event component

See merge request sdk/ESP8266_RTOS_SDK!1274
This commit is contained in:
Dong Heng
2020-02-25 10:26:47 +08:00
200 changed files with 5380 additions and 4170 deletions

View File

@ -29,8 +29,6 @@ else()
"source/esp_wifi_os_adapter.c"
"source/esp_wifi.c"
"source/ets_printf.c"
"source/event_default_handlers.c"
"source/event_loop.c"
"source/phy_init.c"
"source/reset_reason.c"
"source/startup.c"
@ -53,7 +51,7 @@ else()
set(include_dirs "include" "include/driver")
set(requires "esp_common")
set(requires "esp_common" "esp_event")
set(priv_requires "wpa_supplicant" "log" "spi_flash" "tcpip_adapter" "esp_ringbuf" "bootloader_support" "nvs_flash" "util")
set(fragments linker.lf ld/esp8266_fragments.lf ld/esp8266_bss_fragments.lf)

View File

@ -1,201 +0,0 @@
// 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.
#ifndef __ESP_EVENT_H__
#define __ESP_EVENT_H__
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "esp_wifi_types.h"
#include "lwip/ip_addr.h"
#include "tcpip_adapter.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_EVENT_IPV6 LWIP_IPV6
typedef enum {
SYSTEM_EVENT_WIFI_READY = 0, /**< ESP8266 WiFi ready */
SYSTEM_EVENT_SCAN_DONE, /**< ESP8266 finish scanning AP */
SYSTEM_EVENT_STA_START, /**< ESP8266 station start */
SYSTEM_EVENT_STA_STOP, /**< ESP8266 station stop */
SYSTEM_EVENT_STA_CONNECTED, /**< ESP8266 station connected to AP */
SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP8266 station disconnected from AP */
SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP8266 station changed */
SYSTEM_EVENT_STA_GOT_IP, /**< ESP8266 station got IP from connected AP */
SYSTEM_EVENT_STA_LOST_IP, /**< ESP8266 station lost IP and the IP is reset to 0 */
SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /**< ESP8266 station wps succeeds in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_FAILED, /**< ESP8266 station wps fails in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP8266 station wps timeout in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_PIN, /**< ESP8266 station wps pin code in enrollee mode */
SYSTEM_EVENT_AP_START, /**< ESP8266 soft-AP start */
SYSTEM_EVENT_AP_STOP, /**< ESP8266 soft-AP stop */
SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP8266 soft-AP */
SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP8266 soft-AP */
SYSTEM_EVENT_AP_STAIPASSIGNED, /**< ESP8266 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, /**< ESP8266 station or ap or ethernet interface v6IP addr is preferred */
SYSTEM_EVENT_ETH_START, /**< ESP8266 ethernet start */
SYSTEM_EVENT_ETH_STOP, /**< ESP8266 ethernet stop */
SYSTEM_EVENT_ETH_CONNECTED, /**< ESP8266 ethernet phy link up */
SYSTEM_EVENT_ETH_DISCONNECTED, /**< ESP8266 ethernet phy link down */
SYSTEM_EVENT_ETH_GOT_IP, /**< ESP8266 ethernet got IP from connected AP */
SYSTEM_EVENT_MAX
} system_event_id_t;
/* add this macro define for compatible with old IDF version */
#ifndef SYSTEM_EVENT_AP_STA_GOT_IP6
#define SYSTEM_EVENT_AP_STA_GOT_IP6 SYSTEM_EVENT_GOT_IP6
#endif
typedef enum {
WPS_FAIL_REASON_NORMAL = 0, /**< ESP8266 WPS normal fail reason */
WPS_FAIL_REASON_RECV_M2D, /**< ESP8266 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;
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;
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;
typedef struct {
tcpip_adapter_ip_info_t ip_info;
bool ip_changed;
} system_event_sta_got_ip_t;
typedef struct {
uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */
} system_event_sta_wps_er_pin_t;
typedef struct {
tcpip_adapter_if_t if_index;
tcpip_adapter_ip6_info_t ip6_info;
} system_event_got_ip6_t;
typedef struct {
uint8_t mac[6]; /**< MAC address of the station connected to ESP8266 soft-AP */
uint8_t aid; /**< the aid that ESP8266 soft-AP gives to the station connected to */
} system_event_ap_staconnected_t;
typedef struct {
uint8_t mac[6]; /**< MAC address of the station disconnects to ESP8266 soft-AP */
uint8_t aid; /**< the aid that ESP8266 soft-AP gave to the station disconnects to */
} 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;
typedef union {
system_event_sta_connected_t connected; /**< ESP8266 station connected to AP */
system_event_sta_disconnected_t disconnected; /**< ESP8266 station disconnected to AP */
system_event_sta_scan_done_t scan_done; /**< ESP8266 station scan (APs) done */
system_event_sta_authmode_change_t auth_change; /**< the auth mode of AP ESP8266 station connected to changed */
system_event_sta_got_ip_t got_ip; /**< ESP8266 station got IP, first time got IP or when IP is changed */
system_event_sta_wps_er_pin_t sta_er_pin; /**< ESP8266 station WPS enrollee mode PIN code received */
system_event_sta_wps_fail_reason_t sta_er_fail_reason;/**< ESP8266 station WPS enrollee mode failed reason code received */
system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP8266 soft-AP */
system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP8266 soft-AP */
system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP8266 soft-AP receive probe request packet */
system_event_got_ip6_t got_ip6; /**< ESP8266 station or ap or ethernet ipv6 addr state change to preferred */
} system_event_info_t;
typedef struct {
system_event_id_t event_id; /**< event ID */
system_event_info_t event_info; /**< event information */
} system_event_t;
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
*
* @param system_event_t * event : event
*
* @return ESP_OK : succeed
* @return others : fail
*/
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
*/
esp_err_t esp_event_process_default(system_event_t *event);
/**
* @brief Install default event handlers for Wi-Fi interfaces (station and AP)
*
*/
void esp_event_set_default_wifi_handlers();
/**
* @brief Create default event loop
*
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
* - ESP_FAIL: Failed to create task loop
* - Others: Fail
*/
esp_err_t esp_event_loop_create_default(void);
#ifdef __cplusplus
}
#endif
#endif /* __ESP_EVENT_H__ */

View File

@ -1,83 +0,0 @@
// 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.
#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"
#define EVENT_LOOP_STACKSIZE CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE
#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__ */

View File

@ -18,8 +18,10 @@
#include <stdint.h>
#include <stdbool.h>
#include <sys/queue.h>
#include "esp_err.h"
#include "esp_interface.h"
#include "esp_event_base.h"
#ifdef __cplusplus
extern "C" {
@ -418,6 +420,91 @@ typedef struct {
unsigned unused: 4; /*!< Resolved */
} wifi_tx_status_t;
/** @cond **/
/** @brief WiFi event base declaration */
ESP_EVENT_DECLARE_BASE(WIFI_EVENT);
/** @endcond **/
/** WiFi event declarations */
typedef enum {
WIFI_EVENT_WIFI_READY = 0, /**< WiFi ready */
WIFI_EVENT_SCAN_DONE, /**< finish scanning AP */
WIFI_EVENT_STA_START, /**< station start */
WIFI_EVENT_STA_STOP, /**< station stop */
WIFI_EVENT_STA_CONNECTED, /**< station connected to AP */
WIFI_EVENT_STA_DISCONNECTED, /**< station disconnected from AP */
WIFI_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by station changed */
WIFI_EVENT_STA_WPS_ER_SUCCESS, /**< station wps succeeds in enrollee mode */
WIFI_EVENT_STA_WPS_ER_FAILED, /**< station wps fails in enrollee mode */
WIFI_EVENT_STA_WPS_ER_TIMEOUT, /**< station wps timeout in enrollee mode */
WIFI_EVENT_STA_WPS_ER_PIN, /**< station wps pin code in enrollee mode */
WIFI_EVENT_AP_START, /**< soft-AP start */
WIFI_EVENT_AP_STOP, /**< soft-AP stop */
WIFI_EVENT_AP_STACONNECTED, /**< a station connected to soft-AP */
WIFI_EVENT_AP_STADISCONNECTED, /**< a station disconnected from soft-AP */
WIFI_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */
} wifi_event_t;
/** Argument structure for WIFI_EVENT_STA_WPS_ER_FAILED event */
typedef enum {
WPS_FAIL_REASON_NORMAL = 0, /**< WPS normal fail reason */
WPS_FAIL_REASON_RECV_M2D, /**< WPS receive M2D frame */
WPS_FAIL_REASON_MAX
} wifi_event_sta_wps_fail_reason_t;
/** 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_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_AP_STACONNECTED event */
typedef struct {
uint8_t mac[6]; /**< MAC address of the station connected to soft-AP */
uint8_t aid; /**< the aid that 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 soft-AP */
uint8_t aid; /**< the aid that 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;
/** 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;
#ifdef __cplusplus
}
#endif

View File

@ -16,9 +16,12 @@
#include "esp_libc.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "internal/esp_wifi_internal.h"
#include "phy.h"
#define TAG "wifi_init"
const size_t _g_esp_wifi_ppt_task_stk_size = CONFIG_WIFI_PPT_TASKSTACK_SIZE;
#if CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET
@ -29,6 +32,8 @@ const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = false;
esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config);
ESP_EVENT_DEFINE_BASE(WIFI_EVENT);
static void esp_wifi_set_debug_log()
{
/* set WiFi log level and module */
@ -124,11 +129,16 @@ static void esp_wifi_set_debug_log()
*/
esp_err_t esp_wifi_init(const wifi_init_config_t *config)
{
esp_event_set_default_wifi_handlers();
esp_err_t result = esp_wifi_init_internal(config);
if (result == ESP_OK) {
esp_wifi_set_debug_log();
}
result = tcpip_adapter_set_default_wifi_handlers();
if (result != ESP_OK) {
ESP_LOGW(TAG, "Failed to set default Wi-Fi event handlers (0x%x)", result);
}
return result;
}

View File

@ -1,323 +0,0 @@
// 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 <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "rom/ets_sys.h"
#include "esp_err.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_system.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 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);
/* 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 };
static esp_err_t system_event_sta_got_ip_default(system_event_t *event)
{
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_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_start(TCPIP_ADAPTER_IF_AP, ap_mac, &ap_ip);
return ESP_OK;
}
esp_err_t system_event_ap_stop_handle_default(system_event_t *event)
{
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_start(TCPIP_ADAPTER_IF_STA, 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;
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) || ip4_addr_isany_val(sta_ip.gw))) {
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);
return ESP_OK;
}
static esp_err_t esp_system_event_debug(system_event_t *event)
{
if (event == NULL) {
ESP_LOGE(TAG, "event is null!");
printf("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", \
disconnected->ssid, disconnected->ssid_len, MAC2STR(disconnected->bssid), 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;
}
#if ESP_EVENT_IPV6
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;
}
#endif
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);
}

View File

@ -1,116 +0,0 @@
// 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 <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "esp_err.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
static const char* TAG = "event";
static bool s_event_init_flag = false;
static void *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;
}
int ret = xQueueGenericSend(s_event_queue, event, 0, queueSEND_TO_BACK);
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(32, sizeof(system_event_t));
if(s_event_queue == NULL)
return ESP_ERR_NO_MEM;
if(xTaskCreate(esp_event_loop_task, "esp_event_loop_task", EVENT_LOOP_STACKSIZE, NULL, configMAX_PRIORITIES - 5, NULL) != pdPASS) {
return ESP_ERR_NO_MEM;
}
s_event_handler_cb = cb;
s_event_ctx = ctx;
s_event_init_flag = true;
return ESP_OK;
}
esp_err_t esp_event_loop_create_default(void)
{
return ESP_OK;
}

View File

@ -0,0 +1,13 @@
idf_component_register(SRCS "default_event_loop.c"
"esp_event.c"
"esp_event_private.c"
"event_loop_legacy.c"
"event_send.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES log tcpip_adapter)
if(GCC_NOT_5_2_0 AND CONFIG_ESP_EVENT_LOOP_PROFILING)
# uses C11 atomic feature
set_source_files_properties(esp_event.c PROPERTIES COMPILE_FLAGS -std=gnu11)
endif()

View File

@ -0,0 +1,17 @@
menu "Event Loop Library"
config ESP_EVENT_LOOP_PROFILING
bool "Enable event loop profiling"
default n
help
Enables collections of statistics in the event loop library such as the number of events posted
to/recieved by an event loop, number of callbacks involved, number of events dropped to to a full event
loop queue, run time of event handlers, and number of times/run time of each event handler.
config ESP_EVENT_POST_FROM_ISR
bool "Support posting events from ISRs"
default y
help
Enable posting events from interrupt handlers.
endmenu

View File

@ -0,0 +1,17 @@
#
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_PRIV_INCLUDEDIRS := private_include
COMPONENT_SRCDIRS := .
ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
PROFILING_ENABLED := 1
else
PROFILING_ENABLED := 0
endif
ifeq ($(and $(GCC_NOT_5_2_0),$(PROFILING_ENABLED)), 1)
# uses C11 atomic feature
esp_event.o: CFLAGS += -std=gnu11
endif

View File

@ -0,0 +1,120 @@
// 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_internal.h"
#include "esp_task.h"
/* ------------------------- Static Variables ------------------------------- */
static esp_event_loop_handle_t s_default_loop = NULL;
/* ---------------------------- Public API ---------------------------------- */
esp_err_t esp_event_handler_register(esp_event_base_t event_base, int32_t event_id,
esp_event_handler_t event_handler, void* event_handler_arg)
{
if (s_default_loop == NULL) {
return ESP_ERR_INVALID_STATE;
}
return esp_event_handler_register_with(s_default_loop, event_base, event_id,
event_handler, event_handler_arg);
}
esp_err_t esp_event_handler_unregister(esp_event_base_t event_base, int32_t event_id,
esp_event_handler_t event_handler)
{
if (s_default_loop == NULL) {
return ESP_ERR_INVALID_STATE;
}
return esp_event_handler_unregister_with(s_default_loop, event_base, event_id,
event_handler);
}
esp_err_t esp_event_post(esp_event_base_t event_base, int32_t event_id,
void* event_data, size_t event_data_size, TickType_t ticks_to_wait)
{
if (s_default_loop == NULL) {
return ESP_ERR_INVALID_STATE;
}
return esp_event_post_to(s_default_loop, event_base, event_id,
event_data, event_data_size, ticks_to_wait);
}
#if CONFIG_ESP_EVENT_POST_FROM_ISR
esp_err_t esp_event_isr_post(esp_event_base_t event_base, int32_t event_id,
void* event_data, size_t event_data_size, BaseType_t* task_unblocked)
{
if (s_default_loop == NULL) {
return ESP_ERR_INVALID_STATE;
}
return esp_event_isr_post_to(s_default_loop, event_base, event_id,
event_data, event_data_size, task_unblocked);
}
#endif
esp_err_t esp_event_loop_create_default()
{
if (s_default_loop) {
return ESP_ERR_INVALID_STATE;
}
esp_event_loop_args_t loop_args = {
.queue_size = CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE,
.task_name = "sys_evt",
.task_stack_size = ESP_TASKD_EVENT_STACK,
.task_priority = ESP_TASKD_EVENT_PRIO,
.task_core_id = 0
};
esp_err_t err;
err = esp_event_loop_create(&loop_args, &s_default_loop);
if (err != ESP_OK) {
return err;
}
return ESP_OK;
}
esp_err_t esp_event_loop_delete_default()
{
if (!s_default_loop) {
return ESP_ERR_INVALID_STATE;
}
esp_err_t err;
err = esp_event_loop_delete(s_default_loop);
if (err != ESP_OK) {
return err;
}
s_default_loop = NULL;
return ESP_OK;
}
/* Include the code to forward legacy system_event_t events to the this default
* event loop.
*/
#include "event_send_compat.inc"

View File

@ -0,0 +1,944 @@
// 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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "esp_log.h"
#include "esp_event.h"
#include "esp_event_internal.h"
#include "esp_event_private.h"
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
#include "esp_timer.h"
#endif
/* ---------------------------- Definitions --------------------------------- */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
// LOOP @<address, name> rx:<recieved events no.> dr:<dropped events no.>
#define LOOP_DUMP_FORMAT "LOOP @%p,%s rx:%u dr:%u\n"
// handler @<address> ev:<base, id> inv:<times invoked> time:<runtime>
#define HANDLER_DUMP_FORMAT " HANDLER @%p ev:%s,%s inv:%u time:%lld us\n"
#define PRINT_DUMP_INFO(dst, sz, ...) do { \
int cb = snprintf(dst, sz, __VA_ARGS__); \
dst += cb; \
sz -= cb; \
} while(0);
#endif
/* ------------------------- Static Variables ------------------------------- */
static const char* TAG = "event";
static const char* esp_event_any_base = "any";
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
static SLIST_HEAD(esp_event_loop_instance_list_t, esp_event_loop_instance) s_event_loops =
SLIST_HEAD_INITIALIZER(s_event_loops);
static portMUX_TYPE s_event_loops_spinlock = portMUX_INITIALIZER_UNLOCKED;
#endif
/* ------------------------- Static Functions ------------------------------- */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
static int esp_event_dump_prepare()
{
esp_event_loop_instance_t* loop_it;
esp_event_loop_node_t *loop_node_it;
esp_event_base_node_t* base_node_it;
esp_event_id_node_t* id_node_it;
esp_event_handler_instance_t* handler_it;
// Count the number of items to be printed. This is needed to compute how much memory to reserve.
int loops = 0, handlers = 0;
portENTER_CRITICAL(&s_event_loops_spinlock);
SLIST_FOREACH(loop_it, &s_event_loops, next) {
SLIST_FOREACH(loop_node_it, &(loop_it->loop_nodes), next) {
SLIST_FOREACH(handler_it, &(loop_node_it->handlers), next) {
handlers++;
}
SLIST_FOREACH(base_node_it, &(loop_node_it->base_nodes), next) {
SLIST_FOREACH(handler_it, &(base_node_it->handlers), next) {
handlers++;
}
SLIST_FOREACH(id_node_it, &(base_node_it->id_nodes), next) {
SLIST_FOREACH(handler_it, &(id_node_it->handlers), next) {
handlers++;
}
}
}
}
loops++;
}
portEXIT_CRITICAL(&s_event_loops_spinlock);
// Reserve slightly more memory than computed
int allowance = 3;
int size = (((loops + allowance) * (sizeof(LOOP_DUMP_FORMAT) + 10 + 20 + 2 * 11)) +
((handlers + allowance) * (sizeof(HANDLER_DUMP_FORMAT) + 10 + 2 * 20 + 11 + 20)));
return size;
}
#endif
static void esp_event_loop_run_task(void* args)
{
esp_err_t err;
esp_event_loop_handle_t event_loop = (esp_event_loop_handle_t) args;
ESP_LOGD(TAG, "running task for loop %p", event_loop);
while(1) {
err = esp_event_loop_run(event_loop, portMAX_DELAY);
if (err != ESP_OK) {
break;
}
}
ESP_LOGE(TAG, "suspended task for loop %p", event_loop);
vTaskSuspend(NULL);
}
static void handler_execute(esp_event_loop_instance_t* loop, esp_event_handler_instance_t *handler, esp_event_post_instance_t post)
{
ESP_LOGD(TAG, "running post %s:%d with handler %p on loop %p", post.base, post.id, handler->handler, loop);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
int64_t start, diff;
start = esp_timer_get_time();
#endif
// Execute the handler
#if CONFIG_ESP_EVENT_POST_FROM_ISR
void* data_ptr = NULL;
if (post.data_set) {
if (post.data_allocated) {
data_ptr = post.data.ptr;
} else {
data_ptr = &post.data.val;
}
}
(*(handler->handler))(handler->arg, post.base, post.id, data_ptr);
#else
(*(handler->handler))(handler->arg, post.base, post.id, post.data);
#endif
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
diff = esp_timer_get_time() - start;
xSemaphoreTake(loop->profiling_mutex, portMAX_DELAY);
handler->invoked++;
handler->time += diff;
xSemaphoreGive(loop->profiling_mutex);
#endif
}
static esp_err_t handler_instances_add(esp_event_handler_instances_t* handlers, esp_event_handler_t handler, void* handler_arg)
{
esp_event_handler_instance_t* handler_instance = calloc(1, sizeof(*handler_instance));
if (!handler_instance) {
return ESP_ERR_NO_MEM;
}
handler_instance->handler = handler;
handler_instance->arg = handler_arg;
if (SLIST_EMPTY(handlers)) {
SLIST_INSERT_HEAD(handlers, handler_instance, next);
}
else {
esp_event_handler_instance_t *it = NULL, *last = NULL;
SLIST_FOREACH(it, handlers, next) {
if (handler == it->handler) {
it->arg = handler_arg;
ESP_LOGW(TAG, "handler already registered, overwriting");
free(handler_instance);
return ESP_OK;
}
last = it;
}
SLIST_INSERT_AFTER(last, handler_instance, next);
}
return ESP_OK;
}
static esp_err_t base_node_add_handler(esp_event_base_node_t* base_node, int32_t id, esp_event_handler_t handler, void* handler_arg)
{
if (id == ESP_EVENT_ANY_ID) {
return handler_instances_add(&(base_node->handlers), handler, handler_arg);
}
else {
esp_err_t err = ESP_OK;
esp_event_id_node_t *it = NULL, *id_node = NULL, *last_id_node = NULL;
SLIST_FOREACH(it, &(base_node->id_nodes), next) {
if (it->id == id) {
id_node = it;
}
last_id_node = it;
}
if (!last_id_node || !id_node) {
id_node = (esp_event_id_node_t*) calloc(1, sizeof(*id_node));
if (!id_node) {
ESP_LOGE(TAG, "alloc for new id node failed");
return ESP_ERR_NO_MEM;
}
id_node->id = id;
SLIST_INIT(&(id_node->handlers));
err = handler_instances_add(&(id_node->handlers), handler, handler_arg);
if (err == ESP_OK) {
if (!last_id_node) {
SLIST_INSERT_HEAD(&(base_node->id_nodes), id_node, next);
}
else {
SLIST_INSERT_AFTER(last_id_node, id_node, next);
}
} else {
free(id_node);
}
return err;
}
else {
return handler_instances_add(&(id_node->handlers), handler, handler_arg);
}
}
}
static esp_err_t loop_node_add_handler(esp_event_loop_node_t* loop_node, esp_event_base_t base, int32_t id, esp_event_handler_t handler, void* handler_arg)
{
if (base == esp_event_any_base && id == ESP_EVENT_ANY_ID) {
return handler_instances_add(&(loop_node->handlers), handler, handler_arg);
}
else {
esp_err_t err = ESP_OK;
esp_event_base_node_t *it = NULL, *base_node = NULL, *last_base_node = NULL;
SLIST_FOREACH(it, &(loop_node->base_nodes), next) {
if (it->base == base) {
base_node = it;
}
last_base_node = it;
}
if (!last_base_node ||
!base_node ||
(base_node && !SLIST_EMPTY(&(base_node->id_nodes)) && id == ESP_EVENT_ANY_ID) ||
(last_base_node && last_base_node->base != base && !SLIST_EMPTY(&(last_base_node->id_nodes)) && id == ESP_EVENT_ANY_ID)) {
base_node = (esp_event_base_node_t*) calloc(1, sizeof(*base_node));
if (!base_node) {
ESP_LOGE(TAG, "alloc mem for new base node failed");
return ESP_ERR_NO_MEM;
}
base_node->base = base;
SLIST_INIT(&(base_node->handlers));
SLIST_INIT(&(base_node->id_nodes));
err = base_node_add_handler(base_node, id, handler, handler_arg);
if (err == ESP_OK) {
if (!last_base_node) {
SLIST_INSERT_HEAD(&(loop_node->base_nodes), base_node, next);
}
else {
SLIST_INSERT_AFTER(last_base_node, base_node, next);
}
} else {
free(base_node);
}
return err;
} else {
return base_node_add_handler(base_node, id, handler, handler_arg);
}
}
}
static esp_err_t handler_instances_remove(esp_event_handler_instances_t* handlers, esp_event_handler_t handler)
{
esp_event_handler_instance_t *it, *temp;
SLIST_FOREACH_SAFE(it, handlers, next, temp) {
if (it->handler == handler) {
SLIST_REMOVE(handlers, it, esp_event_handler_instance, next);
free(it);
return ESP_OK;
}
}
return ESP_ERR_NOT_FOUND;
}
static esp_err_t base_node_remove_handler(esp_event_base_node_t* base_node, int32_t id, esp_event_handler_t handler)
{
if (id == ESP_EVENT_ANY_ID) {
return handler_instances_remove(&(base_node->handlers), handler);
}
else {
esp_event_id_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(base_node->id_nodes), next, temp) {
if (it->id == id) {
esp_err_t res = handler_instances_remove(&(it->handlers), handler);
if (res == ESP_OK) {
if (SLIST_EMPTY(&(it->handlers))) {
SLIST_REMOVE(&(base_node->id_nodes), it, esp_event_id_node, next);
free(it);
return ESP_OK;
}
}
}
}
}
return ESP_ERR_NOT_FOUND;
}
static esp_err_t loop_node_remove_handler(esp_event_loop_node_t* loop_node, esp_event_base_t base, int32_t id, esp_event_handler_t handler)
{
if (base == esp_event_any_base && id == ESP_EVENT_ANY_ID) {
return handler_instances_remove(&(loop_node->handlers), handler);
}
else {
esp_event_base_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(loop_node->base_nodes), next, temp) {
if (it->base == base) {
esp_err_t res = base_node_remove_handler(it, id, handler);
if (res == ESP_OK) {
if (SLIST_EMPTY(&(it->handlers)) && SLIST_EMPTY(&(it->id_nodes))) {
SLIST_REMOVE(&(loop_node->base_nodes), it, esp_event_base_node, next);
free(it);
return ESP_OK;
}
}
}
}
}
return ESP_ERR_NOT_FOUND;
}
static void handler_instances_remove_all(esp_event_handler_instances_t* handlers)
{
esp_event_handler_instance_t *it, *temp;
SLIST_FOREACH_SAFE(it, handlers, next, temp) {
SLIST_REMOVE(handlers, it, esp_event_handler_instance, next);
free(it);
}
}
static void base_node_remove_all_handler(esp_event_base_node_t* base_node)
{
handler_instances_remove_all(&(base_node->handlers));
esp_event_id_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(base_node->id_nodes), next, temp) {
handler_instances_remove_all(&(it->handlers));
SLIST_REMOVE(&(base_node->id_nodes), it, esp_event_id_node, next);
free(it);
}
}
static void loop_node_remove_all_handler(esp_event_loop_node_t* loop_node)
{
handler_instances_remove_all(&(loop_node->handlers));
esp_event_base_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(loop_node->base_nodes), next, temp) {
base_node_remove_all_handler(it);
SLIST_REMOVE(&(loop_node->base_nodes), it, esp_event_base_node, next);
free(it);
}
}
static void inline __attribute__((always_inline)) post_instance_delete(esp_event_post_instance_t* post)
{
#if CONFIG_ESP_EVENT_POST_FROM_ISR
if (post->data_allocated && post->data.ptr) {
free(post->data.ptr);
}
#else
if (post->data) {
free(post->data);
}
#endif
memset(post, 0, sizeof(*post));
}
/* ---------------------------- Public API --------------------------------- */
esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, esp_event_loop_handle_t* event_loop)
{
assert(event_loop_args);
esp_event_loop_instance_t* loop;
esp_err_t err = ESP_ERR_NO_MEM; // most likely error
loop = calloc(1, sizeof(*loop));
if (loop == NULL) {
ESP_LOGE(TAG, "alloc for event loop failed");
return err;
}
loop->queue = xQueueCreate(event_loop_args->queue_size , sizeof(esp_event_post_instance_t));
if (loop->queue == NULL) {
ESP_LOGE(TAG, "create event loop queue failed");
goto on_err;
}
loop->mutex = xSemaphoreCreateRecursiveMutex();
if (loop->mutex == NULL) {
ESP_LOGE(TAG, "create event loop mutex failed");
goto on_err;
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
loop->profiling_mutex = xSemaphoreCreateMutex();
if (loop->profiling_mutex == NULL) {
ESP_LOGE(TAG, "create event loop profiling mutex failed");
goto on_err;
}
#endif
SLIST_INIT(&(loop->loop_nodes));
// Create the loop task if requested
if (event_loop_args->task_name != NULL) {
BaseType_t task_created = xTaskCreatePinnedToCore(esp_event_loop_run_task, event_loop_args->task_name,
event_loop_args->task_stack_size, (void*) loop,
event_loop_args->task_priority, &(loop->task), event_loop_args->task_core_id);
if (task_created != pdPASS) {
ESP_LOGE(TAG, "create task for loop failed");
err = ESP_FAIL;
goto on_err;
}
loop->name = event_loop_args->task_name;
ESP_LOGD(TAG, "created task for loop %p", loop);
} else {
loop->name = "";
loop->task = NULL;
}
loop->running_task = NULL;
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
portENTER_CRITICAL(&s_event_loops_spinlock);
SLIST_INSERT_HEAD(&s_event_loops, loop, next);
portEXIT_CRITICAL(&s_event_loops_spinlock);
#endif
*event_loop = (esp_event_loop_handle_t) loop;
ESP_LOGD(TAG, "created event loop %p", loop);
return ESP_OK;
on_err:
if (loop->queue != NULL) {
vQueueDelete(loop->queue);
}
if (loop->mutex != NULL) {
vSemaphoreDelete(loop->mutex);
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
if (loop->profiling_mutex != NULL) {
vSemaphoreDelete(loop->profiling_mutex);
}
#endif
free(loop);
return err;
}
// On event lookup performance: The library implements the event list as a linked list, which results to O(n)
// lookup time. The test comparing this implementation to the O(lg n) performance of rbtrees
// (https://github.com/freebsd/freebsd/blob/master/sys/sys/tree.h)
// indicate that the difference is not that substantial, especially considering the additional
// pointers per node of rbtrees. Code for the rbtree implementation of the event loop library is archived
// in feature/esp_event_loop_library_rbtrees if needed.
esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t ticks_to_run)
{
assert(event_loop);
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
esp_event_post_instance_t post;
TickType_t marker = xTaskGetTickCount();
TickType_t end = 0;
#if (configUSE_16_BIT_TICKS == 1)
int32_t remaining_ticks = ticks_to_run;
#else
int64_t remaining_ticks = ticks_to_run;
#endif
while(xQueueReceive(loop->queue, &post, ticks_to_run) == pdTRUE) {
// The event has already been unqueued, so ensure it gets executed.
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
loop->running_task = xTaskGetCurrentTaskHandle();
bool exec = false;
esp_event_handler_instance_t *handler;
esp_event_loop_node_t *loop_node;
esp_event_base_node_t *base_node;
esp_event_id_node_t *id_node;
SLIST_FOREACH(loop_node, &(loop->loop_nodes), next) {
// Execute loop level handlers
SLIST_FOREACH(handler, &(loop_node->handlers), next) {
handler_execute(loop, handler, post);
exec |= true;
}
SLIST_FOREACH(base_node, &(loop_node->base_nodes), next) {
if (base_node->base == post.base) {
// Execute base level handlers
SLIST_FOREACH(handler, &(base_node->handlers), next) {
handler_execute(loop, handler, post);
exec |= true;
}
SLIST_FOREACH(id_node, &(base_node->id_nodes), next) {
if (id_node->id == post.id) {
// Execute id level handlers
SLIST_FOREACH(handler, &(id_node->handlers), next) {
handler_execute(loop, handler, post);
exec |= true;
}
// Skip to next base node
break;
}
}
}
}
}
esp_event_base_t base = post.base;
int32_t id = post.id;
post_instance_delete(&post);
if (ticks_to_run != portMAX_DELAY) {
end = xTaskGetTickCount();
remaining_ticks -= end - marker;
// If the ticks to run expired, return to the caller
if (remaining_ticks <= 0) {
xSemaphoreGiveRecursive(loop->mutex);
break;
} else {
marker = end;
}
}
loop->running_task = NULL;
xSemaphoreGiveRecursive(loop->mutex);
if (!exec) {
// No handlers were registered, not even loop/base level handlers
ESP_LOGD(TAG, "no handlers have been registered for event %s:%d posted to loop %p", base, id, event_loop);
}
}
return ESP_OK;
}
esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop)
{
assert(event_loop);
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
SemaphoreHandle_t loop_mutex = loop->mutex;
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
SemaphoreHandle_t loop_profiling_mutex = loop->profiling_mutex;
#endif
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
xSemaphoreTakeRecursive(loop->profiling_mutex, portMAX_DELAY);
portENTER_CRITICAL(&s_event_loops_spinlock);
SLIST_REMOVE(&s_event_loops, loop, esp_event_loop_instance, next);
portEXIT_CRITICAL(&s_event_loops_spinlock);
#endif
// Delete the task if it was created
if (loop->task != NULL) {
vTaskDelete(loop->task);
}
// Remove all registered events and handlers in the loop
esp_event_loop_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(loop->loop_nodes), next, temp) {
loop_node_remove_all_handler(it);
SLIST_REMOVE(&(loop->loop_nodes), it, esp_event_loop_node, next);
free(it);
}
// Drop existing posts on the queue
esp_event_post_instance_t post;
while(xQueueReceive(loop->queue, &post, 0) == pdTRUE) {
post_instance_delete(&post);
}
// Cleanup loop
vQueueDelete(loop->queue);
free(loop);
// Free loop mutex before deleting
xSemaphoreGiveRecursive(loop_mutex);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
xSemaphoreGiveRecursive(loop_profiling_mutex);
vSemaphoreDelete(loop_profiling_mutex);
#endif
vSemaphoreDelete(loop_mutex);
ESP_LOGD(TAG, "deleted loop %p", (void*) event_loop);
return ESP_OK;
}
esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
int32_t event_id, esp_event_handler_t event_handler, void* event_handler_arg)
{
assert(event_loop);
assert(event_handler);
if (event_base == ESP_EVENT_ANY_BASE && event_id != ESP_EVENT_ANY_ID) {
ESP_LOGE(TAG, "registering to any event base with specific id unsupported");
return ESP_ERR_INVALID_ARG;
}
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
if (event_base == ESP_EVENT_ANY_BASE) {
event_base = esp_event_any_base;
}
esp_err_t err = ESP_OK;
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
esp_event_loop_node_t *loop_node = NULL, *last_loop_node = NULL;
SLIST_FOREACH(loop_node, &(loop->loop_nodes), next) {
last_loop_node = loop_node;
}
bool is_loop_level_handler = (event_base == esp_event_any_base) && (event_id == ESP_EVENT_ANY_ID);
if (!last_loop_node ||
(last_loop_node && !SLIST_EMPTY(&(last_loop_node->base_nodes)) && is_loop_level_handler)) {
loop_node = (esp_event_loop_node_t*) calloc(1, sizeof(*loop_node));
SLIST_INIT(&(loop_node->handlers));
SLIST_INIT(&(loop_node->base_nodes));
if (!loop_node) {
ESP_LOGE(TAG, "alloc for new loop node failed");
err = ESP_ERR_NO_MEM;
goto on_err;
}
err = loop_node_add_handler(loop_node, event_base, event_id, event_handler, event_handler_arg);
if (err == ESP_OK) {
if (!last_loop_node) {
SLIST_INSERT_HEAD(&(loop->loop_nodes), loop_node, next);
}
else {
SLIST_INSERT_AFTER(last_loop_node, loop_node, next);
}
} else {
free(loop_node);
}
}
else {
err = loop_node_add_handler(last_loop_node, event_base, event_id, event_handler, event_handler_arg);
}
on_err:
xSemaphoreGiveRecursive(loop->mutex);
return err;
}
esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop, esp_event_base_t event_base,
int32_t event_id, esp_event_handler_t event_handler)
{
assert(event_loop);
assert(event_handler);
if (event_base == ESP_EVENT_ANY_BASE && event_id != ESP_EVENT_ANY_ID) {
ESP_LOGE(TAG, "unregistering to any event base with specific id unsupported");
return ESP_FAIL;
}
if (event_base == ESP_EVENT_ANY_BASE) {
event_base = esp_event_any_base;
}
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
xSemaphoreTakeRecursive(loop->mutex, portMAX_DELAY);
esp_event_loop_node_t *it, *temp;
SLIST_FOREACH_SAFE(it, &(loop->loop_nodes), next, temp) {
esp_err_t res = loop_node_remove_handler(it, event_base, event_id, event_handler);
if (res == ESP_OK && SLIST_EMPTY(&(it->base_nodes)) && SLIST_EMPTY(&(it->handlers))) {
SLIST_REMOVE(&(loop->loop_nodes), it, esp_event_loop_node, next);
free(it);
break;
}
}
xSemaphoreGiveRecursive(loop->mutex);
return ESP_OK;
}
esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t event_base, int32_t event_id,
void* event_data, size_t event_data_size, TickType_t ticks_to_wait)
{
assert(event_loop);
if (event_base == ESP_EVENT_ANY_BASE || event_id == ESP_EVENT_ANY_ID) {
return ESP_ERR_INVALID_ARG;
}
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
esp_event_post_instance_t post;
memset((void*)(&post), 0, sizeof(post));
if (event_data != NULL && event_data_size != 0) {
// Make persistent copy of event data on heap.
void* event_data_copy = calloc(1, event_data_size);
if (event_data_copy == NULL) {
return ESP_ERR_NO_MEM;
}
memcpy(event_data_copy, event_data, event_data_size);
#if CONFIG_ESP_EVENT_POST_FROM_ISR
post.data.ptr = event_data_copy;
post.data_allocated = true;
post.data_set = true;
#else
post.data = event_data_copy;
#endif
}
post.base = event_base;
post.id = event_id;
BaseType_t result = pdFALSE;
// Find the task that currently executes the loop. It is safe to query loop->task since it is
// not mutated since loop creation. ENSURE THIS REMAINS TRUE.
if (loop->task == NULL) {
// The loop has no dedicated task. Find out what task is currently running it.
result = xSemaphoreTakeRecursive(loop->mutex, ticks_to_wait);
if (result == pdTRUE) {
if (loop->running_task != xTaskGetCurrentTaskHandle()) {
xSemaphoreGiveRecursive(loop->mutex);
result = xQueueSendToBack(loop->queue, &post, ticks_to_wait);
} else {
xSemaphoreGiveRecursive(loop->mutex);
result = xQueueSendToBack(loop->queue, &post, 0);
}
}
} else {
// The loop has a dedicated task.
if (loop->task != xTaskGetCurrentTaskHandle()) {
result = xQueueSendToBack(loop->queue, &post, ticks_to_wait);
} else {
result = xQueueSendToBack(loop->queue, &post, 0);
}
}
if (result != pdTRUE) {
post_instance_delete(&post);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_fetch_add(&loop->events_dropped, 1);
#endif
return ESP_ERR_TIMEOUT;
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_fetch_add(&loop->events_recieved, 1);
#endif
return ESP_OK;
}
#if CONFIG_ESP_EVENT_POST_FROM_ISR
esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t event_base, int32_t event_id,
void* event_data, size_t event_data_size, BaseType_t* task_unblocked)
{
assert(event_loop);
if (event_base == ESP_EVENT_ANY_BASE || event_id == ESP_EVENT_ANY_ID) {
return ESP_ERR_INVALID_ARG;
}
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
esp_event_post_instance_t post;
memset((void*)(&post), 0, sizeof(post));
if (event_data_size > sizeof(post.data.val)) {
return ESP_ERR_INVALID_ARG;
}
if (event_data != NULL && event_data_size != 0) {
memcpy((void*)(&(post.data.val)), event_data, event_data_size);
post.data_allocated = false;
post.data_set = true;
}
post.base = event_base;
post.id = event_id;
BaseType_t result = pdFALSE;
// Post the event from an ISR,
result = xQueueSendToBackFromISR(loop->queue, &post, task_unblocked);
if (result != pdTRUE) {
post_instance_delete(&post);
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_fetch_add(&loop->events_dropped, 1);
#endif
return ESP_FAIL;
}
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_fetch_add(&loop->events_recieved, 1);
#endif
return ESP_OK;
}
#endif
esp_err_t esp_event_dump(FILE* file)
{
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
assert(file);
esp_event_loop_instance_t* loop_it;
esp_event_loop_node_t *loop_node_it;
esp_event_base_node_t* base_node_it;
esp_event_id_node_t* id_node_it;
esp_event_handler_instance_t* handler_it;
// Allocate memory for printing
int sz = esp_event_dump_prepare();
char* buf = calloc(sz, sizeof(char));
char* dst = buf;
char id_str_buf[20];
// Print info to buffer
portENTER_CRITICAL(&s_event_loops_spinlock);
SLIST_FOREACH(loop_it, &s_event_loops, next) {
uint32_t events_recieved, events_dropped;
events_recieved = atomic_load(&loop_it->events_recieved);
events_dropped = atomic_load(&loop_it->events_dropped);
PRINT_DUMP_INFO(dst, sz, LOOP_DUMP_FORMAT, loop_it, loop_it->task != NULL ? loop_it->name : "none" ,
events_recieved, events_dropped);
int sz_bak = sz;
SLIST_FOREACH(loop_node_it, &(loop_it->loop_nodes), next) {
SLIST_FOREACH(handler_it, &(loop_node_it->handlers), next) {
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler, "ESP_EVENT_ANY_BASE",
"ESP_EVENT_ANY_ID", handler_it->invoked, handler_it->time);
}
SLIST_FOREACH(base_node_it, &(loop_node_it->base_nodes), next) {
SLIST_FOREACH(handler_it, &(base_node_it->handlers), next) {
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler, base_node_it->base ,
"ESP_EVENT_ANY_ID", handler_it->invoked, handler_it->time);
}
SLIST_FOREACH(id_node_it, &(base_node_it->id_nodes), next) {
SLIST_FOREACH(handler_it, &(id_node_it->handlers), next) {
memset(id_str_buf, 0, sizeof(id_str_buf));
snprintf(id_str_buf, sizeof(id_str_buf), "%d", id_node_it->id);
PRINT_DUMP_INFO(dst, sz, HANDLER_DUMP_FORMAT, handler_it->handler, base_node_it->base ,
id_str_buf, handler_it->invoked, handler_it->time);
}
}
}
}
// No handlers registered for this loop
if (sz == sz_bak) {
PRINT_DUMP_INFO(dst, sz, " NO HANDLERS REGISTERED\n");
}
}
portEXIT_CRITICAL(&s_event_loops_spinlock);
// Print the contents of the buffer to the file
fprintf(file, buf);
// Free the allocated buffer
free(buf);
#endif
return ESP_OK;
}

View File

@ -0,0 +1,68 @@
// 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_private.h"
#include "esp_event_internal.h"
#include "esp_log.h"
bool esp_event_is_handler_registered(esp_event_loop_handle_t event_loop, esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler)
{
esp_event_loop_instance_t* loop = (esp_event_loop_instance_t*) event_loop;
bool result = false;
esp_event_loop_node_t* loop_node;
esp_event_base_node_t* base_node;
esp_event_id_node_t* id_node;
esp_event_handler_instance_t* handler;
SLIST_FOREACH(loop_node, &(loop->loop_nodes), next) {
SLIST_FOREACH(handler, &(loop_node->handlers), next) {
if(event_base == ESP_EVENT_ANY_BASE && event_id == ESP_EVENT_ANY_ID && handler->handler == event_handler)
{
result = true;
goto out;
}
}
SLIST_FOREACH(base_node, &(loop_node->base_nodes), next) {
if (base_node->base == event_base) {
SLIST_FOREACH(handler, &(base_node->handlers), next) {
if(event_id == ESP_EVENT_ANY_ID && handler->handler == event_handler)
{
result = true;
goto out;
}
}
SLIST_FOREACH(id_node, &(base_node->id_nodes), next) {
if(id_node->id == event_id) {
SLIST_FOREACH(handler, &(id_node->handlers), next) {
if(handler->handler == event_handler)
{
result = true;
goto out;
}
}
}
}
}
}
}
out:
xSemaphoreGive(loop->mutex);
return result;
}

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), portMAX_DELAY);
}
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,45 @@
// 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")));
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;
}
return ESP_OK;
}

View File

@ -0,0 +1,275 @@
// 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"
/**
* 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);
/* IP events */
HANDLE_SYS_EVENT_ARG(IP, STA_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;
}
#if LWIP_IPV6
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;
}
#endif
default: {
ESP_LOGW(TAG, "unexpected system event %d!", event->event_id);
break;
}
}
}
#endif // WITH_EVENT_DEBUG

View File

@ -0,0 +1,382 @@
// 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.
#ifndef ESP_EVENT_H_
#define ESP_EVENT_H_
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_event_base.h"
#include "esp_event_legacy.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Configuration for creating event loops
typedef struct {
int32_t queue_size; /**< size of the event loop queue */
const char* task_name; /**< name of the event loop task; if NULL,
a dedicated task is not created for event loop*/
UBaseType_t task_priority; /**< priority of the event loop task, ignored if task name is NULL */
uint32_t task_stack_size; /**< stack size of the event loop task, ignored if task name is NULL */
BaseType_t task_core_id; /**< core to which the event loop task is pinned to,
ignored if task name is NULL */
} esp_event_loop_args_t;
/**
* @brief Create a new event loop.
*
* @param[in] event_loop_args configuration structure for the event loop to create
* @param[out] event_loop handle to the created event loop
*
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
* - ESP_FAIL: Failed to create task loop
* - Others: Fail
*/
esp_err_t esp_event_loop_create(const esp_event_loop_args_t* event_loop_args, esp_event_loop_handle_t* event_loop);
/**
* @brief Delete an existing event loop.
*
* @param[in] event_loop event loop to delete
*
* @return
* - ESP_OK: Success
* - Others: Fail
*/
esp_err_t esp_event_loop_delete(esp_event_loop_handle_t event_loop);
/**
* @brief Create default event loop
*
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
* - ESP_FAIL: Failed to create task loop
* - Others: Fail
*/
esp_err_t esp_event_loop_create_default();
/**
* @brief Delete the default event loop
*
* @return
* - ESP_OK: Success
* - Others: Fail
*/
esp_err_t esp_event_loop_delete_default();
/**
* @brief Dispatch events posted to an event loop.
*
* This function is used to dispatch events posted to a loop with no dedicated task, i.e task name was set to NULL
* in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time
* it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee
* that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have
* been dispatched during the call, as the function might have spent all of the alloted time waiting on the event queue.
* Once an event has been unqueued, however, it is guaranteed to be dispatched. This guarantee contributes to not being
* able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the unqueued
* event, and (2) during dispatch of the unqueued event there is no way to control the time occupied by handler code
* execution. The guaranteed time of exit is therefore the alloted time + amount of time required to dispatch
* the last unqueued event.
*
* In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is
* normal behavior.
*
* @param[in] event_loop event loop to dispatch posted events from
* @param[in] ticks_to_run number of ticks to run the loop
*
* @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error.
*
* @return
* - ESP_OK: Success
* - Others: Fail
*/
esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t ticks_to_run);
/**
* @brief Register an event handler to the system event loop.
*
* This function can be used to register a handler for either: (1) specific events,
* (2) all events of a certain event base, or (3) all events known by the system event loop.
*
* - specific events: specify exact event_base and event_id
* - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
* - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
*
* Registering multiple handlers to events is possible. Registering a single handler to multiple events is
* also possible. However, registering the same handler to the same event multiple times would cause the
* previous registrations to be overwritten.
*
* @param[in] event_base the base id of the event to register the handler for
* @param[in] event_id the id of the event to register the handler for
* @param[in] event_handler the handler function which gets called when the event is dispatched
* @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
*
* @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
* ensure that event_handler_arg still points to a valid location by the time the handler gets called
*
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - Others: Fail
*/
esp_err_t esp_event_handler_register(esp_event_base_t event_base,
int32_t event_id,
esp_event_handler_t event_handler,
void* event_handler_arg);
/**
* @brief Register an event handler to a specific loop.
*
* This function behaves in the same manner as esp_event_handler_register, except the additional
* specification of the event loop to register the handler to.
*
* @param[in] event_loop the event loop to register this handler function to
* @param[in] event_base the base id of the event to register the handler for
* @param[in] event_id the id of the event to register the handler for
* @param[in] event_handler the handler function which gets called when the event is dispatched
* @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
*
* @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
* ensure that event_handler_arg still points to a valid location by the time the handler gets called
*
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - Others: Fail
*/
esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
esp_event_base_t event_base,
int32_t event_id,
esp_event_handler_t event_handler,
void* event_handler_arg);
/**
* @brief Unregister a handler with the system event loop.
*
* This function can be used to unregister a handler so that it no longer gets called during dispatch.
* Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base,
* or (3) all events known by the system event loop
*
* - specific events: specify exact event_base and event_id
* - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id
* - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id
*
* This function ignores unregistration of handlers that has not been previously registered.
*
* @param[in] event_base the base of the event with which to unregister the handler
* @param[in] event_id the id of the event with which to unregister the handler
* @param[in] event_handler the handler to unregister
*
* @return ESP_OK success
* @return ESP_ERR_INVALID_ARG invalid combination of event base and event id
* @return others fail
*/
esp_err_t esp_event_handler_unregister(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler);
/**
* @brief Unregister a handler with the system event loop.
*
* This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of
* the event loop to unregister the handler with.
*
* @param[in] event_loop the event loop with which to unregister this handler function
* @param[in] event_base the base of the event with which to unregister the handler
* @param[in] event_id the id of the event with which to unregister the handler
* @param[in] event_handler the handler to unregister
*
* @return
* - ESP_OK: Success
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - Others: Fail
*/
esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
esp_event_base_t event_base,
int32_t event_id,
esp_event_handler_t event_handler);
/**
* @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages
* the copy's lifetime automatically (allocation + deletion); this ensures that the data the
* handler recieves is always valid.
*
* @param[in] event_base the event base that identifies the event
* @param[in] event_id the event id that identifies the event
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
* @param[in] event_data_size the size of the event data
* @param[in] ticks_to_wait number of ticks to block on a full event queue
*
* @return
* - ESP_OK: Success
* - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
* queue full when posting from ISR
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - Others: Fail
*/
esp_err_t esp_event_post(esp_event_base_t event_base,
int32_t event_id,
void* event_data,
size_t event_data_size,
TickType_t ticks_to_wait);
/**
* @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages
* the copy's lifetime automatically (allocation + deletion); this ensures that the data the
* handler recieves is always valid.
*
* This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop
* to post the event to.
*
* @param[in] event_loop the event loop to post to
* @param[in] event_base the event base that identifies the event
* @param[in] event_id the event id that identifies the event
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
* @param[in] event_data_size the size of the event data
* @param[in] ticks_to_wait number of ticks to block on a full event queue
*
* @return
* - ESP_OK: Success
* - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
* queue full when posting from ISR
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - Others: Fail
*/
esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop,
esp_event_base_t event_base,
int32_t event_id,
void* event_data,
size_t event_data_size,
TickType_t ticks_to_wait);
#if CONFIG_ESP_EVENT_POST_FROM_ISR
/**
* @brief Special variant of esp_event_post for posting events from interrupt handlers.
*
* @param[in] event_base the event base that identifies the event
* @param[in] event_id the event id that identifies the event
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
* @param[in] event_data_size the size of the event data; max is 4 bytes
* @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
* higher priority than currently running task has been unblocked by the posted event;
* a context switch should be requested before the interrupt is existed.
*
* @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled
* @note when this function is called from an interrupt handler placed in IRAM, this function should
* be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR
*
* @return
* - ESP_OK: Success
* - ESP_FAIL: Event queue for the default event loop full
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id,
* data size of more than 4 bytes
* - Others: Fail
*/
esp_err_t esp_event_isr_post(esp_event_base_t event_base,
int32_t event_id,
void* event_data,
size_t event_data_size,
BaseType_t* task_unblocked);
/**
* @brief Special variant of esp_event_post_to for posting events from interrupt handlers
*
* @param[in] event_base the event base that identifies the event
* @param[in] event_id the event id that identifies the event
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
* @param[in] event_data_size the size of the event data
* @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
* higher priority than currently running task has been unblocked by the posted event;
* a context switch should be requested before the interrupt is existed.
*
* @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled
* @note when this function is called from an interrupt handler placed in IRAM, this function should
* be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR
*
* @return
* - ESP_OK: Success
* - ESP_FAIL: Event queue for the loop full
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id,
* data size of more than 4 bytes
* - Others: Fail
*/
esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop,
esp_event_base_t event_base,
int32_t event_id,
void* event_data,
size_t event_data_size,
BaseType_t* task_unblocked);
#endif
/**
* @brief Dumps statistics of all event loops.
*
* Dumps event loop info in the format:
*
@verbatim
event loop
handler
handler
...
event loop
handler
handler
...
where:
event loop
format: address,name rx:total_recieved dr:total_dropped
where:
address - memory address of the event loop
name - name of the event loop, 'none' if no dedicated task
total_recieved - number of successfully posted events
total_dropped - number of events unsucessfully posted due to queue being full
handler
format: address ev:base,id inv:total_invoked run:total_runtime
where:
address - address of the handler function
base,id - the event specified by event base and id this handler executes
total_invoked - number of times this handler has been invoked
total_runtime - total amount of time used for invoking this handler
@endverbatim
*
* @param[in] file the file stream to output to
*
* @note this function is a noop when CONFIG_ESP_EVENT_LOOP_PROFILING is disabled
*
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list
* - Others: Fail
*/
esp_err_t esp_event_dump(FILE* file);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef ESP_EVENT_H_

View File

@ -0,0 +1,43 @@
// 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.
#ifndef ESP_EVENT_BASE_H_
#define ESP_EVENT_BASE_H_
#ifdef __cplusplus
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
// Event loop library types
typedef const char* esp_event_base_t; /**< unique pointer to a subsystem that exposes events */
typedef void* esp_event_loop_handle_t; /**< a number that identifies an event with respect to a base */
typedef void (*esp_event_handler_t)(void* event_handler_arg,
esp_event_base_t event_base,
int32_t event_id,
void* event_data); /**< function called when an event is posted to the queue */
// Defines for registering/unregistering event handlers
#define ESP_EVENT_ANY_BASE NULL /**< register handler for any event base */
#define ESP_EVENT_ANY_ID -1 /**< register handler for any event id */
#ifdef __cplusplus
}
#endif
#endif // #ifndef ESP_EVENT_BASE_H_

View File

@ -0,0 +1,221 @@
// 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.
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "esp_wifi_types.h"
#include "tcpip_adapter.h"
#ifdef __cplusplus
extern "C" {
#endif
/** System event types enumeration */
typedef enum {
SYSTEM_EVENT_WIFI_READY = 0, /*!< WiFi ready */
SYSTEM_EVENT_SCAN_DONE, /*!< finish scanning AP */
SYSTEM_EVENT_STA_START, /*!< station start */
SYSTEM_EVENT_STA_STOP, /*!< station stop */
SYSTEM_EVENT_STA_CONNECTED, /*!< station connected to AP */
SYSTEM_EVENT_STA_DISCONNECTED, /*!< station disconnected from AP */
SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /*!< the auth mode of AP connected by station changed */
SYSTEM_EVENT_STA_GOT_IP, /*!< station got IP from connected AP */
SYSTEM_EVENT_STA_LOST_IP, /*!< station lost IP and the IP is reset to 0 */
SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /*!< station wps succeeds in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_FAILED, /*!< station wps fails in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /*!< station wps timeout in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_PIN, /*!< station wps pin code in enrollee mode */
SYSTEM_EVENT_AP_START, /*!< soft-AP start */
SYSTEM_EVENT_AP_STOP, /*!< soft-AP stop */
SYSTEM_EVENT_AP_STACONNECTED, /*!< a station connected to soft-AP */
SYSTEM_EVENT_AP_STADISCONNECTED, /*!< a station disconnected from soft-AP */
SYSTEM_EVENT_AP_STAIPASSIGNED, /*!< soft-AP assign an IP to a connected station */
SYSTEM_EVENT_AP_PROBEREQRECVED, /*!< Receive probe request packet in soft-AP interface */
SYSTEM_EVENT_ETH_START, /*!< ethernet start */
SYSTEM_EVENT_ETH_STOP, /*!< ethernet stop */
SYSTEM_EVENT_ETH_CONNECTED, /*!< ethernet phy link up */
SYSTEM_EVENT_ETH_DISCONNECTED, /*!< ethernet phy link down */
SYSTEM_EVENT_ETH_GOT_IP, /*!< ethernet got IP from connected AP */
SYSTEM_EVENT_GOT_IP6, /*!< station or ap or ethernet interface v6IP addr is preferred */
SYSTEM_EVENT_MAX /*!< Number of members in this enum */
} system_event_id_t;
/* add this macro define for compatible with old IDF version */
#ifndef SYSTEM_EVENT_AP_STA_GOT_IP6
#define SYSTEM_EVENT_AP_STA_GOT_IP6 SYSTEM_EVENT_GOT_IP6
#endif
/** 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;
/** Argument structure of SYSTEM_EVENT_SCAN_DONE event */
typedef wifi_event_sta_scan_done_t system_event_sta_scan_done_t;
/** Argument structure of SYSTEM_EVENT_STA_CONNECTED event */
typedef wifi_event_sta_connected_t system_event_sta_connected_t;
/** Argument structure of SYSTEM_EVENT_STA_DISCONNECTED event */
typedef wifi_event_sta_disconnected_t system_event_sta_disconnected_t;
/** Argument structure of SYSTEM_EVENT_STA_AUTHMODE_CHANGE event */
typedef wifi_event_sta_authmode_change_t system_event_sta_authmode_change_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;
/** Argument structure of event */
typedef wifi_event_ap_staconnected_t system_event_ap_staconnected_t;
/** Argument structure of event */
typedef wifi_event_ap_stadisconnected_t system_event_ap_stadisconnected_t;
/** Argument structure of event */
typedef wifi_event_ap_probe_req_rx_t system_event_ap_probe_req_rx_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; /*!< station connected to AP */
system_event_sta_disconnected_t disconnected; /*!< station disconnected to AP */
system_event_sta_scan_done_t scan_done; /*!< station scan (APs) done */
system_event_sta_authmode_change_t auth_change; /*!< the auth mode of AP station connected to changed */
system_event_sta_got_ip_t got_ip; /*!< station got IP, first time got IP or when IP is changed */
system_event_sta_wps_er_pin_t sta_er_pin; /*!< station WPS enrollee mode PIN code received */
system_event_sta_wps_fail_reason_t sta_er_fail_reason; /*!< station WPS enrollee mode failed reason code received */
system_event_ap_staconnected_t sta_connected; /*!< a station connected to soft-AP */
system_event_ap_stadisconnected_t sta_disconnected; /*!< a station disconnected to soft-AP */
system_event_ap_probe_req_rx_t ap_probereqrecved; /*!< soft-AP receive probe request packet */
system_event_ap_staipassigned_t ap_staipassigned; /**< soft-AP assign an IP to the station*/
system_event_got_ip6_t got_ip6; /*!< 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_t;
/** Event handler function type */
typedef esp_err_t (*system_event_handler_t)(system_event_t *event);
/**
* @brief Send a event to event task
*
* @note This API is part of the legacy event system. New code should use event library API in esp_event.h
*
* Other task/modules, such as the tcpip_adapter, can call this API to send an event to event task
*
* @param event Event to send
*
* @return ESP_OK : succeed
* @return others : fail
*/
esp_err_t esp_event_send(system_event_t *event);
/**
* @brief Default event handler for system events
*
* @note This API is part of the legacy event system. New code should use event library API in esp_event.h
*
* This function performs default handling of system events.
* When using esp_event_loop APIs, it is called automatically before invoking the user-provided
* callback function.
*
* 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

View File

@ -0,0 +1 @@
#include "esp_event_legacy.h"

View File

@ -0,0 +1,112 @@
// 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.
#ifndef ESP_EVENT_INTERNAL_H_
#define ESP_EVENT_INTERNAL_H_
#include "esp_event.h"
#include "stdatomic.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef SLIST_HEAD(base_nodes, base_node) base_nodes_t;
/// Event handler
typedef struct esp_event_handler_instance {
esp_event_handler_t handler; /**< event handler function*/
void* arg; /**< event handler argument */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
uint32_t invoked; /**< number of times this handler has been invoked */
int64_t time; /**< total runtime of this handler across all calls */
#endif
SLIST_ENTRY(esp_event_handler_instance) next; /**< next event handler in the list */
} esp_event_handler_instance_t;
typedef SLIST_HEAD(esp_event_handler_instances, esp_event_handler_instance) esp_event_handler_instances_t;
/// Event
typedef struct esp_event_id_node {
int32_t id; /**< id number of the event */
esp_event_handler_instances_t handlers; /**< list of handlers to be executed when
this event is raised */
SLIST_ENTRY(esp_event_id_node) next; /**< pointer to the next event node on the linked list */
} esp_event_id_node_t;
typedef SLIST_HEAD(esp_event_id_nodes, esp_event_id_node) esp_event_id_nodes_t;
typedef struct esp_event_base_node {
esp_event_base_t base; /**< base identifier of the event */
esp_event_handler_instances_t handlers; /**< event base level handlers, handlers for
all events with this base */
esp_event_id_nodes_t id_nodes; /**< list of event ids with this base */
SLIST_ENTRY(esp_event_base_node) next; /**< pointer to the next base node on the linked list */
} esp_event_base_node_t;
typedef SLIST_HEAD(esp_event_base_nodes, esp_event_base_node) esp_event_base_nodes_t;
typedef struct esp_event_loop_node {
esp_event_handler_instances_t handlers; /** event loop level handlers */
esp_event_base_nodes_t base_nodes; /** list of event bases registered to the loop */
SLIST_ENTRY(esp_event_loop_node) next; /** pointer to the next loop node containing
event loop level handlers and the rest of
event bases registered to the loop */
} esp_event_loop_node_t;
typedef SLIST_HEAD(esp_event_loop_nodes, esp_event_loop_node) esp_event_loop_nodes_t;
/// Event loop
typedef struct esp_event_loop_instance {
const char* name; /**< name of this event loop */
QueueHandle_t queue; /**< event queue */
TaskHandle_t task; /**< task that consumes the event queue */
TaskHandle_t running_task; /**< for loops with no dedicated task, the
task that consumes the queue */
SemaphoreHandle_t mutex; /**< mutex for updating the events linked list */
esp_event_loop_nodes_t loop_nodes; /**< set of linked lists containing the
registered handlers for the loop */
#ifdef CONFIG_ESP_EVENT_LOOP_PROFILING
atomic_uint_least32_t events_recieved; /**< number of events successfully posted to the loop */
atomic_uint_least32_t events_dropped; /**< number of events dropped due to queue being full */
SemaphoreHandle_t profiling_mutex; /**< mutex used for profiliing */
SLIST_ENTRY(esp_event_loop_instance) next; /**< next event loop in the list */
#endif
} esp_event_loop_instance_t;
#if CONFIG_ESP_EVENT_POST_FROM_ISR
typedef union esp_event_post_data {
uint32_t val;
void *ptr;
} esp_event_post_data_t;
#else
typedef void* esp_event_post_data_t;
#endif
/// Event posted to the event queue
typedef struct esp_event_post_instance {
#if CONFIG_ESP_EVENT_POST_FROM_ISR
bool data_allocated; /**< indicates whether data is allocated from heap */
bool data_set; /**< indicates if data is null */
#endif
esp_event_base_t base; /**< the event base */
int32_t id; /**< the event id */
esp_event_post_data_t data; /**< data associated with the event */
} esp_event_post_instance_t;
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef ESP_EVENT_INTERNAL_H_

View File

@ -0,0 +1,54 @@
// 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.
#ifndef ESP_EVENT_PRIVATE_H_
#define ESP_EVENT_PRIVATE_H_
#include "esp_event.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Searches handlers registered with an event loop to see if it has been registered.
*
* @param[in] event_loop the loop to search
* @param[in] event_base the event base to search
* @param[in] event_id the event id to search
* @param[in] event_handler the event handler to look for
*
* @return true handler registered
* @return false handler not registered
*
* @return
* - true: Handler registered
* - false: Handler not registered
*/
bool esp_event_is_handler_registered(esp_event_loop_handle_t event_loop, esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler);
/**
* @brief Deinitializes the event loop library
*
* @return
* - ESP_OK: Success
* - Others: Fail
*/
esp_err_t esp_event_loop_deinit();
#ifdef __cplusplus
} // extern "C"
#endif
#endif // #ifndef ESP_EVENT_PRIVATE_H_

View File

@ -0,0 +1,3 @@
idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "../private_include" "."
REQUIRES unity test_utils esp_event driver)

View File

@ -0,0 +1,5 @@
#
#Component Makefile
#
COMPONENT_PRIV_INCLUDEDIRS := ../private_include .
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,184 @@
// 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_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_sta_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, "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_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_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_start(TCPIP_ADAPTER_IF_AP, ap_mac, &ap_ip);
}
static void handle_ap_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
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_start(TCPIP_ADAPTER_IF_STA, 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;
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);
}
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;
}
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);
return ESP_OK;
}

View File

@ -174,6 +174,35 @@ typedef enum{
TCPIP_ADAPTER_IP_REQUEST_RETRY_TIME = 52, /**< request IP address retry counter */
} tcpip_adapter_option_id_t;
/** @brief IP event base declaration */
ESP_EVENT_DECLARE_BASE(IP_EVENT);
/** IP event declarations */
typedef enum {
IP_EVENT_STA_GOT_IP, /*!< station got IP from connected AP */
IP_EVENT_STA_LOST_IP, /*!< station lost IP and the IP is reset to 0 */
IP_EVENT_AP_STAIPASSIGNED, /*!< soft-AP assign an IP to a connected station */
IP_EVENT_GOT_IP6, /*!< station or ap or ethernet interface v6IP addr is preferred */
} ip_event_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;
/** 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;
struct tcpip_adapter_api_msg_s;
typedef int (*tcpip_adapter_api_fn)(struct tcpip_adapter_api_msg_s *msg);
@ -615,6 +644,22 @@ 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 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

@ -79,6 +79,8 @@ static bool tcpip_inited = false;
static const char* TAG = "tcpip_adapter";
ESP_EVENT_DEFINE_BASE(IP_EVENT);
/* Avoid warning. No header file has include these function */
err_t ethernetif_init(struct netif* netif);
void system_station_got_ip_set();
@ -93,6 +95,7 @@ static void tcpip_adapter_dhcps_cb(u8_t client_ip[4])
client_ip[0],client_ip[1],client_ip[2],client_ip[3]);
system_event_t evt;
evt.event_id = SYSTEM_EVENT_AP_STAIPASSIGNED;
memcpy(&evt.event_info.ap_staipassigned.ip, client_ip, 4);
esp_event_send(&evt);
}
@ -584,6 +587,7 @@ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i
evt.event_info.got_ip.ip_changed = true;
}
evt.event_info.got_ip.if_index = TCPIP_ADAPTER_IF_STA;
memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t));
memcpy(&esp_ip_old[tcpip_if], ip_info, sizeof(tcpip_adapter_ip_info_t));
esp_event_send(&evt);

View File

@ -8,6 +8,7 @@
*/
#include <string.h>
#include "protocol_examples_common.h"
#include "sdkconfig.h"
#include "esp_event.h"
@ -32,7 +33,8 @@
static EventGroupHandle_t s_connect_event_group;
static ip4_addr_t s_ip_addr;
static const char *s_connection_name;
static char s_connection_name[32] = CONFIG_EXAMPLE_WIFI_SSID;
static char s_connection_passwd[32] = CONFIG_EXAMPLE_WIFI_PASSWORD;
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
static ip6_addr_t s_ipv6_addr;
@ -40,65 +42,70 @@ static ip6_addr_t s_ipv6_addr;
static const char *TAG = "example_connect";
static esp_err_t event_handler(void *ctx, system_event_t *event)
static void on_wifi_disconnect(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
system_event_sta_disconnected_t *event = (system_event_sta_disconnected_t *)event_data;
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
memcpy(&s_ip_addr, &event->event_info.got_ip.ip_info.ip, sizeof(s_ip_addr));
xEventGroupSetBits(s_connect_event_group, GOT_IPV4_BIT);;
break;
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
case SYSTEM_EVENT_STA_CONNECTED:
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
break;
case SYSTEM_EVENT_AP_STA_GOT_IP6:
memcpy(&s_ipv6_addr, &event->event_info.got_ip6.ip6_info, sizeof(s_ipv6_addr));
xEventGroupSetBits(s_connect_event_group, GOT_IPV6_BIT);
break;
#endif
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect...");
if (event->reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(s_connect_event_group, GOT_IPV4_BIT);
ESP_ERROR_CHECK(esp_wifi_connect());
}
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
xEventGroupClearBits(s_connect_event_group, GOT_IPV6_BIT);
static void on_wifi_connect(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
}
#endif
break;
default:
break;
static void on_got_ip(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
memcpy(&s_ip_addr, &event->ip_info.ip, sizeof(s_ip_addr));
xEventGroupSetBits(s_connect_event_group, GOT_IPV4_BIT);
}
return ESP_OK;
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
static void on_got_ipv6(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr));
xEventGroupSetBits(s_connect_event_group, GOT_IPV6_BIT);
}
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
static void start(void)
{
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL));
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
#endif
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_EXAMPLE_WIFI_SSID,
.password = CONFIG_EXAMPLE_WIFI_PASSWORD,
},
};
wifi_config_t wifi_config = { 0 };
strncpy((char *)&wifi_config.sta.ssid, s_connection_name, 32);
strncpy((char *)&wifi_config.sta.password, s_connection_passwd, 32);
ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
s_connection_name = CONFIG_EXAMPLE_WIFI_SSID;
ESP_ERROR_CHECK(esp_wifi_connect());
}
static void stop(void)
@ -108,6 +115,14 @@ static void stop(void)
return;
}
ESP_ERROR_CHECK(err);
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect));
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip));
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6));
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect));
#endif
ESP_ERROR_CHECK(esp_wifi_deinit());
}
@ -137,6 +152,14 @@ esp_err_t example_disconnect(void)
s_connect_event_group = NULL;
stop();
ESP_LOGI(TAG, "Disconnected from %s", s_connection_name);
s_connection_name = NULL;
s_connection_name[0] = '\0';
return ESP_OK;
}
esp_err_t example_set_connection_info(const char *ssid, const char *passwd)
{
strncpy(s_connection_name, ssid, sizeof(s_connection_name));
strncpy(s_connection_passwd, passwd, sizeof(s_connection_passwd));
return ESP_OK;
}

View File

@ -48,6 +48,11 @@ esp_err_t example_disconnect(void);
*/
esp_err_t example_configure_stdin_stdout(void);
/**
* @brief Configure SSID and password
*/
esp_err_t example_set_connection_info(const char *ssid, const char *passwd);
#ifdef __cplusplus
}
#endif

View File

@ -2,5 +2,9 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(coap_client)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := coap_client
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -6,16 +6,4 @@ config TARGET_DOMAIN_URI
help
Target uri for the example to use.
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
endmenu

View File

@ -13,25 +13,16 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs_flash.h"
#include "coap.h"
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
#define COAP_DEFAULT_TIME_SEC 5
#define COAP_DEFAULT_TIME_USEC 0
@ -43,13 +34,6 @@
*/
#define COAP_DEFAULT_DEMO_URI CONFIG_TARGET_DOMAIN_URI
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const static int CONNECTED_BIT = BIT0;
const static char *TAG = "CoAP_client";
static void message_handler(struct coap_context_t *ctx, const coap_endpoint_t *local_interface, const coap_address_t *remote,
@ -81,13 +65,6 @@ static void coap_example_task(void *p)
uint8_t get_method = 1;
while (1) {
/* Wait for the callback to set the CONNECTED_BIT in the
event group.
*/
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
ESP_LOGI(TAG, "Connected to AP");
if (coap_split_uri((const uint8_t *)server_uri, strlen(server_uri), &uri) == -1) {
ESP_LOGE(TAG, "CoAP server uri error");
break;
@ -157,55 +134,14 @@ static void coap_example_task(void *p)
vTaskDelete(NULL);
}
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_conn_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
wifi_conn_init();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
xTaskCreate(coap_example_task, "coap", 2048, NULL, 5, NULL);
}

View File

@ -2,5 +2,9 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(coap_server)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := coap_server
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,15 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
endmenu

View File

@ -12,35 +12,19 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs_flash.h"
#include "coap.h"
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
#define COAP_DEFAULT_TIME_SEC 5
#define COAP_DEFAULT_TIME_USEC 0
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const static int CONNECTED_BIT = BIT0;
const static char *TAG = "CoAP_server";
static coap_async_state_t *async = NULL;
@ -90,13 +74,6 @@ static void coap_example_thread(void *p)
int flags = 0;
while (1) {
/* Wait for the callback to set the CONNECTED_BIT in the
event group.
*/
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
ESP_LOGI(TAG, "Connected to AP");
/* Prepare the CoAP server socket */
coap_address_init(&serv_addr);
serv_addr.addr.sin.sin_family = AF_INET;
@ -143,56 +120,14 @@ static void coap_example_thread(void *p)
vTaskDelete(NULL);
}
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_conn_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
wifi_conn_init();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
xTaskCreate(coap_example_thread, "coap", 2048, NULL, 5, NULL);
}

View File

@ -2,5 +2,9 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp-http-client-example)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := esp-http-client-example
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,7 +1,4 @@
set(COMPONENT_SRCS "app_wifi.c"
"esp_http_client_example.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
set(COMPONENT_SRCS "esp_http_client_example.c")
# Embed the server root certificate into the final binary
#

View File

@ -1,17 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
endmenu

View File

@ -1,81 +0,0 @@
/* ESP HTTP Client Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "esp_system.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "app_wifi.h"
static const char *TAG = "WIFI";
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int CONNECTED_BIT = BIT0;
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
void app_wifi_initialise(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_WIFI_SSID,
.password = CONFIG_WIFI_PASSWORD,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
void app_wifi_wait_connected()
{
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
}

View File

@ -1,17 +0,0 @@
/* ESP HTTP Client Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef _APP_WIFI_H_
#define _APP_WIFI_H_
void app_wifi_initialise(void);
void app_wifi_wait_connected();
#endif

View File

@ -9,12 +9,16 @@
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "app_wifi.h"
#include "esp_http_client.h"
@ -375,7 +379,6 @@ static void https_async()
static void http_test_task(void *pvParameters)
{
app_wifi_wait_connected();
ESP_LOGI(TAG, "Connected to AP, begin http example");
http_rest();
http_auth_basic();
@ -394,13 +397,12 @@ static void http_test_task(void *pvParameters)
void app_main()
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
app_wifi_initialise();
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL);
}

View File

@ -2,5 +2,9 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(http_request)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := http-request
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,17 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
endmenu

View File

@ -11,34 +11,17 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include <netdb.h>
#include <sys/socket.h>
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int CONNECTED_BIT = BIT0;
/* Constants that aren't configurable in menuconfig */
#define WEB_SERVER "example.com"
#define WEB_PORT 80
@ -51,53 +34,6 @@ static const char *REQUEST = "GET " WEB_URL " HTTP/1.0\r\n"
"User-Agent: esp-idf/1.0 esp32\r\n"
"\r\n";
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void http_get_task(void *pvParameters)
{
const struct addrinfo hints = {
@ -110,13 +46,6 @@ static void http_get_task(void *pvParameters)
char recv_buf[64];
while(1) {
/* Wait for the callback to set the CONNECTED_BIT in the
event group.
*/
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
ESP_LOGI(TAG, "Connected to AP");
int err = getaddrinfo(WEB_SERVER, "80", &hints, &res);
if(err != 0 || res == NULL) {
@ -193,6 +122,11 @@ static void http_get_task(void *pvParameters)
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
xTaskCreate(&http_get_task, "http_get_task", 16384, NULL, 5, NULL);
}

View File

@ -2,6 +2,10 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(tests)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := tests
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,16 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
endmenu

View File

@ -1,88 +1,51 @@
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "tests.h"
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
static const char *TAG = "example";
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
static httpd_handle_t server = NULL;
static const char *TAG="TEST_WIFI";
static esp_err_t event_handler(void *ctx, system_event_t *event)
static void disconnect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t *hd = (httpd_handle_t *) ctx;
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
ESP_ERROR_CHECK(esp_wifi_connect());
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "Got IP: '%s'",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
// Start webserver tests
if (*hd == NULL) {
*hd = start_tests();
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
ESP_LOGI(TAG, "Stopping webserver");
stop_tests(*server);
*server = NULL;
}
}
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
ESP_ERROR_CHECK(esp_wifi_connect());
// Stop webserver tests
if (*hd) {
stop_tests(*hd);
*hd = NULL;
}
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
static void connect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
tcpip_adapter_init();
static httpd_handle_t hd = NULL;
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, &hd));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
ESP_LOGI(TAG, "Starting webserver");
*server = start_tests();
}
}
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
server = start_tests();
}

View File

@ -2,6 +2,10 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(persistent_sockets)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := persistent_sockets
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,16 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
endmenu

View File

@ -7,23 +7,18 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include <esp_http_server.h>
/* An example to demonstrate persistent sockets, with context maintained across
* multiple requests on that socket.
* The examples use simple WiFi configuration that you can set via 'make menuconfig'.
* If you'd rather not, just change the below entries to strings with
* the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
static const char *TAG="APP";
/* Function to free context */
@ -190,70 +185,39 @@ void stop_webserver(httpd_handle_t server)
httpd_stop(server);
}
static esp_err_t event_handler(void *ctx, system_event_t *event)
static httpd_handle_t server = NULL;
static void disconnect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t *server = (httpd_handle_t *) ctx;
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
ESP_ERROR_CHECK(esp_wifi_connect());
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "Got IP: '%s'",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
/* Start the web server */
if (*server == NULL) {
*server = start_webserver();
}
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
ESP_ERROR_CHECK(esp_wifi_connect());
/* Stop the webserver */
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
ESP_LOGI(TAG, "Stopping webserver");
stop_webserver(*server);
*server = NULL;
}
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void *arg)
static void connect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, arg));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
ESP_LOGI(TAG, "Starting webserver");
*server = start_webserver();
}
}
void app_main()
{
static httpd_handle_t server = NULL;
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi(&server);
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
server = start_webserver();
}

View File

@ -2,5 +2,9 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(simple)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := simple
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,16 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
endmenu

View File

@ -6,26 +6,19 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include <esp_http_server.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
/* A simple example that demonstrates how to create GET and POST
* handlers for the web server.
* The examples use simple WiFi configuration that you can set via
* 'make menuconfig'.
* If you'd rather not, just change the below entries to strings
* with the config you want -
* ie. #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
#include <esp_http_server.h>
static const char *TAG="APP";
@ -217,70 +210,40 @@ void stop_webserver(httpd_handle_t server)
httpd_stop(server);
}
static esp_err_t event_handler(void *ctx, system_event_t *event)
static httpd_handle_t server = NULL;
static void disconnect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t *server = (httpd_handle_t *) ctx;
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
ESP_ERROR_CHECK(esp_wifi_connect());
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "Got IP: '%s'",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
/* Start the web server */
if (*server == NULL) {
*server = start_webserver();
}
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
ESP_ERROR_CHECK(esp_wifi_connect());
/* Stop the web server */
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
ESP_LOGI(TAG, "Stopping webserver");
stop_webserver(*server);
*server = NULL;
}
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void *arg)
static void connect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, arg));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
ESP_LOGI(TAG, "Starting webserver");
*server = start_webserver();
}
}
void app_main()
{
static httpd_handle_t server = NULL;
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi(&server);
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
server = start_webserver();
}

View File

@ -2,5 +2,9 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(https_mbedtls)

View File

@ -5,4 +5,6 @@
PROJECT_NAME := https-mbedtls
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,17 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
endmenu

View File

@ -26,12 +26,12 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include <netdb.h>
@ -46,23 +46,6 @@
#include "mbedtls/error.h"
#include "mbedtls/certs.h"
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int CONNECTED_BIT = BIT0;
/* Constants that aren't configurable in menuconfig */
#define WEB_SERVER "www.howsmyssl.com"
#define WEB_PORT "443"
@ -88,53 +71,6 @@ static const char *REQUEST = "GET " WEB_URL " HTTP/1.0\r\n"
extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start");
extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end");
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void https_get_task(void *pvParameters)
{
char buf[512];
@ -212,13 +148,6 @@ static void https_get_task(void *pvParameters)
}
while(1) {
/* Wait for the callback to set the CONNECTED_BIT in the
event group.
*/
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
ESP_LOGI(TAG, "Connected to AP");
mbedtls_net_init(&server_fd);
ESP_LOGI(TAG, "Connecting to %s:%s...", WEB_SERVER, WEB_PORT);
@ -341,6 +270,11 @@ static void https_get_task(void *pvParameters)
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL);
}

View File

@ -2,5 +2,9 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(https_request)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := https_request
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,17 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
endmenu

View File

@ -23,13 +23,15 @@
*/
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "lwip/err.h"
@ -40,23 +42,6 @@
#include "esp_tls.h"
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int CONNECTED_BIT = BIT0;
/* Constants that aren't configurable in menuconfig */
#define WEB_SERVER "www.howsmyssl.com"
#define WEB_PORT 443
@ -82,65 +67,12 @@ static const char *REQUEST = "GET " WEB_URL " HTTP/1.0\r\n"
extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start");
extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end");
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void https_get_task(void *pvParameters)
{
char buf[512];
int ret, len;
while(1) {
/* Wait for the callback to set the CONNECTED_BIT in the
event group.
*/
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
ESP_LOGI(TAG, "Connected to AP");
esp_tls_cfg_t cfg = {
.cacert_pem_buf = server_root_cert_pem_start,
.cacert_pem_bytes = server_root_cert_pem_end - server_root_cert_pem_start,
@ -219,6 +151,10 @@ static void https_get_task(void *pvParameters)
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL);
}

View File

@ -2,5 +2,9 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mdns-test)

View File

@ -5,5 +5,7 @@
PROJECT_NAME := mdns-test
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,19 +1,5 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Can be left blank if the network has no security set.
config MDNS_HOSTNAME
string "mDNS Hostname"
default "esp32-mdns"

View File

@ -7,101 +7,26 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "mdns.h"
#include "driver/gpio.h"
#include <sys/socket.h>
#include <netdb.h>
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
#include "mdns.h"
#define EXAMPLE_MDNS_HOSTNAME CONFIG_MDNS_HOSTNAME
#define EXAMPLE_MDNS_INSTANCE CONFIG_MDNS_INSTANCE
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int IP4_CONNECTED_BIT = BIT0;
const int IP6_CONNECTED_BIT = BIT1;
static const char *TAG = "mdns-test";
static bool auto_reconnect = true;
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_CONNECTED:
/* enable ipv6 */
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, IP4_CONNECTED_BIT);
break;
case SYSTEM_EVENT_AP_STA_GOT_IP6:
xEventGroupSetBits(wifi_event_group, IP6_CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
if (auto_reconnect) {
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
}
xEventGroupClearBits(wifi_event_group, IP4_CONNECTED_BIT | IP6_CONNECTED_BIT);
break;
default:
break;
}
mdns_handle_system_event(ctx, event);
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void initialise_mdns(void)
{
@ -233,9 +158,6 @@ static void check_button(void)
static void mdns_example_task(void *pvParameters)
{
/* Wait for the callback to set the CONNECTED_BIT in the event group. */
xEventGroupWaitBits(wifi_event_group, IP4_CONNECTED_BIT | IP6_CONNECTED_BIT,
false, true, portMAX_DELAY);
while(1) {
check_button();
vTaskDelay(50 / portTICK_PERIOD_MS);
@ -245,8 +167,13 @@ static void mdns_example_task(void *pvParameters)
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
initialise_mdns();
initialise_wifi();
initialise_button();
xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL);
}

View File

@ -2,6 +2,10 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mqtt_ssl)

View File

@ -4,4 +4,6 @@
#
PROJECT_NAME := mqtt_ssl
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,17 +1,5 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
config BROKER_URI
string "Broker URL"
default "mqtts://iot.eclipse.org:8883"

View File

@ -2,81 +2,25 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event_loop.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "mqtt_client.h"
static const char *TAG = "MQTTS_EXAMPLE";
static EventGroupHandle_t wifi_event_group;
const static int CONNECTED_BIT = BIT0;
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_WIFI_SSID,
.password = CONFIG_WIFI_PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID);
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "Waiting for wifi");
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
}
#if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1
static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
#else
@ -144,6 +88,12 @@ static void mqtt_app_start(void)
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
ESP_LOGI(TAG, "[APP] Startup..");
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
@ -155,8 +105,5 @@ void app_main()
esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);
nvs_flash_init();
wifi_init();
mqtt_app_start();
}

View File

@ -1,2 +1,3 @@
CONFIG_BROKER_URI="mqtts://${EXAMPLE_MQTT_BROKER_SSL}"
CONFIG_BROKER_CERTIFICATE_OVERRIDE="${EXAMPLE_MQTT_BROKER_CERTIFICATE}"
CONFIG_MQTT_USING_ESP=y

View File

@ -0,0 +1 @@
CONFIG_MQTT_USING_ESP=y

View File

@ -2,6 +2,10 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mqtt_ssl_mutual_auth)

View File

@ -4,4 +4,6 @@
#
PROJECT_NAME := mqtt_ssl_mutual_auth
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,15 +0,0 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
endmenu

View File

@ -2,81 +2,25 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event_loop.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "mqtt_client.h"
static const char *TAG = "MQTTS_EXAMPLE";
static EventGroupHandle_t wifi_event_group;
const static int CONNECTED_BIT = BIT0;
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_WIFI_SSID,
.password = CONFIG_WIFI_PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID);
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "Waiting for wifi");
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
}
extern const uint8_t client_cert_pem_start[] asm("_binary_client_crt_start");
extern const uint8_t client_cert_pem_end[] asm("_binary_client_crt_end");
extern const uint8_t client_key_pem_start[] asm("_binary_client_key_start");
@ -142,6 +86,12 @@ static void mqtt_app_start(void)
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
ESP_LOGI(TAG, "[APP] Startup..");
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
@ -153,8 +103,5 @@ void app_main()
esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);
nvs_flash_init();
wifi_init();
mqtt_app_start();
}

View File

@ -0,0 +1 @@
CONFIG_MQTT_USING_ESP=y

View File

@ -2,6 +2,10 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mqtt_tcp)

View File

@ -4,4 +4,6 @@
#
PROJECT_NAME := mqtt_tcp
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,17 +1,5 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
config BROKER_URL
string "Broker URL"
default "mqtt://iot.eclipse.org"

View File

@ -2,30 +2,25 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event_loop.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "mqtt_client.h"
static const char *TAG = "MQTT_EXAMPLE";
static EventGroupHandle_t wifi_event_group;
const static int CONNECTED_BIT = BIT0;
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
{
esp_mqtt_client_handle_t client = event->client;
@ -73,56 +68,6 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
return ESP_OK;
}
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_WIFI_SSID,
.password = CONFIG_WIFI_PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID);
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "Waiting for wifi");
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
}
static void mqtt_app_start(void)
{
esp_mqtt_client_config_t mqtt_cfg = {
@ -162,6 +107,12 @@ static void mqtt_app_start(void)
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
ESP_LOGI(TAG, "[APP] Startup..");
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
@ -173,7 +124,5 @@ void app_main()
esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);
nvs_flash_init();
wifi_init();
mqtt_app_start();
}

View File

@ -1,2 +1,3 @@
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_BROKER_URL="FROM_STDIN"
CONFIG_MQTT_USING_ESP=y

View File

@ -0,0 +1 @@
CONFIG_MQTT_USING_ESP=y

View File

@ -2,6 +2,10 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mqtt_websocket)

View File

@ -4,4 +4,6 @@
#
PROJECT_NAME := mqtt_websocket
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,17 +1,5 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
config BROKER_URI
string "Broker URL"
default "ws://iot.eclipse.org:80/ws"

View File

@ -2,30 +2,25 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event_loop.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "mqtt_client.h"
static const char *TAG = "MQTTWS_EXAMPLE";
static EventGroupHandle_t wifi_event_group;
const static int CONNECTED_BIT = BIT0;
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
{
esp_mqtt_client_handle_t client = event->client;
@ -70,56 +65,6 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
return ESP_OK;
}
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_WIFI_SSID,
.password = CONFIG_WIFI_PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID);
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "Waiting for wifi");
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
}
static void mqtt_app_start(void)
{
const esp_mqtt_client_config_t mqtt_cfg = {
@ -134,6 +79,13 @@ static void mqtt_app_start(void)
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
ESP_LOGI(TAG, "[APP] Startup..");
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
@ -146,7 +98,5 @@ void app_main()
esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);
nvs_flash_init();
wifi_init();
mqtt_app_start();
}

View File

@ -1 +1,2 @@
CONFIG_BROKER_URI="ws://${EXAMPLE_MQTT_BROKER_WS}/ws"
CONFIG_MQTT_USING_ESP=y

View File

@ -0,0 +1 @@
CONFIG_MQTT_USING_ESP=y

View File

@ -2,6 +2,10 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mqtt_websocket_secure)

View File

@ -4,4 +4,6 @@
#
PROJECT_NAME := mqtt_websocket_secure
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common
include $(IDF_PATH)/make/project.mk

View File

@ -1,17 +1,5 @@
menu "Example Configuration"
config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
config BROKER_URI
string "Broker URL"
default "wss://iot.eclipse.org:443/ws"

View File

@ -2,81 +2,25 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event_loop.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "mqtt_client.h"
static const char *TAG = "MQTTWSS_EXAMPLE";
static EventGroupHandle_t wifi_event_group;
const static int CONNECTED_BIT = BIT0;
static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void wifi_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.sta = {
.ssid = CONFIG_WIFI_SSID,
.password = CONFIG_WIFI_PASSWORD,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID);
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "Waiting for wifi");
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
}
#if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1
static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
#else
@ -143,6 +87,13 @@ static void mqtt_app_start(void)
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
ESP_LOGI(TAG, "[APP] Startup..");
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
@ -154,7 +105,5 @@ void app_main()
esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);
nvs_flash_init();
wifi_init();
mqtt_app_start();
}

Some files were not shown because too many files have changed in this diff Show More