@@ -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");
@@ -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);
@@ -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);
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@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(-)