c++qtdbusqdbusconnman

How to pass a DBus variant to Qt's QDBusInterface::call


I am trying to send the following message to Connman over Qt 5.12's DBus API:

dbus-send --system --print-reply --dest=net.connman / net.connman.Manager.SetProperty string:"OfflineMode" variant:boolean:true

As seen, the SetProperty method takes a dbus string and a dbus variant.

If I look at the signature with qdbus, I get the following:

$ qdbus --system net.connman / | grep Manager.SetProperty
method void net.connman.Manager.SetProperty(QString name, QDBusVariant value)

So that's what I do...

iface.call("SetProperty", "OfflineMode", QDBusVariant(!m_flightModeOn));

However, I get the following compile error:

error: no matching function for call to ‘QDBusInterface::call(const char [12], const char [12], QDBusVariant)’
         QDBusReply<QVariantMap> reply = iface.call("SetProperty", "OfflineMode", QDBusVariant(true));

Here is the complete function:

void enableFlightMode()
{
    QDBusInterface iface("net.connman", "/", "net.connman.Manager", QDBusConnection::systemBus());
    if (iface.isValid()) {
        QDBusReply<QVariantMap> reply = iface.call("SetProperty", "OfflineMode", QDBusVariant(true));
    }

    qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message());
}

I have tried passing both a bool and a QVariant to ::call, but those result in DBus in a dbus error: Method "SetProperty" with signature "sb" on interface "net.connman.Manager" doesn't exist. This makes sense since the signature is a string and a variant.

I guess my question is, according to the Qt DBus API type system docs, QDBusVariant() is supposed to be analogous to the DBus "VARIANT", so I would expect to be able to pass it into this function. Is there another way I can pass a DBus variant through this API?


Solution

  • I have found a workaround using a different part of the API... Utilizing QDBusMessage, this can be done:

        QDBusMessage message = QDBusMessage::createMethodCall("net.connman", "/", "net.connman.Manager", "SetProperty");
        QList<QVariant> arguments;
        arguments << "OfflineMode" << QVariant::fromValue(QDBusVariant(true));
        message.setArguments(arguments);
        QDBusConnection::systemBus().call(message);
        qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message());
    

    For anyone doing similar things with Connman, check out cmst. It uses Qt to communicate with Connman over DBus.