带有 D-Bus BlueZ 的基本 BLE 客户端

Posted

技术标签:

【中文标题】带有 D-Bus BlueZ 的基本 BLE 客户端【英文标题】:Basic BLE client with D-Bus BlueZ 【发布时间】:2016-11-15 00:18:28 【问题描述】:

我正在使用(每个人都喜欢的)BlueZ 5.40 编译并运行具有实验性功能,我需要扫描 LE 设备,配对并连接到一个设备,并通过 D-Bus API 读取/写入特性。我研究了 hcitool、gatttool 和 bluetootctl 的来源,并使用 GDBus 做了一个基本的应用程序。但是,它有几个问题。

    扫描不添加 /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX obj。 org.bluez 总线的路径(使用 d-feet 检查)。考虑到它不是基于 D-Bus 的,这并不奇怪,但是当我使用 StartDiscovery 时,它根本没有检测到我的设备。 bluetoothctl 也没有。

之后,我使用 gatttool 和 simple-agent 作为解决方法来创建对象路径,然后使用我的程序进行连接,但我遇到了另一个问题:

    当我尝试读取特征时,我收到“连接已关闭 (18)”错误。我怀疑这与蓝牙设备之间的连接无关,它谈论的是 D-Bus 本身,因为当我尝试使用 SetDiscoveryFilter 仅为 LE 设备设置扫描过滤器时,我收到了同样的错误。

每当我只使用 Connect 和 Disconnect 功能时,一切似乎都运行良好,但用于此类应用程序的用途......有限。 所以我的问题是:

    如何使用 GDBus 扫描 LE 设备?如果不行,如何手动添加设备或说服蓝牙为我添加设备?

    如何正确读取特征?

代码在缩短之后还是比较长的,所以我把它放在了 pastebin 上: http://pastebin.com/YNLMF0qC. 用g++ -std=c++11 $(pkg-config --cflags glib-2.0 gobject-2.0 gio-2.0) ./main.cpp $(pkg-config --libs glib-2.0 gobject-2.0 gio-2.0 bluez)编译

【问题讨论】:

把代码放在这里。不是每个人都可以访问外部网站,而且它们可能不会像 *** 那样存在。 【参考方案1】:

终于搞定了。 1.最近被BlueZ 5.41解决了。我的设备是“可扫描的”,但不是“可发现的”。这意味着它广播了广告数据包,但因为它不允许没有 PIN 的连接来发现进一步的服务。在 BlueZ 5.41 中,如果您使用 SetDiscoveryFilter 设置任何过滤器,这些设备也会在扫描期间变得可见。这是对https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/adapter-api.txt 的最新补充(而且一点也不直观!):

设置发现过滤器后,设备对象将被创建为新的 发现具有匹配条件的设备,无论它们是 可连接或可发现,可监听不可连接 和不可发现的设备。

    纯粹是我的错误。正如我所说,我在 ReadValue 和 SetDiscoveryFilter 上遇到了同样的错误,但这个错误与 DBus 连接无关。这是由不正确的 GVariant 参数引起的。正确的形式是"(asv)" 而不是“(sv)”。例如 GVariant *args = g_variant_new_parsed("('Transport': <%s>,)", "le"); 用于 SetDiscoveryFilter 和 GVariant *args = g_variant_new_parsed("('offset': <%q>,)", offset); 工作正常。

【讨论】:

【参考方案2】:

您根本不应该使用 Bluez C 函数。而是使用较新的 GDBus 函数。在https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/adapter-api.txt,您可以了解如何扫描。调用 StartDiscovery。 DBus 设备将在被发现时添加。监听接口添加信号以检测新设备。你说没有检测到设备很奇怪,因为它应该可以工作。

ReadValue 方法应该可以工作。您在阅读时是否连接到设备?

还可以使用 hciconfig 检查 hci 层是否已启动。如果没有任何效果,您可以随时运行“sudo btmon”来捕捉正在发生的事情。

【讨论】:

是的,我已连接并且我的 hci 适配器已启动。正如我所说,我认为“未连接”错误是 DBus,与 BlueZ 无关。当我尝试使用 SetDiscoveryFilter 设置扫描过滤器时,我得到相同的错误。至于扫描,我将尝试使用 btmon 获得一些见解。感谢您对 GDBusObjectManager 的推动,但您确定我应该监听添加的接口而不是添加的对象吗?如果你愿意看,我会发布 DBus 扫描(~40 LOC)。 我不是很喜欢 BlueZ。如果您在这里没有得到更好的答案,您可以尝试在邮件列表bluez.org/development/lists 中提问。

以上是关于带有 D-Bus BlueZ 的基本 BLE 客户端的主要内容,如果未能解决你的问题,请参考以下文章

BlueZ D-Bus C,应用程序BLE

Python+D-Bus+BlueZ 5:无法读取对象的属性?

使用 d-bus 在 C.H.I.P 上使用 bluez 5.43 更改音量

Bluez BLE 连接监控使用 DBUS-Python

蓝牙问题使用 D-Bus (qdbus) 发送 AVRCP 卷更改发送与 org.bluez.MediaTransport1

主动 BLE 扫描 (BlueZ) - DBus 问题