Repository navigation
Conversation
…flight A failed connect, an explicit disconnect, and a drop during a queued command each close the peripheral's BluetoothGatt, but a drop the app did not request while no command was running left it registered with the Bluetooth stack. AdapterManager evicts the peripheral on every DeviceDisconnected, so that client was never reused: the next connection built a new Peripheral and a new BluetoothGatt, and the orphan stayed registered. Android's GATT app table is shared with scanners and holds about 30 registrations, so a device that drops and reconnects repeatedly exhausts it. After that every registration fails with status 133, connects fail immediately, scans fail to start, and dropped devices never come back until the app process exits. Close the client in the main callback when it reports STATE_DISCONNECTED and the pending command, if any, has not already closed it. The retry and command paths clear the reference when they close it, so a client is never closed twice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On older versions of Android, a link that drops while no command is running leaves its
BluetoothGattregistered with the system. Each reconnect then registers a new client, so a device that drops and reconnects often fills Android's client table within minutes. After that every connect fails immediately with status 133, scans stop starting, and the device never comes back until the app restarts. This change closes the client when the main callback seesSTATE_DISCONNECTED.Cause
AdapterManager::emitevicts the peripheral on everyDeviceDisconnected, so the next connection always builds a newPeripheraland a new client. The old client is never reused.Change
In the main callback's
onConnectionStateChange, after the command callback runs, close the client onSTATE_DISCONNECTEDif it is still this peripheral's. Paths that already closed it clear the reference first, so it's never closed twice.Testing
Samsung Galaxy S10+ (Android 12), with one peripheral running test firmware that drops its link a few seconds after every connect, alongside up to four normal peripherals holding connections and communicating continuously.