mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
WiFi: Add WPS softAP registrar example and events
This commit is contained in:
parent
a6982a92fe
commit
924c709efe
@ -646,6 +646,12 @@ typedef enum {
|
||||
|
||||
WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START, /**< ESP32 connectionless module wake interval start */
|
||||
|
||||
WIFI_EVENT_AP_WPS_RG_SUCCESS, /**< Soft-AP wps succeeds in registrar mode */
|
||||
WIFI_EVENT_AP_WPS_RG_FAILED, /**< Soft-AP wps fails in registrar mode */
|
||||
WIFI_EVENT_AP_WPS_RG_TIMEOUT, /**< Soft-AP wps timeout in registrar mode */
|
||||
WIFI_EVENT_AP_WPS_RG_PIN, /**< Soft-AP wps pin code in registrar mode */
|
||||
WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP, /**< Soft-AP wps overlap in registrar mode */
|
||||
|
||||
WIFI_EVENT_MAX, /**< Invalid WiFi event ID */
|
||||
} wifi_event_t;
|
||||
|
||||
@ -789,6 +795,29 @@ typedef struct {
|
||||
uint32_t context; /**< Context to identify the request */
|
||||
} wifi_event_roc_done_t;
|
||||
|
||||
/** Argument structure for WIFI_EVENT_AP_WPS_RG_PIN event */
|
||||
typedef struct {
|
||||
uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */
|
||||
} wifi_event_ap_wps_rg_pin_t;
|
||||
|
||||
typedef enum {
|
||||
WPS_AP_FAIL_REASON_NORMAL = 0, /**< WPS normal fail reason */
|
||||
WPS_AP_FAIL_REASON_CONFIG, /**< WPS failed due to incorrect config */
|
||||
WPS_AP_FAIL_REASON_AUTH, /**< WPS failed during auth */
|
||||
WPS_AP_FAIL_REASON_MAX,
|
||||
} wps_fail_reason_t;
|
||||
|
||||
/** Argument structure for WIFI_EVENT_AP_WPS_RG_FAILED event */
|
||||
typedef struct {
|
||||
wps_fail_reason_t reason; /**< WPS failure reason wps_fail_reason_t */
|
||||
uint8_t peer_macaddr[6]; /**< Enrollee mac address */
|
||||
} wifi_event_ap_wps_rg_fail_reason_t;
|
||||
|
||||
/** Argument structure for WIFI_EVENT_AP_WPS_RG_SUCCESS event */
|
||||
typedef struct {
|
||||
uint8_t peer_macaddr[6]; /**< Enrollee mac address */
|
||||
} wifi_event_ap_wps_rg_success_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 9e81af17476302dbf053242a9a0a9b81a3cd2949
|
||||
Subproject commit 2fae5b132437907691d51ac4b3c31227b7b7ab33
|
@ -119,7 +119,7 @@ esp_err_t esp_wifi_wps_start(int timeout_ms);
|
||||
*
|
||||
* @attention WPS can only be used when softAP is enabled.
|
||||
*
|
||||
* @param wps_type_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported
|
||||
* @param esp_wps_config_t config: wps configuration to be used.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : succeed
|
||||
@ -145,6 +145,10 @@ esp_err_t esp_wifi_ap_wps_disable(void);
|
||||
*
|
||||
* @attention WPS can only be used when softAP is enabled.
|
||||
*
|
||||
* @param pin : Pin to be used in case of WPS mode is pin.
|
||||
* If Pin is not provided, device will use the pin generated/provided
|
||||
* during esp_wifi_ap_wps_enable() and reported in WIFI_EVENT_AP_WPS_RG_PIN
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : succeed
|
||||
* - ESP_ERR_WIFI_WPS_TYPE : wps type is invalid
|
||||
|
@ -32,7 +32,7 @@ extern void *s_wps_api_lock;
|
||||
extern void *s_wps_api_sem;
|
||||
extern bool s_wps_enabled;
|
||||
|
||||
static int wifi_ap_wps_init(void)
|
||||
static int wifi_ap_wps_init(const esp_wps_config_t *config)
|
||||
{
|
||||
struct wps_sm *sm = NULL;
|
||||
uint8_t mac[ETH_ALEN];
|
||||
@ -69,6 +69,7 @@ static int wifi_ap_wps_init(void)
|
||||
cfg.registrar = 1;
|
||||
cfg.wps = sm->wps_ctx;
|
||||
|
||||
os_memcpy((void *)cfg.pin, config->pin, 8);
|
||||
wps_init_cfg_pin(&cfg);
|
||||
os_memcpy(cfg.wps->uuid, sm->uuid, WPS_UUID_LEN);
|
||||
if ((sm->wps = wps_init(&cfg)) == NULL) { /* alloc wps_data */
|
||||
@ -76,6 +77,14 @@ static int wifi_ap_wps_init(void)
|
||||
}
|
||||
|
||||
hostapd_init_wps(hostapd_get_hapd_data(), sm->wps, sm->wps_ctx);
|
||||
|
||||
/* Report PIN */
|
||||
if (wps_get_type() == WPS_TYPE_PIN) {
|
||||
wifi_event_sta_wps_er_pin_t evt;
|
||||
os_memcpy(evt.pin_code, sm->wps->dev_password, 8);
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_PIN, &evt, sizeof(evt), OS_BLOCK);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
_err:
|
||||
@ -102,23 +111,26 @@ int wifi_ap_wps_deinit(void)
|
||||
{
|
||||
struct wps_sm *sm = gWpsSm;
|
||||
|
||||
hostapd_deinit_wps(hostapd_get_hapd_data());
|
||||
if (gWpsSm == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
hostapd_deinit_wps(hostapd_get_hapd_data());
|
||||
if (sm->wps) {
|
||||
sm->wps->registrar = 0;
|
||||
wps_deinit(sm->wps);
|
||||
sm->wps = NULL;
|
||||
}
|
||||
if (sm->dev) {
|
||||
wps_dev_deinit(sm->dev);
|
||||
sm->dev = NULL;
|
||||
}
|
||||
|
||||
if (sm->wps_ctx) {
|
||||
os_free(sm->wps_ctx);
|
||||
sm->wps_ctx = NULL;
|
||||
}
|
||||
if (sm->wps) {
|
||||
wps_deinit(sm->wps);
|
||||
sm->wps = NULL;
|
||||
}
|
||||
|
||||
os_free(gWpsSm);
|
||||
gWpsSm = NULL;
|
||||
|
||||
@ -146,7 +158,7 @@ int wifi_ap_wps_enable_internal(const esp_wps_config_t *config)
|
||||
wps_set_type(config->wps_type);
|
||||
wps_set_status(WPS_STATUS_DISABLE);
|
||||
|
||||
ret = wifi_ap_wps_init();
|
||||
ret = wifi_ap_wps_init(config);
|
||||
|
||||
if (ret != 0) {
|
||||
wps_set_type(WPS_STATUS_DISABLE);
|
||||
@ -199,8 +211,8 @@ int esp_wifi_ap_wps_disable(void)
|
||||
}
|
||||
|
||||
wpa_printf(MSG_INFO, "wifi_wps_disable");
|
||||
wps_set_status(WPS_STATUS_DISABLE);
|
||||
wps_set_type(WPS_TYPE_DISABLE);
|
||||
wps_set_status(WPS_STATUS_DISABLE);
|
||||
|
||||
wifi_ap_wps_deinit();
|
||||
|
||||
@ -232,15 +244,20 @@ int esp_wifi_ap_wps_start(const unsigned char *pin)
|
||||
}
|
||||
|
||||
if (wps_get_type() == WPS_TYPE_DISABLE || (wps_get_status() != WPS_STATUS_DISABLE && wps_get_status() != WPS_STATUS_SCANNING)) {
|
||||
wpa_printf(MSG_ERROR, "wps start: wps_get_type=%d wps_get_status=%d", wps_get_type(), wps_get_status());
|
||||
API_MUTEX_GIVE();
|
||||
return ESP_ERR_WIFI_WPS_TYPE;
|
||||
}
|
||||
|
||||
if (esp_wifi_get_user_init_flag_internal() == 0) {
|
||||
wpa_printf(MSG_ERROR, "wps start: esp_wifi_get_user_init_flag_internal=%d", esp_wifi_get_user_init_flag_internal());
|
||||
API_MUTEX_GIVE();
|
||||
return ESP_ERR_WIFI_STATE;
|
||||
}
|
||||
|
||||
if (!pin) {
|
||||
pin = gWpsSm->wps->dev_password;
|
||||
}
|
||||
/* TODO ideally SoftAP mode should also do a single scan in PBC mode
|
||||
* however softAP scanning is not available at the moment */
|
||||
wps_set_status(WPS_STATUS_PENDING);
|
||||
|
@ -1188,22 +1188,7 @@ int wps_dev_deinit(struct wps_device_data *dev)
|
||||
if (!dev) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (dev->manufacturer) {
|
||||
os_free(dev->manufacturer);
|
||||
}
|
||||
if (dev->model_name) {
|
||||
os_free(dev->model_name);
|
||||
}
|
||||
if (dev->model_number) {
|
||||
os_free(dev->model_number);
|
||||
}
|
||||
if (dev->device_name) {
|
||||
os_free(dev->device_name);
|
||||
}
|
||||
if (dev->serial_number) {
|
||||
os_free(dev->serial_number);
|
||||
}
|
||||
wps_device_data_free(dev);
|
||||
|
||||
if (s_factory_info) {
|
||||
os_free(s_factory_info);
|
||||
@ -1358,21 +1343,23 @@ int wps_init_cfg_pin(struct wps_config *cfg)
|
||||
}
|
||||
|
||||
cfg->pbc = 0;
|
||||
if (os_strncmp((char *)cfg->pin, "00000000", 8) != 0) {
|
||||
|
||||
if ((os_strncmp((char *)cfg->pin, "00000000", 8) == 0) || !wps_pin_str_valid((char *)cfg->pin)) {
|
||||
unsigned int spin = 0;
|
||||
|
||||
cfg->dev_pw_id = DEV_PW_DEFAULT;
|
||||
cfg->pin_len = 8;
|
||||
if (wps_generate_pin(&spin) < 0) {
|
||||
return -1;
|
||||
}
|
||||
wpa_printf(MSG_INFO, "Provided PIN %s is not valid, generated a new PIN %08d", (char *)cfg->pin, spin);
|
||||
os_snprintf((char *)cfg->pin, 9, "%08d", spin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
wifi_station_wps_init(void)
|
||||
static int wifi_station_wps_init(const esp_wps_config_t *config)
|
||||
{
|
||||
struct wps_funcs *wps_cb;
|
||||
struct wps_sm *sm = NULL;
|
||||
@ -1408,6 +1395,7 @@ wifi_station_wps_init(void)
|
||||
|
||||
cfg.wps = sm->wps_ctx;
|
||||
|
||||
os_memcpy((void *)cfg.pin, config->pin, 8);
|
||||
if (wps_init_cfg_pin(&cfg) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
@ -1858,7 +1846,7 @@ int wifi_wps_enable_internal(const esp_wps_config_t *config)
|
||||
wps_set_type(config->wps_type);
|
||||
wps_set_status(WPS_STATUS_DISABLE);
|
||||
|
||||
ret = wifi_station_wps_init();
|
||||
ret = wifi_station_wps_init(config);
|
||||
|
||||
if (ret != 0) {
|
||||
wps_set_type(WPS_STATUS_DISABLE);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "wpa_auth.h"
|
||||
#include "ap_config.h"
|
||||
#include "sta_info.h"
|
||||
#include "esp_wps_i.h"
|
||||
|
||||
static void ap_sta_delayed_1x_auth_fail_cb(void *eloop_ctx, void *timeout_ctx);
|
||||
void hostapd_wps_eap_completed(struct hostapd_data *hapd);
|
||||
@ -167,7 +168,6 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
|
||||
|
||||
static void ap_sta_delayed_1x_auth_fail_cb(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
struct hostapd_data *hapd = eloop_ctx;
|
||||
struct sta_info *sta = timeout_ctx;
|
||||
u16 reason;
|
||||
|
||||
@ -177,14 +177,21 @@ static void ap_sta_delayed_1x_auth_fail_cb(void *eloop_ctx, void *timeout_ctx)
|
||||
|
||||
reason = WLAN_REASON_IEEE_802_1X_AUTH_FAILED;
|
||||
esp_wifi_ap_deauth_internal(sta->addr, reason);
|
||||
if (sta->flags & WLAN_STA_WPS)
|
||||
hostapd_wps_eap_completed(hapd);
|
||||
}
|
||||
|
||||
|
||||
void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
#ifdef ESP_SUPPLICANT
|
||||
wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
|
||||
"IEEE 802.1X: Scheduled disconnection of " MACSTR
|
||||
" after EAP-Failure", MAC2STR(sta->addr));
|
||||
|
||||
esp_wifi_ap_deauth_internal(sta->addr, WLAN_REASON_IEEE_802_1X_AUTH_FAILED);
|
||||
if (wps_get_status() == WPS_STATUS_PENDING)
|
||||
wps_set_status(WPS_STATUS_DISABLE);
|
||||
#else
|
||||
wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
|
||||
"IEEE 802.1X: Force disconnection of " MACSTR
|
||||
" after EAP-Failure in 10 ms", MAC2STR(sta->addr));
|
||||
@ -197,6 +204,7 @@ void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,
|
||||
eloop_cancel_timeout(ap_sta_delayed_1x_auth_fail_cb, hapd, sta);
|
||||
eloop_register_timeout(0, 10000, ap_sta_delayed_1x_auth_fail_cb,
|
||||
hapd, sta);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "esp_wpas_glue.h"
|
||||
#include "esp_wps_i.h"
|
||||
|
||||
#define STATE_MACHINE_DATA struct wpa_state_machine
|
||||
#define STATE_MACHINE_DEBUG_PREFIX "WPA"
|
||||
@ -2375,13 +2376,42 @@ bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WPS_REGISTRAR
|
||||
static void ap_free_sta_timeout(void *ctx, void *data)
|
||||
{
|
||||
struct hostapd_data *hapd = (struct hostapd_data *) ctx;
|
||||
u8 *addr = (u8 *) data;
|
||||
struct sta_info *sta = ap_get_sta(hapd, addr);
|
||||
|
||||
if (sta) {
|
||||
ap_free_sta(hapd, sta);
|
||||
}
|
||||
|
||||
os_free(addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool wpa_ap_remove(void* sta_info)
|
||||
{
|
||||
struct hostapd_data *hapd = hostapd_get_hapd_data();
|
||||
|
||||
if (!sta_info || !hapd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WPS_REGISTRAR
|
||||
wpa_printf(MSG_DEBUG, "wps_status=%d", wps_get_status());
|
||||
if (wps_get_status() == WPS_STATUS_PENDING) {
|
||||
struct sta_info *sta = (struct sta_info *)sta_info;
|
||||
u8 *addr = os_malloc(ETH_ALEN);
|
||||
|
||||
if (!addr) {
|
||||
return false;
|
||||
}
|
||||
os_memcpy(addr, sta->addr, ETH_ALEN);
|
||||
eloop_register_timeout(0, 10000, ap_free_sta_timeout, hapd, addr);
|
||||
} else
|
||||
#endif
|
||||
ap_free_sta(hapd, sta_info);
|
||||
|
||||
return true;
|
||||
|
@ -90,7 +90,6 @@ static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
|
||||
data.dev_pw = dev_pw;
|
||||
data.dev_pw_len = dev_pw_len;
|
||||
wps_stop_registrar(hapd, &data);
|
||||
wps_set_status(WPS_STATUS_DISABLE);
|
||||
|
||||
/* TODO add callback event for freeRTOS */
|
||||
}
|
||||
@ -111,68 +110,20 @@ static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx)
|
||||
wps_registrar_update_ie(hapd->wps->registrar);
|
||||
}
|
||||
|
||||
|
||||
static int wps_pwd_auth_fail(struct hostapd_data *hapd, void *ctx)
|
||||
{
|
||||
struct wps_event_pwd_auth_fail *data = ctx;
|
||||
|
||||
if (!data->enrollee || hapd->conf->ap_pin == NULL || hapd->wps == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
|
||||
* for some time if this happens multiple times to slow down brute
|
||||
* force attacks.
|
||||
*/
|
||||
hapd->ap_pin_failures++;
|
||||
hapd->ap_pin_failures_consecutive++;
|
||||
wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u "
|
||||
"(%u consecutive)",
|
||||
hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive);
|
||||
if (hapd->ap_pin_failures < 3)
|
||||
return 0;
|
||||
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED);
|
||||
hapd->wps->ap_setup_locked = 1;
|
||||
|
||||
wps_registrar_update_ie(hapd->wps->registrar);
|
||||
|
||||
if (!hapd->conf->ap_setup_locked &&
|
||||
hapd->ap_pin_failures_consecutive >= 10) {
|
||||
/*
|
||||
* In indefinite lockdown - disable automatic AP PIN
|
||||
* reenablement.
|
||||
*/
|
||||
eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
|
||||
wpa_printf(MSG_DEBUG, "WPS: AP PIN disabled indefinitely");
|
||||
} else if (!hapd->conf->ap_setup_locked) {
|
||||
if (hapd->ap_pin_lockout_time == 0)
|
||||
hapd->ap_pin_lockout_time = 60;
|
||||
else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
|
||||
(hapd->ap_pin_failures % 3) == 0)
|
||||
hapd->ap_pin_lockout_time *= 2;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN for %u seconds",
|
||||
hapd->ap_pin_lockout_time);
|
||||
eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
|
||||
eloop_register_timeout(hapd->ap_pin_lockout_time, 0,
|
||||
hostapd_wps_reenable_ap_pin, hapd,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
|
||||
struct wps_event_pwd_auth_fail *data)
|
||||
{
|
||||
/* Update WPS Status - Authentication Failure */
|
||||
wifi_event_ap_wps_rg_fail_reason_t evt = {0};
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS: Authentication failure update");
|
||||
hapd->wps_stats.status = WPS_FAILURE_STATUS;
|
||||
os_memcpy(hapd->wps_stats.peer_addr, data->peer_macaddr, ETH_ALEN);
|
||||
|
||||
wps_pwd_auth_fail(hapd, data);
|
||||
os_memcpy(evt.peer_macaddr, data->peer_macaddr, ETH_ALEN);
|
||||
evt.reason = WPS_AP_FAIL_REASON_AUTH;
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_FAILED, &evt,
|
||||
sizeof(evt), OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
@ -193,16 +144,12 @@ static int wps_ap_pin_success(struct hostapd_data *hapd, void *ctx)
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_ap_pin_success(struct hostapd_data *hapd)
|
||||
{
|
||||
wps_ap_pin_success(hapd, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_pbc_overlap(struct hostapd_data *hapd)
|
||||
{
|
||||
/* Update WPS Status - PBC Overlap */
|
||||
|
||||
hapd->wps_stats.pbc_status = WPS_PBC_STATUS_OVERLAP;
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP, NULL, 0, OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
@ -210,16 +157,14 @@ static void hostapd_wps_event_pbc_timeout(struct hostapd_data *hapd)
|
||||
{
|
||||
/* Update WPS PBC Status:PBC Timeout */
|
||||
hapd->wps_stats.pbc_status = WPS_PBC_STATUS_TIMEOUT;
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_TIMEOUT, NULL, 0, OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_pbc_active(struct hostapd_data *hapd)
|
||||
static void hostapd_wps_event_pin_timeout(struct hostapd_data *hapd)
|
||||
{
|
||||
/* Update WPS PBC status - Active */
|
||||
hapd->wps_stats.pbc_status = WPS_PBC_STATUS_ACTIVE;
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_TIMEOUT, NULL, 0, OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_pbc_disable(struct hostapd_data *hapd)
|
||||
{
|
||||
/* Update WPS PBC status - Active */
|
||||
@ -230,31 +175,25 @@ static void hostapd_wps_event_pbc_disable(struct hostapd_data *hapd)
|
||||
static void hostapd_wps_event_success(struct hostapd_data *hapd,
|
||||
struct wps_event_success *success)
|
||||
{
|
||||
/* Update WPS status - Success */
|
||||
hapd->wps_stats.pbc_status = WPS_PBC_STATUS_DISABLE;
|
||||
hapd->wps_stats.status = WPS_SUCCESS_STATUS;
|
||||
os_memcpy(hapd->wps_stats.peer_addr, success->peer_macaddr, ETH_ALEN);
|
||||
wifi_event_ap_wps_rg_success_t evt;
|
||||
|
||||
os_memcpy(evt.peer_macaddr, success->peer_macaddr, ETH_ALEN);
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_SUCCESS, &evt,
|
||||
sizeof(evt), OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_wps_event_fail(struct hostapd_data *hapd,
|
||||
struct wps_event_fail *fail)
|
||||
{
|
||||
/* Update WPS status - Failure */
|
||||
hapd->wps_stats.status = WPS_FAILURE_STATUS;
|
||||
os_memcpy(hapd->wps_stats.peer_addr, fail->peer_macaddr, ETH_ALEN);
|
||||
|
||||
if (fail->error_indication > 0 &&
|
||||
fail->error_indication < NUM_WPS_EI_VALUES) {
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
||||
WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
|
||||
fail->msg, fail->config_error, fail->error_indication,
|
||||
wps_ei_str(fail->error_indication));
|
||||
} else {
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO,
|
||||
WPS_EVENT_FAIL "msg=%d config_error=%d",
|
||||
fail->msg, fail->config_error);
|
||||
}
|
||||
wifi_event_ap_wps_rg_fail_reason_t evt;
|
||||
if (fail->config_error > WPS_CFG_NO_ERROR)
|
||||
evt.reason = WPS_AP_FAIL_REASON_CONFIG;
|
||||
else
|
||||
evt.reason = WPS_AP_FAIL_REASON_NORMAL;
|
||||
os_memcpy(evt.peer_macaddr, fail->peer_macaddr, ETH_ALEN);
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_AP_WPS_RG_FAILED, &evt,
|
||||
sizeof(evt), OS_BLOCK);
|
||||
}
|
||||
|
||||
|
||||
@ -264,9 +203,6 @@ static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
|
||||
struct hostapd_data *hapd = ctx;
|
||||
|
||||
switch (event) {
|
||||
case WPS_EV_M2D:
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_M2D);
|
||||
break;
|
||||
case WPS_EV_FAIL:
|
||||
hostapd_wps_event_fail(hapd, &data->fail);
|
||||
break;
|
||||
@ -285,8 +221,9 @@ static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
|
||||
hostapd_wps_event_pbc_timeout(hapd);
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_TIMEOUT);
|
||||
break;
|
||||
case WPS_EV_SELECTED_REGISTRAR_TIMEOUT:
|
||||
hostapd_wps_event_pin_timeout(hapd);
|
||||
case WPS_EV_PBC_ACTIVE:
|
||||
hostapd_wps_event_pbc_active(hapd);
|
||||
wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_ACTIVE);
|
||||
break;
|
||||
case WPS_EV_PBC_DISABLE:
|
||||
@ -306,7 +243,9 @@ static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
|
||||
case WPS_EV_ER_SET_SELECTED_REGISTRAR:
|
||||
break;
|
||||
case WPS_EV_AP_PIN_SUCCESS:
|
||||
hostapd_wps_ap_pin_success(hapd);
|
||||
wps_ap_pin_success(hapd, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (hapd->wps_event_cb)
|
||||
@ -392,7 +331,8 @@ void hostapd_deinit_wps(struct hostapd_data *hapd)
|
||||
return;
|
||||
}
|
||||
wps_registrar_deinit(hapd->wps->registrar);
|
||||
hostapd_free_wps(hapd->wps);
|
||||
hapd->wps->registrar = NULL;
|
||||
eap_server_unregister_methods();
|
||||
hapd->wps = NULL;
|
||||
hostapd_wps_clear_ies(hapd, 1);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ static void eap_wsc_reset(struct eap_sm *sm, void *priv)
|
||||
struct eap_wsc_data *data = priv;
|
||||
wpabuf_free(data->in_buf);
|
||||
wpabuf_free(data->out_buf);
|
||||
wps_deinit(data->wps);
|
||||
//wps_deinit(data->wps);
|
||||
os_free(data);
|
||||
}
|
||||
|
||||
|
@ -521,7 +521,9 @@ enum wps_event {
|
||||
/**
|
||||
* WPS_EV_AP_PIN_SUCCESS - External Registrar used correct AP PIN
|
||||
*/
|
||||
WPS_EV_AP_PIN_SUCCESS
|
||||
WPS_EV_AP_PIN_SUCCESS,
|
||||
|
||||
WPS_EV_SELECTED_REGISTRAR_TIMEOUT,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -330,6 +330,14 @@ void wps_pbc_overlap_event(struct wps_context *wps)
|
||||
}
|
||||
|
||||
|
||||
void wps_selected_registrar_timeout_event(struct wps_context *wps)
|
||||
{
|
||||
if (wps->event_cb == NULL)
|
||||
return;
|
||||
|
||||
wps->event_cb(wps->cb_ctx, WPS_EV_SELECTED_REGISTRAR_TIMEOUT, NULL);
|
||||
}
|
||||
|
||||
void wps_pbc_timeout_event(struct wps_context *wps)
|
||||
{
|
||||
if (wps->event_cb == NULL)
|
||||
|
@ -145,6 +145,7 @@ void wps_success_event(struct wps_context *wps, const u8 *mac_addr);
|
||||
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part,
|
||||
const u8 *mac_addr);
|
||||
void wps_pbc_overlap_event(struct wps_context *wps);
|
||||
void wps_selected_registrar_timeout_event(struct wps_context *wps);
|
||||
void wps_pbc_timeout_event(struct wps_context *wps);
|
||||
void wps_pbc_active_event(struct wps_context *wps);
|
||||
void wps_pbc_disable_event(struct wps_context *wps);
|
||||
|
@ -852,7 +852,6 @@ static void wps_registrar_remove_pin(struct wps_registrar *reg,
|
||||
addr = pin->enrollee_addr;
|
||||
wps_registrar_remove_authorized_mac(reg, addr);
|
||||
wps_remove_pin(pin);
|
||||
wps_registrar_selected_registrar_changed(reg, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -3485,6 +3484,7 @@ static void wps_registrar_set_selected_timeout(void *eloop_ctx,
|
||||
reg->pbc = 0;
|
||||
wps_registrar_expire_pins(reg);
|
||||
wps_registrar_selected_registrar_changed(reg, 0);
|
||||
wps_selected_registrar_timeout_event(reg->wps);
|
||||
}
|
||||
|
||||
|
||||
|
6
examples/wifi/wps_softap_registrar/CMakeLists.txt
Normal file
6
examples/wifi/wps_softap_registrar/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(wps_softap_registrar)
|
53
examples/wifi/wps_softap_registrar/README.md
Normal file
53
examples/wifi/wps_softap_registrar/README.md
Normal file
@ -0,0 +1,53 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- |
|
||||
|
||||
# Wi-Fi WPS Registrar Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example shows how to use WPS registrar sotAP mode in ESP. The WPS protocol simplifies the process of connecting to a Wi-Fi softAP from a station.
|
||||
|
||||
## How to use example
|
||||
|
||||
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with ESP32/ESP32-S2/ESP32-C3/ESP32-S3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
|
||||
* A USB cable for Power supply and programming
|
||||
|
||||
### Configure the project
|
||||
|
||||
Open the project configuration menu (`idf.py menuconfig`).
|
||||
|
||||
In the `Example Configuration` menu:
|
||||
|
||||
* Use `WPS mode` to select the type.
|
||||
* Select `PBC`, `PIN` or `disable`.
|
||||
|
||||
In `PBC` mode, the ESP will wait for the WPS initialization (usually by pressing WPS button on the Wi-Fi station).
|
||||
|
||||
In `PIN` mode, the ESP will enter the WPS mode and you'll see a pin code on the terminal(If not given through user config). Enter this pin code in your station and then the ESP will connect to it.
|
||||
|
||||
(See your station's manual and configuration for WPS compatibility.)
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run the monitor tool to view the serial output:
|
||||
|
||||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects.
|
||||
|
||||
* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html)
|
||||
* [ESP-IDF Getting Started Guide on ESP32-S2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
|
||||
* [ESP-IDF Getting Started Guide on ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html)
|
||||
* [ESP-IDF Getting Started Guide on ESP32-S3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/get-started/index.html)
|
||||
* [ESP-IDF Getting Started Guide on ESP32-C2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c2/get-started/index.html)
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
2
examples/wifi/wps_softap_registrar/main/CMakeLists.txt
Normal file
2
examples/wifi/wps_softap_registrar/main/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "wps.c"
|
||||
INCLUDE_DIRS ".")
|
50
examples/wifi/wps_softap_registrar/main/Kconfig.projbuild
Normal file
50
examples/wifi/wps_softap_registrar/main/Kconfig.projbuild
Normal file
@ -0,0 +1,50 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config EXAMPLE_WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
help
|
||||
SSID (network name) for the example to connect to.
|
||||
|
||||
config EXAMPLE_WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "mypassword"
|
||||
help
|
||||
WiFi password (WPA or WPA2) for the example to use.
|
||||
|
||||
config EXAMPLE_WIFI_CHANNEL
|
||||
int "WiFi Channel"
|
||||
range 1 13
|
||||
default 1
|
||||
help
|
||||
WiFi channel (network channel) for the example to use.
|
||||
|
||||
config EXAMPLE_MAX_STA_CONN
|
||||
int "Maximal STA connections"
|
||||
default 4
|
||||
help
|
||||
Max number of the STA connects to AP.
|
||||
|
||||
choice EXAMPLE_WPS_TYPE
|
||||
prompt "WPS mode"
|
||||
default EXAMPLE_WPS_TYPE_PBC
|
||||
help
|
||||
WPS type for the esp32 to use.
|
||||
|
||||
config EXAMPLE_WPS_TYPE_PBC
|
||||
bool "PBC"
|
||||
config EXAMPLE_WPS_TYPE_PIN
|
||||
bool "PIN"
|
||||
config EXAMPLE_WPS_TYPE_DISABLE
|
||||
bool "disable"
|
||||
endchoice
|
||||
|
||||
if EXAMPLE_WPS_TYPE_PIN
|
||||
config EXAMPLE_WPS_PIN_VALUE
|
||||
int "WPS PIN"
|
||||
default 0
|
||||
help
|
||||
WPS PIN to be used for the connection, incase its not give, AP will derive a new one.
|
||||
endif
|
||||
|
||||
endmenu
|
179
examples/wifi/wps_softap_registrar/main/wps.c
Normal file
179
examples/wifi/wps_softap_registrar/main/wps.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
/* WPS Registrar example in softAP mode
|
||||
|
||||
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 "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_mac.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_wps.h"
|
||||
#include "esp_event.h"
|
||||
#include "nvs_flash.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*set wps mode via project configuration */
|
||||
#if CONFIG_EXAMPLE_WPS_TYPE_PBC
|
||||
#define WPS_MODE WPS_TYPE_PBC
|
||||
#elif CONFIG_EXAMPLE_WPS_TYPE_PIN
|
||||
#if CONFIG_EXAMPLE_WPS_PIN_VALUE
|
||||
#define EXAMPLE_WPS_PIN_VALUE CONFIG_EXAMPLE_WPS_PIN_VALUE
|
||||
#endif
|
||||
#define WPS_MODE WPS_TYPE_PIN
|
||||
#else
|
||||
#define WPS_MODE WPS_TYPE_DISABLE
|
||||
#endif /*CONFIG_EXAMPLE_WPS_TYPE_PBC*/
|
||||
|
||||
|
||||
#ifndef PIN2STR
|
||||
#define PIN2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
|
||||
#define PINSTR "%c%c%c%c%c%c%c%c"
|
||||
#endif
|
||||
|
||||
#define EXAMPLE_ESP_WIFI_SSID CONFIG_EXAMPLE_WIFI_SSID
|
||||
#define EXAMPLE_ESP_WIFI_PASS CONFIG_EXAMPLE_WIFI_PASSWORD
|
||||
#define EXAMPLE_ESP_WIFI_CHANNEL CONFIG_EXAMPLE_WIFI_CHANNEL
|
||||
#define EXAMPLE_MAX_STA_CONN CONFIG_EXAMPLE_MAX_STA_CONN
|
||||
|
||||
static const char *TAG = "example_wps_registrar";
|
||||
static esp_wps_config_t config = WPS_CONFIG_INIT_DEFAULT(WPS_MODE);
|
||||
|
||||
static unsigned char pin[9];
|
||||
|
||||
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
switch (event_id) {
|
||||
case WIFI_EVENT_AP_START:
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_AP_START");
|
||||
break;
|
||||
case WIFI_EVENT_AP_STADISCONNECTED:
|
||||
{
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_AP_STADISCONNECTED");
|
||||
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
|
||||
ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
|
||||
MAC2STR(event->mac), event->aid);
|
||||
}
|
||||
break;
|
||||
case WIFI_EVENT_AP_STACONNECTED:
|
||||
{
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_AP_STACONNECTED");
|
||||
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
|
||||
ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
|
||||
MAC2STR(event->mac), event->aid);
|
||||
}
|
||||
break;
|
||||
case WIFI_EVENT_AP_WPS_RG_SUCCESS:
|
||||
{
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_AP_WPS_RG_SUCCESS");
|
||||
wifi_event_ap_wps_rg_success_t *evt = (wifi_event_ap_wps_rg_success_t *)event_data;
|
||||
ESP_LOGI(TAG, "station "MACSTR" WPS successful",
|
||||
MAC2STR(evt->peer_macaddr));
|
||||
}
|
||||
break;
|
||||
case WIFI_EVENT_AP_WPS_RG_FAILED:
|
||||
{
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_AP_WPS_RG_FAILED");
|
||||
wifi_event_ap_wps_rg_fail_reason_t *evt = (wifi_event_ap_wps_rg_fail_reason_t *)event_data;
|
||||
ESP_LOGI(TAG, "station "MACSTR" WPS failed, reason=%d",
|
||||
MAC2STR(evt->peer_macaddr), evt->reason);
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_disable());
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_enable(&config));
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_start(pin));
|
||||
}
|
||||
break;
|
||||
case WIFI_EVENT_AP_WPS_RG_TIMEOUT:
|
||||
{
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_AP_WPS_RG_TIMEOUT");
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_disable());
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_enable(&config));
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_start(pin));
|
||||
}
|
||||
break;
|
||||
case WIFI_EVENT_AP_WPS_RG_PIN:
|
||||
{
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_AP_WPS_RG_PIN");
|
||||
/* display the PIN code */
|
||||
wifi_event_ap_wps_rg_pin_t* event = (wifi_event_ap_wps_rg_pin_t *) event_data;
|
||||
ESP_LOGI(TAG, "WPS_PIN = " PINSTR, PIN2STR(event->pin_code));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*init wifi as sta and start wps*/
|
||||
static void start_wps_registrar(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
esp_netif_create_default_wifi_ap();
|
||||
|
||||
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, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
|
||||
|
||||
wifi_config_t wifi_config = {
|
||||
.ap = {
|
||||
.ssid = EXAMPLE_ESP_WIFI_SSID,
|
||||
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
|
||||
.channel = EXAMPLE_ESP_WIFI_CHANNEL,
|
||||
.password = EXAMPLE_ESP_WIFI_PASS,
|
||||
.max_connection = EXAMPLE_MAX_STA_CONN,
|
||||
.authmode = WIFI_AUTH_WPA2_PSK,
|
||||
.pmf_cfg = {
|
||||
.required = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
|
||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
|
||||
ESP_LOGI(TAG, "start wps...");
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_enable(&config));
|
||||
#if EXAMPLE_WPS_PIN_VALUE
|
||||
ESP_LOGI(TAG, "Staring WPS registrar with user specified pin %s", pin);
|
||||
snprintf((char *)pin, 9, "%08d", EXAMPLE_WPS_PIN_VALUE);
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_start(pin));
|
||||
#else
|
||||
if (config.wps_type == WPS_TYPE_PBC) {
|
||||
ESP_LOGI(TAG, "Staring WPS registrar in PBC mode");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Staring WPS registrar with random generated pin");
|
||||
}
|
||||
ESP_ERROR_CHECK(esp_wifi_ap_wps_start(NULL));
|
||||
#endif
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/* Initialize NVS — it is used to store PHY calibration data */
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK( ret );
|
||||
|
||||
start_wps_registrar();
|
||||
}
|
2
examples/wifi/wps_softap_registrar/sdkconfig.defaults
Normal file
2
examples/wifi/wps_softap_registrar/sdkconfig.defaults
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y
|
||||
CONFIG_WPA_WPS_SOFTAP_REGISTRAR=y
|
Loading…
Reference in New Issue
Block a user