在 C++ DBus 中实现蓝牙客户端/服务器架构

问题描述 投票:0回答:2

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

我使用了这个示例:蓝牙编程简介并遇到了问题,这些问题很可能是因为我的示例已被弃用而发生的。有人建议我使用新的 DBus 库,但我无法真正理解如何将手机上的程序(应该用 Java/Kotlin/Flutter 编写)连接到 DBus 架构。

我找到了这个例子:使用低级 API 的 DBus 教程,这一行最让我困惑:

With DBUS, before applications can communicate each other, they must be connected to the same BUS.
这是否意味着如果我在我的服务器(Linux、C++)上使用 DBus,我必须使用我的手机上也有 DBus 吗?

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

android c++ flutter bluetooth dbus
2个回答
1
投票

在深入编码之前,尝试通过 D-Bus API 与 BlueZ

bluetoothd
进行交互可能会很有用。这可以使用各种命令行工具来完成。我假设您将在 C 代码中使用 gdbus 库,因此这似乎是在命令行上进行实验的不错选择。

用于 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/


0
投票

我的系统有

dbus-send
而不是
gdbus
所以上面的例子是:

反省:

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.freedesktop.DBus.Introspectable.Introspect

可以向 SetDiscoveryFilter 提供哪些可用的过滤器:

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.bluez.Adapter1.GetDiscoveryFilters

要获取适配器上的所有属性,我们使用

GetAll
:

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.freedesktop.DBus.Properties.GetAll string:org.bluez.Adapter1

要获取一个属性的值,我们使用

Get
:

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.freedesktop.DBus.Properties.Get string:org.bluez.Adapter1 string:Powered

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

Set
:

dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0 org.freedesktop.DBus.Properties.Set string:org.bluez.Adapter1 string:Powered variant:boolean:true
© www.soinside.com 2019 - 2024. All rights reserved.