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:
@@ -14,6 +14,7 @@
|
||||
#include <QBuffer>
|
||||
#include <QByteArray>
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
|
||||
// hyperion includes
|
||||
#include <utils/jsonschema/QJsonFactory.h>
|
||||
@@ -23,9 +24,6 @@
|
||||
#include <utils/ColorSys.h>
|
||||
#include <utils/Process.h>
|
||||
|
||||
// bonjour wrapper
|
||||
#include <bonjour/bonjourbrowserwrapper.h>
|
||||
|
||||
// ledmapping int <> string transform methods
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
|
||||
@@ -44,17 +42,13 @@ API::API(Logger *log, bool localConnection, QObject *parent)
|
||||
// Init
|
||||
_log = log;
|
||||
_authManager = AuthManager::getInstance();
|
||||
_instanceManager = HyperionIManager::getInstance();
|
||||
_instanceManager = HyperionIManager::getInstance();
|
||||
_localConnection = localConnection;
|
||||
|
||||
_authorized = false;
|
||||
_adminAuthorized = false;
|
||||
|
||||
_hyperion = _instanceManager->getHyperionInstance(0);
|
||||
_currInstanceIndex = 0;
|
||||
// TODO FIXME
|
||||
// report back current registers when a Hyperion instance request it
|
||||
//connect(ApiSync::getInstance(), &ApiSync::requestActiveRegister, this, &API::requestActiveRegister, Qt::QueuedConnection);
|
||||
|
||||
// connect to possible token responses that has been requested
|
||||
connect(_authManager, &AuthManager::tokenResponse, [=] (bool success, QObject *caller, const QString &token, const QString &comment, const QString &id, const int &tan)
|
||||
@@ -73,7 +67,7 @@ API::API(Logger *log, bool localConnection, QObject *parent)
|
||||
|
||||
void API::init()
|
||||
{
|
||||
assert(_hyperion);
|
||||
_hyperion = _instanceManager->getHyperionInstance(0);
|
||||
|
||||
bool apiAuthRequired = _authManager->isAuthRequired();
|
||||
|
||||
@@ -336,13 +330,6 @@ void API::stopInstance(quint8 index)
|
||||
QMetaObject::invokeMethod(_instanceManager, "stopInstance", Qt::QueuedConnection, Q_ARG(quint8, index));
|
||||
}
|
||||
|
||||
void API::requestActiveRegister(QObject *callerInstance)
|
||||
{
|
||||
// TODO FIXME
|
||||
//if (_activeRegisters.size())
|
||||
// QMetaObject::invokeMethod(ApiSync::getInstance(), "answerActiveRegister", Qt::QueuedConnection, Q_ARG(QObject *, callerInstance), Q_ARG(MapRegister, _activeRegisters));
|
||||
}
|
||||
|
||||
bool API::deleteInstance(quint8 index, QString &replyMsg)
|
||||
{
|
||||
if (_adminAuthorized)
|
||||
|
@@ -13,7 +13,7 @@
|
||||
"subcommand": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["discover","getProperties","identify"]
|
||||
"enum": [ "discover", "getProperties", "identify", "addAuthorization" ]
|
||||
},
|
||||
"ledDeviceType": {
|
||||
"type" : "string",
|
||||
|
28
libsrc/api/JSONRPC_schema/schema-service.json
Normal file
28
libsrc/api/JSONRPC_schema/schema-service.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["service"]
|
||||
},
|
||||
"tan" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"subcommand": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["discover"]
|
||||
},
|
||||
"serviceType": {
|
||||
"type" : "string",
|
||||
"required" : true
|
||||
},
|
||||
"params": {
|
||||
"type" : "object",
|
||||
"required" : false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
@@ -5,7 +5,7 @@
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum": [ "color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "inputsource", "transform", "correction", "temperature" ]
|
||||
"enum": [ "color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing", "sysinfo", "videomode", "authorize", "instance", "leddevice", "inputsource", "service", "transform", "correction", "temperature" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@
|
||||
<file alias="schema-instance">JSONRPC_schema/schema-instance.json</file>
|
||||
<file alias="schema-leddevice">JSONRPC_schema/schema-leddevice.json</file>
|
||||
<file alias="schema-inputsource">JSONRPC_schema/schema-inputsource.json</file>
|
||||
<file alias="schema-service">JSONRPC_schema/schema-service.json</file>
|
||||
<!-- The following schemas are derecated but used to ensure backward compatibility with hyperion Classic remote control-->
|
||||
<file alias="schema-transform">JSONRPC_schema/schema-hyperion-classic.json</file>
|
||||
<file alias="schema-correction">JSONRPC_schema/schema-hyperion-classic.json</file>
|
||||
|
@@ -63,11 +63,6 @@
|
||||
#include <utils/Process.h>
|
||||
#include <utils/JsonUtils.h>
|
||||
|
||||
// bonjour wrapper
|
||||
#ifdef ENABLE_AVAHI
|
||||
#include <bonjour/bonjourbrowserwrapper.h>
|
||||
#endif
|
||||
|
||||
// ledmapping int <> string transform methods
|
||||
#include <hyperion/ImageProcessor.h>
|
||||
|
||||
@@ -77,6 +72,15 @@
|
||||
// auth manager
|
||||
#include <hyperion/AuthManager.h>
|
||||
|
||||
#ifdef ENABLE_MDNS
|
||||
// mDNS discover
|
||||
#include <mdns/MdnsBrowser.h>
|
||||
#include <mdns/MdnsServiceRegister.h>
|
||||
#else
|
||||
// ssdp discover
|
||||
#include <ssdp/SSDPDiscover.h>
|
||||
#endif
|
||||
|
||||
using namespace hyperion;
|
||||
|
||||
// Constants
|
||||
@@ -98,8 +102,6 @@ void JsonAPI::initialize()
|
||||
{
|
||||
// init API, REQUIRED!
|
||||
API::init();
|
||||
// Initialise jsonCB with current instance
|
||||
_jsonCB->setSubscriptionsTo(_hyperion);
|
||||
|
||||
// setup auth interface
|
||||
connect(this, &API::onPendingTokenRequest, this, &JsonAPI::newPendingTokenRequest);
|
||||
@@ -112,7 +114,12 @@ void JsonAPI::initialize()
|
||||
connect(_jsonCB, &JsonCB::newCallback, this, &JsonAPI::callbackMessage);
|
||||
|
||||
// notify hyperion about a jsonMessageForward
|
||||
connect(this, &JsonAPI::forwardJsonMessage, _hyperion, &Hyperion::forwardJsonMessage);
|
||||
if (_hyperion != nullptr)
|
||||
{
|
||||
// Initialise jsonCB with current instance
|
||||
_jsonCB->setSubscriptionsTo(_hyperion);
|
||||
connect(this, &JsonAPI::forwardJsonMessage, _hyperion, &Hyperion::forwardJsonMessage);
|
||||
}
|
||||
}
|
||||
|
||||
bool JsonAPI::handleInstanceSwitch(quint8 inst, bool forced)
|
||||
@@ -180,6 +187,12 @@ void JsonAPI::handleMessage(const QString &messageString, const QString &httpAut
|
||||
return;
|
||||
}
|
||||
proceed:
|
||||
if (_hyperion == nullptr)
|
||||
{
|
||||
sendErrorReply("Service Unavailable", command, tan);
|
||||
return;
|
||||
}
|
||||
|
||||
// switch over all possible commands and handle them
|
||||
if (command == "color")
|
||||
handleColorCommand(message, command, tan);
|
||||
@@ -221,6 +234,8 @@ proceed:
|
||||
handleLedDeviceCommand(message, command, tan);
|
||||
else if (command == "inputsource")
|
||||
handleInputSourceCommand(message, command, tan);
|
||||
else if (command == "service")
|
||||
handleServiceCommand(message, command, tan);
|
||||
|
||||
// BEGIN | The following commands are deprecated but used to ensure backward compatibility with hyperion Classic remote control
|
||||
else if (command == "clearall")
|
||||
@@ -627,6 +642,11 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString
|
||||
services.append("protobuffer");
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_MDNS)
|
||||
services.append("mDNS");
|
||||
#endif
|
||||
services.append("SSDP");
|
||||
|
||||
if (!availableScreenGrabbers.isEmpty() || !availableVideoGrabbers.isEmpty() || services.contains("flatbuffer") || services.contains("protobuffer"))
|
||||
{
|
||||
services.append("borderdetection");
|
||||
@@ -649,24 +669,6 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString
|
||||
info["components"] = component;
|
||||
info["imageToLedMappingType"] = ImageProcessor::mappingTypeToStr(_hyperion->getLedMappingType());
|
||||
|
||||
// add sessions
|
||||
QJsonArray sessions;
|
||||
#ifdef ENABLE_AVAHI
|
||||
for (auto session: BonjourBrowserWrapper::getInstance()->getAllServices())
|
||||
{
|
||||
if (session.port < 0)
|
||||
continue;
|
||||
QJsonObject item;
|
||||
item["name"] = session.serviceName;
|
||||
item["type"] = session.registeredType;
|
||||
item["domain"] = session.replyDomain;
|
||||
item["host"] = session.hostName;
|
||||
item["address"] = session.address;
|
||||
item["port"] = session.port;
|
||||
sessions.append(item);
|
||||
}
|
||||
info["sessions"] = sessions;
|
||||
#endif
|
||||
// add instance info
|
||||
QJsonArray instanceInfo;
|
||||
for (const auto &entry : API::getAllInstanceData())
|
||||
@@ -1571,6 +1573,16 @@ void JsonAPI::handleLedDeviceCommand(const QJsonObject &message, const QString &
|
||||
|
||||
sendSuccessReply(full_command, tan);
|
||||
}
|
||||
else if (subc == "addAuthorization")
|
||||
{
|
||||
ledDevice = LedDeviceFactory::construct(config);
|
||||
const QJsonObject& params = message["params"].toObject();
|
||||
const QJsonObject response = ledDevice->addAuthorization(params);
|
||||
|
||||
Debug(_log, "response: [%s]", QString(QJsonDocument(response).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
|
||||
sendSuccessDataReply(QJsonDocument(response), full_command, tan);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendErrorReply("Unknown or missing subcommand", full_command, tan);
|
||||
@@ -1725,6 +1737,55 @@ void JsonAPI::handleInputSourceCommand(const QJsonObject& message, const QString
|
||||
}
|
||||
}
|
||||
|
||||
void JsonAPI::handleServiceCommand(const QJsonObject &message, const QString &command, int tan)
|
||||
{
|
||||
DebugIf(verbose, _log, "message: [%s]", QString(QJsonDocument(message).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
|
||||
const QString &subc = message["subcommand"].toString().trimmed();
|
||||
const QString type = message["serviceType"].toString().trimmed();
|
||||
|
||||
QString full_command = command + "-" + subc;
|
||||
|
||||
if (subc == "discover")
|
||||
{
|
||||
QByteArray serviceType;
|
||||
|
||||
QJsonObject servicesDiscovered;
|
||||
QJsonObject servicesOfType;
|
||||
QJsonArray serviceList;
|
||||
|
||||
#ifdef ENABLE_MDNS
|
||||
QString discoveryMethod("mDNS");
|
||||
serviceType = MdnsServiceRegister::getServiceType(type);
|
||||
#else
|
||||
QString discoveryMethod("ssdp");
|
||||
#endif
|
||||
if (!serviceType.isEmpty())
|
||||
{
|
||||
#ifdef ENABLE_MDNS
|
||||
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
|
||||
Qt::QueuedConnection, Q_ARG(QByteArray, serviceType));
|
||||
|
||||
serviceList = MdnsBrowser::getInstance().getServicesDiscoveredJson(serviceType, MdnsServiceRegister::getServiceNameFilter(type), DEFAULT_DISCOVER_TIMEOUT);
|
||||
#endif
|
||||
servicesOfType.insert(type, serviceList);
|
||||
|
||||
servicesDiscovered.insert("discoveryMethod", discoveryMethod);
|
||||
servicesDiscovered.insert("services", servicesOfType);
|
||||
|
||||
sendSuccessDataReply(QJsonDocument(servicesDiscovered), full_command, tan);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendErrorReply(QString("Discovery of service type [%1] via %2 not supported").arg(type, discoveryMethod), full_command, tan);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendErrorReply("Unknown or missing subcommand", full_command, tan);
|
||||
}
|
||||
}
|
||||
|
||||
void JsonAPI::handleNotImplemented(const QString &command, int tan)
|
||||
{
|
||||
sendErrorReply("Command not implemented", command, tan);
|
||||
|
@@ -9,10 +9,6 @@
|
||||
// components
|
||||
|
||||
#include <hyperion/ComponentRegister.h>
|
||||
// bonjour wrapper
|
||||
#ifdef ENABLE_AVAHI
|
||||
#include <bonjour/bonjourbrowserwrapper.h>
|
||||
#endif
|
||||
// priorityMuxer
|
||||
|
||||
#include <hyperion/PriorityMuxer.h>
|
||||
@@ -33,12 +29,9 @@ JsonCB::JsonCB(QObject* parent)
|
||||
: QObject(parent)
|
||||
, _hyperion(nullptr)
|
||||
, _componentRegister(nullptr)
|
||||
#ifdef ENABLE_AVAHI
|
||||
, _bonjour(BonjourBrowserWrapper::getInstance())
|
||||
#endif
|
||||
, _prioMuxer(nullptr)
|
||||
{
|
||||
_availableCommands << "components-update" << "sessions-update" << "priorities-update" << "imageToLedMapping-update"
|
||||
_availableCommands << "components-update" << "priorities-update" << "imageToLedMapping-update"
|
||||
<< "adjustment-update" << "videomode-update" << "settings-update" << "leds-update" << "instance-update" << "token-update";
|
||||
|
||||
#if defined(ENABLE_EFFECTENGINE)
|
||||
@@ -66,16 +59,6 @@ bool JsonCB::subscribeFor(const QString& type, bool unsubscribe)
|
||||
connect(_componentRegister, &ComponentRegister::updatedComponentState, this, &JsonCB::handleComponentState, Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
if(type == "sessions-update")
|
||||
{
|
||||
#ifdef ENABLE_AVAHI
|
||||
if(unsubscribe)
|
||||
disconnect(_bonjour, &BonjourBrowserWrapper::browserChange, this, &JsonCB::handleBonjourChange);
|
||||
else
|
||||
connect(_bonjour, &BonjourBrowserWrapper::browserChange, this, &JsonCB::handleBonjourChange, Qt::UniqueConnection);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(type == "priorities-update")
|
||||
{
|
||||
if (unsubscribe)
|
||||
@@ -208,26 +191,6 @@ void JsonCB::handleComponentState(hyperion::Components comp, bool state)
|
||||
|
||||
doCallback("components-update", QVariant(data));
|
||||
}
|
||||
#ifdef ENABLE_AVAHI
|
||||
void JsonCB::handleBonjourChange(const QMap<QString,BonjourRecord>& bRegisters)
|
||||
{
|
||||
QJsonArray data;
|
||||
for (const auto & session: bRegisters)
|
||||
{
|
||||
if (session.port<0) continue;
|
||||
QJsonObject item;
|
||||
item["name"] = session.serviceName;
|
||||
item["type"] = session.registeredType;
|
||||
item["domain"] = session.replyDomain;
|
||||
item["host"] = session.hostName;
|
||||
item["address"]= session.address;
|
||||
item["port"] = session.port;
|
||||
data.append(item);
|
||||
}
|
||||
|
||||
doCallback("sessions-update", QVariant(data));
|
||||
}
|
||||
#endif
|
||||
|
||||
void JsonCB::handlePriorityUpdate(int currentPriority, const PriorityMuxer::InputsMap& activeInputs)
|
||||
{
|
||||
|
Reference in New Issue
Block a user