// Squawk messenger. // Copyright (C) 2019 Yury Gubich // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "discoveryhandler.h" #include "core/account.h" #include Core::DiscoveryHandler::DiscoveryHandler(Core::Account* account): QObject(), acc(account), omemoToCarbonsConnected (false) {} Core::DiscoveryHandler::~DiscoveryHandler() {} void Core::DiscoveryHandler::initialize() { QObject::connect(acc->dm, &QXmppDiscoveryManager::itemsReceived, this, &DiscoveryHandler::onItemsReceived); QObject::connect(acc->dm, &QXmppDiscoveryManager::infoReceived, this, &DiscoveryHandler::onInfoReceived); acc->dm->setClientType("pc"); acc->dm->setClientCategory("client"); acc->dm->setClientName(qApp->applicationDisplayName() + " " + qApp->applicationVersion()); acc->dm->setClientCapabilitiesNode("https://git.macaw.me/blue/squawk"); } void Core::DiscoveryHandler::onItemsReceived(const QXmppDiscoveryIq& items) { QString server = acc->getServer(); if (items.from() == server) { std::set needToRequest; qDebug() << "Server items list received for account " << acc->getName() << ":"; for (QXmppDiscoveryIq::Item item : items.items()) { QString jid = item.jid(); if (jid != server) { qDebug() << " Node" << jid; needToRequest.insert(jid); } else { qDebug() << " " << item.node().toStdString().c_str(); } } for (const QString& jid : needToRequest) { acc->dm->requestInfo(jid); } } } void Core::DiscoveryHandler::onInfoReceived(const QXmppDiscoveryIq& info) { QString from = info.from(); QString server = acc->getServer(); QString accName = acc->getName(); QString bareJid = acc->getBareJid(); if (from == server) { bool enableCC = false; qDebug() << "Server info received for account" << accName; QStringList features = info.features(); qDebug() << "List of supported features of the server " << server << ":"; for (const QString& feature : features) { qDebug() << " " << feature.toStdString().c_str(); if (feature == "urn:xmpp:carbons:2") { enableCC = true; } } if (enableCC) { qDebug() << "Enabling carbon copies for account" << accName; #if (QXMPP_VERSION) < QT_VERSION_CHECK(1, 5, 0) acc->cm->setCarbonsEnabled(true); #endif #ifdef WITH_OMEMO if (!omemoToCarbonsConnected && acc->oh->hasOwnDevice()) { // connect(this, &QXmppCarbonManager::messageSent, acc->om, &QXmppOmemoManager::handleMessage); // connect(this, &QXmppCarbonManager::messageReceived, acc->om, &QXmppOmemoManager::handleMessage); omemoToCarbonsConnected = true; } } else { if (omemoToCarbonsConnected) { // disconnect(this, &QXmppCarbonManager::messageSent, acc->om, &QXmppOmemoManager::handleMessage); // disconnect(this, &QXmppCarbonManager::messageReceived, acc->om, &QXmppOmemoManager::handleMessage); omemoToCarbonsConnected = false; } #endif } qDebug() << "Requesting account" << accName << "capabilities"; acc->dm->requestInfo(bareJid); } else if (from == bareJid) { qDebug() << "Received capabilities for account" << accName << ":"; QList identities = info.identities(); bool pepSupported = false; for (const QXmppDiscoveryIq::Identity& identity : identities) { QString type = identity.type(); QString category = identity.category(); qDebug() << " " << category << type; if (type == "pep" && category == "pubsub") { pepSupported = true; } } acc->setPepSupport(pepSupported ? Shared::Support::supported : Shared::Support::unsupported); } else { QString node = info.queryNode(); if (!node.isEmpty()) { qDebug() << "Received features and identities for account" << accName << "about" << from; QStringList feats = info.features(); std::set identities; std::set features(feats.begin(), feats.end()); QList idents = info.identities(); for (const QXmppDiscoveryIq::Identity& ident : idents) { Shared::Identity identity; identity.category = ident.category(); identity.language = ident.language(); identity.name = ident.name(); identity.type = ident.type(); identities.insert(identity); qDebug() << " " << identity.name << identity.category << identity.type; } for (const QString& feat : features) { qDebug() << " " << feat; } emit acc->infoDiscovered(from, node, identities, features); } else { Contact* cont = acc->rh->getContact(from); if (cont != nullptr) { qDebug() << "Received info for account" << accName << "about contact" << from; QList identities = info.identities(); bool pepSupported = false; for (const QXmppDiscoveryIq::Identity& identity : identities) { QString type = identity.type(); QString category = identity.category(); qDebug() << " " << category << type; if (type == "pep" && category == "pubsub") { pepSupported = true; } } cont->setPepSupport(pepSupported ? Shared::Support::supported : Shared::Support::unsupported); } } } }