File indexing completed on 2024-04-21 04:56:45
0001 /** 0002 * SPDX-FileCopyrightText: 2013 Albert Vaca <albertvaka@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "networkpacket.h" 0008 #include "core_debug.h" 0009 0010 #include <QByteArray> 0011 #include <QDataStream> 0012 #include <QDateTime> 0013 #include <QDebug> 0014 #include <QJsonDocument> 0015 #include <QMetaObject> 0016 #include <QMetaProperty> 0017 0018 #include "dbushelper.h" 0019 #include "filetransferjob.h" 0020 #include "kdeconnectconfig.h" 0021 #include "pluginloader.h" 0022 0023 QDebug operator<<(QDebug s, const NetworkPacket &pkg) 0024 { 0025 s.nospace() << "NetworkPacket(" << pkg.type() << ':' << pkg.body(); 0026 if (pkg.hasPayload()) { 0027 s.nospace() << ":withpayload"; 0028 } 0029 s.nospace() << ')'; 0030 return s.space(); 0031 } 0032 0033 const int NetworkPacket::s_protocolVersion = 7; 0034 0035 NetworkPacket::NetworkPacket(const QString &type, const QVariantMap &body) 0036 : m_id(QString::number(QDateTime::currentMSecsSinceEpoch())) 0037 , m_type(type) 0038 , m_body(body) 0039 , m_payload() 0040 , m_payloadSize(0) 0041 { 0042 } 0043 0044 QByteArray NetworkPacket::serialize() const 0045 { 0046 // Object -> QVariant 0047 QVariantMap variant; 0048 variant.insert(QStringLiteral("id"), m_id); 0049 variant.insert(QStringLiteral("type"), m_type); 0050 variant.insert(QStringLiteral("body"), m_body); 0051 0052 if (hasPayload()) { 0053 variant.insert(QStringLiteral("payloadSize"), m_payloadSize); 0054 variant.insert(QStringLiteral("payloadTransferInfo"), m_payloadTransferInfo); 0055 } 0056 0057 // QVariant -> json 0058 auto jsonDocument = QJsonDocument::fromVariant(variant); 0059 QByteArray json = jsonDocument.toJson(QJsonDocument::Compact); 0060 if (json.isEmpty()) { 0061 qCDebug(KDECONNECT_CORE) << "Serialization error:"; 0062 } else { 0063 /*if (!isEncrypted()) { 0064 //qCDebug(KDECONNECT_CORE) << "Serialized packet:" << json; 0065 }*/ 0066 json.append('\n'); 0067 } 0068 0069 return json; 0070 } 0071 0072 template<class T> 0073 void qvariant2qobject(const QVariantMap &variant, T *object) 0074 { 0075 for (QVariantMap::const_iterator iter = variant.begin(); iter != variant.end(); ++iter) { 0076 const int propertyIndex = T::staticMetaObject.indexOfProperty(iter.key().toLatin1().data()); 0077 if (propertyIndex < 0) { 0078 qCWarning(KDECONNECT_CORE) << "missing property" << object << iter.key(); 0079 continue; 0080 } 0081 0082 QMetaProperty property = T::staticMetaObject.property(propertyIndex); 0083 bool ret = property.writeOnGadget(object, *iter); 0084 if (!ret) { 0085 qCWarning(KDECONNECT_CORE) << "couldn't set" << object << "->" << property.name() << '=' << *iter; 0086 } 0087 } 0088 } 0089 0090 bool NetworkPacket::unserialize(const QByteArray &a, NetworkPacket *np) 0091 { 0092 // Json -> QVariant 0093 QJsonParseError parseError; 0094 auto parser = QJsonDocument::fromJson(a, &parseError); 0095 if (parser.isNull()) { 0096 qCDebug(KDECONNECT_CORE) << "Unserialization error:" << parseError.errorString(); 0097 return false; 0098 } 0099 0100 auto variant = parser.toVariant().toMap(); 0101 qvariant2qobject(variant, np); 0102 0103 np->m_payloadTransferInfo = variant[QStringLiteral("payloadTransferInfo")].toMap(); // Will return an empty qvariantmap if was not present, which is ok 0104 0105 // Ids containing characters that are not allowed as dbus paths would make app crash 0106 if (np->m_body.contains(QStringLiteral("deviceId"))) { 0107 QString deviceId = np->get<QString>(QStringLiteral("deviceId")); 0108 DBusHelper::filterNonExportableCharacters(deviceId); 0109 np->set(QStringLiteral("deviceId"), deviceId); 0110 } 0111 0112 return true; 0113 } 0114 0115 FileTransferJob *NetworkPacket::createPayloadTransferJob(const QUrl &destination) const 0116 { 0117 return new FileTransferJob(this, destination); 0118 } 0119 0120 #include "moc_networkpacket.cpp"