[PATCH 13/34] PR: API to process EDCA capabilities from USD PR IE

Peddolla Harshavardhan Reddy peddolla at qti.qualcomm.com
Thu Jun 19 08:37:06 PDT 2025


Add changes to parse part of Proximity Ranging IE corresponding to the
EDCA based ranging capability attribute and store the corresponding
data in a structure. This attribute IE contains capabilities that tell
if the device can act as an EDCA based ranging initiator, EDCA based
ranging responder and list of channels on which the device supports
EDCA based ranging and other device specific capabilities.

Signed-off-by: Peddolla Harshavardhan Reddy <peddolla at qti.qualcomm.com>
---
 src/common/proximity_ranging.c | 81 ++++++++++++++++++++++++++++++++++
 src/common/proximity_ranging.h |  1 +
 2 files changed, 82 insertions(+)

diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c
index b1b93cf75..d2ad2ef98 100644
--- a/src/common/proximity_ranging.c
+++ b/src/common/proximity_ranging.c
@@ -692,6 +692,48 @@ static int pr_parse_ies(const u8 *data, size_t len, struct pr_message *msg)
 }
 
 
+static int pr_process_channels(const u8 *channel_list, size_t channel_list_len,
+			       struct pr_channels *ch)
+{
+	u8 channels;
+	const u8 *pos, *end;
+	u8 op_class_count;
+
+	pos = channel_list;
+	end = channel_list + channel_list_len;
+
+	/* Get total count of the operational classes */
+	op_class_count = pos[0];
+	wpa_printf(MSG_ERROR, "PR: Total operational classes: %u",
+		   op_class_count);
+	pos++;
+
+	ch->op_classes = 0;
+	while (end - pos > 2 && (ch->op_classes <= op_class_count)) {
+		struct pr_op_class *cl = &ch->op_class[ch->op_classes];
+
+		cl->op_class = *pos++;
+		channels = *pos++;
+		if (channels > end - pos) {
+			wpa_printf(MSG_ERROR,
+				   "PR: Invalid channel list channel %d, size: %ld",
+				   channels, end - pos);
+			return -1;
+		}
+		cl->channels = channels > PR_MAX_OP_CLASS_CHANNELS ?
+				PR_MAX_OP_CLASS_CHANNELS : channels;
+		os_memcpy(cl->channel, pos, cl->channels);
+		pos += channels;
+		ch->op_classes++;
+	}
+
+	if (ch->op_classes != op_class_count) {
+		wpa_printf(MSG_ERROR, "PR: Channel list count mismatch %lu, %d",
+			   ch->op_classes, op_class_count);
+		return -1;
+	}
+	return 0;
+}
 
 
 static void pr_process_ranging_capabilities(const u8 *caps, size_t caps_len,
@@ -738,6 +780,40 @@ static void pr_process_ranging_capabilities(const u8 *caps, size_t caps_len,
 }
 
 
+static void pr_process_edca_capabilities(const u8 *caps, size_t caps_len,
+					 struct edca_capabilities *edca_caps)
+{
+	const u8 *pos, *end;
+
+	if (!caps)
+		return;
+
+	pos = caps;
+	end = caps + caps_len;
+
+	if (*pos & PR_ISTA_SUPPORT)
+		edca_caps->ista_support = true;
+	if (*pos & PR_RSTA_SUPPORT)
+		edca_caps->rsta_support = true;
+
+	pos++;
+	edca_caps->edca_hw_caps = WPA_GET_BE16(pos);
+
+	pos += 2;
+	os_memcpy(edca_caps->country, pos, 3);
+
+	pos += 3;
+	pr_process_channels(pos, end - pos, &edca_caps->channels);
+
+	wpa_printf(MSG_INFO, "PR: EDCA ISTA support=%u, EDCA RSTA support= %u, "
+		   "op classes count=%lu, country=%c%c",
+		   edca_caps->ista_support, edca_caps->rsta_support,
+		   edca_caps->channels.op_classes,
+		   edca_caps->country[0] ? edca_caps->country[0] : '_',
+		   edca_caps->country[1] ? edca_caps->country[1] : '_');
+}
+
+
 void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
 			  const u8 *peer_addr, unsigned int freq)
 {
@@ -773,5 +849,10 @@ void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
 	pr_process_ranging_capabilities(msg.pr_capability,
 					msg.pr_capability_len, &dev->pr_caps);
 
+	if (dev->pr_caps.edca_support && msg.edca_capability)
+		pr_process_edca_capabilities(msg.edca_capability,
+					     msg.edca_capability_len,
+					     &dev->edca_caps);
+
 	pr_parse_free(&msg);
 }
diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h
index 719d3fec0..ab6c0f965 100644
--- a/src/common/proximity_ranging.h
+++ b/src/common/proximity_ranging.h
@@ -212,6 +212,7 @@ struct pr_device {
 	u8 pr_device_addr[ETH_ALEN];
 
 	struct pr_capabilities pr_caps;
+	struct edca_capabilities edca_caps;
 
 	/* Password to be used in PASN-SAE by the Seeker
 	 * This is updated with valid password if DIRA matches for the peer
-- 
2.34.1




More information about the Hostap mailing list