Repository navigation
BLE: ESP32 to NimBLE, shared BLE helpers, non-blocking nRF52 sends - #3633
Draft
liquidraver wants to merge 6 commits into
Draft
liquidraver wants to merge 6 commits into
liquidraver wants to merge 6 commits into
Conversation
One header for the ESP32, nRF52 and RP2040 serial BLE interfaces: Nordic UART UUIDs, connection and advertising parameters, the "@@MAC" name helper, debug macros and the frame queue. The queue is a single-producer/single-consumer ring of 2048 bytes that stores frames packed by size, so a burst of small commands (the app's "faster channel sync" sends ~40 GET_CHANNEL requests at once) fits instead of overflowing fixed slots. RP2040 just switches to it.
Send logic unchanged. Settings now come from the shared header: 15-45 ms connection interval, slave latency 3, 5 s timeout (was 15-30 ms, 4, 2 s); slow advertising 211.25 ms (was 152.5 ms). When the receive queue is full, only the frame that doesn't fit is dropped instead of everything buffered. Also rejects a second connection and restarts the advertising watchdog timer on disconnect.
bleuart.write() waits up to 100 ms for one of the SoftDevice's 3 notification slots, which stalls LoRa handling (at SF7/500 kHz a packet is only 12-64 ms on air). Count notifications in flight, freed by HVN_TX_COMPLETE, and only write while a slot is free. The 250 ms backoff stays for other failures. Queues are now cleared from the main loop only: clearing them in the connect/disconnect callbacks could race a pop. RAK4631, 3 contact syncs plus command bursts: waits inside writes went from 131 (3.3 s total, longest 74 ms) to none.
Same Nordic UART service, static passkey with MITM and bonding. Old Bluedroid bonds are erased once, so phones have to re-pair. Notifications go out from the main loop without the old 60 ms gap, retrying after 10 ms when the stack is out of buffers. Connection parameters and the larger data length are requested once the link is secured, and writes without response are accepted. Includes a 1 s advertising check that works around NimBLE-Arduino <= 2.5.1 (h2zero/NimBLE-Arduino#1104); remove it once released.
NimBLE's notify() to a connection handle skips the CCCD check, so frames queued between pairing and subscription were lost. Send only once the phone has subscribed. Start our own MTU exchange and, once it has finished, drop frames too big for the MTU instead of waiting forever when it stays at 23.
Apple accessory guidelines 11.10: don't request pairing until an ATT request was rejected with Insufficient Authentication. NimBLE-Arduino sent a security request when the phone subscribed on an unencrypted link. The CCCD now needs an authenticated link, as on nRF52 with Bluefruit, so the phone's subscribe is rejected and the phone pairs. Guidelines 11.11: request the larger data length before the MTU exchange.
Contributor
Author
|
FYI this will allow setting "faster channel sync" without stalling on channel sync, thanks to the queue redesign |
Contributor
Author
|
A few numbers:
The RAM figures are static RAM only. Bluedroid also allocates a lot of heap when Bluetooth starts; I haven't measured that saving on hardware yet. On 4 MB boards that use |
This branch has not been deployed
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.
Revives #1277. Six commits, each one builds, so it's easiest to review commit by commit.
What
SerialBLECommon.h, shared by ESP32 / nRF52 / RP2040: UART UUIDs, connection and advertising parameters, the@@MACname helper, debug macros and a single-producer/single-consumer frame queue.GET_CHANNELwrites at once. That overflowed the old 12-slot queue, and channel sync froze at about 30 of 40 (currentdevon nRF52 does this too).bleuart.write()used to wait up to 100 ms, which is enough to drop LoRa packets on fast presets (SF7/500 kHz: 12–64 ms on air).Heads-up
ble_gatts_set_clt_cfg_perm_flags(), which isn't in NimBLE's public headers, to require an authenticated link for subscribing.Tested
dev.I only tested it on RAK and Xiao S3, so it needs further testing on other hardware and with other real life scenarios rather than pure bench testing.