使用Bluez的C/C++ BLE读写示例

12

我正在开始使用微控制器和树莓派(tardis BLE dongle)构建一个简单的BLE网络。作为起点,我正在寻找一个简单的C或C++示例来读写BLE设备,类似于我在命令行上能够执行的操作。到目前为止,我发现的示例都相当复杂。作为一个BLE初学者,在进一步设计之前,我需要一些非常简单的示例来构建基础。我可以像在下面的gatttool示例中那样将BLE设备名称硬编码。

以下是我当前如何使用Bluez命令行选项:

从命令行中,我可以使用:

$ sudo hcitool lescan
LE Scan ...
BB:A0:50:02:18:07 MyDevice

接下来,我可以使用gatttool在命令行上连接到设备:

$ sudo gatttol -b BB:A0:50:02:18:07 -I
[BB:A0:50:02:18:07][LE]> connect
Attempting to connect to BB:A0:50:02:18:07
Connection successful

最后我能够使用适当的句柄进行阅读和写作

[BB:A0:50:02:18:07][LE]> char-write-req 000f 0100
Characteristic value was written successfully
[BB:A0:50:02:18:07][LE]> char-write-cmd 0011 4C467A

我用于初步研究和入门的一些网站:
http://people.csail.mit.edu/albert/bluez-intro/c404.html
https://github.com/carsonmcdonald/bluez-experiments/blob/master/experiments/scantest.c


你也可以查看最新版本的Bluez(自5.29以来)发布的最新DBUS GATT API。虽然仍处于实验阶段,但我已经进行了一些测试,它运行得相当不错。当然,性能可能会比直接访问bluez库稍低,但我认为值得一试... - Jorge Martinez
2个回答

8
Bluez(Linux官方蓝牙堆栈)已经转向使用DBUS作为其API。过去,人们通常“分叉”bluez代码来访问Linux上的BLE支持,但现在的方法是使用DBUS。 Bluez DBUS API的文档在此处:https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc 您可以直接使用DBUS与蓝牙C / C ++应用程序进行通信,也可以使用GATT库作为辅助工具。对于初学者来说,第二种方法可能是最好的选择(也适用于非初学者,他们希望保持其程序的Bluez不可知性,例如支持其他操作系统或Bluez pre-DBUS API或使其源更易读)。
这里介绍一种支持现代D-BUS API的GATT库gattlib(注:本人是该库的作者)。以下是基于该库的读写BLE设备的简单示例:https://github.com/labapart/gattlib/blob/master/examples/read_write/read_write.c

@OliverM BlueZ的DBUS API非常不足和反应迟钝。这是基于真实经验的,许多调用都会挂起而从未成功返回。标准套接字read()方法是处理HCI最有前途的方式。 - Ace
@Ace 直接使用 HCI 意味着您正在重写 Bluez 而不使用 DBUS,对吗?提供另一种传输协议给 Bluez 是否更快、更聪明,而不是复制工作?很可能是您在我的回复中加了一个“-1”,但以上所有答案都不太好——它们建议分叉 Bluez 来访问蓝牙。 - OlivierM
DBUS系统不仅在低级语言如C中操作非常复杂,而且在BlueZ中的应用也相对较少。只需尝试导出一个简单的DBUS LEAdvertisement1对象,您就会明白我的意思(复杂度真的是e^x)。套接字读取是最好的解决方案,特别适用于实时嵌入式系统! - Ace
2
我已经在实验阶段完成了导出Bluez DBUS LEAdvertisement1的工作。我不记得它有多复杂,但我成功地完成了它。但这也是为什么在DBUS上创建前端以减少复杂性是有意义的原因。我并不一定反对套接字API。但重新实现Bluez和添加套接字传输布局(除了DBUS之外)是有区别的。正如您可能知道的那样,基于HCI编写库并不容易。 - OlivierM
@OlivierM,您的回答在2021年仍然适用吗?我想使用C++在我的树莓派上创建BLE外设,您推荐的东西应该可以用,对吧? - trixo

5

需要简单的东西吗?有个句子说得好:“线的长度有多长?” 我个人认为,Gatttool代码本身足够简单,可以轻松地跟随并提取自己的目的(我最近已经做到了)。但如果这真的不适合您,那么另一个选项是libgatt。它本质上是与Gatttool相同的代码,但更方便地捆绑成公共库API。请查看gatt.h,其中包含连接/读取/写入等功能。希望您可以自行了解如何使用它。


谢谢您的回复。 gatttool.c和gatt.c似乎有我需要的内容。您能澄清一下GAttrib应该是什么吗?例如,对于命令行操作char-write-cmd,我有一个已知的MAC地址、句柄和要发送的值。我想使用gatt.c中的gatt_write_cmd()函数,并简单地传入一组已知值,但我卡在了GAttrib指针上,以及它如何与我在命令行选项中使用的内容相关联。 - Cole Wilson
Gatttool.c和gatt.c在哪里?如何下载等? - peterk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接