diff --git a/src/plugins/qmldesigner/components/devicesharing/devicemanager.cpp b/src/plugins/qmldesigner/components/devicesharing/devicemanager.cpp index 79fefa2e010..98b82036077 100644 --- a/src/plugins/qmldesigner/components/devicesharing/devicemanager.cpp +++ b/src/plugins/qmldesigner/components/devicesharing/devicemanager.cpp @@ -6,9 +6,8 @@ #include #include #include -#include -#include -#include +#include +#include namespace QmlDesigner::DeviceShare { @@ -21,6 +20,71 @@ DeviceManager::DeviceManager(QObject *parent, const QString &settingsPath) m_uuid = QUuid::createUuid().toString(QUuid::WithoutBraces); writeSettings(); } + initUdpDiscovery(); +} + +void DeviceManager::initUdpDiscovery() +{ + const QList interfaces = QNetworkInterface::allInterfaces(); + for (const QNetworkInterface &interface : interfaces) { + if (interface.flags().testFlag(QNetworkInterface::IsUp) + && interface.flags().testFlag(QNetworkInterface::IsRunning) + && !interface.flags().testFlag(QNetworkInterface::IsLoopBack)) { + for (const QNetworkAddressEntry &entry : interface.addressEntries()) { + if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) { + QSharedPointer udpSocket = QSharedPointer::create(); + connect(udpSocket.data(), + &QUdpSocket::readyRead, + this, + &DeviceManager::incomingDatagram); + + bool retVal = udpSocket->bind(entry.ip(), 53452, QUdpSocket::ShareAddress); + + if (!retVal) { + qCWarning(deviceSharePluginLog) + << "UDP:: Failed to bind to UDP port 53452 on" << entry.ip().toString() + << "on interface" << interface.name() + << ". Error:" << udpSocket->errorString(); + continue; + } + + qCDebug(deviceSharePluginLog) << "UDP:: Listening on" << entry.ip().toString() + << "port" << udpSocket->localPort(); + m_udpSockets.append(udpSocket); + } + } + } + } +} + +void DeviceManager::incomingDatagram() +{ + const auto udpSocket = qobject_cast(sender()); + if (!udpSocket) + return; + + while (udpSocket->hasPendingDatagrams()) { + const QNetworkDatagram datagram = udpSocket->receiveDatagram(); + const QJsonDocument doc = QJsonDocument::fromJson(datagram.data()); + const QJsonObject message = doc.object(); + + if (message["name"].toString() != "__qtuiviewer__") { + continue; + } + + const QString id = message["id"].toString(); + const QString ip = datagram.senderAddress().toString(); + qCDebug(deviceSharePluginLog) << "Qt UI VIewer found at" << ip << "with id" << id; + + for (const auto &device : m_devices) { + if (device->deviceInfo().deviceId() == id) { + if (device->deviceSettings().ipAddress() != ip) { + qCDebug(deviceSharePluginLog) << "Updating IP address for device" << id; + setDeviceIP(id, ip); + } + } + } + } } void DeviceManager::writeSettings() diff --git a/src/plugins/qmldesigner/components/devicesharing/devicemanager.h b/src/plugins/qmldesigner/components/devicesharing/devicemanager.h index bd3484b6d18..5fec51ca194 100644 --- a/src/plugins/qmldesigner/components/devicesharing/devicemanager.h +++ b/src/plugins/qmldesigner/components/devicesharing/devicemanager.h @@ -3,8 +3,7 @@ #pragma once -#include -#include +#include #include #include "device.h" @@ -37,6 +36,7 @@ public: private: // Devices management QList> m_devices; + QList> m_udpSockets; // settings const QString m_settingsPath; @@ -44,6 +44,8 @@ private: private: // internal slots + void initUdpDiscovery(); + void incomingDatagram(); void incomingConnection(); void readSettings(); void writeSettings();