forked from espressif/esp-idf
Merge branch 'feat/support_nan_usd' into 'master'
Add support for Unsynchronized Service Discovery (USD) See merge request espressif/esp-idf!30990
This commit is contained in:
@@ -28,7 +28,7 @@ const esp_netif_ip_info_t _g_esp_netif_soft_ap_ip = {
|
||||
const esp_netif_inherent_config_t _g_esp_netif_inherent_ap_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_AP();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
const esp_netif_inherent_config_t _g_esp_netif_inherent_nan_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -158,7 +158,7 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
/**
|
||||
* @brief Default configuration reference of WIFI NAN
|
||||
*/
|
||||
@@ -204,7 +204,7 @@ extern "C" {
|
||||
#define ESP_NETIF_BASE_DEFAULT_WIFI_AP &_g_esp_netif_inherent_ap_config
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
/**
|
||||
* @brief Default base config (esp-netif inherent) of WIFI NAN
|
||||
*/
|
||||
@@ -230,7 +230,7 @@ extern "C" {
|
||||
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
||||
#define ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP _g_esp_netif_netstack_default_wifi_ap
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
#define ESP_NETIF_NETSTACK_DEFAULT_WIFI_NAN _g_esp_netif_netstack_default_wifi_nan
|
||||
#endif
|
||||
#ifdef CONFIG_PPP_SUPPORT
|
||||
@@ -249,7 +249,7 @@ extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_sta
|
||||
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
||||
extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_ap;
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_nan;
|
||||
#endif
|
||||
#ifdef CONFIG_PPP_SUPPORT
|
||||
@@ -264,7 +264,7 @@ extern const esp_netif_inherent_config_t _g_esp_netif_inherent_sta_config;
|
||||
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
||||
extern const esp_netif_inherent_config_t _g_esp_netif_inherent_ap_config;
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
extern const esp_netif_inherent_config_t _g_esp_netif_inherent_nan_config;
|
||||
#endif
|
||||
extern const esp_netif_inherent_config_t _g_esp_netif_inherent_eth_config;
|
||||
|
||||
@@ -48,7 +48,7 @@ if(CONFIG_ESP_WIFI_ENABLED OR CONFIG_ESP_HOST_WIFI_ENABLED)
|
||||
"src/smartconfig_ack.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_WIFI_NAN_ENABLE)
|
||||
if(CONFIG_ESP_WIFI_NAN_SYNC_ENABLE OR CONFIG_ESP_WIFI_NAN_USD_ENABLE)
|
||||
list(APPEND srcs "wifi_apps/nan_app/src/nan_app.c")
|
||||
endif()
|
||||
if(CONFIG_ESP_WIFI_ENABLE_ROAMING_APP)
|
||||
|
||||
@@ -576,13 +576,20 @@ menu "Wi-Fi"
|
||||
Maximum espnow encrypted peers number + maximum number of connections of SoftAP = Max hardware
|
||||
keys number. When using ESP mesh, this value should be set to a maximum of 6.
|
||||
|
||||
config ESP_WIFI_NAN_ENABLE
|
||||
bool "WiFi Aware"
|
||||
config ESP_WIFI_NAN_SYNC_ENABLE
|
||||
bool "Enable Wi-Fi Aware: Synchronization (NAN-Sync)"
|
||||
default n
|
||||
depends on SOC_WIFI_NAN_SUPPORT
|
||||
select LWIP_IPV6
|
||||
help
|
||||
Enable WiFi Aware (NAN) feature.
|
||||
Enable Wi-Fi Aware: Synchronization feature (NAN-Sync).
|
||||
|
||||
config ESP_WIFI_NAN_USD_ENABLE
|
||||
bool "Enable Wi-Fi Aware: Unsynchronized service discovery (NAN-USD)"
|
||||
depends on IDF_EXPERIMENTAL_FEATURES
|
||||
default n
|
||||
help
|
||||
Enable Wi-Fi Aware: Unsynchronized service discovery (NAN-USD)
|
||||
|
||||
config ESP_WIFI_MBEDTLS_CRYPTO
|
||||
bool "Use MbedTLS crypto APIs"
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef struct {
|
||||
void *storage; /**< storage for FreeRTOS queue */
|
||||
} wifi_static_queue_t;
|
||||
|
||||
struct nan_callbacks {
|
||||
struct nan_sync_callbacks {
|
||||
void (* service_match)(uint8_t sub_id, uint8_t pub_id, uint8_t pub_mac[6], uint16_t capab,
|
||||
uint8_t ssi_ver, uint8_t *ssi, uint16_t ssi_len);
|
||||
void (* replied)(uint8_t pub_id, uint8_t sub_id, uint8_t pub_mac[6], uint8_t *ssi, uint16_t ssi_len);
|
||||
@@ -780,7 +780,7 @@ esp_err_t esp_nan_internal_datapath_end(wifi_nan_datapath_end_req_t *req);
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_nan_internal_register_callbacks(struct nan_callbacks *cb);
|
||||
esp_err_t esp_nan_internal_register_callbacks(struct nan_sync_callbacks *cb);
|
||||
|
||||
/**
|
||||
* @brief Connect WiFi station to the AP.
|
||||
|
||||
@@ -1788,6 +1788,8 @@ esp_err_t esp_wifi_action_tx_req(wifi_action_tx_req_t *req);
|
||||
/**
|
||||
* @brief Remain on the target channel for required duration
|
||||
*
|
||||
* @attention 1. The API returns ESP_ERR_INVALID_ARG when `req->allow_broadcast` is true and the device operates in AP+STA mode.
|
||||
*
|
||||
* @param req roc request structure containing relevant fields
|
||||
*
|
||||
* @return
|
||||
|
||||
@@ -592,7 +592,7 @@ typedef struct {
|
||||
uint8_t master_pref; /**< Device's preference value to serve as NAN Master */
|
||||
uint8_t scan_time; /**< Scan time in seconds while searching for a NAN cluster */
|
||||
uint16_t warm_up_sec; /**< Warm up time before assuming NAN Anchor Master role */
|
||||
} wifi_nan_config_t;
|
||||
} wifi_nan_sync_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration data for device's AP or STA or NAN.
|
||||
@@ -604,7 +604,7 @@ typedef struct {
|
||||
typedef union {
|
||||
wifi_ap_config_t ap; /**< Configuration of AP */
|
||||
wifi_sta_config_t sta; /**< Configuration of STA */
|
||||
wifi_nan_config_t nan; /**< Configuration of NAN */
|
||||
wifi_nan_sync_config_t nan; /**< Configuration of NAN */
|
||||
} wifi_config_t;
|
||||
|
||||
/**
|
||||
@@ -798,6 +798,7 @@ typedef struct {
|
||||
bool no_ack; /**< Indicates no ack required */
|
||||
wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive action frames */
|
||||
uint8_t op_id; /**< Unique Identifier for operation provided by wifi driver */
|
||||
uint8_t bssid[6]; /**< BSSID (A3) address. If all zeroes, broadcast address will be used */
|
||||
uint32_t data_len; /**< Length of the appended Data */
|
||||
uint8_t data[0]; /**< Appended Data payload */
|
||||
} wifi_action_tx_req_t;
|
||||
@@ -830,9 +831,14 @@ typedef struct {
|
||||
uint8_t channel; /**< Channel on which to perform ROC Operation */
|
||||
wifi_second_chan_t sec_channel; /**< Secondary channel */
|
||||
uint32_t wait_time_ms; /**< Duration to wait for on target channel */
|
||||
wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive any response */
|
||||
wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive action mgmt frames */
|
||||
uint8_t op_id; /**< ID of this specific ROC operation provided by wifi driver */
|
||||
wifi_action_roc_done_cb_t done_cb; /**< Callback to function that will be called upon ROC done. If assigned, WIFI_EVENT_ROC_DONE event will not be posted */
|
||||
bool allow_broadcast; /**< If set to true, broadcast/multicast action frames from any network (Address3/BSSID=ANY)
|
||||
will be received in the ROC Rx callback, enabling peer discovery.
|
||||
If false (default), broadcast/multicast action frames from other networks
|
||||
will be filtered out in hardware and not passed to the Rx callback, reducing CPU usage.
|
||||
Frames whose Address3/BSSID is already broadcast are always delivered. */
|
||||
} wifi_roc_req_t;
|
||||
|
||||
/**
|
||||
@@ -846,7 +852,7 @@ typedef struct {
|
||||
uint16_t burst_period; /**< Requested period between FTM bursts in 100's of milliseconds (allowed values 0(No pref) - 100) */
|
||||
} wifi_ftm_initiator_cfg_t;
|
||||
|
||||
#define ESP_WIFI_NAN_MAX_SVC_SUPPORTED 2 /**< Maximum number of NAN services supported */
|
||||
#define ESP_WIFI_NAN_MAX_SVC_SUPPORTED 2 /**< Maximum number of NAN or NAN-USD services supported */
|
||||
#define ESP_WIFI_NAN_DATAPATH_MAX_PEERS 2 /**< Maximum number of NAN datapath peers supported */
|
||||
|
||||
#define ESP_WIFI_NDP_ROLE_INITIATOR 1 /**< Initiator role for NAN Data Path */
|
||||
@@ -878,7 +884,7 @@ typedef enum {
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t wfa_oui[WIFI_OUI_LEN]; /**< WFA OUI - 0x50, 0x6F, 0x9A */
|
||||
wifi_nan_svc_proto_t proto; /**< WFA defined protocol types */
|
||||
uint8_t proto; /**< WFA defined protocol of type wifi_nan_svc_proto_t */
|
||||
uint8_t payload[0]; /**< Service Info payload */
|
||||
} wifi_nan_wfa_ssi_t;
|
||||
|
||||
@@ -893,6 +899,19 @@ typedef enum {
|
||||
NAN_SUBSCRIBE_PASSIVE, /**< Passively listens to Publish frames */
|
||||
} wifi_nan_service_type_t;
|
||||
|
||||
/**
|
||||
* @brief USD specific configuration parameters
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t usd_default_channel; /**< If not specified, default channel 6 is used */
|
||||
wifi_scan_channel_bitmap_t usd_chan_bitmap; /**< Indicates publish channel list used in USD */
|
||||
uint8_t n_min; /**< Indicates minimum value of dwell period N used in the USD (Nmin) */
|
||||
uint8_t n_max; /**< Indicates maximum value of dwell period N used in the USD (Nmax) */
|
||||
uint8_t m_min; /**< Indicates minimum value of dwell period M used in the USD (Mmin) */
|
||||
uint8_t m_max; /**< Indicates maximum value of dwell period M used in the USD (Mmax)*/
|
||||
} wifi_nan_usd_config_t;
|
||||
|
||||
/**
|
||||
* @brief NAN Publish service configuration parameters
|
||||
*
|
||||
@@ -906,9 +925,13 @@ typedef struct {
|
||||
uint8_t fsd_reqd: 1; /**< Further Service Discovery(FSD) required */
|
||||
uint8_t fsd_gas: 1; /**< 0 - Follow-up used for FSD, 1 - GAS used for FSD */
|
||||
uint8_t ndp_resp_needed: 1; /**< 0 - Auto-Accept NDP Requests, 1 - Require explicit response with esp_wifi_nan_datapath_resp */
|
||||
uint8_t reserved: 3; /**< Reserved */
|
||||
uint8_t usd_discovery_flag: 1; /**< 0 - NAN Synchronization for Discovery, 1 - USD for Discovery. 'NAN Discovery flag' from specification */
|
||||
uint8_t reserved: 2; /**< Reserved */
|
||||
uint16_t ssi_len; /**< Length of service specific info, maximum allowed length - ESP_WIFI_MAX_SVC_SSI_LEN */
|
||||
uint8_t *ssi; /**< Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications */
|
||||
unsigned int ttl; /**< Run publish function for a given time interval in seconds. If ttl=0 and usd_discovery_flag is enabled,
|
||||
only one Publish message is transmitted */
|
||||
wifi_nan_usd_config_t usd_publish_config; /**< USD configuration parameters. Relevant only when 'usd_discovery_flag' is set. */
|
||||
} wifi_nan_publish_cfg_t;
|
||||
|
||||
/**
|
||||
@@ -923,9 +946,13 @@ typedef struct {
|
||||
uint8_t datapath_reqd: 1; /**< NAN Datapath required for the service */
|
||||
uint8_t fsd_reqd: 1; /**< Further Service Discovery(FSD) required */
|
||||
uint8_t fsd_gas: 1; /**< 0 - Follow-up used for FSD, 1 - GAS used for FSD */
|
||||
uint8_t reserved: 4; /**< Reserved */
|
||||
uint8_t usd_discovery_flag: 1; /**< 0 - NAN Synchronization for Discovery, 1 - USD for Discovery. 'NAN Discovery flag' from specification */
|
||||
uint8_t reserved: 3; /**< Reserved */
|
||||
uint16_t ssi_len; /**< Length of service specific info, maximum allowed length - ESP_WIFI_MAX_SVC_SSI_LEN */
|
||||
uint8_t *ssi; /**< Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications */
|
||||
unsigned int ttl; /**< Run subscribe function for a given time interval in seconds. If ttl=0 and usd_discovery_flag is enabled,
|
||||
the subscriber listens until the first service match is reported. */
|
||||
wifi_nan_usd_config_t usd_subscribe_config; /**< USD configuration parameters. Relevant only when 'usd_discovery_flag' is set. */
|
||||
} wifi_nan_subscribe_cfg_t;
|
||||
|
||||
/**
|
||||
@@ -1098,8 +1125,8 @@ typedef enum {
|
||||
WIFI_EVENT_BTWT_SETUP, /**< bTWT setup */
|
||||
WIFI_EVENT_BTWT_TEARDOWN, /**< bTWT teardown*/
|
||||
|
||||
WIFI_EVENT_NAN_STARTED, /**< NAN Discovery has started */
|
||||
WIFI_EVENT_NAN_STOPPED, /**< NAN Discovery has stopped */
|
||||
WIFI_EVENT_NAN_SYNC_STARTED, /**< NAN Synchronization Discovery has started */
|
||||
WIFI_EVENT_NAN_SYNC_STOPPED, /**< NAN Synchronization Discovery has stopped */
|
||||
WIFI_EVENT_NAN_SVC_MATCH, /**< NAN Service Discovery match found */
|
||||
WIFI_EVENT_NAN_REPLIED, /**< Replied to a NAN peer with Service Discovery match */
|
||||
WIFI_EVENT_NAN_RECEIVE, /**< Received a Follow-up message */
|
||||
|
||||
+1
-1
Submodule components/esp_wifi/lib updated: 37a69947e1...21eacc3229
@@ -28,6 +28,7 @@ CONFIG_ESP32_WIFI_IRAM_OPT CONFIG_ESP_WIFI_IRAM_OPT
|
||||
CONFIG_ESP32_WIFI_RX_IRAM_OPT CONFIG_ESP_WIFI_RX_IRAM_OPT
|
||||
CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE CONFIG_ESP_WIFI_ENABLE_WPA3_SAE
|
||||
CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA
|
||||
CONFIG_ESP_WIFI_NAN_ENABLE CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
|
||||
# renaming supplicant kconfig to esp_wifi kconfig
|
||||
CONFIG_WPA_MBEDTLS_CRYPTO CONFIG_ESP_WIFI_MBEDTLS_CRYPTO
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "esp_wifi_netif.h"
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
#include "apps_private/wifi_apps_private.h"
|
||||
#endif
|
||||
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
||||
@@ -170,7 +170,7 @@ static void wifi_default_action_sta_got_ip(void *arg, esp_event_base_t base, int
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
static void wifi_default_action_nan_started(void *arg, esp_event_base_t base, int32_t event_id, void *data)
|
||||
{
|
||||
if (s_wifi_netifs[WIFI_IF_NAN] != NULL) {
|
||||
@@ -202,9 +202,9 @@ static esp_err_t clear_default_wifi_handlers(void)
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_AP_STOP, wifi_default_action_ap_stop);
|
||||
#endif
|
||||
esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_default_action_sta_got_ip);
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NAN_STARTED, wifi_default_action_nan_started);
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NAN_STOPPED, wifi_default_action_nan_stopped);
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NAN_SYNC_STARTED, wifi_default_action_nan_started);
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_NAN_SYNC_STOPPED, wifi_default_action_nan_stopped);
|
||||
#endif
|
||||
esp_unregister_shutdown_handler((shutdown_handler_t)esp_wifi_stop);
|
||||
wifi_default_handlers_set = false;
|
||||
@@ -258,13 +258,13 @@ static esp_err_t set_default_wifi_handlers(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NAN_STARTED, wifi_default_action_nan_started, NULL);
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NAN_SYNC_STARTED, wifi_default_action_nan_started, NULL);
|
||||
if (err != ESP_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NAN_STOPPED, wifi_default_action_nan_stopped, NULL);
|
||||
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_NAN_SYNC_STOPPED, wifi_default_action_nan_stopped, NULL);
|
||||
if (err != ESP_OK) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -364,7 +364,7 @@ static inline esp_err_t esp_netif_attach_wifi(esp_netif_t *esp_netif, wifi_inter
|
||||
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
||||
&& wifi_if != WIFI_IF_AP
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
&& wifi_if != WIFI_IF_NAN
|
||||
#endif
|
||||
)) {
|
||||
@@ -386,7 +386,7 @@ esp_err_t esp_netif_attach_wifi_ap(esp_netif_t *esp_netif)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
esp_err_t esp_netif_attach_wifi_nan(esp_netif_t *esp_netif)
|
||||
{
|
||||
return esp_netif_attach_wifi(esp_netif, WIFI_IF_NAN);
|
||||
@@ -425,7 +425,7 @@ esp_netif_t* esp_netif_create_default_wifi_sta(void)
|
||||
return netif;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
/**
|
||||
* @brief User init default NAN (official API)
|
||||
*/
|
||||
@@ -465,7 +465,7 @@ esp_netif_t* esp_netif_create_wifi(wifi_interface_t wifi_if, const esp_netif_inh
|
||||
} else if (wifi_if == WIFI_IF_AP) {
|
||||
cfg.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP;
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
} else if (wifi_if == WIFI_IF_NAN) {
|
||||
cfg.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_NAN;
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#if __has_include("esp_psram.h")
|
||||
#include "esp_psram.h"
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
#include "apps_private/wifi_apps_private.h"
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_WIFI_FTM_ENABLE
|
||||
@@ -187,7 +187,7 @@ static esp_err_t wifi_deinit_internal(void)
|
||||
ESP_LOGW(TAG, "Failed to unregister Rx callbacks");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
esp_nan_app_deinit();
|
||||
#endif
|
||||
|
||||
@@ -484,7 +484,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
|
||||
|
||||
esp_wifi_config_info();
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
esp_nan_app_init();
|
||||
#endif
|
||||
|
||||
@@ -649,7 +649,7 @@ void create_new_bss_for_sa_query_failed_sta(uint8_t arg)
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_SOFTAP_SUPPORT */
|
||||
|
||||
#ifndef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifndef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
|
||||
esp_err_t nan_start(void)
|
||||
{
|
||||
@@ -680,7 +680,7 @@ int wifi_create_nan(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wifi_nan_set_config_local(wifi_nan_config_t *p)
|
||||
int wifi_nan_set_config_local(wifi_nan_sync_config_t *p)
|
||||
{
|
||||
/* Do not remove, stub to overwrite weak link in Wi-Fi Lib */
|
||||
return 0;
|
||||
@@ -707,7 +707,7 @@ void nan_ndp_resp_timeout_process(void *p)
|
||||
{
|
||||
/* Do not remove, stub to overwrite weak link in Wi-Fi Lib */
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_ENABLE */
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C2
|
||||
#if CONFIG_ESP32C2_REV_MIN_FULL < 200
|
||||
|
||||
@@ -46,7 +46,7 @@ static esp_err_t wifi_ap_receive(void *buffer, uint16_t len, void *eb)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
static esp_err_t wifi_nan_receive(void *buffer, uint16_t len, void *eb)
|
||||
{
|
||||
return s_wifi_rxcbs[WIFI_IF_NAN](s_wifi_netifs[WIFI_IF_NAN], buffer, len, eb);
|
||||
@@ -158,7 +158,7 @@ esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
case WIFI_IF_NAN:
|
||||
rxcb = wifi_nan_receive;
|
||||
break;
|
||||
|
||||
@@ -1 +1 @@
|
||||
CONFIG_ESP_WIFI_NAN_ENABLE=y
|
||||
CONFIG_ESP_WIFI_NAN_SYNC_ENABLE=y
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
|
||||
/**
|
||||
* @brief Initialize the NAN App and required Data Structures
|
||||
@@ -35,7 +35,7 @@ void esp_nan_app_deinit(void);
|
||||
* @brief NAN App action handler for NAN Started event. Sets up other event handlers and
|
||||
* initializes NAN App context
|
||||
*
|
||||
* @attention This API should be called in WIFI_EVENT_NAN_STARTED event handler
|
||||
* @attention This API should be called in WIFI_EVENT_NAN_SYNC_STARTED event handler
|
||||
*
|
||||
* @param nan_netif Netif handle corresponding to NAN interface.
|
||||
*/
|
||||
@@ -45,11 +45,11 @@ void esp_nan_action_start(esp_netif_t *nan_netif);
|
||||
* @brief NAN App action handler for NAN Stopped event. Clears other event handlers and
|
||||
* resets NAN App context
|
||||
*
|
||||
* @attention This API should be called in WIFI_EVENT_NAN_STOPPED event handler
|
||||
* @attention This API should be called in WIFI_EVENT_NAN_SYNC_STOPPED event handler
|
||||
*/
|
||||
void esp_nan_action_stop(void);
|
||||
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_ENABLE */
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WIFI_NAN_CONFIG_DEFAULT() { \
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
#define WIFI_NAN_SYNC_CONFIG_DEFAULT() { \
|
||||
.op_channel = 6, \
|
||||
.master_pref = 2, \
|
||||
.scan_time = 3, \
|
||||
@@ -40,7 +41,8 @@ struct nan_peer_record {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Start NAN Discovery with provided configuration
|
||||
* @brief Start NAN Synchronization using the provided parameters.
|
||||
* @note Discovery traffic begins only after publish/subscribe services are started.
|
||||
*
|
||||
* @attention This API should be called after esp_wifi_init().
|
||||
*
|
||||
@@ -50,69 +52,21 @@ struct nan_peer_record {
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg);
|
||||
esp_err_t esp_wifi_nan_sync_start(const wifi_nan_sync_config_t *nan_cfg);
|
||||
|
||||
/**
|
||||
* @brief Stop NAN Discovery, end NAN Services and Datapaths
|
||||
* @brief Stop NAN Synchronization discovery and end publish/subscribe services
|
||||
*
|
||||
* @attention This API will end datapaths if any in NAN synchronization
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_nan_stop(void);
|
||||
esp_err_t esp_wifi_nan_sync_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Start Publishing a service to the NAN Peers in vicinity
|
||||
*
|
||||
* @attention This API should be called after esp_wifi_nan_start().
|
||||
*
|
||||
* @param publish_cfg Configuration parameters for publishing a service.
|
||||
*
|
||||
* @return
|
||||
* - non-zero: Publish service identifier
|
||||
* - zero: failed
|
||||
*/
|
||||
uint8_t esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t *publish_cfg);
|
||||
|
||||
/**
|
||||
* @brief Subscribe for a service within the NAN cluster
|
||||
*
|
||||
* @attention This API should be called after esp_wifi_nan_start().
|
||||
*
|
||||
* @param subscribe_cfg Configuration parameters for subscribing for a service.
|
||||
*
|
||||
* @return
|
||||
* - non-zero: Subscribe service identifier
|
||||
* - zero: failed
|
||||
*/
|
||||
uint8_t esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t *subscribe_cfg);
|
||||
|
||||
/**
|
||||
* @brief Send a follow-up message to the NAN Peer with matched service
|
||||
*
|
||||
* @attention This API should be called after a NAN service is discovered due to a match.
|
||||
*
|
||||
* @param fup_params Configuration parameters for sending a Follow-up message.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params);
|
||||
|
||||
/**
|
||||
* @brief Cancel a NAN service
|
||||
*
|
||||
* @param service_id Publish/Subscribe service id to be cancelled.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id);
|
||||
|
||||
/**
|
||||
* @brief Send NAN Datapath Request to a NAN Publisher with matched service
|
||||
* @brief Send a NAN datapath request to a matched publisher within the synchronized NAN cluster
|
||||
*
|
||||
* @attention This API should be called by the Subscriber after a match occurs with a Publisher.
|
||||
*
|
||||
@@ -125,7 +79,7 @@ esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id);
|
||||
uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req);
|
||||
|
||||
/**
|
||||
* @brief Respond to a NAN Datapath request with Accept or Reject
|
||||
* @brief Respond to a NAN datapath request within the synchronized NAN cluster
|
||||
*
|
||||
* @attention This API should be called if ndp_resp_needed is set 1 in wifi_nan_publish_cfg_t and
|
||||
* a WIFI_EVENT_NDP_INDICATION event is received due to an incoming NDP request.
|
||||
@@ -139,7 +93,7 @@ uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req);
|
||||
esp_err_t esp_wifi_nan_datapath_resp(wifi_nan_datapath_resp_t *resp);
|
||||
|
||||
/**
|
||||
* @brief Terminate a NAN Datapath
|
||||
* @brief Terminate an active NAN datapath within the synchronized NAN cluster
|
||||
*
|
||||
* @param req NAN Datapath end request parameters.
|
||||
*
|
||||
@@ -161,6 +115,7 @@ void esp_wifi_nan_get_ipv6_linklocal_from_mac(ip6_addr_t *ip6, uint8_t *mac_addr
|
||||
* brief Get own Service information from Service ID OR Name.
|
||||
*
|
||||
* @attention If service information is to be fetched from service name, set own_svc_id as zero.
|
||||
* @note Returns records discovered while participating in a synchronized NAN cluster.
|
||||
*
|
||||
* @param[inout] own_svc_id As input, it indicates Service ID to search for.
|
||||
* As output, it indicates Service ID of the service found using Service Name.
|
||||
@@ -171,11 +126,14 @@ void esp_wifi_nan_get_ipv6_linklocal_from_mac(ip6_addr_t *ip6, uint8_t *mac_addr
|
||||
* - ESP_OK: succeed
|
||||
* - ESP_FAIL: failed
|
||||
*/
|
||||
|
||||
esp_err_t esp_wifi_nan_get_own_svc_info(uint8_t *own_svc_id, char *svc_name, int *num_peer_records);
|
||||
|
||||
/**
|
||||
* brief Get a list of Peers discovered by the given Service.
|
||||
*
|
||||
* @note Reports peers discovered via synchronized NAN operations.
|
||||
*
|
||||
* @param[inout] num_peer_records As input param, it stores max peers peer_record can hold.
|
||||
* As output param, it specifies the actual number of peers this API returns.
|
||||
* @param own_svc_id Service ID of own service.
|
||||
@@ -184,11 +142,14 @@ esp_err_t esp_wifi_nan_get_own_svc_info(uint8_t *own_svc_id, char *svc_name, int
|
||||
* - ESP_OK: succeed
|
||||
* - ESP_FAIL: failed
|
||||
*/
|
||||
|
||||
esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_id, struct nan_peer_record *peer_record);
|
||||
|
||||
/**
|
||||
* brief Find Peer's Service information using Peer MAC and optionally Service Name.
|
||||
*
|
||||
* @note Provides peer information available from synchronized NAN discovery.
|
||||
*
|
||||
* @param svc_name Service Name of the published/subscribed service.
|
||||
* @param peer_mac Peer's NAN Management Interface MAC address.
|
||||
* @param[out] peer_info Peer's service information structure.
|
||||
@@ -196,8 +157,141 @@ esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_i
|
||||
* - ESP_OK: succeed
|
||||
* - ESP_FAIL: failed
|
||||
*/
|
||||
|
||||
esp_err_t esp_wifi_nan_get_peer_info(char *svc_name, uint8_t *peer_mac, struct nan_peer_record *peer_info);
|
||||
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
|
||||
#if defined(CONFIG_ESP_WIFI_NAN_SYNC_ENABLE) || defined(CONFIG_ESP_WIFI_NAN_USD_ENABLE)
|
||||
/**
|
||||
* @brief Start publishing a service to NAN peers within a synchronized cluster or to NAN-USD peers
|
||||
*
|
||||
* @attention Call after `esp_wifi_nan_sync_start()` when operating in NAN-Sync, or after
|
||||
* `esp_wifi_nan_usd_start()` when operating in NAN-USD.
|
||||
* @attention When NAN-USD discovery is active the publish request is routed through the
|
||||
* USD engine, otherwise it uses NAN synchronization.
|
||||
* @attention A maximum of two services is allowed simultaneously
|
||||
* (e.g., one publish and one subscribe, or two publish/subscribe).
|
||||
* This limit is defined by the ESP_WIFI_NAN_MAX_SVC_SUPPORTED.
|
||||
*
|
||||
* @param publish_cfg Configuration parameters for publishing a service.
|
||||
* When operating in NAN-USD, populate `publish_cfg->usd_publish_config`
|
||||
* (for example using `esp_wifi_usd_get_default_publish_cfg()`) to tune
|
||||
* the USD dwell and channel parameters.
|
||||
*
|
||||
* @return
|
||||
* - non-zero: Publish service identifier
|
||||
* - zero: failed
|
||||
*/
|
||||
uint8_t esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t *publish_cfg);
|
||||
|
||||
/**
|
||||
* @brief Subscribe to a service published by a NAN peer within a synchronized cluster or by a NAN-USD peer
|
||||
*
|
||||
* @attention Call after `esp_wifi_nan_sync_start()` when operating in NAN-Sync, or after
|
||||
* `esp_wifi_nan_usd_start()` when operating in NAN-USD.
|
||||
* @attention With NAN-USD discovery enabled the subscribe request is handled by the USD
|
||||
* engine, otherwise it uses NAN synchronization.
|
||||
* @attention A maximum of two services is allowed simultaneously
|
||||
* (e.g., one publish and one subscribe, or two publish/subscribe).
|
||||
* This limit is defined by the ESP_WIFI_NAN_MAX_SVC_SUPPORTED.
|
||||
*
|
||||
* @param subscribe_cfg Configuration parameters for subscribing for a service.
|
||||
* When operating in NAN-USD, populate `subscribe_cfg->usd_subscribe_config`
|
||||
* (for example using `esp_wifi_usd_get_default_subscribe_cfg()`) to tune
|
||||
* the USD dwell and channel parameters.
|
||||
*
|
||||
* @return
|
||||
* - non-zero: Subscribe service identifier
|
||||
* - zero: failed
|
||||
*/
|
||||
uint8_t esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t *subscribe_cfg);
|
||||
|
||||
/**
|
||||
* @brief Send a follow-up message to a matched peer in NAN synchronization or USD
|
||||
*
|
||||
* @attention This API should be called after a NAN/USD service is discovered due to a match.
|
||||
*
|
||||
* @param fup_params Configuration parameters for sending a Follow-up message.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params);
|
||||
|
||||
/**
|
||||
* @brief Cancel a NAN synchronization or NAN-USD service
|
||||
*
|
||||
* @param service_id Publish/Subscribe service id to be cancelled.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id);
|
||||
|
||||
#endif /* NAN-Sync || NAN-USD */
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_USD_ENABLE
|
||||
/**
|
||||
* @brief Start NAN Unsynchronized service discovery (USD)
|
||||
*
|
||||
* @attention This API should be called after esp_wifi_start().
|
||||
* @note USD currently operates over the Station interface; this may change in future releases.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_nan_usd_start(void);
|
||||
|
||||
/**
|
||||
* @brief Stop NAN Unsynchronized service discovery (USD) and end publish/subscribe services
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_nan_usd_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Get default configuration for USD publish operation.
|
||||
*
|
||||
* @note This function returns a default configuration structure for initiating
|
||||
* a USD (Unsynchronized Service Discovery) publish session.
|
||||
* - The default channel is set to channel 6 (2.437 GHz) in the 2.4 GHz band.
|
||||
* - The channel list will include all 20 MHz channels in the 2.4 GHz frequency band,
|
||||
* as permitted by the regulatory domain of the current geographic location.
|
||||
* - Default values for dwell periods are set as per Wi-Fi Aware Specification:
|
||||
* - Nmin = 5, Nmax = 10
|
||||
* - Mmin = 5, Mmax = 10
|
||||
*
|
||||
* @return wifi_nan_usd_config_t structure with pre-filled default values for publishing.
|
||||
*/
|
||||
wifi_nan_usd_config_t esp_wifi_usd_get_default_publish_cfg(void);
|
||||
|
||||
/**
|
||||
* @brief Get default configuration for USD subscribe operation.
|
||||
*
|
||||
* @note This function returns a default configuration structure for initiating
|
||||
* a USD (Unsynchronized Service Discovery) subscribe session.
|
||||
* - The default channel is set to channel 6 (2.437 GHz) in the 2.4 GHz band.
|
||||
* - The channel list will include all 20 MHz channels in the 2.4 GHz frequency band,
|
||||
* as permitted by the regulatory domain of the current geographic location.
|
||||
* - Default values for dwell periods are set as per Wi-Fi Aware Specification:
|
||||
* - Nmin = 5, Nmax = 10
|
||||
* - Mmin = 5, Mmax = 10
|
||||
*
|
||||
* @warning Currently, the subscribe function operates only on the default channel.
|
||||
* It does not alternate between the default channel and channels in the channel list.
|
||||
*
|
||||
* @return wifi_nan_usd_config_t structure with pre-filled default values for subscribing.
|
||||
*/
|
||||
wifi_nan_usd_config_t esp_wifi_usd_get_default_subscribe_cfg(void);
|
||||
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_USD_ENABLE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
#include "os.h"
|
||||
#include "esp_nan.h"
|
||||
#include "utils/common.h"
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_USD_ENABLE
|
||||
#include "esp_private/esp_nan_usd.h"
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_USD_ENABLE */
|
||||
|
||||
/* NAN States */
|
||||
#define NAN_STARTED_BIT BIT0
|
||||
@@ -42,18 +45,27 @@
|
||||
|
||||
/* Global Variables */
|
||||
static const char *TAG = "nan_app";
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
static EventGroupHandle_t nan_event_group;
|
||||
static bool s_app_default_handlers_set = false;
|
||||
static uint8_t null_mac[MACADDR_LEN] = {0};
|
||||
static void *s_nan_data_lock = NULL;
|
||||
static const uint8_t s_wfa_oui[3] = {0x50, 0x6f, 0x9a};
|
||||
static uint32_t s_fup_context;
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_USD_ENABLE
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_USD_ENABLE */
|
||||
static bool s_usd_in_progress = false;
|
||||
static const uint8_t s_wfa_oui[3] = {0x50, 0x6f, 0x9a};
|
||||
|
||||
/* Definitions */
|
||||
#define NAN_SDEA_CTRL_FSD_REQD BIT(0)
|
||||
#define NAN_SDEA_CTRL_FSD_GAS BIT(1)
|
||||
#define NAN_SDEA_CTRL_DATAPATH_REQD BIT(2)
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
#define NAN_DATA_LOCK() os_mutex_lock(s_nan_data_lock)
|
||||
#define NAN_DATA_UNLOCK() os_mutex_unlock(s_nan_data_lock)
|
||||
|
||||
struct peer_svc_info {
|
||||
SLIST_ENTRY(peer_svc_info) next;
|
||||
uint8_t peer_svc_info[ESP_WIFI_MAX_SVC_INFO_LEN]; /**< Information for followup message */
|
||||
@@ -748,7 +760,7 @@ void esp_nan_action_start(esp_netif_t *nan_netif)
|
||||
s_nan_ctx.state = NAN_STARTED_BIT;
|
||||
NAN_DATA_UNLOCK();
|
||||
|
||||
struct nan_callbacks nan_cb = {
|
||||
struct nan_sync_callbacks nan_cb = {
|
||||
.service_match = nan_app_service_match_cb,
|
||||
.replied = nan_app_replied_cb,
|
||||
.receive = nan_app_receive_cb,
|
||||
@@ -782,11 +794,10 @@ void esp_nan_action_stop(void)
|
||||
os_event_group_set_bits(nan_event_group, NAN_STOPPED_BIT);
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg)
|
||||
esp_err_t esp_wifi_nan_sync_start(const wifi_nan_sync_config_t *nan_cfg)
|
||||
{
|
||||
wifi_mode_t mode;
|
||||
esp_err_t ret;
|
||||
wifi_config_t config = {0};
|
||||
|
||||
ret = esp_wifi_get_mode(&mode);
|
||||
if (ret == ESP_ERR_WIFI_NOT_INIT) {
|
||||
@@ -797,6 +808,10 @@ esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* XXX: For now, NAN-USD and NAN-Sync can not coexist. */
|
||||
/* NAN-Synchronization Only */
|
||||
wifi_config_t config = {0};
|
||||
if (!s_nan_data_lock) {
|
||||
ESP_LOGE(TAG, "NAN Data lock doesn't exist");
|
||||
return ESP_FAIL;
|
||||
@@ -812,7 +827,7 @@ esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg)
|
||||
|
||||
ESP_RETURN_ON_ERROR(esp_wifi_set_mode(WIFI_MODE_NAN), TAG, "Set mode NAN failed");
|
||||
|
||||
memcpy(&config.nan, nan_cfg, sizeof(wifi_nan_config_t));
|
||||
memcpy(&config.nan, nan_cfg, sizeof(wifi_nan_sync_config_t));
|
||||
ESP_RETURN_ON_ERROR(esp_wifi_set_config(WIFI_IF_NAN, &config), TAG, "Setting NAN config failed");
|
||||
|
||||
if (esp_wifi_start() != ESP_OK) {
|
||||
@@ -833,7 +848,7 @@ esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_nan_stop(void)
|
||||
esp_err_t esp_wifi_nan_sync_stop(void)
|
||||
{
|
||||
NAN_DATA_LOCK();
|
||||
if (!(s_nan_ctx.state & NAN_STARTED_BIT)) {
|
||||
@@ -873,41 +888,77 @@ esp_err_t esp_wifi_nan_stop(void)
|
||||
NAN_DATA_UNLOCK();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
|
||||
uint8_t esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t *publish_cfg)
|
||||
{
|
||||
uint8_t pub_id;
|
||||
int pub_id;
|
||||
|
||||
if (publish_cfg->usd_discovery_flag && !s_usd_in_progress) {
|
||||
ESP_LOGE(TAG, "Can not start Publish function with USD Discovery "
|
||||
"when USD is not enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!publish_cfg->usd_discovery_flag && s_usd_in_progress) {
|
||||
// XXX Add support for NAN-Sync and NAN-USD concurrent discovery
|
||||
ESP_LOGE(TAG, "Can not start Publish function with "
|
||||
"NAN-Synchronization Discovery when USD is enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((publish_cfg->ssi_len && publish_cfg->ssi == NULL) ||
|
||||
(publish_cfg->ssi &&
|
||||
(!publish_cfg->ssi_len ||
|
||||
publish_cfg->ssi_len > ESP_WIFI_MAX_SVC_SSI_LEN))) {
|
||||
ESP_LOGE(TAG, "Configured ssi and ssi_len(%d) incorrect",
|
||||
publish_cfg->ssi_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (publish_cfg->ssi &&
|
||||
!memcmp(publish_cfg->ssi, s_wfa_oui, sizeof(s_wfa_oui))) {
|
||||
/* WFA defined Service Specific Info */
|
||||
wifi_nan_wfa_ssi_t *wfa_ssi = (wifi_nan_wfa_ssi_t *)publish_cfg->ssi;
|
||||
if (wfa_ssi->proto >= WIFI_SVC_PROTO_MAX) {
|
||||
ESP_LOGI(TAG, "Unrecognized WFA Defined SSI protocol (%d)",
|
||||
wfa_ssi->proto);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_USD_ENABLE
|
||||
if (s_usd_in_progress) {
|
||||
if ((pub_id = esp_nan_usd_publish(publish_cfg)) == -1) {
|
||||
ESP_LOGE(TAG, "Failed to publish service '%s'",
|
||||
publish_cfg->service_name);
|
||||
return 0;
|
||||
}
|
||||
ESP_LOGI(TAG, "Started Publishing %s [Service ID - %u]",
|
||||
publish_cfg->service_name, pub_id);
|
||||
return pub_id;
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_USD_ENABLE */
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
NAN_DATA_LOCK();
|
||||
if (!(s_nan_ctx.state & NAN_STARTED_BIT)) {
|
||||
ESP_LOGE(TAG, "NAN not started!");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (nan_services_limit_reached()) {
|
||||
ESP_LOGE(TAG, "Maximum services limit reached");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (nan_find_own_svc_by_name(publish_cfg->service_name)) {
|
||||
ESP_LOGE(TAG, "Service name %s already used!", publish_cfg->service_name);
|
||||
ESP_LOGE(TAG, "Service name %s already used!",
|
||||
publish_cfg->service_name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((publish_cfg->ssi_len && publish_cfg->ssi == NULL) ||
|
||||
(publish_cfg->ssi && (!publish_cfg->ssi_len || publish_cfg->ssi_len > ESP_WIFI_MAX_SVC_SSI_LEN))) {
|
||||
ESP_LOGE(TAG, "Configured ssi and ssi_len(%d) incorrect", publish_cfg->ssi_len);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (publish_cfg->ssi && !memcmp(publish_cfg->ssi, s_wfa_oui, sizeof(s_wfa_oui))) {
|
||||
/* WFA defined Service Specific Info */
|
||||
wifi_nan_wfa_ssi_t *wfa_ssi = (wifi_nan_wfa_ssi_t *)publish_cfg->ssi;
|
||||
if (wfa_ssi->proto >= WIFI_SVC_PROTO_MAX) {
|
||||
ESP_LOGI(TAG, "Unrecognized WFA Defined SSI protocol (%d)", wfa_ssi->proto);
|
||||
}
|
||||
}
|
||||
|
||||
if (esp_nan_internal_publish_service(publish_cfg, &pub_id, false) != ESP_OK) {
|
||||
if (esp_nan_internal_publish_service(publish_cfg, (uint8_t *) &pub_id, false) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to publish service '%s'", publish_cfg->service_name);
|
||||
goto fail;
|
||||
}
|
||||
@@ -920,12 +971,55 @@ uint8_t esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t *publish_cfg)
|
||||
fail:
|
||||
NAN_DATA_UNLOCK();
|
||||
return 0;
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t *subscribe_cfg)
|
||||
{
|
||||
uint8_t sub_id;
|
||||
int sub_id;
|
||||
|
||||
if (subscribe_cfg->usd_discovery_flag && !s_usd_in_progress) {
|
||||
ESP_LOGE(TAG, "Can not start Subscribe function with USD Discovery "
|
||||
"when USD is not enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!subscribe_cfg->usd_discovery_flag && s_usd_in_progress) {
|
||||
// XXX Add support for NAN-Sync and NAN-USD concurrent discovery
|
||||
ESP_LOGE(TAG, "Can not start Subscribe function with "
|
||||
"NAN-Synchronization Discovery when USD is enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((subscribe_cfg->ssi_len && subscribe_cfg->ssi == NULL) ||
|
||||
(subscribe_cfg->ssi && (!subscribe_cfg->ssi_len || subscribe_cfg->ssi_len > ESP_WIFI_MAX_SVC_SSI_LEN))) {
|
||||
ESP_LOGE(TAG, "Configured ssi and ssi_len(%d) incorrect", subscribe_cfg->ssi_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (subscribe_cfg->ssi && !memcmp(subscribe_cfg->ssi, s_wfa_oui, sizeof(s_wfa_oui))) {
|
||||
/* WFA defined Service Specific Info */
|
||||
wifi_nan_wfa_ssi_t *wfa_ssi = (wifi_nan_wfa_ssi_t *)subscribe_cfg->ssi;
|
||||
if (wfa_ssi->proto >= WIFI_SVC_PROTO_MAX) {
|
||||
ESP_LOGI(TAG, "Unrecognized WFA Defined SSI protocol (%d)", wfa_ssi->proto);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_USD_ENABLE
|
||||
if (s_usd_in_progress) {
|
||||
if ((sub_id = esp_nan_usd_subscribe(subscribe_cfg)) == -1) {
|
||||
ESP_LOGE(TAG, "Failed to subscribe to service '%s'",
|
||||
subscribe_cfg->service_name);
|
||||
return 0;
|
||||
}
|
||||
ESP_LOGI(TAG, "Started Subscribing to %s [Service ID - %u]",
|
||||
subscribe_cfg->service_name, sub_id);
|
||||
return sub_id;
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_USD_ENABLE */
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
NAN_DATA_LOCK();
|
||||
if (!(s_nan_ctx.state & NAN_STARTED_BIT)) {
|
||||
ESP_LOGE(TAG, "NAN not started!");
|
||||
@@ -941,63 +1035,70 @@ uint8_t esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t *subscribe
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((subscribe_cfg->ssi_len && subscribe_cfg->ssi == NULL) ||
|
||||
(subscribe_cfg->ssi && (!subscribe_cfg->ssi_len || subscribe_cfg->ssi_len > ESP_WIFI_MAX_SVC_SSI_LEN))) {
|
||||
ESP_LOGE(TAG, "Configured ssi and ssi_len(%d) incorrect", subscribe_cfg->ssi_len);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (subscribe_cfg->ssi && !memcmp(subscribe_cfg->ssi, s_wfa_oui, sizeof(s_wfa_oui))) {
|
||||
/* WFA defined Service Specific Info */
|
||||
wifi_nan_wfa_ssi_t *wfa_ssi = (wifi_nan_wfa_ssi_t *)subscribe_cfg->ssi;
|
||||
if (wfa_ssi->proto >= WIFI_SVC_PROTO_MAX) {
|
||||
ESP_LOGI(TAG, "Unrecognized WFA Defined SSI protocol (%d)", wfa_ssi->proto);
|
||||
}
|
||||
}
|
||||
|
||||
if (esp_nan_internal_subscribe_service(subscribe_cfg, &sub_id, false) != ESP_OK) {
|
||||
if (esp_nan_internal_subscribe_service(subscribe_cfg, (uint8_t*) &sub_id, false) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to subscribe to service '%s'", subscribe_cfg->service_name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Started Subscribing to %s [Service ID - %u]", subscribe_cfg->service_name, sub_id);
|
||||
nan_record_own_svc(sub_id, ESP_NAN_SUBSCRIBE, subscribe_cfg->service_name, false);
|
||||
nan_record_own_svc((uint8_t) sub_id, ESP_NAN_SUBSCRIBE, subscribe_cfg->service_name, false);
|
||||
NAN_DATA_UNLOCK();
|
||||
|
||||
return sub_id;
|
||||
fail:
|
||||
NAN_DATA_UNLOCK();
|
||||
return 0;
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params)
|
||||
{
|
||||
struct peer_svc_info *p_peer_svc;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if ((fup_params->ssi_len && fup_params->ssi == NULL) ||
|
||||
(fup_params->ssi &&
|
||||
(!fup_params->ssi_len ||
|
||||
fup_params->ssi_len > ESP_WIFI_MAX_FUP_SSI_LEN))) {
|
||||
ESP_LOGE(TAG, "Configured ssi and ssi_len(%d) incorrect",
|
||||
fup_params->ssi_len);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (fup_params->ssi &&
|
||||
!memcmp(fup_params->ssi, s_wfa_oui, sizeof(s_wfa_oui))) {
|
||||
/* WFA defined Service Specific Info */
|
||||
wifi_nan_wfa_ssi_t *wfa_ssi = (wifi_nan_wfa_ssi_t *)fup_params->ssi;
|
||||
if (wfa_ssi->proto >= WIFI_SVC_PROTO_MAX) {
|
||||
ESP_LOGI(TAG, "Unrecognized WFA Defined SSI protocol (%d)",
|
||||
wfa_ssi->proto);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_USD_ENABLE
|
||||
if (s_usd_in_progress) {
|
||||
if (esp_nan_usd_transmit(fup_params->inst_id, fup_params->ssi,
|
||||
fup_params->ssi_len, fup_params->peer_mac,
|
||||
fup_params->peer_inst_id) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send Follow-up message!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_USD_ENABLE */
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
struct peer_svc_info *p_peer_svc;
|
||||
NAN_DATA_LOCK();
|
||||
p_peer_svc = nan_find_peer_svc(fup_params->inst_id, fup_params->peer_inst_id,
|
||||
fup_params->peer_mac);
|
||||
p_peer_svc = nan_find_peer_svc(fup_params->inst_id,
|
||||
fup_params->peer_inst_id, fup_params->peer_mac);
|
||||
if (!p_peer_svc) {
|
||||
ESP_LOGE(TAG, "Cannot send Follow-up, peer not found!");
|
||||
NAN_DATA_UNLOCK();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if ((fup_params->ssi_len && fup_params->ssi == NULL) ||
|
||||
(fup_params->ssi && (!fup_params->ssi_len || fup_params->ssi_len > ESP_WIFI_MAX_FUP_SSI_LEN))) {
|
||||
ESP_LOGE(TAG, "Configured ssi and ssi_len(%d) incorrect", fup_params->ssi_len);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (fup_params->ssi && !memcmp(fup_params->ssi, s_wfa_oui, sizeof(s_wfa_oui))) {
|
||||
/* WFA defined Service Specific Info */
|
||||
wifi_nan_wfa_ssi_t *wfa_ssi = (wifi_nan_wfa_ssi_t *)fup_params->ssi;
|
||||
if (wfa_ssi->proto >= WIFI_SVC_PROTO_MAX) {
|
||||
ESP_LOGI(TAG, "Unrecognized WFA Defined SSI protocol (%d)", wfa_ssi->proto);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fup_params->inst_id) {
|
||||
fup_params->inst_id = p_peer_svc->own_svc_id;
|
||||
}
|
||||
@@ -1018,9 +1119,12 @@ esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params)
|
||||
EventBits_t bits = os_event_group_wait_bits(nan_event_group, NAN_TX_SUCCESS | NAN_TX_FAILURE, pdFALSE, pdFALSE, pdMS_TO_TICKS(NAN_ACTION_TIMEOUT));
|
||||
if (bits & NAN_TX_SUCCESS) {
|
||||
if (fup_params->ssi) {
|
||||
ESP_LOGD(TAG, "Sent below payload to Peer "MACSTR" with Service ID %d",
|
||||
ESP_LOGD(TAG, "Sent below payload in Follow-up message to Peer "MACSTR" with Service ID %d",
|
||||
MAC2STR(fup_params->peer_mac), fup_params->peer_inst_id);
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, fup_params->ssi, fup_params->ssi_len, ESP_LOG_DEBUG);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Sent message to Peer "MACSTR" with Service ID %d",
|
||||
MAC2STR(fup_params->peer_mac), fup_params->peer_inst_id);
|
||||
}
|
||||
ret = ESP_OK;
|
||||
} else if (bits & NAN_TX_FAILURE) {
|
||||
@@ -1030,12 +1134,19 @@ esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params)
|
||||
ESP_LOGE(TAG, "Timeout, failed to send Follow-up message!");
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id)
|
||||
{
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_USD_ENABLE
|
||||
if (s_usd_in_progress) {
|
||||
return esp_nan_usd_cancel_service(service_id);
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_USD_ENABLE */
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
NAN_DATA_LOCK();
|
||||
struct own_svc_info *p_own_svc = nan_find_own_svc(service_id);
|
||||
|
||||
@@ -1067,8 +1178,12 @@ fail:
|
||||
done:
|
||||
NAN_DATA_UNLOCK();
|
||||
return ESP_OK;
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_SYNC_ENABLE
|
||||
uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req)
|
||||
{
|
||||
uint8_t ndp_id = 0;
|
||||
@@ -1337,3 +1452,81 @@ esp_err_t esp_wifi_nan_get_peer_info(char *svc_name, uint8_t *peer_mac, struct n
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_SYNC_ENABLE */
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_NAN_USD_ENABLE
|
||||
esp_err_t esp_wifi_nan_usd_start(void)
|
||||
{
|
||||
if (!s_usd_in_progress) {
|
||||
ESP_RETURN_ON_ERROR(esp_wifi_set_mode(WIFI_MODE_STA), "NAN-USD", "Setting STA mode failed");
|
||||
ESP_RETURN_ON_ERROR(esp_nan_usd_init(), "NAN-USD", "Failed to initialise NAN USD engine");
|
||||
s_usd_in_progress = true;
|
||||
ESP_LOGI(TAG, "NaN-USD Started");
|
||||
return ESP_OK;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_wifi_nan_usd_stop(void)
|
||||
{
|
||||
if (s_usd_in_progress) {
|
||||
s_usd_in_progress = false;
|
||||
esp_nan_usd_deinit();
|
||||
ESP_LOGI(TAG, "NaN-USD Stopped");
|
||||
return ESP_OK;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
wifi_nan_usd_config_t esp_wifi_usd_get_default_publish_cfg(void)
|
||||
{
|
||||
wifi_country_t country;
|
||||
uint8_t start_chan, end_chan;
|
||||
|
||||
wifi_nan_usd_config_t cfg = {
|
||||
.usd_default_channel = 6,
|
||||
.n_min = 5,
|
||||
.n_max = 10,
|
||||
.m_min = 5,
|
||||
.m_max = 10,
|
||||
};
|
||||
|
||||
esp_wifi_get_country(&country);
|
||||
start_chan = country.schan;
|
||||
end_chan = country.schan + country.nchan - 1;
|
||||
for (uint8_t chan = start_chan; chan <= end_chan; chan++) {
|
||||
cfg.usd_chan_bitmap.ghz_2_channels |= CHANNEL_TO_BIT(chan);
|
||||
}
|
||||
#if CONFIG_SOC_WIFI_SUPPORT_5G
|
||||
cfg.usd_chan_bitmap.ghz_5_channels = country.wifi_5g_channel_mask;
|
||||
#endif
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
wifi_nan_usd_config_t esp_wifi_usd_get_default_subscribe_cfg(void)
|
||||
{
|
||||
wifi_country_t country;
|
||||
uint8_t start_chan, end_chan;
|
||||
|
||||
wifi_nan_usd_config_t cfg = {
|
||||
.usd_default_channel = 6,
|
||||
.n_min = 5,
|
||||
.n_max = 10,
|
||||
.m_min = 5,
|
||||
.m_max = 10
|
||||
};
|
||||
|
||||
esp_wifi_get_country(&country);
|
||||
start_chan = country.schan;
|
||||
end_chan = country.schan + country.nchan - 1;
|
||||
for (uint8_t chan = start_chan; chan <= end_chan; chan++) {
|
||||
cfg.usd_chan_bitmap.ghz_2_channels |= CHANNEL_TO_BIT(chan);
|
||||
}
|
||||
#if CONFIG_SOC_WIFI_SUPPORT_5G
|
||||
cfg.usd_chan_bitmap.ghz_5_channels = country.wifi_5g_channel_mask;
|
||||
#endif
|
||||
|
||||
return cfg;
|
||||
}
|
||||
#endif /* CONFIG_ESP_WIFI_NAN_USD_ENABLE */
|
||||
|
||||
@@ -240,12 +240,21 @@ else()
|
||||
set(wps_registrar_src "")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_WIFI_NAN_USD_ENABLE)
|
||||
set(usd_src
|
||||
"src/common/nan_de.c"
|
||||
"esp_supplicant/src/esp_nan_usd.c")
|
||||
else()
|
||||
set(usd_src "")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}" "${esp_srcs}" "${tls_src}" "${roaming_src}"
|
||||
"${crypto_src}" "${mbo_src}" "${dpp_src}" "${wps_registrar_src}"
|
||||
"${crypto_src}" "${mbo_src}" "${dpp_src}" "${wps_registrar_src}" "${usd_src}"
|
||||
INCLUDE_DIRS include port/include esp_supplicant/include
|
||||
PRIV_INCLUDE_DIRS src src/utils esp_supplicant/src src/crypto
|
||||
../esp_wifi/wifi_apps/roaming_app/include
|
||||
../esp_wifi/wifi_apps/roaming_app/src
|
||||
esp_supplicant/include/esp_private
|
||||
LDFRAGMENTS ${linker_fragments}
|
||||
PRIV_REQUIRES mbedtls esp_timer esp_wifi)
|
||||
|
||||
@@ -349,6 +358,9 @@ endif()
|
||||
if(CONFIG_ESP_WIFI_EAP_TLS1_3)
|
||||
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_TLSV13)
|
||||
endif()
|
||||
if(CONFIG_ESP_WIFI_NAN_USD_ENABLE)
|
||||
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_NAN_USD)
|
||||
endif()
|
||||
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi_types.h"
|
||||
|
||||
#define GLOBAL_OPERATING_CLASS_81 81
|
||||
|
||||
#define ESP_USD_SUBSCRIBE_DEFAULT_PARAMS() { \
|
||||
.active = false, \
|
||||
.ttl = 0, \
|
||||
.freq = NAN_USD_DEFAULT_FREQ, \
|
||||
.query_period = 0, \
|
||||
};
|
||||
|
||||
#define ESP_USD_PUBLISH_DEFAULT_PARAMS() { \
|
||||
.unsolicited = true, \
|
||||
.solicited = true, \
|
||||
.ttl = 100, \
|
||||
.fsd = true, \
|
||||
.freq = NAN_USD_DEFAULT_FREQ, \
|
||||
.freq_list = NULL, \
|
||||
};
|
||||
|
||||
/* Note: These NaN-USD APIs are intended for internal use only.
|
||||
* For application development, use the public APIs provided in:
|
||||
* 'wifi_apps/nan_app/include/esp_nan.h'
|
||||
*/
|
||||
esp_err_t esp_nan_usd_init(void);
|
||||
|
||||
esp_err_t esp_nan_usd_deinit(void);
|
||||
|
||||
int esp_nan_usd_publish(const wifi_nan_publish_cfg_t *publish_cfg);
|
||||
|
||||
esp_err_t esp_nan_usd_cancel_publish(int publish_id);
|
||||
|
||||
int esp_nan_usd_subscribe(const wifi_nan_subscribe_cfg_t *subscribe_cfg);
|
||||
|
||||
esp_err_t esp_nan_usd_cancel_subscribe(int subscribe_id);
|
||||
|
||||
esp_err_t esp_nan_usd_transmit(int handle, const uint8_t *ssi, uint16_t ssi_len,
|
||||
const uint8_t *peer_addr, uint8_t req_instance_id);
|
||||
|
||||
esp_err_t esp_nan_usd_cancel_service(int service_id);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,679 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_nan_usd.h"
|
||||
#include "common/nan_de.h"
|
||||
#include "esp_wifi_driver.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "esp_nan.h"
|
||||
|
||||
struct nan_de *g_nan_de = NULL;
|
||||
|
||||
static void *s_nan_usd_data_lock = NULL;
|
||||
#define NAN_USD_DATA_LOCK() os_mutex_lock(s_nan_usd_data_lock)
|
||||
#define NAN_USD_DATA_UNLOCK() os_mutex_unlock(s_nan_usd_data_lock)
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
static const char *nan_reason_txt(enum nan_de_reason reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case NAN_DE_REASON_TIMEOUT:
|
||||
return "timeout";
|
||||
case NAN_DE_REASON_USER_REQUEST:
|
||||
return "user-request";
|
||||
case NAN_DE_REASON_FAILURE:
|
||||
return "failure";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
#endif /* DEBUG_PRINT */
|
||||
static void nan_sta_stop_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_id == WIFI_EVENT_STA_STOP) {
|
||||
esp_wifi_nan_usd_stop();
|
||||
}
|
||||
}
|
||||
|
||||
/* Per section 4.5.3 of the Wi-Fi Aware Specification v4.0 (NaN-USD),
|
||||
* only 20 MHz bandwidth channels are permitted for NAN-USD operation
|
||||
* in both the 2.4 GHz and 5 GHz frequency bands.
|
||||
* */
|
||||
static int esp_nan_chan_to_freq(uint8_t chan)
|
||||
{
|
||||
// 2.4 GHz band
|
||||
if (chan >= 1 && chan <= 13) {
|
||||
return 2407 + 5 * chan;
|
||||
} else if (chan == 14) {
|
||||
return 2414 + 5 * chan;
|
||||
}
|
||||
|
||||
// 5 GHz band — standard 20 MHz channel ranges
|
||||
if ((chan >= 36 && chan <= 64) ||
|
||||
(chan >= 100 && chan <= 144) ||
|
||||
(chan >= 149 && chan <= 165)) {
|
||||
return 5000 + chan * 5;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int esp_nan_freq_to_chan(int freq)
|
||||
{
|
||||
// 2.4 GHz band
|
||||
if (freq >= 2412 && freq <= 2472) {
|
||||
return (freq - 2407) / 5;
|
||||
} else if (freq == 2484) {
|
||||
return 14;
|
||||
}
|
||||
|
||||
// 5 GHz band
|
||||
if ((freq >= 5180 && freq <= 5240) || // Channels 36–64
|
||||
(freq >= 5500 && freq <= 5720) || // Channels 100–144
|
||||
(freq >= 5745 && freq <= 5825)) { // Channels 149–165
|
||||
return (freq - 5000) / 5;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
if (event_id == WIFI_EVENT_ACTION_TX_STATUS) {
|
||||
wifi_event_action_tx_status_t *evt = (wifi_event_action_tx_status_t *)event_data;
|
||||
if (evt->status == WIFI_ACTION_TX_DONE) {
|
||||
int freq = esp_nan_chan_to_freq(evt->channel);
|
||||
if (freq == -1) {
|
||||
wpa_printf(MSG_ERROR, "Invalid channel received from Action Tx handler");
|
||||
return;
|
||||
}
|
||||
NAN_USD_DATA_LOCK();
|
||||
nan_de_tx_status(g_nan_de, freq, NULL);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
} else if (evt->status == WIFI_ACTION_TX_DURATION_COMPLETED) {
|
||||
NAN_USD_DATA_LOCK();
|
||||
nan_de_tx_wait_ended(g_nan_de);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
}
|
||||
} else if (event_id == WIFI_EVENT_ROC_DONE) {
|
||||
wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data;
|
||||
int freq = esp_nan_chan_to_freq(evt->channel);
|
||||
if (freq == -1) {
|
||||
wpa_printf(MSG_ERROR, "Invalid channel received from ROC done handler");
|
||||
}
|
||||
NAN_USD_DATA_LOCK();
|
||||
nan_de_listen_ended(g_nan_de, freq);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
}
|
||||
}
|
||||
|
||||
int esp_nan_de_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel)
|
||||
{
|
||||
struct ieee80211_hdr *rx_hdr = (struct ieee80211_hdr *)hdr;
|
||||
int freq;
|
||||
|
||||
if (len < 6) {
|
||||
/* Frame too short for NAN-SDF frame */
|
||||
return ESP_FAIL;
|
||||
}
|
||||
/* NAN SDF
|
||||
* Category code - 1 byte
|
||||
* Public Action - 1 byte
|
||||
* OUI - 3 bytes
|
||||
* WFA subtype - 1 byte
|
||||
* NAN PROTOCOL - Variable */
|
||||
|
||||
uint8_t category = *payload++;
|
||||
uint8_t public_action = *payload++;
|
||||
uint32_t oui_value = WPA_GET_BE24(payload);
|
||||
payload += 3;
|
||||
uint8_t oui_type = *payload++;
|
||||
|
||||
if (category == WLAN_ACTION_PUBLIC &&
|
||||
public_action == WLAN_PA_VENDOR_SPECIFIC &&
|
||||
oui_value == OUI_WFA &&
|
||||
oui_type == NAN_OUI_TYPE) {
|
||||
/* Received a valid NAN Service Discovery Frame */
|
||||
} else {
|
||||
/* Frame is not a NAN SDF frame */
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
freq = esp_nan_chan_to_freq(channel);
|
||||
if (freq == -1) {
|
||||
wpa_printf(MSG_ERROR, "Invalid channel from Rx action frame");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
NAN_USD_DATA_LOCK();
|
||||
nan_de_rx_sdf(g_nan_de, rx_hdr->addr2, rx_hdr->addr3, freq, payload, len - 6);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int esp_nan_de_tx(void *ctx, unsigned int freq, unsigned int wait_time,
|
||||
const u8 *dst, const u8 *src, const u8 *bssid,
|
||||
const struct wpabuf *buf)
|
||||
{
|
||||
int buf_len = buf->used;
|
||||
int channel;
|
||||
|
||||
wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + buf_len);
|
||||
if (!req) {
|
||||
wpa_printf(MSG_ERROR, "Allocation for tx request failed");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
req->ifx = WIFI_IF_STA;
|
||||
req->type = WIFI_OFFCHAN_TX_REQ;
|
||||
req->wait_time_ms = wait_time;
|
||||
memcpy(req->dest_mac, dst, ETH_ALEN);
|
||||
memcpy(req->bssid, bssid, ETH_ALEN);
|
||||
req->no_ack = false;
|
||||
req->data_len = buf_len;
|
||||
req->rx_cb = esp_nan_de_rx_action;
|
||||
memcpy(req->data, buf->buf, buf_len);
|
||||
|
||||
channel = esp_nan_freq_to_chan(freq);
|
||||
if (channel == -1) {
|
||||
wpa_printf(MSG_ERROR, "Could not determine channel for freq %d", freq);
|
||||
os_free(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
req->channel = channel;
|
||||
|
||||
if (esp_wifi_action_tx_req(req) != ESP_OK) {
|
||||
wpa_printf(MSG_ERROR, "Offchannel tx request failed");
|
||||
os_free(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
os_free(req);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int esp_nan_de_listen(void *ctx, unsigned int freq, unsigned int duration)
|
||||
{
|
||||
int channel;
|
||||
|
||||
channel = esp_nan_freq_to_chan(freq);
|
||||
if (channel == -1) {
|
||||
wpa_printf(MSG_ERROR, "Could not determine channel for freq %d", freq);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
wifi_roc_req_t *req = os_zalloc(sizeof(wifi_roc_req_t));
|
||||
if (req == NULL) {
|
||||
wpa_printf(MSG_ERROR, "Failed to allocate for ROC request");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
req->ifx = WIFI_IF_STA;
|
||||
req->type = WIFI_ROC_REQ;
|
||||
req->channel = channel;
|
||||
req->wait_time_ms = duration;
|
||||
req->rx_cb = esp_nan_de_rx_action;
|
||||
req->done_cb = NULL;
|
||||
req->allow_broadcast = true;
|
||||
|
||||
if (esp_wifi_remain_on_channel(req) != ESP_OK) {
|
||||
wpa_printf(MSG_ERROR, "ROC request failure");
|
||||
os_free(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
NAN_USD_DATA_LOCK();
|
||||
nan_de_listen_started(g_nan_de, freq, duration);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
os_free(req);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void esp_nan_de_discovery_result(void *ctx, int subscribe_id, enum nan_service_protocol_type srv_proto_type,
|
||||
const u8 *ssi, size_t ssi_len, int peer_publish_id, const u8 *peer_addr, bool fsd, bool fsd_gas)
|
||||
{
|
||||
wpa_printf(MSG_INFO, "NAN_USD DISCOVERY_RESULT - subscribe_id = %d peer_publish_id = %d peer_address = "MACSTR" service_protocol_type = %d",
|
||||
subscribe_id, peer_publish_id, MAC2STR(peer_addr), srv_proto_type);
|
||||
|
||||
wifi_event_nan_svc_match_t *evt = os_zalloc(sizeof(wifi_event_nan_svc_match_t) + ssi_len);
|
||||
if (evt == NULL) {
|
||||
return;
|
||||
}
|
||||
evt->subscribe_id = subscribe_id;
|
||||
evt->publish_id = peer_publish_id;
|
||||
memcpy(evt->pub_if_mac, peer_addr, ETH_ALEN);
|
||||
if (ssi && ssi_len) {
|
||||
memcpy(evt->ssi, ssi, ssi_len);
|
||||
evt->ssi_len = ssi_len;
|
||||
}
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_NAN_SVC_MATCH, evt, sizeof(wifi_event_nan_svc_match_t) + ssi_len, portMAX_DELAY);
|
||||
os_free(evt);
|
||||
}
|
||||
|
||||
static void esp_nan_de_replied(void *ctx, int publish_id, const u8 *peer_addr,
|
||||
int peer_subscribe_id,
|
||||
enum nan_service_protocol_type srv_proto_type,
|
||||
const u8 *ssi, size_t ssi_len)
|
||||
{
|
||||
|
||||
wpa_printf(MSG_INFO, "NAN_USD REPLIED - publish_id = %d peer_subscribe_id = %d peer_address = "MACSTR" service_protocol_type = %d",
|
||||
publish_id, peer_subscribe_id, MAC2STR(peer_addr), srv_proto_type);
|
||||
|
||||
wifi_event_nan_replied_t *evt = os_zalloc(sizeof(wifi_event_nan_replied_t) + ssi_len);
|
||||
if (evt == NULL) {
|
||||
return;
|
||||
}
|
||||
evt->publish_id = publish_id;
|
||||
evt->subscribe_id = peer_subscribe_id;
|
||||
memcpy(evt->sub_if_mac, peer_addr, ETH_ALEN);
|
||||
if (ssi && ssi_len) {
|
||||
memcpy(evt->ssi, ssi, ssi_len);
|
||||
evt->ssi_len = ssi_len;
|
||||
}
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_NAN_REPLIED, evt, sizeof(wifi_event_nan_replied_t) + ssi_len, portMAX_DELAY);
|
||||
os_free(evt);
|
||||
}
|
||||
|
||||
static void esp_nan_de_publish_terminated(void *ctx, int publish_id,
|
||||
enum nan_de_reason reason)
|
||||
{
|
||||
wpa_printf(MSG_INFO, "NAN_USD PUBLISH_TERMINATED - publish_id = %d reason = %s", publish_id, nan_reason_txt(reason));
|
||||
}
|
||||
|
||||
static void esp_nan_de_subscribe_terminated(void *ctx, int subscribe_id,
|
||||
enum nan_de_reason reason)
|
||||
{
|
||||
wpa_printf(MSG_INFO, "NAN_USD SUBSCRIBE_TERMINATED - subscribe_id = %d reason = %s", subscribe_id, nan_reason_txt(reason));
|
||||
}
|
||||
|
||||
static void esp_nan_de_receive(void *ctx, int id, int peer_instance_id,
|
||||
const u8 *ssi, size_t ssi_len,
|
||||
const u8 *peer_addr)
|
||||
{
|
||||
wpa_hexdump(MSG_INFO, "NAN_RECEIVE", ssi, ssi_len);
|
||||
|
||||
wifi_event_nan_receive_t *evt = os_zalloc(sizeof(wifi_event_nan_receive_t) + ssi_len);
|
||||
if (evt == NULL) {
|
||||
return;
|
||||
}
|
||||
evt->inst_id = id;
|
||||
evt->peer_inst_id = peer_instance_id;
|
||||
memcpy(evt->peer_if_mac, peer_addr, ETH_ALEN);
|
||||
if (ssi && ssi_len) {
|
||||
memcpy(evt->ssi, ssi, ssi_len);
|
||||
evt->ssi_len = ssi_len;
|
||||
}
|
||||
esp_event_post(WIFI_EVENT, WIFI_EVENT_NAN_RECEIVE, evt, sizeof(wifi_event_nan_receive_t) + ssi_len, portMAX_DELAY);
|
||||
os_free(evt);
|
||||
}
|
||||
|
||||
esp_err_t esp_nan_usd_deinit()
|
||||
{
|
||||
|
||||
NAN_USD_DATA_LOCK();
|
||||
if (!g_nan_de) {
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
nan_de_deinit(g_nan_de);
|
||||
g_nan_de = NULL;
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
|
||||
if (s_nan_usd_data_lock) {
|
||||
os_mutex_delete(s_nan_usd_data_lock);
|
||||
s_nan_usd_data_lock = NULL;
|
||||
}
|
||||
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, &nan_de_tx_event_handler);
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, &nan_de_tx_event_handler);
|
||||
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP,
|
||||
&nan_sta_stop_handler);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_nan_usd_init(void)
|
||||
{
|
||||
struct nan_callbacks cb;
|
||||
uint8_t mac[ETH_ALEN];
|
||||
#ifndef ESP_SUPPLICANT
|
||||
bool offload = wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_OFFLOAD;
|
||||
#else
|
||||
bool offload = false;
|
||||
#endif
|
||||
int max_listen = 1000; // default supplicant value; hardcoded for now
|
||||
|
||||
os_memset(&cb, 0, sizeof(cb));
|
||||
cb.ctx = NULL;
|
||||
cb.tx = esp_nan_de_tx;
|
||||
cb.listen = esp_nan_de_listen;
|
||||
cb.discovery_result = esp_nan_de_discovery_result;
|
||||
cb.replied = esp_nan_de_replied;
|
||||
cb.publish_terminated = esp_nan_de_publish_terminated;
|
||||
cb.subscribe_terminated = esp_nan_de_subscribe_terminated;
|
||||
cb.receive = esp_nan_de_receive;
|
||||
|
||||
s_nan_usd_data_lock = os_recursive_mutex_create();
|
||||
if (!s_nan_usd_data_lock) {
|
||||
ESP_LOGE("NAN-USD", "Failed to create NAN-USD data lock");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_RETURN_ON_ERROR(esp_wifi_get_mac(WIFI_IF_STA, mac), "NAN-USD", "Fetching MAC of STA ifx failed");
|
||||
g_nan_de = nan_de_init(mac, offload, false, max_listen, &cb);
|
||||
if (!g_nan_de) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS,
|
||||
&nan_de_tx_event_handler, NULL);
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ROC_DONE,
|
||||
&nan_de_tx_event_handler, NULL);
|
||||
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_STOP,
|
||||
&nan_sta_stop_handler, NULL);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int esp_nan_get_freq_list(int *freq_list, const uint8_t *chan_list, uint8_t chan_list_len)
|
||||
{
|
||||
int freq, freq_ind = 0;
|
||||
for (int i = 0; i < chan_list_len; i++) {
|
||||
freq = esp_nan_chan_to_freq(chan_list[i]);
|
||||
if (freq != -1) {
|
||||
freq_list[freq_ind++] = freq;
|
||||
}
|
||||
}
|
||||
freq_list[freq_ind++] = 0;
|
||||
return freq_ind;
|
||||
}
|
||||
|
||||
static int esp_nan_usd_publish_internal(const char *service_name, enum nan_service_protocol_type srv_proto_type,
|
||||
unsigned int ttl, uint8_t *ssi, uint16_t ssi_len, uint8_t default_channel,
|
||||
const wifi_scan_channel_bitmap_t channel_bitmap)
|
||||
{
|
||||
int publish_id;
|
||||
struct wpabuf *buf = NULL;
|
||||
int freq, *freq_list = NULL;
|
||||
struct nan_publish_params pub_params = ESP_USD_PUBLISH_DEFAULT_PARAMS();
|
||||
bool p2p = false;
|
||||
uint8_t i = 0, chan_list_len;
|
||||
uint8_t bitmap_idx_2g = 1; // BIT-0 is not used in channel bitmap
|
||||
uint16_t channel_2ghz_bitmap;
|
||||
#if CONFIG_SOC_WIFI_SUPPORT_5G
|
||||
uint8_t bitmap_idx_5g = 1; // BIT-0 is not used in channel bitmap
|
||||
uint32_t channel_5ghz_bitmap;
|
||||
#endif
|
||||
|
||||
NAN_USD_DATA_LOCK();
|
||||
if (!g_nan_de) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pub_params.ttl = ttl;
|
||||
if (ssi && ssi_len) {
|
||||
buf = wpabuf_alloc(ssi_len);
|
||||
if (!buf) {
|
||||
wpa_printf(MSG_ERROR, "Allocating memory failed for NaN-USD Publish");
|
||||
goto fail;
|
||||
}
|
||||
wpabuf_put_data(buf, ssi, ssi_len);
|
||||
}
|
||||
|
||||
freq = esp_nan_chan_to_freq(default_channel);
|
||||
if (freq != -1) {
|
||||
pub_params.freq = freq;
|
||||
} else {
|
||||
pub_params.freq = NAN_USD_DEFAULT_FREQ;
|
||||
}
|
||||
|
||||
channel_2ghz_bitmap = channel_bitmap.ghz_2_channels;
|
||||
channel_2ghz_bitmap &= ~BIT(0); // BIT-0 is not used for channel
|
||||
chan_list_len = __builtin_popcount(channel_2ghz_bitmap);
|
||||
|
||||
#if CONFIG_SOC_WIFI_SUPPORT_5G
|
||||
channel_5ghz_bitmap = channel_bitmap.ghz_5_channels;
|
||||
channel_5ghz_bitmap &= ~BIT(0); // BIT-0 is not used for channel
|
||||
chan_list_len += __builtin_popcount(channel_5ghz_bitmap);
|
||||
#endif
|
||||
|
||||
if (chan_list_len) {
|
||||
uint8_t chan_list[chan_list_len];
|
||||
while (channel_2ghz_bitmap) {
|
||||
bitmap_idx_2g = __builtin_ctz(channel_2ghz_bitmap);
|
||||
uint8_t chan_num = BIT_NUMBER_TO_CHANNEL(bitmap_idx_2g, WIFI_BAND_2G);
|
||||
if (chan_num != 0) {
|
||||
chan_list[i++] = chan_num;
|
||||
}
|
||||
channel_2ghz_bitmap &= ~BIT(bitmap_idx_2g);
|
||||
}
|
||||
#if CONFIG_SOC_WIFI_SUPPORT_5G
|
||||
while (channel_5ghz_bitmap) {
|
||||
bitmap_idx_5g = __builtin_ctz(channel_5ghz_bitmap);
|
||||
uint8_t chan_num = BIT_NUMBER_TO_CHANNEL(bitmap_idx_5g, WIFI_BAND_5G);
|
||||
if (chan_num != 0) {
|
||||
chan_list[i++] = chan_num;
|
||||
}
|
||||
channel_5ghz_bitmap &= ~BIT(bitmap_idx_5g);
|
||||
}
|
||||
#endif
|
||||
|
||||
chan_list_len = i;
|
||||
freq_list = (int *)os_malloc(sizeof(int) * (chan_list_len + 1));
|
||||
if (freq_list) {
|
||||
esp_nan_get_freq_list(freq_list, chan_list, chan_list_len);
|
||||
pub_params.freq_list = freq_list;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Allocating memory failed for frequency list");
|
||||
wpabuf_free(buf);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
publish_id = nan_de_publish(g_nan_de, service_name, srv_proto_type,
|
||||
buf, NULL, &pub_params, p2p);
|
||||
|
||||
wpabuf_free(buf);
|
||||
if (freq_list) {
|
||||
os_free(freq_list);
|
||||
}
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return publish_id;
|
||||
fail:
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int esp_nan_usd_publish(const wifi_nan_publish_cfg_t *publish_cfg)
|
||||
{
|
||||
return esp_nan_usd_publish_internal(publish_cfg->service_name, WIFI_SVC_PROTO_RESERVED,
|
||||
publish_cfg->ttl, publish_cfg->ssi,
|
||||
publish_cfg->ssi_len, publish_cfg->usd_publish_config.usd_default_channel,
|
||||
publish_cfg->usd_publish_config.usd_chan_bitmap);
|
||||
}
|
||||
|
||||
esp_err_t esp_nan_usd_update_publish(int publish_id, uint8_t *ssi, uint16_t ssi_len)
|
||||
{
|
||||
struct wpabuf *buf = NULL;
|
||||
esp_err_t ret;
|
||||
|
||||
NAN_USD_DATA_LOCK();
|
||||
if (!g_nan_de) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ssi && ssi_len) {
|
||||
buf = wpabuf_alloc(ssi_len);
|
||||
if (!buf) {
|
||||
wpa_printf(MSG_ERROR, "Allocating memory failed for NaN-USD Update Publish");
|
||||
goto fail;
|
||||
}
|
||||
wpabuf_put_data(buf, ssi, ssi_len);
|
||||
}
|
||||
|
||||
ret = nan_de_update_publish(g_nan_de, publish_id, buf);
|
||||
wpabuf_free(buf);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ret;
|
||||
fail:
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_nan_usd_cancel_publish(int publish_id)
|
||||
{
|
||||
NAN_USD_DATA_LOCK();
|
||||
if (!g_nan_de) {
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
nan_de_cancel_publish(g_nan_de, publish_id);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Note: Our USD implementation uses the Service Protocol Type provided in SSI.
|
||||
* The 'srv_proto_type' parameter will be ignored.
|
||||
*/
|
||||
static int esp_nan_usd_subscribe_internal(const char *service_name, enum nan_service_protocol_type srv_proto_type,
|
||||
unsigned int ttl, uint8_t default_channel, uint8_t *ssi, uint16_t ssi_len,
|
||||
const wifi_scan_channel_bitmap_t channel_bitmap)
|
||||
{
|
||||
int subscribe_id;
|
||||
struct wpabuf *buf = NULL;
|
||||
int freq, *freq_list = NULL;
|
||||
/* USD Specification allows either active or passive mode for subscriber.
|
||||
* By default USD-Subscriber will be in passive mode */
|
||||
struct nan_subscribe_params sub_params = ESP_USD_SUBSCRIBE_DEFAULT_PARAMS();
|
||||
bool p2p = false;
|
||||
uint8_t i = 0, chan_list_len;
|
||||
uint8_t bitmap_idx_2g = 1; // BIT-0 is not used in channel bitmap
|
||||
uint16_t channel_2ghz_bitmap;
|
||||
|
||||
NAN_USD_DATA_LOCK();
|
||||
if (!g_nan_de) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sub_params.ttl = ttl;
|
||||
freq = esp_nan_chan_to_freq(default_channel);
|
||||
if (freq != -1) {
|
||||
sub_params.freq = freq;
|
||||
} else {
|
||||
sub_params.freq = NAN_USD_DEFAULT_FREQ;
|
||||
}
|
||||
|
||||
if (ssi && ssi_len) {
|
||||
buf = wpabuf_alloc(ssi_len);
|
||||
if (!buf) {
|
||||
wpa_printf(MSG_ERROR, "Allocating memory failed for NaN-USD Subscribe");
|
||||
goto fail;
|
||||
}
|
||||
wpabuf_put_data(buf, ssi, ssi_len);
|
||||
}
|
||||
|
||||
channel_2ghz_bitmap = channel_bitmap.ghz_2_channels;
|
||||
channel_2ghz_bitmap &= ~BIT(0); // BIT-0 is not used for channel
|
||||
chan_list_len = __builtin_popcount(channel_2ghz_bitmap);
|
||||
if (chan_list_len) {
|
||||
uint8_t chan_list[chan_list_len];
|
||||
while (channel_2ghz_bitmap) {
|
||||
bitmap_idx_2g = __builtin_ctz(channel_2ghz_bitmap);
|
||||
uint8_t chan_num = BIT_NUMBER_TO_CHANNEL(bitmap_idx_2g, WIFI_BAND_2G);
|
||||
if (chan_num != 0) {
|
||||
chan_list[i++] = chan_num;
|
||||
}
|
||||
channel_2ghz_bitmap &= ~BIT(bitmap_idx_2g);
|
||||
}
|
||||
freq_list = (int *)os_malloc(sizeof(int) * (chan_list_len + 1));
|
||||
if (freq_list) {
|
||||
esp_nan_get_freq_list(freq_list, chan_list, chan_list_len);
|
||||
sub_params.freq_list = freq_list;
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Allocating memory failed for frequency list");
|
||||
wpabuf_free(buf);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
subscribe_id = nan_de_subscribe(g_nan_de, service_name, srv_proto_type, buf, NULL, &sub_params, p2p);
|
||||
|
||||
wpabuf_free(buf);
|
||||
if (freq_list) {
|
||||
os_free(freq_list);
|
||||
}
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return subscribe_id;
|
||||
fail:
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int esp_nan_usd_subscribe(const wifi_nan_subscribe_cfg_t *subscribe_cfg)
|
||||
{
|
||||
return esp_nan_usd_subscribe_internal(subscribe_cfg->service_name, WIFI_SVC_PROTO_RESERVED, subscribe_cfg->ttl,
|
||||
subscribe_cfg->usd_subscribe_config.usd_default_channel, subscribe_cfg->ssi, subscribe_cfg->ssi_len,
|
||||
subscribe_cfg->usd_subscribe_config.usd_chan_bitmap);
|
||||
}
|
||||
|
||||
esp_err_t esp_nan_usd_cancel_subscribe(int subscribe_id)
|
||||
{
|
||||
NAN_USD_DATA_LOCK();
|
||||
if (!g_nan_de) {
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
nan_de_cancel_subscribe(g_nan_de, subscribe_id);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_nan_usd_cancel_service(int service_id)
|
||||
{
|
||||
NAN_USD_DATA_LOCK();
|
||||
if (!g_nan_de) {
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
nan_de_cancel_service(g_nan_de, service_id);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_nan_usd_transmit(int handle, const uint8_t *ssi, uint16_t ssi_len, const u8 *peer_addr, u8 req_instance_id)
|
||||
{
|
||||
struct wpabuf *buf = NULL;
|
||||
esp_err_t ret;
|
||||
|
||||
NAN_USD_DATA_LOCK();
|
||||
if (!g_nan_de || !peer_addr) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ssi && ssi_len) {
|
||||
buf = wpabuf_alloc(ssi_len);
|
||||
if (!buf) {
|
||||
wpa_printf(MSG_ERROR, "Allocating memory failed for NaN-USD transmit");
|
||||
goto fail;
|
||||
}
|
||||
wpabuf_put_data(buf, ssi, ssi_len);
|
||||
}
|
||||
|
||||
ret = nan_de_transmit(g_nan_de, handle, buf, NULL, peer_addr, req_instance_id);
|
||||
|
||||
wpabuf_free(buf);
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ret;
|
||||
fail:
|
||||
NAN_USD_DATA_UNLOCK();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -567,8 +567,12 @@ struct ieee80211_ht_operation {
|
||||
/* 2 - Reserved */
|
||||
#define WMM_TSPEC_DIRECTION_BI_DIRECTIONAL 3
|
||||
|
||||
#define MBO_IE_VENDOR_TYPE 0x506f9a16
|
||||
#define OSEN_IE_VENDOR_TYPE 0x506f9a12
|
||||
#define NAN_IE_VENDOR_TYPE 0x506f9a13
|
||||
#define NAN_SDF_VENDOR_TYPE 0x506f9a13
|
||||
#define NAN_OUI_TYPE 0x13
|
||||
#define MBO_IE_VENDOR_TYPE 0x506f9a16
|
||||
#define NAN_NAF_VENDOR_TYPE 0x506f9a18
|
||||
#define SAE_PK_IE_VENDOR_TYPE 0x506f9a1f
|
||||
#define SAE_PK_OUI_TYPE 0x1f
|
||||
#define MBO_OUI_TYPE 22
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* NAN (Wi-Fi Aware) definitions
|
||||
* Copyright (c) 2024, Qualcomm Innovation Center, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef NAN_H
|
||||
#define NAN_H
|
||||
|
||||
enum nan_attr_id {
|
||||
NAN_ATTR_MASTER_INDICATION = 0x00,
|
||||
NAN_ATTR_CLUSTER = 0x01,
|
||||
NAN_ATTR_NAN_ATTR_SERVICE_ID_LIST = 0x02,
|
||||
NAN_ATTR_SDA = 0x03, /* Service Descriptor attribute */
|
||||
NAN_ATTR_CONN_CAPA = 0x04,
|
||||
NAN_ATTR_WLAN_INFRA = 0x05,
|
||||
NAN_ATTR_P2P_OPER = 0x06,
|
||||
NAN_ATTR_IBSS = 0x07,
|
||||
NAN_ATTR_MESH = 0x08,
|
||||
NAN_ATTR_FURTHER_NAN_SD = 0x09,
|
||||
NAN_ATTR_FURTHER_AVAIL_MAP = 0x0A,
|
||||
NAN_ATTR_COUNTRY_CODE = 0x0B,
|
||||
NAN_ATTR_RANGIN = 0x0C,
|
||||
NAN_ATTR_CLUSTER_DISCOVERY = 0x0D,
|
||||
NAN_ATTR_SDEA = 0x0E, /* Service Descriptor Extension attribute */
|
||||
NAN_ATTR_DEVICE_CAPABILITY = 0x0F,
|
||||
NAN_ATTR_NDP = 0x10,
|
||||
NAN_ATTR_NAN_AVAILABILITY = 0x12,
|
||||
NAN_ATTR_NDC = 0x13,
|
||||
NAN_ATTR_NDL = 0x14,
|
||||
NAN_ATTR_NDL_QOS = 0x15,
|
||||
NAN_ATTR_UNALIGNED_SCHEDULE = 0x17,
|
||||
NAN_ATTR_RANGING_INFO = 0x1A,
|
||||
NAN_ATTR_RANGING_SETUP = 0x1B,
|
||||
NAN_ATTR_FTM_RANGING_REPORT = 0x1C,
|
||||
NAN_ATTR_ELEM_CONTAINER = 0x1D,
|
||||
NAN_ATTR_EXT_WLAN_INFRA = 0x1E,
|
||||
NAN_ATTR_EXT_P2P_OPER = 0x1FE,
|
||||
NAN_ATTR_EXT_IBSS = 0x20,
|
||||
NAN_ATTR_EXT_MESH = 0x21,
|
||||
NAN_ATTR_CSIA = 0x22, /* Cipher Suite Info attribute */
|
||||
NAN_ATTR_SCIA = 0x23, /* Security Context Info attribute */
|
||||
NAN_ATTR_SHARED_KEY_DESCR = 0x24,
|
||||
NAN_ATTR_PUBLIC_AVAILABILITY = 0x27,
|
||||
NAN_ATTR_SUBSC_SERVICE_ID_LIST = 0x28,
|
||||
NAN_ATTR_NDP_EXT = 0x29,
|
||||
NAN_ATTR_DCEA = 0x2A, /* Device Capability Extension attribute */
|
||||
NAN_ATTR_NIRA = 0x2B, /* NAN Identity Resolution attribute */
|
||||
NAN_ATTR_BPBA = 0x2C, /* NAN Pairing Bootstrapping attribute */
|
||||
NAN_ATTR_S3 = 0x2D,
|
||||
NAN_ATTR_TPEA = 0x2E, /* Transmit Power Envelope attribute */
|
||||
NAN_ATTR_VENDOR_SPECIFIC = 0xDD,
|
||||
};
|
||||
|
||||
/* Service Descriptor attribute (SDA) */
|
||||
|
||||
/* Service Control field */
|
||||
#define NAN_SRV_CTRL_TYPE_MASK (BIT(0) | BIT(1))
|
||||
#define NAN_SRV_CTRL_MATCHING_FILTER BIT(2)
|
||||
#define NAN_SRV_CTRL_RESP_FILTER BIT(3)
|
||||
#define NAN_SRV_CTRL_SRV_INFO BIT(4)
|
||||
#define NAN_SRV_CTRL_DISCOVERY_RANGE_LIMITED BIT(5)
|
||||
#define NAN_SRV_CTRL_BINDING_BITMAP BIT(6)
|
||||
|
||||
enum nan_service_control_type {
|
||||
NAN_SRV_CTRL_PUBLISH = 0,
|
||||
NAN_SRV_CTRL_SUBSCRIBE = 1,
|
||||
NAN_SRV_CTRL_FOLLOW_UP = 2,
|
||||
};
|
||||
|
||||
/* Service Descriptor Extension attribute (SDEA) */
|
||||
|
||||
/* SDEA Control field */
|
||||
#define NAN_SDEA_CTRL_FSD_REQ BIT(0)
|
||||
#define NAN_SDEA_CTRL_FSD_GAS BIT(1)
|
||||
#define NAN_SDEA_CTRL_DATA_PATH_REQ BIT(2)
|
||||
#define NAN_SDEA_CTRL_DATA_PATH_TYPE BIT(3)
|
||||
#define NAN_SDEA_CTRL_QOS_REQ BIT(5)
|
||||
#define NAN_SDEA_CTRL_SECURITY_REQ BIT(6)
|
||||
#define NAN_SDEA_CTRL_RANGING_REQ BIT(7)
|
||||
#define NAN_SDEA_CTRL_RANGE_LIMIT BIT(8)
|
||||
#define NAN_SDEA_CTRL_SRV_UPD_INDIC BIT(9)
|
||||
#define NAN_SDEA_CTRL_GTK_REQ BIT(10)
|
||||
|
||||
enum nan_service_protocol_type {
|
||||
NAN_SRV_PROTO_BONJOUR = 1,
|
||||
NAN_SRV_PROTO_GENERIC = 2,
|
||||
NAN_SRV_PROTO_CSA_MATTER = 3,
|
||||
};
|
||||
|
||||
#define NAN_ATTR_HDR_LEN 3
|
||||
#define NAN_SERVICE_ID_LEN 6
|
||||
|
||||
#define NAN_USD_DEFAULT_FREQ 2437
|
||||
|
||||
#endif /* NAN_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* NAN Discovery Engine
|
||||
* Copyright (c) 2024, Qualcomm Innovation Center, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef NAN_DE_H
|
||||
#define NAN_DE_H
|
||||
|
||||
#include "nan.h"
|
||||
#include "utils/common.h"
|
||||
|
||||
/* Maximum number of active local publish and subscribe instances */
|
||||
#ifndef NAN_DE_MAX_SERVICE
|
||||
#ifndef ESP_SUPPLICANT
|
||||
#define NAN_DE_MAX_SERVICE 20
|
||||
#else
|
||||
#define NAN_DE_MAX_SERVICE 2
|
||||
#endif
|
||||
#endif /* NAN_DE_MAX_SERVICE */
|
||||
|
||||
struct nan_de;
|
||||
|
||||
enum nan_de_reason {
|
||||
NAN_DE_REASON_TIMEOUT,
|
||||
NAN_DE_REASON_USER_REQUEST,
|
||||
NAN_DE_REASON_FAILURE,
|
||||
};
|
||||
|
||||
struct nan_callbacks {
|
||||
void *ctx;
|
||||
|
||||
int (*tx)(void *ctx, unsigned int freq, unsigned int wait_time,
|
||||
const u8 *dst, const u8 *src, const u8 *bssid,
|
||||
const struct wpabuf *buf);
|
||||
int (*listen)(void *ctx, unsigned int freq, unsigned int duration);
|
||||
|
||||
/* NAN DE Events */
|
||||
void (*discovery_result)(void *ctx, int subscribe_id,
|
||||
enum nan_service_protocol_type srv_proto_type,
|
||||
const u8 *ssi, size_t ssi_len,
|
||||
int peer_publish_id,
|
||||
const u8 *peer_addr, bool fsd, bool fsd_gas);
|
||||
|
||||
void (*replied)(void *ctx, int publish_id, const u8 *peer_addr,
|
||||
int peer_subscribe_id,
|
||||
enum nan_service_protocol_type srv_proto_type,
|
||||
const u8 *ssi, size_t ssi_len);
|
||||
|
||||
void (*publish_terminated)(void *ctx, int publish_id,
|
||||
enum nan_de_reason reason);
|
||||
|
||||
void (*subscribe_terminated)(void *ctx, int subscribe_id,
|
||||
enum nan_de_reason reason);
|
||||
|
||||
void (*receive)(void *ctx, int id, int peer_instance_id,
|
||||
const u8 *ssi, size_t ssi_len,
|
||||
const u8 *peer_addr);
|
||||
};
|
||||
|
||||
bool nan_de_is_nan_network_id(const u8 *addr);
|
||||
bool nan_de_is_p2p_network_id(const u8 *addr);
|
||||
struct nan_de * nan_de_init(const u8 *nmi, bool offload, bool ap,
|
||||
unsigned int max_listen,
|
||||
const struct nan_callbacks *cb);
|
||||
void nan_de_flush(struct nan_de *de);
|
||||
void nan_de_deinit(struct nan_de *de);
|
||||
|
||||
void nan_de_listen_started(struct nan_de *de, unsigned int freq,
|
||||
unsigned int duration);
|
||||
void nan_de_listen_ended(struct nan_de *de, unsigned int freq);
|
||||
void nan_de_tx_status(struct nan_de *de, unsigned int freq, const u8 *dst);
|
||||
void nan_de_tx_wait_ended(struct nan_de *de);
|
||||
|
||||
void nan_de_rx_sdf(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
|
||||
unsigned int freq, const u8 *buf, size_t len);
|
||||
const u8 * nan_de_get_service_id(struct nan_de *de, int id);
|
||||
|
||||
struct nan_publish_params {
|
||||
/* configuration_parameters */
|
||||
|
||||
/* Publish type */
|
||||
bool unsolicited;
|
||||
bool solicited;
|
||||
|
||||
/* Solicited transmission type */
|
||||
bool solicited_multicast;
|
||||
|
||||
/* Time to live (in seconds); 0 = one TX only */
|
||||
unsigned int ttl;
|
||||
|
||||
/* Event conditions */
|
||||
bool disable_events;
|
||||
|
||||
/* Further Service Discovery flag */
|
||||
bool fsd;
|
||||
|
||||
/* Further Service Discovery function */
|
||||
bool fsd_gas;
|
||||
|
||||
/* Default frequency (defaultPublishChannel) */
|
||||
unsigned int freq;
|
||||
|
||||
/* Multi-channel frequencies (publishChannelList) */
|
||||
const int *freq_list;
|
||||
|
||||
/* Announcement period in ms; 0 = use default */
|
||||
unsigned int announcement_period;
|
||||
};
|
||||
|
||||
/* Returns -1 on failure or >0 publish_id */
|
||||
int nan_de_publish(struct nan_de *de, const char *service_name,
|
||||
enum nan_service_protocol_type srv_proto_type,
|
||||
const struct wpabuf *ssi, const struct wpabuf *elems,
|
||||
struct nan_publish_params *params, bool p2p);
|
||||
|
||||
void nan_de_cancel_publish(struct nan_de *de, int publish_id);
|
||||
|
||||
int nan_de_update_publish(struct nan_de *de, int publish_id,
|
||||
const struct wpabuf *ssi);
|
||||
|
||||
struct nan_subscribe_params {
|
||||
/* configuration_parameters */
|
||||
|
||||
/* Subscribe type */
|
||||
bool active;
|
||||
|
||||
/* Time to live (in seconds); 0 = until first result */
|
||||
unsigned int ttl;
|
||||
|
||||
/* Selected frequency */
|
||||
unsigned int freq;
|
||||
|
||||
/* Multi-channel frequencies (publishChannelList) */
|
||||
const int *freq_list;
|
||||
|
||||
/* Query period in ms; 0 = use default */
|
||||
unsigned int query_period;
|
||||
};
|
||||
|
||||
/* Returns -1 on failure or >0 subscribe_id */
|
||||
int nan_de_subscribe(struct nan_de *de, const char *service_name,
|
||||
enum nan_service_protocol_type srv_proto_type,
|
||||
const struct wpabuf *ssi, const struct wpabuf *elems,
|
||||
struct nan_subscribe_params *params, bool p2p);
|
||||
|
||||
void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id);
|
||||
|
||||
/* handle = publish_id or subscribe_id
|
||||
* req_instance_id = peer publish_id or subscribe_id */
|
||||
int nan_de_transmit(struct nan_de *de, int handle,
|
||||
const struct wpabuf *ssi, const struct wpabuf *elems,
|
||||
const u8 *peer_addr, u8 req_instance_id);
|
||||
|
||||
#ifdef ESP_SUPPLICANT
|
||||
void nan_de_cancel_service(struct nan_de *de, int service_id);
|
||||
#endif
|
||||
#endif /* NAN_DE_H */
|
||||
@@ -543,6 +543,23 @@ int os_reltime_initialized(struct os_reltime *t)
|
||||
return t->sec != 0 || t->usec != 0;
|
||||
}
|
||||
|
||||
void os_reltime_add_ms(struct os_reltime *ts, int ms)
|
||||
{
|
||||
ts->usec += ms * 1000;
|
||||
while (ts->usec >= 1000000) {
|
||||
ts->sec++;
|
||||
ts->usec -= 1000000;
|
||||
}
|
||||
while (ts->usec < 0) {
|
||||
ts->sec--;
|
||||
ts->usec += 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
int os_reltime_in_ms(struct os_reltime *ts)
|
||||
{
|
||||
return ts->sec * 1000 + ts->usec / 1000;
|
||||
}
|
||||
|
||||
u8 rssi_to_rcpi(int rssi)
|
||||
{
|
||||
|
||||
@@ -398,6 +398,8 @@ int os_reltime_expired(struct os_time *now,
|
||||
struct os_time *ts,
|
||||
os_time_t timeout_secs);
|
||||
int os_reltime_initialized(struct os_reltime *t);
|
||||
void os_reltime_add_ms(struct os_reltime *ts, int ms);
|
||||
int os_reltime_in_ms(struct os_reltime *ts);
|
||||
|
||||
#ifdef CONFIG_NATIVE_WINDOWS
|
||||
void wpa_unicode2ascii_inplace(TCHAR *str);
|
||||
@@ -435,6 +437,11 @@ static inline int is_multicast_ether_addr(const u8 *a)
|
||||
return a[0] & 0x01;
|
||||
}
|
||||
|
||||
static inline bool ether_addr_equal(const u8 *a, const u8 *b)
|
||||
{
|
||||
return os_memcmp(a, b, ETH_ALEN) == 0;
|
||||
}
|
||||
|
||||
#define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff"
|
||||
|
||||
|
||||
|
||||
@@ -2094,6 +2094,14 @@ Detailed information on creating certificates and how to run wpa2_enterprise exa
|
||||
|
||||
Refer to ESP-IDF examples :idf_file:`examples/wifi/wifi_aware/nan_publisher/README.md` and :idf_file:`examples/wifi/wifi_aware/nan_subscriber/README.md` to setup a NAN Publisher and Subscriber.
|
||||
|
||||
Wi-Fi Aware\ :sup:`TM` (NAN): Unsynchronized Service Discovery (USD)
|
||||
--------------------------------------------------------------------
|
||||
Unsynchronized Service Discovery (USD) is a mechanism for devices to discover the services that have been made discoverable on new devices that enter the RF environment, without requiring synchronization between the devices.
|
||||
|
||||
USD uses Service Info field in the SDEA of a Publish and Follow-up message to convey the service specific information.
|
||||
|
||||
Refer to ESP-IDF examples :idf_file:`examples/wifi/wifi_aware/usd_publisher/README.md` and :idf_file:`examples/wifi/wifi_aware/usd_subscriber/README.md` to setup a NAN-USD Publisher and Subscriber.
|
||||
|
||||
Wireless Network Management
|
||||
----------------------------
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ Application Examples
|
||||
|
||||
- :example:`wifi/wifi_aware/nan_subscriber` demonstrates how to use the NAN protocol to discover other devices that publishes the required service in the proximity, and communicate with them either by sending a message or initiating a datapath.
|
||||
|
||||
- :example:`wifi/wifi_aware/usd_publisher` demonstrates how to use lightweight NAN Unsynchronized Service Discovery (NAN-USD) to advertise a service to nearby devices without forming NAN clusters. It walks through bringing up USD, publishing a service, responding to subscribers with follow-up messages, and returning to the idle state once discovery completes.
|
||||
|
||||
- :example:`wifi/wifi_aware/usd_subscriber` demonstrates how to use the lightweight NAN Unsynchronized Service Discovery (NAN-USD) protocol to discover services advertised by nearby devices and interact with them. It covers enabling USD discovery, subscribing to services, handling follow-up exchanges, and terminating discovery after the session ends.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
|
||||
@@ -46,4 +46,18 @@ The following Wi-Fi functions have been modified.
|
||||
|
||||
- **WPS:** The function ``esp_wifi_wps_start`` no longer accepts a ``timeout_ms`` argument. It should now be called as ``esp_wifi_wps_start(void)``.
|
||||
|
||||
- **NAN:** The function argument ``ndp_resp_needed`` of ``esp_wifi_nan_publish_service`` has been moved to structure ``wifi_nan_publish_cfg_t``.
|
||||
- **NAN:**
|
||||
- NAN API's are modified so that they can be shared between two separate NAN modes of operation called NAN Synchronization (NAN-Sync) and NAN Unsynchronized Discovery (NAN-USD) roles:
|
||||
- ``esp_wifi_nan_sync_start`` and ``esp_wifi_nan_sync_stop`` replace the previous ``esp_wifi_nan_start`` / ``esp_wifi_nan_stop`` pair.
|
||||
- Functions starting with prefix ``esp_wifi_nan_*`` are shared by both NAN-Sync and NAN-USD modes (for example ``esp_wifi_nan_publish_service`` and ``esp_wifi_nan_subscribe_service``).
|
||||
- Use ``WIFI_NAN_SYNC_CONFIG_DEFAULT()`` instead of the former ``WIFI_NAN_CONFIG_DEFAULT()`` macro when initialising synchronized NAN configuration.
|
||||
- The structure ``wifi_nan_config_t`` has been renamed to ``wifi_nan_sync_config_t``; update declarations such as ``wifi_config_t.nan`` to use the new type.
|
||||
- NAN datapath APIs and associated structures are valid for NAN Synchronization (NAN-Sync) clusters only.
|
||||
- Wi-Fi events ``WIFI_EVENT_NAN_STARTED`` / ``WIFI_EVENT_NAN_STOPPED`` have been renamed to ``WIFI_EVENT_NAN_SYNC_STARTED`` / ``WIFI_EVENT_NAN_SYNC_STOPPED``.
|
||||
- The function argument ``ndp_resp_needed`` of ``esp_wifi_nan_publish_service`` has been moved to structure ``wifi_nan_publish_cfg_t``.
|
||||
- The structure ``wifi_nan_wfa_ssi_t`` now declares its ``proto`` field as ``uint8_t`` (previously ``wifi_nan_svc_proto_t``). Update code that stores pointers to this field or relies on its size to treat it as a single octet.
|
||||
- The structures ``wifi_nan_publish_cfg_t`` and ``wifi_nan_subscribe_cfg_t`` now include a ``usd_discovery_flag`` bitfield together with corresponding ``wifi_nan_usd_config_t`` members. Add designated initialisers for these fields when constructing the structures to avoid accidental field shifts.
|
||||
|
||||
- **Off-Channel Operations:**
|
||||
- The structure :cpp:struct:`wifi_action_tx_req_t` now includes a ``bssid`` field that is placed in Address3 of the transmitted action frame. Initialise this field explicitly; leaving it all zeros retains the previous behaviour where the Wi-Fi driver inserts the broadcast address, so frames do not carry unintended BSSID values.
|
||||
- The structure :cpp:struct:`wifi_roc_req_t` now includes an ``allow_broadcast`` flag that controls whether broadcast and multicast action frames are passed to the ``rx_cb`` callback during remain-on-channel operations. Existing applications should review the default ``false`` value and enable it when discovery of broadcast peers is required. Frames whose Address3/BSSID is already broadcast continue to reach the callback even when ``allow_broadcast`` remains ``false``.
|
||||
|
||||
@@ -46,5 +46,18 @@ Wi-Fi
|
||||
|
||||
- **WPS:** 函数 ``esp_wifi_wps_start`` 不再接受 ``timeout_ms`` 参数。现在应调用为 ``esp_wifi_wps_start(void)``。
|
||||
|
||||
- **NAN:** 函数 ``esp_wifi_nan_publish_service`` 的参数 ``ndp_resp_needed`` 已移至结构体 ``wifi_nan_publish_cfg_t``。
|
||||
- **NAN:**
|
||||
- 已调整 NAN API,使其可在两个独立的 NAN 工作模式间共享:NAN 同步(NAN-Sync)与 NAN 非同步发现(NAN-USD):
|
||||
- ``esp_wifi_nan_sync_start`` 与 ``esp_wifi_nan_sync_stop`` 取代原有的 ``esp_wifi_nan_start`` / ``esp_wifi_nan_stop``。
|
||||
- 以 ``esp_wifi_nan_*`` 为前缀的函数在 NAN-Sync 与 NAN 非同步发现(NAN-USD) 模式间通用(例如 ``esp_wifi_nan_publish_service``、``esp_wifi_nan_subscribe_service``)。
|
||||
- 初始化 NAN 同步配置时,请使用 ``WIFI_NAN_SYNC_CONFIG_DEFAULT()``,原 ``WIFI_NAN_CONFIG_DEFAULT()`` 已停用。
|
||||
- 结构体 ``wifi_nan_config_t`` 已重命名为 ``wifi_nan_sync_config_t``,例如需将 ``wifi_config_t.nan`` 等声明更新为新类型。
|
||||
- NAN 数据通道相关的 API 与结构体目前仅适用于 NAN 同步(NAN-Sync)集群。
|
||||
- Wi-Fi 事件 ``WIFI_EVENT_NAN_STARTED`` / ``WIFI_EVENT_NAN_STOPPED`` 已重命名为 ``WIFI_EVENT_NAN_SYNC_STARTED`` / ``WIFI_EVENT_NAN_SYNC_STOPPED``。
|
||||
- 函数 ``esp_wifi_nan_publish_service`` 的参数 ``ndp_resp_needed`` 已移至结构体 ``wifi_nan_publish_cfg_t``。
|
||||
- 结构体 ``wifi_nan_wfa_ssi_t`` 中的 ``proto`` 字段类型现为 ``uint8_t`` (之前为 ``wifi_nan_svc_proto_t``)。如果代码存储该字段的指针或依赖其大小,请按单个八位字节处理。
|
||||
- 结构体 ``wifi_nan_publish_cfg_t`` 和 ``wifi_nan_subscribe_cfg_t`` 新增 ``usd_discovery_flag`` 位域及对应的 ``wifi_nan_usd_config_t`` 成员。构造这些结构体时,请为新增字段提供指定初始化器,以避免字段偏移。
|
||||
|
||||
- **离信道操作:**
|
||||
- 结构体 :cpp:struct:`wifi_action_tx_req_t` 新增 ``bssid`` 字段,该字段会写入发送动作帧的 Address3。请显式初始化该字段;保持全零时将沿用之前的行为,由 Wi-Fi 驱动填入广播地址,从而避免帧携带意外的 BSSID。
|
||||
- 结构体 :cpp:struct:`wifi_roc_req_t` 新增 ``allow_broadcast`` 标志,用于控制在驻留信道期间是否将广播/组播动作帧传递给 ``rx_cb`` 回调。现有应用应结合默认值 ``false`` 评估是否需要启用该选项,以便在需要时进行广播节点发现。若动作帧的 Address3/BSSID 本身为广播地址,即便 ``allow_broadcast`` 保持 ``false``,回调仍会收到该帧。
|
||||
|
||||
@@ -98,7 +98,7 @@ examples/wifi/softap_sta:
|
||||
disable:
|
||||
- if: (SOC_WIFI_SUPPORTED != 1) and (SOC_WIRELESS_HOST_SUPPORTED != 1)
|
||||
|
||||
examples/wifi/wifi_aware:
|
||||
examples/wifi/wifi_aware/nan_console:
|
||||
disable:
|
||||
- if: SOC_WIFI_NAN_SUPPORT != 1
|
||||
reason: targets esp32c3, esp32s3, esp32c2 and esp32c6 are not supported
|
||||
@@ -114,3 +114,43 @@ examples/wifi/wifi_aware:
|
||||
- nvs_flash
|
||||
depends_filepatterns:
|
||||
- examples/system/console/advanced/components/**/*
|
||||
|
||||
examples/wifi/wifi_aware/nan_publisher:
|
||||
disable:
|
||||
- if: SOC_WIFI_NAN_SUPPORT != 1
|
||||
reason: targets esp32c3, esp32s3, esp32c2 and esp32c6 are not supported
|
||||
depends_components:
|
||||
- esp_wifi
|
||||
- esp_phy
|
||||
- esp_netif
|
||||
- lwip
|
||||
- esp_event
|
||||
- esp_coex
|
||||
- wpa_supplicant
|
||||
- mbedtls
|
||||
- nvs_flash
|
||||
|
||||
examples/wifi/wifi_aware/nan_subscriber:
|
||||
disable:
|
||||
- if: SOC_WIFI_NAN_SUPPORT != 1
|
||||
reason: targets esp32c3, esp32s3, esp32c2 and esp32c6 are not supported
|
||||
depends_components:
|
||||
- esp_wifi
|
||||
- esp_phy
|
||||
- esp_netif
|
||||
- lwip
|
||||
- esp_event
|
||||
- esp_coex
|
||||
- wpa_supplicant
|
||||
- mbedtls
|
||||
- nvs_flash
|
||||
|
||||
examples/wifi/wifi_aware/usd_publisher:
|
||||
<<: *wifi_depends_default
|
||||
disable:
|
||||
- if: SOC_WIFI_SUPPORTED != 1
|
||||
|
||||
examples/wifi/wifi_aware/usd_subscriber:
|
||||
<<: *wifi_depends_default
|
||||
disable:
|
||||
- if: SOC_WIFI_SUPPORTED != 1
|
||||
|
||||
@@ -234,7 +234,7 @@ static int wifi_cmd_nan_disc(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (nan_args.init->count) {
|
||||
wifi_nan_config_t nan_cfg = WIFI_NAN_CONFIG_DEFAULT();
|
||||
wifi_nan_sync_config_t nan_cfg = WIFI_NAN_SYNC_CONFIG_DEFAULT();
|
||||
|
||||
if (nan_args.master_pref->count) {
|
||||
nan_cfg.master_pref = nan_args.master_pref->ival[0];
|
||||
@@ -250,7 +250,7 @@ static int wifi_cmd_nan_disc(int argc, char **argv)
|
||||
g_nan_netif = esp_netif_create_default_wifi_nan();
|
||||
}
|
||||
|
||||
if ((esp_wifi_nan_start(&nan_cfg)) != ESP_OK) {
|
||||
if ((esp_wifi_nan_sync_start(&nan_cfg)) != ESP_OK) {
|
||||
ESP_LOGI(TAG, "Failed to start NAN");
|
||||
esp_netif_destroy_default_wifi(g_nan_netif);
|
||||
g_nan_netif = NULL;
|
||||
@@ -266,7 +266,7 @@ static int wifi_cmd_nan_disc(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (nan_args.deinit->count) {
|
||||
ret = esp_wifi_nan_stop();
|
||||
ret = esp_wifi_nan_sync_stop();
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGI(TAG, "Failed to stop NAN");
|
||||
|
||||
@@ -1 +1 @@
|
||||
CONFIG_ESP_WIFI_NAN_ENABLE=y
|
||||
CONFIG_ESP_WIFI_NAN_SYNC_ENABLE=y
|
||||
|
||||
@@ -81,10 +81,10 @@ void wifi_nan_publish(void)
|
||||
&instance_any_id));
|
||||
|
||||
/* Start NAN Discovery */
|
||||
wifi_nan_config_t nan_cfg = WIFI_NAN_CONFIG_DEFAULT();
|
||||
wifi_nan_sync_config_t nan_cfg = WIFI_NAN_SYNC_CONFIG_DEFAULT();
|
||||
|
||||
esp_netif_create_default_wifi_nan();
|
||||
esp_wifi_nan_start(&nan_cfg);
|
||||
esp_wifi_nan_sync_start(&nan_cfg);
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
WIFI_EVENT_NDP_INDICATION,
|
||||
|
||||
@@ -1 +1 @@
|
||||
CONFIG_ESP_WIFI_NAN_ENABLE=y
|
||||
CONFIG_ESP_WIFI_NAN_SYNC_ENABLE=y
|
||||
|
||||
@@ -177,10 +177,10 @@ void wifi_nan_subscribe(void)
|
||||
#endif
|
||||
|
||||
/* Start NAN Discovery */
|
||||
wifi_nan_config_t nan_cfg = WIFI_NAN_CONFIG_DEFAULT();
|
||||
wifi_nan_sync_config_t nan_cfg = WIFI_NAN_SYNC_CONFIG_DEFAULT();
|
||||
esp_netif_t *nan_netif = esp_netif_create_default_wifi_nan();
|
||||
(void) nan_netif;
|
||||
esp_wifi_nan_start(&nan_cfg);
|
||||
esp_wifi_nan_sync_start(&nan_cfg);
|
||||
|
||||
/* Subscribe a service */
|
||||
uint8_t sub_id;
|
||||
|
||||
@@ -1 +1 @@
|
||||
CONFIG_ESP_WIFI_NAN_ENABLE=y
|
||||
CONFIG_ESP_WIFI_NAN_SYNC_ENABLE=y
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following five 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(usd_publisher)
|
||||
@@ -0,0 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
@@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "usd_publisher_example_main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,20 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config ESP_WIFI_USD_PUB_SVC_NAME
|
||||
string "USD publish service name"
|
||||
default "ESP-USD-TEST"
|
||||
|
||||
config ESP_WIFI_USD_PUB_TTL
|
||||
int "Time to live (in seconds)"
|
||||
range 0 1000
|
||||
default 100
|
||||
help
|
||||
Time to live of the Publish instance, in seconds. If TTL = 0, only one publish message is transmitted.
|
||||
|
||||
config ESP_WIFI_USD_SVC_SPECIFIC_INFO
|
||||
string "Service specific info to be transmitted in a followup message"
|
||||
default "Welcome"
|
||||
help
|
||||
SSI to be transmitted in a followup frame
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_nan.h"
|
||||
#include "esp_mac.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#define MAC_ADDR_LEN 6
|
||||
|
||||
#define EXAMPLE_USD_SVC_NAME CONFIG_ESP_WIFI_USD_PUB_SVC_NAME
|
||||
#define EXAMPLE_USD_TTL CONFIG_ESP_WIFI_USD_PUB_TTL
|
||||
#define EXAMPLE_USD_SVC_INFO CONFIG_ESP_WIFI_USD_SVC_SPECIFIC_INFO
|
||||
|
||||
static EventGroupHandle_t s_nan_event_group;
|
||||
static int NAN_RECEIVE = BIT0;
|
||||
const char *TAG = "usd_publisher";
|
||||
uint8_t g_peer_inst_id;
|
||||
uint8_t g_peer_mac[MAC_ADDR_LEN];
|
||||
uint8_t g_publish_id;
|
||||
|
||||
static void nan_receive_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
wifi_event_nan_receive_t *evt = (wifi_event_nan_receive_t *)event_data;
|
||||
if (evt == NULL) {
|
||||
return;
|
||||
}
|
||||
g_peer_inst_id = evt->peer_inst_id;
|
||||
memcpy(g_peer_mac, evt->peer_if_mac, MAC_ADDR_LEN);
|
||||
ESP_LOGI(TAG, "Received Follow-up message from peer with ID %d and MAC "MACSTR"",
|
||||
evt->peer_inst_id, MAC2STR(evt->peer_if_mac));
|
||||
if (evt->ssi_len) {
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, evt->ssi, evt->ssi_len, ESP_LOG_INFO);
|
||||
xEventGroupSetBits(s_nan_event_group, NAN_RECEIVE);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "SSI - [NULL]");
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_usd_publish(void)
|
||||
{
|
||||
s_nan_event_group = xEventGroupCreate();
|
||||
esp_event_handler_instance_t instance_any_id;
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
WIFI_EVENT_NAN_RECEIVE,
|
||||
&nan_receive_event_handler,
|
||||
NULL,
|
||||
&instance_any_id));
|
||||
|
||||
ESP_RETURN_VOID_ON_ERROR(esp_wifi_start(), TAG, "NAN-USD failed to start Wi-Fi");
|
||||
|
||||
/* Start USD-NAN Discovery */
|
||||
ESP_RETURN_VOID_ON_ERROR(esp_wifi_nan_usd_start(), TAG, "NAN-USD initialization failed");
|
||||
|
||||
wifi_nan_publish_cfg_t publish_cfg = {
|
||||
.service_name = EXAMPLE_USD_SVC_NAME,
|
||||
.ttl = EXAMPLE_USD_TTL,
|
||||
.ssi = NULL,
|
||||
.ssi_len = 0,
|
||||
.usd_discovery_flag = 1,
|
||||
.usd_publish_config = esp_wifi_usd_get_default_publish_cfg(),
|
||||
};
|
||||
|
||||
g_publish_id = esp_wifi_nan_publish_service(&publish_cfg);
|
||||
|
||||
|
||||
if (g_publish_id == 0) {
|
||||
ESP_LOGE(TAG, "Publishing to %s failed", publish_cfg.service_name);
|
||||
return;
|
||||
}
|
||||
|
||||
EventBits_t bits = xEventGroupWaitBits(s_nan_event_group, NAN_RECEIVE, pdFALSE, pdFALSE, pdMS_TO_TICKS(EXAMPLE_USD_TTL*1000));
|
||||
if (bits & NAN_RECEIVE) {
|
||||
xEventGroupClearBits(s_nan_event_group, NAN_RECEIVE);
|
||||
wifi_nan_followup_params_t fup_params = {
|
||||
.inst_id = g_publish_id,
|
||||
.peer_inst_id = g_peer_inst_id,
|
||||
.ssi = (uint8_t *)EXAMPLE_USD_SVC_INFO,
|
||||
.ssi_len = strlen(EXAMPLE_USD_SVC_INFO),
|
||||
};
|
||||
memcpy(fup_params.peer_mac, g_peer_mac, MAC_ADDR_LEN);
|
||||
|
||||
ESP_LOGI(TAG, "Sending message to the peer with ID %d", g_peer_inst_id);
|
||||
if (fup_params.ssi_len) {
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, fup_params.ssi, fup_params.ssi_len, ESP_LOG_INFO);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "SSI - [NULL]");
|
||||
}
|
||||
ESP_RETURN_VOID_ON_ERROR(esp_wifi_nan_send_message(&fup_params), TAG, "Sending message to the peer with ID %d failed!", g_peer_inst_id);
|
||||
}
|
||||
|
||||
esp_wifi_nan_cancel_service(g_publish_id);
|
||||
esp_wifi_nan_usd_stop();
|
||||
}
|
||||
|
||||
void initialise_wifi(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM) );
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
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);
|
||||
|
||||
initialise_wifi();
|
||||
wifi_usd_publish();
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_ESP_WIFI_NAN_USD_ENABLE=y
|
||||
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
|
||||
@@ -0,0 +1,6 @@
|
||||
# The following five 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(usd_subscriber)
|
||||
@@ -0,0 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
@@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "usd_subscriber_example_main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,28 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config ESP_WIFI_USD_SUB_SVC_NAME
|
||||
string "USD subscribe service name"
|
||||
default "ESP-USD-TEST"
|
||||
|
||||
config ESP_WIFI_USD_SUB_TTL
|
||||
int "Time to live (in seconds)"
|
||||
range 0 1000
|
||||
default 100
|
||||
help
|
||||
Time to live of the Subscribe instance, in seconds. If TTL = 0,
|
||||
the subscriber listens until the first service match is reported.
|
||||
|
||||
config ESP_WIFI_USD_DEFAULT_CHAN
|
||||
int "Default Subscribe channel"
|
||||
range 1 13
|
||||
default 6
|
||||
help
|
||||
Default channel of subscriber
|
||||
|
||||
config ESP_WIFI_USD_SVC_SPECIFIC_INFO
|
||||
string "Service specific info to be transmitted in a followup message"
|
||||
default "Hello"
|
||||
help
|
||||
SSI to be transmitted in a followup frame
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_nan.h"
|
||||
#include "esp_mac.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#define MAC_ADDR_LEN 6
|
||||
|
||||
#define EXAMPLE_USD_SVC_NAME CONFIG_ESP_WIFI_USD_SUB_SVC_NAME
|
||||
#define EXAMPLE_USD_TTL CONFIG_ESP_WIFI_USD_SUB_TTL
|
||||
#define EXAMPLE_USD_DEFAULT_SUB_CHANNEL CONFIG_ESP_WIFI_USD_DEFAULT_CHAN
|
||||
#define EXAMPLE_USD_SVC_INFO CONFIG_ESP_WIFI_USD_SVC_SPECIFIC_INFO
|
||||
|
||||
static EventGroupHandle_t s_nan_event_group;
|
||||
static int NAN_RECEIVE = BIT0;
|
||||
static int NAN_SRV_MATCH = BIT1;
|
||||
const char *TAG = "usd_subscriber";
|
||||
uint8_t g_peer_inst_id;
|
||||
uint8_t g_peer_mac[MAC_ADDR_LEN];
|
||||
uint8_t g_subscribe_id;
|
||||
|
||||
static void nan_svc_match_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
wifi_event_nan_svc_match_t *evt = (wifi_event_nan_svc_match_t *)event_data;
|
||||
if (evt == NULL) {
|
||||
return;
|
||||
}
|
||||
g_peer_inst_id = evt->publish_id;
|
||||
memcpy(g_peer_mac, evt->pub_if_mac, MAC_ADDR_LEN);
|
||||
ESP_LOGI(TAG, "Service matched with peer_id %d peer mac "MACSTR"", evt->publish_id, MAC2STR(evt->pub_if_mac));
|
||||
if (evt->ssi_len) {
|
||||
ESP_LOGI(TAG, "SSI -");
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, evt->ssi,
|
||||
evt->ssi_len, ESP_LOG_INFO);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "SSI - [NULL]");
|
||||
}
|
||||
xEventGroupSetBits(s_nan_event_group, NAN_SRV_MATCH);
|
||||
}
|
||||
|
||||
static void nan_receive_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
wifi_event_nan_receive_t *evt = (wifi_event_nan_receive_t *)event_data;
|
||||
if (evt == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Received Follow-up message from peer with ID %d and MAC "MACSTR"",
|
||||
evt->peer_inst_id, MAC2STR(evt->peer_if_mac));
|
||||
if (evt->ssi_len) {
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, evt->ssi, evt->ssi_len, ESP_LOG_INFO);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "SSI - [NULL]");
|
||||
}
|
||||
xEventGroupSetBits(s_nan_event_group, NAN_RECEIVE);
|
||||
esp_wifi_nan_cancel_service(g_subscribe_id);
|
||||
}
|
||||
|
||||
void wifi_usd_subscribe(void)
|
||||
{
|
||||
s_nan_event_group = xEventGroupCreate();
|
||||
esp_event_handler_instance_t instance_any_id;
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
WIFI_EVENT_NAN_SVC_MATCH,
|
||||
&nan_svc_match_event_handler,
|
||||
NULL,
|
||||
&instance_any_id));
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||
WIFI_EVENT_NAN_RECEIVE,
|
||||
&nan_receive_event_handler,
|
||||
NULL,
|
||||
&instance_any_id));
|
||||
|
||||
ESP_RETURN_VOID_ON_ERROR(esp_wifi_start(), TAG, "NAN-USD failed to start Wi-Fi");
|
||||
|
||||
/* Start NAN-USD Discovery */
|
||||
ESP_RETURN_VOID_ON_ERROR(esp_wifi_nan_usd_start(), TAG, "NAN-USD initialization failed");
|
||||
|
||||
wifi_nan_subscribe_cfg_t subscribe_cfg = {
|
||||
.service_name = EXAMPLE_USD_SVC_NAME,
|
||||
.ttl = EXAMPLE_USD_TTL,
|
||||
.ssi = NULL,
|
||||
.ssi_len = 0,
|
||||
.usd_discovery_flag = 1,
|
||||
.usd_subscribe_config = esp_wifi_usd_get_default_subscribe_cfg(),
|
||||
};
|
||||
subscribe_cfg.usd_subscribe_config.usd_default_channel = EXAMPLE_USD_DEFAULT_SUB_CHANNEL;
|
||||
|
||||
g_subscribe_id = esp_wifi_nan_subscribe_service(&subscribe_cfg);
|
||||
if (g_subscribe_id == 0) {
|
||||
ESP_LOGE(TAG, "Subscribing to %s failed", subscribe_cfg.service_name);
|
||||
return;
|
||||
}
|
||||
|
||||
EventBits_t bits = xEventGroupWaitBits(s_nan_event_group, NAN_SRV_MATCH, pdTRUE, pdFALSE, pdMS_TO_TICKS(EXAMPLE_USD_TTL*1000));
|
||||
if (bits & NAN_SRV_MATCH) {
|
||||
wifi_nan_followup_params_t fup_params = {
|
||||
.inst_id = g_subscribe_id,
|
||||
.peer_inst_id = g_peer_inst_id,
|
||||
.ssi = (uint8_t *)EXAMPLE_USD_SVC_INFO,
|
||||
.ssi_len = strlen(EXAMPLE_USD_SVC_INFO),
|
||||
};
|
||||
memcpy(fup_params.peer_mac, g_peer_mac, MAC_ADDR_LEN);
|
||||
|
||||
ESP_LOGI(TAG, "Sending message to the peer with ID %d", g_peer_inst_id);
|
||||
if (fup_params.ssi_len) {
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, fup_params.ssi, fup_params.ssi_len, ESP_LOG_INFO);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "SSI - [NULL]");
|
||||
}
|
||||
ESP_RETURN_VOID_ON_ERROR(esp_wifi_nan_send_message(&fup_params), TAG, "Sending message to the peer with ID %d failed!", g_peer_inst_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void initialise_wifi(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM) );
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
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);
|
||||
initialise_wifi();
|
||||
wifi_usd_subscribe();
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
CONFIG_ESP_WIFI_NAN_USD_ENABLE=y
|
||||
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
|
||||
@@ -624,6 +624,10 @@
|
||||
re: "error: implicit declaration of function 'esp_wifi_config_espnow_rate'"
|
||||
hint: "The function 'esp_wifi_config_espnow_rate' has been removed. Use 'esp_now_set_peer_rate_config' instead."
|
||||
|
||||
-
|
||||
re: "(initialization|assignment) of 'wifi_nan_svc_proto_t \\*' from incompatible pointer type 'uint8_t \\*'"
|
||||
hint: "The field 'proto' in structure 'wifi_nan_wfa_ssi_t' is now declared as 'uint8_t'. Update pointer usage accordingly, for example by using a 'uint8_t *' or copying the enum value into a separate variable."
|
||||
|
||||
-
|
||||
re: "error: too many arguments to function 'esp_wifi_wps_start'"
|
||||
hint: "The function 'esp_wifi_wps_start' no longer accepts a 'timeout_ms' argument."
|
||||
@@ -656,10 +660,36 @@
|
||||
re: "error: 'peer_svc_info' undeclared"
|
||||
hint: "The field 'peer_svc_info' from structure 'wifi_event_nan_receive_t' has been removed. Please use the equivalent fields 'ssi' and 'ssi_len' instead."
|
||||
|
||||
-
|
||||
re: "error: 'WIFI_EVENT_NAN_STARTED' undeclared"
|
||||
hint: "The Wi-Fi NAN event 'WIFI_EVENT_NAN_STARTED' has been renamed to 'WIFI_EVENT_NAN_SYNC_STARTED'."
|
||||
|
||||
-
|
||||
re: "error: 'WIFI_EVENT_NAN_STOPPED' undeclared"
|
||||
hint: "The Wi-Fi NAN event 'WIFI_EVENT_NAN_STOPPED' has been renamed to 'WIFI_EVENT_NAN_SYNC_STOPPED'."
|
||||
|
||||
-
|
||||
re: "error: too few arguments to function 'esp_wifi_nan_publish_service'"
|
||||
hint: "The function argument 'ndp_resp_needed' of 'esp_wifi_nan_publish_service' has been moved to structure 'wifi_nan_publish_cfg_t'."
|
||||
|
||||
-
|
||||
re: "error: implicit declaration of function '{}'"
|
||||
hint: "The NAN synchronization API '{}' has been renamed to '{}'."
|
||||
variables:
|
||||
-
|
||||
re_variables: ['esp_wifi_nan_start']
|
||||
hint_variables: ['esp_wifi_nan_start', 'esp_wifi_nan_sync_start']
|
||||
-
|
||||
re_variables: ['esp_wifi_nan_stop']
|
||||
hint_variables: ['esp_wifi_nan_stop', 'esp_wifi_nan_sync_stop']
|
||||
-
|
||||
re_variables: ['WIFI_NAN_CONFIG_DEFAULT']
|
||||
hint_variables: ['WIFI_NAN_CONFIG_DEFAULT', 'WIFI_NAN_SYNC_CONFIG_DEFAULT']
|
||||
|
||||
-
|
||||
re: "error: unknown type name 'wifi_nan_config_t'"
|
||||
hint: "The structure 'wifi_nan_config_t' has been renamed to 'wifi_nan_sync_config_t'."
|
||||
|
||||
-
|
||||
re: "error: '(WIFI_REASON_ASSOC_EXPIRE|WIFI_REASON_NOT_AUTHED|WIFI_REASON_NOT_ASSOCED)' undeclared"
|
||||
hint: "The Wi-Fi disconnection reason codes '{0}' have been removed. Please use '{1}', '{2}', and '{3}' respectively."
|
||||
|
||||
Reference in New Issue
Block a user