From 43084873a693f038c3dced11061b77ede10e1e35 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 16 Jul 2026 13:02:43 -0500 Subject: [PATCH] nRF52 BLE: restore pairing passkey callback on re-enable (#11027) shutdown() installs onUnwantedPairing to actively refuse pairing (used on the factory-reset / BT-disable teardown path), but the correct callback (onPairingPasskey) is installed only in setup(). Re-enabling BLE on an already-constructed nrf52Bluetooth goes through resumeAdvertising(), not setup() (main-nrf52.cpp), which only re-armed advertising and never restored the pairing callback. So a shutdown()->resumeAdvertising() cycle without a reboot left the device silently refusing all pairing until the next reboot. Restore the correct pairing passkey callback in resumeAdvertising(), guarded by the same config.bluetooth.mode check setup() uses. Only PIN modes drive a passkey-display callback; NO_PIN (Just Works) never invokes it, so no restore is needed there. Reachable today only via the PowerStress module's BT_OFF/BT_ON opcodes (normal runtime BT-disable paths reboot), so low severity, but a real teardown-latches / re-enable-doesn't-restore asymmetry. --- src/platform/nrf52/NRF52Bluetooth.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index dd0230100..357c1484c 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -369,6 +369,15 @@ void NRF52Bluetooth::setup() } void NRF52Bluetooth::resumeAdvertising() { + // shutdown() latches onUnwantedPairing to actively refuse pairing (used on the factory-reset / + // BT-disable teardown path). The real pairing passkey callback is installed only in setup(), but a + // shutdown()->resumeAdvertising() re-enable cycle skips setup() entirely (see setBluetoothEnable() in + // main-nrf52.cpp), so restore the correct callback here - otherwise the device silently refuses all + // pairing until the next reboot. Mirror the mode check in setup(): only PIN modes drive a passkey- + // display callback, so NO_PIN (Just Works) needs no restore. + if (config.bluetooth.mode != meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN) + Bluefruit.Security.setPairPasskeyCallback(NRF52Bluetooth::onPairingPasskey); + Bluefruit.Advertising.restartOnDisconnect(true); Bluefruit.Advertising.setInterval(32, 668); // in unit of 0.625 ms Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode