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

corebluetooth: work around macOS 12 scanner bug #692

Merged
merged 6 commits into from
Dec 7, 2021
Merged

Conversation

dlech
Copy link
Collaborator

@dlech dlech commented Nov 27, 2021

macOS has a bug (feature?) where advertising data is no longer received unless one or more service UUIDs are given in scanForPeripheralsWithServices:options:.

This implements a new kwarg on BleakScanner to allow users to provide such a list of UUIDs. This commit only implements it in the CoreBluetooth backend with other backends to follow.

If macOS 12 is detected and this kwarg is not given, an error will be logged explaining how to fix the problem.

Fixes #635.

@hbldh
Copy link
Owner

hbldh commented Nov 27, 2021

This is great, but a sad state of affairs that it is needed. I was wrong in my comment in the issue then: there was a workaround that was reasonable...

It does require prior knowledge of the device though, or could you pass e.g. Device Information service uuid if nothing is sent in in Bleak and get all devices anyway? The DI is always present, or am I wrong again? 🤔

@dlech
Copy link
Collaborator Author

dlech commented Nov 27, 2021

The DI is always present, or am I wrong again?

The services have to be specifically included in the advertising data, so if a device advertises no services, we won't be able to connect.

The Accessory Design Guidelines for Apple Devices specifically says:

The accessory shall implement the Device Information Service. The service UUID for this service should not be advertised in the Advertising Data

So I'm afraid you are wrong about counting on the DI service.

@dlech dlech force-pushed the macos12-scanning branch 2 times, most recently from 597600c to 993f1bf Compare November 27, 2021 23:54
@dlech
Copy link
Collaborator Author

dlech commented Nov 27, 2021

All platforms have been implemented now. Incidentally, this also fixes #230.

@dlech dlech linked an issue Nov 27, 2021 that may be closed by this pull request
@bri3d
Copy link

bri3d commented Nov 29, 2021

Unless I'm missing something, this doesn't fix find_device_by_address and by proxy the use of connect with a string device identifier on Mac OS 12, because there's no way to send the new kwarg through that call chain.

@dlech
Copy link
Collaborator Author

dlech commented Nov 29, 2021

The kwargs from find_device_by_address are passed through to the BleakScanner constructor, so that should work with the new service_uuids kwarg.

Using async with BleakClient(address) as client: won't work currently though as you have pointed out. I suppose we could add a scanner_args kwarg there to pass to the scanner. Or maybe we should consider deprecating/discouraging that use - it seems like a good number of issues are resolved by advising people to use a separate BleakScanner object for scanning, so if that was only/recommended way to do it, we could save people some trouble.

@bri3d
Copy link

bri3d commented Nov 29, 2021

From my standpoint as a user, I don't see any reason not to deprecate that use - switching my project away from it was trivial and I agree there are wins there. 👍

dlech and others added 6 commits December 5, 2021 18:13
macOS has a bug (feature?) where advertising data is no longer received unless one
or more service UUIDs are given in scanForPeripheralsWithServices:options:.

This implements a new kwarg on `BleakScanner` to allow users to provide
such a list of UUIDs. This commit only implements it in the CoreBluetooth
backend with other backends to follow.

Issue #635.
This implements the service_uuids kwarg in BleakScanner in the BlueZ backend.
This changes set_scanning_filter in the Android backend to raise
NotImplementedError since it is not implemented. Also remove async
specifier since this is not supposed to be an async function.
This implements the BleakScanner service_uuids kwarg in the Android backend.
This changes how advertising data is cached and combined. Previously,
we just cached scan response data to get the local name later. Separate
callbacks were called for advertising data and scan response data which
makes more work for users who are interested in filtering on data that
is split between the two packets.

Now, the advertising data and scan response data are both cached together
as a single object and this object is used to create the Bleak advertising
data structure so that the advertising data seen by Bleak users now
contains the information from both advertising data type combined.
This provides an implementation for the BleakScanner service_uuids
kwarg in the WinRT backend. As explained in the code comment, it is
not possible to use the OS-provided filter mechanism for technical
reasons.

Fixes #230
@challiwill
Copy link

What is the path to get this merged to master? I have been using it and it has been working for me.

@dlech dlech merged commit b644ae2 into develop Dec 7, 2021
@dlech dlech deleted the macos12-scanning branch December 7, 2021 18:44
@ph4r05
Copy link

ph4r05 commented Dec 8, 2021

Is there pls any estimate on when this PR (currently develop branch) gets to a new release on pipy? Thanks

@elupus
Copy link
Contributor

elupus commented Jan 4, 2022

How does this work with manufacturer data? They seem to come as separate announcements from the list of services? Will the scanner still get these manufacturer data if the device at least once announce a selected service?

@dlech
Copy link
Collaborator Author

dlech commented Jan 4, 2022

MacOS combines the information from the advertising data packet and scan response packet so I don't expect any problems in that regard.

@elupus
Copy link
Contributor

elupus commented Jan 4, 2022

I can confirm that it seem to work. Seams to take a bit longer for first manufacturer data to show up, but no issue otherwise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backend: Core Bluetooth Issues and PRs relating to the Core Bluetooth backend
Projects
None yet
Development

Successfully merging this pull request may close these issues.

No results when scanning on MacOS 12 Scan peripherals and filter by service UUID
6 participants