[RFC 20/34] wpa_supplicant: Refactor NAN USD
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Aug 13 10:39:04 PDT 2025
NAN USD and synchronized discovery have a lot of common parts,
combine them together:
- Rename "usd" functions that are common for sync NAN as well.
- Combine nan_usd.c/h with nan_supplicant.c/h files.
- Provide better inline stubs for all the nan functions to reduce ifdef
usage in core supplicant code.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
wpa_supplicant/Android.mk | 14 +-
wpa_supplicant/Makefile | 12 +-
wpa_supplicant/ctrl_iface.c | 35 +-
wpa_supplicant/dbus/dbus_new_handlers.c | 14 +-
wpa_supplicant/events.c | 19 +-
wpa_supplicant/nan_supplicant.c | 560 +++++++++++++++++++++++
wpa_supplicant/nan_supplicant.h | 96 ++++
wpa_supplicant/nan_usd.c | 568 ------------------------
wpa_supplicant/nan_usd.h | 49 --
wpa_supplicant/p2p_supplicant.c | 1 +
wpa_supplicant/wpa_supplicant.c | 9 +-
wpa_supplicant/wpa_supplicant_i.h | 2 +-
12 files changed, 705 insertions(+), 674 deletions(-)
delete mode 100644 wpa_supplicant/nan_usd.c
delete mode 100644 wpa_supplicant/nan_usd.h
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 3b755459d4..220b916276 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -284,18 +284,22 @@ endif
endif
ifdef CONFIG_NAN
-OBJS += nan_supplicant.o
-OBJS += src/nan/nan.o
-CFLAGS += -DCONFIG_NAN
+NEED_NAN=y
+L_CFLAGS += -DCONFIG_NAN
endif
ifdef CONFIG_NAN_USD
-OBJS += src/common/nan_de.c
-OBJS += nan_usd.c
NEED_OFFCHANNEL=y
+NEED_NAN=y
L_CFLAGS += -DCONFIG_NAN_USD
endif
+ifdef NEED_NAN
+OBJS += nan_supplicant.o
+OBJS += src/nan/nan.o
+OBJS += src/common/nan_de.c
+endif
+
ifdef CONFIG_OWE
L_CFLAGS += -DCONFIG_OWE
NEED_ECC=y
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 4e753f4ed6..de7dc58301 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -318,18 +318,22 @@ endif
endif
ifdef CONFIG_NAN
-OBJS += nan_supplicant.o
-OBJS += ../src/nan/nan.o
+NEED_NAN=y
CFLAGS += -DCONFIG_NAN
endif
ifdef CONFIG_NAN_USD
-OBJS += ../src/common/nan_de.o
-OBJS += nan_usd.o
NEED_OFFCHANNEL=y
+NEED_NAN=y
CFLAGS += -DCONFIG_NAN_USD
endif
+ifdef NEED_NAN
+OBJS += nan_supplicant.o
+OBJS += ../src/nan/nan.o
+OBJS += ../src/common/nan_de.o
+endif
+
ifdef CONFIG_OWE
CFLAGS += -DCONFIG_OWE
NEED_ECC=y
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 47a956af4b..9180c90623 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -59,7 +59,6 @@
#include "mesh.h"
#include "dpp_supplicant.h"
#include "sme.h"
-#include "nan_usd.h"
#include "nan_supplicant.h"
#ifdef __NetBSD__
@@ -9180,9 +9179,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
wpa_s->conf->ignore_old_scan_res = 0;
-#ifdef CONFIG_NAN_USD
- wpas_nan_usd_flush(wpa_s);
-#endif /* CONFIG_NAN_USD */
+ wpas_nan_de_flush(wpa_s);
}
@@ -12567,7 +12564,7 @@ static int wpas_ctrl_ml_probe(struct wpa_supplicant *wpa_s, char *cmd)
#endif /* CONFIG_TESTING_OPTIONS */
-#ifdef CONFIG_NAN_USD
+#if defined(CONFIG_NAN) || defined(CONFIG_NAN_USD)
static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd,
char *buf, size_t buflen)
@@ -12666,8 +12663,8 @@ static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd,
goto fail;
}
- publish_id = wpas_nan_usd_publish(wpa_s, service_name, srv_proto_type,
- ssi, ¶ms, p2p);
+ publish_id = wpas_nan_publish(wpa_s, service_name, srv_proto_type, ssi,
+ ¶ms, p2p);
if (publish_id > 0)
ret = os_snprintf(buf, buflen, "%d", publish_id);
fail:
@@ -12698,7 +12695,7 @@ static int wpas_ctrl_nan_cancel_publish(struct wpa_supplicant *wpa_s,
return -1;
}
- wpas_nan_usd_cancel_publish(wpa_s, publish_id);
+ wpas_nan_cancel_publish(wpa_s, publish_id);
return 0;
}
@@ -12734,7 +12731,7 @@ static int wpas_ctrl_nan_update_publish(struct wpa_supplicant *wpa_s,
goto fail;
}
- ret = wpas_nan_usd_update_publish(wpa_s, publish_id, ssi);
+ ret = wpas_nan_update_publish(wpa_s, publish_id, ssi);
fail:
wpabuf_free(ssi);
return ret;
@@ -12824,9 +12821,9 @@ static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd,
goto fail;
}
- subscribe_id = wpas_nan_usd_subscribe(wpa_s, service_name,
- srv_proto_type, ssi,
- ¶ms, p2p);
+ subscribe_id = wpas_nan_subscribe(wpa_s, service_name,
+ srv_proto_type, ssi,
+ ¶ms, p2p);
if (subscribe_id > 0)
ret = os_snprintf(buf, buflen, "%d", subscribe_id);
fail:
@@ -12857,7 +12854,7 @@ static int wpas_ctrl_nan_cancel_subscribe(struct wpa_supplicant *wpa_s,
return -1;
}
- wpas_nan_usd_cancel_subscribe(wpa_s, subscribe_id);
+ wpas_nan_cancel_subscribe(wpa_s, subscribe_id);
return 0;
}
@@ -12913,8 +12910,8 @@ static int wpas_ctrl_nan_transmit(struct wpa_supplicant *wpa_s, char *cmd)
goto fail;
}
- ret = wpas_nan_usd_transmit(wpa_s, handle, ssi, NULL, peer_addr,
- req_instance_id);
+ ret = wpas_nan_transmit(wpa_s, handle, ssi, NULL, peer_addr,
+ req_instance_id);
fail:
wpabuf_free(ssi);
return ret;
@@ -12967,7 +12964,7 @@ static int wpas_ctrl_nan_unpause_publish(struct wpa_supplicant *wpa_s,
peer_addr);
}
-#endif /* CONFIG_NAN_USD */
+#endif /* CONFIG_NAN || CONFIG_NAN_USD */
char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
@@ -13975,7 +13972,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
reply_len = -1;
#endif /* CONFIG_DPP3 */
#endif /* CONFIG_DPP */
-#ifdef CONFIG_NAN_USD
+#if defined (CONFIG_NAN_USD) || defined (CONFIG_NAN)
} else if (os_strncmp(buf, "NAN_PUBLISH ", 12) == 0) {
reply_len = wpas_ctrl_nan_publish(wpa_s, buf + 12, reply,
reply_size);
@@ -13998,8 +13995,8 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (wpas_ctrl_nan_unpause_publish(wpa_s, buf + 20) < 0)
reply_len = -1;
} else if (os_strcmp(buf, "NAN_FLUSH") == 0) {
- wpas_nan_usd_flush(wpa_s);
-#endif /* CONFIG_NAN_USD */
+ wpas_nan_de_flush(wpa_s);
+#endif /* CONFIG_NAN_USD || CONFIG_NAN */
#ifdef CONFIG_PASN
} else if (os_strncmp(buf, "PASN_START ", 11) == 0) {
if (wpas_ctrl_iface_pasn_start(wpa_s, buf + 11) < 0)
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index e212235c59..21325a87e5 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -28,7 +28,7 @@
#include "../autoscan.h"
#include "../ap.h"
#include "../interworking.h"
-#include "../nan_usd.h"
+#include "../nan_supplicant.h"
#include "dbus_new_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
@@ -6600,8 +6600,8 @@ DBusMessage * wpas_dbus_handler_nan_publish(DBusMessage *message,
if (!srv_name)
goto fail;
- publish_id = wpas_nan_usd_publish(wpa_s, srv_name, srv_proto_type, ssi,
- ¶ms, p2p);
+ publish_id = wpas_nan_publish(wpa_s, srv_name, srv_proto_type, ssi,
+ ¶ms, p2p);
if (publish_id < 0) {
reply = wpas_dbus_error_unknown_error(
message, "error publishing NAN USD");
@@ -6836,8 +6836,8 @@ DBusMessage * wpas_dbus_handler_nan_subscribe(DBusMessage *message,
if (!srv_name)
goto fail;
- subscribe_id = wpas_nan_usd_subscribe(wpa_s, srv_name, srv_proto_type,
- ssi, ¶ms, p2p);
+ subscribe_id = wpas_nan_subscribe(wpa_s, srv_name, srv_proto_type,
+ ssi, ¶ms, p2p);
if (subscribe_id < 0) {
reply = wpas_dbus_error_unknown_error(
message, "error subscribing NAN USD");
@@ -6966,8 +6966,8 @@ DBusMessage * wpas_dbus_handler_nan_transmit(DBusMessage *message,
if (handle < 0 || req_instance_id < 0 || !peer_addr_set || !ssi)
goto fail;
- if (wpas_nan_usd_transmit(wpa_s, handle, ssi, NULL, peer_addr,
- req_instance_id) < 0)
+ if (wpas_nan_transmit(wpa_s, handle, ssi, NULL, peer_addr,
+ req_instance_id) < 0)
reply = wpas_dbus_error_unknown_error(
message, "failed to transmit follow-up");
out:
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 18fc729f10..fcfce4a511 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -51,7 +51,6 @@
#include "mesh.h"
#include "mesh_mpm.h"
#include "wmm_ac.h"
-#include "nan_usd.h"
#include "dpp_supplicant.h"
#include "nan_supplicant.h"
@@ -5580,17 +5579,17 @@ static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
}
#endif /* CONFIG_FST */
-#ifdef CONFIG_NAN_USD
+#if defined(CONFIG_NAN_USD) || defined(CONFIG_NAN)
if (category == WLAN_ACTION_PUBLIC && plen >= 5 &&
payload[0] == WLAN_PA_VENDOR_SPECIFIC &&
WPA_GET_BE32(&payload[1]) == NAN_SDF_VENDOR_TYPE) {
payload += 5;
plen -= 5;
- wpas_nan_usd_rx_sdf(wpa_s, mgmt->sa, mgmt->bssid, freq,
- payload, plen);
+ wpas_nan_de_rx_sdf(wpa_s, mgmt->sa, mgmt->bssid, freq,
+ payload, plen);
return;
}
-#endif /* CONFIG_NAN_USD */
+#endif /* CONFIG_NAN_USD || CONFIG_NAN */
#ifdef CONFIG_DPP
if (category == WLAN_ACTION_PUBLIC && plen >= 5 &&
@@ -6854,11 +6853,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
wpa_s, data->remain_on_channel.freq,
data->remain_on_channel.duration);
#endif /* CONFIG_DPP */
-#ifdef CONFIG_NAN_USD
wpas_nan_usd_remain_on_channel_cb(
wpa_s, data->remain_on_channel.freq,
data->remain_on_channel.duration);
-#endif /* CONFIG_NAN_USD */
break;
case EVENT_CANCEL_REMAIN_ON_CHANNEL:
#ifdef CONFIG_OFFCHANNEL
@@ -6871,10 +6868,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
wpas_dpp_cancel_remain_on_channel_cb(
wpa_s, data->remain_on_channel.freq);
#endif /* CONFIG_DPP */
-#ifdef CONFIG_NAN_USD
wpas_nan_usd_cancel_remain_on_channel_cb(
wpa_s, data->remain_on_channel.freq);
-#endif /* CONFIG_NAN_USD */
break;
case EVENT_EAPOL_RX:
wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
@@ -7216,9 +7211,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
#ifdef CONFIG_DPP
wpas_dpp_tx_wait_expire(wpa_s);
#endif /* CONFIG_DPP */
-#ifdef CONFIG_NAN_USD
- wpas_nan_usd_tx_wait_expire(wpa_s);
-#endif /* CONFIG_NAN_USD */
+ wpas_nan_tx_wait_expire(wpa_s);
break;
case EVENT_TID_LINK_MAP:
if (data)
@@ -7228,7 +7221,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
if (data)
wpas_setup_link_reconfig(wpa_s, &data->reconfig_info);
break;
-#ifdef CONFIG_NAN
case EVENT_NAN_CLUSTER_JOIN:
wpas_nan_cluster_join(wpa_s, data->nan_cluster_join_info.bssid,
data->nan_cluster_join_info.new_cluster);
@@ -7236,7 +7228,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
case EVENT_NAN_NEXT_DW:
wpas_nan_next_dw(wpa_s, data->nan_next_dw_info.freq);
break;
-#endif /* CONFIG_NAN */
default:
wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
break;
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index b2b70bb6d8..5ebaa39ca8 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -13,10 +13,15 @@
#include "driver_i.h"
#include "nan/nan.h"
#include "config.h"
+#include "common/nan_de.h"
+#include "offchannel.h"
+#include "notify.h"
+#include "p2p_supplicant.h"
#define DEFAULT_NAN_MASTER_PREF 2
#define DEFAULT_NAN_DUAL_BAND 0
+#ifdef CONFIG_NAN
static int wpas_nan_start_cb(void *ctx, struct nan_cluster_config *config)
{
@@ -132,6 +137,7 @@ void wpas_nan_cluster_join(struct wpa_supplicant *wpa_s,
nan_de_set_cluster_id(wpa_s->nan_de, cluster_id);
}
+
void wpas_nan_next_dw(struct wpa_supplicant *wpa_s, u32 freq)
{
if (!wpas_nan_ready(wpa_s))
@@ -141,3 +147,557 @@ void wpas_nan_next_dw(struct wpa_supplicant *wpa_s, u32 freq)
nan_de_dw_trigger(wpa_s->nan_de, freq);
}
+#endif /* CONFIG_NAN */
+
+static const char *
+tx_status_result_txt(enum offchannel_send_action_result result)
+{
+ switch (result) {
+ case OFFCHANNEL_SEND_ACTION_SUCCESS:
+ return "success";
+ case OFFCHANNEL_SEND_ACTION_NO_ACK:
+ return "no-ack";
+ case OFFCHANNEL_SEND_ACTION_FAILED:
+ return "failed";
+ }
+
+ return "?";
+}
+
+
+static void wpas_nan_de_tx_status(struct wpa_supplicant *wpa_s,
+ unsigned int freq, const u8 *dst,
+ const u8 *src, const u8 *bssid,
+ const u8 *data, size_t data_len,
+ enum offchannel_send_action_result result)
+{
+ if (!wpa_s->nan_de)
+ return;
+
+ wpa_printf(MSG_DEBUG, "NAN: TX status A1=" MACSTR " A2=" MACSTR
+ " A3=" MACSTR " freq=%d len=%zu result=%s",
+ MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), freq,
+ data_len, tx_status_result_txt(result));
+
+ nan_de_tx_status(wpa_s->nan_de, freq, dst);
+}
+
+
+struct wpas_nan_tx_work {
+ unsigned int freq;
+ unsigned int wait_time;
+ u8 dst[ETH_ALEN];
+ u8 src[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+ struct wpabuf *buf;
+};
+
+
+static void wpas_nan_tx_work_free(struct wpas_nan_tx_work *twork)
+{
+ if (!twork)
+ return;
+ wpabuf_free(twork->buf);
+ os_free(twork);
+}
+
+
+static void wpas_nan_tx_work_done(struct wpa_supplicant *wpa_s)
+{
+ struct wpas_nan_tx_work *twork;
+
+ if (!wpa_s->nan_tx_work)
+ return;
+
+ twork = wpa_s->nan_tx_work->ctx;
+ wpas_nan_tx_work_free(twork);
+ radio_work_done(wpa_s->nan_tx_work);
+ wpa_s->nan_tx_work = NULL;
+}
+
+
+static int wpas_nan_de_tx_send(struct wpa_supplicant *wpa_s, unsigned int freq,
+ unsigned int wait_time, const u8 *dst,
+ const u8 *src, const u8 *bssid,
+ const struct wpabuf *buf)
+{
+ wpa_printf(MSG_DEBUG, "NAN: TX NAN SDF A1=" MACSTR " A2=" MACSTR
+ " A3=" MACSTR " freq=%d len=%zu",
+ MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), freq,
+ wpabuf_len(buf));
+
+ return offchannel_send_action(wpa_s, freq, dst, src, bssid,
+ wpabuf_head(buf), wpabuf_len(buf),
+ wait_time, wpas_nan_de_tx_status, 1);
+}
+
+
+static void wpas_nan_start_tx_cb(struct wpa_radio_work *work, int deinit)
+{
+ struct wpa_supplicant *wpa_s = work->wpa_s;
+ struct wpas_nan_tx_work *twork = work->ctx;
+
+ if (deinit) {
+ if (work->started) {
+ wpa_s->nan_tx_work = NULL;
+ offchannel_send_action_done(wpa_s);
+ }
+ wpas_nan_tx_work_free(twork);
+ return;
+ }
+
+ wpa_s->nan_tx_work = work;
+
+ if (wpas_nan_de_tx_send(wpa_s, twork->freq, twork->wait_time,
+ twork->dst, twork->src, twork->bssid,
+ twork->buf) < 0)
+ wpas_nan_tx_work_done(wpa_s);
+}
+
+
+static int wpas_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)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ struct wpas_nan_tx_work *twork;
+
+ if (wpa_s->nan_tx_work || wpa_s->nan_usd_listen_work) {
+ /* Reuse ongoing radio work */
+ return wpas_nan_de_tx_send(wpa_s, freq, wait_time, dst, src,
+ bssid, buf);
+ }
+
+ twork = os_zalloc(sizeof(*twork));
+ if (!twork)
+ return -1;
+ twork->freq = freq;
+ twork->wait_time = wait_time;
+ os_memcpy(twork->dst, dst, ETH_ALEN);
+ os_memcpy(twork->src, src, ETH_ALEN);
+ os_memcpy(twork->bssid, bssid, ETH_ALEN);
+ twork->buf = wpabuf_dup(buf);
+ if (!twork->buf) {
+ wpas_nan_tx_work_free(twork);
+ return -1;
+ }
+
+ if (radio_add_work(wpa_s, freq, "nan-tx", 0,
+ wpas_nan_start_tx_cb, twork) < 0) {
+ wpas_nan_tx_work_free(twork);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+struct wpas_nan_usd_listen_work {
+ unsigned int freq;
+ unsigned int duration;
+};
+
+
+static void wpas_nan_usd_listen_work_done(struct wpa_supplicant *wpa_s)
+{
+ struct wpas_nan_usd_listen_work *lwork;
+
+ if (!wpa_s->nan_usd_listen_work)
+ return;
+
+ lwork = wpa_s->nan_usd_listen_work->ctx;
+ os_free(lwork);
+ radio_work_done(wpa_s->nan_usd_listen_work);
+ wpa_s->nan_usd_listen_work = NULL;
+}
+
+
+static void wpas_nan_usd_start_listen_cb(struct wpa_radio_work *work,
+ int deinit)
+{
+ struct wpa_supplicant *wpa_s = work->wpa_s;
+ struct wpas_nan_usd_listen_work *lwork = work->ctx;
+ unsigned int duration;
+
+ if (deinit) {
+ if (work->started) {
+ wpa_s->nan_usd_listen_work = NULL;
+ wpa_drv_cancel_remain_on_channel(wpa_s);
+ }
+ os_free(lwork);
+ return;
+ }
+
+ wpa_s->nan_usd_listen_work = work;
+
+ duration = lwork->duration;
+ if (duration > wpa_s->max_remain_on_chan)
+ duration = wpa_s->max_remain_on_chan;
+ wpa_printf(MSG_DEBUG, "NAN: Start listen on %u MHz for %u ms",
+ lwork->freq, duration);
+ if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, duration) < 0) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Failed to request the driver to remain on channel (%u MHz) for listen",
+ lwork->freq);
+ wpas_nan_usd_listen_work_done(wpa_s);
+ return;
+ }
+}
+
+
+static int wpas_nan_usd_listen(void *ctx, unsigned int freq,
+ unsigned int duration)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ struct wpas_nan_usd_listen_work *lwork;
+
+ lwork = os_zalloc(sizeof(*lwork));
+ if (!lwork)
+ return -1;
+ lwork->freq = freq;
+ lwork->duration = duration;
+
+ if (radio_add_work(wpa_s, freq, "nan-usd-listen", 0,
+ wpas_nan_usd_start_listen_cb, lwork) < 0) {
+ os_free(lwork);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void
+wpas_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)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpas_notify_nan_discovery_result(wpa_s, srv_proto_type, subscribe_id,
+ peer_publish_id, peer_addr, fsd,
+ fsd_gas, ssi, ssi_len);
+}
+
+
+static void wpas_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)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpas_notify_nan_replied(wpa_s, srv_proto_type, publish_id,
+ peer_subscribe_id, peer_addr, ssi, ssi_len);
+}
+
+
+static void wpas_nan_de_publish_terminated(void *ctx, int publish_id,
+ enum nan_de_reason reason)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpas_notify_nan_publish_terminated(wpa_s, publish_id, reason);
+}
+
+
+static void wpas_nan_usd_offload_cancel_publish(void *ctx, int publish_id)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
+ wpas_drv_nan_cancel_publish(wpa_s, publish_id);
+}
+
+
+static void wpas_nan_de_subscribe_terminated(void *ctx, int subscribe_id,
+ enum nan_de_reason reason)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpas_notify_nan_subscribe_terminated(wpa_s, subscribe_id, reason);
+}
+
+
+static void wpas_nan_usd_offload_cancel_subscribe(void *ctx, int subscribe_id)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
+ wpas_drv_nan_cancel_subscribe(wpa_s, subscribe_id);
+}
+
+
+
+static void wpas_nan_de_receive(void *ctx, int id, int peer_instance_id,
+ const u8 *ssi, size_t ssi_len,
+ const u8 *peer_addr)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpas_notify_nan_receive(wpa_s, id, peer_instance_id, peer_addr,
+ ssi, ssi_len);
+}
+
+
+#ifdef CONFIG_P2P
+static void wpas_nan_process_p2p_usd_elems(void *ctx, const u8 *buf,
+ u16 buf_len, const u8 *peer_addr,
+ unsigned int freq)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+
+ wpas_p2p_process_usd_elems(wpa_s, buf, buf_len, peer_addr, freq);
+}
+#endif /* CONFIG_P2P */
+
+
+int wpas_nan_de_init(struct wpa_supplicant *wpa_s)
+{
+ struct nan_callbacks cb;
+ bool offload = !!(wpa_s->drv_flags2 &
+ WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD);
+
+ os_memset(&cb, 0, sizeof(cb));
+ cb.ctx = wpa_s;
+ cb.tx = wpas_nan_de_tx;
+ cb.discovery_result = wpas_nan_de_discovery_result;
+ cb.replied = wpas_nan_de_replied;
+ cb.publish_terminated = wpas_nan_de_publish_terminated;
+ cb.subscribe_terminated = wpas_nan_de_subscribe_terminated;
+ cb.receive = wpas_nan_de_receive;
+#ifdef CONFIG_NAN_USD
+ cb.listen = wpas_nan_usd_listen;
+ cb.offload_cancel_publish = wpas_nan_usd_offload_cancel_publish;
+ cb.offload_cancel_subscribe = wpas_nan_usd_offload_cancel_subscribe;
+#ifdef CONFIG_P2P
+ cb.process_p2p_usd_elems = wpas_nan_process_p2p_usd_elems;
+#endif /* CONFIG_P2P */
+#endif /* CONFIG_NAN_USD */
+
+ wpa_s->nan_de = nan_de_init(wpa_s->own_addr, offload, false,
+ wpa_s->max_remain_on_chan, &cb);
+ if (!wpa_s->nan_de)
+ return -1;
+ return 0;
+}
+
+
+void wpas_nan_de_deinit(struct wpa_supplicant *wpa_s)
+{
+ nan_de_deinit(wpa_s->nan_de);
+ wpa_s->nan_de = NULL;
+}
+
+
+void wpas_nan_de_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
+ const u8 *a3,
+ unsigned int freq, const u8 *buf, size_t len)
+{
+ if (!wpa_s->nan_de)
+ return;
+ nan_de_rx_sdf(wpa_s->nan_de, src, a3, freq, buf, len);
+}
+
+
+void wpas_nan_de_flush(struct wpa_supplicant *wpa_s)
+{
+ if (!wpa_s->nan_de)
+ return;
+ nan_de_flush(wpa_s->nan_de);
+ if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
+ wpas_drv_nan_flush(wpa_s);
+}
+
+
+int wpas_nan_publish(struct wpa_supplicant *wpa_s, const char *service_name,
+ enum nan_service_protocol_type srv_proto_type,
+ const struct wpabuf *ssi,
+ struct nan_publish_params *params, bool p2p)
+{
+ int publish_id;
+ struct wpabuf *elems = NULL;
+ const u8 *addr;
+
+ if (!wpa_s->nan_de)
+ return -1;
+
+ if (p2p) {
+ elems = wpas_p2p_usd_elems(wpa_s, service_name);
+ addr = wpa_s->global->p2p_dev_addr;
+ } else {
+ addr = wpa_s->own_addr;
+ }
+
+ publish_id = nan_de_publish(wpa_s->nan_de, service_name, srv_proto_type,
+ ssi, elems, params, p2p);
+ if (publish_id >= 1 &&
+ (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
+ wpas_drv_nan_publish(wpa_s, addr, publish_id, service_name,
+ nan_de_get_service_id(wpa_s->nan_de,
+ publish_id),
+ srv_proto_type, ssi, elems, params) < 0) {
+ nan_de_cancel_publish(wpa_s->nan_de, publish_id);
+ publish_id = -1;
+ }
+
+ wpabuf_free(elems);
+ return publish_id;
+}
+
+
+void wpas_nan_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id)
+{
+ if (!wpa_s->nan_de)
+ return;
+ nan_de_cancel_publish(wpa_s->nan_de, publish_id);
+ if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
+ wpas_drv_nan_cancel_publish(wpa_s, publish_id);
+}
+
+
+int wpas_nan_update_publish(struct wpa_supplicant *wpa_s, int publish_id,
+ const struct wpabuf *ssi)
+{
+ int ret;
+
+ if (!wpa_s->nan_de)
+ return -1;
+ ret = nan_de_update_publish(wpa_s->nan_de, publish_id, ssi);
+ if (ret == 0 && (wpa_s->drv_flags2 &
+ WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
+ wpas_drv_nan_update_publish(wpa_s, publish_id, ssi) < 0)
+ return -1;
+ return ret;
+}
+
+
+int wpas_nan_usd_unpause_publish(struct wpa_supplicant *wpa_s, int publish_id,
+ u8 peer_instance_id, const u8 *peer_addr)
+{
+ if (!wpa_s->nan_de)
+ return -1;
+ return nan_de_unpause_publish(wpa_s->nan_de, publish_id,
+ peer_instance_id, peer_addr);
+}
+
+
+int wpas_nan_subscribe(struct wpa_supplicant *wpa_s,
+ const char *service_name,
+ enum nan_service_protocol_type srv_proto_type,
+ const struct wpabuf *ssi,
+ struct nan_subscribe_params *params, bool p2p)
+{
+ int subscribe_id;
+ struct wpabuf *elems = NULL;
+ const u8 *addr;
+
+ if (!wpa_s->nan_de)
+ return -1;
+
+ if (p2p) {
+ elems = wpas_p2p_usd_elems(wpa_s, service_name);
+ addr = wpa_s->global->p2p_dev_addr;
+ } else {
+ addr = wpa_s->own_addr;
+ }
+
+ subscribe_id = nan_de_subscribe(wpa_s->nan_de, service_name,
+ srv_proto_type, ssi, elems, params,
+ p2p);
+ if (subscribe_id >= 1 &&
+ (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
+ wpas_drv_nan_subscribe(wpa_s, addr, subscribe_id, service_name,
+ nan_de_get_service_id(wpa_s->nan_de,
+ subscribe_id),
+ srv_proto_type, ssi, elems, params) < 0) {
+ nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
+ subscribe_id = -1;
+ }
+
+ wpabuf_free(elems);
+ return subscribe_id;
+}
+
+
+void wpas_nan_cancel_subscribe(struct wpa_supplicant *wpa_s,
+ int subscribe_id)
+{
+ if (!wpa_s->nan_de)
+ return;
+ nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
+ if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
+ wpas_drv_nan_cancel_subscribe(wpa_s, subscribe_id);
+}
+
+
+int wpas_nan_transmit(struct wpa_supplicant *wpa_s, int handle,
+ const struct wpabuf *ssi, const struct wpabuf *elems,
+ const u8 *peer_addr, u8 req_instance_id)
+{
+ if (!wpa_s->nan_de)
+ return -1;
+ return nan_de_transmit(wpa_s->nan_de, handle, ssi, elems, peer_addr,
+ req_instance_id);
+}
+
+
+void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq, unsigned int duration)
+{
+ wpas_nan_usd_listen_work_done(wpa_s);
+
+ if (wpa_s->nan_de)
+ nan_de_listen_started(wpa_s->nan_de, freq, duration);
+}
+
+
+void wpas_nan_usd_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq)
+{
+ if (wpa_s->nan_de)
+ nan_de_listen_ended(wpa_s->nan_de, freq);
+}
+
+
+void wpas_nan_tx_wait_expire(struct wpa_supplicant *wpa_s)
+{
+ wpas_nan_tx_work_done(wpa_s);
+
+ if (wpa_s->nan_de)
+ nan_de_tx_wait_ended(wpa_s->nan_de);
+}
+
+
+int * wpas_nan_usd_all_freqs(struct wpa_supplicant *wpa_s)
+{
+ int i, j;
+ int *freqs = NULL;
+
+ if (!wpa_s->hw.modes)
+ return NULL;
+
+ for (i = 0; i < wpa_s->hw.num_modes; i++) {
+ struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i];
+
+ for (j = 0; j < mode->num_channels; j++) {
+ struct hostapd_channel_data *chan = &mode->channels[j];
+
+ /* All 20 MHz channels on 2.4 and 5 GHz band */
+ if (chan->freq < 2412 || chan->freq > 5900)
+ continue;
+
+ /* that allow frames to be transmitted */
+ if (chan->flag & (HOSTAPD_CHAN_DISABLED |
+ HOSTAPD_CHAN_NO_IR |
+ HOSTAPD_CHAN_RADAR))
+ continue;
+
+ int_array_add_unique(&freqs, chan->freq);
+ }
+ }
+
+ return freqs;
+}
+
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index 483130e6e1..9bf9713e72 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -1,5 +1,6 @@
/*
* wpa_supplicant - NAN
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc.
* Copyright (C) 2025 Intel Corporation
*
* This software may be distributed under the terms of the BSD license.
@@ -9,6 +10,7 @@
#ifndef NAN_SUPPLICANT_H
#define NAN_SUPPLICANT_H
+/* NAN synchronization only */
#ifdef CONFIG_NAN
int wpas_nan_init(struct wpa_supplicant *wpa_s);
@@ -53,4 +55,98 @@ static inline void wpas_nan_next_dw(struct wpa_supplicant *wpa_s, u32 freq)
{}
#endif /* CONFIG_NAN */
+struct nan_subscribe_params;
+struct nan_publish_params;
+enum nan_service_protocol_type;
+
+/* NAN sync and USD common */
+#if defined(CONFIG_NAN_USD) || defined (CONFIG_NAN)
+
+int wpas_nan_de_init(struct wpa_supplicant *wpa_s);
+void wpas_nan_de_deinit(struct wpa_supplicant *wpa_s);
+void wpas_nan_de_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
+ const u8 *a3,
+ unsigned int freq, const u8 *buf, size_t len);
+void wpas_nan_de_flush(struct wpa_supplicant *wpa_s);
+int wpas_nan_publish(struct wpa_supplicant *wpa_s, const char *service_name,
+ enum nan_service_protocol_type srv_proto_type,
+ const struct wpabuf *ssi,
+ struct nan_publish_params *params, bool p2p);
+void wpas_nan_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id);
+int wpas_nan_update_publish(struct wpa_supplicant *wpa_s, int publish_id,
+ const struct wpabuf *ssi);
+int wpas_nan_subscribe(struct wpa_supplicant *wpa_s,
+ const char *service_name,
+ enum nan_service_protocol_type srv_proto_type,
+ const struct wpabuf *ssi,
+ struct nan_subscribe_params *params, bool p2p);
+void wpas_nan_cancel_subscribe(struct wpa_supplicant *wpa_s,
+ int subscribe_id);
+int wpas_nan_transmit(struct wpa_supplicant *wpa_s, int handle,
+ const struct wpabuf *ssi, const struct wpabuf *elems,
+ const u8 *peer_addr, u8 req_instance_id);
+void wpas_nan_tx_wait_expire(struct wpa_supplicant *wpa_s);
+
+#else /* CONFIG_NAN_USD || CONFIG_NAN */
+
+static inline int wpas_nan_de_init(struct wpa_supplicant *wpa_s)
+{
+ return 0;
+}
+
+static inline void wpas_nan_de_deinit(struct wpa_supplicant *wpa_s)
+{}
+
+static inline
+void wpas_nan_de_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
+ const u8 *a3,
+ unsigned int freq, const u8 *buf, size_t len)
+{}
+
+static inline void wpas_nan_de_flush(struct wpa_supplicant *wpa_s)
+{}
+
+static inline void wpas_nan_tx_wait_expire(struct wpa_supplicant *wpa_s)
+{}
+
+#endif /* CONFIG_NAN_USD || CONFIG_NAN */
+
+/* NAN USD only */
+#ifdef CONFIG_NAN_USD
+void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq,
+ unsigned int duration);
+void wpas_nan_usd_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq);
+int * wpas_nan_usd_all_freqs(struct wpa_supplicant *wpa_s);
+int wpas_nan_usd_unpause_publish(struct wpa_supplicant *wpa_s, int publish_id,
+ u8 peer_instance_id, const u8 *peer_addr);
+
+#else /* CONFIG_NAN_USD */
+
+static inline
+void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq,
+ unsigned int duration)
+{}
+
+static inline
+void wpas_nan_usd_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
+ unsigned int freq)
+{}
+
+static inline
+int * wpas_nan_usd_all_freqs(struct wpa_supplicant *wpa_s)
+{
+ return NULL;
+}
+
+static inline
+int wpas_nan_usd_unpause_publish(struct wpa_supplicant *wpa_s, int publish_id,
+ u8 peer_instance_id, const u8 *peer_addr)
+{
+ return -1;
+}
+#endif /* CONFIG_NAN_USD */
+
#endif /* NAN_SUPPLICANT_H */
diff --git a/wpa_supplicant/nan_usd.c b/wpa_supplicant/nan_usd.c
deleted file mode 100644
index 9320fa816b..0000000000
--- a/wpa_supplicant/nan_usd.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * NAN unsynchronized service discovery (USD)
- * Copyright (c) 2024, Qualcomm Innovation Center, Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/nan_de.h"
-#include "wpa_supplicant_i.h"
-#include "offchannel.h"
-#include "driver_i.h"
-#include "notify.h"
-#include "p2p_supplicant.h"
-#include "nan_usd.h"
-
-
-static const char *
-tx_status_result_txt(enum offchannel_send_action_result result)
-{
- switch (result) {
- case OFFCHANNEL_SEND_ACTION_SUCCESS:
- return "success";
- case OFFCHANNEL_SEND_ACTION_NO_ACK:
- return "no-ack";
- case OFFCHANNEL_SEND_ACTION_FAILED:
- return "failed";
- }
-
- return "?";
-}
-
-
-static void wpas_nan_de_tx_status(struct wpa_supplicant *wpa_s,
- unsigned int freq, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const u8 *data, size_t data_len,
- enum offchannel_send_action_result result)
-{
- if (!wpa_s->nan_de)
- return;
-
- wpa_printf(MSG_DEBUG, "NAN: TX status A1=" MACSTR " A2=" MACSTR
- " A3=" MACSTR " freq=%d len=%zu result=%s",
- MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), freq,
- data_len, tx_status_result_txt(result));
-
- nan_de_tx_status(wpa_s->nan_de, freq, dst);
-}
-
-
-struct wpas_nan_usd_tx_work {
- unsigned int freq;
- unsigned int wait_time;
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 bssid[ETH_ALEN];
- struct wpabuf *buf;
-};
-
-
-static void wpas_nan_usd_tx_work_free(struct wpas_nan_usd_tx_work *twork)
-{
- if (!twork)
- return;
- wpabuf_free(twork->buf);
- os_free(twork);
-}
-
-
-static void wpas_nan_usd_tx_work_done(struct wpa_supplicant *wpa_s)
-{
- struct wpas_nan_usd_tx_work *twork;
-
- if (!wpa_s->nan_usd_tx_work)
- return;
-
- twork = wpa_s->nan_usd_tx_work->ctx;
- wpas_nan_usd_tx_work_free(twork);
- radio_work_done(wpa_s->nan_usd_tx_work);
- wpa_s->nan_usd_tx_work = NULL;
-}
-
-
-static int wpas_nan_de_tx_send(struct wpa_supplicant *wpa_s, unsigned int freq,
- unsigned int wait_time, const u8 *dst,
- const u8 *src, const u8 *bssid,
- const struct wpabuf *buf)
-{
- wpa_printf(MSG_DEBUG, "NAN: TX NAN SDF A1=" MACSTR " A2=" MACSTR
- " A3=" MACSTR " freq=%d len=%zu",
- MAC2STR(dst), MAC2STR(src), MAC2STR(bssid), freq,
- wpabuf_len(buf));
-
- return offchannel_send_action(wpa_s, freq, dst, src, bssid,
- wpabuf_head(buf), wpabuf_len(buf),
- wait_time, wpas_nan_de_tx_status, 1);
-}
-
-
-static void wpas_nan_usd_start_tx_cb(struct wpa_radio_work *work, int deinit)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct wpas_nan_usd_tx_work *twork = work->ctx;
-
- if (deinit) {
- if (work->started) {
- wpa_s->nan_usd_tx_work = NULL;
- offchannel_send_action_done(wpa_s);
- }
- wpas_nan_usd_tx_work_free(twork);
- return;
- }
-
- wpa_s->nan_usd_tx_work = work;
-
- if (wpas_nan_de_tx_send(wpa_s, twork->freq, twork->wait_time,
- twork->dst, twork->src, twork->bssid,
- twork->buf) < 0)
- wpas_nan_usd_tx_work_done(wpa_s);
-}
-
-
-static int wpas_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)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpas_nan_usd_tx_work *twork;
-
- if (wpa_s->nan_usd_tx_work || wpa_s->nan_usd_listen_work) {
- /* Reuse ongoing radio work */
- return wpas_nan_de_tx_send(wpa_s, freq, wait_time, dst, src,
- bssid, buf);
- }
-
- twork = os_zalloc(sizeof(*twork));
- if (!twork)
- return -1;
- twork->freq = freq;
- twork->wait_time = wait_time;
- os_memcpy(twork->dst, dst, ETH_ALEN);
- os_memcpy(twork->src, src, ETH_ALEN);
- os_memcpy(twork->bssid, bssid, ETH_ALEN);
- twork->buf = wpabuf_dup(buf);
- if (!twork->buf) {
- wpas_nan_usd_tx_work_free(twork);
- return -1;
- }
-
- if (radio_add_work(wpa_s, freq, "nan-usd-tx", 0,
- wpas_nan_usd_start_tx_cb, twork) < 0) {
- wpas_nan_usd_tx_work_free(twork);
- return -1;
- }
-
- return 0;
-}
-
-
-struct wpas_nan_usd_listen_work {
- unsigned int freq;
- unsigned int duration;
-};
-
-
-static void wpas_nan_usd_listen_work_done(struct wpa_supplicant *wpa_s)
-{
- struct wpas_nan_usd_listen_work *lwork;
-
- if (!wpa_s->nan_usd_listen_work)
- return;
-
- lwork = wpa_s->nan_usd_listen_work->ctx;
- os_free(lwork);
- radio_work_done(wpa_s->nan_usd_listen_work);
- wpa_s->nan_usd_listen_work = NULL;
-}
-
-
-static void wpas_nan_usd_start_listen_cb(struct wpa_radio_work *work,
- int deinit)
-{
- struct wpa_supplicant *wpa_s = work->wpa_s;
- struct wpas_nan_usd_listen_work *lwork = work->ctx;
- unsigned int duration;
-
- if (deinit) {
- if (work->started) {
- wpa_s->nan_usd_listen_work = NULL;
- wpa_drv_cancel_remain_on_channel(wpa_s);
- }
- os_free(lwork);
- return;
- }
-
- wpa_s->nan_usd_listen_work = work;
-
- duration = lwork->duration;
- if (duration > wpa_s->max_remain_on_chan)
- duration = wpa_s->max_remain_on_chan;
- wpa_printf(MSG_DEBUG, "NAN: Start listen on %u MHz for %u ms",
- lwork->freq, duration);
- if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, duration) < 0) {
- wpa_printf(MSG_DEBUG,
- "NAN: Failed to request the driver to remain on channel (%u MHz) for listen",
- lwork->freq);
- wpas_nan_usd_listen_work_done(wpa_s);
- return;
- }
-}
-
-
-static int wpas_nan_de_listen(void *ctx, unsigned int freq,
- unsigned int duration)
-{
- struct wpa_supplicant *wpa_s = ctx;
- struct wpas_nan_usd_listen_work *lwork;
-
- lwork = os_zalloc(sizeof(*lwork));
- if (!lwork)
- return -1;
- lwork->freq = freq;
- lwork->duration = duration;
-
- if (radio_add_work(wpa_s, freq, "nan-usd-listen", 0,
- wpas_nan_usd_start_listen_cb, lwork) < 0) {
- os_free(lwork);
- return -1;
- }
-
- return 0;
-}
-
-
-static void
-wpas_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)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_notify_nan_discovery_result(wpa_s, srv_proto_type, subscribe_id,
- peer_publish_id, peer_addr, fsd,
- fsd_gas, ssi, ssi_len);
-}
-
-
-static void wpas_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)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_notify_nan_replied(wpa_s, srv_proto_type, publish_id,
- peer_subscribe_id, peer_addr, ssi, ssi_len);
-}
-
-
-static void wpas_nan_de_publish_terminated(void *ctx, int publish_id,
- enum nan_de_reason reason)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_notify_nan_publish_terminated(wpa_s, publish_id, reason);
-}
-
-
-static void wpas_nan_usd_offload_cancel_publish(void *ctx, int publish_id)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
- wpas_drv_nan_cancel_publish(wpa_s, publish_id);
-}
-
-
-static void wpas_nan_de_subscribe_terminated(void *ctx, int subscribe_id,
- enum nan_de_reason reason)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_notify_nan_subscribe_terminated(wpa_s, subscribe_id, reason);
-}
-
-
-static void wpas_nan_usd_offload_cancel_subscribe(void *ctx, int subscribe_id)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
- wpas_drv_nan_cancel_subscribe(wpa_s, subscribe_id);
-}
-
-
-static void wpas_nan_de_receive(void *ctx, int id, int peer_instance_id,
- const u8 *ssi, size_t ssi_len,
- const u8 *peer_addr)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_notify_nan_receive(wpa_s, id, peer_instance_id, peer_addr,
- ssi, ssi_len);
-}
-
-
-#ifdef CONFIG_P2P
-static void wpas_nan_process_p2p_usd_elems(void *ctx, const u8 *buf,
- u16 buf_len, const u8 *peer_addr,
- unsigned int freq)
-{
- struct wpa_supplicant *wpa_s = ctx;
-
- wpas_p2p_process_usd_elems(wpa_s, buf, buf_len, peer_addr, freq);
-}
-#endif /* CONFIG_P2P */
-
-
-int wpas_nan_usd_init(struct wpa_supplicant *wpa_s)
-{
- struct nan_callbacks cb;
- bool offload = !!(wpa_s->drv_flags2 &
- WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD);
-
- os_memset(&cb, 0, sizeof(cb));
- cb.ctx = wpa_s;
- cb.tx = wpas_nan_de_tx;
- cb.listen = wpas_nan_de_listen;
- cb.discovery_result = wpas_nan_de_discovery_result;
- cb.replied = wpas_nan_de_replied;
- cb.publish_terminated = wpas_nan_de_publish_terminated;
- cb.subscribe_terminated = wpas_nan_de_subscribe_terminated;
- cb.offload_cancel_publish = wpas_nan_usd_offload_cancel_publish;
- cb.offload_cancel_subscribe = wpas_nan_usd_offload_cancel_subscribe;
- cb.receive = wpas_nan_de_receive;
-#ifdef CONFIG_P2P
- cb.process_p2p_usd_elems = wpas_nan_process_p2p_usd_elems;
-#endif /* CONFIG_P2P */
-
- wpa_s->nan_de = nan_de_init(wpa_s->own_addr, offload, false,
- wpa_s->max_remain_on_chan, &cb);
- if (!wpa_s->nan_de)
- return -1;
- return 0;
-}
-
-
-void wpas_nan_usd_deinit(struct wpa_supplicant *wpa_s)
-{
- nan_de_deinit(wpa_s->nan_de);
- wpa_s->nan_de = NULL;
-}
-
-
-void wpas_nan_usd_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *a3,
- unsigned int freq, const u8 *buf, size_t len)
-{
- if (!wpa_s->nan_de)
- return;
- nan_de_rx_sdf(wpa_s->nan_de, src, a3, freq, buf, len);
-}
-
-
-void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s)
-{
- if (!wpa_s->nan_de)
- return;
- nan_de_flush(wpa_s->nan_de);
- if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
- wpas_drv_nan_flush(wpa_s);
-}
-
-
-int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name,
- enum nan_service_protocol_type srv_proto_type,
- const struct wpabuf *ssi,
- struct nan_publish_params *params, bool p2p)
-{
- int publish_id;
- struct wpabuf *elems = NULL;
- const u8 *addr;
-
- if (!wpa_s->nan_de)
- return -1;
-
- if (p2p) {
- elems = wpas_p2p_usd_elems(wpa_s, service_name);
- addr = wpa_s->global->p2p_dev_addr;
- } else {
- addr = wpa_s->own_addr;
- }
-
- publish_id = nan_de_publish(wpa_s->nan_de, service_name, srv_proto_type,
- ssi, elems, params, p2p);
- if (publish_id >= 1 &&
- (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
- wpas_drv_nan_publish(wpa_s, addr, publish_id, service_name,
- nan_de_get_service_id(wpa_s->nan_de,
- publish_id),
- srv_proto_type, ssi, elems, params) < 0) {
- nan_de_cancel_publish(wpa_s->nan_de, publish_id);
- publish_id = -1;
- }
-
- wpabuf_free(elems);
- return publish_id;
-}
-
-
-void wpas_nan_usd_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id)
-{
- if (!wpa_s->nan_de)
- return;
- nan_de_cancel_publish(wpa_s->nan_de, publish_id);
- if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
- wpas_drv_nan_cancel_publish(wpa_s, publish_id);
-}
-
-
-int wpas_nan_usd_update_publish(struct wpa_supplicant *wpa_s, int publish_id,
- const struct wpabuf *ssi)
-{
- int ret;
-
- if (!wpa_s->nan_de)
- return -1;
- ret = nan_de_update_publish(wpa_s->nan_de, publish_id, ssi);
- if (ret == 0 && (wpa_s->drv_flags2 &
- WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
- wpas_drv_nan_update_publish(wpa_s, publish_id, ssi) < 0)
- return -1;
- return ret;
-}
-
-
-int wpas_nan_usd_unpause_publish(struct wpa_supplicant *wpa_s, int publish_id,
- u8 peer_instance_id, const u8 *peer_addr)
-{
- if (!wpa_s->nan_de)
- return -1;
- return nan_de_unpause_publish(wpa_s->nan_de, publish_id,
- peer_instance_id, peer_addr);
-}
-
-
-int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s,
- const char *service_name,
- enum nan_service_protocol_type srv_proto_type,
- const struct wpabuf *ssi,
- struct nan_subscribe_params *params, bool p2p)
-{
- int subscribe_id;
- struct wpabuf *elems = NULL;
- const u8 *addr;
-
- if (!wpa_s->nan_de)
- return -1;
-
- if (p2p) {
- elems = wpas_p2p_usd_elems(wpa_s, service_name);
- addr = wpa_s->global->p2p_dev_addr;
- } else {
- addr = wpa_s->own_addr;
- }
-
- subscribe_id = nan_de_subscribe(wpa_s->nan_de, service_name,
- srv_proto_type, ssi, elems, params,
- p2p);
- if (subscribe_id >= 1 &&
- (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD) &&
- wpas_drv_nan_subscribe(wpa_s, addr, subscribe_id, service_name,
- nan_de_get_service_id(wpa_s->nan_de,
- subscribe_id),
- srv_proto_type, ssi, elems, params) < 0) {
- nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
- subscribe_id = -1;
- }
-
- wpabuf_free(elems);
- return subscribe_id;
-}
-
-
-void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s,
- int subscribe_id)
-{
- if (!wpa_s->nan_de)
- return;
- nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
- if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD)
- wpas_drv_nan_cancel_subscribe(wpa_s, subscribe_id);
-}
-
-
-int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle,
- const struct wpabuf *ssi, const struct wpabuf *elems,
- const u8 *peer_addr, u8 req_instance_id)
-{
- if (!wpa_s->nan_de)
- return -1;
- return nan_de_transmit(wpa_s->nan_de, handle, ssi, elems, peer_addr,
- req_instance_id);
-}
-
-
-void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq, unsigned int duration)
-{
- wpas_nan_usd_listen_work_done(wpa_s);
-
- if (wpa_s->nan_de)
- nan_de_listen_started(wpa_s->nan_de, freq, duration);
-}
-
-
-void wpas_nan_usd_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq)
-{
- if (wpa_s->nan_de)
- nan_de_listen_ended(wpa_s->nan_de, freq);
-}
-
-
-void wpas_nan_usd_tx_wait_expire(struct wpa_supplicant *wpa_s)
-{
- wpas_nan_usd_tx_work_done(wpa_s);
-
- if (wpa_s->nan_de)
- nan_de_tx_wait_ended(wpa_s->nan_de);
-}
-
-
-int * wpas_nan_usd_all_freqs(struct wpa_supplicant *wpa_s)
-{
- int i, j;
- int *freqs = NULL;
-
- if (!wpa_s->hw.modes)
- return NULL;
-
- for (i = 0; i < wpa_s->hw.num_modes; i++) {
- struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i];
-
- for (j = 0; j < mode->num_channels; j++) {
- struct hostapd_channel_data *chan = &mode->channels[j];
-
- /* All 20 MHz channels on 2.4 and 5 GHz band */
- if (chan->freq < 2412 || chan->freq > 5900)
- continue;
-
- /* that allow frames to be transmitted */
- if (chan->flag & (HOSTAPD_CHAN_DISABLED |
- HOSTAPD_CHAN_NO_IR |
- HOSTAPD_CHAN_RADAR))
- continue;
-
- int_array_add_unique(&freqs, chan->freq);
- }
- }
-
- return freqs;
-}
diff --git a/wpa_supplicant/nan_usd.h b/wpa_supplicant/nan_usd.h
deleted file mode 100644
index 6a43fb2417..0000000000
--- a/wpa_supplicant/nan_usd.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * NAN unsynchronized service discovery (USD)
- * 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_USD_H
-#define NAN_USD_H
-
-struct nan_subscribe_params;
-struct nan_publish_params;
-enum nan_service_protocol_type;
-
-int wpas_nan_usd_init(struct wpa_supplicant *wpa_s);
-void wpas_nan_usd_deinit(struct wpa_supplicant *wpa_s);
-void wpas_nan_usd_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *a3,
- unsigned int freq, const u8 *buf, size_t len);
-void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s);
-int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name,
- enum nan_service_protocol_type srv_proto_type,
- const struct wpabuf *ssi,
- struct nan_publish_params *params, bool p2p);
-void wpas_nan_usd_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id);
-int wpas_nan_usd_update_publish(struct wpa_supplicant *wpa_s, int publish_id,
- const struct wpabuf *ssi);
-int wpas_nan_usd_unpause_publish(struct wpa_supplicant *wpa_s, int publish_id,
- u8 peer_instance_id, const u8 *peer_addr);
-int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s,
- const char *service_name,
- enum nan_service_protocol_type srv_proto_type,
- const struct wpabuf *ssi,
- struct nan_subscribe_params *params, bool p2p);
-void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s,
- int subscribe_id);
-int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle,
- const struct wpabuf *ssi, const struct wpabuf *elems,
- const u8 *peer_addr, u8 req_instance_id);
-void wpas_nan_usd_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq,
- unsigned int duration);
-void wpas_nan_usd_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
- unsigned int freq);
-void wpas_nan_usd_tx_wait_expire(struct wpa_supplicant *wpa_s);
-int * wpas_nan_usd_all_freqs(struct wpa_supplicant *wpa_s);
-
-#endif /* NAN_USD_H */
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 300e118f33..61c33502b9 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -39,6 +39,7 @@
#include "wps_supplicant.h"
#include "p2p_supplicant.h"
#include "wifi_display.h"
+#include "nan_supplicant.h"
/*
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 5bfee7abe8..aafad96a69 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -65,7 +65,6 @@
#include "wpas_kay.h"
#include "mesh.h"
#include "dpp_supplicant.h"
-#include "nan_usd.h"
#include "nan_supplicant.h"
#ifdef CONFIG_MESH
#include "ap/ap_config.h"
@@ -865,9 +864,7 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
wpa_s->dpp = NULL;
#endif /* CONFIG_DPP */
-#ifdef CONFIG_NAN_USD
- wpas_nan_usd_deinit(wpa_s);
-#endif /* CONFIG_NAN_USD */
+ wpas_nan_de_deinit(wpa_s);
#ifdef CONFIG_PASN
wpas_pasn_auth_stop(wpa_s);
@@ -7919,10 +7916,8 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
return -1;
#endif /* CONFIG_DPP */
-#ifdef CONFIG_NAN_USD
- if (wpas_nan_usd_init(wpa_s) < 0)
+ if (wpas_nan_de_init(wpa_s) < 0)
return -1;
-#endif /* CONFIG_NAN_USD */
#ifdef CONFIG_NAN
wpa_s->nan_drv_flags = capa.nan_flags;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 0387768a52..46f841aeba 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1626,7 +1626,7 @@ struct wpa_supplicant {
#ifdef CONFIG_NAN_USD
struct nan_de *nan_de;
struct wpa_radio_work *nan_usd_listen_work;
- struct wpa_radio_work *nan_usd_tx_work;
+ struct wpa_radio_work *nan_tx_work;
#endif /* CONFIG_NAN_USD */
bool ssid_verified;
--
2.49.0
More information about the Hostap
mailing list