feat: GATT Client Identity Signaling & Connection Deduplication#627
feat: GATT Client Identity Signaling & Connection Deduplication#627
Conversation
…cation Implements a mechanism for GATT clients to signal their Peer ID to the server immediately after connection, allowing for robust deduplication of redundant connections. Includes: - New IDENTITY_CHARACTERISTIC_UUID in AppConstants - Server-side handling of identity writes and deduplication logic - Client-side active signaling of Peer ID upon service discovery - Updated BluetoothConnectionTracker to map devices to Peer IDs - Comprehensive specification document in docs/PEERID_GATT_SERVER_CLIENT_SPEC.md
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6c7483956e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| val idBytes = myPeerID.chunked(2).map { it.toInt(16).toByte() }.toByteArray().take(8).toByteArray() | ||
| identityChar.value = idBytes | ||
| identityChar.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE | ||
| gatt.writeCharacteristic(identityChar) | ||
| Log.d(TAG, "Client: Signaled identity to server $deviceAddress") |
There was a problem hiding this comment.
Serialize GATT ops before enabling notifications
Android’s GATT stack only allows one outstanding operation at a time, and this path issues writeCharacteristic(identityChar) and then immediately proceeds to write the CCCD. On devices that enforce serialization (common), the subsequent writeDescriptor can return false/never execute, leaving notifications disabled and the connection unable to receive data even though it is marked “connected.” This is especially risky with WRITE_TYPE_NO_RESPONSE, which provides no completion signal to gate the descriptor write. Consider queueing the CCCD write and only enabling notifications after the identity write completes (or use a write type with a completion callback).
Useful? React with 👍 / 👎.
Summary
This PR implements a robust mechanism for GATT clients to signal their stable Peer ID to the server immediately after connection. This solves the issue of redundant connections caused by MAC address rotation and allows servers to enforce strict 1-to-1 connection policies per peer.
Changes
IDENTITY_CHARACTERISTIC_UUID(...C5E) toAppConstants.BluetoothGattServerManagernow exposes the Identity Characteristic and handles write requests. It maps the MAC address to the Peer ID and disconnects the new connection if that Peer ID is already connected via another MAC.BluetoothGattClientManagerchecks for the Identity Characteristic during service discovery and writes its truncated Peer ID (8 bytes).BluetoothConnectionTrackersupports updating the Peer ID for an existing device connection (setDevicePeerID).docs/PEERID_GATT_SERVER_CLIENT_SPEC.mdfor cross-platform implementation (iOS).Testing