Linux bluetooth development
 help / color / mirror / Atom feed
From: Cheng Jiang <cheng.jiang@oss.qualcomm.com>
To: linux-bluetooth@vger.kernel.org
Cc: jinwang.li@oss.qualcomm.com, wei.deng@oss.qualcomm.com,
	xiuzhuo.shang@oss.qualcomm.com, shuai.zhang@oss.qualcomm.com,
	Cheng Jiang <cheng.jiang@oss.qualcomm.com>
Subject: [PATCH 04/11] shared/rap: Add RAS Control Point Abort Operation
Date: Thu,  1 Oct 2026 21:18:50 +0800	[thread overview]
Message-ID: <20261001131900.707485-5-cheng.jiang@oss.qualcomm.com> (raw)
In-Reply-To: <20261001131900.707485-1-cheng.jiang@oss.qualcomm.com>

Implement the Abort_Operation procedure (Op Code 0x03) so a client can
cancel an On-demand Ranging Data transfer that is already in progress,
and advertise it through bit 2 of the RAS Features characteristic.

Abort clears the sending state and removes the pending segment timer.
Since the transfer keeps at most one segment outstanding, dropping that
timer stops the transfer instead of letting a queued backlog drain out.
The Control Point busy check lets Abort through while every other Op Code
is answered with Server Busy, so an abort is accepted mid-transfer.

On the requester side, an Abort is written when a Get_Ranging_Data
request times out and the peer advertises Abort support, so the responder
does not keep sending data for a request the requester gave up on.

The unit test Features value changes to 0x05 accordingly.

Assisted-by: Claude:claude-opus-4.8
---
 src/shared/rap.c | 35 ++++++++++++++++++++++++++++++-----
 unit/test-rap.c  |  6 +++---
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/shared/rap.c b/src/shared/rap.c
index a794de044..b45bfc9e6 100644
--- a/src/shared/rap.c
+++ b/src/shared/rap.c
@@ -312,8 +312,8 @@ struct cstracker {
 enum ras_cp_opcode {
 	RAS_CP_OP_GET_RANGING_DATA = 0x00,
 	RAS_CP_OP_ACK_RANGING_DATA = 0x01,
+	RAS_CP_OP_ABORT_OPERATION = 0x03,
 	/* 0x02 Retrieve_Lost_Ranging_Data_Segments,
-	 * 0x03 Abort_Operation,
 	 * 0x04 Set_Filter - optional, not implemented
 	 */
 };
@@ -366,6 +366,7 @@ struct ras_ondemand_client {
 	 * peer never sends a Control Point response.
 	 */
 	unsigned int        cp_timeout_id;
+	bool                abort_operation;
 };
 
 /* Ranging Service context */
@@ -1196,7 +1197,7 @@ static void ras_features_read_cb(struct gatt_db_attribute *attrib,
 {
 	struct ras *ras = user_data;
 	/* Real-time ranging and Abort Operation are supported. */
-	uint8_t value[4] = { 0x01, 0x00, 0x00, 0x00 };
+	uint8_t value[4] = { 0x05, 0x00, 0x00, 0x00 };
 
 	if (ras)
 		bt_rap_get_session(att, ras->rapdb->db);
@@ -1244,7 +1245,7 @@ static void ras_control_point_write_cb(struct gatt_db_attribute *attrib,
 		return;
 	}
 
-	if (rap->cache.sending) {
+	if (rap->cache.sending && value[0] != RAS_CP_OP_ABORT_OPERATION) {
 		ras_cp_send_response_code(rap, ras, RAS_CP_RSP_CODE_SERVER_BUSY);
 		goto done;
 	}
@@ -1269,6 +1270,22 @@ static void ras_control_point_write_cb(struct gatt_db_attribute *attrib,
 
 		send_ondemand_segment_data(rap, ras);
 		break;
+	case RAS_CP_OP_ABORT_OPERATION:
+		if (len != 1) {
+			ras_cp_send_response_code(rap, ras,
+					RAS_CP_RSP_CODE_INVALID_PARAMETER);
+			break;
+		}
+
+		if (rap->cache.sending) {
+			if (rap->cache.send_id)
+				timeout_remove(rap->cache.send_id);
+			rap->cache.send_id = 0;
+			rap->cache.sending = false;
+		}
+
+		ras_cp_send_response_code(rap, ras, RAS_CP_RSP_CODE_SUCCESS);
+		break;
 	case RAS_CP_OP_ACK_RANGING_DATA:
 		if (len != 3) {
 			ras_cp_send_response_code(rap, ras,
@@ -3352,6 +3369,10 @@ static bool ras_cp_timeout_cb(void *user_data)
 		 * on it.
 		 */
 		ras->client.cp_timeout_id = 0;
+		if (ras->client.pending_op == RAS_CP_PENDING_GET &&
+				ras->client.abort_operation)
+			ras_cp_write_op(rap, ras, RAS_CP_OP_ABORT_OPERATION,
+					ras->client.pending_counter);
 		ras_ondemand_client_reset(ras);
 	}
 
@@ -3397,8 +3418,10 @@ static bool ras_cp_write_op(struct bt_rap *rap, struct ras *ras,
 		return false;
 
 	value[0] = opcode;
-	put_le16(counter, value + 1);
-	length = sizeof(value);
+	if (opcode != RAS_CP_OP_ABORT_OPERATION) {
+		put_le16(counter, value + 1);
+		length = sizeof(value);
+	}
 
 	return bt_gatt_client_write_without_response(rap->client,
 					value_handle, false,
@@ -4265,6 +4288,8 @@ static void read_ras_features(struct bt_rap *rap, bool success,
 	supports_realtime = (features & 0x01) != 0;
 	retrieve_lost = (features & 0x02) != 0;
 	abort_operation = (features & 0x04) != 0;
+	if (ras)
+		ras->client.abort_operation = abort_operation;
 
 	DBG(rap, "RAS Features - Real-time: %s, Retrieve Lost: %s, Abort: %s",
 	    supports_realtime ? "Yes" : "No",
diff --git a/unit/test-rap.c b/unit/test-rap.c
index 5c6033a4e..349d06840 100644
--- a/unit/test-rap.c
+++ b/unit/test-rap.c
@@ -802,11 +802,11 @@ const struct test_config_rap cfg_cggit_discovery = {
  *       Handle: 0x0003 (RAS Features value handle)
  *
  *  ATT: Read Response (0x0b) len 5
- *       Value: 0x01 0x00 0x00 0x00
+ *       Value: 0x05 0x00 0x00 0x00
  *       Feature bits:
  *         Bit 0: Real-time ranging (1 = supported)
  *         Bit 1: Retrieve stored results (0 = not supported)
- *         Bit 2: Abort operation (0 = not supported)
+ *         Bit 2: Abort operation (1 = supported)
  *
  *  Note: The RAS Features characteristic is registered with
  *  BT_ATT_PERM_READ | BT_ATT_PERM_READ_ENCRYPT. Since the test sets
@@ -817,7 +817,7 @@ const struct test_config_rap cfg_cggit_discovery = {
 
 #define ATT_READ_RAS_FEATURES \
 	IOV_DATA(0x0a, 0x03, 0x00), \
-	IOV_DATA(0x0b, 0x01, 0x00, 0x00, 0x00)
+	IOV_DATA(0x0b, 0x05, 0x00, 0x00, 0x00)
 
 #define RAS_SR_RCO_BV_01_C \
 	ATT_EXCHANGE_MTU, \
-- 
2.43.0


  parent reply	other threads:[~2026-10-01 13:19 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01 13:18 [PATCH 00/11] Ranging Profile and Ranging Service PTS fixes Cheng Jiang
2026-10-01 13:18 ` [PATCH 01/11] shared/gatt-client: Allow registering notify with explicit CCC value Cheng Jiang
2026-10-01 16:03   ` Ranging Profile and Ranging Service PTS fixes bluez.test.bot
2026-10-01 13:18 ` [PATCH 02/11] shared/gatt-db: Add gatt_db_attribute_indicate() Cheng Jiang
2026-10-01 15:48   ` Luiz Augusto von Dentz
2026-10-09  8:45     ` Cheng Jiang
2026-10-01 13:18 ` [PATCH 03/11] shared/rap: Honor CCCD transport for RAS on-demand ranging data Cheng Jiang
2026-10-01 13:18 ` Cheng Jiang [this message]
2026-10-01 13:18 ` [PATCH 05/11] shared/rap: Shorten the requester Control Point response timeout Cheng Jiang
2026-10-01 13:18 ` [PATCH 06/11] shared/rap: Add real-time ranging data delivery on the responder Cheng Jiang
2026-10-01 13:18 ` [PATCH 07/11] shared/rap: Add requester ranging data subscription API Cheng Jiang
2026-10-01 13:18 ` [PATCH 08/11] profiles/ranging: Expose requester ranging data mode over D-Bus Cheng Jiang
2026-10-01 13:18 ` [PATCH 09/11] client: Add Channel Sounding ranging data mode control Cheng Jiang
2026-10-01 13:18 ` [PATCH 10/11] doc: Document " Cheng Jiang
2026-10-01 13:18 ` [PATCH 11/11] doc/qualification: Add RAP/RAS PTS qualification results Cheng Jiang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261001131900.707485-5-cheng.jiang@oss.qualcomm.com \
    --to=cheng.jiang@oss.qualcomm.com \
    --cc=jinwang.li@oss.qualcomm.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=shuai.zhang@oss.qualcomm.com \
    --cc=wei.deng@oss.qualcomm.com \
    --cc=xiuzhuo.shang@oss.qualcomm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox