我正在尝试使用BlueZ 4.X DBus接口在Linux上建立与Bluetooth 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连接到设备时,一切都运行良好。
我发现这种情况主要发生在我尝试使用不同的程序(即肉桂设置)连接到设备后,并提前取消连接。我也注意到了其他程序,如Angstrom上的蓝牙属性。
我的猜测是Bluez在某些条件下将错误的HCI命令发送到我的蓝牙加密狗。我认为这是因为gui程序试图与设备配对而不是仅仅连接它,这可能导致BlueZ认为我的设备是蓝牙2.0设备。
到目前为止,我似乎能够通过使用gui应用程序连接到我的BT设备,等待它失败并重新启动计算机来解决此问题。然而,问题似乎偶尔会再次出现,这使得这非常痛苦。
我在运行BlueZ版本4.99和4.101的系统上看到了这个问题。
有谁知道我怎么能正确解决这个问题?
答案 0 :(得分:2)
似乎我的预测或多或少是正确的。经过几个小时的蓝牙守护程序调试后,我发现在没有初步扫描的情况下连接BT LE设备会导致守护程序尝试作为BR / EDR设备连接到设备。这是因为守护进程的内部缓存&#34;在发现设备时填充EIR信息。如果在连接到LE设备时此信息不可用,则CreateDevice方法将失败。
一个简单的解决方案是始终确保在连接设备之前发现它们。
BlueZ 5 API introduction and porting guide也描述了这个问题,以及它如何在BlueZ 5中解决:
Bluetooth Low Energy本质上通过一个额外的位扩展蓝牙地址,要求人们始终知道地址是“随机”还是“公共”。这导致了BlueZ 4 API的问题,其中在CreateDevice和CreatePairedDevice调用中将地址提供给BlueZ。由于参数不包含任何这些额外的随机/公共信息,因此bluetoothd必须维护内部缓存以查找必要的信息。另一个问题是BlueZ D-Bus API没有区分传统的BR / EDR设备和LE设备,因此基本上有三种可能的地址类型:BR / EDR,LE public和LE random。