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

Advertised UUIDs are erased on subsequent calls to CentralDelegateManager scanner callback #329

Closed
adamincera opened this issue Oct 9, 2020 · 1 comment
Labels
Backend: Core Bluetooth Issues and PRs relating to the Core Bluetooth backend bug Something isn't working

Comments

@adamincera
Copy link
Contributor

  • bleak version: 0.8.0
  • Python version: 3.8.5
  • Operating System: macOS 10.15.7
  • BlueZ version (bluetoothctl -v) in case of Linux: N/A

Description

When calling BleakScanner.discover() on macOS, devices which advertise service UUIDs are returned with device.metadata["uuids"] empty. For each of these devices, multiple calls are made to CentralManagerDelegate.did_discover_peripheral(). Each call to this function calls the following function, callback(), defined inside BleakScannerCoreBluetooth.start():

     def callback(p, a, r):
            self._identifiers[p.identifier()] = a
            if self._callback:
                self._callback(p, a, r)

If callback() is called multiple times, self._identifiers[p.identifier()] will only contain the advertising data a passed in on the final call.

Proposed Solution

I was able to fix the issue for my use case by changing callback() to the following:

       def callback(p, a, r):
            if p.identifier() in self._identifiers:
                self._identifiers[p.identifier()] = {**a, **self._identifiers[p.identifier()]}
            else:
                self._identifiers[p.identifier()] = a
            if self._callback:
                self._callback(p, a, r)

This change merges the advertising data objects according to the method described in this stackoverflow post. However, I am not familiar enough with this library to know if this could cause other adverse effects. Please let me know if this solution makes sense, or how I should test it.

@dlech dlech added Backend: Core Bluetooth Issues and PRs relating to the Core Bluetooth backend bug Something isn't working labels Oct 9, 2020
@dlech
Copy link
Collaborator

dlech commented Oct 9, 2020

I think this makes sense.

The dictionary update could probably be simplified to this:

self._identifiers.setdefault(p.identifier(), {}).update(a)

To test it, you could log the individual a dictionaries to see that they are indeed different (not all have the same keys) and then log the combined result to make sure it keeps the old data and updates the new/changed data.

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 bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants