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

@@ -181,6 +181,7 @@ if (WIN32)
get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
get_filename_component(QT_BIN_DIR "${QT_QMAKE_EXECUTABLE}" DIRECTORY)
find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_BIN_DIR}")
if (NOT WINDEPLOYQT_EXECUTABLE)
find_program(WINDEPLOYQT_EXECUTABLE windeployqt)
endif()
@@ -190,6 +191,37 @@ if (WIN32)
message(STATUS "Found windeployqt: ${WINDEPLOYQT_EXECUTABLE} PATH_HINT:${QT_BIN_DIR}")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${WINDEPLOYQT_EXECUTABLE} ${WINDEPLOYQT_PARAMS_RUNTIME} "$<TARGET_FILE:${PROJECT_NAME}>")
endif()
find_package(OpenSSL REQUIRED)
if (OPENSSL_FOUND)
string(REGEX MATCHALL "[0-9]+" openssl_versions "${OPENSSL_VERSION}")
list(GET openssl_versions 0 openssl_version_major)
list(GET openssl_versions 1 openssl_version_minor)
set(library_suffix "-${openssl_version_major}_${openssl_version_minor}")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
string(APPEND library_suffix "-x64")
endif()
find_file(OPENSSL_SSL
NAMES "libssl${library_suffix}.dll"
PATHS ${OPENSSL_INCLUDE_DIR}/.. ${OPENSSL_INCLUDE_DIR}/../bin
NO_DEFAULT_PATH
)
find_file(OPENSSL_CRYPTO
NAMES "libcrypto${library_suffix}.dll"
PATHS ${OPENSSL_INCLUDE_DIR}/.. ${OPENSSL_INCLUDE_DIR}/../bin
NO_DEFAULT_PATH
)
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${OPENSSL_SSL} ${OPENSSL_CRYPTO}
$<TARGET_FILE_DIR:${PROJECT_NAME}>
)
endif(OPENSSL_FOUND)
endif(WIN32)
if(ENABLE_DEPLOY_DEPENDENCIES)

View File

@@ -26,6 +26,8 @@
#include <QDir>
#include <QStringList>
#include <QSystemTrayIcon>
#include <QNetworkInterface>
#include <QHostInfo>
#include "HyperionConfig.h"
@@ -47,7 +49,7 @@
using namespace commandline;
#define PERM0664 QFileDevice::ReadOwner | QFileDevice::ReadGroup | QFileDevice::ReadOther | QFileDevice::WriteOwner | QFileDevice::WriteGroup
#define PERM0664 (QFileDevice::ReadOwner | QFileDevice::ReadGroup | QFileDevice::ReadOther | QFileDevice::WriteOwner | QFileDevice::WriteGroup)
#ifndef _WIN32
void signal_handler(int signum)
@@ -59,7 +61,6 @@ void signal_handler(int signum)
{
// only quit when a registered child process is gone
// currently this feature is not active ...
return;
}
else if (signum == SIGUSR1)
{
@@ -67,7 +68,6 @@ void signal_handler(int signum)
{
_hyperion->toggleStateAllInstances(false);
}
return;
}
else if (signum == SIGUSR2)
{
@@ -75,7 +75,6 @@ void signal_handler(int signum)
{
_hyperion->toggleStateAllInstances(true);
}
return;
}
}
#endif
@@ -106,8 +105,8 @@ QCoreApplication* createApplication(int &argc, char *argv[])
{
// if x11, then test if xserver is available
#if defined(ENABLE_X11)
Display* dpy = XOpenDisplay(NULL);
if (dpy != NULL)
Display* dpy = XOpenDisplay(nullptr);
if (dpy != nullptr)
{
XCloseDisplay(dpy);
isGuiApp = true;
@@ -165,7 +164,7 @@ int main(int argc, char** argv)
// Initialising QCoreApplication
QScopedPointer<QCoreApplication> app(createApplication(argc, argv));
bool isGuiApp = (qobject_cast<QApplication *>(app.data()) != 0 && QSystemTrayIcon::isSystemTrayAvailable());
bool isGuiApp = (qobject_cast<QApplication *>(app.data()) != nullptr && QSystemTrayIcon::isSystemTrayAvailable());
DefaultSignalHandler::install();
@@ -200,6 +199,13 @@ int main(int argc, char** argv)
parser.process(*qApp);
#ifdef WIN32
if (parser.isSet(consoleOption))
{
CreateConsole();
}
#endif
if (parser.isSet(versionOption))
{
std::cout
@@ -215,6 +221,24 @@ int main(int argc, char** argv)
if (getProcessIdsByProcessName(processName).size() > 1)
{
Error(log, "The Hyperion Daemon is already running, abort start");
// use the first non-localhost IPv4 address, IPv6 are not supported by Yeelight currently
for (const auto& address : QNetworkInterface::allAddresses())
{
if (!address.isLoopback() && (address.protocol() == QAbstractSocket::IPv4Protocol))
{
std::cout << "Access the Hyperion User-Interface for configuration and control via:" << std::endl;
std::cout << "http:://" << address.toString().toStdString() << ":8090" << std::endl;
QHostInfo hostInfo = QHostInfo::fromName(address.toString());
if (hostInfo.error() == QHostInfo::NoError)
{
QString hostname = hostInfo.hostName();
std::cout << "http:://" << hostname.toStdString() << ":8090" << std::endl;
}
break;
}
}
return 0;
}
}
@@ -226,13 +250,6 @@ int main(int argc, char** argv)
}
}
#ifdef WIN32
if (parser.isSet(consoleOption))
{
CreateConsole();
}
#endif
int logLevelCheck = 0;
if (parser.isSet(silentOption))
{
@@ -268,11 +285,13 @@ int main(int argc, char** argv)
std::cout << "Extract to folder: " << destDir.absolutePath().toStdString() << std::endl;
QStringList filenames = directory.entryList(QStringList() << "*", QDir::Files, QDir::Name | QDir::IgnoreCase);
QString destFileName;
for (const QString & filename : filenames)
for (const QString & filename : qAsConst(filenames))
{
destFileName = destDir.dirName()+"/"+filename;
if (QFile::exists(destFileName))
{
QFile::remove(destFileName);
}
std::cout << "Extract: " << filename.toStdString() << " ... ";
if (QFile::copy(QString(":/effects/")+filename, destFileName))
@@ -303,20 +322,16 @@ int main(int argc, char** argv)
try
{
if (dbFile.exists())
{
if (!dbFile.isReadable())
{
throw std::runtime_error("Configuration database '" + dbFile.absoluteFilePath().toStdString() + "' is not readable. Please setup permissions correctly!");
}
else
if (!dbFile.isWritable())
{
if (!dbFile.isWritable())
{
readonlyMode = true;
}
readonlyMode = true;
}
}
else
@@ -338,18 +353,16 @@ int main(int argc, char** argv)
Error(log,"Password reset is not possible. The user data path '%s' is not writeable.", QSTRING_CSTR(userDataDirectory.absolutePath()));
throw std::runtime_error("Password reset failed");
}
else
{
AuthTable* table = new AuthTable(userDataDirectory.absolutePath());
if(table->resetHyperionUser()){
Info(log,"Password reset successful");
delete table;
exit(0);
} else {
Error(log,"Failed to reset password!");
delete table;
exit(1);
}
AuthTable* table = new AuthTable(userDataDirectory.absolutePath());
if(table->resetHyperionUser()){
Info(log,"Password reset successful");
delete table;
exit(0);
} else {
Error(log,"Failed to reset password!");
delete table;
exit(1);
}
}
@@ -361,25 +374,23 @@ int main(int argc, char** argv)
Error(log,"Deleting the configuration database is not possible. The user data path '%s' is not writeable.", QSTRING_CSTR(dbFile.absolutePath()));
throw std::runtime_error("Deleting the configuration database failed");
}
else
if (QFile::exists(dbFile.absoluteFilePath()))
{
if (QFile::exists(dbFile.absoluteFilePath()))
if (!QFile::remove(dbFile.absoluteFilePath()))
{
if (!QFile::remove(dbFile.absoluteFilePath()))
{
Info(log,"Failed to delete Database!");
exit(1);
}
else
{
Info(log,"Configuration database deleted successfully.");
}
Info(log,"Failed to delete Database!");
exit(1);
}
else
{
Warning(log,"Configuration database [%s] does not exist!", QSTRING_CSTR(dbFile.absoluteFilePath()));
Info(log,"Configuration database deleted successfully.");
}
}
else
{
Warning(log,"Configuration database [%s] does not exist!", QSTRING_CSTR(dbFile.absoluteFilePath()));
}
}
Info(log,"Starting Hyperion - %s, %s, built: %s:%s", HYPERION_VERSION, HYPERION_BUILD_ID, __DATE__, __TIME__);