populate zeroconf/avahi/bonjour records via json api (#419)

* start of integrating a bonkour service browser

* some experiments

* blub

* bonjour browser via jsonrpc ...

* fix indention

* - make leddevice as component
- extend sysinfo with domain
- add more data for  bonjour browser (e.g. split domain and hostname)

* code cleanup

* add translation

* use component names instead of ids

* fix compile
This commit is contained in:
redPanther 2017-03-21 17:55:46 +01:00 committed by GitHub
parent 9a0e1daf7b
commit 0aa467cceb
25 changed files with 601 additions and 95 deletions

View File

@ -21,6 +21,7 @@
"general_comp_BOBLIGHTSERVER" : "Boblight Server", "general_comp_BOBLIGHTSERVER" : "Boblight Server",
"general_comp_GRABBER" : "Plattform Aufnahme", "general_comp_GRABBER" : "Plattform Aufnahme",
"general_comp_V4L" : "USB Aufnahme", "general_comp_V4L" : "USB Aufnahme",
"general_comp_LEDDEVICE" : "LED Hardware",
"general_col_red" : "rot", "general_col_red" : "rot",
"general_col_green" : "grün", "general_col_green" : "grün",
"general_col_blue" : "blau", "general_col_blue" : "blau",

View File

@ -21,6 +21,7 @@
"general_comp_BOBLIGHTSERVER" : "Boblight Server", "general_comp_BOBLIGHTSERVER" : "Boblight Server",
"general_comp_GRABBER" : "Platform Capture", "general_comp_GRABBER" : "Platform Capture",
"general_comp_V4L" : "USB Capture", "general_comp_V4L" : "USB Capture",
"general_comp_LEDDEVICE" : "LED device",
"general_col_red" : "red", "general_col_red" : "red",
"general_col_green" : "green", "general_col_green" : "green",
"general_col_blue" : "blue", "general_col_blue" : "blue",

View File

@ -119,26 +119,24 @@ $(document).ready(function() {
} }
if(ip) if(ip)
origin += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_ip')+' '+ip+'</span>'; origin += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_ip')+' '+ip+'</span>';
if(compId == 10) if(compId == "EFFECT")
owner = $.i18n('remote_effects_label_effects')+' '+owner; owner = $.i18n('remote_effects_label_effects')+' '+owner;
if(compId == 9) if(compId == "COLOR")
owner = $.i18n('remote_color_label_color')+' '+'<div style="width:18px; height:18px; border-radius:20px; margin-bottom:-4px; border:1px grey solid; background-color: rgb('+prios[i].value.RGB+'); display:inline-block" title="RGB: ('+prios[i].value.RGB+')"></div>'; owner = (owner == "Off") ? $.i18n('general_btn_off') : $.i18n('remote_color_label_color')+' '+'<div style="width:18px; height:18px; border-radius:20px; margin-bottom:-4px; border:1px grey solid; background-color: rgb('+prios[i].value.RGB+'); display:inline-block" title="RGB: ('+prios[i].value.RGB+')"></div>';
if(compId == 7) if(compId == "GRABBER")
owner = $.i18n('general_comp_GRABBER')+': ('+owner+')'; owner = $.i18n('general_comp_GRABBER')+': ('+owner+')';
if(compId == 8) if(compId == "V4L")
owner = $.i18n('general_comp_V4L')+': ('+owner+')'; owner = $.i18n('general_comp_V4L')+': ('+owner+')';
if(compId == 6) if(compId == "BOBLIGHTSERVER")
owner = $.i18n('general_comp_BOBLIGHTSERVER'); owner = $.i18n('general_comp_BOBLIGHTSERVER');
if(compId == 5) if(compId == "UDPLISTENER")
owner = $.i18n('general_comp_UDPLISTENER'); owner = $.i18n('general_comp_UDPLISTENER');
if(owner == "Off") if(duration && compId != "GRABBER" && compId != "PROTOSERVER")
owner = $.i18n('general_btn_off');
if(duration && compId != 7 && compId != 11)
owner += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_duration')+' '+duration.toFixed(0)+$.i18n('edt_append_s')+'</span>'; owner += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_duration')+' '+duration.toFixed(0)+$.i18n('edt_append_s')+'</span>';
var btn = '<button id="srcBtn'+i+'" type="button" '+btn_state+' class="btn btn-'+btn_type+' btn_input_selection" onclick="requestSetSource('+priority+');">'+btn_text+'</button>'; var btn = '<button id="srcBtn'+i+'" type="button" '+btn_state+' class="btn btn-'+btn_type+' btn_input_selection" onclick="requestSetSource('+priority+');">'+btn_text+'</button>';
if((compId == 10 || compId == 9) && priority != 254) if((compId == "EFFECT" || compId == "COLOR") && priority < 254)
btn += '<button type="button" class="btn btn-sm btn-danger" style="margin-left:10px;" onclick="requestPriorityClear('+priority+');"><i class="fa fa-close"></button>'; btn += '<button type="button" class="btn btn-sm btn-danger" style="margin-left:10px;" onclick="requestPriorityClear('+priority+');"><i class="fa fa-close"></button>';
if(btn_type != 'default') if(btn_type != 'default')

View File

@ -5,14 +5,14 @@ Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, 1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, 2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products 3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@ -35,24 +35,34 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class BonjourRecord class BonjourRecord
{ {
public: public:
BonjourRecord() {} BonjourRecord() : port(-1) {}
BonjourRecord(const QString &name, const QString &regType, const QString &domain) BonjourRecord(const QString &name, const QString &regType, const QString &domain)
: serviceName(name), registeredType(regType), replyDomain(domain) : serviceName(name)
{} , registeredType(regType)
BonjourRecord(const char *name, const char *regType, const char *domain) , replyDomain(domain)
{ , port(-1)
serviceName = QString::fromUtf8(name); {}
registeredType = QString::fromUtf8(regType);
replyDomain = QString::fromUtf8(domain); BonjourRecord(const char *name, const char *regType, const char *domain)
} : serviceName(QString::fromUtf8(name))
QString serviceName; , registeredType(QString::fromUtf8(regType))
QString registeredType; , replyDomain(QString::fromUtf8(domain))
QString replyDomain; , port(-1)
bool operator==(const BonjourRecord &other) const { {
return serviceName == other.serviceName }
&& registeredType == other.registeredType
&& replyDomain == other.replyDomain; QString serviceName;
} QString registeredType;
QString replyDomain;
QString hostName;
int port;
bool operator==(const BonjourRecord &other) const
{
return serviceName == other.serviceName
&& registeredType == other.registeredType
&& replyDomain == other.replyDomain;
}
}; };
Q_DECLARE_METATYPE(BonjourRecord) Q_DECLARE_METATYPE(BonjourRecord)

View File

@ -0,0 +1,65 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BONJOURSERVICEBROWSER_H
#define BONJOURSERVICEBROWSER_H
#include <QtCore/QObject>
#include <dns_sd.h>
#include "bonjour/bonjourrecord.h"
class QSocketNotifier;
class BonjourServiceBrowser : public QObject
{
Q_OBJECT
public:
BonjourServiceBrowser(QObject *parent = 0);
~BonjourServiceBrowser();
void browseForServiceType(const QString &serviceType);
inline QList<BonjourRecord> currentRecords() const { return bonjourRecords; }
inline QString serviceType() const { return browsingType; }
signals:
void currentBonjourRecordsChanged(const QList<BonjourRecord> &list);
void error(DNSServiceErrorType err);
private slots:
void bonjourSocketReadyRead();
private:
static void DNSSD_API bonjourBrowseReply(DNSServiceRef , DNSServiceFlags flags, quint32,
DNSServiceErrorType errorCode, const char *serviceName,
const char *regType, const char *replyDomain, void *context);
DNSServiceRef dnssref;
QSocketNotifier *bonjourSocket;
QList<BonjourRecord> bonjourRecords;
QString browsingType;
};
#endif // BONJOURSERVICEBROWSER_H

View File

@ -0,0 +1,69 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BONJOURSERVICERESOLVER_H
#define BONJOURSERVICERESOLVER_H
#include <QtCore/QObject>
#include <dns_sd.h>
class QSocketNotifier;
class QHostInfo;
class BonjourRecord;
class BonjourServiceResolver : public QObject
{
Q_OBJECT
public:
BonjourServiceResolver(QObject *parent);
~BonjourServiceResolver();
bool resolveBonjourRecord(const BonjourRecord &record);
signals:
void bonjourRecordResolved(const QHostInfo &hostInfo, int port);
void error(DNSServiceErrorType error);
private slots:
void bonjourSocketReadyRead();
void cleanupResolve();
void finishConnect(const QHostInfo &hostInfo);
private:
static void DNSSD_API bonjourResolveReply(DNSServiceRef sdRef, DNSServiceFlags flags,
quint32 interfaceIndex, DNSServiceErrorType errorCode,
const char *fullName, const char *hosttarget, quint16 port,
quint16 txtLen, const char *txtRecord, void *context);
DNSServiceRef dnssref;
QSocketNotifier *bonjourSocket;
int bonjourPort;
};
#endif // BONJOURSERVICERESOLVER_H

View File

@ -2,11 +2,12 @@
// stl includes // stl includes
#include <list> #include <list>
#include <map> #include <QMap>
// QT includes // QT includes
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QStringList>
#include <QTimer> #include <QTimer>
#include <QSize> #include <QSize>
#include <QJsonObject> #include <QJsonObject>
@ -33,6 +34,8 @@
// KodiVideoChecker includes // KodiVideoChecker includes
#include <kodivideochecker/KODIVideoChecker.h> #include <kodivideochecker/KODIVideoChecker.h>
#include <bonjour/bonjourservicebrowser.h>
#include <bonjour/bonjourserviceresolver.h>
// Forward class declaration // Forward class declaration
class LedDevice; class LedDevice;
@ -52,8 +55,8 @@ class Hyperion : public QObject
public: public:
/// Type definition of the info structure used by the priority muxer /// Type definition of the info structure used by the priority muxer
typedef PriorityMuxer::InputInfo InputInfo; typedef PriorityMuxer::InputInfo InputInfo;
typedef std::map<QString,int> PriorityRegister; typedef QMap<QString,int> PriorityRegister;
typedef QMap<QString,BonjourRecord> BonjourRegister;
/// ///
/// RGB-Color channel enumeration /// RGB-Color channel enumeration
/// ///
@ -257,6 +260,9 @@ public slots:
/// sets the methode how image is maped to leds /// sets the methode how image is maped to leds
void setLedMappingType(int mappingType); void setLedMappingType(int mappingType);
///
Hyperion::BonjourRegister getHyperionSessions();
public: public:
static Hyperion *_hyperion; static Hyperion *_hyperion;
@ -302,6 +308,10 @@ private slots:
/// ///
void update(); void update();
void currentBonjourRecordsChanged(const QList<BonjourRecord> &list);
void bonjourRecordResolved(const QHostInfo &hostInfo, int port);
void bonjourResolve();
private: private:
/// ///
@ -344,6 +354,7 @@ private:
/// The timer for handling priority channel timeouts /// The timer for handling priority channel timeouts
QTimer _timer; QTimer _timer;
QTimer _timerBonjourResolver;
/// buffer for leds /// buffer for leds
std::vector<ColorRgb> _ledBuffer; std::vector<ColorRgb> _ledBuffer;
@ -373,5 +384,9 @@ private:
int _configVersionId; int _configVersionId;
hyperion::Components _prevCompId; hyperion::Components _prevCompId;
BonjourServiceBrowser _bonjourBrowser;
BonjourServiceResolver _bonjourResolver;
BonjourRegister _hyperionSessions;
QString _bonjourCurrentServiceToResolve;
}; };

View File

@ -19,6 +19,7 @@
#include <utils/RgbToRgbw.h> #include <utils/RgbToRgbw.h>
#include <utils/Logger.h> #include <utils/Logger.h>
#include <functional> #include <functional>
#include <utils/Components.h>
class LedDevice; class LedDevice;
@ -58,6 +59,12 @@ public:
static QJsonObject getLedDeviceSchemas(); static QJsonObject getLedDeviceSchemas();
static void setLedCount(int ledCount); static void setLedCount(int ledCount);
static int getLedCount() { return _ledCount; } static int getLedCount() { return _ledCount; }
void setEnable(bool enable);
bool enabled() { return _enabled; };
inline bool componentState() { return enabled(); };
protected: protected:
/// ///
/// Writes the RGB-Color values to the leds. /// Writes the RGB-Color values to the leds.
@ -95,4 +102,6 @@ protected slots:
private: private:
std::vector<ColorRgb> _ledValues; std::vector<ColorRgb> _ledValues;
bool _componentRegistered;
bool _enabled;
}; };

View File

@ -19,7 +19,8 @@ enum Components
COMP_V4L, COMP_V4L,
COMP_COLOR, COMP_COLOR,
COMP_EFFECT, COMP_EFFECT,
COMP_PROTOSERVER COMP_PROTOSERVER,
COMP_LEDDEVICE
}; };
inline const char* componentToString(Components c) inline const char* componentToString(Components c)
@ -37,6 +38,7 @@ inline const char* componentToString(Components c)
case COMP_COLOR: return "Solid color"; case COMP_COLOR: return "Solid color";
case COMP_EFFECT: return "Effect"; case COMP_EFFECT: return "Effect";
case COMP_PROTOSERVER: return "Proto Server"; case COMP_PROTOSERVER: return "Proto Server";
case COMP_LEDDEVICE: return "LED device";
default: return ""; default: return "";
} }
} }
@ -56,6 +58,7 @@ inline const char* componentToIdString(Components c)
case COMP_COLOR: return "COLOR"; case COMP_COLOR: return "COLOR";
case COMP_EFFECT: return "EFFECT"; case COMP_EFFECT: return "EFFECT";
case COMP_PROTOSERVER: return "PROTOSERVER"; case COMP_PROTOSERVER: return "PROTOSERVER";
case COMP_LEDDEVICE: return "LEDDEVICE";
default: return ""; default: return "";
} }
} }
@ -74,6 +77,7 @@ inline Components stringToComponent(QString component)
if (component == "COLOR") return COMP_COLOR; if (component == "COLOR") return COMP_COLOR;
if (component == "EFFECT") return COMP_EFFECT; if (component == "EFFECT") return COMP_EFFECT;
if (component == "PROTOSERVER") return COMP_PROTOSERVER; if (component == "PROTOSERVER") return COMP_PROTOSERVER;
if (component == "LEDDEVICE") return COMP_LEDDEVICE;
return COMP_INVALID; return COMP_INVALID;
} }

View File

@ -18,6 +18,7 @@ public:
QString productVersion; QString productVersion;
QString prettyName; QString prettyName;
QString hostName; QString hostName;
QString domainName;
}; };
~SysInfo(); ~SysInfo();

View File

@ -6,6 +6,8 @@ set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/bonjour)
# Group the headers that go through the MOC compiler # Group the headers that go through the MOC compiler
set(Bonjour_QT_HEADERS set(Bonjour_QT_HEADERS
${CURRENT_HEADER_DIR}/bonjourserviceregister.h ${CURRENT_HEADER_DIR}/bonjourserviceregister.h
${CURRENT_HEADER_DIR}/bonjourservicebrowser.h
${CURRENT_HEADER_DIR}/bonjourserviceresolver.h
) )
set(Bonjour_HEADERS set(Bonjour_HEADERS
@ -13,13 +15,15 @@ set(Bonjour_HEADERS
set(Bonjour_SOURCES set(Bonjour_SOURCES
${CURRENT_SOURCE_DIR}/bonjourserviceregister.cpp ${CURRENT_SOURCE_DIR}/bonjourserviceregister.cpp
${CURRENT_SOURCE_DIR}/bonjourservicebrowser.cpp
${CURRENT_SOURCE_DIR}/bonjourserviceresolver.cpp
) )
set(Bonjour_RESOURCES #set(Bonjour_RESOURCES
) #)
qt5_wrap_cpp(Bonjour_HEADERS_MOC ${Bonjour_QT_HEADERS}) qt5_wrap_cpp(Bonjour_HEADERS_MOC ${Bonjour_QT_HEADERS})
qt5_add_resources(Bonjour_RESOURCES_RCC ${Bonjour_RESOURCES} OPTIONS "-no-compress") #qt5_add_resources(Bonjour_RESOURCES_RCC ${Bonjour_RESOURCES} OPTIONS "-no-compress")
add_library(bonjour add_library(bonjour
${Bonjour_HEADERS} ${Bonjour_HEADERS}

View File

@ -0,0 +1,109 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bonjour/bonjourservicebrowser.h"
#include <QtCore/QSocketNotifier>
BonjourServiceBrowser::BonjourServiceBrowser(QObject *parent)
: QObject(parent)
, dnssref(0)
, bonjourSocket(0)
{
}
BonjourServiceBrowser::~BonjourServiceBrowser()
{
if (dnssref)
{
DNSServiceRefDeallocate(dnssref);
dnssref = 0;
}
}
void BonjourServiceBrowser::browseForServiceType(const QString &serviceType)
{
DNSServiceErrorType err = DNSServiceBrowse(&dnssref, 0, 0, serviceType.toUtf8().constData(), 0, bonjourBrowseReply, this);
if (err != kDNSServiceErr_NoError)
{
emit error(err);
}
else
{
int sockfd = DNSServiceRefSockFD(dnssref);
if (sockfd == -1)
{
emit error(kDNSServiceErr_Invalid);
}
else
{
bonjourSocket = new QSocketNotifier(sockfd, QSocketNotifier::Read, this);
connect(bonjourSocket, SIGNAL(activated(int)), this, SLOT(bonjourSocketReadyRead()));
}
}
}
void BonjourServiceBrowser::bonjourSocketReadyRead()
{
DNSServiceErrorType err = DNSServiceProcessResult(dnssref);
if (err != kDNSServiceErr_NoError)
{
emit error(err);
}
}
void BonjourServiceBrowser::bonjourBrowseReply(DNSServiceRef , DNSServiceFlags flags,
quint32 , DNSServiceErrorType errorCode,
const char *serviceName, const char *regType,
const char *replyDomain, void *context)
{
BonjourServiceBrowser *serviceBrowser = static_cast<BonjourServiceBrowser *>(context);
if (errorCode != kDNSServiceErr_NoError)
{
emit serviceBrowser->error(errorCode);
}
else
{
BonjourRecord bonjourRecord(serviceName, regType, replyDomain);
if (flags & kDNSServiceFlagsAdd)
{
if (!serviceBrowser->bonjourRecords.contains(bonjourRecord))
{
serviceBrowser->bonjourRecords.append(bonjourRecord);
}
}
else
{
serviceBrowser->bonjourRecords.removeAll(bonjourRecord);
}
if (!(flags & kDNSServiceFlagsMoreComing))
{
emit serviceBrowser->currentBonjourRecordsChanged(serviceBrowser->bonjourRecords);
}
}
}

View File

@ -0,0 +1,122 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <QtCore/QSocketNotifier>
#include <QtNetwork/QHostInfo>
#include "bonjour/bonjourrecord.h"
#include "bonjour/bonjourserviceresolver.h"
BonjourServiceResolver::BonjourServiceResolver(QObject *parent)
: QObject(parent)
, dnssref(0)
, bonjourSocket(0)
, bonjourPort(-1)
{
}
BonjourServiceResolver::~BonjourServiceResolver()
{
cleanupResolve();
}
void BonjourServiceResolver::cleanupResolve()
{
if (dnssref)
{
DNSServiceRefDeallocate(dnssref);
dnssref = 0;
delete bonjourSocket;
bonjourPort = -1;
}
}
bool BonjourServiceResolver::resolveBonjourRecord(const BonjourRecord &record)
{
if (dnssref)
{
//qWarning("resolve in process, aborting");
return false;
}
DNSServiceErrorType err = DNSServiceResolve(&dnssref, 0, 0,
record.serviceName.toUtf8().constData(),
record.registeredType.toUtf8().constData(),
record.replyDomain.toUtf8().constData(),
(DNSServiceResolveReply)bonjourResolveReply, this);
if (err != kDNSServiceErr_NoError)
{
emit error(err);
}
else
{
int sockfd = DNSServiceRefSockFD(dnssref);
if (sockfd == -1)
{
emit error(kDNSServiceErr_Invalid);
}
else
{
bonjourSocket = new QSocketNotifier(sockfd, QSocketNotifier::Read, this);
connect(bonjourSocket, SIGNAL(activated(int)), this, SLOT(bonjourSocketReadyRead()));
}
}
return true;
}
void BonjourServiceResolver::bonjourSocketReadyRead()
{
DNSServiceErrorType err = DNSServiceProcessResult(dnssref);
if (err != kDNSServiceErr_NoError)
emit error(err);
}
void BonjourServiceResolver::bonjourResolveReply(DNSServiceRef sdRef, DNSServiceFlags ,
quint32 , DNSServiceErrorType errorCode,
const char *, const char *hosttarget, quint16 port,
quint16 , const char *, void *context)
{
BonjourServiceResolver *serviceResolver = static_cast<BonjourServiceResolver *>(context);
if (errorCode != kDNSServiceErr_NoError) {
emit serviceResolver->error(errorCode);
return;
}
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
{
port = 0 | ((port & 0x00ff) << 8) | ((port & 0xff00) >> 8);
}
#endif
serviceResolver->bonjourPort = port;
QHostInfo::lookupHost(QString::fromUtf8(hosttarget), serviceResolver, SLOT(finishConnect(const QHostInfo &)));
}
void BonjourServiceResolver::finishConnect(const QHostInfo &hostInfo)
{
emit bonjourRecordResolved(hostInfo, bonjourPort);
QMetaObject::invokeMethod(this, "cleanupResolve", Qt::QueuedConnection);
}

View File

@ -57,5 +57,6 @@ target_link_libraries(hyperion
blackborder blackborder
hyperion-utils hyperion-utils
leddevice leddevice
bonjour
${QT_LIBRARIES} ${QT_LIBRARIES}
) )

View File

@ -3,6 +3,7 @@
#include <cassert> #include <cassert>
#include <exception> #include <exception>
#include <sstream> #include <sstream>
#include <unistd.h>
// QT includes // QT includes
#include <QDateTime> #include <QDateTime>
@ -13,6 +14,7 @@
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QHostInfo>
// hyperion include // hyperion include
#include <hyperion/Hyperion.h> #include <hyperion/Hyperion.h>
@ -317,8 +319,7 @@ QSize Hyperion::getLedLayoutGridSize(const QJsonValue& ledsConfig)
LinearColorSmoothing * Hyperion::createColorSmoothing(const QJsonObject & smoothingConfig, LedDevice* leddevice) LinearColorSmoothing * Hyperion::createColorSmoothing(const QJsonObject & smoothingConfig, LedDevice* leddevice){
{
QString type = smoothingConfig["type"].toString("linear").toLower(); QString type = smoothingConfig["type"].toString("linear").toLower();
LinearColorSmoothing * device = nullptr; LinearColorSmoothing * device = nullptr;
type = "linear"; // TODO currently hardcoded type, delete it if we have more types type = "linear"; // TODO currently hardcoded type, delete it if we have more types
@ -390,12 +391,15 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile)
, _qjsonConfig(qjsonConfig) , _qjsonConfig(qjsonConfig)
, _configFile(configFile) , _configFile(configFile)
, _timer() , _timer()
, _timerBonjourResolver()
, _log(CORE_LOGGER) , _log(CORE_LOGGER)
, _hwLedCount(_ledString.leds().size()) , _hwLedCount(_ledString.leds().size())
, _sourceAutoSelectEnabled(true) , _sourceAutoSelectEnabled(true)
, _configHash() , _configHash()
, _ledGridSize(getLedLayoutGridSize(qjsonConfig["leds"])) , _ledGridSize(getLedLayoutGridSize(qjsonConfig["leds"]))
, _prevCompId(hyperion::COMP_INVALID) , _prevCompId(hyperion::COMP_INVALID)
, _bonjourBrowser(this)
, _bonjourResolver(this)
{ {
registerPriority("Off", PriorityMuxer::LOWEST_PRIORITY); registerPriority("Off", PriorityMuxer::LOWEST_PRIORITY);
@ -406,6 +410,10 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile)
// set color correction activity state // set color correction activity state
const QJsonObject& color = qjsonConfig["color"].toObject(); const QJsonObject& color = qjsonConfig["color"].toObject();
_bonjourBrowser.browseForServiceType(QLatin1String("_hyperiond-http._tcp"));
connect(&_bonjourBrowser, SIGNAL(currentBonjourRecordsChanged(const QList<BonjourRecord>&)),this, SLOT(currentBonjourRecordsChanged(const QList<BonjourRecord> &)));
connect(&_bonjourResolver, SIGNAL(bonjourRecordResolved(const QHostInfo &, int)), this, SLOT(bonjourRecordResolved(const QHostInfo &, int)));
// initialize the image processor factory // initialize the image processor factory
_ledMAppingType = ImageProcessor::mappingTypeToInt(color["imageToLedMappingType"].toString()); _ledMAppingType = ImageProcessor::mappingTypeToInt(color["imageToLedMappingType"].toString());
ImageProcessorFactory::getInstance().init(_ledString, qjsonConfig["blackborderdetector"].toObject(),_ledMAppingType ); ImageProcessorFactory::getInstance().init(_ledString, qjsonConfig["blackborderdetector"].toObject(),_ledMAppingType );
@ -416,11 +424,17 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile)
_device = LedDeviceFactory::construct(qjsonConfig["device"].toObject(),_hwLedCount); _device = LedDeviceFactory::construct(qjsonConfig["device"].toObject(),_hwLedCount);
_deviceSmooth = createColorSmoothing(qjsonConfig["smoothing"].toObject(), _device); _deviceSmooth = createColorSmoothing(qjsonConfig["smoothing"].toObject(), _device);
getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState()); getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState());
getComponentRegister().componentStateChanged(hyperion::COMP_LEDDEVICE, _device->componentState());
// setup the timer // setup the timer
_timer.setSingleShot(true); _timer.setSingleShot(true);
QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update())); QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
_timerBonjourResolver.setSingleShot(false);
_timerBonjourResolver.setInterval(1000);
QObject::connect(&_timerBonjourResolver, SIGNAL(timeout()), this, SLOT(bonjourResolve()));
_timerBonjourResolver.start();
// create the effect engine // create the effect engine
_effectEngine = new EffectEngine(this,qjsonConfig["effects"].toObject()); _effectEngine = new EffectEngine(this,qjsonConfig["effects"].toObject());
@ -470,6 +484,48 @@ unsigned Hyperion::getLedCount() const
return _ledString.leds().size(); return _ledString.leds().size();
} }
void Hyperion::currentBonjourRecordsChanged(const QList<BonjourRecord> &list)
{
_hyperionSessions.clear();
for ( auto rec : list )
{
_hyperionSessions.insert(rec.serviceName, rec);
}
}
void Hyperion::bonjourRecordResolved(const QHostInfo &hostInfo, int port)
{
if ( _hyperionSessions.contains(_bonjourCurrentServiceToResolve))
{
QString host = hostInfo.hostName();
QString domain = _hyperionSessions[_bonjourCurrentServiceToResolve].replyDomain;
if (host.endsWith("."+domain))
{
host.remove(host.length()-domain.length()-1,domain.length()+1);
}
_hyperionSessions[_bonjourCurrentServiceToResolve].hostName = host;
_hyperionSessions[_bonjourCurrentServiceToResolve].port = port;
Debug(_log, "found hyperion session: %s:%d",QSTRING_CSTR(hostInfo.hostName()), port);
}
}
void Hyperion::bonjourResolve()
{
for(auto key : _hyperionSessions.keys())
{
if (_hyperionSessions[key].port < 0)
{
_bonjourCurrentServiceToResolve = key;
_bonjourResolver.resolveBonjourRecord(_hyperionSessions[key]);
break;
}
}
}
Hyperion::BonjourRegister Hyperion::getHyperionSessions()
{
return _hyperionSessions;
}
bool Hyperion::configModified() bool Hyperion::configModified()
{ {
@ -507,19 +563,19 @@ void Hyperion::registerPriority(const QString &name, const int priority/*, const
{ {
Info(_log, "Register new input source named '%s' for priority channel '%d'", QSTRING_CSTR(name), priority ); Info(_log, "Register new input source named '%s' for priority channel '%d'", QSTRING_CSTR(name), priority );
for(auto const &entry : _priorityRegister) for(auto key : _priorityRegister.keys())
{ {
WarningIf( ( entry.first != name && entry.second == priority), _log, WarningIf( ( key != name && _priorityRegister.value(key) == priority), _log,
"Input source '%s' uses same priority channel (%d) as '%s'.", QSTRING_CSTR(name), priority, QSTRING_CSTR(entry.first)); "Input source '%s' uses same priority channel (%d) as '%s'.", QSTRING_CSTR(name), priority, QSTRING_CSTR(key));
} }
_priorityRegister.emplace(name,priority); _priorityRegister.insert(name, priority);
} }
void Hyperion::unRegisterPriority(const QString &name) void Hyperion::unRegisterPriority(const QString &name)
{ {
Info(_log, "Unregister input source named '%s' from priority register", QSTRING_CSTR(name)); Info(_log, "Unregister input source named '%s' from priority register", QSTRING_CSTR(name));
_priorityRegister.erase(name); _priorityRegister.remove(name);
} }
void Hyperion::setSourceAutoSelectEnabled(bool enabled) void Hyperion::setSourceAutoSelectEnabled(bool enabled)
@ -550,14 +606,20 @@ bool Hyperion::setCurrentSourcePriority(int priority )
void Hyperion::setComponentState(const hyperion::Components component, const bool state) void Hyperion::setComponentState(const hyperion::Components component, const bool state)
{ {
if (component == hyperion::COMP_SMOOTHING) switch (component)
{ {
_deviceSmooth->setEnable(state); case hyperion::COMP_SMOOTHING:
getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState()); _deviceSmooth->setEnable(state);
} getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState());
else break;
{
emit componentStateChanged(component, state); case hyperion::COMP_LEDDEVICE:
_device->setEnable(state);
getComponentRegister().componentStateChanged(hyperion::COMP_LEDDEVICE, _device->componentState());
break;
default:
emit componentStateChanged(component, state);
} }
} }
@ -785,10 +847,13 @@ void Hyperion::update()
} }
// Write the data to the device // Write the data to the device
if (_deviceSmooth->enabled()) if (_device->enabled())
_deviceSmooth->setLedValues(_ledBuffer); {
else if (_deviceSmooth->enabled())
_device->setLedValues(_ledBuffer); _deviceSmooth->setLedValues(_ledBuffer);
else
_device->setLedValues(_ledBuffer);
}
// Start the timeout-timer // Start the timeout-timer
if (priorityInfo.timeoutTime_ms == -1) if (priorityInfo.timeoutTime_ms == -1)
@ -800,4 +865,5 @@ void Hyperion::update()
int timeout_ms = std::max(0, int(priorityInfo.timeoutTime_ms - QDateTime::currentMSecsSinceEpoch())); int timeout_ms = std::max(0, int(priorityInfo.timeoutTime_ms - QDateTime::currentMSecsSinceEpoch()));
_timer.start(timeout_ms); _timer.start(timeout_ms);
} }
} }

View File

@ -17,7 +17,6 @@ LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, double ledUpd
, _outputDelay(updateDelay) , _outputDelay(updateDelay)
, _writeToLedsEnable(true) , _writeToLedsEnable(true)
, _continuousOutput(continuousOutput) , _continuousOutput(continuousOutput)
, _enabled(true)
{ {
_log = Logger::getInstance("Smoothing"); _log = Logger::getInstance("Smoothing");
_timer.setSingleShot(false); _timer.setSingleShot(false);
@ -143,7 +142,8 @@ void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> & ledColors)
void LinearColorSmoothing::setEnable(bool enable) void LinearColorSmoothing::setEnable(bool enable)
{ {
_enabled = enable; LedDevice::setEnable(enable);
if (!enable) if (!enable)
{ {
_timer.stop(); _timer.stop();
@ -151,8 +151,3 @@ void LinearColorSmoothing::setEnable(bool enable)
} }
} }
bool LinearColorSmoothing::enabled()
{
return _enabled;
}

View File

@ -41,9 +41,6 @@ public:
virtual int switchOff(); virtual int switchOff();
void setEnable(bool enable); void setEnable(bool enable);
bool enabled();
bool componentState() { return enabled(); };
private slots: private slots:
/// Timer callback which writes updated led values to the led device /// Timer callback which writes updated led values to the led device
@ -91,6 +88,4 @@ private:
/// Flag for dis/enable continuous output to led device regardless there is new data or not /// Flag for dis/enable continuous output to led device regardless there is new data or not
bool _continuousOutput; bool _continuousOutput;
bool _enabled;
}; };

View File

@ -11,9 +11,11 @@ PriorityMuxer::PriorityMuxer(int ledCount)
, _activeInputs() , _activeInputs()
, _lowestPriorityInfo() , _lowestPriorityInfo()
{ {
_lowestPriorityInfo.priority = LOWEST_PRIORITY; _lowestPriorityInfo.priority = LOWEST_PRIORITY;
_lowestPriorityInfo.timeoutTime_ms = -1; _lowestPriorityInfo.timeoutTime_ms = -1;
_lowestPriorityInfo.ledColors = std::vector<ColorRgb>(ledCount, {0, 0, 0}); _lowestPriorityInfo.ledColors = std::vector<ColorRgb>(ledCount, {0, 0, 0});
_lowestPriorityInfo.componentId = hyperion::COMP_COLOR;
_lowestPriorityInfo.origin = "System";
_activeInputs[_currentPriority] = _lowestPriorityInfo; _activeInputs[_currentPriority] = _lowestPriorityInfo;
} }

View File

@ -48,6 +48,8 @@
using namespace hyperion; using namespace hyperion;
int _connectionCounter = 0;
JsonClientConnection::JsonClientConnection(QTcpSocket *socket) JsonClientConnection::JsonClientConnection(QTcpSocket *socket)
: QObject() : QObject()
, _socket(socket) , _socket(socket)
@ -577,6 +579,7 @@ void JsonClientConnection::handleSysInfoCommand(const QJsonObject&, const QStrin
system["productVersion"] = data.productVersion; system["productVersion"] = data.productVersion;
system["prettyName" ] = data.prettyName; system["prettyName" ] = data.prettyName;
system["hostName" ] = data.hostName; system["hostName" ] = data.hostName;
system["domainName" ] = data.domainName;
info["system"] = system; info["system"] = system;
QJsonObject hyperion; QJsonObject hyperion;
@ -619,22 +622,21 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
} }
item["owner"] = QString(hyperion::componentToIdString(priorityInfo.componentId)); item["owner"] = QString(hyperion::componentToIdString(priorityInfo.componentId));
item["componentId"] = priorityInfo.componentId; item["componentId"] = QString(hyperion::componentToIdString(priorityInfo.componentId));
item["origin"] = priorityInfo.origin; item["origin"] = priorityInfo.origin;
item["component"] = QString(hyperion::componentToString(priorityInfo.componentId)); item["component"] = QString(hyperion::componentToString(priorityInfo.componentId));
item["active"] = true; item["active"] = true;
item["visible"] = (priority == currentPriority); item["visible"] = (priority == currentPriority);
foreach(auto const &entry, priorityRegister)
// remove item from prio register, because we have more valuable information via active priority
QList<QString> prios = priorityRegister.keys(priority);
if (! prios.empty())
{ {
if (entry.second == priority) item["owner"] = prios[0];
{ priorityRegister.remove(prios[0]);
item["owner"] = entry.first;
priorityRegister.erase(entry.first);
break;
}
} }
if(priorityInfo.componentId == 9) if(priorityInfo.componentId == hyperion::COMP_COLOR)
{ {
QJsonObject LEDcolor; QJsonObject LEDcolor;
@ -680,13 +682,14 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
priorities.append(item); priorities.append(item);
} }
foreach(auto const &entry, priorityRegister) // append left over priorities
for(auto key : priorityRegister.keys())
{ {
QJsonObject item; QJsonObject item;
item["priority"] = entry.second; item["priority"] = priorityRegister[key];
item["active"] = false; item["active"] = false;
item["visible"] = false; item["visible"] = false;
item["owner"] = entry.first; item["owner"] = key;
priorities.append(item); priorities.append(item);
} }
@ -827,6 +830,22 @@ void JsonClientConnection::handleServerInfoCommand(const QJsonObject&, const QSt
QJsonObject hyperion; QJsonObject hyperion;
hyperion["config_modified" ] = _hyperion->configModified(); hyperion["config_modified" ] = _hyperion->configModified();
hyperion["config_writeable"] = _hyperion->configWriteable(); hyperion["config_writeable"] = _hyperion->configWriteable();
// sessions
QJsonArray sessions;
for (auto session: _hyperion->getHyperionSessions())
{
if (session.port<0) continue;
QJsonObject item;
item["name"] = session.serviceName;
item["type"] = session.registeredType;
item["domain"] = session.replyDomain;
item["host"] = session.hostName;
item["port"] = session.port;
sessions.append(item);
}
hyperion["sessions"] = sessions;
info["hyperion"] = hyperion; info["hyperion"] = hyperion;
// send the result // send the result

View File

@ -21,7 +21,7 @@
"component": "component":
{ {
"type" : "string", "type" : "string",
"enum" : ["SMOOTHING", "BLACKBORDER", "KODICHECKER", "FORWARDER", "UDPLISTENER", "BOBLIGHTSERVER", "GRABBER", "V4L"], "enum" : ["SMOOTHING", "BLACKBORDER", "KODICHECKER", "FORWARDER", "UDPLISTENER", "BOBLIGHTSERVER", "GRABBER", "V4L", "LEDDEVICE"],
"required": true "required": true
}, },
"state": "state":

View File

@ -5,6 +5,7 @@
#include <QResource> #include <QResource>
#include <QStringList> #include <QStringList>
#include <QDir> #include <QDir>
#include "hyperion/Hyperion.h"
LedDeviceRegistry LedDevice::_ledDeviceMap = LedDeviceRegistry(); LedDeviceRegistry LedDevice::_ledDeviceMap = LedDeviceRegistry();
QString LedDevice::_activeDevice = ""; QString LedDevice::_activeDevice = "";
@ -19,8 +20,11 @@ LedDevice::LedDevice()
, _deviceReady(true) , _deviceReady(true)
, _refresh_timer() , _refresh_timer()
, _refresh_timer_interval(0) , _refresh_timer_interval(0)
, _componentRegistered(false)
, _enabled(true)
{ {
LedDevice::getLedDeviceSchemas(); LedDevice::getLedDeviceSchemas();
qRegisterMetaType<hyperion::Components>("hyperion::Components");
// setup timer // setup timer
_refresh_timer.setSingleShot(false); _refresh_timer.setSingleShot(false);
@ -34,6 +38,16 @@ int LedDevice::open()
return 0; return 0;
} }
void LedDevice::setEnable(bool enable)
{
if ( _enabled && !enable)
{
switchOff();
}
_enabled = enable;
}
int LedDevice::addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr) int LedDevice::addToDeviceMap(QString name, LedDeviceCreateFuncType funcPtr)
{ {
_ledDeviceMap.emplace(name,funcPtr); _ledDeviceMap.emplace(name,funcPtr);
@ -111,10 +125,9 @@ QJsonObject LedDevice::getLedDeviceSchemas()
return result; return result;
} }
int LedDevice::setLedValues(const std::vector<ColorRgb>& ledValues) int LedDevice::setLedValues(const std::vector<ColorRgb>& ledValues)
{ {
if (!_deviceReady) if (!_deviceReady || !_enabled)
return -1; return -1;
_ledValues = ledValues; _ledValues = ledValues;
@ -142,5 +155,5 @@ void LedDevice::setLedCount(int ledCount)
int LedDevice::rewriteLeds() int LedDevice::rewriteLeds()
{ {
return write(_ledValues); return _enabled ? write(_ledValues) : -1;
} }

View File

@ -29,6 +29,7 @@ SysInfo::SysInfo()
_sysinfo.productVersion = v.productVersion; _sysinfo.productVersion = v.productVersion;
_sysinfo.prettyName = v.prettyName; _sysinfo.prettyName = v.prettyName;
_sysinfo.hostName = QHostInfo::localHostName(); _sysinfo.hostName = QHostInfo::localHostName();
_sysinfo.domainName = QHostInfo::localDomainName();
} }
SysInfo::~SysInfo() SysInfo::~SysInfo()

View File

@ -3,6 +3,7 @@
#include <initializer_list> #include <initializer_list>
#include <limits> #include <limits>
#include <iostream> #include <iostream>
#include <stdlib.h>
// Qt includes // Qt includes
#include <QCoreApplication> #include <QCoreApplication>
@ -40,6 +41,8 @@ void showHelp(Option & option){
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
setenv("AVAHI_COMPAT_NOWARN", "1", 1);
std::cout std::cout
<< "hyperion-remote:" << std::endl << "hyperion-remote:" << std::endl
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl << "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
@ -70,8 +73,8 @@ int main(int argc, char * argv[])
BooleanOption & argSysInfo = parser.add<BooleanOption>('s', "sysinfo" , "show system info"); BooleanOption & argSysInfo = parser.add<BooleanOption>('s', "sysinfo" , "show system info");
BooleanOption & argClear = parser.add<BooleanOption>('x', "clear" , "Clear data for the priority channel provided by the -p option"); BooleanOption & argClear = parser.add<BooleanOption>('x', "clear" , "Clear data for the priority channel provided by the -p option");
BooleanOption & argClearAll = parser.add<BooleanOption>(0x0, "clearall" , "Clear data for all active priority channels"); BooleanOption & argClearAll = parser.add<BooleanOption>(0x0, "clearall" , "Clear data for all active priority channels");
Option & argEnableComponent = parser.add<Option> ('E', "enable" , "Enable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER, V4L]"); Option & argEnableComponent = parser.add<Option> ('E', "enable" , "Enable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER, V4L, LEDDEVICE]");
Option & argDisableComponent = parser.add<Option> ('D', "disable" , "Disable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER, V4L]"); Option & argDisableComponent = parser.add<Option> ('D', "disable" , "Disable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER, V4L, LEDDEVICE]");
Option & argId = parser.add<Option> ('q', "qualifier" , "Identifier(qualifier) of the adjustment to set"); Option & argId = parser.add<Option> ('q', "qualifier" , "Identifier(qualifier) of the adjustment to set");
DoubleOption & argBrightness = parser.add<DoubleOption> ('L', "brightness" , "Set the brightness gain of the leds"); DoubleOption & argBrightness = parser.add<DoubleOption> ('L', "brightness" , "Set the brightness gain of the leds");
DoubleOption & argBacklightThreshold= parser.add<DoubleOption> ('n', "backlightThreshold" , "threshold for activating backlight (minimum brightness)"); DoubleOption & argBacklightThreshold= parser.add<DoubleOption> ('n', "backlightThreshold" , "threshold for activating backlight (minimum brightness)");

View File

@ -1,6 +1,7 @@
#include <cassert> #include <cassert>
#include <csignal> #include <csignal>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h>
#ifndef __APPLE__ #ifndef __APPLE__
/* prctl is Linux only */ /* prctl is Linux only */
@ -60,6 +61,8 @@ void startNewHyperion(int parentPid, std::string hyperionFile, std::string confi
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
setenv("AVAHI_COMPAT_NOWARN", "1", 1);
// initialize main logger and set global log level // initialize main logger and set global log level
Logger* log = Logger::getInstance("MAIN"); Logger* log = Logger::getInstance("MAIN");
Logger::setLogLevel(Logger::WARNING); Logger::setLogLevel(Logger::WARNING);