Fix bonded reconnect: connect to the visible address, not the flipped identity - #4
Open
vkolotov wants to merge 1 commit into
Open
Fix bonded reconnect: connect to the visible address, not the flipped identity#4vkolotov wants to merge 1 commit into
vkolotov wants to merge 1 commit into
Conversation
… identity A peer that distributes an IRK + identity address during SMP has its tracked address flipped to the identity (updateIdentityAddress), but the controller is never given the IRK (no resolving-list support, BTDevice.cpp TODO), so the next le_create_conn targets an address the peer is not advertising under and the reconnect loops forever. Software resolution instead of controller resolution (the same strategy the Linux kernel uses when LL privacy is unavailable): - connectLE(): when the tracked identity differs from the visible (advertised) address, issue le_create_conn to the visible address and register setResolvHCIConnectionAddr(visible, identity) so HCI events map back to the identity. BTAdapter::findDevice already resolves fresh advertisements (RPA via matches_irk, static random via the visible match) and keeps visibleAddressAndType current, so the connect target is always reachable. - L2CAPClient::open(): connect the ATT channel to the address the kernel tracks the ACL under (new BTDevice::getKernelConnectionAddressAndType()): the kernel rewrites its hci_conn dst to the bonded identity only where it can resolve an RPA via the peer IRK; for a static-random visible address it keeps the visible address, and an l2cap connect to the identity would miss the connection. Validated live (nRF52840 peripheral, static random address distributing a public identity): Just-Works and Passkey-Entry both reconnect encrypted after link drops (previously 21 failed-reconnect loops per window), no regression on unbonded devices.
vkolotov
force-pushed
the
bonded-reconnect-visible-address
branch
from
August 17, 2026 04:09
52f7236 to
a0fd62a
Compare
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.
Problem
When a peer distributes an IRK + identity address during SMP pairing,
BTDevice::updateIdentityAddressflips the tracked address to the identity (typically advertised RANDOM -> identity PUBLIC). But the controller is never given the IRK — the resolving list is not used (the acknowledged// TODO: Shall we support 'resolving list' ...inBTDevice::connectLE) — so the nextle_create_conntargets the identity address the peer is not advertising under. The connection never establishes and every reconnect to a bonded LE device loops forever.Reproducible with any peripheral that distributes an identity during bonding (e.g. an nRF52 SoftDevice peripheral, which always sets
kdist_own.id).Fix — software resolution using machinery that already exists
Direct-BT already resolves addresses in software on the discovery side:
BTAdapter::findDevicematches a fresh advertisement against the visible or identity address (RPAs viamatches_irk), keepsvisibleAddressAndTypecurrent, andsetResolvHCIConnectionAddrmaps HCI events back to the identity. The only gap was the connect path.BTDevice::connectLE: when the tracked identity differs from the visible (advertised) address, issuele_create_connto the visible address and re-registersetResolvHCIConnectionAddr(visible, identity)so events map back to the identity. This mirrors what the Linux kernel does when LL privacy is unavailable.L2CAPClient::open: connect the ATT channel to the address the kernel tracks the ACL under (newBTDevice::getKernelConnectionAddressAndType()). The kernel rewrites itshci_conndestination to the bonded identity only where it can resolve an RPA via the peer IRK; for a static-random visible address it keeps the visible address, and an l2cap connect to the identity would miss the connection.Validation
Tested live against an nRF52840 peripheral (static random address, distributes a public identity, both Just-Works and Passkey-Entry pairing): bonded reconnects now establish reliably after forced link drops and host restarts (previously: infinite reconnect loop). Unbonded devices are unaffected (
connect_address == addressAndTypekeeps the existing behaviour).Note: a peer that switches to advertising under its identity address while an older visible address is still tracked will not reconnect until re-discovery refreshes the visible address; this is documented at the connect site and does not regress current behaviour.