[RFC 08/13] wpa_supplicant: Implement NAN bootstrap callbacks and configuration

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Dec 23 03:57:20 PST 2025


- Implement NAN bootsrapping callbacks
- Assign default configuration for bootstrapping
- Support configuring bootstrapping from control interface.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/common/wpa_ctrl.h           |  3 ++
 src/nan/nan.c                   | 26 ++++++++++
 src/nan/nan.h                   |  4 ++
 wpa_supplicant/nan_supplicant.c | 90 ++++++++++++++++++++++++++++++++-
 wpa_supplicant/notify.c         | 28 ++++++++++
 wpa_supplicant/notify.h         |  7 +++
 6 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 3c4f8f9f68..f726be6c37 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -251,6 +251,9 @@ extern "C" {
 #define NAN_NDP_COUNTER_REQUEST "NAN-NDP-COUNTER-REQUEST "
 #define NAN_NDP_CONNECTED "NAN-NDP-CONNECTED "
 #define NAN_NDP_DISCONNECTED "NAN-NDP-DISCONNECTED "
+#define NAN_BOOTSTRAP_REQUEST "NAN-BOOTSTRAP-REQUEST "
+#define NAN_BOOTSTRAP_SUCCESS "NAN-BOOTSTRAP-SUCCESS "
+#define NAN_BOOTSTRAP_FAILURE "NAN-BOOTSTRAP-FAILURE "
 
 /* MESH events */
 #define MESH_GROUP_STARTED "MESH-GROUP-STARTED "
diff --git a/src/nan/nan.c b/src/nan/nan.c
index 869f9fbac1..3767db6c39 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -2314,3 +2314,29 @@ int nan_get_peer_elems(struct nan_data *nan, const u8 *addr, u8 **elems)
 
 	return -1;
 }
+
+
+/**
+ * nan_set_bootstrap_configuration - Set NAN bootstrap configuration
+ *
+ * @nan: NAN module context from nan_init()
+ * @supported_bootstrap_methods: Bitmap of supported bootstrap methods
+ * @auto_accept_bootstrap_methods: Bitmap of bootstrap methods to auto-accept
+ * @bootstrap_comeback_timeout: Timeout in TUs for bootstrap comeback
+ * Return 0 on success; -1 on failure.
+ */
+int nan_set_bootstrap_configuration(struct nan_data *nan,
+				    u16 supported_bootstrap_methods,
+				    u16 auto_accept_bootstrap_methods,
+				    u16 bootstrap_comeback_timeout)
+{
+	if (!nan)
+		return -1;
+
+	nan->cfg->supported_bootstrap_methods = supported_bootstrap_methods;
+	nan->cfg->auto_accept_bootstrap_methods =
+		auto_accept_bootstrap_methods;
+	nan->cfg->bootstrap_comeback_timeout = bootstrap_comeback_timeout;
+
+	return 0;
+}
diff --git a/src/nan/nan.h b/src/nan/nan.h
index 1c070cf7b9..9ce3448444 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -640,4 +640,8 @@ int nan_peer_del_all_ndps(struct nan_data *nan, const u8 *addr);
 int nan_get_chan_entry(struct nan_data *nan, const struct nan_sched_chan *chan,
 		       struct nan_chan_entry *chan_entry);
 int nan_get_peer_elems(struct nan_data *nan, const u8 *addr, u8 **elems);
+int nan_set_bootstrap_configuration(struct nan_data *nan,
+				    u16 supported_bootstrap_methods,
+				    u16 auto_accept_bootstrap_methods,
+				    u16 bootstrap_comeback_timeout);
 #endif /* NAN_H */
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 1815455c9d..e32169b43c 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -35,6 +35,21 @@
 
 #define NAN_MIN_RSSI_CLOSE  -60
 #define NAN_MIN_RSSI_MIDDLE -75
+
+#define DEFAULT_NAN_SUPP_PBM (NAN_PBA_METHOD_OPPORTUNISTIC |      \
+			      NAN_PBA_METHOD_PIN_DISPLAY |        \
+			      NAN_PBA_METHOD_PASSPHRASE_DISPLAY | \
+			      NAN_PBA_METHOD_QR_DISPLAY |         \
+			      NAN_PBA_METHOD_NFC_TAG |            \
+			      NAN_PBA_METHOD_PIN_KEYPAD |         \
+			      NAN_PBA_METHOD_PASSPHRASE_KEYPAD |  \
+			      NAN_PBA_METHOD_QR_SCAN |            \
+			      NAN_PBA_METHOD_NFC_READER)
+
+#define DEFAULT_NAN_AUTO_ACCEPT_PBM NAN_PBA_METHOD_OPPORTUNISTIC
+
+#define DEFAULT_NAN_BOOTSTRAP_COMEBACK_TIMEOUT 1024
+
 #ifdef CONFIG_NAN
 
 static int get_center(u8 channel, const u8 *center_channels, size_t num_chan,
@@ -742,7 +757,7 @@ static bool wpas_nan_is_valid_publish_id_cb(void *ctx, u8 instance_id,
 {
 	struct wpa_supplicant *wpa_s = ctx;
 
-	wpa_printf(MSG_DEBUG, "NAN: Check valid publish ID - instance_id=%u",
+	wpa_printf(MSG_DEBUG, "NAN: Check valid publish ID: instance_id=%u",
 		   instance_id);
 
 	return nan_de_is_valid_instance_id(wpa_s->nan_de, instance_id,
@@ -750,6 +765,54 @@ static bool wpas_nan_is_valid_publish_id_cb(void *ctx, u8 instance_id,
 }
 
 
+static void wpas_nan_bootstrap_request_cb(void *ctx, const u8 *peer_nmi,
+					  u16 pbm)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+
+	wpas_notify_nan_bootstrap_request(wpa_s, peer_nmi, pbm);
+}
+
+
+static void wpas_nan_bootstrap_completed_cb(void *ctx, const u8 *peer_nmi,
+					    u16 pbm, bool success,
+					    u8 reason_code)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+
+	if (success)
+		wpas_notify_nan_bootstrap_success(wpa_s, peer_nmi, pbm);
+	else
+		wpas_notify_nan_bootstrap_failure(wpa_s, peer_nmi, pbm,
+						  reason_code);
+}
+
+
+static int wpas_nan_transmit_followup_cb(void *ctx, const u8 *peer_nmi,
+					 const struct wpabuf *attrs, int handle,
+					 u8 req_instance_id)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+
+	if (!wpa_s->nan_de)
+		return -1;
+
+	return nan_de_transmit(wpa_s->nan_de, handle, NULL, NULL,
+			       peer_nmi, req_instance_id, attrs);
+}
+
+
+static u16 wpas_nan_get_service_bootstrap_methods(void *ctx, int handle)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+
+	if (!wpa_s->nan_de)
+		return 0;
+
+	return nan_de_get_service_bootstrap_methods(wpa_s->nan_de, handle);
+}
+
+
 int wpas_nan_init(struct wpa_supplicant *wpa_s)
 {
 	struct nan_config nan;
@@ -797,6 +860,15 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
 	nan.dev_capa.n_antennas = wpa_s->nan_capa.num_antennas;
 	nan.dev_capa.channel_switch_time = wpa_s->nan_capa.max_channel_switch_time;
 	nan.dev_capa.capa = wpa_s->nan_capa.dev_capa;
+	nan.bootstrap_request = wpas_nan_bootstrap_request_cb;
+	nan.bootstrap_completed = wpas_nan_bootstrap_completed_cb;
+	nan.transmit_followup = wpas_nan_transmit_followup_cb;
+	nan.get_supported_bootstrap_methods =
+		wpas_nan_get_service_bootstrap_methods;
+
+	nan.supported_bootstrap_methods = DEFAULT_NAN_SUPP_PBM;
+	nan.auto_accept_bootstrap_methods = DEFAULT_NAN_AUTO_ACCEPT_PBM;
+	nan.bootstrap_comeback_timeout = DEFAULT_NAN_BOOTSTRAP_COMEBACK_TIMEOUT;
 
 	wpa_s->nan = nan_init(&nan);
 	if (!wpa_s->nan) {
@@ -984,6 +1056,22 @@ int wpas_nan_set(struct wpa_supplicant *wpa_s, char *cmd)
 		return 0;
 	}
 
+	if (os_strcmp("bootstrap_config", cmd) == 0) {
+		u16 supported_methods, auto_accept_methods, comeback_timeout;
+
+		if (sscanf(param, "%hx,%hx,%hu", &supported_methods,
+			   &auto_accept_methods, &comeback_timeout) != 3) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Invalid value for boostrap_config");
+			return -1;
+		}
+
+		return nan_set_bootstrap_configuration(wpa_s->nan,
+						       supported_methods,
+						       auto_accept_methods,
+						       comeback_timeout);
+	}
+
 #undef NAN_PARSE
 #undef NAN_PARSE_BAND
 
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 36694b48c8..3ebba574bb 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1213,6 +1213,34 @@ void wpas_notify_nan_subscribe_terminated(struct wpa_supplicant *wpa_s,
 						  nan_reason_txt(reason));
 }
 
+
+void wpas_notify_nan_bootstrap_request(struct wpa_supplicant *wpa_s,
+				       const u8 *peer_nmi, u16 pbm)
+{
+	wpa_msg_global(wpa_s, MSG_INFO, NAN_BOOTSTRAP_REQUEST
+		       "peer_nmi=" MACSTR " pbm=0x%04x",
+		       MAC2STR(peer_nmi), pbm);
+}
+
+
+void wpas_notify_nan_bootstrap_success(struct wpa_supplicant *wpa_s,
+				       const u8 *peer_nmi, u16 pbm)
+{
+	wpa_msg_global(wpa_s, MSG_INFO, NAN_BOOTSTRAP_SUCCESS
+		       "peer_nmi=" MACSTR " pbm=0x%04x",
+		       MAC2STR(peer_nmi), pbm);
+}
+
+
+void wpas_notify_nan_bootstrap_failure(struct wpa_supplicant *wpa_s,
+				       const u8 *peer_nmi, u16 pbm,
+				       u8 reason)
+{
+	wpa_msg_global(wpa_s, MSG_INFO, NAN_BOOTSTRAP_FAILURE
+		       "peer_nmi=" MACSTR " pbm=0x%04x reason=%u",
+		       MAC2STR(peer_nmi), pbm, reason);
+}
+
 #endif /* CONFIG_NAN || CONFIG_NAN_USD */
 
 
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 79d7abd564..e51562986d 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -212,5 +212,12 @@ void wpas_notify_pr_ranging_params(struct wpa_supplicant *wpa_s,
 				   const u8 *dev_addr, const u8 *peer_addr,
 				   u8 role, u8 protocol, int freq, int channel,
 				   int bw, int format_bw);
+void wpas_notify_nan_bootstrap_request(struct wpa_supplicant *wpa_s,
+				       const u8 *peer_addr, u16 pbm);
+void wpas_notify_nan_bootstrap_success(struct wpa_supplicant *wpa_s,
+				       const u8 *peer_addr, u16 pbm);
+void wpas_notify_nan_bootstrap_failure(struct wpa_supplicant *wpa_s,
+				       const u8 *peer_addr, u16 pbm,
+				       u8 reason);
 
 #endif /* NOTIFY_H */
-- 
2.49.0




More information about the Hostap mailing list