'How do I insert customType array data in QDBusArgument

I am trying to set and get DNS using QtDBusInterface. As per the documentation, it has "a(iay)" format. which contains an array of IP types and an array of unsigned short. I have overloaded the >> and << operator for QDBusArgument object. I am able to extract data but insertion is not working for me. Below is the code:

struct DNSIPStruct;

const QDBusArgument & extract(const QDBusArgument &arg, QList<DNSIPStruct>& members);
typedef QList<DNSIPStruct> DNSIPList;

Q_DECLARE_METATYPE(DNSIPStruct)
Q_DECLARE_METATYPE(DNSIPList)

struct DNSIPStruct
{
    int  a;
    QList<ushort> c;

public:
    friend QDBusArgument &operator<<(QDBusArgument &arg, const DNSIPStruct& d)
    {
        arg << d.a ;
        arg << d.c;
        return arg;
    }

    friend const QDBusArgument &operator>>(const QDBusArgument &arg, DNSIPStruct& d)
    {
        arg >> d.a ;
        arg >> d.c;
        return arg;
    }

    friend QDBusArgument &operator<<(QDBusArgument &argument, const QList<DNSIPStruct>& obj)
    {
        int id = qMetaTypeId<DNSIPStruct>();
        argument.beginArray(id);

        qDebug() << "DNSIPStruct QList << ";
         for ( int i = 0; i < obj.size(); ++i )
         {
             DNSIPStruct element = obj.at(i);
             argument << element;
         }
         argument.endArray();
         return argument;
    }

    friend const QDBusArgument &operator>>(const QDBusArgument &argument, QList<DNSIPStruct>& obj)
    {
        argument.beginArray();
        DNSIPStruct m;
        argument >> m;
        obj << m;
        argument.endArray();
        qDebug() << "DNSIPStruct QList  >>";
        return argument;
    }

};

I am using the below code to extract and print data in user-readable format.


struct BusSignature
{
    QString mService, mPath, mInterface, mName;
    QString mTypeSig;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    BusSignature sig;
    sig.mService = "org.freedesktop.resolve1";
    sig.mInterface = "org.freedesktop.resolve1.Link";
    sig.mPath = "/org/freedesktop/resolve1/link/_32";
    sig.mName = "DNS";
    sig.mTypeSig = "";
   
   QDNSReadWrite *dnsread = new QDNSReadWrite();
   systemBusViewer->getProperty(sig);
    return a.exec();
}
void QDBusViewer::getProperty(const BusSignature &sig)
{
    QDBusConnection bus=  QDBusConnection::systemBus();
    QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get"));
    QList<QVariant> arguments;
    arguments << sig.mInterface << sig.mName;
    message.setArguments(arguments);
    bus.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage)));
}
void QDNSReadWrite::dumpMessage(const QDBusMessage &message)
{
    QVariant v = message.arguments().first();
    QDBusArgument arg = v.value<QDBusVariant>().variant().value<QDBusArgument>();
    DNSIPList members;
    arg.beginArray();
    while(!arg.atEnd())
    {
        DNSIPList m;
        arg >> m;
        members.append(m);
    }
    arg.endArray();

    for(auto i : members)
    {
        auto list = i.c;
        if(list.size() > 3)
        {
            QString IP =QString::number(list.at(0));

            for(int j = 1; j < list.size(); j++)
            {
                IP = IP + ":" + QString::number(list.at(j));
            }
            qDebug() <<"DNS IP: " << IP;
        }
    }
}

Set the DNS using some hardcode values

void QDBusViewer::SetDNS(const BusSignature &sig)
{
        QDBusConnection bus=  QDBusConnection::systemBus();
        QDBusArgument arg;

        DNSIPStruct IPDetails;
        IPDetails.a = 2;
        IPDetails.c.append(173);
        IPDetails.c.append(20);
        IPDetails.c.append(24);
        IPDetails.c.append(58);
        DNSIPList dnsList;
        dnsList.append(IPDetails);
        arg << dnsList;

        QDBusVariant busV;
        busV.setVariant(arg.asVariant());
        QList<QVariant> list2;
        list2.append(busV.variant());
        QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, sig.mInterface,
                sig.mName);
        message.setArguments(list2);
        bus.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage)));

}

I am getting the below error message after calling setDNS method:

QDBusMarshaller: cannot add an invalid QVariant QDBusConnection: error: could not send message to service "org.freedesktop.resolve1" path "/org/freedesktop/resolve1/link/_32" interface "org.freedesktop.resolve1.Link" member "SetDNS": Marshalling failed: Variant containing QVariant::Invalid passed in arguments

Note: I have used Qt qdbusviewer code for reference

Am I missing anything within the code?



Sources

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

Source: Stack Overflow

Solution Source