[bluez/bluez] cde4bf: gatt-client:Implement error handling for DB_OUT_OF...

From: MengshiWu-mengshiw <hidden>
Date: 2026-02-24 11:26:45

  Branch: refs/heads/1057153
  Home:   https://github.com/bluez/bluez
  Commit: cde4bfa2c6ba4c0d62598493210bd95afc658867
      https://github.com/bluez/bluez/commit/cde4bfa2c6ba4c0d62598493210bd95afc658867
  Author: Mengshi Wu [off-list ref]
  Date:   2026-02-24 (Tue, 24 Feb 2026)

  Changed paths:
    M src/shared/att.c
    M src/shared/att.h
    M src/shared/gatt-client.c
    M src/shared/gatt-helpers.c
    M src/shared/gatt-helpers.h

  Log Message:
  -----------
  gatt-client:Implement error handling for DB_OUT_OF_SYNC in GATT caching

Implement automatic retry logic for GATT operations that fail with
DB_OUT_OF_SYNC error (0x12).

This implementation follows the GATT caching specification and provides
robust error recovery while minimizing unnecessary service discovery
operations.

When a DB_OUT_OF_SYNC error occurs, the implementation:

1. Pauses the failed operation in a pending_db_sync state
2. Notifies the GATT client layer via db_sync_callback
3. Reads the remote Database Hash characteristic (0x2B2A)
4. Compares it with the locally cached hash value
5. If hashes match: Retries the operation (database is in sync)
6. If hashes differ: Triggers full service discovery

Workflow:
---------

Hash Match Case:
  App → GATT Client → ATT Layer → Remote Device
                                      ↓ (DB_OUT_OF_SYNC error)
  App ← GATT Client ← ATT Layer ← Remote Device
                ↓
         Read DB Hash (0x2B2A)
                ↓
         Compare with local cache
                ↓ (Match)
         bt_att_resend(att, id, ...)
                ↓
  App → GATT Client → ATT Layer → Remote Device (retry)
                                      ↓ (Success)
  App ← GATT Client ← ATT Layer ← Remote Device

Hash Differ Case:
  App → GATT Client → ATT Layer → Remote Device
                                      ↓ (DB_OUT_OF_SYNC error)
  App ← GATT Client ← ATT Layer ← Remote Device
                ↓
         Read DB Hash (0x2B2A)
                ↓
         Compare with local cache
                ↓ (Differ)
         bt_att_cancel(att, id)
                ↓
         Trigger Service Discovery
                ↓
  App ← GATT Client (operation failed, discovery in progress)

Service Changed Ind Received (Handle Outside Affected Range):
  App → GATT Client → ATT Layer → Remote Device
                                      ↓ (DB_OUT_OF_SYNC error)
  App ← GATT Client ← ATT Layer ← Remote Device
                ↓
         Service Changed Ind arrives
                ↓
         Check error handle vs affected range
                ↓ (Outside range)
         bt_att_resend(att, id, ...)
                ↓
  App → GATT Client → ATT Layer → Remote Device (retry)
                                      ↓ (Success)
  App ← GATT Client ← ATT Layer ← Remote Device

Service Changed Ind Received (Handle Inside Affected Range):
  App → GATT Client → ATT Layer → Remote Device
                                      ↓ (DB_OUT_OF_SYNC error)
  App ← GATT Client ← ATT Layer ← Remote Device
                ↓
         Service Changed Ind arrives
                ↓
         Check error handle vs affected range
                ↓ (Inside range)
         bt_att_cancel(att, id)
                ↓
         Service Discovery already in progress
                ↓
  App ← GATT Client (operation failed, discovery in progress)

btmon traffics:
--------------

Hash Match Case:

bluetoothd[91554]: < ACL Data TX: Handle 3 flags 0x00 dlen 7   #1 [hci1]
13.675271
      ATT: Read Request (0x0a) len 2
        Handle: 0x000d
HCI Event: Number of Completed Packets (0x13) plen 5         #2 [hci1]
13.694287
        Num handles: 1
        Handle: 3
        Count: 1
ACL Data RX: Handle 3 flags 0x02 dlen 9                      #3 [hci1]
13.728279
      ATT: Error Response (0x01) len 4
        Read Request (0x0a)
        Handle: 0x000d
        Error: Database Out of Sync (0x12)
bluetoothd[91554]: < ACL Data TX: Handle 3 flags 0x00 dlen 11  #4 [hci1]
13.730759
      ATT: Read By Type Request (0x08) len 6
        Handle range: 0x0001-0xffff
        Attribute type: Database Hash (0x2b2a)
HCI Event: Number of Completed Packets (0x13) plen 5         #5 [hci1]
13.754290
        Num handles: 1
        Handle: 3
        Count: 1
ACL Data RX: Handle 3 flags 0x02 dlen 24                     #6 [hci1]
13.820283
      ATT: Read By Type Response (0x09) len 19
        Attribute data length: 18
        Attribute data list: 1 entry
        Handle: 0x000f
        Value: f74347d19eef647d97f0b2f7af502e33
bluetoothd[91554]: < ACL Data TX: Handle 3 flags 0x00 dlen 11  #7 [hci1]
13.822792
      ATT: Read By Type Request (0x08) len 6
        Handle range: 0x0010-0xffff
        Attribute type: Database Hash (0x2b2a)
HCI Event: Number of Completed Packets (0x13) plen 5         #8 [hci1]
13.842581
        Num handles: 1
        Handle: 3
        Count: 1
ACL Data RX: Handle 3 flags 0x02 dlen 9                      #9 [hci1]
13.880369
      ATT: Error Response (0x01) len 4
        Read By Type Request (0x08)
        Handle: 0x0010
        Error: Attribute Not Found (0x0a)
bluetoothd[91554]: < ACL Data TX: Handle 3 flags 0x00 dlen 7   #10
[hci1] 13.880999
      ATT: Read Request (0x0a) len 2
        Handle: 0x000d
HCI Event: Number of Completed Packets (0x13) plen 5         #11
[hci1] 13.904288
        Num handles: 1
        Handle: 3
        Count: 1
ACL Data RX: Handle 3 flags 0x02 dlen 6                      #12
[hci1] 13.940273
      ATT: Read Response (0x0b) len 1

--------------------
Hash differ case:

bluetoothd[91554]: < ACL Data TX: Handle 3 flags 0x00 dlen 7
      ATT: Read Request (0x0a) len 2
        Handle: 0x000d
HCI Event: Number of Completed Packets (0x13) plen 5
#17 [hci1] 50.171857
        Num handles: 1
        Handle: 3
        Count: 1
ACL Data RX: Handle 3 flags 0x02 dlen 9
#18 [hci1] 50.171970
      ATT: Error Response (0x01) len 4
        Read Request (0x0a)
        Handle: 0x000d
        Error: Database Out of Sync (0x12)
bluetoothd[91554]: < ACL Data TX: Handle 3 flags 0x00 dlen 11
      ATT: Read By Type Request (0x08) len 6
        Handle range: 0x0001-0xffff
        Attribute type: Database Hash (0x2b2a)
HCI Event: Number of Completed Packets (0x13) plen 5
#20 [hci1] 50.201854
        Num handles: 1
        Handle: 3
        Count: 1
ACL Data RX: Handle 3 flags 0x02 dlen 24
#21 [hci1] 50.268291
      ATT: Read By Type Response (0x09) len 19
        Attribute data length: 18
        Attribute data list: 1 entry
        Handle: 0x000f
        Value: 5fa98eed072ee317aa521990be294bf3
bluetoothd[91554]: < ACL Data TX: Handle 3 flags 0x00 dlen 11
      ATT: Read By Type Request (0x08) len 6
        Handle range: 0x0010-0xffff
        Attribute type: Database Hash (0x2b2a)
HCI Event: Number of Completed Packets (0x13) plen 5
#23 [hci1] 50.291849
        Num handles: 1
        Handle: 3
        Count: 1
ACL Data RX: Handle 3 flags 0x02 dlen 9
#24 [hci1] 50.419999
      ATT: Error Response (0x01) len 4
        Read By Type Request (0x08)
        Handle: 0x0010
        Error: Attribute Not Found (0x0a)
bluetoothd[91554]: < ACL Data TX: Handle 3 flags 0x00 dlen 11
      ATT: Read By Group Type Request (0x10) len 6
        Handle range: 0x0001-0xffff
        Attribute group type: Primary Service (0x2800)
HCI Event: Number of Completed Packets (0x13) plen 5
#26 [hci1] 50.471607
        Num handles: 1
        Handle: 3
        Count: 1
ACL Data RX: Handle 3 flags 0x02 dlen 24
#27 [hci1] 50.471663
      ATT: Read By Group Type Response (0x11) len 19
        Attribute data length: 6
        Attribute group list: 3 entries
        Handle range: 0x0001-0x0007
        UUID: Generic Access Profile (0x1800)
        Handle range: 0x0008-0x0011
        UUID: Generic Attribute Profile (0x1801)
        Handle range: 0x0012-0x0014
        UUID: Device Information (0x180a)
--------------------

Changes from v4:
 - Fix errors reported by bluez.test.bot
 - Link to v4
   https://lore.kernel.org/all/20260210011347.3237740-1-mengshi.wu@oss.qualcomm.com/ (local)

Changes from v3:
 - Reuses existing bt_att_resend() and bt_att_cancel() functions
 - Add new structure pending_db_sync
 - Link to v3
   https://lore.kernel.org/all/20260121083804.4010106-1-mengshi.wu@oss.qualcomm.com/ (local)

Changes from v2:
 - Detects DB_OUT_OF_SYNC errors during GATT operations
 - Extracts affected handles from the original request PDU
 - Checks if Service Changed indications overlap with those handles
 - Verifies database consistency using Database Hash characteristic
 - Automatically retries the original request if DB is consistent
 - Automatically retries the original request if handle is not affected
 - Link to v2
   https://lore.kernel.org/all/20260105103828.105346-1-mengshi.wu@oss.qualcomm.com/ (local)

Changes from v1:
 - Implement automatic recovery when ATT_ECODE_DB_OUT_OF_SYNC error is
   received from the remote device.
 - Link to v1
   https://lore.kernel.org/all/20251208101915.247459-1-mengshi.wu@oss.qualcomm.com/ (local)

Signed-off-by: Mengshi Wu <redacted>



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help