【发布时间】:2021-10-09 04:43:11
【问题描述】:
我正在尝试弄清楚 Bluez DBus API,但我无法理解其中的一些概念。
我见过的最彻底的 Bluez 示例都使用了 Python 的 dbus-python 库。例如,this python script 演示了如何创建 BLE 广告。很多内容都在Advertisement 类中,它扩展了dbus.service.Object。 Advertisement 类实现了一个GetAll 方法(来自org.freedesktop.DBus.Properties 接口)和一个Release 方法(来自org.bluez.LEAdvertisement1 接口)。为了注册该广告,它从org.bluez.LEAdvertisingManager1 接口调用RegisterAdvertisement。
我被绊倒了,因为我更习惯于 Qt DBus,所以我在想如果使用 PyQt 而不是 dbus-python 完成同样的事情会是什么样子。我认为最大的障碍是:
- 我不知道示例中的
Advertisement类如何适合 Qt Dbus 的接口/适配器模型 - 在示例中,
Advertisement类从两个接口实现方法。我找到了this discussion,这意味着它可以做到,但我认为我没有完全理解它的机制
所以,总而言之,如果我想用 Qt DBus 重新实现这个示例,Advertisement 类会是什么样子?它会扩展QDBusAbstractAdaptor 还是QDBusAbstractInterface?它会包含其中一种(或两种)吗?还是我完全错过了其他东西?
编辑:
根据来自@ukBaz 的一些信息,我挖掘得更深一些,并尝试了更多的东西,但到目前为止我还是一无所获。作为参考,我有两个脚本in this github repo。 stock-example.py 脚本直接拉到from the Bluez source tree。 qt-example.py 脚本是我尝试“翻译”它以使用 QtDBus。
我发现股票脚本和 Qt 脚本都可以正常工作,我可以在我的手机上看到它们在 nRF Connect 上做广告。但是,Qt 应用中对RegisterAdvertisement 的调用总是超时:
class BleAdManager(QDBusAbstractInterface):
def __init__(self, dbus_obj_path, parent=None):
self._ble_adapter_dbus_path = dbus_obj_path
self._dbus_system_bus = QDBusConnection.systemBus()
super().__init__("org.bluez",
self._ble_adapter_dbus_path,
"org.bluez.LEAdvertisingManager1",
self._dbus_system_bus,
parent)
def RegisterAdvertisement(self, ad_path):
print("Registering {0}...".format(ad_path))
msg = self.call('RegisterAdvertisement', QDBusObjectPath(ad_path), {})
print("Call returned.")
reply = QDBusReply(msg)
if reply.isValid():
print("Valid")
return reply.value()
else:
print(reply.error().message())
return None
当我运行它时,它会在 QDBusAbstractInterface.call() 上挂起大约 25 秒,然后吐出
Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
由于股票脚本有效,因此不会是安全策略问题。远程应用程序是否应该给我回复RegisterAdvertisement?如果不是,我如何使用 QtDBus 优雅地处理它(即,没有它挂起并给我一个错误)?如果是这样,为什么我得不到响应,我应该如何尝试调试?
【问题讨论】: