* [PATCH BlueZ v2] src/shared: add custom CCC callbacks
@ 2026-04-24 4:28 Prathibha Madugonde
2026-04-24 6:22 ` [BlueZ,v2] " bluez.test.bot
2026-04-24 15:00 ` [PATCH BlueZ v2] " patchwork-bot+bluetooth
0 siblings, 2 replies; 3+ messages in thread
From: Prathibha Madugonde @ 2026-04-24 4:28 UTC (permalink / raw)
To: linux-bluetooth; +Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg
From: Prathibha Madugonde <prathibha.madugonde@oss.qualcomm.com>
Introduce custom CCC callbacks to allow interception of
client notification subscription changes. This enables
stack-level handling of CCC writes.
---
src/shared/gatt-db.c | 119 ++++++++++++++++++++++++++++++++++++++++++-
src/shared/gatt-db.h | 4 ++
2 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index d0e149d6f..87cc61cf3 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -1214,6 +1214,112 @@ gatt_db_service_add_ccc(struct gatt_db_attribute *attrib, uint32_t permissions)
return ccc;
}
+static void ccc_custom_read(struct gatt_db_attribute *attrib,
+ unsigned int id, uint16_t offset,
+ uint8_t opcode, struct bt_att *att,
+ void *user_data)
+{
+ struct gatt_db *db = attrib->service->db;
+
+ db->ccc->read_func(attrib, id, offset, opcode, att, db->ccc->user_data);
+}
+
+static void custom_write_result(struct gatt_db_attribute *attr, int err,
+ void *user_data)
+{
+ int *result = user_data;
+
+ *result = err;
+}
+
+static void ccc_custom_write(struct gatt_db_attribute *attrib,
+ unsigned int id, uint16_t offset,
+ const uint8_t *value, size_t len,
+ uint8_t opcode, struct bt_att *att,
+ void *user_data)
+{
+ struct gatt_db_ccc *data = user_data;
+ struct gatt_db *db = attrib->service->db;
+ struct pending_write *p;
+ int err = 0;
+
+ /* Create another pending write to handle results from custom write
+ * function.
+ */
+ p = new0(struct pending_write, 1);
+ p->attrib = attrib;
+ p->id = ++attrib->write_id;
+ p->func = custom_write_result;
+ p->user_data = &err;
+
+ queue_push_tail(attrib->pending_writes, p);
+
+ /* Call custom write function first */
+ data->write_func(attrib, p->id, offset, value, len, opcode, att,
+ data->user_data);
+
+ if (err) {
+ gatt_db_attribute_write_result(attrib, id, err);
+ return;
+ }
+
+ /* If custom write function did not return error proceed to call the
+ * default CCC write function.
+ */
+ db->ccc->write_func(attrib, id, offset, value, len, opcode, att,
+ db->ccc->user_data);
+}
+
+struct gatt_db_attribute *
+gatt_db_service_add_ccc_custom(struct gatt_db_attribute *attrib,
+ uint32_t permissions,
+ gatt_db_write_t write_func, void *user_data)
+{
+ struct gatt_db *db;
+ struct gatt_db_attribute *ccc;
+ struct gatt_db_attribute *value;
+ uint16_t handle = 0;
+ struct gatt_db_ccc *data;
+
+ if (!attrib || !permissions)
+ return NULL;
+
+ db = attrib->service->db;
+
+ if (!db->ccc)
+ return NULL;
+
+ /* Locate value handle */
+ gatt_db_service_foreach_char(attrib, find_ccc_value, &handle);
+
+ if (!handle)
+ return NULL;
+
+ value = gatt_db_get_attribute(db, handle);
+ if (!value || value->notify_func)
+ return NULL;
+
+ data = new0(struct gatt_db_ccc, 1);
+ data->write_func = write_func;
+ data->user_data = user_data;
+
+ ccc = service_insert_descriptor(attrib->service, 0, &ccc_uuid,
+ permissions,
+ ccc_custom_read,
+ ccc_custom_write,
+ data);
+ if (!ccc) {
+ free(data);
+ return NULL;
+ }
+
+ gatt_db_attribute_set_fixed_length(ccc, 2);
+ ccc->notify_func = db->ccc->notify_func;
+ value->notify_func = db->ccc->notify_func;
+
+ return ccc;
+}
+
void gatt_db_ccc_register(struct gatt_db *db, gatt_db_read_t read_func,
gatt_db_write_t write_func,
gatt_db_notify_t notify_func,
@@ -2338,6 +2444,8 @@ bool gatt_db_attribute_notify(struct gatt_db_attribute *attrib,
struct bt_att *att)
{
struct gatt_db_attribute *ccc;
+ struct gatt_db *db;
+ void *notify_user_data;
if (!attrib || !attrib->notify_func)
return false;
@@ -2350,7 +2458,16 @@ bool gatt_db_attribute_notify(struct gatt_db_attribute *attrib,
if (!ccc)
return false;
- attrib->notify_func(attrib, ccc, value, len, att, ccc->user_data);
+ /* For custom CCC descriptors, use the database user_data for
+ * notify_func. For regular CCC descriptors, use the CCC's user_data.
+ */
+ db = attrib->service->db;
+ if (ccc->write_func == ccc_custom_write && db && db->ccc)
+ notify_user_data = db->ccc->user_data;
+ else
+ notify_user_data = ccc->user_data;
+
+ attrib->notify_func(attrib, ccc, value, len, att, notify_user_data);
return true;
}
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index dc2daf7fc..da0600c01 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -112,6 +112,10 @@ gatt_db_service_insert_descriptor(struct gatt_db_attribute *attrib,
struct gatt_db_attribute *
gatt_db_service_add_ccc(struct gatt_db_attribute *attrib, uint32_t permissions);
+struct gatt_db_attribute *
+gatt_db_service_add_ccc_custom(struct gatt_db_attribute *attrib,
+ uint32_t permissions,
+ gatt_db_write_t write_func, void *user_data);
struct gatt_db_attribute *
gatt_db_insert_included(struct gatt_db *db, uint16_t handle,
struct gatt_db_attribute *include);
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* RE: [BlueZ,v2] src/shared: add custom CCC callbacks
2026-04-24 4:28 [PATCH BlueZ v2] src/shared: add custom CCC callbacks Prathibha Madugonde
@ 2026-04-24 6:22 ` bluez.test.bot
2026-04-24 15:00 ` [PATCH BlueZ v2] " patchwork-bot+bluetooth
1 sibling, 0 replies; 3+ messages in thread
From: bluez.test.bot @ 2026-04-24 6:22 UTC (permalink / raw)
To: linux-bluetooth, prathibha.madugonde
[-- Attachment #1: Type: text/plain, Size: 989 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1085008
---Test result---
Test Summary:
CheckPatch PASS 0.48 seconds
GitLint PASS 0.28 seconds
BuildEll PASS 20.67 seconds
BluezMake PASS 648.34 seconds
MakeCheck PASS 1.02 seconds
MakeDistcheck PASS 249.68 seconds
CheckValgrind PASS 225.71 seconds
CheckSmatch PASS 352.21 seconds
bluezmakeextell PASS 183.36 seconds
IncrementalBuild PASS 640.32 seconds
ScanBuild PASS 1032.72 seconds
https://github.com/bluez/bluez/pull/2068
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH BlueZ v2] src/shared: add custom CCC callbacks
2026-04-24 4:28 [PATCH BlueZ v2] src/shared: add custom CCC callbacks Prathibha Madugonde
2026-04-24 6:22 ` [BlueZ,v2] " bluez.test.bot
@ 2026-04-24 15:00 ` patchwork-bot+bluetooth
1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+bluetooth @ 2026-04-24 15:00 UTC (permalink / raw)
To: Prathibha Madugonde
Cc: linux-bluetooth, luiz.dentz, quic_mohamull, quic_hbandi,
quic_anubhavg
Hello:
This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Fri, 24 Apr 2026 09:58:30 +0530 you wrote:
> From: Prathibha Madugonde <prathibha.madugonde@oss.qualcomm.com>
>
> Introduce custom CCC callbacks to allow interception of
> client notification subscription changes. This enables
> stack-level handling of CCC writes.
> ---
> src/shared/gatt-db.c | 119 ++++++++++++++++++++++++++++++++++++++++++-
> src/shared/gatt-db.h | 4 ++
> 2 files changed, 122 insertions(+), 1 deletion(-)
Here is the summary with links:
- [BlueZ,v2] src/shared: add custom CCC callbacks
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=83ddf46ccc06
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-04-24 15:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-24 4:28 [PATCH BlueZ v2] src/shared: add custom CCC callbacks Prathibha Madugonde
2026-04-24 6:22 ` [BlueZ,v2] " bluez.test.bot
2026-04-24 15:00 ` [PATCH BlueZ v2] " patchwork-bot+bluetooth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox