mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(nan): fix NAN pairing NIK/NIRA exchange and verification
Register esp_nan_verify_nira, cache NIRA for publish frames, send own_nik in pairing follow-up, and complete pairing only after peer NIK is stored.
This commit is contained in:
@@ -195,6 +195,7 @@ struct nan_sync_callbacks {
|
||||
void (* receive_pasn)(uint8_t *buf, size_t len, uint16_t trans_seq, uint16_t status);
|
||||
uint32_t (* get_nira_len)(void);
|
||||
int (* construct_nira)(uint8_t *frm);
|
||||
bool (*verify_nira)(uint8_t *peer_mac, uint8_t *nira_attr, uint16_t nira_attr_len);
|
||||
};
|
||||
|
||||
/* Host helpers for NAN encrypted-datapath, registered via
|
||||
@@ -1197,6 +1198,17 @@ uint32_t esp_nan_get_nira_len(void);
|
||||
*/
|
||||
int esp_nan_construct_nira(uint8_t *frm);
|
||||
|
||||
/**
|
||||
* @brief Verify a received NAN Identity Resolution Attribute (NIRA)
|
||||
*
|
||||
* @param[in] peer_mac NMI of the sender
|
||||
* @param[in] nira_attr NIRA attribute buffer
|
||||
* @param[in] nira_attr_len Attribute length in bytes
|
||||
*
|
||||
* @return true if the tag matches, false otherwise
|
||||
*/
|
||||
bool esp_nan_verify_nira(uint8_t *peer_mac, uint8_t *nira_attr, uint16_t nira_attr_len);
|
||||
|
||||
/**
|
||||
* @brief Get the time information from the MAC clock. The time is precise only if modem sleep or light sleep is not enabled.
|
||||
*
|
||||
|
||||
@@ -1580,8 +1580,8 @@ typedef struct {
|
||||
} wifi_event_nan_replied_t;
|
||||
|
||||
/**
|
||||
* @brief Argument structure for WIFI_EVENT_NAN_CLUSTER_JOIN event
|
||||
*/
|
||||
* @brief Argument structure for WIFI_EVENT_NAN_CLUSTER_JOIN event
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t cluster_id[6]; /**< Cluster ID (BSSID) that was joined/started */
|
||||
} wifi_event_nan_cluster_join_t;
|
||||
|
||||
@@ -1580,8 +1580,8 @@ typedef struct {
|
||||
} wifi_event_nan_replied_t;
|
||||
|
||||
/**
|
||||
* @brief Argument structure for WIFI_EVENT_NAN_CLUSTER_JOIN event
|
||||
*/
|
||||
* @brief Argument structure for WIFI_EVENT_NAN_CLUSTER_JOIN event
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t cluster_id[6]; /**< Cluster ID (BSSID) that was joined/started */
|
||||
} wifi_event_nan_cluster_join_t;
|
||||
|
||||
@@ -59,6 +59,14 @@ int esp_nan_construct_nira(uint8_t *frm)
|
||||
(void)frm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool esp_nan_verify_nira(uint8_t *peer_mac, uint8_t *nira_attr, uint16_t nira_attr_len)
|
||||
{
|
||||
(void)peer_mac;
|
||||
(void)nira_attr;
|
||||
(void)nira_attr_len;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ESP_WIFI_NAN_SYNC_ENABLE) && defined(CONFIG_ESP_WIFI_PASN_SUPPORT)
|
||||
@@ -1435,6 +1443,7 @@ void esp_nan_action_start(esp_netif_t *nan_netif)
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_PAIRING
|
||||
.get_nira_len = esp_nan_get_nira_len,
|
||||
.construct_nira = esp_nan_construct_nira,
|
||||
.verify_nira = esp_nan_verify_nira,
|
||||
.receive_pasn = handle_auth_pasn,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -287,9 +287,11 @@ typedef struct {
|
||||
struct own_svc_info own_svc[ESP_WIFI_NAN_MAX_SVC_SUPPORTED];
|
||||
esp_netif_t *nan_netif;
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SECURITY
|
||||
/* Own NAN Identity Key (NIK) cached for pairing/security flows. */
|
||||
uint8_t own_nik[ESP_WIFI_NAN_NIK_LEN];
|
||||
bool own_nik_valid;
|
||||
uint8_t cached_nira_nonce[8];
|
||||
uint8_t cached_nira_tag[8];
|
||||
bool cached_nira_valid;
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_WIFI_PASN_SUPPORT
|
||||
struct nan_pasn_data *nan_pasn_data;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "nan_i.h"
|
||||
#include "os.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
|
||||
#if defined(CONFIG_ESP_WIFI_PASN_SUPPORT)
|
||||
#include "esp_private/esp_supp_nan.h"
|
||||
@@ -49,42 +50,7 @@ static void nan_pairing_key_installed_cb(const uint8_t *peer_nmi,
|
||||
uint8_t role,
|
||||
uint8_t ndp_csid,
|
||||
const uint8_t *nd_pmk,
|
||||
size_t nd_pmk_len)
|
||||
{
|
||||
wifi_event_nan_pairing_complete_t evt = {0};
|
||||
|
||||
if (!peer_nmi) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ESP_WIFI_NAN_SECURITY)
|
||||
/* Cache ND-PMK for future paired NDPs (Wi-Fi Aware v4.0 §7.6.4.2). The
|
||||
* NDP cipher (CSID) is determined by the PASN cipher and resolved on the
|
||||
* supplicant side before this callback fires; if either is missing, the
|
||||
* pairing event still fires but the security layer will fall back to its
|
||||
* service-credential path for any subsequent NDP. */
|
||||
if (ndp_csid && nd_pmk && nd_pmk_len == ESP_WIFI_NAN_NDP_PMK_LEN) {
|
||||
(void)nan_app_register_paired_peer(peer_nmi, role, ndp_csid,
|
||||
nd_pmk, nd_pmk_len,
|
||||
NAN_PAIRING_DEFAULT_NIK_LIFETIME_SEC);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Pairing complete for " MACSTR
|
||||
": ND-PMK unavailable (csid=%u nd_pmk_len=%u); "
|
||||
"paired-peer cache not updated",
|
||||
MAC2STR(peer_nmi), ndp_csid, (unsigned)nd_pmk_len);
|
||||
}
|
||||
#else
|
||||
(void)role;
|
||||
(void)ndp_csid;
|
||||
(void)nd_pmk;
|
||||
(void)nd_pmk_len;
|
||||
#endif
|
||||
|
||||
evt.status = WIFI_NAN_PAIRING_STATUS_ACCEPTED;
|
||||
evt.reason_code = 0;
|
||||
MACADDR_COPY(evt.peer_nmi, peer_nmi);
|
||||
nan_app_post_event(WIFI_EVENT_NAN_PAIRING_CONFIRM, &evt, sizeof(evt));
|
||||
}
|
||||
size_t nd_pmk_len);
|
||||
#endif
|
||||
|
||||
bool nan_pairing_validate_publish_bootstrapping(uint16_t bootstrapping_methods)
|
||||
@@ -334,53 +300,66 @@ uint32_t esp_nan_get_nira_len(void)
|
||||
|
||||
int esp_nan_construct_nira(uint8_t *frm)
|
||||
{
|
||||
uint8_t nonce[NAN_NIRA_NONCE_LEN];
|
||||
uint8_t tag[NAN_NIRA_TAG_LEN];
|
||||
const uint8_t *nonce;
|
||||
const uint8_t *tag;
|
||||
uint8_t fresh_nonce[NAN_NIRA_NONCE_LEN];
|
||||
uint8_t fresh_tag[NAN_NIRA_TAG_LEN];
|
||||
|
||||
if (!frm) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (os_get_random(nonce, sizeof(nonce)) != 0) {
|
||||
ESP_LOGE(TAG, "NIRA: failed to generate nonce");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SECURITY
|
||||
uint8_t own_nmi[MACADDR_LEN];
|
||||
const unsigned char *addr[3];
|
||||
int len_arr[3];
|
||||
uint8_t digest[32];
|
||||
if (s_nan_ctx.cached_nira_valid) {
|
||||
nonce = s_nan_ctx.cached_nira_nonce;
|
||||
tag = s_nan_ctx.cached_nira_tag;
|
||||
} else {
|
||||
uint8_t own_nmi[MACADDR_LEN];
|
||||
const unsigned char *addr[3];
|
||||
int len_arr[3];
|
||||
uint8_t digest[32];
|
||||
|
||||
if (!s_nan_ctx.own_nik_valid) {
|
||||
ESP_LOGW(TAG, "NIRA: own NIK is not available");
|
||||
return 0;
|
||||
}
|
||||
if (!g_wifi_default_wpa_crypto_funcs.hmac_sha256_vector) {
|
||||
ESP_LOGE(TAG, "NIRA: hmac_sha256_vector not registered");
|
||||
return 0;
|
||||
}
|
||||
if (esp_wifi_get_mac(WIFI_IF_NAN, own_nmi) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "NIRA: failed to read NAN NMI");
|
||||
return 0;
|
||||
}
|
||||
if (!s_nan_ctx.own_nik_valid) {
|
||||
ESP_LOGW(TAG, "NIRA: own NIK is not available");
|
||||
return 0;
|
||||
}
|
||||
if (!g_wifi_default_wpa_crypto_funcs.hmac_sha256_vector) {
|
||||
ESP_LOGE(TAG, "NIRA: hmac_sha256_vector not registered");
|
||||
return 0;
|
||||
}
|
||||
if (esp_wifi_get_mac(WIFI_IF_NAN, own_nmi) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "NIRA: failed to read NAN NMI");
|
||||
return 0;
|
||||
}
|
||||
if (os_get_random(fresh_nonce, sizeof(fresh_nonce)) != 0) {
|
||||
ESP_LOGE(TAG, "NIRA: failed to generate nonce");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Tag = Truncate-64(HMAC-SHA-256(NIK, "NIR" || NMI || Nonce)) */
|
||||
addr[0] = (const unsigned char *)NAN_NIRA_STR;
|
||||
len_arr[0] = NAN_NIRA_STR_LEN;
|
||||
addr[1] = own_nmi;
|
||||
len_arr[1] = MACADDR_LEN;
|
||||
addr[2] = nonce;
|
||||
len_arr[2] = NAN_NIRA_NONCE_LEN;
|
||||
if (g_wifi_default_wpa_crypto_funcs.hmac_sha256_vector(s_nan_ctx.own_nik,
|
||||
ESP_WIFI_NAN_NIK_LEN,
|
||||
3, addr, len_arr,
|
||||
digest) != 0) {
|
||||
ESP_LOGE(TAG, "NIRA: tag derivation failed");
|
||||
return 0;
|
||||
/* Tag = Truncate-64(HMAC-SHA-256(NIK, "NIR" || NMI || Nonce)) */
|
||||
addr[0] = (const unsigned char *)NAN_NIRA_STR;
|
||||
len_arr[0] = NAN_NIRA_STR_LEN;
|
||||
addr[1] = own_nmi;
|
||||
len_arr[1] = MACADDR_LEN;
|
||||
addr[2] = fresh_nonce;
|
||||
len_arr[2] = NAN_NIRA_NONCE_LEN;
|
||||
if (g_wifi_default_wpa_crypto_funcs.hmac_sha256_vector(s_nan_ctx.own_nik,
|
||||
ESP_WIFI_NAN_NIK_LEN,
|
||||
3, addr, len_arr,
|
||||
digest) != 0) {
|
||||
ESP_LOGE(TAG, "NIRA: tag derivation failed");
|
||||
return 0;
|
||||
}
|
||||
memcpy(fresh_tag, digest, NAN_NIRA_TAG_LEN);
|
||||
memset(digest, 0, sizeof(digest));
|
||||
|
||||
memcpy(s_nan_ctx.cached_nira_nonce, fresh_nonce, NAN_NIRA_NONCE_LEN);
|
||||
memcpy(s_nan_ctx.cached_nira_tag, fresh_tag, NAN_NIRA_TAG_LEN);
|
||||
s_nan_ctx.cached_nira_valid = true;
|
||||
|
||||
nonce = fresh_nonce;
|
||||
tag = fresh_tag;
|
||||
}
|
||||
memcpy(tag, digest, NAN_NIRA_TAG_LEN);
|
||||
memset(digest, 0, sizeof(digest));
|
||||
#else
|
||||
/* NIRA requires an available NIK; skip when NAN security is not enabled. */
|
||||
return 0;
|
||||
@@ -403,7 +382,6 @@ int esp_nan_construct_nira(uint8_t *frm)
|
||||
#if defined(CONFIG_ESP_WIFI_NAN_PAIRING) && defined(CONFIG_ESP_WIFI_PASN_SUPPORT) && defined(CONFIG_ESP_WIFI_NAN_SECURITY)
|
||||
|
||||
#include "crypto/sha256.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/wpa_common.h"
|
||||
@@ -680,9 +658,14 @@ static esp_err_t nan_app_send_pairing_followup(uint8_t svc_id, uint8_t peer_svc_
|
||||
(void)shared_key_attr;
|
||||
(void)shared_key_attr_len;
|
||||
|
||||
if (!peer_mac || os_get_random(nik, sizeof(nik)) != 0) {
|
||||
if (!peer_mac) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!s_nan_ctx.own_nik_valid) {
|
||||
ESP_LOGW(TAG, "Pairing follow-up: own NIK is not available");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
memcpy(nik, s_nan_ctx.own_nik, sizeof(nik));
|
||||
|
||||
saved = nan_pasn_get_saved_keys();
|
||||
if (!saved || !saved->kek_len) {
|
||||
@@ -773,6 +756,7 @@ static void nan_app_send_pairing_followup_eloop(void *eloop_data, void *user_dat
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
(void) nan_app_send_pairing_followup(ctx->svc_id, ctx->peer_svc_id,
|
||||
ctx->peer_mac,
|
||||
ctx->shared_key_attr,
|
||||
@@ -780,6 +764,62 @@ static void nan_app_send_pairing_followup_eloop(void *eloop_data, void *user_dat
|
||||
os_free(ctx);
|
||||
}
|
||||
|
||||
static void nan_pairing_key_installed_cb(const uint8_t *peer_nmi,
|
||||
uint8_t role,
|
||||
uint8_t ndp_csid,
|
||||
const uint8_t *nd_pmk,
|
||||
size_t nd_pmk_len)
|
||||
{
|
||||
if (!peer_nmi) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ESP_WIFI_NAN_SECURITY)
|
||||
/* Cache ND-PMK for future paired NDPs (Wi-Fi Aware v4.0 §7.6.4.2). */
|
||||
if (ndp_csid && nd_pmk && nd_pmk_len == ESP_WIFI_NAN_NDP_PMK_LEN) {
|
||||
(void)nan_app_register_paired_peer(peer_nmi, role, ndp_csid,
|
||||
nd_pmk, nd_pmk_len,
|
||||
NAN_PAIRING_DEFAULT_NIK_LIFETIME_SEC);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Pairing complete for " MACSTR
|
||||
": ND-PMK unavailable (csid=%u nd_pmk_len=%u); "
|
||||
"paired-peer cache not updated",
|
||||
MAC2STR(peer_nmi), ndp_csid, (unsigned)nd_pmk_len);
|
||||
}
|
||||
#else
|
||||
(void)ndp_csid;
|
||||
(void)nd_pmk;
|
||||
(void)nd_pmk_len;
|
||||
#endif
|
||||
|
||||
if (role == NAN_ROLE_PAIRING_INITIATOR) {
|
||||
struct nan_pairing_fup_ctx *ctx = os_zalloc(sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
ESP_LOGW(TAG, "Pairing key installed: failed to alloc fup ctx for " MACSTR,
|
||||
MAC2STR(peer_nmi));
|
||||
return;
|
||||
}
|
||||
|
||||
NAN_DATA_LOCK();
|
||||
struct peer_svc_info *peer = nan_find_peer_svc(0, 0, (uint8_t *)peer_nmi);
|
||||
if (peer) {
|
||||
ctx->svc_id = peer->own_svc_id;
|
||||
ctx->peer_svc_id = peer->svc_id;
|
||||
}
|
||||
NAN_DATA_UNLOCK();
|
||||
|
||||
MACADDR_COPY(ctx->peer_mac, peer_nmi);
|
||||
ctx->shared_key_attr_len = 0;
|
||||
|
||||
if (eloop_register_timeout(0, 0, nan_app_send_pairing_followup_eloop, NULL, ctx) != 0) {
|
||||
ESP_LOGW(TAG, "Pairing key installed: failed to schedule initiator follow-up");
|
||||
os_free(ctx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
(void)role;
|
||||
}
|
||||
|
||||
void nan_app_receive_pairing_followup(uint8_t svc_id, uint8_t peer_svc_id,
|
||||
const uint8_t *peer_mac,
|
||||
const uint8_t *shared_key_attr,
|
||||
@@ -792,7 +832,6 @@ void nan_app_receive_pairing_followup(uint8_t svc_id, uint8_t peer_svc_id,
|
||||
uint32_t lifetime_sec = 0;
|
||||
struct nan_pairing_fup_ctx *ctx;
|
||||
size_t alloc_len;
|
||||
|
||||
if (!shared_key_attr || !peer_mac) {
|
||||
return;
|
||||
}
|
||||
@@ -802,7 +841,6 @@ void nan_app_receive_pairing_followup(uint8_t svc_id, uint8_t peer_svc_id,
|
||||
if (shared_key_attr[0] != NAN_ATTR_ID_SHARED_KEY_DESC) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16_t *attr_body_len_field = (const uint16_t *)&shared_key_attr[1];
|
||||
|
||||
attr_body_len = *attr_body_len_field;
|
||||
@@ -823,18 +861,39 @@ void nan_app_receive_pairing_followup(uint8_t svc_id, uint8_t peer_svc_id,
|
||||
return;
|
||||
}
|
||||
|
||||
bool already_had_nik = false;
|
||||
|
||||
NAN_DATA_LOCK();
|
||||
struct peer_svc_info *p_peer_svc = nan_find_peer_svc_exact(svc_id, peer_svc_id, peer_mac);
|
||||
if (p_peer_svc) {
|
||||
already_had_nik = p_peer_svc->has_nik;
|
||||
memcpy(p_peer_svc->peer_nik, nik, NAN_APP_PEER_NIK_LEN);
|
||||
p_peer_svc->peer_nik_cipher_ver = cipher_ver;
|
||||
p_peer_svc->peer_nik_lifetime_sec = lifetime_sec;
|
||||
p_peer_svc->has_nik = true;
|
||||
ESP_LOGI(TAG, "Stored peer NIK from " MACSTR " (cipher_ver=%u, lifetime=%u s)",
|
||||
MAC2STR(peer_mac), cipher_ver, lifetime_sec);
|
||||
|
||||
if (!already_had_nik) {
|
||||
wifi_event_nan_pairing_complete_t evt = {0};
|
||||
evt.status = WIFI_NAN_PAIRING_STATUS_ACCEPTED;
|
||||
evt.reason_code = 0;
|
||||
MACADDR_COPY(evt.peer_nmi, peer_mac);
|
||||
esp_nan_disable_pairing();
|
||||
nan_app_post_event(WIFI_EVENT_NAN_PAIRING_CONFIRM, &evt, sizeof(evt));
|
||||
}
|
||||
}
|
||||
NAN_DATA_UNLOCK();
|
||||
|
||||
/* Only reply with our own NIK the first time we receive the peer's.
|
||||
* If has_nik was already true this is a redundant echo — don't reply
|
||||
* or we create an infinite ping-pong of follow-ups. */
|
||||
if (already_had_nik) {
|
||||
ESP_LOGD(TAG, "Pairing follow-up: NIK already known for " MACSTR ", skipping reply",
|
||||
MAC2STR(peer_mac));
|
||||
return;
|
||||
}
|
||||
|
||||
if (total_len > SIZE_MAX - sizeof(*ctx)) {
|
||||
return;
|
||||
}
|
||||
@@ -855,6 +914,51 @@ void nan_app_receive_pairing_followup(uint8_t svc_id, uint8_t peer_svc_id,
|
||||
}
|
||||
}
|
||||
|
||||
bool esp_nan_verify_nira(uint8_t *peer_mac, uint8_t *nira_attr, uint16_t nira_attr_len)
|
||||
{
|
||||
uint8_t expected_tag[NAN_NIRA_TAG_LEN];
|
||||
const uint8_t *nonce;
|
||||
const uint8_t *received_tag;
|
||||
struct peer_svc_info *p_peer_svc;
|
||||
bool match;
|
||||
|
||||
if (!peer_mac || !nira_attr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nira_attr_len < NAN_NIRA_ATTR_LEN) {
|
||||
ESP_LOGW(TAG, "NIRA verify: attribute too short (%u < %u)",
|
||||
(unsigned)nira_attr_len, (unsigned)NAN_NIRA_ATTR_LEN);
|
||||
return false;
|
||||
}
|
||||
|
||||
nonce = nira_attr + 4;
|
||||
received_tag = nira_attr + 4 + NAN_NIRA_NONCE_LEN;
|
||||
|
||||
NAN_DATA_LOCK();
|
||||
p_peer_svc = nan_find_peer_svc(0, 0, peer_mac);
|
||||
if (!p_peer_svc || !p_peer_svc->has_nik) {
|
||||
NAN_DATA_UNLOCK();
|
||||
ESP_LOGD(TAG, "NIRA verify: no stored NIK for "MACSTR, MAC2STR(peer_mac));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nan_pairing_derive_nira_tag(p_peer_svc->peer_nik, peer_mac, nonce, expected_tag) != 0) {
|
||||
NAN_DATA_UNLOCK();
|
||||
ESP_LOGE(TAG, "NIRA verify: tag derivation failed for "MACSTR, MAC2STR(peer_mac));
|
||||
return false;
|
||||
}
|
||||
NAN_DATA_UNLOCK();
|
||||
|
||||
match = (os_memcmp_const(expected_tag, received_tag, NAN_NIRA_TAG_LEN) == 0);
|
||||
if (match) {
|
||||
ESP_LOGD(TAG, "NIRA verify: OK for "MACSTR, MAC2STR(peer_mac));
|
||||
} else {
|
||||
ESP_LOGW(TAG, "NIRA verify: tag mismatch for "MACSTR, MAC2STR(peer_mac));
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_PAIRING && CONFIG_ESP_WIFI_PASN_SUPPORT && CONFIG_ESP_WIFI_NAN_SECURITY */
|
||||
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_PAIRING */
|
||||
|
||||
@@ -334,5 +334,6 @@ void esp_wifi_ap_set_group_mgmt_cipher_internal(wifi_cipher_type_t cipher);
|
||||
uint8_t esp_wifi_op_class_supported_internal(uint8_t op_class, uint8_t min_chan, uint8_t max_chan, uint8_t inc, uint8_t bw, channel_bitmap_t *non_pref_channels);
|
||||
bool esp_wifi_is_wpa3_compatible_mode_enabled(uint8_t if_index);
|
||||
uint8_t esp_wifi_ap_get_owe_config_internal(void);
|
||||
esp_err_t esp_nan_disable_pairing(void);
|
||||
|
||||
#endif /* _ESP_WIFI_DRIVER_H_ */
|
||||
|
||||
Reference in New Issue
Block a user