[Bugfix] HCI response to disconnect of unknown ID should return success.#414
[Bugfix] HCI response to disconnect of unknown ID should return success.#414
Conversation
📝 WalkthroughWalkthroughAvast: standardized HCI error comparisons to Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/NimBLEServer.cpp (1)
336-343:⚠️ Potential issue | 🔴 CriticalArrr, matey! The server be needin' cleanup when the controller says it knows not the connection.
Line 338 treats
BLE_ERR_UNK_CONN_IDas success, but this be leavin'm_connectedPeersstale forever. When the controller reports it knows not the connection, there'll be noBLE_GAP_EVENT_DISCONNECTevent comin' back to clean up yer bookkeeping. This meansgetConnectedCount(),getPeerDevices(),advertiseOnDisconnect, and the optionalm_pClient->m_connHandlemirror stay stale. The client handles this right by settin'm_connStatus = DISCONNECTEDon the spot (line 387); the server should do the same form_connectedPeersbefore returnin'true.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/NimBLEServer.cpp` around lines 336 - 343, NimBLEServer::disconnect currently treats BLE_ERR_UNK_CONN_ID as a non-error and returns true without cleaning up state; update disconnect(uint16_t connHandle, uint8_t reason) so when ble_gap_terminate returns BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) you remove the peer from m_connectedPeers (and perform the same per-peer cleanup you would on BLE_GAP_EVENT_DISCONNECT) and update any mirror state (e.g., clear the peer's m_connHandle, set its connection status to DISCONNECTED) before returning true so getConnectedCount(), getPeerDevices(), advertiseOnDisconnect and related logic reflect the disconnection.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/NimBLEClient.cpp`:
- Around line 381-387: When ble_gap_terminate(...) returns BLE_ERR_UNK_CONN_ID
the code sets m_connStatus to DISCONNECTED without firing the
BLE_GAP_EVENT_DISCONNECT cleanup path, which can orphan clients when
deleteOnDisconnect is true; modify the post-terminate branch in NimBLEClient.cpp
(where BLE_ERR_UNK_CONN_ID is checked) to perform the same cleanup the GAP
disconnect handler does: detect the BLE_ERR_UNK_CONN_ID fast path, check
this->deleteOnDisconnect (and any relevant client flags), and invoke the same
cleanup sequence used by the GAP handler (or call the same helper used by that
handler) so delete-on-disconnect clients are freed immediately rather than
relying on an event. Ensure m_lastErr and m_connStatus are still set
appropriately and reuse existing cleanup logic to avoid duplication.
---
Outside diff comments:
In `@src/NimBLEServer.cpp`:
- Around line 336-343: NimBLEServer::disconnect currently treats
BLE_ERR_UNK_CONN_ID as a non-error and returns true without cleaning up state;
update disconnect(uint16_t connHandle, uint8_t reason) so when ble_gap_terminate
returns BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) you remove the peer from
m_connectedPeers (and perform the same per-peer cleanup you would on
BLE_GAP_EVENT_DISCONNECT) and update any mirror state (e.g., clear the peer's
m_connHandle, set its connection status to DISCONNECTED) before returning true
so getConnectedCount(), getPeerDevices(), advertiseOnDisconnect and related
logic reflect the disconnection.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f943e235-e0ba-400f-b17a-09b83939accb
📒 Files selected for processing (2)
src/NimBLEClient.cppsrc/NimBLEServer.cpp
4e27a4f to
69cff9a
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/NimBLEClient.cpp (1)
381-387:⚠️ Potential issue | 🟠 MajorArrr,
BLE_ERR_UNK_CONN_IDstill leaves the client stuck inDISCONNECTING.Line 381 now treats
BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID)as success, but Line 387 still maps it toDISCONNECTING.connect()only acceptsDISCONNECTEDat Lines 261-264, so this path now depends on a later GAP disconnect event to restore state. If that event never arrives for an unknown handle, the client stays wedged and reconnects get rejected. I’d treatBLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID)the same asBLE_HS_ENOTCONNin the local state machine.🏴☠️ Minimal state fix
- m_connStatus = rc == BLE_HS_ENOTCONN ? DISCONNECTED : DISCONNECTING; + m_connStatus = (rc == BLE_HS_ENOTCONN || rc == BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID)) + ? DISCONNECTED + : DISCONNECTING;#!/bin/bash set -euo pipefail client_file="$(fd -p 'NimBLEClient\.cpp$' src | head -n1)" device_file="$(fd -p 'NimBLEDevice\.cpp$' src | head -n1)" printf '\n== disconnect() success path ==\n' sed -n '379,388p' "$client_file" printf '\n== connect() precondition ==\n' sed -n '255,265p' "$client_file" printf '\n== all m_connStatus transitions in NimBLEClient.cpp ==\n' rg -n -C2 'm_connStatus\s*=' "$client_file" printf '\n== deleteClient / deleteOnDisconnect handling ==\n' rg -n -C3 'deleteClient\s*\(|deleteOnDisconnect|deleteOnConnectFail' "$device_file" "$client_file"Expected result: ye should see the unknown-connection success path landing in
DISCONNECTING,connect()only allowingDISCONNECTED, and whether any separate delete-on-disconnect cleanup exists outside this branch.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/NimBLEClient.cpp` around lines 381 - 387, The code treats BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) as a non-error return from ble_gap_terminate() but still sets m_connStatus to DISCONNECTING, which can leave the client wedged; update the disconnect() success-path in NimBLEClient.cpp so that when rc equals BLE_HS_ENOTCONN OR BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) you set m_connStatus = DISCONNECTED (same as the ENOTCONN case) and preserve m_lastErr handling, so connect() (which checks for DISCONNECTED) will allow reconnection immediately.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/NimBLEClient.cpp`:
- Around line 381-387: The code treats BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) as a
non-error return from ble_gap_terminate() but still sets m_connStatus to
DISCONNECTING, which can leave the client wedged; update the disconnect()
success-path in NimBLEClient.cpp so that when rc equals BLE_HS_ENOTCONN OR
BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) you set m_connStatus = DISCONNECTED (same as
the ENOTCONN case) and preserve m_lastErr handling, so connect() (which checks
for DISCONNECTED) will allow reconnection immediately.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: bd099957-ae8e-4cd2-891c-8f6cd7eaf01c
📒 Files selected for processing (2)
src/NimBLEClient.cppsrc/NimBLEServer.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
- src/NimBLEServer.cpp
5f8a1be to
0a0dbaa
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/NimBLEClient.cpp (1)
381-393:⚠️ Potential issue | 🟠 MajorArrr, this “success” branch still skips local disconnect finalization.
For
BLE_HS_ENOTCONNandBLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID), this returnstruewithout clearingm_connHandle, settingm_connStatus = DISCONNECTED, or reaching thedeleteOnDisconnectpath that only runs in theBLE_GAP_EVENT_DISCONNECThandler on Lines 1036-1099. If no disconnect event follows those codes, a laterconnect()can still fail the guard on Lines 261-264 and self-delete never fires. Please route these cases through the same disconnect-finalization path instead of a bare success return.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/NimBLEClient.cpp` around lines 381 - 393, The switch that treats BLE_HS_ENOTCONN and BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) as a simple success must instead perform the same local disconnect finalization as the BLE_GAP_EVENT_DISCONNECT path: clear m_connHandle, set m_connStatus = DISCONNECTED, and trigger the deleteOnDisconnect behavior (or call the same helper used in the BLE_GAP_EVENT_DISCONNECT handler) before returning true; update the case arms in the switch in NimBLEClient.cpp so they do not just return true but run that finalization logic to avoid leaving the client in a half-disconnected state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/NimBLEClient.cpp`:
- Around line 381-393: The switch that treats BLE_HS_ENOTCONN and
BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) as a simple success must instead perform the
same local disconnect finalization as the BLE_GAP_EVENT_DISCONNECT path: clear
m_connHandle, set m_connStatus = DISCONNECTED, and trigger the
deleteOnDisconnect behavior (or call the same helper used in the
BLE_GAP_EVENT_DISCONNECT handler) before returning true; update the case arms in
the switch in NimBLEClient.cpp so they do not just return true but run that
finalization logic to avoid leaving the client in a half-disconnected state.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 19de5ead-c538-42bf-89b0-86310d5d6146
📒 Files selected for processing (2)
src/NimBLEClient.cppsrc/NimBLEServer.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
- src/NimBLEServer.cpp
* Update macro use to use conversion macros.
0a0dbaa to
91251ea
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/NimBLEClient.cpp (1)
381-393:⚠️ Potential issue | 🟠 MajorArrr, the same ghost-client snag remains here.
On
BLE_HS_ENOTCONNandBLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID), we now returntruewithout clearingm_connHandle/m_connStatusor applying the local finalization that theBLE_GAP_EVENT_DISCONNECTbranch does.src/NimBLEDevice.cpptreats thattrueas “disconnect cleanup will finish later”, so this can strand a client in a phantom connected state and miss the self-delete path.Ye can verify the missing local cleanup with:
#!/bin/bash set -euo pipefail printf '\n== NimBLEClient::disconnect fast path ==\n' sed -n '379,394p' src/NimBLEClient.cpp printf '\n== BLE_GAP_EVENT_DISCONNECT finalization ==\n' sed -n '1087,1099p' src/NimBLEClient.cpp printf '\n== deleteClient() path that trusts disconnect() ==\n' rg -n -C4 'deleteOnDisconnect|disconnect\(' src/NimBLEDevice.cpp🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/NimBLEClient.cpp` around lines 381 - 393, The fast-path in NimBLEClient::disconnect currently returns true for BLE_HS_ENOTCONN and BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) without performing the same local cleanup done in the BLE_GAP_EVENT_DISCONNECT branch, which can leave m_connHandle/m_connStatus stale and prevent deleteOnDisconnect/deleteClient from running; fix by performing the same finalization steps (clear m_connHandle, set m_connStatus to DISCONNECTED or appropriate terminal state, set m_lastErr if needed, and run any local cleanup/finalization hooks) before returning true in the BLE_HS_ENOTCONN and BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) cases inside disconnect(), so the client is not left in a phantom-connected state and deleteClient()/disconnect() logic can proceed normally.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/NimBLEClient.cpp`:
- Around line 381-393: The fast-path in NimBLEClient::disconnect currently
returns true for BLE_HS_ENOTCONN and BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) without
performing the same local cleanup done in the BLE_GAP_EVENT_DISCONNECT branch,
which can leave m_connHandle/m_connStatus stale and prevent
deleteOnDisconnect/deleteClient from running; fix by performing the same
finalization steps (clear m_connHandle, set m_connStatus to DISCONNECTED or
appropriate terminal state, set m_lastErr if needed, and run any local
cleanup/finalization hooks) before returning true in the BLE_HS_ENOTCONN and
BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) cases inside disconnect(), so the client is
not left in a phantom-connected state and deleteClient()/disconnect() logic can
proceed normally.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 02c6c787-d38f-4cb2-98b5-36199dd51cf4
📒 Files selected for processing (2)
src/NimBLEClient.cppsrc/NimBLEServer.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
- src/NimBLEServer.cpp
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/NimBLEClient.cpp (1)
381-388:⚠️ Potential issue | 🟠 MajorArrr, unknown-conn-id success path leaves local state adrift.
On Line 387 through Line 388, returnin’
trueforBLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID)without normalizin’m_connStatus/m_connHandlecan leave the client thinkin’ it still has a live link when the controller says otherwise.⚓ Proposed patch
bool NimBLEClient::disconnect(uint8_t reason) { int rc = ble_gap_terminate(m_connHandle, reason); switch (rc) { case 0: m_connStatus = DISCONNECTING; return true; case BLE_HS_ENOTCONN: + m_connHandle = BLE_HS_CONN_HANDLE_NONE; + m_connStatus = DISCONNECTED; + return true; case BLE_HS_EALREADY: return true; case BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID): // should not happen but just in case + m_connHandle = BLE_HS_CONN_HANDLE_NONE; + m_connStatus = DISCONNECTED; return true; } NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); m_lastErr = rc; return false; } // disconnectAlso applies to: 391-393
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/NimBLEClient.cpp` around lines 381 - 388, The BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) path returns true without clearing local connection state, which can leave m_connStatus/m_connHandle inconsistent; update the handler(s) for BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) (the cases in the switch that currently return true) to normalize state by setting m_connStatus to DISCONNECTED and resetting m_connHandle to the sentinel (e.g., BLE_HS_CONN_HANDLE_NONE or your project's invalid-handle value) before returning; apply the same fix to the other identical case block mentioned (the duplicate at the later switch).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/NimBLEClient.cpp`:
- Around line 381-388: The BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) path returns true
without clearing local connection state, which can leave
m_connStatus/m_connHandle inconsistent; update the handler(s) for
BLE_HS_HCI_ERR(BLE_ERR_UNK_CONN_ID) (the cases in the switch that currently
return true) to normalize state by setting m_connStatus to DISCONNECTED and
resetting m_connHandle to the sentinel (e.g., BLE_HS_CONN_HANDLE_NONE or your
project's invalid-handle value) before returning; apply the same fix to the
other identical case block mentioned (the duplicate at the later switch).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6724b75e-a38d-4a8f-a536-4037252b737e
📒 Files selected for processing (2)
src/NimBLEClient.cppsrc/NimBLEServer.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
- src/NimBLEServer.cpp
Summary by CodeRabbit