简体   繁体   English

使用org.bluez.Adapter.CreateDevice连接到BT LE设备失败,并出现org.bluez.Error.Failed:操作取消错误

[英]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. 我正在尝试使用BlueZ 4.X DBus接口在Linux上建立到Bluetooth 4.0 LE设备的连接。

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. 并使我能够与设备DBus对象进行交互。

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 -n -d ),在执行方法调用时,我注意到以下几点:

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. 据我所知,当我尝试连接到设备时,蓝牙加密狗向我发送了一个错误事件(状态4)。

However, when I use hcitool ot gatttool to connect to the device, everything works perfectly. 但是,当我使用hcitool或gatttool连接到设备时,一切运行正常。

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. 我还注意到了其他程序,例如Angstrom上的bluetooth-properties。

My guess is that Bluez sends the wrong HCI commands to my bluetooth dongle in certain conditions. 我的猜测是,Bluez在某些情况下会将错误的HCI命令发送到我的蓝牙加密狗。 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. 我认为这是因为gui程序尝试与设备配对而不是仅与设备配对,这可能会使BlueZ认为我的设备是Bluetooth 2.0设备。

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. 到目前为止,我似乎可以通过使用gui应用程序连接到BT设备,等到失败后再重新启动计算机来解决此问题。 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. 我在同时运行BlueZ版本4.99和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. 在对蓝牙守护程序进行了许多小时的调试之后,我发现在没有进行初步扫描的情况下连接到BT LE设备会导致该守护程序尝试将其作为BR / EDR设备连接到该设备。 This is because the daemon's "internal cache" is filled with the EIR information at the time the device is discovered. 这是因为在发现设备时,守护进程的“内部缓存”已填充有EIR信息。 If this information is not available when connecting to a LE device the CreateDevice method will fail. 如果连接到LE设备时此信息不可用,则CreateDevice方法将失败。

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: BlueZ 5 API的介绍和移植指南还描述了此问题,以及如何在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. 这导致了BlueZ 4 API的问题,其中在CreateDevice和CreatePairedDevice调用中将地址分配给了BlueZ。 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. 问题的另一个复杂之处在于,BlueZ D-Bus API无法在传统的BR / EDR设备和LE设备之间进行区分,因此本质上存在三种可能的地址类型:BR / EDR,LE public和LE random。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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