BLE workflow: add a guard service so user-created services don't break the web editor - #11333
Open
dhalbert wants to merge 1 commit into
Open
BLE workflow: add a guard service so user-created services don't break the web editor#11333dhalbert wants to merge 1 commit into
dhalbert wants to merge 1 commit into
Conversation
A peripheral reports its last primary service with End Group Handle 0xffff, and hosts cache that literally. A service that user code adds later lands inside that cached range, so hosts treat it as a change to the last workflow service: Chrome invalidates the page's object for it with no event to say so, and BlueZ drops it from its cache. On every host the web editor's REPL terminal went dead as soon as user code created a `_bleio.Service`. Create a placeholder service after the file transfer and serial services so that it, not a workflow service, is the one affected. Verified on nordic and espressif against BlueZ, CoreBluetooth and WinRT. Also move `circuitpython_base_uuid` from `serial.c` to `bluetooth.c`, since the guard uses it too, and factor the repeated `CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE` into `BLE_WORKFLOW`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Diagnosis by Claude and @dhalbert. Code by Claude with refactoring and comment rewrites by @dhalbert. PR post by Claude with considerable editing by @dhalbert.
Problem
Creating a
_bleio.Servicefrom user code while the web editor is connected hung the editor's REPL terminal on Linux, macOS and Windows. File transfer kept working. The problem is that a peripheral reports its last primary service with End Group Handle0xffff, and hosts cache that literally, with the0xffff. When BLE workflow is on, two services are added: File and Serial. The Serial Service then is recorded by the host with0xffffas its ending handle.If CircuitPython user code adds another service, the start and end handles will fall inside the cached handle range for the Serial Service, since
0xffffincludes everything. The host then treats the addition as a change to the Serial Service, since the new handles fall inside the range it cached for it.Because the Serial Service handle range changed, Chrome invalidates its service object, and the terminal stops working. (Also there's no Web Bluetooth event provided by Chrome to report that.) In addition, BlueZ (used by Linux) has a bug that drops the service from its cache until a real link-level reconnect.
The serial service was affected only because it was created last. If the file and serial services were reversed, it would have been the file service (verified by testing).
Fix
adaf0004, one read-only characteristicadaf0005, three handles) after the file transfer and serial services insupervisor_start_bluetooth(). This is the service a later user-created service will overlap.circuitpython_base_uuidfromserial.ctobluetooth.c, since the guard uses it too.bluetooth.c.Testing
Tested Feather nRF52840 Express and Metro ESP32-S3, using code.circuitpython.org in Chrome, on Linux, macOS and Windows:
importa file that creates a Battery Service.Before the change the terminal died on all three hosts; after it both keep working.
btmonlogs confirmed the guard is the service the hosts discard and the new service is placed after it.Ctrl-D after creating a user service still drops the BLE connection. That is a pre-existing problem: you have to reconnect. But now you can do that successfully.