Auto-reconnect on unexpected BLE disconnect#81
Open
dgkanatsios wants to merge 1 commit into
Open
Conversation
The BLE provider never listened for the Web Bluetooth
`gattserverdisconnected` event, so when the Spark dropped its BLE
link the app would keep `isConnected = true`, the UI would still
report "connected", and every subsequent command silently failed.
This change wires up a disconnect-detection + single-attempt
auto-reconnect path while keeping the existing manual connect/
disconnect flow untouched.
Behavior:
* BleProvider attaches a `gattserverdisconnected` listener after
services are wired up. On unexpected drop it tears down local
state, detaches the notification listener, clears the receive/
send queues, fails any pending ack waiters, and invokes
`onDisconnected`.
* A new `intentionalDisconnect` flag plus listener removal in
`disconnect()` keeps user-initiated disconnects from triggering
the auto-reconnect path.
* `BleProvider.reconnect()` re-uses the cached `BluetoothDevice`
handle and re-runs service discovery, so the user is not
re-prompted with the device picker.
* `SparkDeviceManager` exposes `onConnectionLost` and `reconnect()`
and now tracks its receive-loop `setInterval` id so reconnect
cycles don't stack additional 50ms intervals.
* `DeviceContext` reacts to connection loss by emitting a
'disconnected' event to the UI and kicking off a single
`attemptReconnect()` after a 1.5s settle delay. A monotonic
`reconnectGeneration` token cancels stale attempts when the
user takes a competing action (manual scan/connect) so the
UI state is not clobbered by a superseded attempt.
* `DeviceViewModel` handles the new 'disconnected' /
'reconnecting' events alongside the existing 'connected' /
'failed' ones; the status dot now reflects reality.
Correctness fixes uncovered during review:
* `connect()` previously left `isConnected = true` if service
discovery failed after the GATT link was up. A later reconnect
would short-circuit and report success against an unusable
connection. Now rolled back fully on failure.
* `beginQueuedReceive()` registered an anonymous
`characteristicvaluechanged` listener with no removal path,
leaking across reconnects. The bound listener and its target
characteristic are now tracked and removed on every disconnect.
* `write()` set `isSendQueueProcessing = true` without a
`try/finally`, so a write that threw (e.g. mid-drop) would
leave the queue permanently "processing" and stall all future
commands. Now wrapped in try/finally.
* `SparkDeviceManager.startReceiver()` called `setInterval` with
no reference, so every reconnect would add another loop on top
of the existing one. The interval handle is now stored and
cleared on disconnect/reconnect.
Out of scope (intentional follow-ups):
* Multi-attempt backoff (currently exactly one auto-attempt).
* Aborting an in-flight Spark 2 chunked preset upload when the
underlying BLE link drops mid-upload.
* Heartbeat-based liveness for stalls that don't fire
`gattserverdisconnected` (some Windows BLE stacks).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Author
|
Also tested it with my Spark Go (connect, disconnect, reconnect) and it works OK. |
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.
Thanks a ton for this app! Just tried it on my Spark 2 and the connection was dropped after a while, so I crafted this PR (with AI's help) to mitigate the issue. Tried it on Windows during my guitar class now (1 hour) and there were 0 disconnects. I also tried the "turn off/on Spark 2" scenario and it reconnected successfully.