Hyperiond refactoring + preparation for ip restriction settings (#12)

* make hyperion to singelton.
remove arguments for config and hyperion - both are gettable via Hyperion::getInstance

* refactor hyperiond

* remove qt4 comapt
make zeroconf mandatory
refactor hyperiond

* xbmcchecker is now a singleton

* cleanup in hyperiond
zeroconf switchable between static and shared linking

* fix xbmcchecker

* extensive refactoring of hyperiond
webserver: make client ip information availabel in request object - preparation for ip filters
proto/json server, use hyperion::getInstance instead of hyperion argument

* move creation of hyperion core into hyperionDeamon class
cleanup
This commit is contained in:
redPanther
2016-06-19 00:56:47 +02:00
committed by brindosch
parent 0e5607db65
commit 4533b34606
14 changed files with 261 additions and 226 deletions

View File

@@ -9,7 +9,6 @@
#include "HyperionConfig.h"
#include <utils/jsonschema/JsonFactory.h>
#include <utils/Logger.h>
#include <hyperion/Hyperion.h>
#include <effectengine/EffectEngine.h>
@@ -22,15 +21,94 @@
#include "hyperiond.h"
void startBootsequence()
HyperionDaemon::HyperionDaemon(std::string configFile, QObject *parent)
: QObject(parent)
, _log(Logger::getInstance("MAIN"))
, _xbmcVideoChecker(nullptr)
, _jsonServer(nullptr)
, _protoServer(nullptr)
, _boblightServer(nullptr)
, _v4l2Grabber(nullptr)
, _dispmanx(nullptr)
, _amlGrabber(nullptr)
, _fbGrabber(nullptr)
, _osxGrabber(nullptr)
, _webConfig(nullptr)
{
loadConfig(configFile);
Hyperion::initInstance(_config, configFile);
Info(_log, "Hyperion started and initialised");
}
HyperionDaemon::~HyperionDaemon()
{
delete _amlGrabber;
delete _dispmanx;
delete _fbGrabber;
delete _osxGrabber;
delete _v4l2Grabber;
delete _xbmcVideoChecker;
delete _jsonServer;
delete _protoServer;
delete _boblightServer;
delete _webConfig;
}
void HyperionDaemon::run()
{
startBootsequence();
createXBMCVideoChecker();
// ---- network services -----
startNetworkServices();
_webConfig = new WebConfig(this);
// ---- grabber -----
createGrabberV4L2();
createGrabberDispmanx();
createGrabberAmlogic();
createGrabberFramebuffer();
createGrabberDispmanx();
#if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB)
ErrorIf(_config.isMember("framegrabber"), log, "No grabber can be instantiated, because all grabbers have been left out from the build");
#endif
}
void HyperionDaemon::loadConfig(const std::string & configFile)
{
Info(_log, "Selected configuration file: %s", configFile.c_str() );
// make sure the resources are loaded (they may be left out after static linking)
Q_INIT_RESOURCE(resource);
// read the json schema from the resource
QResource schemaData(":/hyperion-schema");
assert(schemaData.isValid());
Json::Reader jsonReader;
Json::Value schemaJson;
if (!jsonReader.parse(reinterpret_cast<const char *>(schemaData.data()), reinterpret_cast<const char *>(schemaData.data()) + schemaData.size(), schemaJson, false))
{
throw std::runtime_error("ERROR: Json schema wrong: " + jsonReader.getFormattedErrorMessages()) ;
}
JsonSchemaChecker schemaChecker;
schemaChecker.setSchema(schemaJson);
_config = JsonFactory::readJson(configFile);
schemaChecker.validate(_config);
}
void HyperionDaemon::startBootsequence()
{
Hyperion *hyperion = Hyperion::getInstance();
const Json::Value &config = hyperion->getJsonConfig();
// create boot sequence if the configuration is present
if (config.isMember("bootsequence"))
if (_config.isMember("bootsequence"))
{
const Json::Value effectConfig = config["bootsequence"];
const Json::Value effectConfig = _config["bootsequence"];
// Get the parameters for the bootsequence
const std::string effectName = effectConfig["effect"].asString();
@@ -75,15 +153,13 @@ void startBootsequence()
}
// create XBMC video checker if the configuration is present
XBMCVideoChecker* createXBMCVideoChecker()
// create XBMC video checker if the _configuration is present
void HyperionDaemon::createXBMCVideoChecker()
{
XBMCVideoChecker* xbmcVideoChecker = nullptr;
const Json::Value &config = Hyperion::getInstance()->getJsonConfig();
if (config.isMember("xbmcVideoChecker"))
if (_config.isMember("xbmcVideoChecker"))
{
const Json::Value & videoCheckerConfig = config["xbmcVideoChecker"];
xbmcVideoChecker = XBMCVideoChecker::initInstance(
const Json::Value & videoCheckerConfig = _config["xbmcVideoChecker"];
_xbmcVideoChecker = XBMCVideoChecker::initInstance(
videoCheckerConfig["xbmcAddress"].asString(),
videoCheckerConfig["xbmcTcpPort"].asUInt(),
videoCheckerConfig["grabVideo"].asBool(),
@@ -94,137 +170,133 @@ XBMCVideoChecker* createXBMCVideoChecker()
videoCheckerConfig.get("grabScreensaver", true).asBool(),
videoCheckerConfig.get("enable3DDetection", true).asBool());
xbmcVideoChecker->start();
Info(Logger::getInstance("MAIN"), "Kodi checker created and started");
_xbmcVideoChecker->start();
Info(_log, "Kodi checker created and started");
}
return xbmcVideoChecker;
}
void startNetworkServices(JsonServer* &jsonServer, ProtoServer* &protoServer, BoblightServer* &boblightServer)
void HyperionDaemon::startNetworkServices()
{
Hyperion *hyperion = Hyperion::getInstance();
XBMCVideoChecker* xbmcVideoChecker = XBMCVideoChecker::getInstance();
const Json::Value &config = hyperion->getJsonConfig();
// Create Json server if configuration is present
unsigned int jsonPort = 19444;
if (config.isMember("jsonServer"))
if (_config.isMember("jsonServer"))
{
const Json::Value & jsonServerConfig = config["jsonServer"];
const Json::Value & jsonServerConfig = _config["jsonServer"];
//jsonEnable = jsonServerConfig.get("enable", true).asBool();
jsonPort = jsonServerConfig.get("port", jsonPort).asUInt();
}
jsonServer = new JsonServer(hyperion, jsonPort );
Info(Logger::getInstance("MAIN"), "Json server created and started on port %d", jsonServer->getPort());
_jsonServer = new JsonServer(jsonPort );
Info(_log, "Json server created and started on port %d", _jsonServer->getPort());
// Create Proto server if configuration is present
unsigned int protoPort = 19445;
if (config.isMember("protoServer"))
if (_config.isMember("protoServer"))
{
const Json::Value & protoServerConfig = config["protoServer"];
const Json::Value & protoServerConfig = _config["protoServer"];
//protoEnable = protoServerConfig.get("enable", true).asBool();
protoPort = protoServerConfig.get("port", protoPort).asUInt();
}
protoServer = new ProtoServer(hyperion, protoPort );
_protoServer = new ProtoServer(protoPort );
if (xbmcVideoChecker != nullptr)
{
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), protoServer, SIGNAL(grabbingMode(GrabbingMode)));
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), protoServer, SIGNAL(videoMode(VideoMode)));
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _protoServer, SIGNAL(grabbingMode(GrabbingMode)));
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), _protoServer, SIGNAL(videoMode(VideoMode)));
}
Info(Logger::getInstance("MAIN"), "Proto server created and started on port %d", protoServer->getPort());
Info(_log, "Proto server created and started on port %d", _protoServer->getPort());
const Json::Value & deviceConfig = config["device"];
// Create Boblight server if configuration is present
if (_config.isMember("boblightServer"))
{
const Json::Value & boblightServerConfig = _config["boblightServer"];
_boblightServer = new BoblightServer(hyperion, boblightServerConfig.get("priority",900).asInt(), boblightServerConfig["port"].asUInt());
Info(_log, "Boblight server created and started on port %d", _boblightServer->getPort());
}
// zeroconf
const Json::Value & deviceConfig = _config["device"];
const std::string deviceName = deviceConfig.get("name", "").asString();
const std::string hostname = QHostInfo::localHostName().toStdString();
// zeroconf json
std::string mDNSDescr_json = hostname;
std::string mDNSService_json = "_hyperiond_json._tcp";
if (config.isMember("jsonServer"))
if (_config.isMember("jsonServer"))
{
const Json::Value & jsonServerConfig = config["jsonServer"];
const Json::Value & jsonServerConfig = _config["jsonServer"];
mDNSDescr_json = jsonServerConfig.get("mDNSDescr", mDNSDescr_json).asString();
mDNSService_json = jsonServerConfig.get("mDNSService", mDNSService_json).asString();
}
BonjourServiceRegister *bonjourRegister_json = new BonjourServiceRegister();
bonjourRegister_json->registerService(BonjourRecord((deviceName + " @ " + mDNSDescr_json).c_str(), mDNSService_json.c_str(),
QString()), jsonServer->getPort() );
Info(Logger::getInstance("MAIN"), "Json mDNS responder started");
QString()), _jsonServer->getPort() );
Info(_log, "Json mDNS responder started");
// zeroconf proto
std::string mDNSDescr_proto = hostname;
std::string mDNSService_proto = "_hyperiond_proto._tcp";
if (config.isMember("protoServer"))
if (_config.isMember("protoServer"))
{
const Json::Value & protoServerConfig = config["protoServer"];
const Json::Value & protoServerConfig = _config["protoServer"];
mDNSDescr_proto = protoServerConfig.get("mDNSDescr", mDNSDescr_proto).asString();
mDNSService_proto = protoServerConfig.get("mDNSService", mDNSService_proto).asString();
}
BonjourServiceRegister *bonjourRegister_proto = new BonjourServiceRegister();
bonjourRegister_proto->registerService(BonjourRecord((deviceName + " @ " + mDNSDescr_proto).c_str(), mDNSService_proto.c_str(),
QString()), protoServer->getPort() );
Info(Logger::getInstance("MAIN"), "Proto mDNS responder started");
QString()), _protoServer->getPort() );
Info(_log, "Proto mDNS responder started");
// Create Boblight server if configuration is present
if (config.isMember("boblightServer"))
{
const Json::Value & boblightServerConfig = config["boblightServer"];
boblightServer = new BoblightServer(hyperion, boblightServerConfig.get("priority",900).asInt(), boblightServerConfig["port"].asUInt());
Info(Logger::getInstance("MAIN"), "Boblight server created and started on port %d", boblightServer->getPort());
}
}
DispmanxWrapper* createGrabberDispmanx(ProtoServer* &protoServer)
void HyperionDaemon::createGrabberDispmanx()
{
DispmanxWrapper* dispmanx = nullptr;
#ifdef ENABLE_DISPMANX
XBMCVideoChecker* xbmcVideoChecker = XBMCVideoChecker::getInstance();
const Json::Value &config = Hyperion::getInstance()->getJsonConfig();
// Construct and start the frame-grabber if the configuration is present
if (config.isMember("framegrabber"))
if (_config.isMember("framegrabber"))
{
const Json::Value & frameGrabberConfig = config["framegrabber"];
dispmanx = new DispmanxWrapper(
const Json::Value & frameGrabberConfig = _config["framegrabber"];
_dispmanx = new DispmanxWrapper(
frameGrabberConfig["width"].asUInt(),
frameGrabberConfig["height"].asUInt(),
frameGrabberConfig["frequency_Hz"].asUInt(),
frameGrabberConfig.get("priority",900).asInt());
dispmanx->setCropping(
_dispmanx->setCropping(
frameGrabberConfig.get("cropLeft", 0).asInt(),
frameGrabberConfig.get("cropRight", 0).asInt(),
frameGrabberConfig.get("cropTop", 0).asInt(),
frameGrabberConfig.get("cropBottom", 0).asInt());
if (xbmcVideoChecker != nullptr)
if (_xbmcVideoChecker != nullptr)
{
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), dispmanx, SLOT(setVideoMode(VideoMode)));
QObject::connect(_xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), _dispmanx, SLOT(setVideoMode(VideoMode)));
}
QObject::connect(dispmanx, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
QObject::connect(_dispmanx, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
dispmanx->start();
Info(Logger::getInstance("MAIN"), "Frame grabber created and started");
_dispmanx->start();
Info(_log, "Frame grabber created and started");
}
#else
ErrorIf(_config.isMember("framegrabber"), _log, "The dispmanx framegrabber can not be instantiated, because it has been left out from the build");
#endif
return dispmanx;
}
V4L2Wrapper* createGrabberV4L2(ProtoServer* &protoServer )
void HyperionDaemon::createGrabberV4L2()
{
// construct and start the v4l2 grabber if the configuration is present
V4L2Wrapper* v4l2Grabber = nullptr;
#ifdef ENABLE_V4L2
const Json::Value &config = Hyperion::getInstance()->getJsonConfig();
if (config.isMember("grabber-v4l2"))
if (_config.isMember("grabber-v4l2"))
{
const Json::Value & grabberConfig = config["grabber-v4l2"];
v4l2Grabber = new V4L2Wrapper(
const Json::Value & grabberConfig = _config["grabber-v4l2"];
_v4l2Grabber = new V4L2Wrapper(
grabberConfig.get("device", "/dev/video0").asString(),
grabberConfig.get("input", 0).asInt(),
parseVideoStandard(grabberConfig.get("standard", "no-change").asString()),
@@ -237,118 +309,110 @@ V4L2Wrapper* createGrabberV4L2(ProtoServer* &protoServer )
grabberConfig.get("greenSignalThreshold", 0.0).asDouble(),
grabberConfig.get("blueSignalThreshold", 0.0).asDouble(),
grabberConfig.get("priority", 900).asInt());
v4l2Grabber->set3D(parse3DMode(grabberConfig.get("mode", "2D").asString()));
v4l2Grabber->setCropping(
_v4l2Grabber->set3D(parse3DMode(grabberConfig.get("mode", "2D").asString()));
_v4l2Grabber->setCropping(
grabberConfig.get("cropLeft", 0).asInt(),
grabberConfig.get("cropRight", 0).asInt(),
grabberConfig.get("cropTop", 0).asInt(),
grabberConfig.get("cropBottom", 0).asInt());
QObject::connect(v4l2Grabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
QObject::connect(_v4l2Grabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
v4l2Grabber->start();
Info(Logger::getInstance("MAIN"), "V4L2 grabber created and started");
_v4l2Grabber->start();
Info(_log, "V4L2 grabber created and started");
}
#else
ErrorIf(_config.isMember("grabber-v4l2"), _log, "The v4l2 grabber can not be instantiated, because it has been left out from the build");
#endif
return v4l2Grabber;
}
AmlogicWrapper* createGrabberAmlogic(ProtoServer* &protoServer)
void HyperionDaemon::createGrabberAmlogic()
{
AmlogicWrapper* amlGrabber = nullptr;
#ifdef ENABLE_AMLOGIC
XBMCVideoChecker* xbmcVideoChecker = XBMCVideoChecker::getInstance();
const Json::Value &config = Hyperion::getInstance()->getJsonConfig();
// Construct and start the framebuffer grabber if the configuration is present
if (config.isMember("amlgrabber"))
if (_config.isMember("amlgrabber"))
{
const Json::Value & grabberConfig = config["amlgrabber"];
amlGrabber = new AmlogicWrapper(
const Json::Value & grabberConfig = _config["amlgrabber"];
_amlGrabber = new AmlogicWrapper(
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig["frequency_Hz"].asUInt(),
grabberConfig.get("priority",900).asInt());
if (xbmcVideoChecker != nullptr)
if (_xbmcVideoChecker != nullptr)
{
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), amlGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), amlGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _amlGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), _amlGrabber, SLOT(setVideoMode(VideoMode)));
}
QObject::connect(amlGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
QObject::connect(_amlGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
amlGrabber->start();
Info(Logger::getInstance("MAIN"), "AMLOGIC grabber created and started");
_amlGrabber->start();
Info(_log, "AMLOGIC grabber created and started");
}
#else
ErrorIf(_config.isMember("amlgrabber"), _log, "The AMLOGIC grabber can not be instantiated, because it has been left out from the build");
#endif
return amlGrabber;
}
FramebufferWrapper* createGrabberFramebuffer(ProtoServer* &protoServer)
void HyperionDaemon::createGrabberFramebuffer()
{
FramebufferWrapper* fbGrabber = nullptr;
#ifdef ENABLE_FB
XBMCVideoChecker* xbmcVideoChecker = XBMCVideoChecker::getInstance();
const Json::Value &config = Hyperion::getInstance()->getJsonConfig();
// Construct and start the framebuffer grabber if the configuration is present
if (config.isMember("framebuffergrabber") || config.isMember("framegrabber"))
if (_config.isMember("framebuffergrabber") || _config.isMember("framegrabber"))
{
const Json::Value & grabberConfig = config.isMember("framebuffergrabber")? config["framebuffergrabber"] : config["framegrabber"];
fbGrabber = new FramebufferWrapper(
const Json::Value & grabberConfig = _config.isMember("framebuffergrabber")? _config["framebuffergrabber"] : _config["framegrabber"];
_fbGrabber = new FramebufferWrapper(
grabberConfig.get("device", "/dev/fb0").asString(),
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig["frequency_Hz"].asUInt(),
grabberConfig.get("priority",900).asInt());
if (xbmcVideoChecker != nullptr)
if (_xbmcVideoChecker != nullptr)
{
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), fbGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), fbGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _fbGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), _fbGrabber, SLOT(setVideoMode(VideoMode)));
}
QObject::connect(fbGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
QObject::connect(_fbGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
fbGrabber->start();
Info(Logger::getInstance("MAIN"), "Framebuffer grabber created and started");
_fbGrabber->start();
Info(_log, "Framebuffer grabber created and started");
}
#else
ErrorIf(_config.isMember("framebuffergrabber"), _log, "The framebuffer grabber can not be instantiated, because it has been left out from the build");
#endif
return fbGrabber;
}
OsxWrapper* createGrabberOsx(ProtoServer* &protoServer)
void HyperionDaemon::createGrabberOsx()
{
OsxWrapper* osxGrabber = nullptr;
#ifdef ENABLE_OSX
XBMCVideoChecker* xbmcVideoChecker = XBMCVideoChecker::getInstance();
const Json::Value &config = Hyperion::getInstance()->getJsonConfig();
// Construct and start the osx grabber if the configuration is present
if (config.isMember("osxgrabber") || config.isMember("framegrabber"))
if (_config.isMember("framegrabber"))
{
const Json::Value & grabberConfig = config.isMember("osxgrabber")? config["osxgrabber"] : config["framegrabber"];
osxGrabber = new OsxWrapper(
const Json::Value & grabberConfig = _config.isMember("osxgrabber")? _config["osxgrabber"] : _config["framegrabber"];
_osxGrabber = new OsxWrapper(
grabberConfig.get("display", 0).asUInt(),
grabberConfig["width"].asUInt(),
grabberConfig["height"].asUInt(),
grabberConfig["frequency_Hz"].asUInt(),
grabberConfig.get("priority",900).asInt());
if (xbmcVideoChecker != nullptr)
if (_xbmcVideoChecker != nullptr)
{
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), osxGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), osxGrabber, SLOT(setVideoMode(VideoMode)));
QObject::connect(_xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), _osxGrabber, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(_xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), _osxGrabber, SLOT(setVideoMode(VideoMode)));
}
QObject::connect(osxGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
QObject::connect(_osxGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
osxGrabber->start();
Info(Logger::getInstance("MAIN"), "OSX grabber created and started");
_osxGrabber->start();
Info(_log, "OSX grabber created and started");
}
#else
ErrorIf(_config.isMember("osxgrabber"), _log, "The osx grabber can not be instantiated, because it has been left out from the build");
#endif
return osxGrabber;
}