Skip to content

fix(nrf54l15): request BLE security on connect - #11521

Draft
cvaldess wants to merge 1 commit into
meshtastic:developfrom
cvaldess:fix/nrf54l15-request-security
Draft

fix(nrf54l15): request BLE security on connect#11521
cvaldess wants to merge 1 commit into
meshtastic:developfrom
cvaldess:fix/nrf54l15-request-security

Conversation

@cvaldess

Copy link
Copy Markdown
Contributor

Every characteristic and CCC in mesh_svc carries BT_GATT_PERM_*_AUTHEN, but connected_cb deliberately skipped bt_conn_set_security(), leaving the escalation to the central. That only works with centrals that react to an "Insufficient Authentication" ATT error by pairing: iOS CoreBluetooth and BlueZ do, Chrome's Web Bluetooth on Windows does not.

Captured over RTT while connecting from client.meshtastic.org on Windows: the link came up unencrypted, MTU negotiated to 247, service discovery completed, and then the CCC writes for fromNum (handle 0x000c) and logRadio (0x0010) were both answered with an ATT Error Response. With no subscription to fromNum the client never sends want_config, so it hangs on "loading" - and 60 s later the BLE zombie watchdog reboots the board. No SMP traffic appeared at all, which is also why Windows never showed a pairing prompt.

Send a Security Request from connected_cb instead, asking for level 4 (LE Secure Connections + the fixed passkey) to match what the AUTHEN permissions require. A peer holding a valid bond just encrypts; one with a stale bond gets unpaired by the existing security_changed_cb handler and pairs cleanly on the next attempt.

The comment removed here justified the old behaviour with a pairing dialog that broke advertising restart. That failure mode predates the adv_restart_work queue and did not reproduce.

Testing

Verified on an nRF54L15-DK:

  • smp_send_security_req -> pairing -> BLE security level 4 established -> Client wants config -> full config stream and packets in both directions.
  • Reproduced from both the Windows web client (which was the broken case) and the iOS app.
  • A later reconnect reached level 4 with no re-pairing.
  • Zero BLE zombie reboots over the session.

The change is guarded by #if defined(CONFIG_BT_SMP), so builds without SMP are unaffected.

Every characteristic and CCC in mesh_svc carries BT_GATT_PERM_*_AUTHEN,
but connected_cb deliberately skipped bt_conn_set_security(), leaving the
escalation to the central. That only works with centrals that react to an
"Insufficient Authentication" ATT error by pairing: iOS CoreBluetooth and
BlueZ do, Chrome's Web Bluetooth on Windows does not.

Captured over RTT while connecting from client.meshtastic.org on Windows:
the link came up unencrypted, MTU negotiated to 247, service discovery
completed, and then the CCC writes for fromNum (handle 0x000c) and
logRadio (0x0010) were both answered with an ATT Error Response. With no
subscription to fromNum the client never sends want_config, so it hangs
on "loading" - and 60 s later the BLE zombie watchdog reboots the board.
No SMP traffic appeared at all, which is also why Windows never showed a
pairing prompt.

Send a Security Request from connected_cb instead, asking for level 4
(LE Secure Connections + the fixed passkey) to match what the AUTHEN
permissions require. A peer holding a valid bond just encrypts; one with
a stale bond gets unpaired by the existing security_changed_cb handler
and pairs cleanly on the next attempt.

The comment removed here justified the old behaviour with a pairing
dialog that broke advertising restart. That failure mode predates the
adv_restart_work queue and did not reproduce.

Verified on an nRF54L15-DK: "smp_send_security_req" -> pairing ->
"BLE security level 4 established" -> "Client wants config" -> full
config stream and packets in both directions, from both the Windows web
client and the iOS app. A later reconnect reached level 4 with no
re-pairing, and the session logged zero BLE zombie reboots.
@github-actions

Copy link
Copy Markdown
Contributor

⚡ Try this PR in the Web Flasher

Note

Building this pull request… the flash button, badges and supported-board
list will appear here automatically once CI finishes.

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e6732b9e-61ef-4149-b8d9-28b940dc8846

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant