简体   繁体   中英

Connecting to BT LE device using org.bluez.Adapter.CreateDevice fails with org.bluez.Error.Failed: Operation canceled Error

I'm trying to set up a connection to a Bluetooth 4.0 LE device on Linux using the BlueZ 4.X DBus interface.

To test this I use the following command:

dbus-send --system --dest=org.bluez --print-reply /org/bluez/<PID of bluetoothd>/hci0 org.bluez.Adapter.CreateDevice string:<MAC of BT device>

This command seems to work most times, giving a result like:

method return sender=:1.238 -> dest=:1.262 reply_serial=2
   object path "/org/bluez/9652/hci1/dev_BC_6A_29_26_C2_1C"

and enabling me to interact with the device DBus object.

However, starting from yesterday, this seems to fail very frequently returning the following error:

Error org.bluez.Error.Failed: Operation canceled

When debugging the bluetooth daemon, (using bluetoothd -n -d ) I notice the following things when executing the method call:

bluetoothd[340]: src/adapter.c:create_device() BC:6A:29:26:C2:1C
bluetoothd[340]: src/adapter.c:adapter_create_device() BC:6A:29:26:C2:1C
bluetoothd[340]: src/device.c:device_create() Creating device /org/bluez/340/hci0/dev_BC_6A_29_26_C2_1C
bluetoothd[340]: src/device.c:btd_device_ref() 0xb7ad8: ref=1
bluetoothd[340]: src/device.c:device_set_temporary() temporary 1
bluetoothd[340]: src/device.c:btd_device_ref() 0xb7ad8: ref=2
bluetoothd[340]: plugins/mgmtops.c:mgmt_event() cond 1
bluetoothd[340]: plugins/mgmtops.c:mgmt_event() Received 14 bytes from management socket
bluetoothd[340]: plugins/mgmtops.c:mgmt_connect_failed() hci0 BC:6A:29:26:C2:1C status 4
bluetoothd[340]: src/event.c:btd_event_conn_failed() status 0x04
bluetoothd[340]: src/device.c:device_remove() Removing device /org/bluez/340/hci0/dev_BC_6A_29_26_C2_1C
bluetoothd[340]: src/device.c:device_set_temporary() temporary 1
bluetoothd[340]: src/device.c:btd_device_unref() 0xb7ad8: ref=1
bluetoothd[340]: src/device.c:btd_device_unref() 0xb7ad8: ref=0
bluetoothd[340]: src/device.c:device_free() 0xb7ad8

As far as I can see, my Bluetooth dongle sends me an error event (status 4) when I try to connect to the device.

However, when I use hcitool ot gatttool to connect to the device, everything works perfectly.

I found that this happens mostly after I try to connect to the device using a different program (ie cinnamon-settings), and cancel the connection prematurely. I also noticed this with other programs like bluetooth-properties on Angstrom.

My guess is that Bluez sends the wrong HCI commands to my bluetooth dongle in certain conditions. I think this is because the gui programs try to pair with the device instead of just connecting to it, which may cause BlueZ to think my device is a Bluetooth 2.0 device.

Thus far I seemed to be able to resolve this problem by connecting to my BT device using a gui application, waiting till it fails, and restarting my computer. However, the problem seems to reoccur occasionally, making this very painful.

I have seen this problem on systems running both BlueZ version 4.99 and 4.101.

Does anyone know how I can solve this correctly?

It seems like my predictions where more or less correct. After many hours of debugging the Bluetooth daemon I discovered that connecting to BT LE devices without a preliminary scan causes the daemon to try to connect to the device as a BR/EDR device. This is because the daemon's "internal cache" is filled with the EIR information at the time the device is discovered. If this information is not available when connecting to a LE device the CreateDevice method will fail.

A simple solution is to always make sure to discover devices before connecting to them.

The BlueZ 5 API introduction and porting guide also describes this problem, and how it is solved in BlueZ 5:

Bluetooth Low Energy essentially extended Bluetooth addresses with one extra bit, requiring one to always know whether an address is “random” or “public”. This caused issues with the BlueZ 4 API where the address was given to BlueZ in the CreateDevice and CreatePairedDevice calls. Since the parameter didn't contain any of this extra random/public information bluetoothd had to maintain an internal cache to look up the necessary info. Another complication to the matter is that the BlueZ D-Bus API doesn't differentiate between traditional BR/EDR devices and LE devices so there are essentially three possible address types: BR/EDR, LE public and LE random.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM