mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 18:57:19 +02:00
Merge branch 'bugfix/wps_crash_issue_v5.2' into 'release/v5.2'
fix(wpa_supplicant): Avoid dereferencing a dangling function pointer in WPS (Backport v5.2) See merge request espressif/esp-idf!29735
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -26,12 +26,15 @@
|
|||||||
#include "ap/hostapd.h"
|
#include "ap/hostapd.h"
|
||||||
#include "ap/ap_config.h"
|
#include "ap/ap_config.h"
|
||||||
#include "ap/wps_hostapd.h"
|
#include "ap/wps_hostapd.h"
|
||||||
|
#include "utils/eloop.h"
|
||||||
|
|
||||||
extern struct wps_sm *gWpsSm;
|
extern struct wps_sm *gWpsSm;
|
||||||
extern void *s_wps_api_lock;
|
extern void *s_wps_api_lock;
|
||||||
extern void *s_wps_api_sem;
|
extern void *s_wps_api_sem;
|
||||||
extern bool s_wps_enabled;
|
extern bool s_wps_enabled;
|
||||||
|
|
||||||
|
static int wps_reg_eloop_post_block(uint32_t sig, void *arg);
|
||||||
|
|
||||||
static int wifi_ap_wps_init(const esp_wps_config_t *config)
|
static int wifi_ap_wps_init(const esp_wps_config_t *config)
|
||||||
{
|
{
|
||||||
struct wps_sm *sm = NULL;
|
struct wps_sm *sm = NULL;
|
||||||
@ -138,41 +141,8 @@ int wifi_ap_wps_deinit(void)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wifi_ap_wps_enable_internal(const esp_wps_config_t *config)
|
static int wifi_ap_wps_enable_internal(const esp_wps_config_t *config)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "ESP WPS crypto initialize!");
|
|
||||||
if (config->wps_type == WPS_TYPE_DISABLE) {
|
|
||||||
wpa_printf(MSG_ERROR, "wps enable: invalid wps type");
|
|
||||||
return ESP_ERR_WIFI_WPS_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "Set factory information.");
|
|
||||||
ret = wps_set_factory_info(config);
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
wpa_printf(MSG_INFO, "wifi_wps_enable");
|
|
||||||
|
|
||||||
wps_set_type(config->wps_type);
|
|
||||||
wps_set_status(WPS_STATUS_DISABLE);
|
|
||||||
|
|
||||||
ret = wifi_ap_wps_init(config);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
wps_set_type(WPS_STATUS_DISABLE);
|
|
||||||
wps_set_status(WPS_STATUS_DISABLE);
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int esp_wifi_ap_wps_enable(const esp_wps_config_t *config)
|
|
||||||
{
|
|
||||||
int ret = ESP_OK;
|
|
||||||
struct wps_sm *sm = gWpsSm;
|
struct wps_sm *sm = gWpsSm;
|
||||||
wifi_mode_t mode = WIFI_MODE_NULL;
|
wifi_mode_t mode = WIFI_MODE_NULL;
|
||||||
|
|
||||||
@ -181,7 +151,11 @@ int esp_wifi_ap_wps_enable(const esp_wps_config_t *config)
|
|||||||
return ESP_ERR_WIFI_STATE;
|
return ESP_ERR_WIFI_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = esp_wifi_get_mode(&mode);
|
if (esp_wifi_get_mode(&mode) != ESP_OK) {
|
||||||
|
wpa_printf(MSG_ERROR, "wps enable: unable to get current wifi mode");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode != WIFI_MODE_AP && mode != WIFI_MODE_APSTA) {
|
if (mode != WIFI_MODE_AP && mode != WIFI_MODE_APSTA) {
|
||||||
wpa_printf(MSG_ERROR, "wps enable: mode=%d does not include AP", mode);
|
wpa_printf(MSG_ERROR, "wps enable: mode=%d does not include AP", mode);
|
||||||
return ESP_ERR_WIFI_MODE;
|
return ESP_ERR_WIFI_MODE;
|
||||||
@ -192,58 +166,106 @@ int esp_wifi_ap_wps_enable(const esp_wps_config_t *config)
|
|||||||
return ESP_ERR_WIFI_MODE;
|
return ESP_ERR_WIFI_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
API_MUTEX_TAKE();
|
|
||||||
if (s_wps_enabled) {
|
if (s_wps_enabled) {
|
||||||
if (sm && os_memcmp(sm->identity, WSC_ID_ENROLLEE, sm->identity_len) == 0) {
|
if (sm && os_memcmp(sm->identity, WSC_ID_ENROLLEE, sm->identity_len) == 0) {
|
||||||
wpa_printf(MSG_ERROR, "wps enable: wps enrollee already enabled cannot enable wpsreg");
|
wpa_printf(MSG_ERROR, "wps enable: wps enrollee already enabled cannot enable wpsreg");
|
||||||
ret = ESP_ERR_WIFI_MODE;
|
return ESP_ERR_WIFI_MODE;
|
||||||
} else {
|
} else {
|
||||||
wpa_printf(MSG_DEBUG, "wps enable: already enabled");
|
wpa_printf(MSG_DEBUG, "wps enable: already enabled");
|
||||||
ret = ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
API_MUTEX_GIVE();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wifi_ap_wps_enable_internal(config);
|
if (config->wps_type == WPS_TYPE_DISABLE) {
|
||||||
|
wpa_printf(MSG_ERROR, "wps enable: invalid wps type");
|
||||||
|
return ESP_ERR_WIFI_WPS_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "Set factory information.");
|
||||||
|
if (wps_set_factory_info(config) != ESP_OK) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (wps_set_type(config->wps_type) != ESP_OK) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wps_set_status(WPS_STATUS_DISABLE) != ESP_OK) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wifi_ap_wps_init(config) != ESP_OK) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO, "wifi_wps_enable");
|
||||||
s_wps_enabled = true;
|
s_wps_enabled = true;
|
||||||
|
return ESP_OK;
|
||||||
|
|
||||||
|
_err:
|
||||||
|
wpa_printf(MSG_ERROR, "failure in wifi_wps_enable");
|
||||||
|
wps_set_type(WPS_TYPE_DISABLE);
|
||||||
|
wps_set_status(WPS_STATUS_DISABLE);
|
||||||
|
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int esp_wifi_ap_wps_enable(const esp_wps_config_t *config)
|
||||||
|
{
|
||||||
|
int ret = ESP_OK;
|
||||||
|
|
||||||
|
API_MUTEX_TAKE();
|
||||||
|
ret = wps_reg_eloop_post_block(SIG_WPS_REG_ENABLE, (void *) config);
|
||||||
API_MUTEX_GIVE();
|
API_MUTEX_GIVE();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int esp_wifi_ap_wps_disable(void)
|
static int wifi_ap_wps_disable_internal(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
struct wps_sm *sm = gWpsSm;
|
struct wps_sm *sm = gWpsSm;
|
||||||
|
|
||||||
if (sm && os_memcmp(sm->identity, WSC_ID_ENROLLEE, sm->identity_len) == 0) {
|
if (sm && os_memcmp(sm->identity, WSC_ID_ENROLLEE, sm->identity_len) == 0) {
|
||||||
return ESP_ERR_WIFI_MODE;
|
return ESP_ERR_WIFI_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
API_MUTEX_TAKE();
|
|
||||||
|
|
||||||
if (!s_wps_enabled) {
|
if (!s_wps_enabled) {
|
||||||
wpa_printf(MSG_DEBUG, "wps disable: already disabled");
|
wpa_printf(MSG_DEBUG, "wps disable: already disabled");
|
||||||
API_MUTEX_GIVE();
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_INFO, "wifi_wps_disable");
|
wpa_printf(MSG_INFO, "wifi_wps_disable");
|
||||||
wps_set_type(WPS_TYPE_DISABLE);
|
if (wps_set_type(WPS_TYPE_DISABLE) != ESP_OK) {
|
||||||
wps_set_status(WPS_STATUS_DISABLE);
|
goto _err;
|
||||||
|
|
||||||
wifi_ap_wps_deinit();
|
|
||||||
|
|
||||||
if (ESP_OK != ret) {
|
|
||||||
wpa_printf(MSG_ERROR, "wps disable: failed to disable wps, ret=%d", ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wps_set_status(WPS_STATUS_DISABLE) != ESP_OK) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wifi_ap_wps_deinit() != ESP_OK) {
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
s_wps_enabled = false;
|
s_wps_enabled = false;
|
||||||
API_MUTEX_GIVE();
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
||||||
|
_err:
|
||||||
|
wpa_printf(MSG_ERROR, "wps disable: failed to disable wps");
|
||||||
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int esp_wifi_ap_wps_start(const unsigned char *pin)
|
int esp_wifi_ap_wps_disable(void)
|
||||||
|
{
|
||||||
|
int ret = ESP_FAIL;
|
||||||
|
API_MUTEX_TAKE();
|
||||||
|
ret = wps_reg_eloop_post_block(SIG_WPS_REG_DISABLE, NULL);
|
||||||
|
API_MUTEX_GIVE();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wifi_ap_wps_start_internal(const unsigned char *pin)
|
||||||
{
|
{
|
||||||
wifi_mode_t mode = WIFI_MODE_NULL;
|
wifi_mode_t mode = WIFI_MODE_NULL;
|
||||||
|
|
||||||
@ -253,7 +275,6 @@ int esp_wifi_ap_wps_start(const unsigned char *pin)
|
|||||||
return ESP_ERR_WIFI_MODE;
|
return ESP_ERR_WIFI_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
API_MUTEX_TAKE();
|
|
||||||
|
|
||||||
if (!s_wps_enabled) {
|
if (!s_wps_enabled) {
|
||||||
wpa_printf(MSG_ERROR, "wps start: wps not enabled");
|
wpa_printf(MSG_ERROR, "wps start: wps not enabled");
|
||||||
@ -261,29 +282,100 @@ int esp_wifi_ap_wps_start(const unsigned char *pin)
|
|||||||
return ESP_ERR_WIFI_WPS_SM;
|
return ESP_ERR_WIFI_WPS_SM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wps_get_type() == WPS_TYPE_DISABLE || (wps_get_status() != WPS_STATUS_DISABLE && wps_get_status() != WPS_STATUS_SCANNING)) {
|
if (wps_get_type() == WPS_TYPE_DISABLE ||
|
||||||
wpa_printf(MSG_ERROR, "wps start: wps_get_type=%d wps_get_status=%d", wps_get_type(), wps_get_status());
|
(wps_get_status() != WPS_STATUS_DISABLE &&
|
||||||
API_MUTEX_GIVE();
|
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());
|
||||||
return ESP_ERR_WIFI_WPS_TYPE;
|
return ESP_ERR_WIFI_WPS_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_wifi_get_user_init_flag_internal() == 0) {
|
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());
|
wpa_printf(MSG_ERROR, "wps start: esp_wifi_get_user_init_flag_internal=%d",
|
||||||
API_MUTEX_GIVE();
|
esp_wifi_get_user_init_flag_internal());
|
||||||
return ESP_ERR_WIFI_STATE;
|
return ESP_ERR_WIFI_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pin) {
|
if (!pin) {
|
||||||
pin = gWpsSm->wps->dev_password;
|
pin = gWpsSm->wps->dev_password;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO ideally SoftAP mode should also do a single scan in PBC mode
|
/* TODO ideally SoftAP mode should also do a single scan in PBC mode
|
||||||
* however softAP scanning is not available at the moment */
|
* however softAP scanning is not available at the moment */
|
||||||
wps_set_status(WPS_STATUS_PENDING);
|
if (wps_set_status(WPS_STATUS_PENDING) != ESP_OK) {
|
||||||
if (wps_get_type() == WPS_TYPE_PBC) {
|
return ESP_FAIL;
|
||||||
hostapd_wps_button_pushed(hostapd_get_hapd_data(), NULL);
|
}
|
||||||
} else if (wps_get_type() == WPS_TYPE_PIN) {
|
if (wps_get_type() == WPS_TYPE_PBC) {
|
||||||
hostapd_wps_add_pin(hostapd_get_hapd_data(), pin);
|
if (hostapd_wps_button_pushed(hostapd_get_hapd_data(), NULL) != ESP_OK) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
} else if (wps_get_type() == WPS_TYPE_PIN) {
|
||||||
|
if (hostapd_wps_add_pin(hostapd_get_hapd_data(), pin) != ESP_OK) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
API_MUTEX_GIVE();
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int esp_wifi_ap_wps_start(const unsigned char *pin)
|
||||||
|
{
|
||||||
|
int ret = ESP_FAIL;
|
||||||
|
API_MUTEX_TAKE();
|
||||||
|
ret = wps_reg_eloop_post_block(SIG_WPS_REG_START, (void *)pin);
|
||||||
|
API_MUTEX_GIVE();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wps_reg_eloop_handler(void *eloop_ctx, void *user_ctx)
|
||||||
|
{
|
||||||
|
int ret = ESP_FAIL;
|
||||||
|
enum wps_reg_sig_type *sig = (enum wps_reg_sig_type *) eloop_ctx;
|
||||||
|
wps_ioctl_param_t *param = (wps_ioctl_param_t *) user_ctx;
|
||||||
|
|
||||||
|
switch(*sig) {
|
||||||
|
case SIG_WPS_REG_ENABLE:
|
||||||
|
esp_wps_config_t *config = (esp_wps_config_t *)param->arg;
|
||||||
|
ret = wifi_ap_wps_enable_internal(config);
|
||||||
|
break;
|
||||||
|
case SIG_WPS_REG_START:
|
||||||
|
unsigned char *pin = (unsigned char *)param->arg;
|
||||||
|
ret = wifi_ap_wps_start_internal((const unsigned char *)pin);
|
||||||
|
break;
|
||||||
|
case SIG_WPS_REG_DISABLE:
|
||||||
|
ret = wifi_ap_wps_disable_internal();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wpa_printf(MSG_WARNING, "%s(): invalid signal type=%d", __func__, *sig);
|
||||||
|
ret = ESP_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
param->ret = ret;
|
||||||
|
os_semphr_give(s_wps_api_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wps_reg_eloop_post_block(uint32_t sig, void *arg)
|
||||||
|
{
|
||||||
|
int ret = ESP_FAIL;
|
||||||
|
wps_ioctl_param_t param;
|
||||||
|
param.ret = ESP_FAIL;
|
||||||
|
param.arg = arg;
|
||||||
|
|
||||||
|
if (s_wps_api_sem == NULL) {
|
||||||
|
s_wps_api_sem = os_semphr_create(1, 0);
|
||||||
|
if (s_wps_api_sem == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "%s(): failed to create WPA API semaphore", __func__);
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eloop_register_timeout(0, 0, wps_reg_eloop_handler, (void *)&sig, (void *)¶m);
|
||||||
|
|
||||||
|
if (TRUE == os_semphr_take(s_wps_api_sem, OS_BLOCK)) {
|
||||||
|
ret = param.ret;
|
||||||
|
} else {
|
||||||
|
ret = ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -33,8 +33,8 @@
|
|||||||
|
|
||||||
const char *wps_model_number = CONFIG_IDF_TARGET;
|
const char *wps_model_number = CONFIG_IDF_TARGET;
|
||||||
|
|
||||||
void *s_wps_api_lock = NULL; /* Used in WPS public API only, never be freed */
|
void *s_wps_api_lock = NULL; /* Used in WPS/WPS-REG public API only, never be freed */
|
||||||
void *s_wps_api_sem = NULL; /* Sync semaphore used between WPS publi API caller task and WPS task */
|
void *s_wps_api_sem = NULL; /* Sync semaphore used between WPS/WPS-REG public API caller task and WPS task, never be freed */
|
||||||
bool s_wps_enabled = false;
|
bool s_wps_enabled = false;
|
||||||
#ifdef USE_WPS_TASK
|
#ifdef USE_WPS_TASK
|
||||||
struct wps_rx_param {
|
struct wps_rx_param {
|
||||||
@ -45,11 +45,6 @@ struct wps_rx_param {
|
|||||||
};
|
};
|
||||||
static STAILQ_HEAD(,wps_rx_param) s_wps_rxq;
|
static STAILQ_HEAD(,wps_rx_param) s_wps_rxq;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void *arg;
|
|
||||||
int ret; /* return value */
|
|
||||||
} wps_ioctl_param_t;
|
|
||||||
|
|
||||||
static void *s_wps_task_hdl = NULL;
|
static void *s_wps_task_hdl = NULL;
|
||||||
static void *s_wps_queue = NULL;
|
static void *s_wps_queue = NULL;
|
||||||
static void *s_wps_data_lock = NULL;
|
static void *s_wps_data_lock = NULL;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -27,6 +27,19 @@ enum wps_sig_type {
|
|||||||
SIG_WPS_NUM, //10
|
SIG_WPS_NUM, //10
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum wps_reg_sig_type {
|
||||||
|
SIG_WPS_REG_ENABLE = 1, //1
|
||||||
|
SIG_WPS_REG_DISABLE, //2
|
||||||
|
SIG_WPS_REG_START, //3
|
||||||
|
SIG_WPS_REG_MAX, //4
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *arg;
|
||||||
|
int ret; /* return value */
|
||||||
|
} wps_ioctl_param_t;
|
||||||
|
|
||||||
#ifdef ESP_SUPPLICANT
|
#ifdef ESP_SUPPLICANT
|
||||||
enum wps_sm_state{
|
enum wps_sm_state{
|
||||||
WAIT_START,
|
WAIT_START,
|
||||||
|
@ -321,6 +321,14 @@ fail:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESP_SUPPLICANT
|
||||||
|
static int ap_sta_server_sm_deinit(struct hostapd_data *hapd,
|
||||||
|
struct sta_info *sta, void *ctx)
|
||||||
|
{
|
||||||
|
ieee802_1x_free_station(hapd, sta);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* ESP_SUPPLICANT */
|
||||||
|
|
||||||
void hostapd_deinit_wps(struct hostapd_data *hapd)
|
void hostapd_deinit_wps(struct hostapd_data *hapd)
|
||||||
{
|
{
|
||||||
@ -332,6 +340,11 @@ void hostapd_deinit_wps(struct hostapd_data *hapd)
|
|||||||
}
|
}
|
||||||
wps_registrar_deinit(hapd->wps->registrar);
|
wps_registrar_deinit(hapd->wps->registrar);
|
||||||
hapd->wps->registrar = NULL;
|
hapd->wps->registrar = NULL;
|
||||||
|
|
||||||
|
#ifdef ESP_SUPPLICANT
|
||||||
|
ap_for_each_sta(hapd, ap_sta_server_sm_deinit, NULL);
|
||||||
|
#endif /* ESP_SUPPLICANT */
|
||||||
|
|
||||||
eap_server_unregister_methods();
|
eap_server_unregister_methods();
|
||||||
hapd->wps = NULL;
|
hapd->wps = NULL;
|
||||||
hostapd_wps_clear_ies(hapd, 1);
|
hostapd_wps_clear_ies(hapd, 1);
|
||||||
|
Reference in New Issue
Block a user