/** * SPDX-FileCopyrightText: 2023 Albert Vaca * * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL */ #include "mdnsdiscovery.h" #include "core_debug.h" #include "kdeconnectconfig.h" #include "lanlinkprovider.h" #include #include #include const QString kServiceName = QStringLiteral("_kdeconnect._udp"); MdnsDiscovery::MdnsDiscovery(LanLinkProvider *lanLinkProvider) : lanLinkProvider(lanLinkProvider) { switch (KDNSSD::ServiceBrowser::isAvailable()) { case KDNSSD::ServiceBrowser::Stopped: qCWarning(KDECONNECT_CORE) << "mDNS or Avahi daemons are not running, mDNS discovery not available"; break; case KDNSSD::ServiceBrowser::Working: qCDebug(KDECONNECT_CORE) << "mDNS discovery is available"; break; case KDNSSD::ServiceBrowser::Unsupported: qCWarning(KDECONNECT_CORE) << "mDNS discovery not available (library built without DNS-SD support)"; break; } } MdnsDiscovery::~MdnsDiscovery() { stopAnnouncing(); stopDiscovering(); } void MdnsDiscovery::startAnnouncing() { if (m_publisher != nullptr) { qCDebug(KDECONNECT_CORE) << "MDNS already announcing"; return; } qCDebug(KDECONNECT_CORE) << "MDNS start announcing"; KdeConnectConfig &config = KdeConnectConfig::instance(); m_publisher = new KDNSSD::PublicService(config.deviceId(), kServiceName, LanLinkProvider::UDP_PORT, QStringLiteral("local")); m_publisher->setParent(this); // We can't fit the device certificate in this field, so this is not enough info to create a Device and won't be used. QMap data; data[QStringLiteral("id")] = config.deviceId().toUtf8(); data[QStringLiteral("name")] = config.name().toUtf8(); data[QStringLiteral("type")] = config.deviceType().toString().toUtf8(); data[QStringLiteral("protocol")] = QString::number(NetworkPacket::s_protocolVersion).toUtf8(); m_publisher->setTextData(data); connect(m_publisher, &KDNSSD::PublicService::published, [](bool successful) { if (successful) { qCDebug(KDECONNECT_CORE) << "MDNS published successfully"; } else { qCWarning(KDECONNECT_CORE) << "MDNS failed to publish"; } }); m_publisher->publishAsync(); } void MdnsDiscovery::stopAnnouncing() { if (m_publisher != nullptr) { qCDebug(KDECONNECT_CORE) << "MDNS stop announcing"; delete m_publisher; m_publisher = nullptr; } } void MdnsDiscovery::startDiscovering() { if (m_serviceBrowser != nullptr) { qCDebug(KDECONNECT_CORE) << "MDNS already discovering"; return; } qCDebug(KDECONNECT_CORE) << "MDNS start discovering"; m_serviceBrowser = new KDNSSD::ServiceBrowser(kServiceName, true); connect(m_serviceBrowser, &KDNSSD::ServiceBrowser::serviceAdded, [this](KDNSSD::RemoteService::Ptr service) { if (KdeConnectConfig::instance().deviceId() == service->serviceName()) { qCDebug(KDECONNECT_CORE) << "Discovered myself, ignoring"; return; } qCDebug(KDECONNECT_CORE) << "Discovered " << service->serviceName() << " at " << service->hostName(); QHostAddress address(service->hostName()); lanLinkProvider->sendUdpIdentityPacket(QList{address}); }); connect(m_serviceBrowser, &KDNSSD::ServiceBrowser::serviceRemoved, [](KDNSSD::RemoteService::Ptr service) { qCDebug(KDECONNECT_CORE) << "Lost " << service->serviceName(); }); connect(m_serviceBrowser, &KDNSSD::ServiceBrowser::finished, []() { qCDebug(KDECONNECT_CORE) << "Finished discovery"; }); m_serviceBrowser->startBrowse(); } void MdnsDiscovery::stopDiscovering() { if (m_serviceBrowser != nullptr) { qCDebug(KDECONNECT_CORE) << "MDNS stop discovering"; delete m_serviceBrowser; m_serviceBrowser = nullptr; } }