There is a timing issue to update DB Hash value. The gatt_client_service_changed() callback in src/device.c is called from service_changed_complete() in gatt-client.c, which is invoked after db_hash_read_cb() has already updated the hash. Adding store_gatt_db(device) here guarantees the db is persisted with the correct, up-to-date hash for both the addition and removal cases.
Upstream-Status: Backport [bluez/bluez@0fd01e9] Signed-off-by: Mengshi Wu <[email protected]> --- meta/recipes-connectivity/bluez5/bluez5.inc | 1 + ...x-stored-gatt-cache-DB-Hash-value-no.patch | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 meta/recipes-connectivity/bluez5/bluez5/0001-src-device-Fix-stored-gatt-cache-DB-Hash-value-no.patch diff --git a/meta/recipes-connectivity/bluez5/bluez5.inc b/meta/recipes-connectivity/bluez5/bluez5.inc index e827d0a..5c55afc 100644 --- a/meta/recipes-connectivity/bluez5/bluez5.inc +++ b/meta/recipes-connectivity/bluez5/bluez5.inc @@ -72,6 +72,7 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/bluetooth/bluez-${PV}.tar.xz \ file://0001-tools-Work-around-broken-stdin-handling-in-home-made.patch \ file://0001-gatt-client-Fix-use-after-free-caused-by-reentrant-c.patch \ file://0001-transport-Fix-set-volume-failure-with-invalid-device.patch \ + file://0001-src-device-Fix-stored-gatt-cache-DB-Hash-value-no.patch \ " S = "${UNPACKDIR}/bluez-${PV}" diff --git a/meta/recipes-connectivity/bluez5/bluez5/0001-src-device-Fix-stored-gatt-cache-DB-Hash-value-no.patch b/meta/recipes-connectivity/bluez5/bluez5/0001-src-device-Fix-stored-gatt-cache-DB-Hash-value-no.patch new file mode 100644 index 0000000..69323bd --- /dev/null +++ b/meta/recipes-connectivity/bluez5/bluez5/0001-src-device-Fix-stored-gatt-cache-DB-Hash-value-no.patch @@ -0,0 +1,84 @@ +From 9ec8cad56e47c0555a056e928e6568d543b3ae0c Mon Sep 17 00:00:00 2001 +From: Mengshi Wu <[email protected]> +Date: Wed, 1 Apr 2026 19:30:04 +0800 +Subject: [PATCH v1] src/device: Fix stored gatt cache DB Hash value not update +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is an asymmetry in behavior: when services are added during +the same connection (via Service Changed indication), the persistent +storage (disk) is not updated with the new DB hash, but when services +are removed, it is updated. + +During the same connection, We check DB hash value stored at +/var/lib/bluetooth/<adaptor addr>/cache/<remote addr>. +When established connection, the stored DB Hash value is A.Then we +add new services, the stored DB Hash value is still A which should +change to B. However, if we remove the existing services, the stored +DB Hash value changed to C. + +When performing addition, it goes like this: + +discover_primary_cb() + └─> gatt_db_insert_service() ← NEW service inserted into db + └─> gatt_service_added() ← callback fires immediately + └─> store_gatt_db() ← SAVED TO DISK (hash still OLD) + ... + └─> discovery_op_complete(success=true) + └─> read_db_hash(op) ← sends ATT Read By Type + └─> [ATT response arrives] + └─> db_hash_read_cb() + ├─> gatt_db_attribute_write(op->hash, ...) + │ └─> hash UPDATED IN MEMORY + └─> discovery_op_complete(true, 0) + ├─> [no services to remove, no + │ store_gatt_db called] + └─> service_changed_complete() + +Whereas removal perform like this: +discovery_op_complete(success=true) [1st call] + └─> read_db_hash(op) + └─> op->hash is NULL → sends ATT request → early return +... +[ATT response arrives] +db_hash_read_cb() + └─> gatt_db_attribute_write(op->hash, ) ← hash UPDATED IN MEMORY + └─> discovery_op_complete(true, 0) [2nd call] + └─> read_db_hash(op) → op->hash already set → returns false + └─> gatt_db_remove_service() + └─> gatt_service_removed() + └─> store_gatt_db() ← SAVED TO DISK (hash is NEW) + +There is a timing issue to update DB Hash value. + +The gatt_client_service_changed() callback in src/device.c is called +from service_changed_complete() in gatt-client.c, which is invoked +after db_hash_read_cb() has already updated the hash. Adding +store_gatt_db(device) here guarantees the db is persisted with the +correct, up-to-date hash for both the addition and removal cases. + +Upstream-Status: Backport [https://github.com/bluez/bluez/commit/0fd01e98cf94616a5c1c39749314cdd4a1654687] +Signed-off-by: Mengshi Wu <[email protected]> +--- + src/device.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/device.c b/src/device.c +index 3ea683667..cfbde307b 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -6267,7 +6267,11 @@ static void gatt_client_service_changed(uint16_t start_handle, + uint16_t end_handle, + void *user_data) + { ++ struct btd_device *device = user_data; ++ + DBG("start 0x%04x, end: 0x%04x", start_handle, end_handle); ++ ++ store_gatt_db(device); + } + + static void gatt_debug(const char *str, void *user_data) +-- +2.34.1 -- 2.43.0
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#238225): https://lists.openembedded.org/g/openembedded-core/message/238225 Mute This Topic: https://lists.openembedded.org/mt/119701180/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
