This commit is contained in:
Paulchen Panther
2020-10-18 17:05:07 +02:00
committed by GitHub
parent 9d2e442d42
commit aa465c018c
18 changed files with 207 additions and 90 deletions

View File

@@ -56,7 +56,18 @@ API::API(Logger *log, bool localConnection, QObject *parent)
//connect(ApiSync::getInstance(), &ApiSync::requestActiveRegister, this, &API::requestActiveRegister, Qt::QueuedConnection);
// connect to possible token responses that has been requested
connect(_authManager, &AuthManager::tokenResponse, this, &API::checkTokenResponse);
connect(_authManager, &AuthManager::tokenResponse, [=] (bool success, QObject *caller, const QString &token, const QString &comment, const QString &id, const int &tan)
{
if (this == caller)
emit onTokenResponse(success, token, comment, id, tan);
});
// connect to possible startInstance responses that has been requested
connect(_instanceManager, &HyperionIManager::startInstanceResponse, [=] (QObject *caller, const int &tan)
{
if (this == caller)
emit onStartInstanceResponse(tan);
});
}
void API::init()
@@ -211,16 +222,19 @@ void API::setVideoMode(VideoMode mode, hyperion::Components callerComp)
QMetaObject::invokeMethod(_hyperion, "setVideoMode", Qt::QueuedConnection, Q_ARG(VideoMode, mode));
}
void API::setEffect(const EffectCmdData &dat, hyperion::Components callerComp)
bool API::setEffect(const EffectCmdData &dat, hyperion::Components callerComp)
{
int res;
if (!dat.args.isEmpty())
{
QMetaObject::invokeMethod(_hyperion, "setEffect", Qt::QueuedConnection, Q_ARG(QString, dat.effectName), Q_ARG(QJsonObject, dat.args), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.pythonScript), Q_ARG(QString, dat.origin), Q_ARG(QString, dat.data));
QMetaObject::invokeMethod(_hyperion, "setEffect", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, res), Q_ARG(QString, dat.effectName), Q_ARG(QJsonObject, dat.args), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.pythonScript), Q_ARG(QString, dat.origin), Q_ARG(QString, dat.data));
}
else
{
QMetaObject::invokeMethod(_hyperion, "setEffect", Qt::QueuedConnection, Q_ARG(QString, dat.effectName), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.origin));
QMetaObject::invokeMethod(_hyperion, "setEffect", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, res), Q_ARG(QString, dat.effectName), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.origin));
}
return res >= 0;
}
void API::setSourceAutoSelect(bool state, hyperion::Components callerComp)
@@ -285,9 +299,14 @@ QVector<QVariantMap> API::getAllInstanceData()
return vec;
}
void API::startInstance(quint8 index)
bool API::startInstance(quint8 index, int tan)
{
QMetaObject::invokeMethod(_instanceManager, "startInstance", Qt::QueuedConnection, Q_ARG(quint8, index));
bool res;
(_instanceManager->thread() != this->thread())
? QMetaObject::invokeMethod(_instanceManager, "startInstance", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, res), Q_ARG(quint8, index), Q_ARG(bool, false), Q_ARG(QObject*, this), Q_ARG(int, tan))
: res = _instanceManager->startInstance(index, false, this, tan);
return res;
}
void API::stopInstance(quint8 index)
@@ -407,9 +426,9 @@ QString API::deleteToken(const QString &id)
return "";
}
void API::setNewTokenRequest(const QString &comment, const QString &id)
void API::setNewTokenRequest(const QString &comment, const QString &id, const int &tan)
{
QMetaObject::invokeMethod(_authManager, "setNewTokenRequest", Qt::QueuedConnection, Q_ARG(QObject *, this), Q_ARG(QString, comment), Q_ARG(QString, id));
QMetaObject::invokeMethod(_authManager, "setNewTokenRequest", Qt::QueuedConnection, Q_ARG(QObject *, this), Q_ARG(QString, comment), Q_ARG(QString, id), Q_ARG(int, tan));
}
void API::cancelNewTokenRequest(const QString &comment, const QString &id)
@@ -465,12 +484,11 @@ bool API::getUserToken(QString &userToken)
bool API::isTokenAuthorized(const QString &token)
{
bool res;
QMetaObject::invokeMethod(_authManager, "isTokenAuthorized", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, res), Q_ARG(QString, token));
if (res)
_authorized = true;
(_authManager->thread() != this->thread())
? QMetaObject::invokeMethod(_authManager, "isTokenAuthorized", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, _authorized), Q_ARG(QString, token))
: _authorized = _authManager->isTokenAuthorized(token);
return res;
return _authorized;
}
bool API::isUserAuthorized(const QString &password)
@@ -503,12 +521,6 @@ void API::logout()
stopDataConnectionss();
}
void API::checkTokenResponse(bool success, QObject *caller, const QString &token, const QString &comment, const QString &id)
{
if (this == caller)
emit onTokenResponse(success, token, comment, id);
}
void API::stopDataConnectionss()
{
}

View File

@@ -243,9 +243,10 @@ void JsonAPI::handleEffectCommand(const QJsonObject &message, const QString &com
dat.data = message["imageData"].toString("").toUtf8();
dat.args = message["effect"].toObject()["args"].toObject();
API::setEffect(dat);
sendSuccessReply(command, tan);
if (API::setEffect(dat))
sendSuccessReply(command, tan);
else
sendErrorReply("Effect '" + dat.effectName + "' not found", command, tan);
}
void JsonAPI::handleCreateEffectCommand(const QJsonObject &message, const QString &command, int tan)
@@ -351,8 +352,10 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString
item["value"] = LEDcolor;
}
// priorities[priorities.size()] = item;
priorities.append(item);
(priority == currentPriority)
? priorities.prepend(item)
: priorities.append(item);
}
info["priorities"] = priorities;
@@ -1186,7 +1189,7 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject &message, const QString &
const QString &comment = message["comment"].toString().trimmed();
const bool &acc = message["accept"].toBool(true);
if (acc)
API::setNewTokenRequest(comment, id);
API::setNewTokenRequest(comment, id, tan);
else
API::cancelNewTokenRequest(comment, id);
// client should wait for answer
@@ -1323,9 +1326,10 @@ void JsonAPI::handleInstanceCommand(const QJsonObject &message, const QString &c
if (subc == "startInstance")
{
// silent fail
API::startInstance(inst);
sendSuccessReply(command + "-" + subc, tan);
connect(this, &API::onStartInstanceResponse, [=] (const int &tan) { sendSuccessReply(command + "-" + subc, tan); });
if (!API::startInstance(inst, tan))
sendErrorReply("Can't start Hyperion instance index " + QString::number(inst), command + "-" + subc, tan);
return;
}
@@ -1557,7 +1561,7 @@ void JsonAPI::newPendingTokenRequest(const QString &id, const QString &comment)
sendSuccessDataReply(QJsonDocument(obj), "authorize-tokenRequest", 1);
}
void JsonAPI::handleTokenResponse(bool success, const QString &token, const QString &comment, const QString &id)
void JsonAPI::handleTokenResponse(bool success, const QString &token, const QString &comment, const QString &id, const int &tan)
{
const QString cmd = "authorize-requestToken";
QJsonObject result;
@@ -1566,9 +1570,9 @@ void JsonAPI::handleTokenResponse(bool success, const QString &token, const QStr
result["id"] = id;
if (success)
sendSuccessDataReply(QJsonDocument(result), cmd);
sendSuccessDataReply(QJsonDocument(result), cmd, tan);
else
sendErrorReply("Token request timeout or denied", cmd, 5);
sendErrorReply("Token request timeout or denied", cmd, tan);
}
void JsonAPI::handleInstanceStateChange(InstanceState state, quint8 instance, const QString &name)

View File

@@ -141,8 +141,6 @@ int EffectEngine::runEffect(const QString &effectName, int priority, int timeout
int EffectEngine::runEffect(const QString &effectName, const QJsonObject &args, int priority, int timeout, const QString &pythonScript, const QString &origin, unsigned smoothCfg, const QString &imageData)
{
Info( _log, "Run effect \"%s\" on channel %d", QSTRING_CSTR(effectName), priority);
if (pythonScript.isEmpty())
{
const EffectDefinition *effectDefinition = nullptr;
@@ -157,12 +155,14 @@ int EffectEngine::runEffect(const QString &effectName, const QJsonObject &args,
if (effectDefinition == nullptr)
{
// no such effect
Error(_log, "Effect %s not found", QSTRING_CSTR(effectName));
Error(_log, "Effect \"%s\" not found", QSTRING_CSTR(effectName));
return -1;
}
Info( _log, "Run effect \"%s\" on channel %d", QSTRING_CSTR(effectName), priority);
return runEffectScript(effectDefinition->script, effectName, (args.isEmpty() ? effectDefinition->args : args), priority, timeout, origin, effectDefinition->smoothCfg);
}
Info( _log, "Run effect \"%s\" on channel %d", QSTRING_CSTR(effectName), priority);
return runEffectScript(pythonScript, effectName, args, priority, timeout, origin, smoothCfg, imageData);
}

View File

@@ -150,18 +150,18 @@ bool AuthManager::resetHyperionUser()
return _authTable->resetHyperionUser();
}
void AuthManager::setNewTokenRequest(QObject *caller, const QString &comment, const QString &id)
void AuthManager::setNewTokenRequest(QObject *caller, const QString &comment, const QString &id, const int &tan)
{
if (!_pendingRequests.contains(id))
{
AuthDefinition newDef{id, comment, caller, uint64_t(QDateTime::currentMSecsSinceEpoch() + 180000)};
AuthDefinition newDef{id, comment, caller, tan, uint64_t(QDateTime::currentMSecsSinceEpoch() + 180000)};
_pendingRequests[id] = newDef;
_timer->start();
emit newPendingTokenRequest(id, comment);
}
}
void AuthManager::cancelNewTokenRequest(QObject *caller, const QString &comment, const QString &id)
void AuthManager::cancelNewTokenRequest(QObject *caller, const QString &, const QString &id)
{
if (_pendingRequests.contains(id))
{
@@ -182,12 +182,12 @@ void AuthManager::handlePendingTokenRequest(const QString &id, bool accept)
{
const QString token = QUuid::createUuid().toString().remove("{").remove("}");
_authTable->createToken(token, def.comment, id);
emit tokenResponse(true, def.caller, token, def.comment, id);
emit tokenResponse(true, def.caller, token, def.comment, id, def.tan);
emit tokenChange(getTokenList());
}
else
{
emit tokenResponse(false, def.caller, QString(), def.comment, id);
emit tokenResponse(false, def.caller, QString(), def.comment, id, def.tan);
}
}
}
@@ -249,7 +249,7 @@ void AuthManager::checkTimeout()
const AuthDefinition &def = i.value();
if (def.timeoutTime <= now)
{
emit tokenResponse(false, def.caller, QString(), def.comment, def.id);
emit tokenResponse(false, def.caller, QString(), def.comment, def.id, def.tan);
_pendingRequests.remove(i.key());
}
}

View File

@@ -67,7 +67,7 @@ void HyperionIManager::toggleStateAllInstances(bool pause)
}
}
bool HyperionIManager::startInstance(quint8 inst, bool block)
bool HyperionIManager::startInstance(quint8 inst, bool block, QObject* caller, int tan)
{
if(_instanceTable->instanceExist(inst))
{
@@ -104,6 +104,12 @@ bool HyperionIManager::startInstance(quint8 inst, bool block)
while(!hyperionThread->isRunning()){};
}
if (!_pendingRequests.contains(inst) && caller != nullptr)
{
PendingRequests newDef{caller, tan};
_pendingRequests[inst] = newDef;
}
return true;
}
Debug(_log,"Can't start Hyperion instance index '%d' with name '%s' it's already running or queued for start", inst, QSTRING_CSTR(_instanceTable->getNamebyIndex(inst)));
@@ -211,4 +217,11 @@ void HyperionIManager::handleStarted()
_runningInstances.insert(instance, hyperion);
emit instanceStateChanged(InstanceState::H_STARTED, instance);
emit change();
if (_pendingRequests.contains(instance))
{
PendingRequests def = _pendingRequests.take(instance);
emit startInstanceResponse(def.caller, def.tan);
_pendingRequests.remove(instance);
}
}

View File

@@ -142,9 +142,11 @@ hyperion::Components PriorityMuxer::getComponentOfPriority(int priority) const
void PriorityMuxer::registerInput(int priority, hyperion::Components component, const QString& origin, const QString& owner, unsigned smooth_cfg)
{
// detect new registers
bool newInput = false;
if(!_activeInputs.contains(priority))
bool newInput, reusedInput = false;
if (!_activeInputs.contains(priority))
newInput = true;
else
reusedInput = true;
InputInfo& input = _activeInputs[priority];
input.priority = priority;
@@ -154,12 +156,15 @@ void PriorityMuxer::registerInput(int priority, hyperion::Components component,
input.smooth_cfg = smooth_cfg;
input.owner = owner;
if(newInput)
if (newInput)
{
Debug(_log,"Register new input '%s/%s' with priority %d as inactive", QSTRING_CSTR(origin), hyperion::componentToIdString(component), priority);
emit prioritiesChanged();
if (!_sourceAutoSelectEnabled) // emit 'prioritiesChanged' only on when _sourceAutoSelectEnabled is false
emit prioritiesChanged();
return;
}
if (reusedInput) emit prioritiesChanged();
}
bool PriorityMuxer::setInput(int priority, const std::vector<ColorRgb>& ledColors, int64_t timeout_ms)
@@ -339,7 +344,6 @@ void PriorityMuxer::setCurrentTime()
_prevVisComp = comp;
emit visibleComponentChanged(comp);
}
emit prioritiesChanged();
}
}

View File

@@ -39,10 +39,7 @@ ProviderRestApi::ProviderRestApi()
ProviderRestApi::~ProviderRestApi()
{
if ( _networkManager != nullptr )
{
delete _networkManager;
}
delete _networkManager;
}
void ProviderRestApi::setBasePath(const QString &basePath)

View File

@@ -27,6 +27,12 @@ static const QString SSDP_DESCRIPTION = "<?xml version=\"1.0\"?>"
"<modelURL>https://www.hyperion-project.org</modelURL>"
"<serialNumber>%4</serialNumber>"
"<UDN>uuid:%4</UDN>"
"<ports>"
"<jsonServer>%5</jsonServer>"
"<sslServer>%6</sslServer>"
"<protoBuffer>%7</protoBuffer>"
"<flatBuffer>%8</flatBuffer>"
"</ports>"
"<presentationURL>index.html</presentationURL>"
"<iconList>"
"<icon>"

View File

@@ -15,14 +15,16 @@
static const QString SSDP_HYPERION_ST("urn:hyperion-project.org:device:basic:1");
SSDPHandler::SSDPHandler(WebServer* webserver, quint16 flatBufPort, quint16 jsonServerPort, const QString& name, QObject * parent)
SSDPHandler::SSDPHandler(WebServer* webserver, quint16 flatBufPort, quint16 protoBufPort, quint16 jsonServerPort, quint16 sslPort, const QString& name, QObject * parent)
: SSDPServer(parent)
, _webserver(webserver)
, _localAddress()
, _NCA(nullptr)
{
setFlatBufPort(flatBufPort);
setProtoBufPort(protoBufPort);
setJsonServerPort(jsonServerPort);
setSSLServerPort(sslPort);
setHyperionName(name);
}
@@ -85,6 +87,14 @@ void SSDPHandler::handleSettingsUpdate(settings::type type, const QJsonDocument&
}
}
if(type == settings::PROTOSERVER)
{
if(obj["port"].toInt() != SSDPServer::getProtoBufPort())
{
SSDPServer::setProtoBufPort(obj["port"].toInt());
}
}
if(type == settings::JSONSERVER)
{
if(obj["port"].toInt() != SSDPServer::getJsonServerPort())
@@ -93,6 +103,14 @@ void SSDPHandler::handleSettingsUpdate(settings::type type, const QJsonDocument&
}
}
if(type == settings::WEBSERVER)
{
if(obj["sslPort"].toInt() != SSDPServer::getSSLServerPort())
{
SSDPServer::setSSLServerPort(obj["sslPort"].toInt());
}
}
if (type == settings::GENERAL)
{
if (obj["name"].toString() != SSDPServer::getHyperionName())
@@ -199,7 +217,21 @@ QString SSDPHandler::buildDesc() const
/// %2 friendly name Hyperion 2.0.0 (192.168.0.177)
/// %3 modelNumber 2.0.0
/// %4 serialNumber / UDN (H ID) Fjsa723dD0....
return SSDP_DESCRIPTION.arg(getBaseAddress(), QString("Hyperion (%1)").arg(_localAddress), QString(HYPERION_VERSION), _uuid);
/// %5 json port 19444
/// %6 ssl server port 8092
/// %7 protobuf port 19445
/// %8 flatbuf port 19400
return SSDP_DESCRIPTION.arg(
getBaseAddress(),
QString("Hyperion (%1)").arg(_localAddress),
QString(HYPERION_VERSION),
_uuid,
QString::number(SSDPServer::getJsonServerPort()),
QString::number(SSDPServer::getSSLServerPort()),
QString::number(SSDPServer::getProtoBufPort()),
QString::number(SSDPServer::getFlatBufPort())
);
}
void SSDPHandler::sendAnnounceList(bool alive)

View File

@@ -153,7 +153,7 @@ void QtHttpClientWrapper::onClientDataReceived (void)
case RequestParsed: // a valid request has ben fully parsed
{
// Catch websocket header "Upgrade"
if(m_currentRequest->getHeader(QtHttpHeader::Upgrade) == "websocket")
if(m_currentRequest->getHeader(QtHttpHeader::Upgrade).toLower() == "websocket")
{
if(m_websocketClient == Q_NULLPTR)
{