fix(hal): keep what a BLE scan discovers, and find a device by its service - #142
Merged
Conversation
…rvice
From the bench: GLIDER's scan named a lab chair and never named the Maimu,
while nRF Connect showed it fine. The scan was not missing the device -- it was
discarding what identifies it. A peripheral advertising no usable name came
back as ("(unknown)", address) and appeared in the picker as a bare MAC among
other bare MACs, which is indistinguishable from not being there.
Zephyr devices put their name in the SCAN RESPONSE, and Windows drops that
often enough that a working stimulator routinely appears nameless. So the scan
now keeps the two things that identify one anyway: the advertised service UUIDs
and the RSSI. Results are sorted strongest-first, the picker shows signal
strength beside the address, and the services go in the tooltip -- which is how
you tell which bare MAC is the stimulator you are holding.
An empty name stays empty rather than becoming the string "(unknown)", so a
caller can tell a nameless peripheral from one that is genuinely named that.
BLEDevice can now resolve by service UUID as a last resort, after the address
and the advertised name. It is the sturdiest identifier available: unlike a
resolvable private address it does not rotate, and unlike a name it does not
depend on a scan response surviving the trip. The Maimu's settings carry its
service UUID already, so this costs its users no configuration.
It refuses to guess. When several peripherals advertise the service -- six
identical stimulators on a bench is the normal case, not an exotic one -- it
logs what it saw and declines, because connecting to whichever answered first
would be the wrong animal's. A configured name is tried first for the same
reason: a name identifies one unit, a service UUID identifies a model.
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.
Stacked on #141 — retarget to
mainonce that lands.From the bench: GLIDER's scan named a lab chair and never named the Maimu, while nRF Connect showed it fine.
The scan wasn't missing it — it was throwing away what identifies it
A peripheral advertising no usable name came back as
("(unknown)", address)and appeared in the picker as a bare MAC among other bare MACs. That is indistinguishable from not being there, which is exactly how it looked.Zephyr devices put their name in the scan response, and Windows drops that often enough that a working stimulator routinely appears nameless. The
ble_boarddocstring already knew this; the code just discarded everything that would have let you identify one anyway.What the scan keeps now
Results sort strongest-first, the picker shows signal strength beside the address, and services go in the tooltip. An empty name now stays empty rather than becoming the literal string
"(unknown)", so callers can tell nameless from named "(unknown)".Finding a device by its service
BLEDeviceresolves by service UUID as a last resort, after address and advertised name. It's the sturdiest identifier available: unlike a resolvable private address it doesn't rotate (#141), and unlike a name it doesn't depend on a scan response surviving the trip.The Maimu's settings already carry its service UUID, so this costs its users no configuration at all.
It refuses to guess. When several peripherals advertise the service — six identical stimulators on a bench is the normal case, not an exotic one — it logs what it saw and declines, because connecting to whichever answered first would be the wrong animal's. A configured name is tried first for the same reason: a name identifies one unit, a service UUID identifies a model.
Tests — 10 new
Scan: each peripheral reported; an unnamed one labelled by address; the label carrying signal strength; strongest-first ordering; service UUIDs kept and matched case-insensitively (advertisements and config disagree on case routinely).
Device: a nameless peripheral found by its service after a stale address; several matches refused rather than guessed; and the name preferred over the service when both are configured, asserting the service scan never even runs.
Verification
PYTHONPATH=src QT_QPA_PLATFORM=offscreen pytest tests/— 3648 passed, 4 skipped, ruff and black clean.