Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backends/scanner: add handle_early_stop hooks #1146

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

dlech
Copy link
Collaborator

@dlech dlech commented Nov 25, 2022

This is inspired by #1140 (comment). Quite a long time ago, I noticed that we weren't really handling scanner stop events when a scanner stops before we actually request it to. (This is somewhat similar to how we have a disconnect event for devices except in that case, the callback is called even if we requested the disconnect or not.) There haven't been any reported problems due to not having such a feature until now, so it has never been addressed until now.

So far, this PR just implements the platform-specific parts to call a common scanner backend method when an unrequested scanner stop event occurs. The idea is to use this as part of the context manager so that it will cancel the task if an early stop happens.

async with BleakScanner():
    await asyncio.sleep(10)  # BleakError("scanner stopped early") will be raised here
    # e.g. if something unexpected happened, like Bluetooth is turned off

We probably also need some sort of API for anyone using start and stop without a context manager (although maybe we don't want to support this and require a context manager if you want the callback to do something?).

Code hasn't been tested yet on any platform, so expect bugs.

cc: @bojanpotocnik

@dlech dlech force-pushed the scanner-early-stop-hook branch 3 times, most recently from f0f69f4 to 2e47a54 Compare November 26, 2022 00:03
@dlech
Copy link
Collaborator Author

dlech commented Nov 26, 2022

This has now been tested on Windows, Linux and Mac. It is working as expected (when used with #1147 and #1148). The test case is running the discover.py example and turning off Bluetooth before the scan stops. I replaced the ... implementation of handle_early_stop() with a print to see if it ran.

In the case of Linux with passive scanning, it is not working because "Release" of the advertisement watcher is not called. I think this could be considered a bug in BlueZ (the advertisement watcher is still experimental after all) since "Release" is called on other errors. It seems like Release should be called if the adapter is powered off or disappears.

Release was called as expected when I gave bad args for or_patterns so it does seem to be working as expected for cases other than adapter power off. (although for this particular case, we should check the type of the args in __init__ to avoid this altogether, but that is a separate issue #1149).

All supported platforms provide some sort of hook that we can use to
get a callback when scanning stops. On Mac and Linux, there is only a
simple boolean value indicating if scanning is currently in progress.
Windows and Android provide additional error information, but this
is ignored for now since it isn't available cross-platform.

What we actually do with this hook is not yet implemented.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant