在 C++ DBus 中实现蓝牙 client/server 架构

Implementing bluetooth client/server architecture in C++ DBus

我需要通过蓝牙将我的 android phone 连接到 Linux PC。 Phone 需要能够完全自动地通过 PC MAC 和服务的 UUID(或仅 UUID)创建连接。 phone 应该是连接发起者。

我已将此示例:An Introduction to Bluetooth Programming 和 运行 用于问题,这很可能是因为我的示例已弃用。我被建议使用新的 DBus 库,但我无法真正理解如何将我的 phone 上的程序(应该写在 Java/Kotlin/Flutter 中)连接到 DBus 架构。

我找到了这个例子:DBus tutorial using the low-level API 这行最让我困惑:With DBUS, before applications can communicate each other, they must be connected to the same BUS. 这是否意味着如果我在我的服务器上使用 DBus (Linux, C++) ,我也必须在 phone 上使用 DBus?

如果是这样,我还能用什么来完成我的任务?

在开始编写代码之前,尝试通过 D-Bus API 与 BlueZ bluetoothd 进行交互可能会有用。这可以使用各种命令行工具来完成。我将假设您将 gdbus 库用于您的 C 代码,因此这似乎是在命令行上进行试验的不错选择。

用于 Linux 蓝牙适配器的 BlueZ D-Bus API 可能是最容易上手的。

此 API 的文档位于:

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt

在顶部它说明了 D-Bus 服务和接口是什么。并且对象路径可以是可变的。

Service     org.bluez
Interface   org.bluez.Adapter1

bluetoothd 正在 D-Bus System 总线上通信。

D-Bus 有一个 GetManagedObjects 方法,我们可以用它来报告 BlueZ 知道的所有事情,所以要列出有关 BlueZ 使用的所有信息:

$ gdbus call --system --dest org.bluez --object-path / --method org.freedesktop.DBus.ObjectManager.GetManagedObjects

信息量很大,所以让我们使用 grep 查找适配器的对象路径:

$ gdbus call --system --dest org.bluez --object-path / --method org.freedesktop.DBus.ObjectManager.GetManagedObjects | grep -Pio "/org/bluez/hci.*Adapter1"

/org/bluez/hci0': {'org.freedesktop.DBus.Introspectable': {}, 'org.bluez.Adapter1

所以我们现在可以看到(对我来说)D-Bus 对象路径是 /org/bluez/hci0。我现在可以反省了:

$ gdbus introspect --system --dest org.bluez --object-path /org/bluez/hci0

现在我有了服务、接口和对象路径,我可以调用 BlueZ 记录的方法。例如,查找可以提供给 SetDiscoveryFilter 的可用过滤器:

$ gdbus call --system --dest org.bluez --object-path /org/bluez/hci0 --method org.bluez.Adapter1.GetDiscoveryFilters

(['UUIDs', 'RSSI', 'Pathloss', 'Transport', 'DuplicateData'],)

要获取适配器上的所有属性,那么我们可以使用 GetAll 方法(我们可以从内省中看到)在 org.freedesktop.DBus.Properties 接口上。调用示例:

$ gdbus call --system --dest org.bluez --object-path /org/bluez/hci0 --method org.freedesktop.DBus.Properties.GetAll "org.bluez.Adapter1"

要获得一个 属性 的值,我们使用 Get:

$ gdbus call --system --dest org.bluez --object-path /org/bluez/hci0 --method org.freedesktop.DBus.Properties.Get "org.bluez.Adapter1" "Powered"

要设置 属性 的值,我们使用 Set:

$ gdbus call --system --dest org.bluez --object-path /org/bluez/hci0 --method org.freedesktop.DBus.Properties.Set "org.bluez.Adapter1" "Powered" "<boolean true>"

下面看起来像是对在 C 中执行某些操作的有用介绍:

https://www.linumiz.com/bluetooth-list-devices-using-gdbus/