Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 00/11] Ranging Profile and Ranging Service PTS fixes
@ 2026-10-01 13:18 Cheng Jiang
  2026-10-01 13:18 ` [PATCH 01/11] shared/gatt-client: Allow registering notify with explicit CCC value Cheng Jiang
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: Cheng Jiang @ 2026-10-01 13:18 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: jinwang.li, wei.deng, xiuzhuo.shang, shuai.zhang, Cheng Jiang

Qualifying the existing Ranging Profile and Ranging Service code against PTS
turned up behaviour that does not match the specifications, plus procedures
that were not implemented at all. This series is what the RAP Requester and
RAS Server needed to pass, and the PTS results it records.

Most of it comes down to one thing the GATT layer could not express. RAS
picks the notification or the indication transport per characteristic, and
when a client enables both, the choice is not the same everywhere:

- Ranging Data Ready and Ranging Data Overwritten must be indicated
  (RAS 3.4.2, 3.5.2; RAS/SR/RCO/BV-08-C and BV-09-C).
- On-demand and Real-time Ranging Data must be notified
  (RAS 3.2.2, 3.2.3.1; RAS/SR/RCO/BV-05..07-C and RAS/SR/RRD/BV-03-C).

gatt_db_attribute_notify() prefers notifications whenever the client enabled
them, so a server cannot honour the first rule, and
bt_gatt_client_register_notify() derives the CCC value from the
characteristic properties, so a requester cannot ask for one transport
specifically. Patches 1 and 2 add an entry point for each case, leaving
gatt_db_notify_t and every existing caller of both functions untouched.

Patches 3 to 6 apply that on the responder and fill in what the RAS Server
cases exercise: the transport of every notified characteristic now follows
the peer's CCCD, Abort Operation is implemented and advertised in RAS
Features, the requester's Control Point watchdog uses the 5 seconds
RAP 4.5.4.1 specifies, and Real-time Ranging Data is queued so segments are
not dropped when a procedure completes before they are all sent.

Segmented ranging data was also queued a whole transfer at a time, which
starves incoming ATT operations: notifications land on the att write queue,
which pick_next_send_op() drains ahead of the request queue and with no flow
control of its own. It now goes out a segment at a time, gated on
confirmations for indications and on a short delay otherwise, so an Abort
Operation stops a transfer the peer no longer wants instead of having to
wait for it to drain. A real flow control for the notification path, driven
by how much the att write queue has left to send, would be better than that
delay and is left for later.

Patches 7 to 9 add the requester side the RAP cases need: an API to select
Real-time or On-demand reception together with the transport to configure on
the peer, exposed as org.bluez.ChannelSounding1.SetRangingDataMode() and as
a bluetoothctl ranging-data-mode command.

Patches 10 and 11 document the new method and command, and record the
results: 19 RAP and 31 RAS cases pass with PTS 8.14.0.4, run against PTS
pre-generated ranging data (TSPX_test_method), since the PTS dongle in use
does not support Channel Sounding. That covers the RAS protocol behaviour
above but not the HCI Channel Sounding entry path. RAS/SR/SPE/BI-02-C is
listed as not applicable, since RAS.TS Table 5.1 selects it only when Abort
Operation is unsupported and the IUT supports it.

Each patch builds on its own, and unit/test-rap, test-bap, test-bass,
test-mcp, test-micp, test-vcp and test-gatt pass on every one of them.

Cheng Jiang (11):
  shared/gatt-client: Allow registering notify with explicit CCC value
  shared/gatt-db: Add gatt_db_attribute_indicate()
  shared/rap: Honor CCCD transport for RAS on-demand ranging data
  shared/rap: Add RAS Control Point Abort Operation
  shared/rap: Shorten the requester Control Point response timeout
  shared/rap: Add real-time ranging data delivery on the responder
  shared/rap: Add requester ranging data subscription API
  profiles/ranging: Expose requester ranging data mode over D-Bus
  client: Add Channel Sounding ranging data mode control
  doc: Document Channel Sounding ranging data mode control
  doc/qualification: Add RAP/RAS PTS qualification results

 client/cs.c                        |  82 +++
 doc/bluetoothctl-cs.rst            |  24 +
 doc/org.bluez.ChannelSounding1.rst |  32 ++
 doc/qualification/rap-pts.rst      | 180 +++++++
 doc/qualification/ras-pts.rst      | 135 +++++
 profiles/ranging/rap.c             |  34 ++
 src/gatt-database.c                |   7 +-
 src/shared/gatt-client.c           |  41 +-
 src/shared/gatt-client.h           |   7 +
 src/shared/gatt-db.c               |  35 +-
 src/shared/gatt-db.h               |  17 +
 src/shared/rap.c                   | 824 ++++++++++++++++++++++++-----
 src/shared/rap.h                   |  21 +
 unit/test-rap.c                    |  19 +-
 14 files changed, 1319 insertions(+), 139 deletions(-)
 create mode 100644 doc/qualification/rap-pts.rst
 create mode 100644 doc/qualification/ras-pts.rst

-- 
2.43.0


^ permalink raw reply	[flat|nested] 16+ messages in thread
* [PATCH v2 01/14] shared/gatt-client: Allow registering notify with explicit CCC value
@ 2026-10-09  9:25 Cheng Jiang
  2026-10-09 15:42 ` Ranging Profile and Ranging Service PTS fixes bluez.test.bot
  0 siblings, 1 reply; 16+ messages in thread
From: Cheng Jiang @ 2026-10-09  9:25 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: jinwang.li, wei.deng, xiuzhuo.shang, shuai.zhang, Cheng Jiang

bt_gatt_client_register_notify() picks the CCC value to write based on
the characteristic properties, preferring notifications over indications
when both are supported. A client that specifically needs one of the two
- for example the Ranging Service, which distinguishes notification and
indication transports - has no way to request it.

Add bt_gatt_client_register_notify_with_ccc() which takes the desired
CCC value (0x0001 for notifications, 0x0002 for indications) and writes
it verbatim. register_notify() gains a ccc_value argument and rejects a
value the characteristic does not support. The existing entry point
keeps its behaviour by passing 0, which restores the property-based
selection.

Assisted-by: Claude:claude-opus-4.8
---
 src/shared/gatt-client.c | 43 +++++++++++++++++++++++++++++++++++-----
 src/shared/gatt-client.h |  7 +++++++
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 95f83fa3e..5c29587bb 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -242,6 +242,7 @@ struct notify_data {
 	uint8_t att_ecode;
 	int ref_count;
 	struct notify_chrc *chrc;
+	uint16_t ccc_value;
 	bt_gatt_client_register_callback_t callback;
 	bt_gatt_client_notify_callback_t notify;
 	void *user_data;
@@ -1680,10 +1681,9 @@ static bool notify_data_write_ccc(struct notify_data *notify_data, bool enable,
 	assert(notify_data->chrc->ccc_handle);
 
 	if (enable) {
-		/* Try to enable notifications or indications based on
-		 * whatever the characteristic supports.
-		 */
-		if (properties & BT_GATT_CHRC_PROP_NOTIFY)
+		if (notify_data->ccc_value)
+			value = cpu_to_le16(notify_data->ccc_value);
+		else if (properties & BT_GATT_CHRC_PROP_NOTIFY)
 			value = cpu_to_le16(0x0001);
 		else if (properties & BT_GATT_CHRC_PROP_INDICATE)
 			value = cpu_to_le16(0x0002);
@@ -1759,6 +1759,7 @@ static bool match_notify_chrc_value_handle(const void *a, const void *b)
 
 static unsigned int register_notify(struct bt_gatt_client *client,
 				uint16_t handle,
+				uint16_t ccc_value,
 				bt_gatt_client_register_callback_t callback,
 				bt_gatt_client_notify_callback_t notify,
 				void *user_data,
@@ -1788,10 +1789,22 @@ static unsigned int register_notify(struct bt_gatt_client *client,
 	if (chrc->notify_count == INT_MAX)
 		return 0;
 
+	if (ccc_value == 0x0001 &&
+			!(chrc->properties & BT_GATT_CHRC_PROP_NOTIFY))
+		return 0;
+
+	if (ccc_value == 0x0002 &&
+			!(chrc->properties & BT_GATT_CHRC_PROP_INDICATE))
+		return 0;
+
+	if (ccc_value != 0 && ccc_value != 0x0001 && ccc_value != 0x0002)
+		return 0;
+
 	notify_data = new0(struct notify_data, 1);
 	notify_data->client = client;
 	notify_data->ref_count = 1;
 	notify_data->chrc = chrc;
+	notify_data->ccc_value = ccc_value;
 	notify_data->callback = callback;
 	notify_data->notify = notify;
 	notify_data->user_data = user_data;
@@ -1881,6 +1894,7 @@ static bool register_service_changed(struct bt_gatt_client *client)
 	 */
 	client->svc_chngd_ind_id = register_notify(client,
 					gatt_db_attribute_get_handle(attr),
+					0x0002,
 					service_changed_register_cb,
 					service_changed_cb,
 					client, NULL);
@@ -3852,10 +3866,29 @@ unsigned int bt_gatt_client_register_notify(struct bt_gatt_client *client,
 	if (client->in_svc_chngd)
 		return 0;
 
-	return register_notify(client, chrc_value_handle, callback, notify,
+	return register_notify(client, chrc_value_handle, 0, callback, notify,
 							user_data, destroy);
 }
 
+unsigned int bt_gatt_client_register_notify_with_ccc(
+				struct bt_gatt_client *client,
+				uint16_t chrc_value_handle, uint16_t ccc_value,
+				bt_gatt_client_register_callback_t callback,
+				bt_gatt_client_notify_callback_t notify,
+				void *user_data,
+				bt_gatt_client_destroy_func_t destroy)
+{
+	if (!client || !client->db || !chrc_value_handle ||
+			(!callback && !notify) || !ccc_value)
+		return 0;
+
+	if (client->in_svc_chngd)
+		return 0;
+
+	return register_notify(client, chrc_value_handle, ccc_value, callback,
+						notify, user_data, destroy);
+}
+
 bool bt_gatt_client_unregister_notify(struct bt_gatt_client *client,
 							unsigned int id)
 {
diff --git a/src/shared/gatt-client.h b/src/shared/gatt-client.h
index ff90fd8ea..0c5d118c7 100644
--- a/src/shared/gatt-client.h
+++ b/src/shared/gatt-client.h
@@ -123,6 +123,13 @@ unsigned int bt_gatt_client_register_notify(struct bt_gatt_client *client,
 				bt_gatt_client_notify_callback_t notify,
 				void *user_data,
 				bt_gatt_client_destroy_func_t destroy);
+unsigned int bt_gatt_client_register_notify_with_ccc(
+				struct bt_gatt_client *client,
+				uint16_t chrc_value_handle, uint16_t ccc_value,
+				bt_gatt_client_register_callback_t callback,
+				bt_gatt_client_notify_callback_t notify,
+				void *user_data,
+				bt_gatt_client_destroy_func_t destroy);
 bool bt_gatt_client_unregister_notify(struct bt_gatt_client *client,
 							unsigned int id);
 
-- 
2.43.0


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

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

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 04/11] shared/rap: Add RAS Control Point Abort Operation Cheng Jiang
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
  -- strict thread matches above, loose matches on Subject: below --
2026-10-09  9:25 [PATCH v2 01/14] shared/gatt-client: Allow registering notify with explicit CCC value Cheng Jiang
2026-10-09 15:42 ` Ranging Profile and Ranging Service PTS fixes bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox