在 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 中执行某些操作的有用介绍:
我需要通过蓝牙将我的 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 中执行某些操作的有用介绍: