IPv6 support (#1369)

* hyperion-remote - Support IPv6

* LEDDevices - Remove IPv6 limitations

* Separate JsonEditorHostValidation

* Standalone grabbers & JSON/Flatbuffer forwarder: IPv6 support

* remote: Fix setting multiple colors via Hex, add standard logging

* IPv6 Updates -Add db migration activities

* Addressing non-Windows compile issues

* Code cleanup, address clang feedback

* Update address (hostname, IPv4/IPv6) help text

* Apply migration steps to "old" configurations imported

* Show user the UI-Url, if hyperion is already running, address clang findings

* Windows Cmake OpenSLL output

* Minor Text update
This commit is contained in:
LordGrey
2021-11-17 20:30:43 +00:00
committed by GitHub
parent b33466d392
commit ad293b2fb6
61 changed files with 1714 additions and 926 deletions

View File

@@ -10,6 +10,7 @@
#include <QJsonArray>
#include <QJsonDocument>
#include <QHostInfo>
#include <QUrl>
// hyperion-remote includes
#include "JsonConnection.h"
@@ -17,31 +18,17 @@
// util includes
#include <utils/JsonUtils.h>
JsonConnection::JsonConnection(const QString & address, bool printJson)
JsonConnection::JsonConnection(const QString & host, bool printJson , quint16 port)
: _printJson(printJson)
, _log(Logger::getInstance("REMOTE"))
, _socket()
{
QStringList parts = address.split(":");
if (parts.size() != 2)
{
throw std::runtime_error(QString("Wrong address: unable to parse address (%1)").arg(address).toStdString());
}
bool ok;
uint16_t port = parts[1].toUShort(&ok);
if (!ok)
{
throw std::runtime_error(QString("Wrong address: Unable to parse the port number (%1)").arg(parts[1]).toStdString());
}
_socket.connectToHost(parts[0], port);
_socket.connectToHost(host, port);
if (!_socket.waitForConnected())
{
throw std::runtime_error("Unable to connect to host");
throw std::runtime_error(QString("Unable to connect to host (%1), port (%2)").arg(host).arg(port).toStdString());
}
qDebug() << "Connected to:" << address;
Debug(_log, "Connected to: %s, port: %u", QSTRING_CSTR(host), port);
}
JsonConnection::~JsonConnection()
@@ -51,7 +38,7 @@ JsonConnection::~JsonConnection()
void JsonConnection::setColor(std::vector<QColor> colors, int priority, int duration)
{
qDebug() << "Set color to " << colors[0].red() << " " << colors[0].green() << " " << colors[0].blue() << (colors.size() > 1 ? " + ..." : "");
Debug(_log, "Set color to [%d,%d,%d] %s", colors[0].red(), colors[0].green(), colors[0].blue(), (colors.size() > 1 ? " + ..." : ""));
// create command
QJsonObject command;
@@ -81,7 +68,7 @@ void JsonConnection::setColor(std::vector<QColor> colors, int priority, int dura
void JsonConnection::setImage(QImage &image, int priority, int duration)
{
qDebug() << "Set image has size: " << image.width() << "x" << image.height();
Debug(_log, "Set image has size: %dx%d", image.width(), image.height());
// ensure the image has RGB888 format
image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
@@ -121,7 +108,7 @@ void JsonConnection::setImage(QImage &image, int priority, int duration)
void JsonConnection::setEffect(const QString &effectName, const QString & effectArgs, int priority, int duration)
{
qDebug() << "Start effect " << effectName;
Debug(_log, "Start effect: %s", QSTRING_CSTR(effectName));
// create command
QJsonObject command, effect;
@@ -157,7 +144,7 @@ void JsonConnection::setEffect(const QString &effectName, const QString & effect
void JsonConnection::createEffect(const QString &effectName, const QString &effectScript, const QString & effectArgs)
{
qDebug() << "Create effect " << effectName;
Debug(_log, "Create effect: %s", QSTRING_CSTR(effectName));
// create command
QJsonObject effect;
@@ -185,7 +172,7 @@ void JsonConnection::createEffect(const QString &effectName, const QString &effe
void JsonConnection::deleteEffect(const QString &effectName)
{
qDebug() << "Delete effect configuration" << effectName;
Debug(_log, "Delete effect configuration: %s", QSTRING_CSTR(effectName));
// create command
QJsonObject effect;
@@ -208,7 +195,7 @@ QString JsonConnection::getServerInfoString()
QJsonObject JsonConnection::getServerInfo()
{
qDebug() << "Get server info";
Debug(_log, "Get server info");
// create command
QJsonObject command;
@@ -233,7 +220,7 @@ QJsonObject JsonConnection::getServerInfo()
QString JsonConnection::getSysInfo()
{
qDebug() << "Get system info";
Debug(_log, "Get system info");
// create command
QJsonObject command;
@@ -260,7 +247,7 @@ QString JsonConnection::getSysInfo()
void JsonConnection::clear(int priority)
{
qDebug() << "Clear priority channel " << priority;
Debug(_log, "Clear priority channel [%d]", priority);
// create command
QJsonObject command;
@@ -276,7 +263,7 @@ void JsonConnection::clear(int priority)
void JsonConnection::clearAll()
{
qDebug() << "Clear all priority channels";
Debug(_log, "Clear all priority channels");
// create command
QJsonObject command;
@@ -292,7 +279,7 @@ void JsonConnection::clearAll()
void JsonConnection::setComponentState(const QString & component, bool state)
{
qDebug() << (state ? "Enable" : "Disable") << "Component" << component;
Debug(_log, "%s Component: %s", (state ? "Enable" : "Disable"), QSTRING_CSTR(component));
// create command
QJsonObject command, parameter;
@@ -339,7 +326,7 @@ void JsonConnection::setSourceAutoSelect()
QString JsonConnection::getConfig(std::string type)
{
assert( type == "schema" || type == "config" );
qDebug() << "Get configuration file from Hyperion Server";
Debug(_log, "Get configuration file from Hyperion Server");
// create command
QJsonObject command;
@@ -408,7 +395,7 @@ void JsonConnection::setAdjustment(
int *brightness,
int *brightnessC)
{
qDebug() << "Set color adjustments";
Debug(_log, "Set color adjustments");
// create command
QJsonObject command, adjust;

View File

@@ -9,6 +9,8 @@
//forward class decl
class Logger;
const int JSON_DEFAULT_PORT = 19444;
///
/// Connection class to setup an connection to the hyperion server and execute commands
///
@@ -18,10 +20,11 @@ public:
///
/// Constructor
///
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
/// @param address The hostname or IP-address of the Hyperion JSON-server (for example "192.168.0.32")
/// @param address The port of the Hyperion JSON-server (default port = 19444)
/// @param printJson Boolean indicating if the sent and received json is written to stdout
///
JsonConnection(const QString & address, bool printJson);
JsonConnection(const QString& host, bool printJson, quint16 port = JSON_DEFAULT_PORT);
///
/// Destructor

View File

@@ -9,14 +9,16 @@
#include <QCoreApplication>
#include <QLocale>
#include "HyperionConfig.h"
#include <commandline/Parser.h>
// hyperion-remote include
#include "JsonConnection.h"
// ssdp discover
#include <ssdp/SSDPDiscover.h>
#include <utils/NetUtils.h>
#include "HyperionConfig.h"
#include <commandline/Parser.h>
#include <utils/DefaultSignalHandler.h>
using namespace commandline;
@@ -66,6 +68,10 @@ int main(int argc, char * argv[])
#ifndef _WIN32
setenv("AVAHI_COMPAT_NOWARN", "1", 1);
#endif
Logger* log = Logger::getInstance("REMOTE");
Logger::setLogLevel(Logger::INFO);
std::cout
<< "hyperion-remote:" << std::endl
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
@@ -87,8 +93,8 @@ int main(int argc, char * argv[])
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// art variable definition append art to Parser short-, long option description, optional default value //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Option & argAddress = parser.add<Option> ('a', "address" , "Set the address of the hyperion server [default: %1]", "127.0.0.1:19444");
Option & argToken = parser.add<Option> ('t', "token " , "If authorization tokens are required, this token is used");
Option & argAddress = parser.add<Option> ('a', "address" , "The hostname or IP-address (IPv4 or IPv6) of the hyperion server.\nDefault port: 19444.\nSample addresses:\nHost : hyperion.fritz.box\nIPv4 : 127.0.0.1:19444\nIPv6 : [2001:1:2:3:4:5:6:7]");
Option & argToken = parser.add<Option> ('t', "token" , "If authorization tokens are required, this token is used");
Option & argInstance = parser.add<Option> ('I', "instance" , "Select a specific target instance by name for your command. By default it uses always the first instance");
IntOption & argPriority = parser.add<IntOption> ('p', "priority" , "Used to the provided priority channel (suggested 2-99) [default: %1]", "50");
IntOption & argDuration = parser.add<IntOption> ('d', "duration" , "Specify how long the LEDs should be switched on in milliseconds [default: infinity]");
@@ -111,8 +117,6 @@ int main(int argc, char * argv[])
IntOption & argBacklightThreshold = parser.add<IntOption> ('n', "backlightThreshold" , "threshold for activating backlight (minimum brightness)");
IntOption & argBacklightColored = parser.add<IntOption> (0x0, "backlightColored" , "0 = white backlight; 1 = colored backlight");
DoubleOption & argGamma = parser.add<DoubleOption> ('g', "gamma" , "Set the overall gamma of the LEDs");
BooleanOption & argPrint = parser.add<BooleanOption>(0x0, "print" , "Print the JSON input and output messages on stdout");
BooleanOption & argHelp = parser.add<BooleanOption>('h', "help" , "Show this help message and exit");
ColorOption & argRAdjust = parser.add<ColorOption> ('R', "redAdjustment" , "Set the adjustment of the red color (requires colors in hex format as RRGGBB)");
ColorOption & argGAdjust = parser.add<ColorOption> ('G', "greenAdjustment" , "Set the adjustment of the green color (requires colors in hex format as RRGGBB)");
ColorOption & argBAdjust = parser.add<ColorOption> ('B', "blueAdjustment" , "Set the adjustment of the blue color (requires colors in hex format as RRGGBB)");
@@ -131,9 +135,19 @@ int main(int argc, char * argv[])
BooleanOption & argSchemaGet = parser.add<BooleanOption>(0x0, "schemaGet" , "Print the JSON schema for Hyperion configuration");
Option & argConfigSet = parser.add<Option> (0x0, "configSet" , "Write to the actual loaded configuration file. Should be a JSON object string.");
BooleanOption & argPrint = parser.add<BooleanOption>(0x0, "print", "Print the JSON input and output messages on stdout");
BooleanOption & argDebug = parser.add<BooleanOption>(0x0, "debug", "Enable debug logging");
BooleanOption & argHelp = parser.add<BooleanOption>('h', "help", "Show this help message and exit");
// parse all _options
parser.process(app);
// check if debug logging is required
if (parser.isSet(argDebug))
{
Logger::setLogLevel(Logger::DEBUG);
}
// check if we need to display the usage. exit if we do.
if (parser.isSet(argHelp))
{
@@ -196,8 +210,17 @@ int main(int argc, char * argv[])
}
}
// Resolve hostname and port (or use default port)
QString host;
quint16 port{ JSON_DEFAULT_PORT };
if (!NetUtils::resolveHostPort(address, host, port))
{
throw std::runtime_error(QString("Wrong address: unable to parse address (%1)").arg(address).toStdString());
}
// create the connection to the hyperion server
JsonConnection connection(address, parser.isSet(argPrint));
JsonConnection connection(host, parser.isSet(argPrint), port);
// authorization token specified. Use it first
if (parser.isSet(argToken))
@@ -323,7 +346,7 @@ int main(int argc, char * argv[])
catch (const std::runtime_error & e)
{
// An error occurred. Display error and quit
std::cerr << e.what() << std::endl;
Error(log, "%s", e.what());
return 1;
}