[PATCH 74/97] wpa_supplicant: Handle NAN ULW notification

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Apr 28 13:06:15 PDT 2026


From: Avraham Stern <avraham.stern at intel.com>

When the driver notifies about a ULW attribute, add the ULW attribute
to NAN frames together with the NAN availability attribute.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 src/drivers/driver.h              | 21 +++++++++++++++++
 src/drivers/driver_common.c       |  1 +
 wpa_supplicant/events.c           |  4 ++++
 wpa_supplicant/nan_supplicant.c   | 38 ++++++++++++++++++++++++++++++-
 wpa_supplicant/nan_supplicant.h   |  6 +++++
 wpa_supplicant/wpa_supplicant_i.h |  1 +
 6 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index c38ad98d6a..36ae970ba9 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -6507,6 +6507,14 @@ enum wpa_event_type {
 	 * update has been completed by the driver/firmware.
 	 */
 	EVENT_NAN_SCHED_UPDATE_DONE,
+
+	/**
+	 * EVENT_NAN_ULW_UPDATE - NAN ULW blob update
+	 *
+	 * This event is used to notify wpa_supplicant that the device ULW blob
+	 * has changed and can be attached to outgoing NAN frames.
+	 */
+	EVENT_NAN_ULW_UPDATE,
 };
 
 
@@ -7537,6 +7545,19 @@ union wpa_event_data {
 	struct nan_sched_update_done_info {
 		bool success;
 	} nan_sched_update_done_info;
+
+	/**
+	 * struct nan_ulw_update_info - Data for EVENT_NAN_ULW_UPDATE
+	 * @ulw: Pointer to ULW blob data, containing one or more Unaligned
+	 *	Schedule attributes as defined in the Wi-Fi Aware (TM) 4.0
+	 *	specification Table 109, including attribute header for each
+	 *	attribute.
+	 * @ulw_len: ULW blob length in bytes
+	 */
+	struct nan_ulw_update_info {
+		const u8 *ulw;
+		size_t ulw_len;
+	} nan_ulw_update_info;
 };
 
 /**
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index 5a3a07a89e..5835095d22 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -106,6 +106,7 @@ const char * event_to_string(enum wpa_event_type event)
 	E2S(NAN_NEXT_DW);
 	E2S(INCUMBT_SIG_INTF_DETECTED);
 	E2S(NAN_SCHED_UPDATE_DONE);
+	E2S(NAN_ULW_UPDATE);
 	}
 
 	return "UNKNOWN";
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index dcf1af5f49..0157820aee 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -7655,6 +7655,10 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 	case EVENT_NAN_SCHED_UPDATE_DONE:
 		wpas_nan_sched_update_done(wpa_s, data);
 		break;
+	case EVENT_NAN_ULW_UPDATE:
+		wpas_nan_ulw_update(wpa_s, data->nan_ulw_update_info.ulw,
+				    data->nan_ulw_update_info.ulw_len);
+		break;
 #endif /* CONFIG_NAN */
 	default:
 		wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index c5626d7dcc..25e746d4c6 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -1467,6 +1467,8 @@ void wpas_nan_deinit(struct wpa_supplicant *wpa_s)
 	os_memset(&wpa_s->nan_disallowed_freqs, 0,
 		  sizeof(wpa_s->nan_disallowed_freqs));
 	clear_sched_config(&wpa_s->nan_sched_update.sched);
+	wpabuf_free(wpa_s->nan_ulw_attr);
+	wpa_s->nan_ulw_attr = NULL;
 
 	wpa_s->nan = NULL;
 }
@@ -3355,6 +3357,7 @@ static void wpas_nan_de_add_extra_attrs(void *ctx, struct wpabuf *buf)
 	struct wpa_supplicant *wpa_s = ctx;
 	struct nan_schedule sched;
 	u32 map_ids = (BIT(wpa_s->nan_capa.num_radios) - 1) << 1;
+	int i;
 
 	if (!wpas_nan_ndp_allowed(wpa_s) || !map_ids)
 		return;
@@ -3365,8 +3368,18 @@ static void wpas_nan_de_add_extra_attrs(void *ctx, struct wpabuf *buf)
 					 wpa_s->schedule_sequence_id,
 					 map_ids, sched.n_chans,
 					 sched.chans, buf, true);
-
 	nan_pairing_add_attrs(wpa_s->nan, buf);
+
+	if (!wpa_s->nan_ulw_attr)
+		return;
+
+	/* Add ULW attribute only if there are committed availability entries */
+	for (i = 0; i < sched.n_chans; i++) {
+		if (sched.chans[i].committed.len) {
+			wpabuf_put_buf(buf, wpa_s->nan_ulw_attr);
+			break;
+		}
+	}
 }
 
 
@@ -3429,6 +3442,29 @@ void wpas_nan_sched_update_done(struct wpa_supplicant *wpa_s,
 }
 
 
+void wpas_nan_ulw_update(struct wpa_supplicant *wpa_s,
+			 const u8 *ulw, size_t ulw_len)
+{
+	if (!wpas_nan_ready(wpa_s))
+		return;
+
+	wpabuf_free(wpa_s->nan_ulw_attr);
+	if (ulw && ulw_len) {
+		wpa_s->nan_ulw_attr = wpabuf_alloc_copy(ulw, ulw_len);
+		if (!wpa_s->nan_ulw_attr) {
+			wpa_printf(MSG_ERROR,
+				   "NAN: Failed to allocate ULW attribute buffer");
+			return;
+		}
+
+		wpa_hexdump(MSG_DEBUG, "NAN: ULW update", ulw, ulw_len);
+	} else {
+		wpa_printf(MSG_DEBUG, "NAN: ULW update cleared");
+		wpa_s->nan_ulw_attr = NULL;
+	}
+}
+
+
 #ifdef CONFIG_PASN
 
 static int wpas_nan_pasn_update_station(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index 3105dc54f0..415934fc35 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -26,6 +26,8 @@ void wpas_nan_cluster_join(struct wpa_supplicant *wpa_s,
 void wpas_nan_next_dw(struct wpa_supplicant *wpa_s, u32 freq);
 void wpas_nan_sched_update_done(struct wpa_supplicant *wpa_s,
 				const union wpa_event_data *data);
+void wpas_nan_ulw_update(struct wpa_supplicant *wpa_s,
+			 const u8 *ulw, size_t ulw_len);
 int wpas_nan_sched_config_map(struct wpa_supplicant *wpa_s, const char *cmd);
 int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd);
 void wpas_nan_rx_naf(struct wpa_supplicant *wpa_s,
@@ -93,6 +95,10 @@ static inline void wpas_nan_sched_update_done(struct wpa_supplicant *wpa_s,
 					      const union wpa_event_data *data)
 {}
 
+static inline void wpas_nan_ulw_update(struct wpa_supplicant *wpa_s,
+				       const u8 *ulw, size_t ulw_len)
+{}
+
 static inline void wpas_nan_rx_naf(struct wpa_supplicant *wpa_s,
 				   const struct ieee80211_mgmt *mgmt,
 				   size_t len)
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 45a70fbead..95c0f577d4 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1740,6 +1740,7 @@ struct wpa_supplicant {
 		struct nan_schedule_config sched;
 		u8 map_id;
 	} nan_sched_update;
+	struct wpabuf *nan_ulw_attr;
 	struct wpa_freq_range_list nan_disallowed_freqs;
 	u16 nan_max_bw;
 	unsigned int nan_ndi_ndp_refcount; /* Active NDP count on this NDI */
-- 
2.53.0




More information about the Hostap mailing list