使用 BlueZ 在 Linux 机器上制作蓝牙 GATT 服务器。使用现代 (5.50) BlueZ 的首选方法是通过 dbus API。
这文档关于这个主题指出:
GATT 本地和远程服务共享相同的高级 D-Bus API。本地是指由 BlueZ 插件或外部应用程序导出的基于 GATT 的服务。 Remote是指对端导出的GATT服务。
我将此解释为:
两个都本地服务(Linux机器是服务器,其他设备通过蓝牙连接到它)和远程服务(Linux机器是客户端,它通过蓝牙连接其他设备)在dbus上表示
这就设定了问题的基本假设。
bluez源代码提供了一个示例 gatt 服务器。您可以执行一个示例,它将正常工作并将您的 Linux 计算机置于 GATT 服务器中。
在那个例子中任意命名的 dbus 对象被引用。它的名字是/org/bluez/example/service
从文档中我预计,一旦./example-gatt-server
成功运行,应该有一个/org/bluez/example/service
地方。
事实并非如此:
~$ busctl tree org.bluez
└─/org
└─/org/bluez
└─/org/bluez/hci0
我正在使用外部设备确认 Linux 计算机正在充当 GATT 服务器,但未/org/bluez/example/service
列出。
为什么/org/bluez/example/service
在 下找不到对象org.bluez
?
答案1
我也对此感到困惑,我发现我们无法看到 dbus 对象,因为此示例没有在 dbus 上为该服务定义众所周知/请求的名称。
按照总线控制文档为了能够查询该服务,您需要有一个与其关联的名称。虽然本示例 Gatt 服务器没有。
显示一项或多项服务的对象树。如果指定了 SERVICE,则仅显示指定服务的对象树。否则,显示总线上至少获得一个众所周知的名称的所有服务的所有对象树。
尽管您可以使用 sudo dbus-monitor --system 来监视正在注册的对象,也可以在 gatt 服务器示例代码中创建应用程序对象之前通过在总线上调用 request_name 来向 dbus 请求名称。您可以检查具有请求名称的示例服务这里。
bus.request_name(BUS_NAME)
named_bus = dbus.service.BusName(BUS_NAME, bus=bus)
您还需要通过编辑 /etc/dbus-1/system.conf 授予系统总线发布权限,并添加您的服务名称,如下所示:
<policy user="root">
<allow own="com.example.gattServer"/>
</policy>