gatt-python icon indicating copy to clipboard operation
gatt-python copied to clipboard

Passive scan feature

Open Snevzor opened this issue 7 years ago • 9 comments

Hi!

I would need a passive scan function to get the RSSI values from advertisement data at a relative high rate (like hcitool lescan --passive). The discover function is way too slow for this.

Is this even supported by the dbus API? I don't know where to start.

Best regards

Snevzor avatar Jan 09 '18 15:01 Snevzor

Hello,

You are correct that there is currently no support in the DBus API to select scanning in passive versus active mode.

Historically the issue with the DBus API has been that it did not support reporting duplicate advertisements from devices meaning that there was no updates when the RSSI changed. As of BlueZ 5.47 duplicates are now supported in the DBus API: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt?h=5.47#n107

ukBaz avatar Jan 09 '18 16:01 ukBaz

Thanks for the fast and clear response!

So if I understand correct, with BlueZ 5.47 I can get updates when RSSI changes but it is still active scanning only?

In that case I might need to resort to gatt-python + something like aioblescan.

Snevzor avatar Jan 10 '18 08:01 Snevzor

So if I understand correct, with BlueZ 5.47 I can get updates when RSSI changes but it is still active scanning only?

While I haven't tested it myself, that would be my expectation from following the conversation on the BlueZ mailing list.

In that case I might need to resort to gatt-python + something like aioblescan

I have found aioblescan very good for detecting beacons. The only downside is that it needs to run as root because it is using HCI/sockets.

ukBaz avatar Jan 10 '18 08:01 ukBaz

Thanks @ukBaz! Unfortunately it seems that gatt-python requires devices to be 'discovered' first to be able to connect. They are not 'discovered' when scanned by hcitool or aioblescan. Maybe you've stumbled upon this as well?

Snevzor avatar Jan 16 '18 17:01 Snevzor

I have not mixed and matched libraries so have not seen the problem directly. Given what I understand about the two libraries your findings do not surprise me.

This is getting to the edge of my knowledge so please treat the information below with some caution...

The BlueZ architecture is split between the Linux kernel and user space. The raw HCI socket connection used by aioblescan is controlling the Linux kernel directly The DBus API allows the user space (through bluetoothd) to control the kernel. bluetoothd adds a lot of flow control and status tracking to assist users. If devices are discovered with raw HCI socket commands then my assumption is that bluetoothd does not get updated to know about them

There is another BlueZ API called Bluetooth Management interface (mgmt) that operates in the user space but is more HCI socket like. It is not possible to access the mgmt API using Python. The problem seems to be that the current Python socket module doesn't let you get at it. The relevant code appears to be in makesockaddr() in CPython's socketmodule.c - see https://github.com/python/cpython/blob/master/Modules/socketmodule.c#L1276. It only ever seems to set the dev and bdaddr members, leaving the hci_channel field set to 0 (HCI_CHANNEL_RAW).

There is a presentation called "Bluetooth on modern Linux" that has more information about the BlueZ architecture: slides: https://elinux.org/images/8/89/Janc.pdf video: https://youtu.be/tclS9arLFzk

ukBaz avatar Jan 17 '18 09:01 ukBaz

I've just read the presentation and tested with btmgt before reading your latest comment, so we are on the same track!

btmgt indeed seems to be more HCI socket like and the devices that get discovered using this tool can again not be accessed with bluetoothd unfortunatately. It's a pity that btmgmt cannot be accessed using Python, that would have been my next search.

I'm convinced in the whole bluetoothd + dbus story but I also really need to have passive scanning functionality. Currently we are using HCI stuff and that can really not be considered stable.

Snevzor avatar Jan 17 '18 09:01 Snevzor

Maybe worth getting in contact with the developers of BlueZ directly to ask the question about how to solve the issue you are having with the DBus API? http://www.bluez.org/contact/

ukBaz avatar Jan 17 '18 10:01 ukBaz

I've talked with the author of https://elinux.org/images/8/89/Janc.pdf at #bluez-users on freenode. He confirmed that indeed the current D-Bus API does not support passive scanning for discovery. Passive scanning is only used for connection creation. (Apparently even if this is added to BlueZ now, it appears that the kernel is not exposing this enough.)

Basically, it is unlikely that we'll see passive scanning in gatt-python any time soon.

Snevzor avatar Jan 18 '18 08:01 Snevzor

But is there any way to get RSSI-values from a connected device using gatt-python?

JlnWntr avatar Nov 27 '18 13:11 JlnWntr