All of lore.kernel.org
 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 01/11] shared/gatt-client: Allow registering notify with explicit CCC value
Date: Thu,  1 Oct 2026 21:18:47 +0800	[thread overview]
Message-ID: <20261001131900.707485-2-cheng.jiang@oss.qualcomm.com> (raw)
In-Reply-To: <20261001131900.707485-1-cheng.jiang@oss.qualcomm.com>

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 | 41 +++++++++++++++++++++++++++++++++++-----
 src/shared/gatt-client.h |  7 +++++++
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 92ad7c39c..1cf361f50 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -232,6 +232,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;
@@ -1670,10 +1671,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);
@@ -1749,6 +1749,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,
@@ -1778,10 +1779,20 @@ 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;
@@ -1871,6 +1882,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);
@@ -3834,10 +3846,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 63cf99500..1b19c885b 100644
--- a/src/shared/gatt-client.h
+++ b/src/shared/gatt-client.h
@@ -122,6 +122,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


  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 ` Cheng Jiang [this message]
2026-10-01 16:03   ` 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

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-2-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 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.