diff --git a/include/jsonserver/JsonServer.h b/include/jsonserver/JsonServer.h index 1ae95854..7773ab88 100644 --- a/include/jsonserver/JsonServer.h +++ b/include/jsonserver/JsonServer.h @@ -27,7 +27,7 @@ public: /// @param hyperion Hyperion instance /// @param port port number on which to start listening for connections /// - JsonServer(Hyperion * hyperion, uint16_t port = 19444); + JsonServer(uint16_t port = 19444); ~JsonServer(); /// diff --git a/include/protoserver/ProtoServer.h b/include/protoserver/ProtoServer.h index f62425a3..ff98850c 100644 --- a/include/protoserver/ProtoServer.h +++ b/include/protoserver/ProtoServer.h @@ -41,7 +41,7 @@ public: /// @param hyperion Hyperion instance /// @param port port number on which to start listening for connections /// - ProtoServer(Hyperion * hyperion, uint16_t port = 19445); + ProtoServer(uint16_t port = 19445); ~ProtoServer(); /// diff --git a/libsrc/jsonserver/JsonServer.cpp b/libsrc/jsonserver/JsonServer.cpp index 54a8fe94..0d1d7132 100644 --- a/libsrc/jsonserver/JsonServer.cpp +++ b/libsrc/jsonserver/JsonServer.cpp @@ -5,9 +5,9 @@ #include #include "JsonClientConnection.h" -JsonServer::JsonServer(Hyperion *hyperion, uint16_t port) : +JsonServer::JsonServer(uint16_t port) : QObject(), - _hyperion(hyperion), + _hyperion(Hyperion::getInstance()), _server(), _openConnections() { diff --git a/libsrc/protoserver/ProtoServer.cpp b/libsrc/protoserver/ProtoServer.cpp index eef471bf..9e549a78 100644 --- a/libsrc/protoserver/ProtoServer.cpp +++ b/libsrc/protoserver/ProtoServer.cpp @@ -7,14 +7,14 @@ #include "protoserver/ProtoConnection.h" #include "ProtoClientConnection.h" -ProtoServer::ProtoServer(Hyperion *hyperion, uint16_t port) : +ProtoServer::ProtoServer(uint16_t port) : QObject(), - _hyperion(hyperion), + _hyperion(Hyperion::getInstance()), _server(), _openConnections() { - MessageForwarder * forwarder = hyperion->getForwarder(); + MessageForwarder * forwarder = _hyperion->getForwarder(); QStringList slaves = forwarder->getProtoSlaves(); for (int i = 0; i < slaves.size(); ++i) { diff --git a/libsrc/webconfig/CgiHandler.cpp b/libsrc/webconfig/CgiHandler.cpp index f04571c3..9d606080 100644 --- a/libsrc/webconfig/CgiHandler.cpp +++ b/libsrc/webconfig/CgiHandler.cpp @@ -4,6 +4,7 @@ #include #include "CgiHandler.h" +#include "QtHttpHeader.h" CgiHandler::CgiHandler (Hyperion * hyperion, QObject * parent) : QObject(parent) @@ -16,10 +17,15 @@ CgiHandler::~CgiHandler() { } -void CgiHandler::exec(const QStringList & args, QtHttpReply * reply) +void CgiHandler::exec(const QStringList & args, QtHttpRequest * request, QtHttpReply * reply) { try { +// QByteArray header = reply->getHeader(QtHttpHeader::Host); +// QtHttpRequest::ClientInfo info = request->getClientInfo(); +// qDebug() << info.clientAddress.toString(); +// qDebug() << info.serverAddress.toString(); + cmd_cfg_jsonserver(args,reply); cmd_cfg_hyperion(args,reply); throw 1; diff --git a/libsrc/webconfig/CgiHandler.h b/libsrc/webconfig/CgiHandler.h index 8c691a69..38d6feb9 100644 --- a/libsrc/webconfig/CgiHandler.h +++ b/libsrc/webconfig/CgiHandler.h @@ -9,6 +9,7 @@ #include #include "QtHttpReply.h" +#include "QtHttpRequest.h" class CgiHandler : public QObject { Q_OBJECT @@ -17,7 +18,7 @@ public: CgiHandler (Hyperion * hyperion, QObject * parent = NULL); virtual ~CgiHandler (void); - void exec(const QStringList & args, QtHttpReply * reply); + void exec(const QStringList & args,QtHttpRequest * request, QtHttpReply * reply); // cgi commands void cmd_cfg_jsonserver(const QStringList & args, QtHttpReply * reply); diff --git a/libsrc/webconfig/QtHttpClientWrapper.cpp b/libsrc/webconfig/QtHttpClientWrapper.cpp index 6e88fb44..4464ff5f 100644 --- a/libsrc/webconfig/QtHttpClientWrapper.cpp +++ b/libsrc/webconfig/QtHttpClientWrapper.cpp @@ -10,6 +10,7 @@ #include #include #include +#include const QByteArray & QtHttpClientWrapper::CRLF = QByteArrayLiteral ("\r\n"); @@ -54,6 +55,7 @@ void QtHttpClientWrapper::onClientDataReceived (void) { // << "url :" << url // << "version :" << version; m_currentRequest = new QtHttpRequest (m_serverHandle); + m_currentRequest->setClientInfo(m_sockClient->localAddress(), m_sockClient->peerAddress()); m_currentRequest->setUrl (QUrl (url)); m_currentRequest->setCommand (command); m_parsingStatus = AwaitingHeaders; diff --git a/libsrc/webconfig/QtHttpRequest.cpp b/libsrc/webconfig/QtHttpRequest.cpp index 0571c5f8..93909b9f 100644 --- a/libsrc/webconfig/QtHttpRequest.cpp +++ b/libsrc/webconfig/QtHttpRequest.cpp @@ -23,6 +23,10 @@ QString QtHttpRequest::getCommand (void) const { return m_command; } +QtHttpRequest::ClientInfo QtHttpRequest::getClientInfo (void) const { + return m_clientInfo; +} + int QtHttpRequest::getRawDataSize (void) const { return m_data.size (); } @@ -48,6 +52,11 @@ void QtHttpRequest::setCommand (const QString & command) { m_command = command; } +void QtHttpRequest::setClientInfo (const QHostAddress & server, const QHostAddress & client) { + m_clientInfo.serverAddress = server; + m_clientInfo.clientAddress = client; +} + void QtHttpRequest::addHeader (const QByteArray & header, const QByteArray & value) { QByteArray key = header.trimmed (); if (!key.isEmpty ()) { diff --git a/libsrc/webconfig/QtHttpRequest.h b/libsrc/webconfig/QtHttpRequest.h index 9224f1ed..ac10d79e 100644 --- a/libsrc/webconfig/QtHttpRequest.h +++ b/libsrc/webconfig/QtHttpRequest.h @@ -6,6 +6,7 @@ #include #include #include +#include class QtHttpServer; @@ -15,17 +16,24 @@ class QtHttpRequest : public QObject { public: explicit QtHttpRequest (QtHttpServer * parent); - int getRawDataSize (void) const; + struct ClientInfo { + QHostAddress serverAddress; + QHostAddress clientAddress; + }; + + int getRawDataSize (void) const; QUrl getUrl (void) const; QString getCommand (void) const; QByteArray getRawData (void) const; QList getHeadersList (void) const; + ClientInfo getClientInfo (void) const; QByteArray getHeader (const QByteArray & header) const; public slots: void setUrl (const QUrl & url); void setCommand (const QString & command); + void setClientInfo (const QHostAddress & server, const QHostAddress & client); void addHeader (const QByteArray & header, const QByteArray & value); void appendRawData (const QByteArray & data); @@ -35,6 +43,7 @@ private: QByteArray m_data; QtHttpServer * m_serverHandle; QHash m_headersHash; + ClientInfo m_clientInfo; }; #endif // QTHTTPREQUEST_H diff --git a/libsrc/webconfig/StaticFileServing.cpp b/libsrc/webconfig/StaticFileServing.cpp index 6492f573..2035a8e3 100644 --- a/libsrc/webconfig/StaticFileServing.cpp +++ b/libsrc/webconfig/StaticFileServing.cpp @@ -66,7 +66,7 @@ void StaticFileServing::onRequestNeedsReply (QtHttpRequest * request, QtHttpRepl uri_parts.removeAt(0); try { - _cgi.exec(uri_parts, reply); + _cgi.exec(uri_parts, request, reply); } catch(...) { diff --git a/libsrc/webconfig/StaticFileServing.h b/libsrc/webconfig/StaticFileServing.h index 438ab16c..51303894 100644 --- a/libsrc/webconfig/StaticFileServing.h +++ b/libsrc/webconfig/StaticFileServing.h @@ -16,7 +16,7 @@ class StaticFileServing : public QObject { Q_OBJECT public: - explicit StaticFileServing (Hyperion *hyperion, QString baseUrl, quint16 port, QObject * parent = NULL); + explicit StaticFileServing (Hyperion *hyperion, QString baseUrl, quint16 port, QObject * parent = nullptr); virtual ~StaticFileServing (void); public slots: diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index 07f56383..f0003af6 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -9,7 +9,6 @@ #include "HyperionConfig.h" #include -#include #include #include @@ -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(schemaData.data()), reinterpret_cast(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&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, const int)) ); + QObject::connect(_dispmanx, SIGNAL(emitImage(int, const Image&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, 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&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, const int)) ); + QObject::connect(_v4l2Grabber, SIGNAL(emitImage(int, const Image&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, 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&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, const int)) ); + QObject::connect(_amlGrabber, SIGNAL(emitImage(int, const Image&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, 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&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, const int)) ); + QObject::connect(_fbGrabber, SIGNAL(emitImage(int, const Image&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, 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&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, const int)) ); + QObject::connect(_osxGrabber, SIGNAL(emitImage(int, const Image&, const int)), _protoServer, SLOT(sendImageToProtoSlaves(int, const Image&, 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; } diff --git a/src/hyperiond/hyperiond.h b/src/hyperiond/hyperiond.h index ed4b5856..fd1354d2 100644 --- a/src/hyperiond/hyperiond.h +++ b/src/hyperiond/hyperiond.h @@ -32,18 +32,45 @@ typedef QObject OsxWrapper; #endif +#include + #include #include #include #include +#include -void startBootsequence(); -XBMCVideoChecker* createXBMCVideoChecker(); -void startNetworkServices(JsonServer* &jsonServer, ProtoServer* &protoServer, BoblightServer* &boblightServer); +class HyperionDaemon : public QObject +{ +public: + HyperionDaemon(std::string configFile, QObject *parent=nullptr); + ~HyperionDaemon(); + + void loadConfig(const std::string & configFile); + void run(); -// grabber creators -DispmanxWrapper* createGrabberDispmanx(ProtoServer* &protoServer); -V4L2Wrapper* createGrabberV4L2(ProtoServer* &protoServer ); -AmlogicWrapper* createGrabberAmlogic(ProtoServer* &protoServer); -FramebufferWrapper* createGrabberFramebuffer(ProtoServer* &protoServer); -OsxWrapper* createGrabberOsx(ProtoServer* &protoServer); + void startBootsequence(); + void createXBMCVideoChecker(); + void startNetworkServices(); + + // grabber creators + void createGrabberDispmanx(); + void createGrabberV4L2(); + void createGrabberAmlogic(); + void createGrabberFramebuffer(); + void createGrabberOsx(); + +private: + Logger* _log; + Json::Value _config; + XBMCVideoChecker* _xbmcVideoChecker; + JsonServer* _jsonServer; + ProtoServer* _protoServer; + BoblightServer* _boblightServer; + V4L2Wrapper* _v4l2Grabber; + DispmanxWrapper* _dispmanx; + AmlogicWrapper* _amlGrabber; + FramebufferWrapper* _fbGrabber; + OsxWrapper* _osxGrabber; + WebConfig* _webConfig; +}; diff --git a/src/hyperiond/main.cpp b/src/hyperiond/main.cpp index 66b0ca41..183e349b 100644 --- a/src/hyperiond/main.cpp +++ b/src/hyperiond/main.cpp @@ -4,18 +4,15 @@ #include #include -#include #include #include #include "HyperionConfig.h" #include -#include #include -#include -#include + #include "hyperiond.h" @@ -30,30 +27,6 @@ void signal_handler(const int signum) } -Json::Value loadConfig(const std::string & configFile) -{ - // 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(schemaData.data()), reinterpret_cast(schemaData.data()) + schemaData.size(), schemaJson, false)) - { - throw std::runtime_error("ERROR: Json schema wrong: " + jsonReader.getFormattedErrorMessages()) ; - } - JsonSchemaChecker schemaChecker; - schemaChecker.setSchema(schemaJson); - - const Json::Value jsonConfig = JsonFactory::readJson(configFile); - schemaChecker.validate(jsonConfig); - - return jsonConfig; -} - void startNewHyperion(int parentPid, std::string hyperionFile, std::string configFile) { if ( fork() == 0 ) @@ -136,70 +109,14 @@ int main(int argc, char** argv) return 1; } - const std::string configFile = configFiles[argvId]; - Info(log, "Selected configuration file: %s", configFile.c_str() ); - const Json::Value config = loadConfig(configFile); - - Hyperion::initInstance(config, configFile); - Info(log, "Hyperion started and initialised"); - - startBootsequence(); - - XBMCVideoChecker * xbmcVideoChecker = createXBMCVideoChecker(); - - // ---- network services ----- - JsonServer * jsonServer = nullptr; - ProtoServer * protoServer = nullptr; - BoblightServer * boblightServer = nullptr; - startNetworkServices(jsonServer, protoServer, boblightServer); - - WebConfig webConfig(&app); - - // ---- grabber ----- - // if a grabber is left out of build, then Wrapper is set to QObject as dummy and has value nullptr - V4L2Wrapper * v4l2Grabber = createGrabberV4L2(protoServer); - #ifndef ENABLE_V4L2 - ErrorIf(config.isMember("grabber-v4l2"), log, "The v4l2 grabber can not be instantiated, because it has been left out from the build"); - #endif - - DispmanxWrapper * dispmanx = createGrabberDispmanx(protoServer); - #ifndef ENABLE_DISPMANX - ErrorIf(config.isMember("framegrabber"), log, "The dispmanx framegrabber can not be instantiated, because it has been left out from the build"); - #endif - - AmlogicWrapper * amlGrabber = createGrabberAmlogic(protoServer); - #ifndef ENABLE_AMLOGIC - ErrorIf(config.isMember("amlgrabber"), log, "The AMLOGIC grabber can not be instantiated, because it has been left out from the build"); - #endif - - FramebufferWrapper * fbGrabber = createGrabberFramebuffer(protoServer); - #ifndef ENABLE_FB - ErrorIf(config.isMember("framebuffergrabber"), log, "The framebuffer grabber can not be instantiated, because it has been left out from the build"); - #endif - - OsxWrapper * osxGrabber = createGrabberDispmanx(protoServer); - #ifndef ENABLE_OSX - ErrorIf(config.isMember("osxgrabber"), log, "The osx grabber can not be instantiated, because it has been left out from the build"); - #endif - - #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 + HyperionDaemon* hyperiond = new HyperionDaemon(configFiles[argvId], &app); + hyperiond->run(); // run the application int rc = app.exec(); Info(log, "INFO: Application closed with code %d", rc); - // Delete all components - delete amlGrabber; - delete dispmanx; - delete fbGrabber; - delete osxGrabber; - delete v4l2Grabber; - delete xbmcVideoChecker; - delete jsonServer; - delete protoServer; - delete boblightServer; + delete hyperiond; return rc; }