'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 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1