examples/provisioning : use esp_event library to handle WiFi/IP events

pull/3310/head
Anurag Kar 2018-12-25 23:08:50 +05:30 zatwierdzone przez bot
rodzic 8b2128ce07
commit 3608f9bde4
16 zmienionych plików z 355 dodań i 350 usunięć

Wyświetl plik

@ -29,6 +29,12 @@ menu "Example Configuration"
prompt "Reset provisioned status of the device"
help
This erases the NVS to reset provisioned status of the device on every reboot.
Provisioned status is determined by the WiFi STA configuration, saved on the NVS.
Provisioned status is determined by the Wi-Fi STA configuration, saved on the NVS.
config AP_RECONN_ATTEMPTS
int "Maximum AP connection attempts"
default 5
help
Set the maximum connection attempts to perform when connecting to a Wi-Fi AP.
endmenu

Wyświetl plik

@ -12,7 +12,7 @@
#include <freertos/task.h>
#include <esp_system.h>
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <esp_event.h>
#include <esp_log.h>
#include <nvs_flash.h>
@ -21,55 +21,75 @@
#include "app_prov.h"
#define EXAMPLE_AP_RECONN_ATTEMPTS CONFIG_AP_RECONN_ATTEMPTS
static const char *TAG = "app";
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* Invoke Provisioning event handler first */
app_prov_event_handler(ctx, event);
static void start_ble_provisioning();
switch(event->event_id) {
case SYSTEM_EVENT_AP_START:
ESP_LOGI(TAG, "SoftAP started");
break;
case SYSTEM_EVENT_AP_STOP:
ESP_LOGI(TAG, "SoftAP stopped");
break;
case SYSTEM_EVENT_STA_START:
static void event_handler(void* arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
static int s_retry_num_ap_not_found = 0;
static int s_retry_num_ap_auth_fail = 0;
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data;
switch (disconnected->reason) {
case WIFI_REASON_AUTH_EXPIRE:
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
case WIFI_REASON_BEACON_TIMEOUT:
case WIFI_REASON_AUTH_FAIL:
case WIFI_REASON_ASSOC_FAIL:
case WIFI_REASON_HANDSHAKE_TIMEOUT:
ESP_LOGW(TAG, "connect to the AP fail : auth Error");
if (s_retry_num_ap_auth_fail < EXAMPLE_AP_RECONN_ATTEMPTS) {
s_retry_num_ap_auth_fail++;
esp_wifi_connect();
ESP_LOGI(TAG, "retry connecting to the AP...");
} else {
/* Restart provisioning if authentication fails */
start_ble_provisioning();
}
break;
case WIFI_REASON_NO_AP_FOUND:
ESP_LOGW(TAG, "connect to the AP fail : not found");
if (s_retry_num_ap_not_found < EXAMPLE_AP_RECONN_ATTEMPTS) {
s_retry_num_ap_not_found++;
esp_wifi_connect();
ESP_LOGI(TAG, "retry to connecting to the AP...");
}
break;
default:
/* None of the expected reasons */
esp_wifi_connect();
break;
}
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:%s",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
break;
case SYSTEM_EVENT_AP_STACONNECTED:
ESP_LOGI(TAG, "station:"MACSTR" join, AID=%d",
MAC2STR(event->event_info.sta_connected.mac),
event->event_info.sta_connected.aid);
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
ESP_LOGI(TAG, "station:"MACSTR"leave, AID=%d",
MAC2STR(event->event_info.sta_disconnected.mac),
event->event_info.sta_disconnected.aid);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
break;
default:
break;
ip4addr_ntoa(&event->ip_info.ip));
s_retry_num_ap_not_found = 0;
s_retry_num_ap_auth_fail = 0;
}
return ESP_OK;
}
static void wifi_init_sta()
{
/* Set our event handling */
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, NULL));
/* Start wifi in station mode with credentials set during provisioning */
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
}
void app_main()
static void start_ble_provisioning()
{
/* Security version */
int security = 0;
@ -89,11 +109,17 @@ void app_main()
pop = &app_pop;
#endif
ESP_ERROR_CHECK(app_prov_start_ble_provisioning(security, pop));
}
void app_main()
{
/* Initialize networking stack */
tcpip_adapter_init();
/* Set our event handling */
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
/* Create default event loop needed by the
* main app and the provisioning service */
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* Check if device is provisioned */
bool provisioned;
@ -105,7 +131,7 @@ void app_main()
if (provisioned == false) {
/* If not provisioned, start provisioning via BLE */
ESP_LOGI(TAG, "Starting BLE provisioning");
app_prov_start_ble_provisioning(security, pop);
start_ble_provisioning();
} else {
/* Else start as station with credentials set during provisioning */
ESP_LOGI(TAG, "Starting WiFi station");

Wyświetl plik

@ -14,6 +14,7 @@
#include <nvs_flash.h>
#include <nvs.h>
#include <esp_bt.h>
#include <esp_event.h>
#include <protocomm.h>
#include <protocomm_ble.h>
@ -26,6 +27,9 @@
static const char *TAG = "app_prov";
static const char *ssid_prefix = "PROV_";
/* Handler for catching WiFi events */
static void app_prov_event_handler(void* handler_arg, esp_event_base_t base, int id, void* data);
/* Handlers for wifi_config provisioning endpoint */
extern wifi_prov_config_handlers_t wifi_prov_handlers;
@ -131,6 +135,10 @@ static void app_prov_stop_service(void)
/* Delete protocomm instance */
protocomm_delete(g_prov->pc);
/* Remove event handler */
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler);
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler);
/* Release memory used by BT stack */
esp_bt_mem_release(ESP_BT_MODE_BTDM);
}
@ -160,33 +168,24 @@ static void _stop_prov_cb(void * arg)
xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL);
}
/* Event handler for starting/stopping provisioning.
* To be called from within the context of the main
* event handler.
*/
esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
/* Event handler for starting/stopping provisioning */
static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
/* If pointer to provisioning application data is NULL
* then provisioning is not running, therefore return without
* error */
* then provisioning is not running */
if (!g_prov) {
return ESP_OK;
return;
}
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
ESP_LOGI(TAG, "STA Start");
/* Once configuration is received through protocomm,
* device is started as station. Once station starts,
* wait for connection to establish with configured
* host SSID and password */
g_prov->wifi_state = WIFI_PROV_STA_CONNECTING;
break;
case SYSTEM_EVENT_STA_GOT_IP:
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ESP_LOGI(TAG, "STA Got IP");
/* Station got IP. That means configuration is successful.
* Schedule timer to stop provisioning app after 30 seconds. */
@ -194,16 +193,16 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
if (g_prov && g_prov->timer) {
esp_timer_start_once(g_prov->timer, 30000*1000U);
}
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
ESP_LOGE(TAG, "STA Disconnected");
/* Station couldn't connect to configured host SSID */
g_prov->wifi_state = WIFI_PROV_STA_DISCONNECTED;
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data;
ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason);
/* Set code corresponding to the reason for disconnection */
switch (info->disconnected.reason) {
switch (disconnected->reason) {
case WIFI_REASON_AUTH_EXPIRE:
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
case WIFI_REASON_BEACON_TIMEOUT:
@ -223,12 +222,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
g_prov->wifi_state = WIFI_PROV_STA_CONNECTING;
esp_wifi_connect();
}
break;
default:
break;
}
return ESP_OK;
}
esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state)
@ -358,6 +352,18 @@ esp_err_t app_prov_start_ble_provisioning(int security, const protocomm_security
return err;
}
err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register WiFi event handler");
return err;
}
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register IP event handler");
return err;
}
/* Start provisioning service through BLE */
err = app_prov_start_service();
if (err != ESP_OK) {

Wyświetl plik

@ -42,21 +42,6 @@ esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state);
*/
esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason);
/**
* @brief Event handler for provisioning app
*
* This is called from the main event handler and controls the
* provisioning application, depeding on WiFi events
*
* @param[in] ctx Event context data
* @param[in] event Event info
*
* @return
* - ESP_OK : Event handled successfully
* - ESP_FAIL : Failed to start server on event AP start
*/
esp_err_t app_prov_event_handler(void *ctx, system_event_t *event);
/**
* @brief Checks if device is provisioned
* *

Wyświetl plik

@ -29,6 +29,12 @@ menu "Example Configuration"
prompt "Reset provisioned status of the device"
help
This erases the NVS to reset provisioned status of the device on every reboot.
Provisioned status is determined by the WiFi STA configuration, saved on the NVS.
Provisioned status is determined by the Wi-Fi STA configuration, saved on the NVS.
config AP_RECONN_ATTEMPTS
int "Maximum AP connection attempts"
default 5
help
Set the maximum connection attempts to perform when connecting to a Wi-Fi AP.
endmenu

Wyświetl plik

@ -12,7 +12,7 @@
#include <freertos/task.h>
#include <esp_system.h>
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <esp_event.h>
#include <esp_log.h>
#include <nvs_flash.h>
@ -21,55 +21,46 @@
#include "app_prov.h"
#define EXAMPLE_AP_RECONN_ATTEMPTS CONFIG_AP_RECONN_ATTEMPTS
static const char *TAG = "app";
static esp_err_t event_handler(void *ctx, system_event_t *event)
static void event_handler(void* arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
/* Invoke Provisioning event handler first */
app_prov_event_handler(ctx, event);
static int s_retry_num = 0;
switch(event->event_id) {
case SYSTEM_EVENT_AP_START:
ESP_LOGI(TAG, "SoftAP started");
break;
case SYSTEM_EVENT_AP_STOP:
ESP_LOGI(TAG, "SoftAP stopped");
break;
case SYSTEM_EVENT_STA_START:
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < EXAMPLE_AP_RECONN_ATTEMPTS) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
ESP_LOGI(TAG,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:%s",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
break;
case SYSTEM_EVENT_AP_STACONNECTED:
ESP_LOGI(TAG, "station:"MACSTR" join, AID=%d",
MAC2STR(event->event_info.sta_connected.mac),
event->event_info.sta_connected.aid);
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
ESP_LOGI(TAG, "station:"MACSTR"leave, AID=%d",
MAC2STR(event->event_info.sta_disconnected.mac),
event->event_info.sta_disconnected.aid);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
break;
default:
break;
ip4addr_ntoa(&event->ip_info.ip));
s_retry_num = 0;
}
return ESP_OK;
}
static void wifi_init_sta()
{
/* Set our event handling */
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, NULL));
/* Start wifi in station mode with credentials set during provisioning */
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
}
void app_main()
static void start_console_provisioning()
{
/* Security version */
int security = 0;
@ -89,11 +80,17 @@ void app_main()
pop = &app_pop;
#endif
ESP_ERROR_CHECK(app_prov_start_console_provisioning(security, pop));
}
void app_main()
{
/* Initialize networking stack */
tcpip_adapter_init();
/* Set our event handling */
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
/* Create default event loop needed by the
* main app and the provisioning service */
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* Check if device is provisioned */
bool provisioned;
@ -105,7 +102,7 @@ void app_main()
if (provisioned == false) {
/* If not provisioned, start provisioning via console */
ESP_LOGI(TAG, "Starting console provisioning");
app_prov_start_console_provisioning(security, pop);
start_console_provisioning();
} else {
/* Else start as station with credentials set during provisioning */
ESP_LOGI(TAG, "Starting WiFi station");

Wyświetl plik

@ -13,6 +13,7 @@
#include <esp_wifi.h>
#include <nvs_flash.h>
#include <nvs.h>
#include <esp_event.h>
#include <protocomm.h>
#include <protocomm_console.h>
@ -24,6 +25,9 @@
static const char *TAG = "app_prov";
/* Handler for catching WiFi events */
static void app_prov_event_handler(void* handler_arg, esp_event_base_t base, int id, void* data);
/* Handlers for wifi_config provisioning endpoint */
extern wifi_prov_config_handlers_t wifi_prov_handlers;
@ -99,6 +103,10 @@ static void app_prov_stop_service(void)
protocomm_console_stop(g_prov->pc);
/* Delete protocomm instance */
protocomm_delete(g_prov->pc);
/* Remove event handler */
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler);
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler);
}
/* Task spawned by timer callback */
@ -126,33 +134,24 @@ static void _stop_prov_cb(void * arg)
xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL);
}
/* Event handler for starting/stopping provisioning.
* To be called from within the context of the main
* event handler.
*/
esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
/* Event handler for starting/stopping provisioning */
static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
/* If pointer to provisioning application data is NULL
* then provisioning is not running, therefore return without
* error */
* then provisioning is not running */
if (!g_prov) {
return ESP_OK;
return;
}
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
ESP_LOGI(TAG, "STA Start");
/* Once configuration is received through protocomm,
* device is started as station. Once station starts,
* wait for connection to establish with configured
* host SSID and password */
g_prov->wifi_state = WIFI_PROV_STA_CONNECTING;
break;
case SYSTEM_EVENT_STA_GOT_IP:
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ESP_LOGI(TAG, "STA Got IP");
/* Station got IP. That means configuration is successful.
* Schedule timer to stop provisioning app after 30 seconds. */
@ -160,16 +159,16 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
if (g_prov && g_prov->timer) {
esp_timer_start_once(g_prov->timer, 30000*1000U);
}
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
ESP_LOGE(TAG, "STA Disconnected");
/* Station couldn't connect to configured host SSID */
g_prov->wifi_state = WIFI_PROV_STA_DISCONNECTED;
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data;
ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason);
/* Set code corresponding to the reason for disconnection */
switch (info->disconnected.reason) {
switch (disconnected->reason) {
case WIFI_REASON_AUTH_EXPIRE:
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
case WIFI_REASON_BEACON_TIMEOUT:
@ -189,12 +188,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
g_prov->wifi_state = WIFI_PROV_STA_CONNECTING;
esp_wifi_connect();
}
break;
default:
break;
}
return ESP_OK;
}
esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state)
@ -324,6 +318,18 @@ esp_err_t app_prov_start_console_provisioning(int security, const protocomm_secu
return err;
}
err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register WiFi event handler");
return err;
}
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register IP event handler");
return err;
}
/* Start provisioning service through console */
err = app_prov_start_service();
if (err != ESP_OK) {

Wyświetl plik

@ -42,21 +42,6 @@ esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state);
*/
esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason);
/**
* @brief Event handler for provisioning app
*
* This is called from the main event handler and controls the
* provisioning application, depeding on WiFi events
*
* @param[in] ctx Event context data
* @param[in] event Event info
*
* @return
* - ESP_OK : Event handled successfully
* - ESP_FAIL : Failed to start server on event AP start
*/
esp_err_t app_prov_event_handler(void *ctx, system_event_t *event);
/**
* @brief Checks if device is provisioned
* *

Wyświetl plik

@ -1,16 +1,16 @@
menu "Example Configuration"
config SOFTAP_SSID
string "WiFi SSID"
string "Wi-Fi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config SOFTAP_PASS
string "WiFi Password"
string "Wi-Fi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
Wi-Fi password (WPA or WPA2) for the example to use.
config USE_SEC_1
bool
@ -47,6 +47,12 @@ menu "Example Configuration"
prompt "Reset provisioned status of the device"
help
This erases the NVS to reset provisioned status of the device on every reboot.
Provisioned status is determined by the WiFi STA configuration, saved on the NVS.
Provisioned status is determined by the Wi-Fi STA configuration, saved on the NVS.
config AP_RECONN_ATTEMPTS
int "Maximum AP connection attempts"
default 5
help
Set the maximum connection attempts to perform when connecting to a Wi-Fi AP.
endmenu

Wyświetl plik

@ -12,7 +12,7 @@
#include <freertos/task.h>
#include <esp_system.h>
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <esp_event.h>
#include <esp_log.h>
#include <nvs_flash.h>
@ -21,55 +21,46 @@
#include "app_prov.h"
#define EXAMPLE_AP_RECONN_ATTEMPTS CONFIG_AP_RECONN_ATTEMPTS
static const char *TAG = "app";
static esp_err_t event_handler(void *ctx, system_event_t *event)
static void event_handler(void* arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
/* Invoke Provisioning event handler first */
app_prov_event_handler(ctx, event);
static int s_retry_num = 0;
switch(event->event_id) {
case SYSTEM_EVENT_AP_START:
ESP_LOGI(TAG, "SoftAP started");
break;
case SYSTEM_EVENT_AP_STOP:
ESP_LOGI(TAG, "SoftAP stopped");
break;
case SYSTEM_EVENT_STA_START:
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < EXAMPLE_AP_RECONN_ATTEMPTS) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
ESP_LOGI(TAG,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:%s",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
break;
case SYSTEM_EVENT_AP_STACONNECTED:
ESP_LOGI(TAG, "station:"MACSTR" join, AID=%d",
MAC2STR(event->event_info.sta_connected.mac),
event->event_info.sta_connected.aid);
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
ESP_LOGI(TAG, "station:"MACSTR"leave, AID=%d",
MAC2STR(event->event_info.sta_disconnected.mac),
event->event_info.sta_disconnected.aid);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
break;
default:
break;
ip4addr_ntoa(&event->ip_info.ip));
s_retry_num = 0;
}
return ESP_OK;
}
static void wifi_init_sta()
{
/* Set our event handling */
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, NULL));
/* Start wifi in station mode with credentials set during provisioning */
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
}
void app_main()
static void start_softap_provisioning()
{
/* Security version */
int security = 0;
@ -89,11 +80,18 @@ void app_main()
pop = &app_pop;
#endif
ESP_ERROR_CHECK(app_prov_start_softap_provisioning(
CONFIG_SOFTAP_SSID, CONFIG_SOFTAP_PASS, security, pop));
}
void app_main()
{
/* Initialize networking stack */
tcpip_adapter_init();
/* Set our event handling */
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
/* Create default event loop needed by the
* main app and the provisioning service */
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* Check if device is provisioned */
bool provisioned;
@ -105,8 +103,7 @@ void app_main()
if (provisioned == false) {
/* If not provisioned, start provisioning via soft AP */
ESP_LOGI(TAG, "Starting WiFi SoftAP provisioning");
app_prov_start_softap_provisioning(CONFIG_SOFTAP_SSID, CONFIG_SOFTAP_PASS,
security, pop);
start_softap_provisioning();
} else {
/* Start WiFi station with credentials set during provisioning */
ESP_LOGI(TAG, "Starting WiFi station");

Wyświetl plik

@ -13,6 +13,7 @@
#include <esp_wifi.h>
#include <nvs_flash.h>
#include <nvs.h>
#include <esp_event.h>
#include <protocomm.h>
#include <protocomm_httpd.h>
@ -25,6 +26,9 @@
static const char *TAG = "app_prov";
/* Handler for catching WiFi events */
static void app_prov_event_handler(void* handler_arg, esp_event_base_t base, int id, void* data);
/* Handlers for provisioning endpoints */
extern wifi_prov_config_handlers_t wifi_prov_handlers;
extern custom_prov_config_handler_t custom_prov_handler;
@ -114,6 +118,10 @@ static void app_prov_stop_service(void)
protocomm_httpd_stop(g_prov->pc);
/* Delete protocomm instance */
protocomm_delete(g_prov->pc);
/* Remove event handler */
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler);
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler);
}
/* Task spawned by timer callback */
@ -142,33 +150,24 @@ static void _stop_prov_cb(void * arg)
xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL);
}
/* Event handler for starting/stopping provisioning.
* To be called from within the context of the main
* event handler.
*/
esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
/* Event handler for starting/stopping provisioning */
static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
/* If pointer to provisioning application data is NULL
* then provisioning is not running, therefore return without
* error */
* then provisioning is not running */
if (!g_prov) {
return ESP_OK;
return;
}
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
ESP_LOGI(TAG, "STA Start");
/* Once configuration is received by protocomm server,
* device is restarted as both AP and Station.
* Once station starts, wait for connection to
* establish with configured host SSID and password */
/* Once configuration is received through protocomm,
* device is started as station. Once station starts,
* wait for connection to establish with configured
* host SSID and password */
g_prov->wifi_state = WIFI_PROV_STA_CONNECTING;
break;
case SYSTEM_EVENT_STA_GOT_IP:
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ESP_LOGI(TAG, "STA Got IP");
/* Station got IP. That means configuration is successful.
* Schedule timer to stop provisioning app after 30 seconds. */
@ -185,16 +184,16 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
* signaling a failure in provisioning. */
esp_timer_start_once(g_prov->timer, 30000*1000U);
}
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
ESP_LOGE(TAG, "STA Disconnected");
/* Station couldn't connect to configured host SSID */
g_prov->wifi_state = WIFI_PROV_STA_DISCONNECTED;
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data;
ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason);
/* Set code corresponding to the reason for disconnection */
switch (info->disconnected.reason) {
switch (disconnected->reason) {
case WIFI_REASON_AUTH_EXPIRE:
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
case WIFI_REASON_BEACON_TIMEOUT:
@ -214,12 +213,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
g_prov->wifi_state = WIFI_PROV_STA_CONNECTING;
esp_wifi_connect();
}
break;
default:
break;
}
return ESP_OK;
}
esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state)
@ -248,6 +242,8 @@ esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reaso
esp_err_t app_prov_is_provisioned(bool *provisioned)
{
*provisioned = false;
#ifdef CONFIG_RESET_PROVISIONED
nvs_flash_erase();
#endif
@ -266,7 +262,6 @@ esp_err_t app_prov_is_provisioned(bool *provisioned)
/* Get WiFi Station configuration */
wifi_config_t wifi_cfg;
if (esp_wifi_get_config(ESP_IF_WIFI_STA, &wifi_cfg) != ESP_OK) {
*provisioned = false;
return ESP_FAIL;
}
@ -374,7 +369,7 @@ esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass,
return ESP_ERR_NO_MEM;
}
/* Initialise app data */
/* Initialize app data */
g_prov->pop = pop;
g_prov->security = security;
@ -391,6 +386,18 @@ esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass,
return err;
}
err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register WiFi event handler");
return err;
}
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register IP event handler");
return err;
}
/* Start WiFi softAP with specified ssid and password */
err = start_wifi_ap(ssid, pass);
if (err != ESP_OK) {

Wyświetl plik

@ -43,21 +43,6 @@ esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state);
*/
esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason);
/**
* @brief Event handler for provisioning app
*
* This is called from the main event handler and controls the
* provisioning application, depeding on WiFi events
*
* @param[in] ctx Event context data
* @param[in] event Event info
*
* @return
* - ESP_OK : Event handled successfully
* - ESP_FAIL : Failed to start server on event AP start
*/
esp_err_t app_prov_event_handler(void *ctx, system_event_t *event);
/**
* @brief Checks if device is provisioned
* *

Wyświetl plik

@ -7,17 +7,17 @@ menu "Example Configuration"
Set SoftAP SSID as PROV_<MAC>.
config SOFTAP_SSID
string "WiFi SSID"
string "Wi-Fi SSID"
default "PROV_SSID"
depends on !SOFTAP_SSID_SET_MAC
help
SSID (network name) for the example to connect to.
config SOFTAP_PASS
string "WiFi Password"
string "Wi-Fi Password"
default "PROV_PASS"
help
WiFi password (WPA or WPA2) for the example to use.
Wi-Fi password (WPA or WPA2) for the example to use.
config USE_SEC_1
bool
@ -48,6 +48,12 @@ menu "Example Configuration"
prompt "Reset provisioned status of the device"
help
This erases the NVS to reset provisioned status of the device on every reboot.
Provisioned status is determined by the WiFi STA configuration, saved on the NVS.
Provisioned status is determined by the Wi-Fi STA configuration, saved on the NVS.
config AP_RECONN_ATTEMPTS
int "Maximum AP connection attempts"
default 5
help
Set the maximum connection attempts to perform when connecting to a Wi-Fi AP.
endmenu

Wyświetl plik

@ -12,7 +12,7 @@
#include <freertos/task.h>
#include <esp_system.h>
#include <esp_wifi.h>
#include <esp_event_loop.h>
#include <esp_event.h>
#include <esp_log.h>
#include <nvs_flash.h>
@ -21,55 +21,46 @@
#include "app_prov.h"
#define EXAMPLE_AP_RECONN_ATTEMPTS CONFIG_AP_RECONN_ATTEMPTS
static const char *TAG = "app";
static esp_err_t event_handler(void *ctx, system_event_t *event)
static void event_handler(void* arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
/* Invoke Provisioning event handler first */
app_prov_event_handler(ctx, event);
static int s_retry_num = 0;
switch(event->event_id) {
case SYSTEM_EVENT_AP_START:
ESP_LOGI(TAG, "SoftAP started");
break;
case SYSTEM_EVENT_AP_STOP:
ESP_LOGI(TAG, "SoftAP stopped");
break;
case SYSTEM_EVENT_STA_START:
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < EXAMPLE_AP_RECONN_ATTEMPTS) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
ESP_LOGI(TAG,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:%s",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
break;
case SYSTEM_EVENT_AP_STACONNECTED:
ESP_LOGI(TAG, "station:"MACSTR" join, AID=%d",
MAC2STR(event->event_info.sta_connected.mac),
event->event_info.sta_connected.aid);
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
ESP_LOGI(TAG, "station:"MACSTR"leave, AID=%d",
MAC2STR(event->event_info.sta_disconnected.mac),
event->event_info.sta_disconnected.aid);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
break;
default:
break;
ip4addr_ntoa(&event->ip_info.ip));
s_retry_num = 0;
}
return ESP_OK;
}
static void wifi_init_sta()
{
/* Set our event handling */
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, NULL));
/* Start wifi in station mode with credentials set during provisioning */
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
}
void app_main()
static void start_softap_provisioning()
{
/* Security version */
int security = 0;
@ -89,23 +80,6 @@ void app_main()
pop = &app_pop;
#endif
/* Initialize networking stack */
tcpip_adapter_init();
/* Set our event handling */
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
/* Check if device is provisioned */
bool provisioned;
if (app_prov_is_provisioned(&provisioned) != ESP_OK) {
ESP_LOGE(TAG, "Error getting device provisioning state");
return;
}
if (provisioned == false) {
/* If not provisioned, start provisioning via soft AP */
ESP_LOGI(TAG, "Starting WiFi SoftAP provisioning");
const char *ssid = NULL;
#ifdef CONFIG_SOFTAP_SSID
@ -121,8 +95,30 @@ void app_main()
ssid = ssid_with_mac;
#endif
app_prov_start_softap_provisioning(ssid, CONFIG_SOFTAP_PASS,
security, pop);
ESP_ERROR_CHECK(app_prov_start_softap_provisioning(
ssid, CONFIG_SOFTAP_PASS, security, pop));
}
void app_main()
{
/* Initialize networking stack */
tcpip_adapter_init();
/* Create default event loop needed by the
* main app and the provisioning service */
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* Check if device is provisioned */
bool provisioned;
if (app_prov_is_provisioned(&provisioned) != ESP_OK) {
ESP_LOGE(TAG, "Error getting device provisioning state");
return;
}
if (provisioned == false) {
/* If not provisioned, start provisioning via soft AP */
ESP_LOGI(TAG, "Starting WiFi SoftAP provisioning");
start_softap_provisioning();
} else {
/* Start WiFi station with credentials set during provisioning */
ESP_LOGI(TAG, "Starting WiFi station");

Wyświetl plik

@ -13,6 +13,7 @@
#include <esp_wifi.h>
#include <nvs_flash.h>
#include <nvs.h>
#include <esp_event.h>
#include <protocomm.h>
#include <protocomm_httpd.h>
@ -24,6 +25,9 @@
static const char *TAG = "app_prov";
/* Handler for catching WiFi events */
static void app_prov_event_handler(void* handler_arg, esp_event_base_t base, int id, void* data);
/* Handlers for wifi_config provisioning endpoint */
extern wifi_prov_config_handlers_t wifi_prov_handlers;
@ -100,6 +104,10 @@ static void app_prov_stop_service(void)
protocomm_httpd_stop(g_prov->pc);
/* Delete protocomm instance */
protocomm_delete(g_prov->pc);
/* Remove event handler */
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler);
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler);
}
/* Task spawned by timer callback */
@ -128,33 +136,24 @@ static void _stop_prov_cb(void * arg)
xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL);
}
/* Event handler for starting/stopping provisioning.
* To be called from within the context of the main
* event handler.
*/
esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
/* Event handler for starting/stopping provisioning */
static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_base,
int event_id, void* event_data)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
/* If pointer to provisioning application data is NULL
* then provisioning is not running, therefore return without
* error */
* then provisioning is not running */
if (!g_prov) {
return ESP_OK;
return;
}
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
ESP_LOGI(TAG, "STA Start");
/* Once configuration is received by protocomm server,
* device is restarted as both AP and Station.
* Once station starts, wait for connection to
* establish with configured host SSID and password */
/* Once configuration is received through protocomm,
* device is started as station. Once station starts,
* wait for connection to establish with configured
* host SSID and password */
g_prov->wifi_state = WIFI_PROV_STA_CONNECTING;
break;
case SYSTEM_EVENT_STA_GOT_IP:
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ESP_LOGI(TAG, "STA Got IP");
/* Station got IP. That means configuration is successful.
* Schedule timer to stop provisioning app after 30 seconds. */
@ -171,16 +170,16 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
* signaling a failure in provisioning. */
esp_timer_start_once(g_prov->timer, 30000*1000U);
}
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
ESP_LOGE(TAG, "STA Disconnected");
/* Station couldn't connect to configured host SSID */
g_prov->wifi_state = WIFI_PROV_STA_DISCONNECTED;
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data;
ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason);
/* Set code corresponding to the reason for disconnection */
switch (info->disconnected.reason) {
switch (disconnected->reason) {
case WIFI_REASON_AUTH_EXPIRE:
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
case WIFI_REASON_BEACON_TIMEOUT:
@ -200,12 +199,7 @@ esp_err_t app_prov_event_handler(void *ctx, system_event_t *event)
g_prov->wifi_state = WIFI_PROV_STA_CONNECTING;
esp_wifi_connect();
}
break;
default:
break;
}
return ESP_OK;
}
esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state)
@ -378,6 +372,18 @@ esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass,
return err;
}
err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register WiFi event handler");
return err;
}
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register IP event handler");
return err;
}
/* Start WiFi softAP with specified ssid and password */
err = start_wifi_ap(ssid, pass);
if (err != ESP_OK) {

Wyświetl plik

@ -42,21 +42,6 @@ esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state);
*/
esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason);
/**
* @brief Event handler for provisioning app
*
* This is called from the main event handler and controls the
* provisioning application, depeding on WiFi events
*
* @param[in] ctx Event context data
* @param[in] event Event info
*
* @return
* - ESP_OK : Event handled successfully
* - ESP_FAIL : Failed to start server on event AP start
*/
esp_err_t app_prov_event_handler(void *ctx, system_event_t *event);
/**
* @brief Checks if device is provisioned
* *