Skip Master-role unpair to avoid blocking the HCI management channel - #1
Open
vkolotov wants to merge 1 commit into
Open
Skip Master-role unpair to avoid blocking the HCI management channel#1vkolotov wants to merge 1 commit into
vkolotov wants to merge 1 commit into
Conversation
In Master role, unpairDevice() is issued on every disconnect and for every newly discovered device. Each mgmt UNPAIR_DEVICE can time out (around 10s) and block the single HCI management channel, which stalls GATT traffic on the connected device. The unpair is only required for the Slave SC DHKey path, so guard both call sites with BTRole::Master and keep just the local SMP state cleanup for Masters.
vkolotov
force-pushed
the
directbt-no-unpair-fix
branch
from
June 25, 2026 20:35
10cb1a0 to
ba510d8
Compare
vkolotov
marked this pull request as ready for review
June 25, 2026 20:36
Owner
|
Thank you Vlad, will check this later. Great stuff. |
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.
When acting as a Master/Central, Direct-BT issues a management UNPAIR_DEVICE command in two places: on every disconnect (BTDevice::unpair via notifyDisconnected) and for every newly discovered device (BTAdapter::mgmtEvDeviceFoundHCI). In a busy RF environment with several nearby BLE devices, those management commands frequently time out (around 10 seconds each) and block the single HCI management channel. While the channel is blocked, GATT reads on the actually connected device stall, and the read timeout then forces a disconnect. The device also re-bonds on every reconnect, adding churn.
The comment in the slave_unpair block explains that unpair is needed in SC mode (or with key pre-pairing) so the peripheral does not fail the DHKey check. That reasoning applies to the Slave/peripheral role. As a Master connecting to a peripheral it does not, so the unconditional unpair is unnecessary work there.
This change guards both unpair sites with BTRole::Master. When we are the Master we skip the management round trip and keep only the local SMP state cleanup (clearSMPStates). The Slave path is unchanged.
Effect in testing: with this change a CSR BT4 adapter talking to an nRF peripheral went from a read stall and disconnect roughly every 47 seconds to fully stable. Wire captures (btmon) showed 61 of 61 and 45 of 45 ATT reads answered with zero host disconnects, matching the in kernel BlueZ stack on the same hardware. Confirmed on both a CSR BT4 and a Realtek BT5 adapter.
Scope: two files, BTDevice.cpp and BTAdapter.cpp, both guarded so only the Master role behavior changes.