mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
mDNS Support (#1452)
* Allow build, if no grabbers are enabled * Align available functions to right Qt version * Update to next development version * Align available functions to right Qt version * fix workflows (apt/nightly) * Disable QNetworkConfigurationManager deprecation warnings * Initial go on Smart Pointers * Add Deallocation * Correct QT_WARNING_DISABLE_DEPRECATED (available since 5.9) * Cluster Build Variables * Hyperion Light * Address build warnings * Hyperion Light - UI * Update Protobuf to latest master * Removed compiler warnings * Added restart ability to systray * Correct Protobuf * Ignore 'no-return' warning on protobuf build * hyperion-remote: Fix auto discovery of hyperion server * Fix Qt version override * Update changelog * Remove Grabber Components, if no Grabber exists * Standalone Grabber - Fix fps default * Remote Control - Have Source Selction accrosswhole screen * Enable Blackborder detection only, if relevant input sources available * Enable Blackborder detection only, if relevant input sources available * Remote UI - rearrange containers * Checkout * Fix compilation on windows * Re-added qmdnsengine template cmake * chrono added for linux * Removed existing AVAHI/Bonjour, allow to enable/disable mDNS * hyperiond macos typo fix * Fix macOS Bundle build * Fix macOS bundle info details * Correct CMake files * Removed existing AVAHI/Bonjour (2) * Share hyperion's services via mDNS * Add mDNS Browser and mDNS for LED-Devices * Support mDNS discovery for standalone grabbers * Remove ZLib Dependency & Cleanup * mDNS - hanle 2.local2 an ".local." domains equally * Hue - Link discovery to bridge class, workaround port 443 for mDNS discovery * Fix save button state when switching between devices * Removed sessions (of other hyperions) * mDNS Publisher - Simplify service naming * mDNS refactoring & Forwarder discovery * mDNS Updates to use device service name * Consistency of standalone grabbers with mDNS Service Registry * Merge branch 'hyperion-project:master' into mDNS * Start JSON and WebServers only after Instance 0 is available * Remove bespoke qDebug Output again * MDNS updates and refactor Forwarder * Minor updates * Upgrade to CMake 3.1 * typo * macOS fix * Correct merge * - Remove dynamic linker flag from standalone dispmanX Grabber - Added ability to use system qmdns libs * Cec handler library will load at runtime * typo fix * protobuf changes * mDNS changes for Windows/macOS * test window build qmdnsengine * absolute path to protobuf cmake dir * Rework Hue Wizard supporting mDNS * LED-Devices - Retry support + Refactoring (excl. Hue) * LED-Devices - Refactoring/Retry support Hue + additional alignments * Address LGTM findings * Fix CI-Build, revert test changes * Build Windows in Release mode to avoid python problem * Correct that WebServerObject is available earlier * Ensure that instance name in logs for one instance are presented * Update content LEDs * Rework mDNS Address lookup * Fix LED UI * Fix for non mDNS Services (ignore default port) * Disbale device when now input is available * Revert back some updates, ensure last color is updated when switched on * Handle reopening case and changed IP, port for API-calls * Add UPD-DDP Device * WLED support for DDP * Fix printout * LEDDevice - Allow more retries, udapte defaults * LED-Net Devices - Select Custom device, if configured Co-authored-by: Paulchen Panther <16664240+Paulchen-Panther@users.noreply.github.com> Co-authored-by: Paulchen Panther <Paulchen-Panter@protonmail.com>
This commit is contained in:
@@ -31,6 +31,30 @@ struct ColorRgb
|
||||
static const ColorRgb YELLOW;
|
||||
/// 'White' RgbColor (255, 255, 255)
|
||||
static const ColorRgb WHITE;
|
||||
|
||||
ColorRgb() = default;
|
||||
|
||||
ColorRgb(uint8_t _red, uint8_t _green,uint8_t _blue):
|
||||
red(_red),
|
||||
green(_green),
|
||||
blue(_blue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ColorRgb operator-(const ColorRgb& b) const
|
||||
{
|
||||
ColorRgb a(*this);
|
||||
a.red -= b.red;
|
||||
a.green -= b.green;
|
||||
a.blue -= b.blue;
|
||||
return a;
|
||||
}
|
||||
|
||||
QString toQString() const
|
||||
{
|
||||
return QString("(%1,%2,%3)").arg(red).arg(green).arg(blue);
|
||||
}
|
||||
};
|
||||
|
||||
/// Assert to ensure that the size of the structure is 'only' 3 bytes
|
||||
|
@@ -1,12 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <utils/Logger.h>
|
||||
|
||||
#include <QTcpServer>
|
||||
#include <QUrl>
|
||||
#include <QHostAddress>
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <HyperionConfig.h>
|
||||
#include <utils/Logger.h>
|
||||
|
||||
#ifdef ENABLE_MDNS
|
||||
#include <mdns/MdnsBrowser.h>
|
||||
#endif
|
||||
|
||||
namespace NetUtils {
|
||||
|
||||
const int MAX_PORT = 65535;
|
||||
@@ -38,15 +43,15 @@ namespace NetUtils {
|
||||
///
|
||||
/// @brief Check if the port is in the valid range
|
||||
/// @param log The logger of the caller to print///
|
||||
/// @param[in] port The port to be tested
|
||||
/// @param[in] port The port to be tested (port = -1 is ignored for testing)
|
||||
/// @param[in] host A hostname/IP-address to make reference to during logging
|
||||
/// @return True on success else false
|
||||
///
|
||||
inline bool isValidPort(Logger* log, int port, const QString& host)
|
||||
{
|
||||
if (port <= 0 || port > MAX_PORT)
|
||||
if ((port <= 0 || port > MAX_PORT) && port != -1)
|
||||
{
|
||||
Error(log, "Invalid port [%d] for host: %s!", port, QSTRING_CSTR(host));
|
||||
Error(log, "Invalid port [%d] for host: (%s)! - Port must be in range [0 - %d]", port, QSTRING_CSTR(host), MAX_PORT);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -59,7 +64,7 @@ namespace NetUtils {
|
||||
/// @param[in/out] port The resolved port, if available.
|
||||
/// @return True on success else false
|
||||
///
|
||||
inline bool resolveHostPort(const QString& address, QString& host, quint16& port)
|
||||
inline bool resolveHostPort(const QString& address, QString& host, int& port)
|
||||
{
|
||||
if (address.isEmpty())
|
||||
{
|
||||
@@ -91,38 +96,109 @@ namespace NetUtils {
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Check if the port is in the valid range
|
||||
/// @param log The logger of the caller to print
|
||||
/// @param[in] address The port to be tested
|
||||
/// @param[out] hostAddress A hostname to make reference to during logging
|
||||
/// @return True on success else false
|
||||
/// @brief Resolve a hostname (DNS/mDNS) into an IP-address. A given IP address will be passed through
|
||||
/// @param[in/out] log The logger of the caller to print
|
||||
/// @param[in] hostname The hostname to be resolved
|
||||
/// @param[out] hostAddress The resolved IP-Address
|
||||
/// @return True on success else false
|
||||
///
|
||||
|
||||
inline bool resolveHostAddress(Logger* log, const QString& address, QHostAddress& hostAddress)
|
||||
inline bool resolveMdDnsHostToAddress(Logger* log, const QString& hostname, QHostAddress& hostAddress)
|
||||
{
|
||||
bool isHostAddressOK{ false };
|
||||
|
||||
if (hostAddress.setAddress(address))
|
||||
if (!hostname.isEmpty())
|
||||
{
|
||||
Debug(log, "Successfully parsed %s as an IP-address.", QSTRING_CSTR(hostAddress.toString()));
|
||||
isHostAddressOK = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
QHostInfo hostInfo = QHostInfo::fromName(address);
|
||||
if (hostInfo.error() == QHostInfo::NoError)
|
||||
#ifdef ENABLE_MDNS
|
||||
if (hostname.endsWith(".local") || hostname.endsWith(".local."))
|
||||
{
|
||||
hostAddress = hostInfo.addresses().first();
|
||||
Debug(log, "Successfully resolved IP-address (%s) for hostname (%s).", QSTRING_CSTR(hostAddress.toString()), QSTRING_CSTR(address));
|
||||
isHostAddressOK = true;
|
||||
QHostAddress resolvedAddress;
|
||||
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "resolveAddress",
|
||||
Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, isHostAddressOK),
|
||||
Q_ARG(Logger*, log), Q_ARG(QString, hostname), Q_ARG(QHostAddress&, resolvedAddress));
|
||||
hostAddress = resolvedAddress;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
QString errortext = QString("Failed resolving IP-address for [%1], (%2) %3").arg(address).arg(hostInfo.error()).arg(hostInfo.errorString());
|
||||
Error(log, "%s", QSTRING_CSTR(errortext));
|
||||
isHostAddressOK = false;
|
||||
if (hostAddress.setAddress(hostname))
|
||||
{
|
||||
//Debug(log, "IP-address (%s) not required to be resolved.", QSTRING_CSTR(hostAddress.toString()));
|
||||
isHostAddressOK = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
QHostInfo hostInfo = QHostInfo::fromName(hostname);
|
||||
if (hostInfo.error() == QHostInfo::NoError)
|
||||
{
|
||||
hostAddress = hostInfo.addresses().at(0);
|
||||
Debug(log, "Successfully resolved hostname (%s) to IP-address (%s)", QSTRING_CSTR(hostname), QSTRING_CSTR(hostAddress.toString()));
|
||||
isHostAddressOK = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
QString errortext = QString("Failed resolving hostname (%1) to IP-address. Error: (%2) %3").arg(hostname).arg(hostInfo.error()).arg(hostInfo.errorString());
|
||||
Error(log, "%s", QSTRING_CSTR(errortext));
|
||||
isHostAddressOK = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isHostAddressOK;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Resolve a hostname(DNS) or mDNS service name into an IP-address. A given IP address will be passed through
|
||||
/// @param[in/out] log The logger of the caller to print
|
||||
/// @param[in] hostname The hostname/mDNS service name to be resolved
|
||||
/// @param[out] hostAddress The resolved IP-Address
|
||||
/// @param[in/out] port The port provided by the mDNS service, if not mDNS the input port is returned
|
||||
/// @return True on success else false
|
||||
///
|
||||
inline bool resolveHostToAddress(Logger* log, const QString& hostname, QHostAddress& hostAddress, int& port)
|
||||
{
|
||||
bool areHostAddressPartOK{ false };
|
||||
QString target {hostname};
|
||||
|
||||
#ifdef ENABLE_MDNS
|
||||
if (hostname.endsWith("._tcp.local"))
|
||||
{
|
||||
//Treat hostname as service instance name that requires to be resolved into an mDNS-Hostname first
|
||||
QMdnsEngine::Record service = MdnsBrowser::getInstance().getServiceInstanceRecord(hostname.toUtf8());
|
||||
if (!service.target().isEmpty())
|
||||
{
|
||||
Info(log, "Resolved service [%s] to mDNS hostname [%s], service port [%d]", QSTRING_CSTR(hostname), service.target().constData(), service.port());
|
||||
target = service.target();
|
||||
port = service.port();
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(log, "Cannot resolve mDNS hostname for given service [%s]!", QSTRING_CSTR(hostname));
|
||||
return areHostAddressPartOK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QHostAddress resolvedAddress;
|
||||
if (NetUtils::resolveMdDnsHostToAddress(log, target, resolvedAddress))
|
||||
{
|
||||
hostAddress = resolvedAddress;
|
||||
if (hostname != hostAddress.toString())
|
||||
{
|
||||
Info(log, "Resolved hostname (%s) to IP-address (%s)", QSTRING_CSTR(hostname), QSTRING_CSTR(hostAddress.toString()));
|
||||
}
|
||||
|
||||
if (NetUtils::isValidPort(log, port, hostAddress.toString()))
|
||||
{
|
||||
areHostAddressPartOK = true;
|
||||
}
|
||||
}
|
||||
return areHostAddressPartOK;
|
||||
}
|
||||
|
||||
inline bool resolveHostToAddress(Logger* log, const QString& hostname, QHostAddress& hostAddress)
|
||||
{
|
||||
int ignoredPort {MAX_PORT};
|
||||
return resolveHostToAddress(log, hostname, hostAddress, ignoredPort);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user