mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Add Event Subscriptions & Instance specific replies
This commit is contained in:
parent
ec6a65bfbb
commit
7a604ee5e7
@ -316,7 +316,7 @@ private:
|
|||||||
///
|
///
|
||||||
/// Send a standard reply indicating success
|
/// Send a standard reply indicating success
|
||||||
///
|
///
|
||||||
void sendSuccessReply(const QString &command = "", int tan = 0);
|
void sendSuccessReply(const QString &command = "", int tan = 0, InstanceCmd::Type isInstanceCmd = InstanceCmd::No);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Send a standard reply indicating success with data
|
/// Send a standard reply indicating success with data
|
||||||
@ -326,7 +326,7 @@ private:
|
|||||||
///
|
///
|
||||||
/// Send a standard reply indicating success with data
|
/// Send a standard reply indicating success with data
|
||||||
///
|
///
|
||||||
void sendSuccessDataReply(const QJsonValue &infoData, const QString &command = "", int tan = 0);
|
void sendSuccessDataReply(const QJsonValue &infoData, const QString &command = "", int tan = 0, InstanceCmd::Type isInstanceCmd = InstanceCmd::No);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Send a standard reply indicating success with data and error details
|
/// Send a standard reply indicating success with data and error details
|
||||||
@ -336,8 +336,7 @@ private:
|
|||||||
///
|
///
|
||||||
/// Send a standard reply indicating success with data and error details
|
/// Send a standard reply indicating success with data and error details
|
||||||
///
|
///
|
||||||
void sendSuccessDataReplyWithError(const QJsonValue &infoData, const QString &command = "", int tan = 0, const QStringList& errorDetails = {});
|
void sendSuccessDataReplyWithError(const QJsonValue &infoData, const QString &command = "", int tan = 0, const QStringList& errorDetails = {}, InstanceCmd::Type isInstanceCmd = InstanceCmd::No);
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Send a message with data.
|
/// Send a message with data.
|
||||||
@ -349,7 +348,7 @@ private:
|
|||||||
/// Send a message with data
|
/// Send a message with data
|
||||||
/// Note: To be used as a new message and not as a response to a previous request.
|
/// Note: To be used as a new message and not as a response to a previous request.
|
||||||
///
|
///
|
||||||
void sendNewRequest(const QJsonValue &infoData, const QString &command);
|
void sendNewRequest(const QJsonValue &infoData, const QString &command, InstanceCmd::Type isInstanceCmd = InstanceCmd::No);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Send an error message back to the client
|
/// Send an error message back to the client
|
||||||
@ -372,7 +371,7 @@ private:
|
|||||||
/// @param error String describing the error
|
/// @param error String describing the error
|
||||||
/// @param errorDetails additional information detailing the error scenario
|
/// @param errorDetails additional information detailing the error scenario
|
||||||
///
|
///
|
||||||
void sendErrorReply(const QString &error, const QStringList& errorDetails = {}, const QString &command = "", int tan = 0);
|
void sendErrorReply(const QString &error, const QStringList& errorDetails = {}, const QString &command = "", int tan = 0, InstanceCmd::Type isInstanceCmd = InstanceCmd::No);
|
||||||
|
|
||||||
void sendNoAuthorization(const JsonApiCommand& cmd);
|
void sendNoAuthorization(const JsonApiCommand& cmd);
|
||||||
|
|
||||||
|
@ -194,6 +194,14 @@ public:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InstanceCmd {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
No,
|
||||||
|
Yes
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
class JsonApiCommand {
|
class JsonApiCommand {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -202,21 +210,26 @@ public:
|
|||||||
subCommand(SubCommand::Unknown),
|
subCommand(SubCommand::Unknown),
|
||||||
tan(0),
|
tan(0),
|
||||||
authorization(Authorization::Admin),
|
authorization(Authorization::Admin),
|
||||||
|
isInstanceCmd(InstanceCmd::No),
|
||||||
isNolistenerCmd(NoListenerCmd::Yes)
|
isNolistenerCmd(NoListenerCmd::Yes)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
JsonApiCommand(Command::Type command, SubCommand::Type subCommand,
|
JsonApiCommand(Command::Type command, SubCommand::Type subCommand,
|
||||||
Authorization::Type authorization,
|
Authorization::Type authorization,
|
||||||
NoListenerCmd::Type isNolistenerCmd, int tan = 0)
|
InstanceCmd::Type isInstanceCmd,
|
||||||
|
NoListenerCmd::Type isNolistenerCmd,
|
||||||
|
int tan = 0)
|
||||||
: command(command),
|
: command(command),
|
||||||
subCommand(subCommand),
|
subCommand(subCommand),
|
||||||
tan(tan),
|
tan(tan),
|
||||||
authorization(authorization),
|
authorization(authorization),
|
||||||
|
isInstanceCmd(isInstanceCmd),
|
||||||
isNolistenerCmd(isNolistenerCmd)
|
isNolistenerCmd(isNolistenerCmd)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Command::Type getCommand() const { return command; }
|
Command::Type getCommand() const { return command; }
|
||||||
SubCommand::Type getSubCommand() const { return subCommand; }
|
SubCommand::Type getSubCommand() const { return subCommand; }
|
||||||
|
InstanceCmd::Type instanceCmd() const { return isInstanceCmd; };
|
||||||
int getTan() const { return tan; }
|
int getTan() const { return tan; }
|
||||||
|
|
||||||
QString toString() const {
|
QString toString() const {
|
||||||
@ -232,6 +245,7 @@ public:
|
|||||||
int tan;
|
int tan;
|
||||||
|
|
||||||
Authorization::Type authorization;
|
Authorization::Type authorization;
|
||||||
|
InstanceCmd::Type isInstanceCmd;
|
||||||
NoListenerCmd::Type isNolistenerCmd;
|
NoListenerCmd::Type isNolistenerCmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -242,72 +256,72 @@ public:
|
|||||||
|
|
||||||
static const CommandLookupMap& getCommandLookup() {
|
static const CommandLookupMap& getCommandLookup() {
|
||||||
static const CommandLookupMap commandLookup {
|
static const CommandLookupMap commandLookup {
|
||||||
{ {"adjustment", ""}, { Command::Adjustment, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"adjustment", ""}, { Command::Adjustment, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"authorize", "adminRequired"}, { Command::Authorize, SubCommand::AdminRequired, Authorization::No, NoListenerCmd::Yes} },
|
{ {"authorize", "adminRequired"}, { Command::Authorize, SubCommand::AdminRequired, Authorization::No, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"authorize", "answerRequest"}, { Command::Authorize, SubCommand::AnswerRequest, Authorization::Admin, NoListenerCmd::No} },
|
{ {"authorize", "answerRequest"}, { Command::Authorize, SubCommand::AnswerRequest, Authorization::Admin, InstanceCmd::No, NoListenerCmd::No} },
|
||||||
{ {"authorize", "createToken"}, { Command::Authorize, SubCommand::CreateToken, Authorization::Admin, NoListenerCmd::No} },
|
{ {"authorize", "createToken"}, { Command::Authorize, SubCommand::CreateToken, Authorization::Admin, InstanceCmd::No, NoListenerCmd::No} },
|
||||||
{ {"authorize", "deleteToken"}, { Command::Authorize, SubCommand::DeleteToken, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"authorize", "deleteToken"}, { Command::Authorize, SubCommand::DeleteToken, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"authorize", "getPendingTokenRequests"}, { Command::Authorize, SubCommand::GetPendingTokenRequests, Authorization::Admin, NoListenerCmd::No} },
|
{ {"authorize", "getPendingTokenRequests"}, { Command::Authorize, SubCommand::GetPendingTokenRequests, Authorization::Admin, InstanceCmd::No, NoListenerCmd::No} },
|
||||||
{ {"authorize", "getTokenList"}, { Command::Authorize, SubCommand::GetTokenList, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"authorize", "getTokenList"}, { Command::Authorize, SubCommand::GetTokenList, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"authorize", "login"}, { Command::Authorize, SubCommand::Login, Authorization::No, NoListenerCmd::No} },
|
{ {"authorize", "login"}, { Command::Authorize, SubCommand::Login, Authorization::No, InstanceCmd::No, NoListenerCmd::No} },
|
||||||
{ {"authorize", "logout"}, { Command::Authorize, SubCommand::Logout, Authorization::No, NoListenerCmd::No} },
|
{ {"authorize", "logout"}, { Command::Authorize, SubCommand::Logout, Authorization::No, InstanceCmd::No, NoListenerCmd::No} },
|
||||||
{ {"authorize", "newPassword"}, { Command::Authorize, SubCommand::NewPassword, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"authorize", "newPassword"}, { Command::Authorize, SubCommand::NewPassword, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"authorize", "newPasswordRequired"}, { Command::Authorize, SubCommand::NewPasswordRequired, Authorization::No, NoListenerCmd::Yes} },
|
{ {"authorize", "newPasswordRequired"}, { Command::Authorize, SubCommand::NewPasswordRequired, Authorization::No, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"authorize", "renameToken"}, { Command::Authorize, SubCommand::RenameToken, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"authorize", "renameToken"}, { Command::Authorize, SubCommand::RenameToken, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"authorize", "requestToken"}, { Command::Authorize, SubCommand::RequestToken, Authorization::No, NoListenerCmd::Yes} },
|
{ {"authorize", "requestToken"}, { Command::Authorize, SubCommand::RequestToken, Authorization::No, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"authorize", "tokenRequired"}, { Command::Authorize, SubCommand::TokenRequired, Authorization::No, NoListenerCmd::Yes} },
|
{ {"authorize", "tokenRequired"}, { Command::Authorize, SubCommand::TokenRequired, Authorization::No, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"clear", ""}, { Command::Clear, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"clear", ""}, { Command::Clear, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"clearall", ""}, { Command::ClearAll, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"clearall", ""}, { Command::ClearAll, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"color", ""}, { Command::Color, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"color", ""}, { Command::Color, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"componentstate", ""}, { Command::ComponentState, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"componentstate", ""}, { Command::ComponentState, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"config", "getconfig"}, { Command::Config, SubCommand::GetConfig, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"config", "getconfig"}, { Command::Config, SubCommand::GetConfig, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"config", "getschema"}, { Command::Config, SubCommand::GetSchema, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"config", "getschema"}, { Command::Config, SubCommand::GetSchema, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"config", "reload"}, { Command::Config, SubCommand::Reload, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"config", "reload"}, { Command::Config, SubCommand::Reload, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"config", "restoreconfig"}, { Command::Config, SubCommand::RestoreConfig, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"config", "restoreconfig"}, { Command::Config, SubCommand::RestoreConfig, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"config", "setconfig"}, { Command::Config, SubCommand::SetConfig, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"config", "setconfig"}, { Command::Config, SubCommand::SetConfig, Authorization::Admin, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"correction", ""}, { Command::Correction, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"correction", ""}, { Command::Correction, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"create-effect", ""}, { Command::CreateEffect, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"create-effect", ""}, { Command::CreateEffect, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"delete-effect", ""}, { Command::DeleteEffect, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"delete-effect", ""}, { Command::DeleteEffect, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"effect", ""}, { Command::Effect, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"effect", ""}, { Command::Effect, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"image", ""}, { Command::Image, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"image", ""}, { Command::Image, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"inputsource", "discover"}, { Command::InputSource, SubCommand::Discover, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"inputsource", "discover"}, { Command::InputSource, SubCommand::Discover, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"inputsource", "getProperties"}, { Command::InputSource, SubCommand::GetProperties, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"inputsource", "getProperties"}, { Command::InputSource, SubCommand::GetProperties, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"instance", "createInstance"}, { Command::Instance, SubCommand::CreateInstance, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"instance", "createInstance"}, { Command::Instance, SubCommand::CreateInstance, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"instance", "deleteInstance"}, { Command::Instance, SubCommand::DeleteInstance, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"instance", "deleteInstance"}, { Command::Instance, SubCommand::DeleteInstance, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"instance", "saveName"}, { Command::Instance, SubCommand::SaveName, Authorization::Admin, NoListenerCmd::Yes} },
|
{ {"instance", "saveName"}, { Command::Instance, SubCommand::SaveName, Authorization::Admin, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"instance", "startInstance"}, { Command::Instance, SubCommand::StartInstance, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"instance", "startInstance"}, { Command::Instance, SubCommand::StartInstance, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"instance", "stopInstance"}, { Command::Instance, SubCommand::StopInstance, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"instance", "stopInstance"}, { Command::Instance, SubCommand::StopInstance, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"instance", "switchTo"}, { Command::Instance, SubCommand::SwitchTo, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"instance", "switchTo"}, { Command::Instance, SubCommand::SwitchTo, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"ledcolors", "imagestream-start"}, { Command::LedColors, SubCommand::ImageStreamStart, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"ledcolors", "imagestream-start"}, { Command::LedColors, SubCommand::ImageStreamStart, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"ledcolors", "imagestream-stop"}, { Command::LedColors, SubCommand::ImageStreamStop, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"ledcolors", "imagestream-stop"}, { Command::LedColors, SubCommand::ImageStreamStop, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"ledcolors", "ledstream-start"}, { Command::LedColors, SubCommand::LedStreamStart, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"ledcolors", "ledstream-start"}, { Command::LedColors, SubCommand::LedStreamStart, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"ledcolors", "ledstream-stop"}, { Command::LedColors, SubCommand::LedStreamStop, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"ledcolors", "ledstream-stop"}, { Command::LedColors, SubCommand::LedStreamStop, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"leddevice", "addAuthorization"}, { Command::LedDevice, SubCommand::AddAuthorization, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"leddevice", "addAuthorization"}, { Command::LedDevice, SubCommand::AddAuthorization, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"leddevice", "discover"}, { Command::LedDevice, SubCommand::Discover, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"leddevice", "discover"}, { Command::LedDevice, SubCommand::Discover, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"leddevice", "getProperties"}, { Command::LedDevice, SubCommand::GetProperties, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"leddevice", "getProperties"}, { Command::LedDevice, SubCommand::GetProperties, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"leddevice", "identify"}, { Command::LedDevice, SubCommand::Identify, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"leddevice", "identify"}, { Command::LedDevice, SubCommand::Identify, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"logging", "start"}, { Command::Logging, SubCommand::Start, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"logging", "start"}, { Command::Logging, SubCommand::Start, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"logging", "stop"}, { Command::Logging, SubCommand::Stop, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"logging", "stop"}, { Command::Logging, SubCommand::Stop, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"logging", "update"}, { Command::Logging, SubCommand::Update, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"logging", "update"}, { Command::Logging, SubCommand::Update, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"processing", ""}, { Command::Processing, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"processing", ""}, { Command::Processing, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"sourceselect", ""}, { Command::SourceSelect, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"serverinfo", ""}, { Command::ServerInfo, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"serverinfo", ""}, { Command::ServerInfo, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"serverinfo", "getInfo"}, { Command::ServerInfo, SubCommand::GetInfo, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"serverinfo", "getInfo"}, { Command::ServerInfo, SubCommand::GetInfo, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"serverinfo", "subscribe"}, { Command::ServerInfo, SubCommand::Subscribe, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::No} },
|
||||||
{ {"serverinfo", "subscribe"}, { Command::ServerInfo, SubCommand::Subscribe, Authorization::Yes, NoListenerCmd::No} },
|
{ {"serverinfo", "unsubscribe"}, { Command::ServerInfo, SubCommand::Unsubscribe, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::No} },
|
||||||
{ {"serverinfo", "unsubscribe"}, { Command::ServerInfo, SubCommand::Unsubscribe, Authorization::Yes, NoListenerCmd::No} },
|
{ {"serverinfo", "getSubscriptions"}, { Command::ServerInfo, SubCommand::GetSubscriptions, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::No} },
|
||||||
{ {"serverinfo", "getSubscriptions"}, { Command::ServerInfo, SubCommand::GetSubscriptions, Authorization::Yes, NoListenerCmd::No} },
|
{ {"serverinfo", "getSubscriptionCommands"}, { Command::ServerInfo, SubCommand::GetSubscriptionCommands, Authorization::No, InstanceCmd::No, NoListenerCmd::No} },
|
||||||
{ {"serverinfo", "getSubscriptionCommands"}, { Command::ServerInfo, SubCommand::GetSubscriptionCommands, Authorization::No, NoListenerCmd::No} },
|
{ {"service", "discover"}, { Command::Service, SubCommand::Discover, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"sysinfo", ""}, { Command::SysInfo, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"sourceselect", ""}, { Command::SourceSelect, SubCommand::Empty, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"system", "restart"}, { Command::System, SubCommand::Restart, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"sysinfo", ""}, { Command::SysInfo, SubCommand::Empty, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"system", "resume"}, { Command::System, SubCommand::Resume, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"system", "restart"}, { Command::System, SubCommand::Restart, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"system", "suspend"}, { Command::System, SubCommand::Suspend, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"system", "resume"}, { Command::System, SubCommand::Resume, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"system", "toggleSuspend"}, { Command::System, SubCommand::ToggleSuspend, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"system", "suspend"}, { Command::System, SubCommand::Suspend, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"system", "idle"}, { Command::System, SubCommand::Idle, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"system", "toggleSuspend"}, { Command::System, SubCommand::ToggleSuspend, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"system", "toggleIdle"}, { Command::System, SubCommand::ToggleIdle, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"system", "idle"}, { Command::System, SubCommand::Idle, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"temperature", ""}, { Command::Temperature, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"system", "toggleIdle"}, { Command::System, SubCommand::ToggleIdle, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} },
|
||||||
{ {"transform", ""}, { Command::Transform, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"temperature", ""}, { Command::Temperature, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"videomode", ""}, { Command::VideoMode, SubCommand::Empty, Authorization::Yes, NoListenerCmd::Yes} },
|
{ {"transform", ""}, { Command::Transform, SubCommand::Empty, Authorization::Yes, InstanceCmd::Yes, NoListenerCmd::Yes} },
|
||||||
{ {"service", "discover"}, { Command::Service, SubCommand::Discover, Authorization::Yes, NoListenerCmd::Yes} }
|
{ {"videomode", ""}, { Command::VideoMode, SubCommand::Empty, Authorization::Yes, InstanceCmd::No, NoListenerCmd::Yes} }
|
||||||
};
|
};
|
||||||
return commandLookup;
|
return commandLookup;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ public:
|
|||||||
#if defined(ENABLE_EFFECTENGINE)
|
#if defined(ENABLE_EFFECTENGINE)
|
||||||
EffectsUpdate,
|
EffectsUpdate,
|
||||||
#endif
|
#endif
|
||||||
|
EventUpdate,
|
||||||
ImageToLedMappingUpdate,
|
ImageToLedMappingUpdate,
|
||||||
ImageUpdate,
|
ImageUpdate,
|
||||||
InstanceUpdate,
|
InstanceUpdate,
|
||||||
@ -35,6 +36,7 @@ public:
|
|||||||
#if defined(ENABLE_EFFECTENGINE)
|
#if defined(ENABLE_EFFECTENGINE)
|
||||||
case EffectsUpdate: return "effects-update";
|
case EffectsUpdate: return "effects-update";
|
||||||
#endif
|
#endif
|
||||||
|
case EventUpdate: return "event-update";
|
||||||
case ImageToLedMappingUpdate: return "imageToLedMapping-update";
|
case ImageToLedMappingUpdate: return "imageToLedMapping-update";
|
||||||
case ImageUpdate: return "image-update";
|
case ImageUpdate: return "image-update";
|
||||||
case InstanceUpdate: return "instance-update";
|
case InstanceUpdate: return "instance-update";
|
||||||
@ -48,6 +50,30 @@ public:
|
|||||||
default: return "unknown";
|
default: return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isInstacneSpecific(Type type) {
|
||||||
|
switch (type) {
|
||||||
|
case AdjustmentUpdate:
|
||||||
|
case ComponentsUpdate:
|
||||||
|
#if defined(ENABLE_EFFECTENGINE)
|
||||||
|
case EffectsUpdate:
|
||||||
|
#endif
|
||||||
|
case ImageToLedMappingUpdate:
|
||||||
|
case ImageUpdate:
|
||||||
|
case LedColorsUpdate:
|
||||||
|
case LedsUpdate:
|
||||||
|
case PrioritiesUpdate:
|
||||||
|
case SettingsUpdate:
|
||||||
|
return true;
|
||||||
|
case EventUpdate:
|
||||||
|
case InstanceUpdate:
|
||||||
|
case LogMsgUpdate:
|
||||||
|
case TokenUpdate:
|
||||||
|
case VideomodeUpdate:
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class JsonApiSubscription {
|
class JsonApiSubscription {
|
||||||
@ -86,6 +112,7 @@ public:
|
|||||||
#if defined(ENABLE_EFFECTENGINE)
|
#if defined(ENABLE_EFFECTENGINE)
|
||||||
{ {"effects-update"}, { Subscription::EffectsUpdate, true} },
|
{ {"effects-update"}, { Subscription::EffectsUpdate, true} },
|
||||||
#endif
|
#endif
|
||||||
|
{ {"event-update"}, { Subscription::EventUpdate, true} },
|
||||||
{ {"imageToLedMapping-update"}, { Subscription::ImageToLedMappingUpdate, true} },
|
{ {"imageToLedMapping-update"}, { Subscription::ImageToLedMappingUpdate, true} },
|
||||||
{ {"image-update"}, { Subscription::ImageUpdate, false} },
|
{ {"image-update"}, { Subscription::ImageUpdate, false} },
|
||||||
{ {"instance-update"}, { Subscription::InstanceUpdate, true} },
|
{ {"instance-update"}, { Subscription::InstanceUpdate, true} },
|
||||||
|
@ -2,22 +2,17 @@
|
|||||||
|
|
||||||
#include "api/JsonApiSubscription.h"
|
#include "api/JsonApiSubscription.h"
|
||||||
#include <api/API.h>
|
#include <api/API.h>
|
||||||
|
#include <events/EventEnum.h>
|
||||||
|
|
||||||
// qt incl
|
// qt incl
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
// components def
|
|
||||||
#include <utils/Components.h>
|
#include <utils/Components.h>
|
||||||
|
|
||||||
// videModes
|
|
||||||
#include <utils/VideoMode.h>
|
#include <utils/VideoMode.h>
|
||||||
// settings
|
|
||||||
#include <utils/settings.h>
|
#include <utils/settings.h>
|
||||||
// AuthManager
|
|
||||||
#include <hyperion/AuthManager.h>
|
#include <hyperion/AuthManager.h>
|
||||||
|
|
||||||
#include <hyperion/PriorityMuxer.h>
|
#include <hyperion/PriorityMuxer.h>
|
||||||
|
|
||||||
class Hyperion;
|
class Hyperion;
|
||||||
@ -177,6 +172,12 @@ private slots:
|
|||||||
///
|
///
|
||||||
void handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &);
|
void handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Is called whenever an event is triggert
|
||||||
|
/// @param image The current event
|
||||||
|
///
|
||||||
|
void handleEventUpdate(const Event &event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// construct callback msg
|
/// construct callback msg
|
||||||
|
@ -1312,45 +1312,51 @@ void JsonAPI::handleSystemCommand(const QJsonObject& /*message*/, const JsonApiC
|
|||||||
|
|
||||||
void JsonAPI::sendSuccessReply(const JsonApiCommand& cmd)
|
void JsonAPI::sendSuccessReply(const JsonApiCommand& cmd)
|
||||||
{
|
{
|
||||||
sendSuccessReply(cmd.toString(), cmd.tan);
|
sendSuccessReply(cmd.toString(), cmd.tan, cmd.isInstanceCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendSuccessReply(const QString &command, int tan)
|
void JsonAPI::sendSuccessReply(const QString &command, int tan, InstanceCmd::Type isInstanceCmd)
|
||||||
{
|
{
|
||||||
// create reply
|
|
||||||
QJsonObject reply;
|
QJsonObject reply;
|
||||||
reply["instance"] = _hyperion->getInstanceIndex();
|
|
||||||
reply["success"] = true;
|
reply["success"] = true;
|
||||||
reply["command"] = command;
|
reply["command"] = command;
|
||||||
reply["tan"] = tan;
|
reply["tan"] = tan;
|
||||||
|
|
||||||
// send reply
|
if (isInstanceCmd == InstanceCmd::Yes)
|
||||||
|
{
|
||||||
|
reply["instance"] = _hyperion->getInstanceIndex();
|
||||||
|
}
|
||||||
|
|
||||||
emit callbackMessage(reply);
|
emit callbackMessage(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const JsonApiCommand& cmd)
|
void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const JsonApiCommand& cmd)
|
||||||
{
|
{
|
||||||
sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.tan, {});
|
sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.tan, {}, cmd.isInstanceCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const QString &command, int tan)
|
void JsonAPI::sendSuccessDataReply(const QJsonValue &infoData, const QString &command, int tan, InstanceCmd::Type isInstanceCmd)
|
||||||
{
|
{
|
||||||
sendSuccessDataReplyWithError(infoData, command, tan, {});
|
sendSuccessDataReplyWithError(infoData, command, tan, {}, isInstanceCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const JsonApiCommand& cmd, const QStringList& errorDetails)
|
void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const JsonApiCommand& cmd, const QStringList& errorDetails)
|
||||||
{
|
{
|
||||||
sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.tan, errorDetails);
|
sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.tan, errorDetails, cmd.isInstanceCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const QString &command, int tan, const QStringList& errorDetails)
|
void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const QString &command, int tan, const QStringList& errorDetails, InstanceCmd::Type isInstanceCmd)
|
||||||
{
|
{
|
||||||
QJsonObject reply;
|
QJsonObject reply;
|
||||||
reply["instance"] = _hyperion->getInstanceIndex();
|
|
||||||
reply["success"] = true;
|
reply["success"] = true;
|
||||||
|
|
||||||
reply["command"] = command;
|
reply["command"] = command;
|
||||||
reply["tan"] = tan;
|
reply["tan"] = tan;
|
||||||
|
|
||||||
|
if (isInstanceCmd == InstanceCmd::Yes)
|
||||||
|
{
|
||||||
|
reply["instance"] = _hyperion->getInstanceIndex();
|
||||||
|
}
|
||||||
|
|
||||||
reply["info"] = infoData;
|
reply["info"] = infoData;
|
||||||
|
|
||||||
if (!errorDetails.isEmpty())
|
if (!errorDetails.isEmpty())
|
||||||
@ -1369,13 +1375,19 @@ void JsonAPI::sendSuccessDataReplyWithError(const QJsonValue &infoData, const QS
|
|||||||
|
|
||||||
void JsonAPI::sendNewRequest(const QJsonValue &infoData, const JsonApiCommand& cmd)
|
void JsonAPI::sendNewRequest(const QJsonValue &infoData, const JsonApiCommand& cmd)
|
||||||
{
|
{
|
||||||
sendSuccessDataReplyWithError(infoData, cmd.toString());
|
sendSuccessDataReplyWithError(infoData, cmd.toString(), cmd.isInstanceCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendNewRequest(const QJsonValue &infoData, const QString &command)
|
void JsonAPI::sendNewRequest(const QJsonValue &infoData, const QString &command, InstanceCmd::Type isInstanceCmd)
|
||||||
{
|
{
|
||||||
QJsonObject request;
|
QJsonObject request;
|
||||||
request["command"] = command;
|
request["command"] = command;
|
||||||
|
|
||||||
|
if (isInstanceCmd == InstanceCmd::Yes)
|
||||||
|
{
|
||||||
|
request["instance"] = _hyperion->getInstanceIndex();
|
||||||
|
}
|
||||||
|
|
||||||
request["info"] = infoData;
|
request["info"] = infoData;
|
||||||
|
|
||||||
emit callbackMessage(request);
|
emit callbackMessage(request);
|
||||||
@ -1383,24 +1395,26 @@ void JsonAPI::sendNewRequest(const QJsonValue &infoData, const QString &command)
|
|||||||
|
|
||||||
void JsonAPI::sendErrorReply(const QString &error, const JsonApiCommand& cmd)
|
void JsonAPI::sendErrorReply(const QString &error, const JsonApiCommand& cmd)
|
||||||
{
|
{
|
||||||
sendErrorReply(error, {}, cmd.toString(), cmd.tan);
|
sendErrorReply(error, {}, cmd.toString(), cmd.tan, cmd.isInstanceCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetails, const JsonApiCommand& cmd)
|
void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetails, const JsonApiCommand& cmd)
|
||||||
{
|
{
|
||||||
sendErrorReply(error, errorDetails, cmd.toString(), cmd.tan);
|
sendErrorReply(error, errorDetails, cmd.toString(), cmd.tan, cmd.isInstanceCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetails, const QString &command, int tan)
|
void JsonAPI::sendErrorReply(const QString &error, const QStringList& errorDetails, const QString &command, int tan, InstanceCmd::Type isInstanceCmd)
|
||||||
{
|
{
|
||||||
// create reply
|
|
||||||
QJsonObject reply;
|
QJsonObject reply;
|
||||||
reply["instance"] = _hyperion->getInstanceIndex();
|
|
||||||
reply["success"] = false;
|
reply["success"] = false;
|
||||||
|
|
||||||
reply["command"] = command;
|
reply["command"] = command;
|
||||||
reply["tan"] = tan;
|
reply["tan"] = tan;
|
||||||
|
|
||||||
|
if (isInstanceCmd == InstanceCmd::Yes)
|
||||||
|
{
|
||||||
|
reply["instance"] = _hyperion->getInstanceIndex();
|
||||||
|
}
|
||||||
|
|
||||||
reply["error"] = error;
|
reply["error"] = error;
|
||||||
if (!errorDetails.isEmpty())
|
if (!errorDetails.isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -1,33 +1,20 @@
|
|||||||
// proj incl
|
|
||||||
#include <api/JsonCallbacks.h>
|
#include <api/JsonCallbacks.h>
|
||||||
#include <api/JsonInfo.h>
|
#include <api/JsonInfo.h>
|
||||||
#include <api/JsonApiSubscription.h>
|
#include <api/JsonApiSubscription.h>
|
||||||
|
|
||||||
// hyperion
|
|
||||||
#include <hyperion/Hyperion.h>
|
#include <hyperion/Hyperion.h>
|
||||||
|
|
||||||
// HyperionIManager
|
|
||||||
#include <hyperion/HyperionIManager.h>
|
#include <hyperion/HyperionIManager.h>
|
||||||
// components
|
#include <events/EventHandler.h>
|
||||||
|
|
||||||
#include <hyperion/ComponentRegister.h>
|
#include <hyperion/ComponentRegister.h>
|
||||||
// priorityMuxer
|
|
||||||
|
|
||||||
#include <hyperion/PriorityMuxer.h>
|
#include <hyperion/PriorityMuxer.h>
|
||||||
|
|
||||||
// utils
|
|
||||||
#include <utils/ColorSys.h>
|
#include <utils/ColorSys.h>
|
||||||
|
#include <hyperion/ImageProcessor.h>
|
||||||
|
|
||||||
// qt
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
|
||||||
// Image to led map helper
|
|
||||||
|
|
||||||
#include <hyperion/ImageProcessor.h>
|
|
||||||
|
|
||||||
using namespace hyperion;
|
using namespace hyperion;
|
||||||
|
|
||||||
JsonCallbacks::JsonCallbacks(Logger *log, const QString& peerAddress, QObject* parent)
|
JsonCallbacks::JsonCallbacks(Logger *log, const QString& peerAddress, QObject* parent)
|
||||||
@ -56,6 +43,9 @@ bool JsonCallbacks::subscribe(const Subscription::Type cmd)
|
|||||||
connect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCallbacks::handleEffectListChange);
|
connect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCallbacks::handleEffectListChange);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case Subscription::EventUpdate:
|
||||||
|
connect(EventHandler::getInstance().data(), &EventHandler::signalEvent, this, &JsonCallbacks::handleEventUpdate);
|
||||||
|
break;
|
||||||
case Subscription::ImageToLedMappingUpdate:
|
case Subscription::ImageToLedMappingUpdate:
|
||||||
connect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCallbacks::handleImageToLedsMappingChange);
|
connect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCallbacks::handleImageToLedsMappingChange);
|
||||||
break;
|
break;
|
||||||
@ -155,6 +145,9 @@ bool JsonCallbacks::unsubscribe(const Subscription::Type cmd)
|
|||||||
disconnect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCallbacks::handleEffectListChange);
|
disconnect(_hyperion, &Hyperion::effectListUpdated, this, &JsonCallbacks::handleEffectListChange);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case Subscription::EventUpdate:
|
||||||
|
disconnect(EventHandler::getInstance().data(), &EventHandler::signalEvent, this, &JsonCallbacks::handleEventUpdate);
|
||||||
|
break;
|
||||||
case Subscription::ImageToLedMappingUpdate:
|
case Subscription::ImageToLedMappingUpdate:
|
||||||
disconnect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCallbacks::handleImageToLedsMappingChange);
|
disconnect(_hyperion, &Hyperion::imageToLedsMappingChanged, this, &JsonCallbacks::handleImageToLedsMappingChange);
|
||||||
break;
|
break;
|
||||||
@ -290,9 +283,13 @@ QStringList JsonCallbacks::getSubscribedCommands() const
|
|||||||
void JsonCallbacks::doCallback(Subscription::Type cmd, const QVariant& data)
|
void JsonCallbacks::doCallback(Subscription::Type cmd, const QVariant& data)
|
||||||
{
|
{
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
obj["instance"] = _hyperion->getInstanceIndex();
|
|
||||||
obj["command"] = Subscription::toString(cmd);
|
obj["command"] = Subscription::toString(cmd);
|
||||||
|
|
||||||
|
if (Subscription::isInstacneSpecific(cmd))
|
||||||
|
{
|
||||||
|
obj["instance"] = _hyperion->getInstanceIndex();
|
||||||
|
}
|
||||||
|
|
||||||
if (data.userType() == QMetaType::QJsonArray) {
|
if (data.userType() == QMetaType::QJsonArray) {
|
||||||
obj["data"] = data.toJsonArray();
|
obj["data"] = data.toJsonArray();
|
||||||
} else {
|
} else {
|
||||||
@ -449,3 +446,13 @@ void JsonCallbacks::handleLogMessageUpdate(const Logger::T_LOG_MESSAGE &msg)
|
|||||||
|
|
||||||
doCallback(Subscription::LogMsgUpdate, QVariant(result));
|
doCallback(Subscription::LogMsgUpdate, QVariant(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JsonCallbacks::handleEventUpdate(const Event &event)
|
||||||
|
{
|
||||||
|
QJsonObject result;
|
||||||
|
|
||||||
|
result["event"] = eventToString(event);
|
||||||
|
|
||||||
|
doCallback(Subscription::EventUpdate, QVariant(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -179,10 +179,12 @@ void EventHandler::handleEvent(Event event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Event::Reload:
|
case Event::Reload:
|
||||||
|
emit signalEvent(Event::Reload);
|
||||||
Process::restartHyperion(10);
|
Process::restartHyperion(10);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Event::Restart:
|
case Event::Restart:
|
||||||
|
emit signalEvent(Event::Restart);
|
||||||
Process::restartHyperion(11);
|
Process::restartHyperion(11);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user