[PATCH v3 42/46] PR: Track peer discovery type and handle OOB peers in PASN initiation

Kavita Kavita kavita.kavita at oss.qualcomm.com
Wed May 13 03:00:06 PDT 2026


Add discovery_type to struct pr_device to distinguish peers discovered
via NAN USD from peers added out-of-band. Mark peers as NAN-discovered
when found via USD and as OOB when added without prior NAN discovery.

When PR_PASN_START is issued for a peer that is not in the discovery
list, create a minimal OOB peer entry so that PASN can proceed without
requiring prior NAN USD discovery. This is done at PR_PASN_START time
for both initiator and responder roles.

For OOB peers, skip capability comparison and PASN parameter validation
since their capabilities are not known. Per spec, all PR devices must
support unauthenticated DH group 19, so cipher and group selection
defaults to the mandatory baseline.

Signed-off-by: Kavita Kavita <kavita.kavita at oss.qualcomm.com>
---
 src/common/proximity_ranging.c | 52 +++++++++++++++++++++++++++++++---
 src/common/proximity_ranging.h |  6 ++++
 wpa_supplicant/pr_supplicant.c |  6 +++-
 3 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c
index d728e0030..2624b8d97 100644
--- a/src/common/proximity_ranging.c
+++ b/src/common/proximity_ranging.c
@@ -1140,6 +1140,7 @@ void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
 
 	os_get_reltime(&dev->last_seen);
 	dev->listen_freq = freq;
+	dev->discovery_type = PR_DISCOVERY_TYPE_USD;
 
 	pr_process_ranging_capabilities(msg.pr_capability,
 					msg.pr_capability_len, &dev->pr_caps);
@@ -1162,11 +1163,45 @@ void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
 }
 
 
+/**
+ * pr_ensure_oob_peer - Add a minimal OOB peer entry if not already present
+ */
+int pr_ensure_oob_peer(struct pr_data *pr, const u8 *addr, int freq)
+{
+	struct pr_device *dev;
+
+	if (!pr || !addr)
+		return -1;
+
+	dev = pr_get_device(pr, addr);
+	if (dev)
+		return 0;
+
+	dev = pr_create_device(pr, addr);
+	if (!dev) {
+		wpa_printf(MSG_DEBUG, "PR: Failed to create OOB peer " MACSTR,
+			   MAC2STR(addr));
+		return -1;
+	}
+
+	dev->discovery_type = PR_DISCOVERY_TYPE_OOB;
+	if (freq)
+		dev->listen_freq = freq;
+
+	wpa_printf(MSG_DEBUG, "PR: OOB peer " MACSTR " created at PASN_START",
+		   MAC2STR(addr));
+	return 0;
+}
+
+
 #ifdef CONFIG_PASN
 
 static bool pr_eq_ranging_capa_params(const struct pr_device *dev,
 				     const struct pr_capabilities *caps)
 {
+	if (dev->discovery_type == PR_DISCOVERY_TYPE_OOB)
+		return true;
+
 	return dev->pr_caps.edca_support == caps->edca_support &&
 		dev->pr_caps.ntb_support == caps->ntb_support &&
 		dev->pr_caps.pasn_type == caps->pasn_type &&
@@ -1179,6 +1214,9 @@ static bool pr_eq_ranging_capa_params(const struct pr_device *dev,
 static bool pr_eq_edca_params(const struct pr_device *dev,
 			      const struct edca_capabilities *edca_caps)
 {
+	if (dev->discovery_type == PR_DISCOVERY_TYPE_OOB)
+		return true;
+
 	return dev->edca_caps.ista_support == edca_caps->ista_support &&
 		dev->edca_caps.rsta_support == edca_caps->rsta_support &&
 		dev->edca_caps.edca_hw_caps == edca_caps->edca_hw_caps &&
@@ -1189,6 +1227,9 @@ static bool pr_eq_edca_params(const struct pr_device *dev,
 static bool pr_eq_ntb_params(const struct pr_device *dev,
 			     const struct ntb_capabilities *ntb_caps)
 {
+	if (dev->discovery_type == PR_DISCOVERY_TYPE_OOB)
+		return true;
+
 	return dev->ntb_caps.ista_support == ntb_caps->ista_support &&
 		dev->ntb_caps.rsta_support == ntb_caps->rsta_support &&
 		dev->ntb_caps.ntb_hw_caps == ntb_caps->ntb_hw_caps &&
@@ -1717,9 +1758,11 @@ static int pr_pasn_initialize(struct pr_data *pr, struct pr_device *dev,
 
 	/* As specified in Proximity Ranging Implementation Considerations for
 	 * P2P Operation D1.8, unauthenticated mode PASN with DH group 19
-	 * should be supported by all P2P proximity ranging devices. */
-	if (!(pr->cfg->pasn_type & BIT(0)) ||
-	    !(dev->pr_caps.pasn_type & BIT(0))) {
+	 * should be supported by all P2P proximity ranging devices. Skip
+	 * this check for OOB peers whose capabilities are not known. */
+	if (dev->discovery_type != PR_DISCOVERY_TYPE_OOB &&
+	    (!(pr->cfg->pasn_type & BIT(0)) ||
+	     !(dev->pr_caps.pasn_type & BIT(0)))) {
 		wpa_printf(MSG_DEBUG,
 			   "PR PASN: Unauthenticated DH group 19 NOT supported, PASN type of self 0x%x, peer 0x%x",
 			   pr->cfg->pasn_type, dev->pr_caps.pasn_type);
@@ -1927,7 +1970,8 @@ int pr_initiate_pasn_auth(struct pr_data *pr, const u8 *addr, int freq,
 		return -1;
 	}
 
-	if (pr_validate_pasn_request(pr, dev, auth_mode, ranging_role,
+	if (dev->discovery_type != PR_DISCOVERY_TYPE_OOB &&
+	    pr_validate_pasn_request(pr, dev, auth_mode, ranging_role,
 				     ranging_type) < 0) {
 		wpa_printf(MSG_INFO,
 			   "PR PASN: Invalid parameters to initiate authentication");
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index 52a9620ec..908827c83 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -258,6 +258,10 @@ enum pr_attr_id {
 #define PR_PASN_AUTH_MODE_SAE    1
 #define PR_PASN_AUTH_MODE_PMK    2
 
+/* Peer discovery type */
+#define PR_DISCOVERY_TYPE_USD    0
+#define PR_DISCOVERY_TYPE_OOB    1
+
 /**
  * struct pr_pasn_ranging_params - peer parameters to be used in PASN
  * then to trigger ranging in case where PR PASN is successful.
@@ -410,6 +414,7 @@ struct pr_device {
 	u8 protocol_type;
 	u8 final_op_class;
 	u8 final_op_channel;
+	u8 discovery_type;
 };
 
 
@@ -637,6 +642,7 @@ void pr_add_dev_ik(struct pr_data *pr, const u8 *dik, const char *password,
 struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr);
 void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
 			  const u8 *peer_addr, unsigned int freq);
+int pr_ensure_oob_peer(struct pr_data *pr, const u8 *addr, int freq);
 int pr_initiate_pasn_auth(struct pr_data *pr, const u8 *addr, int freq,
 			  u8 auth_mode, u8 ranging_role, u8 ranging_type,
 			  int forced_pr_freq);
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index f37d1915e..7f0061c0c 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -1261,10 +1261,14 @@ int wpas_pr_initiate_pasn_auth(struct wpa_supplicant *wpa_s,
 			       enum pr_pasn_role pasn_role)
 {
 	struct wpa_pr_pasn_auth_work *awork;
+	struct pr_data *pr = wpa_s->global->pr;
+
+	/* Add OOB peer if not already in the discovery list */
+	if (pr && pr_ensure_oob_peer(pr, peer_addr, freq) < 0)
+		return -1;
 
 	if (pasn_role == PR_ROLE_PASN_RESPONDER) {
 		struct wpa_pr_pasn_roc_work *rwork;
-		struct pr_data *pr = wpa_s->global->pr;
 		unsigned int roc_time_ms = PR_PASN_RESPONDER_ROC_DURATION;
 		bool has_src_addr = src_addr && !is_zero_ether_addr(src_addr);
 
-- 
2.34.1




More information about the Hostap mailing list