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

Posted

技术标签:

【中文标题】使用 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 【发布时间】:2014-08-24 14:19:57 【问题描述】:

我正在尝试使用 BlueZ 4.X DBus 接口在 Linux 上建立与蓝牙 4.0 LE 设备的连接。

为了测试这一点,我使用以下命令:

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

这个命令似乎大多数时候都有效,结果如下:

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

让我能够与设备 DBus 对象进行交互。

但是,从昨天开始,这似乎经常失败,返回以下错误:

Error org.bluez.Error.Failed: Operation canceled

在调试蓝牙守护进程时,(使用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

据我所知,当我尝试连接到设备时,我的蓝牙加密狗向我发送了一个错误事件(状态 4)。

但是,当我使用 hcitool ot gatttool 连接到设备时,一切正常。

我发现这主要发生在我尝试使用不同的程序(即 cinnamon-settings)连接到设备并过早取消连接之后。我还注意到其他程序,如 Angstrom 上的蓝牙属性。

我的猜测是 Bluez 在某些情况下向我的蓝牙加密狗发送了错误的 HCI 命令。我认为这是因为 gui 程序尝试与设备配对而不是仅仅连接到它,这可能导致 BlueZ 认为我的设备是蓝牙 2.0 设备。

到目前为止,我似乎能够通过使用 gui 应用程序连接到我的 BT 设备,等到它失败,然后重新启动我的计算机来解决这个问题。但是,这个问题似乎偶尔会再次出现,这让这非常痛苦。

我在同时运行 BlueZ 版本 4.99 和 4.101 的系统上看到了这个问题。

有谁知道我该如何正确解决这个问题?

【问题讨论】:

【参考方案1】:

我的预测似乎或多或少是正确的。经过数小时的蓝牙守护程序调试后,我发现在没有进行初步扫描的情况下连接到 BT LE 设备会导致守护程序尝试将设备作为 BR/EDR 设备连接到设备。这是因为在发现设备时,守护进程的“内部缓存”填充了EIR 信息。如果在连接到 LE 设备时此信息不可用,则 CreateDevice 方法将失败。

一个简单的解决方案是始终确保在连接到设备之前发现它们。

BlueZ 5 API introduction and porting guide 也描述了这个问题,以及它在 BlueZ 5 中是如何解决的:

Bluetooth Low Energy 本质上是用一个额外的位扩展了蓝牙地址,要求始终知道地址是“随机”还是“公共”。这导致 BlueZ 4 API 出现问题,在 CreateDevice 和 CreatePairedDevice 调用中将地址提供给 BlueZ。由于该参数不包含任何这些额外的随机/公共信息,蓝牙必须维护一个内部缓存来查找必要的信息。问题的另一个复杂之处在于,BlueZ D-Bus API 不区分传统的 BR/EDR 设备和 LE 设备,因此基本上存在三种可能的地址类型:BR/EDR、LE 公共和 LE 随机。

【讨论】:

以上是关于使用 org.bluez.Adapter.CreateDevice 连接到 BT LE 设备失败并出现 org.bluez.Error.Failed:操作取消错误的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)