Environment
- ESP32 Dev Module
- PlatformIO / espressif32 6.13.0
- Arduino framework 3.20017.241212 (ESP-IDF 4.4.7)
- NimBLE-Arduino 2.5.1
- One Android or iPhone peer, already bonded with passkey and MITM protection
Server security configuration:
NimBLEDevice::setSecurityAuth(true, true, true);
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
NimBLEDevice::setSecurityInitKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID);
NimBLEDevice::setSecurityRespKey(BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID);
NimBLEDevice::setSecurityPasskey(BLE_PASSKEY);
Reproduction
- Pair and bond the phone with the ESP32. Reconnection after a normal reboot works.
- On the next boot, before creating or starting the
NimBLEServer, run one passive scan for 250 ms.
- The known peer advertises during this scan. The saved NimBLE bond and incoming connection address are identical.
- Start the normal peripheral/server advertising and connect the same phone.
The failure occurs when either of these is used to inspect the scan result:
setMaxResults(20) followed by checking NimBLEScanResults, or
setMaxResults(0) plus an onResult callback that only compares six address bytes and sets an atomic boolean.
The reconnect works when setMaxResults(0) and setScanCallbacks(nullptr, false) are used, even though the same passive scan is performed for the same duration with the phone present.
Actual result
The stored bond remains present, but the next reconnect fails authentication. The application does not alter the immobilizer state in this test.
BLE: stored bondings at startup: 1
PhoneGuard: passive 250 ms startup scan initiated, target b0:54:76:08:b7:d8 type 0
PhoneGuard: target phone detected in callback (b0:54:76:08:b7:d8), authorization suspended for testing
BLE: connection started, handle 0, address b0:54:76:08:b7:d8 type 0, bonding 0, encrypted 0
PhoneGuard: security setup for connection 0
BLE: authentication failed (encrypted 0, authenticated 0)
BLE: connection disconnected, handle 0, reason 534
With result storage disabled and no callback, the same peer reconnects and authentication succeeds:
PhoneGuard: 250 ms initial scan completed without saving results
BLE: Connection initiated, handle 0, address b0:54:76:08:b7:d8 type 0, bonding 0, encrypted 0
PhoneGuard: Target address saved: d8:b7:08:76:54:b0 type 0
Expected result
Inspecting a passive scan result, or receiving onResult, must not prevent a previously bonded peer with the same address from resuming encryption on its next peripheral connection.
Investigation performed
- No active scan and no scan request are used.
- The scan is completed before server creation and advertising.
- The automatic immobilizer action was disabled after detection; failure remained.
NimBLEDevice::getNumBonds() reports one stored bond after the scan.
NimBLEDevice::getBondedAddress(0) and the connected peer address are both b0:54:76:08:b7:d8, type 0.
- Restarting NimBLE after the scan did not resolve the problem.
Could scan-result handling or NimBLEScanCallbacks::onResult leave host/controller state that prevents a bonded peripheral reconnect from resuming security?
Environment
Server security configuration:
Reproduction
NimBLEServer, run one passive scan for 250 ms.The failure occurs when either of these is used to inspect the scan result:
setMaxResults(20)followed by checkingNimBLEScanResults, orsetMaxResults(0)plus anonResultcallback that only compares six address bytes and sets an atomic boolean.The reconnect works when
setMaxResults(0)andsetScanCallbacks(nullptr, false)are used, even though the same passive scan is performed for the same duration with the phone present.Actual result
The stored bond remains present, but the next reconnect fails authentication. The application does not alter the immobilizer state in this test.
With result storage disabled and no callback, the same peer reconnects and authentication succeeds:
Expected result
Inspecting a passive scan result, or receiving
onResult, must not prevent a previously bonded peer with the same address from resuming encryption on its next peripheral connection.Investigation performed
NimBLEDevice::getNumBonds()reports one stored bond after the scan.NimBLEDevice::getBondedAddress(0)and the connected peer address are bothb0:54:76:08:b7:d8, type 0.Could scan-result handling or
NimBLEScanCallbacks::onResultleave host/controller state that prevents a bonded peripheral reconnect from resuming security?