fix(ble): keep auto-reconnect alive when the rescan fails - #66
Merged
Conversation
Auto-reconnect waits for an advertisement from the adapter's MAC before
retrying, but that wait sat outside the retry loop's try/catch:
while (isActive) {
waitForDevice() // <- unguarded
try { runObdSession(...) }
catch (e: Exception) { ...; delay(3_000) }
}
Any failure inside waitForDevice escapes the while loop entirely, runs the
finally, and terminates the connect() flow for good. Nothing is scanning
after that, yet the last status emitted was Scanning, so the device sits in
"scanning" forever and never reconnects — while a manual connect still works,
because that path starts a fresh job with skipScan=true and dials the MAC
directly instead of scanning. That matches the reported symptom exactly.
scanForMac can end without emitting (permission check returning early, or the
underlying scan flow completing or erroring after Android refuses another scan
start), and first() on an empty flow throws NoSuchElementException, so this is
reachable in normal use rather than only on a hard error.
Move waitForDevice inside the try in both the OBD and GATT-notify loops so a
scan failure is retried like any other session failure, and log the reason at
LINK level so the next occurrence is visible instead of silent. Also make the
missing-permission path in scanForMac throw SecurityException rather than
returning an empty flow, so the cause is named instead of surfacing as an
unrelated NoSuchElementException.
Co-Authored-By: Claude Opus 5 <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.
Auto-reconnect waits for an advertisement from the adapter's MAC before retrying, but that wait sat outside the retry loop's try/catch:
Any failure inside waitForDevice escapes the while loop entirely, runs the finally, and terminates the connect() flow for good. Nothing is scanning after that, yet the last status emitted was Scanning, so the device sits in "scanning" forever and never reconnects — while a manual connect still works, because that path starts a fresh job with skipScan=true and dials the MAC directly instead of scanning. That matches the reported symptom exactly.
scanForMac can end without emitting (permission check returning early, or the underlying scan flow completing or erroring after Android refuses another scan start), and first() on an empty flow throws NoSuchElementException, so this is reachable in normal use rather than only on a hard error.
Move waitForDevice inside the try in both the OBD and GATT-notify loops so a scan failure is retried like any other session failure, and log the reason at LINK level so the next occurrence is visible instead of silent. Also make the missing-permission path in scanForMac throw SecurityException rather than returning an empty flow, so the cause is named instead of surfacing as an unrelated NoSuchElementException.