From 42cf37a43ef40797b67fc9f859e1e86864354d78 Mon Sep 17 00:00:00 2001 From: Burak Hancerli Date: Thu, 24 Oct 2024 10:36:34 +0200 Subject: [PATCH] DeviceShare: Add UDP discovery for Design Studio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the network allows UDP broadcasts and if the IP address of the Qt UI Viewer has changed, we can update the device IP without expecting the user to update it. Change-Id: I50a89a9e2412220a3f8200aed807f691e5c9e377 Reviewed-by: Henning Gründl --- .../devicesharing/devicemanager.cpp | 70 ++++++++++++++++++- .../components/devicesharing/devicemanager.h | 6 +- 2 files changed, 71 insertions(+), 5 deletions(-) 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();