Map non-transmittable disconnect reasons to a valid HCI error code - #5
Open
vkolotov wants to merge 1 commit into
Open
Map non-transmittable disconnect reasons to a valid HCI error code#5vkolotov wants to merge 1 commit into
vkolotov wants to merge 1 commit into
Conversation
… error code The DISCONNECT command only accepts the reason codes listed in BT Core Spec v5.2, Vol 4, Part E, 7.1.6. Extended HCIStatusCode values (MgmtStatus mappings and internal codes such as L2CAP_CLIENT_TIMEOUT) sent as-is are rejected by the controller with INVALID_HCI_COMMAND_PARAMETERS, so no disconnect is performed: the failure branch drops the connection tracker entry while the ACL remains established. The peripheral then stops advertising and stays unreachable until the HCI channel is closed. Observed live on an RTL8761BU (BT5) central: processL2CAPSetup failing with EBUSY issued disconnect(L2CAP_CLIENT_TIMEOUT) = 0xfc on the wire, the controller rejected it and the leaked ACL held the peripheral captive. Keep the caller's reason for tracking and logging; only the wire value is mapped, defaulting to REMOTE_USER_TERMINATED_CONNECTION.
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.
HCIHandler::disconnect() puts the given HCIStatusCode straight into the DISCONNECT command. The controller only accepts the reason codes from the spec (Core v5.2, Vol 4, Part E, 7.1.6). If the reason is one of the extended values, for example L2CAP_CLIENT_TIMEOUT or one of the MgmtStatus mappings, the controller rejects the command with INVALID_HCI_COMMAND_PARAMETERS and nothing gets disconnected. The failure branch then removes the connection tracker entry anyway, so the library thinks the link is gone while the ACL is actually still up. The peripheral stops advertising and there is no way to reach it again until the HCI channel is closed.
I hit this on an RTL8761BU in central role. An L2CAP ATT open failed with EBUSY, which triggered disconnect(L2CAP_CLIENT_TIMEOUT). In btmon you can see the command going out with reason 0xfc and the controller answering with status 0x12. The ACL stayed up and the device was stuck until I restarted the process.
The fix maps any reason that is not valid on the wire to REMOTE_USER_TERMINATED_CONNECTION. Only the wire value changes, the original reason is still used for tracking and logging.