feat(split): optionally clear stale split bond on PIN/key mismatch#3377
feat(split): optionally clear stale split bond on PIN/key mismatch#3377akira-toriyama wants to merge 1 commit into
Conversation
|
I am confused about the scope of this change. Is this for
|
Add CONFIG_ZMK_SPLIT_AUTO_UNPAIR_ON_KEY_MISMATCH (off by default, depends on ZMK_SPLIT_ROLE_CENTRAL). When enabled, a split central that receives BT_SECURITY_ERR_PIN_OR_KEY_MISSING from a peripheral calls bt_unpair() + bt_conn_disconnect() so the next advertising window re-pairs from scratch without manual user action. In a split setup the central's bond record for one peripheral can become invalid while the peripheral still holds the old LTK. Once that happens the next reconnection sits in an infinite PIN_OR_KEY_MISSING loop and cannot recover without user action. Dongle-style centrals suffer the most because they have no keymap from which to trigger recovery behaviors. The flag is off by default because clearing a bond is destructive. The check is gated on CONFIG_ZMK_SPLIT_ROLE_CENTRAL so it cannot fire on the central <-> host pairing path, and only matches the exact PIN_OR_KEY_MISSING error code. Related: zmkfirmware#805
51b7e76 to
00d14f8
Compare
|
Thanks for the careful read — your second bullet is the intent, and you've correctly flagged two factual errors in my body. I've just force-pushed an update; here's the summary. Scope: split central ↔ peripheral pairing. To make that unambiguous in the code I renamed the Kconfig to On the inaccuracies you spotted:
In all three, the central's view of one peripheral's bond is gone or shifted, the peripheral keeps replaying the old LTK, and the link sits in Updated body and a cleaner testing section are pushed. Marking ready-for-review. |
What
Add
CONFIG_ZMK_SPLIT_AUTO_UNPAIR_ON_KEY_MISMATCH(off by default,depends on
ZMK_SPLIT_ROLE_CENTRAL). When enabled, a split centralthat receives
BT_SECURITY_ERR_PIN_OR_KEY_MISSINGfrom a peripheralcalls
bt_unpair()+bt_conn_disconnect()so the next advertisingwindow re-pairs from scratch.
Why
In a split setup (one central + N peripherals), the central's bond
record for one peripheral can become invalid while the peripheral
still holds the old LTK. Once that happens the next reconnection
sits in an infinite
PIN_OR_KEY_MISSINGloop and cannot recoverwithout manual intervention — which on a dongle-style central is
particularly painful because the dongle has no keymap from which to
issue any recovery behavior.
Concrete situations that produce this state:
settings_resetUF2 is flashed on the central (or, lesscommonly, on the peripheral) while the other side keeps its bond.
the peripherals are kept as-is.
the two peripherals occasionally landing in this state on KVM
switch-over and recovering automatically once the patch is active
(I can't fully attribute the KVM trigger to NVS state yet, only
that the symptom is the same
PIN_OR_KEY_MISSINGloop and thesame
bt_unpair()clears it).In all three the symptom is the same: the central's LTK is gone or
shifted for that peripheral, the peripheral still replays the old
LTK, and the link cannot complete without user action.
Scope and gating
IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL). The new behaviorcannot fire on the central ↔ host pairing path.
ZMK_SPLIT_AUTO_UNPAIR_ON_KEY_MISMATCHisoff by default. Clearing a bond is destructive; only deployments
that are known to benefit (typically dongle setups) should enable
it.
BT_SECURITY_ERR_PIN_OR_KEY_MISSING. Other security failures areleft alone.
Testing
Verified on hardware via akira-toriyama/canon (Cyboard Imprint:
XIAO BLE dongle as central, both halves as peripherals):
xiao_ble/nrf52840/zmk + imprint_dongle.under normal use, and a previously-reproducible failure where
one peripheral half stopped responding after a KVM USB switch-over
no longer reproduces in the user's setup. A few switch cycles
tested; not claimed as exhaustive given KVM-USB enumeration
variability.
Related
Security failed: ... err 2=BT_SECURITY_ERR_PIN_OR_KEY_MISSINGpattern in a different(host-side) scenario. This PR doesn't claim to close it; the
split flag is unrelated to the host pair path by design.
Notes for maintainers
ZMK_SPLIT_DROP_STALE_BOND, etc.) if there's apreferred convention.
(peripheral keeps its bond, central LTK shifted) but left it out
of this PR to keep the scope tight. Happy to follow up if you'd
like it included here.