Allows disabling backwards compatibility, which is not enabled by default since IDF 5. Since these symbols have been stable for many years now, it's time to let them go. - portTICK_RATE_MS renamed to portTICK_PERIOD_MS - xSemaphoreHandle renamed to SemaphoreHandle_t - xTaskHandle renamed to TaskHandle_t
585 lines
21 KiB
C
585 lines
21 KiB
C
/*
|
|
* ESPRESSIF MIT License
|
|
*
|
|
* Copyright (c) 2018 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
|
*
|
|
* Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in
|
|
* which case, it is free of charge, to any person obtaining a copy of this
|
|
* software and associated documentation files (the "Software"), to deal in the
|
|
* Software without restriction, including without limitation the rights to use,
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do
|
|
* so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
#include "periph_wifi.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "audio_idf_version.h"
|
|
#include "audio_mem.h"
|
|
#include "esp_event.h"
|
|
#include "esp_log.h"
|
|
#include "esp_peripherals.h"
|
|
#include "esp_smartconfig.h"
|
|
#include "esp_wifi.h"
|
|
#include "esp_wpa2.h"
|
|
#include "wifibleconfig.h"
|
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0))
|
|
#include "esp_netif.h"
|
|
#include "esp_wifi_netif.h"
|
|
#include "nvs_flash.h"
|
|
static esp_netif_t *sta = NULL;
|
|
#endif
|
|
|
|
static const char *TAG = "PERIPH_WIFI";
|
|
|
|
#define VALIDATE_WIFI(periph, ret) \
|
|
if (!(periph && esp_periph_get_id(periph) == PERIPH_ID_WIFI)) { \
|
|
ESP_LOGE(TAG, "Invalid WIFI periph, at line %d", __LINE__); \
|
|
return ret; \
|
|
}
|
|
|
|
#define DEFAULT_RECONNECT_TIMEOUT_MS (1000)
|
|
|
|
/* Constants that aren't configurable in menuconfig */
|
|
#define EAP_PEAP 1
|
|
#define EAP_TTLS 2
|
|
|
|
typedef struct periph_wifi *periph_wifi_handle_t;
|
|
|
|
struct periph_wifi {
|
|
periph_wifi_state_t wifi_state;
|
|
bool disable_auto_reconnect;
|
|
bool is_open;
|
|
uint8_t max_recon_time;
|
|
char *ssid;
|
|
char *password;
|
|
EventGroupHandle_t state_event;
|
|
int reconnect_timeout_ms;
|
|
periph_wifi_config_mode_t config_mode;
|
|
periph_wpa2_enterprise_cfg_t *wpa2_e_cfg;
|
|
};
|
|
|
|
static const int CONNECTED_BIT = BIT0;
|
|
static const int DISCONNECTED_BIT = BIT1;
|
|
static const int SMARTCONFIG_DONE_BIT = BIT2;
|
|
static const int SMARTCONFIG_ERROR_BIT = BIT3;
|
|
|
|
static esp_periph_handle_t g_periph = NULL;
|
|
static wifi_config_t wifi_config;
|
|
|
|
esp_err_t periph_wifi_wait_for_connected(esp_periph_handle_t periph,
|
|
TickType_t tick_to_wait) {
|
|
VALIDATE_WIFI(periph, ESP_FAIL);
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(periph);
|
|
EventBits_t connected_bit = xEventGroupWaitBits(
|
|
periph_wifi->state_event, CONNECTED_BIT, false, true, tick_to_wait);
|
|
if (connected_bit & CONNECTED_BIT) {
|
|
return ESP_OK;
|
|
}
|
|
#if defined(CONFIG_BTDM_CTRL_MODE_BLE_ONLY) || \
|
|
defined(CONFIG_BTDM_CTRL_MODE_BTDM)
|
|
if (periph_wifi->config_mode == WIFI_CONFIG_BLUEFI) {
|
|
ble_config_stop();
|
|
}
|
|
#endif
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
periph_wifi_state_t periph_wifi_is_connected(esp_periph_handle_t periph) {
|
|
VALIDATE_WIFI(periph, false);
|
|
periph_wifi_handle_t wifi = (periph_wifi_handle_t)esp_periph_get_data(periph);
|
|
return wifi->wifi_state;
|
|
}
|
|
|
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0))
|
|
static void _wifi_smartconfig_event_callback(void *arg,
|
|
esp_event_base_t event_base,
|
|
int32_t event_id,
|
|
void *event_data) {
|
|
wifi_config_t sta_conf;
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(g_periph);
|
|
switch (event_id) {
|
|
case SC_EVENT_SCAN_DONE:
|
|
ESP_LOGD(TAG, "SC_EVENT_SCAN_DONE");
|
|
break;
|
|
|
|
case SC_EVENT_FOUND_CHANNEL:
|
|
ESP_LOGD(TAG, "SC_EVENT_FOUND_CHANNEL");
|
|
break;
|
|
|
|
case SC_EVENT_GOT_SSID_PSWD:
|
|
ESP_LOGE(TAG, "SC_EVENT_GOT_SSID_PSWD");
|
|
smartconfig_event_got_ssid_pswd_t *evt =
|
|
(smartconfig_event_got_ssid_pswd_t *)event_data;
|
|
memset(&sta_conf, 0x00, sizeof(sta_conf));
|
|
memcpy(sta_conf.sta.ssid, evt->ssid, sizeof(sta_conf.sta.ssid));
|
|
memcpy(sta_conf.sta.password, evt->password,
|
|
sizeof(sta_conf.sta.password));
|
|
sta_conf.sta.bssid_set = evt->bssid_set;
|
|
if (sta_conf.sta.bssid_set == true) {
|
|
memcpy(sta_conf.sta.bssid, evt->bssid, sizeof(sta_conf.sta.bssid));
|
|
}
|
|
ESP_LOGE(TAG, "SSID=%s, PASS=%s", sta_conf.sta.ssid,
|
|
sta_conf.sta.password);
|
|
|
|
esp_wifi_disconnect();
|
|
|
|
if (esp_wifi_set_config(WIFI_IF_STA, &sta_conf) != ESP_OK) {
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONFIG_ERROR;
|
|
xEventGroupSetBits(periph_wifi->state_event, SMARTCONFIG_ERROR_BIT);
|
|
}
|
|
if (esp_wifi_connect() != ESP_OK) {
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONFIG_ERROR;
|
|
xEventGroupSetBits(periph_wifi->state_event, SMARTCONFIG_ERROR_BIT);
|
|
esp_periph_send_event(g_periph, PERIPH_WIFI_CONFIG_ERROR, NULL, 0);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SC_EVENT_SEND_ACK_DONE:
|
|
ESP_LOGE(TAG, "SC_EVENT_SEND_ACK_DONE");
|
|
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONFIG_DONE;
|
|
esp_periph_send_event(g_periph, PERIPH_WIFI_CONFIG_DONE, NULL, 0);
|
|
xEventGroupSetBits(periph_wifi->state_event, SMARTCONFIG_DONE_BIT);
|
|
esp_smartconfig_stop();
|
|
break;
|
|
}
|
|
}
|
|
#else
|
|
static void _wifi_smartconfig_event_callback(smartconfig_status_t status,
|
|
void *pdata) {
|
|
wifi_config_t sta_conf;
|
|
smartconfig_type_t *type;
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(g_periph);
|
|
switch (status) {
|
|
case SC_STATUS_WAIT:
|
|
ESP_LOGD(TAG, "SC_STATUS_WAIT");
|
|
break;
|
|
|
|
case SC_STATUS_FIND_CHANNEL:
|
|
ESP_LOGD(TAG, "SC_STATUS_FIND_CHANNEL");
|
|
break;
|
|
|
|
case SC_STATUS_GETTING_SSID_PSWD:
|
|
type = pdata;
|
|
ESP_LOGD(TAG, "SC_STATUS_GETTING_SSID_PSWD, SC_TYPE=%d", (int)*type);
|
|
break;
|
|
|
|
case SC_STATUS_LINK:
|
|
ESP_LOGE(TAG, "SC_STATUS_LINK");
|
|
memset(&sta_conf, 0x00, sizeof(sta_conf));
|
|
memcpy(&sta_conf.sta, pdata, sizeof(wifi_sta_config_t));
|
|
ESP_LOGE(TAG, "SSID=%s, PASS=%s", sta_conf.sta.ssid,
|
|
sta_conf.sta.password);
|
|
esp_wifi_disconnect();
|
|
|
|
if (esp_wifi_set_config(WIFI_IF_STA, &sta_conf) != ESP_OK) {
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONFIG_ERROR;
|
|
xEventGroupSetBits(periph_wifi->state_event, SMARTCONFIG_ERROR_BIT);
|
|
}
|
|
if (esp_wifi_connect() != ESP_OK) {
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONFIG_ERROR;
|
|
xEventGroupSetBits(periph_wifi->state_event, SMARTCONFIG_ERROR_BIT);
|
|
esp_periph_send_event(g_periph, PERIPH_WIFI_CONFIG_ERROR, NULL, 0);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SC_STATUS_LINK_OVER:
|
|
ESP_LOGE(TAG, "SC_STATUS_LINK_OVER");
|
|
|
|
if (pdata != NULL) {
|
|
char phone_ip[4] = {0};
|
|
memcpy(phone_ip, (const void *)pdata, 4);
|
|
ESP_LOGD(TAG, "Phone ip: %d.%d.%d.%d", phone_ip[0], phone_ip[1],
|
|
phone_ip[2], phone_ip[3]);
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONFIG_DONE;
|
|
esp_periph_send_event(g_periph, PERIPH_WIFI_CONFIG_DONE, NULL, 0);
|
|
xEventGroupSetBits(periph_wifi->state_event, SMARTCONFIG_DONE_BIT);
|
|
} else {
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONFIG_ERROR;
|
|
esp_periph_send_event(g_periph, PERIPH_WIFI_CONFIG_ERROR, NULL, 0);
|
|
xEventGroupSetBits(periph_wifi->state_event, SMARTCONFIG_ERROR_BIT);
|
|
}
|
|
esp_smartconfig_stop();
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
esp_err_t periph_wifi_wait_for_disconnected(esp_periph_handle_t periph,
|
|
TickType_t tick_to_wait) {
|
|
VALIDATE_WIFI(periph, ESP_FAIL);
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(periph);
|
|
EventBits_t disconnected_bit = xEventGroupWaitBits(
|
|
periph_wifi->state_event, DISCONNECTED_BIT, false, true, tick_to_wait);
|
|
if (disconnected_bit & DISCONNECTED_BIT) {
|
|
return ESP_OK;
|
|
}
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
esp_err_t periph_wifi_config_start(esp_periph_handle_t periph,
|
|
periph_wifi_config_mode_t mode) {
|
|
VALIDATE_WIFI(periph, ESP_FAIL);
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(periph);
|
|
esp_err_t err = ESP_OK;
|
|
periph_wifi->disable_auto_reconnect = true;
|
|
periph_wifi->config_mode = mode;
|
|
esp_wifi_disconnect();
|
|
|
|
if (periph_wifi_wait_for_disconnected(periph, portMAX_DELAY) != ESP_OK) {
|
|
return ESP_FAIL;
|
|
}
|
|
periph_wifi->wifi_state = PERIPH_WIFI_SETTING;
|
|
if (mode >= WIFI_CONFIG_ESPTOUCH && mode <= WIFI_CONFIG_ESPTOUCH_AIRKISS) {
|
|
err = ESP_OK; // 0;
|
|
// esp_wifi_start();
|
|
err |= esp_smartconfig_set_type(mode);
|
|
err |= esp_smartconfig_fast_mode(true);
|
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0))
|
|
smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
|
|
err |= esp_smartconfig_start(&cfg);
|
|
esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID,
|
|
&_wifi_smartconfig_event_callback, NULL);
|
|
#else
|
|
err |= esp_smartconfig_start(_wifi_smartconfig_event_callback, 0);
|
|
#endif
|
|
xEventGroupClearBits(periph_wifi->state_event, SMARTCONFIG_DONE_BIT);
|
|
xEventGroupClearBits(periph_wifi->state_event, SMARTCONFIG_ERROR_BIT);
|
|
|
|
} else if (mode == WIFI_CONFIG_WPS) {
|
|
// todo : add wps
|
|
return ESP_OK;
|
|
} else if (mode == WIFI_CONFIG_BLUEFI) {
|
|
#if defined(CONFIG_BTDM_CTRL_MODE_BLE_ONLY) || \
|
|
defined(CONFIG_BTDM_CTRL_MODE_BTDM)
|
|
ble_config_start(periph);
|
|
#endif
|
|
return ESP_OK;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
esp_err_t periph_wifi_config_wait_done(esp_periph_handle_t periph,
|
|
TickType_t tick_to_wait) {
|
|
VALIDATE_WIFI(periph, ESP_FAIL);
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(periph);
|
|
EventBits_t wificonfig_bit = xEventGroupWaitBits(
|
|
periph_wifi->state_event, SMARTCONFIG_DONE_BIT | SMARTCONFIG_ERROR_BIT,
|
|
false, false, tick_to_wait);
|
|
|
|
if (wificonfig_bit & SMARTCONFIG_DONE_BIT) {
|
|
return ESP_OK;
|
|
}
|
|
if (wificonfig_bit & SMARTCONFIG_ERROR_BIT) {
|
|
return ESP_FAIL;
|
|
}
|
|
esp_smartconfig_stop();
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
static void wifi_reconnect_timer(xTimerHandle tmr) {
|
|
esp_periph_handle_t periph = (esp_periph_handle_t)pvTimerGetTimerID(tmr);
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(periph);
|
|
esp_periph_stop_timer(periph);
|
|
if (periph_wifi->disable_auto_reconnect != true) {
|
|
esp_wifi_connect();
|
|
}
|
|
}
|
|
|
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0))
|
|
static void _wifi_event_callback(void *arg, esp_event_base_t event_base,
|
|
int32_t event_id, void *event_data) {
|
|
esp_periph_handle_t self = (esp_periph_handle_t)arg;
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(self);
|
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
|
esp_wifi_connect();
|
|
} 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:" IPSTR, IP2STR(&event->ip_info.ip));
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONNECTED;
|
|
xEventGroupClearBits(periph_wifi->state_event, DISCONNECTED_BIT);
|
|
esp_periph_send_event(self, PERIPH_WIFI_CONNECTED, NULL, 0);
|
|
xEventGroupSetBits(periph_wifi->state_event, CONNECTED_BIT);
|
|
wifi_config_t w_config;
|
|
memset(&w_config, 0x00, sizeof(wifi_config_t));
|
|
esp_wifi_get_config(WIFI_IF_STA, &w_config);
|
|
strcpy(periph_wifi->ssid, (char *)w_config.sta.ssid);
|
|
} else if (event_base == WIFI_EVENT &&
|
|
event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
|
periph_wifi->wifi_state = PERIPH_WIFI_DISCONNECTED;
|
|
xEventGroupClearBits(periph_wifi->state_event, CONNECTED_BIT);
|
|
xEventGroupSetBits(periph_wifi->state_event, DISCONNECTED_BIT);
|
|
esp_periph_send_event(self, PERIPH_WIFI_DISCONNECTED, NULL, 0);
|
|
|
|
ESP_LOGW(TAG,
|
|
"Wi-Fi disconnected from SSID %s, auto-reconnect %s, reconnect "
|
|
"after %d ms",
|
|
periph_wifi->ssid,
|
|
periph_wifi->disable_auto_reconnect == 0 ? "enabled" : "disabled",
|
|
periph_wifi->reconnect_timeout_ms);
|
|
if (periph_wifi->disable_auto_reconnect) {
|
|
return;
|
|
}
|
|
esp_periph_start_timer(
|
|
self, periph_wifi->reconnect_timeout_ms / portTICK_PERIOD_MS,
|
|
wifi_reconnect_timer);
|
|
|
|
} else {
|
|
ESP_LOGW(TAG, "WiFi Event cb, Unhandle event_base:%s, event_id:%d",
|
|
event_base, (int)event_id);
|
|
}
|
|
}
|
|
#else
|
|
static esp_err_t _wifi_event_callback(void *ctx, system_event_t *event) {
|
|
esp_periph_handle_t self = (esp_periph_handle_t)ctx;
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(self);
|
|
switch (event->event_id) {
|
|
case SYSTEM_EVENT_STA_START:
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONNECTING;
|
|
esp_wifi_connect();
|
|
break;
|
|
|
|
case SYSTEM_EVENT_STA_CONNECTED:
|
|
break;
|
|
case SYSTEM_EVENT_STA_GOT_IP:
|
|
periph_wifi->wifi_state = PERIPH_WIFI_CONNECTED;
|
|
xEventGroupClearBits(periph_wifi->state_event, DISCONNECTED_BIT);
|
|
esp_periph_send_event(self, PERIPH_WIFI_CONNECTED, NULL, 0);
|
|
xEventGroupSetBits(periph_wifi->state_event, CONNECTED_BIT);
|
|
wifi_config_t w_config;
|
|
memset(&w_config, 0x00, sizeof(wifi_config_t));
|
|
esp_wifi_get_config(WIFI_IF_STA, &w_config);
|
|
strcpy(periph_wifi->ssid, (char *)w_config.sta.ssid);
|
|
break;
|
|
case SYSTEM_EVENT_STA_DISCONNECTED:
|
|
periph_wifi->wifi_state = PERIPH_WIFI_DISCONNECTED;
|
|
xEventGroupClearBits(periph_wifi->state_event, CONNECTED_BIT);
|
|
xEventGroupSetBits(periph_wifi->state_event, DISCONNECTED_BIT);
|
|
esp_periph_send_event(self, PERIPH_WIFI_DISCONNECTED, NULL, 0);
|
|
|
|
ESP_LOGW(
|
|
TAG,
|
|
"Wi-Fi disconnected from SSID %s, auto-reconnect %s, reconnect after "
|
|
"%d ms",
|
|
periph_wifi->ssid,
|
|
periph_wifi->disable_auto_reconnect == 0 ? "enabled" : "disabled",
|
|
periph_wifi->reconnect_timeout_ms);
|
|
if (periph_wifi->disable_auto_reconnect) {
|
|
break;
|
|
}
|
|
esp_periph_start_timer(
|
|
self, periph_wifi->reconnect_timeout_ms / portTICK_PERIOD_MS,
|
|
wifi_reconnect_timer);
|
|
break;
|
|
default:
|
|
ESP_LOGW(TAG, "WiFi Event cb, Unhandled event_id: 0x%08X",
|
|
event->event_id);
|
|
break;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
#endif
|
|
|
|
static esp_err_t _wifi_run(esp_periph_handle_t self,
|
|
audio_event_iface_msg_t *msg) {
|
|
esp_periph_send_event(self, msg->cmd, NULL, 0);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t esp_wifi_set_listen_interval(esp_periph_handle_t periph,
|
|
int interval) {
|
|
if (wifi_config.sta.listen_interval != interval) {
|
|
wifi_config.sta.listen_interval = interval;
|
|
} else {
|
|
ESP_LOGW(TAG, "Wifi listen interval %d is already set", interval);
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t _wifi_init(esp_periph_handle_t self) {
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(self);
|
|
|
|
if (periph_wifi->is_open) {
|
|
ESP_LOGE(TAG, "Wifi has initialized");
|
|
return ESP_FAIL;
|
|
}
|
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0))
|
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0))
|
|
sta = esp_netif_create_default_wifi_sta();
|
|
#elif (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0))
|
|
esp_netif_create_default_wifi_sta();
|
|
#endif
|
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID,
|
|
&_wifi_event_callback, self));
|
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP,
|
|
&_wifi_event_callback, self));
|
|
#else
|
|
#include "esp_event_loop.h"
|
|
if (esp_event_loop_get_queue() == NULL) {
|
|
ESP_ERROR_CHECK(esp_event_loop_init(_wifi_event_callback, self));
|
|
} else {
|
|
esp_event_loop_set_cb(_wifi_event_callback, self);
|
|
}
|
|
#endif
|
|
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
|
|
if (periph_wifi->ssid) {
|
|
strcpy((char *)wifi_config.sta.ssid, periph_wifi->ssid);
|
|
ESP_LOGD(TAG, "WIFI_SSID=%s", wifi_config.sta.ssid);
|
|
if (periph_wifi->password) {
|
|
strcpy((char *)wifi_config.sta.password, periph_wifi->password);
|
|
ESP_LOGD(TAG, "WIFI_PASS=%s", wifi_config.sta.password);
|
|
}
|
|
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
|
|
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_set_ps(WIFI_PS_MIN_MODEM));
|
|
}
|
|
if (periph_wifi->wpa2_e_cfg->diasble_wpa2_e) {
|
|
unsigned int ca_pem_bytes = periph_wifi->wpa2_e_cfg->ca_pem_end -
|
|
periph_wifi->wpa2_e_cfg->ca_pem_start;
|
|
unsigned int client_crt_bytes = periph_wifi->wpa2_e_cfg->wpa2_e_cert_end -
|
|
periph_wifi->wpa2_e_cfg->wpa2_e_cert_start;
|
|
unsigned int client_key_bytes = periph_wifi->wpa2_e_cfg->wpa2_e_key_end -
|
|
periph_wifi->wpa2_e_cfg->wpa2_e_key_start;
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_ca_cert(
|
|
(const unsigned char *)periph_wifi->wpa2_e_cfg->ca_pem_start,
|
|
ca_pem_bytes));
|
|
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_cert_key(
|
|
(const unsigned char *)periph_wifi->wpa2_e_cfg->wpa2_e_cert_start,
|
|
client_crt_bytes,
|
|
(const unsigned char *)periph_wifi->wpa2_e_cfg->wpa2_e_key_start,
|
|
client_key_bytes, NULL, 0));
|
|
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_identity(
|
|
(uint8_t *)periph_wifi->wpa2_e_cfg->eap_id,
|
|
strlen(periph_wifi->wpa2_e_cfg->eap_id)));
|
|
if (periph_wifi->wpa2_e_cfg->eap_method == EAP_PEAP ||
|
|
periph_wifi->wpa2_e_cfg->eap_method == EAP_TTLS) {
|
|
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_username(
|
|
(uint8_t *)periph_wifi->wpa2_e_cfg->eap_username,
|
|
strlen(periph_wifi->wpa2_e_cfg->eap_username)));
|
|
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_password(
|
|
(uint8_t *)periph_wifi->wpa2_e_cfg->eap_password,
|
|
strlen(periph_wifi->wpa2_e_cfg->eap_password)));
|
|
}
|
|
|
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0))
|
|
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_enable());
|
|
#else
|
|
esp_wpa2_config_t wpa2_config = WPA2_CONFIG_INIT_DEFAULT();
|
|
ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_enable(&wpa2_config));
|
|
#endif
|
|
}
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_start());
|
|
periph_wifi->is_open = true;
|
|
periph_wifi->wifi_state = PERIPH_WIFI_DISCONNECTED;
|
|
xEventGroupClearBits(periph_wifi->state_event, CONNECTED_BIT);
|
|
xEventGroupSetBits(periph_wifi->state_event, DISCONNECTED_BIT);
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t _wifi_destroy(esp_periph_handle_t self) {
|
|
periph_wifi_handle_t periph_wifi =
|
|
(periph_wifi_handle_t)esp_periph_get_data(self);
|
|
esp_periph_stop_timer(self);
|
|
periph_wifi->disable_auto_reconnect = true;
|
|
esp_wifi_disconnect();
|
|
periph_wifi_wait_for_disconnected(self, portMAX_DELAY);
|
|
esp_wifi_stop();
|
|
esp_wifi_deinit();
|
|
audio_free(periph_wifi->ssid);
|
|
audio_free(periph_wifi->password);
|
|
|
|
vEventGroupDelete(periph_wifi->state_event);
|
|
if (periph_wifi->wpa2_e_cfg != NULL) {
|
|
audio_free(periph_wifi->wpa2_e_cfg);
|
|
periph_wifi->wpa2_e_cfg = NULL;
|
|
}
|
|
audio_free(periph_wifi);
|
|
g_periph = NULL;
|
|
|
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0))
|
|
esp_event_loop_delete_default();
|
|
esp_netif_destroy_default_wifi(sta);
|
|
#endif
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_periph_handle_t periph_wifi_init(periph_wifi_cfg_t *config) {
|
|
esp_periph_handle_t periph = NULL;
|
|
periph_wifi_handle_t periph_wifi = NULL;
|
|
bool _success =
|
|
((periph = esp_periph_create(PERIPH_ID_WIFI, "periph_wifi")) &&
|
|
(periph_wifi = audio_calloc(1, sizeof(struct periph_wifi))) &&
|
|
(periph_wifi->state_event = xEventGroupCreate()) &&
|
|
(config->ssid ? (bool)(periph_wifi->ssid = audio_strdup(config->ssid))
|
|
: true) &&
|
|
(config->password
|
|
? (bool)(periph_wifi->password = audio_strdup(config->password))
|
|
: true));
|
|
|
|
AUDIO_MEM_CHECK(TAG, _success, goto _periph_wifi_init_failed);
|
|
|
|
periph_wifi->reconnect_timeout_ms = config->reconnect_timeout_ms;
|
|
if (periph_wifi->reconnect_timeout_ms == 0) {
|
|
periph_wifi->reconnect_timeout_ms = DEFAULT_RECONNECT_TIMEOUT_MS;
|
|
}
|
|
periph_wifi->disable_auto_reconnect = config->disable_auto_reconnect;
|
|
|
|
periph_wifi->wpa2_e_cfg = audio_malloc(sizeof(periph_wpa2_enterprise_cfg_t));
|
|
AUDIO_NULL_CHECK(TAG, periph_wifi->wpa2_e_cfg, {
|
|
audio_free(periph);
|
|
goto _periph_wifi_init_failed;
|
|
});
|
|
memcpy(periph_wifi->wpa2_e_cfg, &config->wpa2_e_cfg,
|
|
sizeof(periph_wpa2_enterprise_cfg_t));
|
|
memset(&wifi_config, 0x00, sizeof(wifi_config_t));
|
|
|
|
esp_periph_set_data(periph, periph_wifi);
|
|
esp_periph_set_function(periph, _wifi_init, _wifi_run, _wifi_destroy);
|
|
g_periph = periph;
|
|
return periph;
|
|
|
|
_periph_wifi_init_failed:
|
|
if (periph_wifi) {
|
|
vEventGroupDelete(periph_wifi->state_event);
|
|
audio_free(periph_wifi->ssid);
|
|
audio_free(periph_wifi->password);
|
|
audio_free(periph_wifi);
|
|
}
|
|
return NULL;
|
|
}
|