All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ranging: Route CS subevent results by connection and configuration
@ 2026-09-30  5:45 Cheng Jiang
  2026-09-30  8:33 ` bluez.test.bot
  2026-09-30 15:40 ` [PATCH] " patchwork-bot+bluetooth
  0 siblings, 2 replies; 3+ messages in thread
From: Cheng Jiang @ 2026-09-30  5:45 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: jinwang.li, wei.deng, xiuzhuo.shang, shuai.zhang, Cheng Jiang

bt_rap_attach_hci() allocates a state machine per device and registers the
CS subevent handlers of each one on the shared bt_hci. LE Meta subevents
are dispatched with queue_foreach() over every registered handler, so each
CS Subevent Result is delivered to all of them, not only to the device the
event belongs to.

The Subevent Result and Subevent Result Continue handlers then passed their
own sm->rap on without checking which connection reported the event, unlike
every other handler in rap_hci.c, which resolves it with
find_mapping_by_handle() and returns when the connection is not its own.
The Connection_Handle was parsed into the event and never read again, in
rap_hci.c or in shared/rap.c.

With two CS connections up, one set of ranging data was therefore consumed
by both sessions and sent out over both peers' RAS characteristics. Resolve
the mapping and drop the subevent when the connection is not tracked.

handle_local_subevent_result() and parse_cs_local_initiator_data() also
took a config_id they never checked against the tracked one, so subevents
belonging to a second CS configuration on the same connection were
appended to the procedure of the first. Ignore a subevent whose config_id
does not match the tracker, once the tracker has one.

Assisted-by: Claude:claude-opus-4.8
---
 profiles/ranging/rap_hci.c | 16 ++++++++++++++--
 src/shared/rap.c           | 22 ++++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/profiles/ranging/rap_hci.c b/profiles/ranging/rap_hci.c
index 66bc7b5eb..c472cedc9 100644
--- a/profiles/ranging/rap_hci.c
+++ b/profiles/ranging/rap_hci.c
@@ -1478,6 +1478,7 @@ static void rap_cs_subevt_result_evt(const void *data, uint8_t size,
 {
 	struct cs_state_machine *sm = (struct cs_state_machine *) user_data;
 	struct rap_ev_cs_subevent_result *rap_ev;
+	struct rap_conn_mapping *mapping;
 	struct iovec iov;
 	uint8_t cs_role;
 	uint8_t cs_rtt_type;
@@ -1563,7 +1564,12 @@ static void rap_cs_subevt_result_evt(const void *data, uint8_t size,
 			offsetof(struct rap_ev_cs_subevent_result, step_data));
 
 	DBG("CS subevent result processed: %zu bytes, ", send_len);
-	bt_rap_hci_cs_subevent_result_callback(send_len, rap_ev, sm->rap);
+	mapping = find_mapping_by_handle(sm, handle);
+	if (mapping && mapping->rap)
+		bt_rap_hci_cs_subevent_result_callback(send_len, rap_ev,
+							mapping->rap);
+	else
+		DBG("No RAP mapping for handle 0x%04X, ignoring", handle);
 	free(rap_ev);
 }
 
@@ -1572,6 +1578,7 @@ static void rap_cs_subevt_result_cont_evt(const void *data, uint8_t size,
 {
 	struct cs_state_machine *sm = (struct cs_state_machine *) user_data;
 	struct rap_ev_cs_subevent_result_cont *rap_ev;
+	struct rap_conn_mapping *mapping;
 	struct iovec iov;
 	uint8_t cs_role;
 	uint8_t cs_rtt_type;
@@ -1646,7 +1653,12 @@ static void rap_cs_subevt_result_cont_evt(const void *data, uint8_t size,
 							step_data));
 
 	DBG("CS subevent result cont processed: %zu bytes, ", send_len);
-	bt_rap_hci_cs_subevent_result_cont_callback(send_len, rap_ev, sm->rap);
+	mapping = find_mapping_by_handle(sm, handle);
+	if (mapping && mapping->rap)
+		bt_rap_hci_cs_subevent_result_cont_callback(send_len, rap_ev,
+							mapping->rap);
+	else
+		DBG("No RAP mapping for handle 0x%04X, ignoring", handle);
 	free(rap_ev);
 }
 
diff --git a/src/shared/rap.c b/src/shared/rap.c
index c0305a9e3..765ab11c2 100644
--- a/src/shared/rap.c
+++ b/src/shared/rap.c
@@ -2721,6 +2721,18 @@ static void handle_local_subevent_result(struct bt_rap *rap,
 
 	resptracker = rap->resptracker;
 
+	/* A connection can hold several CS configurations at once. Only the one
+	 * the responder tracker was set up for by CS Config Complete may feed
+	 * this procedure, otherwise subevents of a different configuration
+	 * would be appended to the same ranging data.
+	 */
+	if (resptracker->config_id != CS_INVALID_CONFIG_ID &&
+			resptracker->config_id != config_id) {
+		DBG(rap, "Ignoring subevent for config_id %u (tracking %u)",
+			config_id, resptracker->config_id);
+		return;
+	}
+
 	if (resptracker->current_proc) {
 		struct cs_procedure_data *cur = resptracker->current_proc;
 
@@ -2995,6 +3007,16 @@ static void parse_cs_local_initiator_data(struct bt_rap *rap,
 	struct cs_proc_state *state;
 	struct bcs_procedure_data *bcs;
 
+	/* Same as the responder side: only the tracked CS configuration may
+	 * contribute steps to this procedure.
+	 */
+	if (reqtracker->config_id != CS_INVALID_CONFIG_ID &&
+			reqtracker->config_id != config_id) {
+		DBG(rap, "Ignoring subevent for config_id %u (tracking %u)",
+			config_id, reqtracker->config_id);
+		return;
+	}
+
 	effective_counter = has_header_fields ? proc_counter
 					      : reqtracker->last_proc_counter;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-30 15:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-30  5:45 [PATCH] ranging: Route CS subevent results by connection and configuration Cheng Jiang
2026-09-30  8:33 ` bluez.test.bot
2026-09-30 15:40 ` [PATCH] " patchwork-bot+bluetooth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.