Repository navigation
Conversation
…#155) NimBLE's NVS store saves a bond only when the number of bonds changes. A pairing that replaced an existing bond for the same identity updated RAM only; after a restart the old keys came back, often without the new IRK, so a Computer on private addresses was never resolved and couldn't reconnect. When a pairing replaces the Computer, its keys are now deleted and written again, which makes both reach NVS. Subscriptions are kept. Assisted-by: Claude Code:claude-opus-5-5
- Remove the Computer's resolving-list entry before rewriting its peer keys: the controller already holds it (from the pairing, or from boot with the old IRK) and would refuse the re-add, failing every pairing that sends an IRK. Advertising is stopped first, as HCI requires. - Rewrite each record in turn, and judge the peer record by reading it back, since a resolving-list error is returned after it's saved. Assisted-by: Claude Code:claude-opus-5-5
This was referenced Oct 26, 2026
Open
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.
Fixes #155.
Cause (agent2 traced it in the source; confirmed on black2): NimBLE's NVS store (
ble_store_config_persist_*_secs) only writes when the number of bonds changes. When a Computer pairs again while the panel still has a bond for the same identity,ble_store_config_write_*_secoverwrites the record in RAM, the count stays the same, and NVS keeps the old keys. After a restart those come back. In the test, the old record was black2's earlier privacy-off bond, withirk_present=0. So there was no resolving-list entry, the RPA wasn't resolved (diag:id == otaon every connect), the LTK lookup missed, and every connect ended in Authentication Failure.Fix: in
ReplaceOthers,persistBond()reads the Computer'sour_secandpeer_secfrom RAM, deletes them, and writes them back. The count drops and then grows, so both reach NVS, and the peer write re-adds the IRK to the resolving list. Only the key records are rewritten.ble_store_util_delete_peerwould also delete the Computer's stored subscriptions. Before the peer record is rewritten, advertising stops and the Computer's resolving-list entry is removed (ble_hs_pvcy_remove_entry). The controller already holds that entry, from the pairing or from boot with the old IRK, and would refuse a second one, which would fail every pairing that sends an IRK. The rewrite then re-adds it with the new IRK. Each record is rewritten in turn. The peer record is judged by reading it back, because a resolving-list error is returned after the record is saved; that error is logged. If the rewrite fails, the pairing is rejected, as for a refused write.Evidence on black2 (privacy on, RPAs), with diag builds of main:
peer_sec irk_present=0; connects arrive unresolved; Authentication Failure loop.irk_present=1; the connect resolves (ota= RPA,id= identity); it reconnects and stays connected.Tests:
pio test -e nativepasses 69/69 andpio run -e crowpanelbuilds. There's no native test because the fix is entirely in NimBLE's store, which the native env doesn't have. The hardware check, through the panel-owner rule: pair black2 (privacy on) on a panel that already has a bond for it, restart, and it reconnects. Also check the log for a resolving-list rc.Who it affects: a Computer pairing again while an old bond for it still exists, for example a Mac re-pairing. A first pairing on a clean panel was fine.
No auto-merge until the firmware and AppSec reviews pass and the hardware check is done. #153 will merge main once this lands.