我正在构建一个简单的基于Qt的应用程序,用于监控和连接WiFi网络。我通过Connman的D-Bus API与之对接,能够扫描可用网络,打开/关闭技术,并按预期注册代理。当调用Connman RequestInput方法时(当试图连接到受保护/安全的网络时(,我目前无法提供请求的密码短语,因为我不确定如何将RequestInput方法与Qt中的函数绑定。
以下是概述方法的一些指示性代码:
//Create a QDBusConnection systemBus() object
QDBusConnection connection = QDBusConnection::systemBus();
//Ensure the systemBus() connection is established
if (!connection.isConnected()) {
qDebug() << "Connection error.";
}
//Create a Connman Manager D-Bus API interface object
QDBusInterface manager("net.connman", "/", "net.connman.Manager", connection);
//Register an agent with the Connman Manager API
manager.call("RegisterAgent", QVariant::fromValue(QDBusObjectPath("/test/agent")));
//Attempt to bind the mySlot() function with the net.connman.Agent RequestInput method
//This does not currently work
connection.connect("",
"/test/agent",
"net.connman.Agent",
"RequestInput",
this,
SLOT(mySlot(QDBusObjectPath, QVariantMap)));
//Create a Connman Service D-Bus API interface object (for a specific WiFi Service)
QDBusInterface service("net.connman",
"/net/connman/service/[WIFI SERVICE]",
"net.connman.Service",
connection);
//Attempt to connect to the secure WiFi network
//Note: this network has not previously been connected, so the RequestInput method is guaranteed to be called
service.call("Connect");
QVariantMap myClass::mySlot(const QDBusObjectPath &path, const QVariantMap &map)
{
//Connman Agent RequestInput() method received
}
如上所述,尝试将/test/agent路径、net.conman.agent接口和RequestInput方法绑定到mySlot((函数不起作用;没有报告错误,但从未调用mySlot((函数。如果我使用QDBUS_DEBUG环境变量启用调试,我会收到以下消息:
QDBusConnectionPrivate(0xffff74003a00) got message (signal): QDBusMessage(type=MethodCall, service=":1.3", path="/test/agent", interface="net.connman.Agent", member="RequestInput", signature="oa{sv}", contents=([ObjectPath: /net/connman/service/[WIFI SERVICE]], [Argument: a{sv} {"Passphrase" = [Variant: [Argument: a{sv} {"Type" = [Variant(QString): "psk"], "Requirement" = [Variant(QString): "mandatory"]}]]}]) )
以上正是我所期望的;正在为net.conf上的/test/agent路径调用RequestInput方法。具有oa{sv}签名的agent接口。
我的问题:
- 如何"连接"到RequestInput方法调用,以便mySlot((函数可以解析RequestInput方法数据
- 如何从mySlot((中返回所需的QVariantMap
从调试输出中可以看出,ConnMan正在执行MethodCall
,但QDBusConnection::connect()
用于处理DBus信号,这就是为什么您的插槽没有被调用的原因。
您需要将实现net.connman.Agent
接口的对象注册到相应的路径上,以便ConnMan可以调用您的方法:
class ConnManAgent : public QObject {
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "net.connman.Agent")
public:
ConnManAgent(QObject *parent = nullptr);
Q_INVOKABLE QVariantMap RequestInput(const QDBusObjectPath &, const QVariantMap &);
// ... Rest of the net.connman.Agent interface
};
然后将其注册在相应的路径上:
connection.registerObject(
QStringLiteral("/test/agent"),
new ConnManAgent(this),
QDBusConnection::ExportAllInvokables);
这将所有用Q_INVOKABLE
标记的方法导出到DBus。您也可以将它们标记为Q_SLOTS
并使用ExportAllSlots
,这主要取决于您。