/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright 2013 - 2020, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. * This project including source code and documentation is protected by * copyright law, and remains the property of nymea GmbH. All rights, including * reproduction, publication, editing and translation, are reserved. The use of * this project is subject to the terms of a license agreement to be concluded * with nymea GmbH in accordance with the terms of use of nymea GmbH, available * under https://nymea.io/license * * GNU General Public License Usage * Alternatively, this project may be redistributed and/or modified under the * terms of the GNU General Public License as published by the Free Software * Foundation, GNU version 3. This project is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along with * this project. If not, see . * * For any further details and any questions please contact us under * contact@nymea.io or see our FAQ/Licensing Information on * https://nymea.io/license/faq * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "nymeaconfiguration.h" #include "serverconfiguration.h" #include "serverconfigurations.h" #include "mqttpolicy.h" #include "mqttpolicies.h" #include "jsonrpc/jsonrpcclient.h" #include #include #include "logging.h" NYMEA_LOGGING_CATEGORY(dcNymeaConfiguration, "NymeaConfiguration") NymeaConfiguration::NymeaConfiguration(JsonRpcClient *client, QObject *parent): QObject(parent), m_client(client), m_tcpServerConfigurations(new ServerConfigurations(this)), m_webSocketServerConfigurations(new ServerConfigurations(this)), m_webServerConfigurations(new WebServerConfigurations(this)), m_mqttServerConfigurations(new ServerConfigurations(this)), m_mqttPolicies(new MqttPolicies(this)) { client->registerNotificationHandler(this, "Configuration", "notificationReceived"); } void NymeaConfiguration::init() { m_tcpServerConfigurations->clear(); m_webSocketServerConfigurations->clear(); m_mqttServerConfigurations->clear(); m_client->sendCommand("Configuration.GetConfigurations", this, "getConfigurationsResponse"); m_client->sendCommand("Configuration.GetMqttServerConfigurations", this, "getMqttServerConfigsReply"); m_client->sendCommand("Configuration.GetMqttPolicies", this, "getMqttPoliciesReply"); } QString NymeaConfiguration::serverName() const { return m_serverName; } void NymeaConfiguration::setServerName(const QString &serverName) { QVariantMap params; params.insert("serverName", serverName); m_client->sendCommand("Configuration.SetServerName", params, this, "setServerNameResponse"); } void NymeaConfiguration::setTimezone(const QString &timezone) { QVariantMap params; params.insert("timeZone", timezone); m_client->sendCommand("System.SetTimeZone", params, this, "setTimezoneResponse"); } bool NymeaConfiguration::debugServerEnabled() const { return m_debugServerEnabled; } void NymeaConfiguration::setDebugServerEnabled(bool debugServerEnabled) { QVariantMap params; params.insert("enabled", debugServerEnabled); m_client->sendCommand("Configuration.SetDebugServerEnabled", params, this, "setDebugServerEnabledResponse"); } bool NymeaConfiguration::cloudEnabled() const { return m_cloudEnabled; } void NymeaConfiguration::setCloudEnabled(bool cloudEnabled) { QVariantMap params; params.insert("enabled", cloudEnabled); m_client->sendCommand("Configuration.SetCloudEnabled", params, this, "setCloudEnabledResponse"); } ServerConfigurations *NymeaConfiguration::tcpServerConfigurations() const { return m_tcpServerConfigurations; } ServerConfigurations *NymeaConfiguration::webSocketServerConfigurations() const { return m_webSocketServerConfigurations; } WebServerConfigurations *NymeaConfiguration::webServerConfigurations() const { return m_webServerConfigurations; } ServerConfigurations *NymeaConfiguration::mqttServerConfigurations() const { return m_mqttServerConfigurations; } MqttPolicies *NymeaConfiguration::mqttPolicies() const { return m_mqttPolicies; } ServerConfiguration *NymeaConfiguration::createServerConfiguration(const QString &address, int port, bool authEnabled, bool sslEnabled) { return new ServerConfiguration(QUuid::createUuid().toString(), QHostAddress(address), port, authEnabled, sslEnabled); } WebServerConfiguration *NymeaConfiguration::createWebServerConfiguration(const QString &address, int port, bool authEnabled, bool sslEnabled, const QString &publicFolder) { auto ret = new WebServerConfiguration(QUuid::createUuid().toString(), QHostAddress(address), port, authEnabled, sslEnabled); ret->setPublicFolder(publicFolder); return ret; } MqttPolicy *NymeaConfiguration::createMqttPolicy() const { return new MqttPolicy(QString(), QString(), QString(), {"#"}, {"#"}); } void NymeaConfiguration::setTcpServerConfiguration(ServerConfiguration *configuration) { QVariantMap params; QVariantMap configurationMap; configurationMap.insert("id", configuration->id()); configurationMap.insert("address", configuration->address()); configurationMap.insert("port", configuration->port()); configurationMap.insert("authenticationEnabled", configuration->authenticationEnabled()); configurationMap.insert("sslEnabled", configuration->sslEnabled()); params.insert("configuration", configurationMap); m_client->sendCommand("Configuration.SetTcpServerConfiguration", params, this, "setTcpConfigReply"); } void NymeaConfiguration::setWebSocketServerConfiguration(ServerConfiguration *configuration) { QVariantMap params; QVariantMap configurationMap; configurationMap.insert("id", configuration->id()); configurationMap.insert("address", configuration->address()); configurationMap.insert("port", configuration->port()); configurationMap.insert("authenticationEnabled", configuration->authenticationEnabled()); configurationMap.insert("sslEnabled", configuration->sslEnabled()); params.insert("configuration", configurationMap); m_client->sendCommand("Configuration.SetWebSocketServerConfiguration", params, this, "setWebSocketConfigReply"); } void NymeaConfiguration::setWebServerConfiguration(WebServerConfiguration *configuration) { QVariantMap params; QVariantMap configurationMap; configurationMap.insert("id", configuration->id()); configurationMap.insert("address", configuration->address()); configurationMap.insert("port", configuration->port()); configurationMap.insert("authenticationEnabled", configuration->authenticationEnabled()); configurationMap.insert("sslEnabled", configuration->sslEnabled()); configurationMap.insert("publicFolder", configuration->publicFolder()); params.insert("configuration", configurationMap); m_client->sendCommand("Configuration.SetWebServerConfiguration", params, this, "setWebConfigReply"); } void NymeaConfiguration::setMqttServerConfiguration(ServerConfiguration *configuration) { QVariantMap params; QVariantMap configurationMap; configurationMap.insert("id", configuration->id()); configurationMap.insert("address", configuration->address()); configurationMap.insert("port", configuration->port()); configurationMap.insert("authenticationEnabled", configuration->authenticationEnabled()); configurationMap.insert("sslEnabled", configuration->sslEnabled()); params.insert("configuration", configurationMap); m_client->sendCommand("Configuration.SetMqttServerConfiguration", params, this, "setMqttConfigReply"); } void NymeaConfiguration::deleteTcpServerConfiguration(const QString &id) { QVariantMap params; params.insert("id", id); m_client->sendCommand("Configuration.DeleteTcpServerConfiguration", params, this, "deleteTcpConfigReply"); } void NymeaConfiguration::deleteWebSocketServerConfiguration(const QString &id) { QVariantMap params; params.insert("id", id); m_client->sendCommand("Configuration.DeleteWebSocketServerConfiguration", params, this, "deleteWebSocketConfigReply"); } void NymeaConfiguration::deleteWebServerConfiguration(const QString &id) { QVariantMap params; params.insert("id", id); m_client->sendCommand("Configuration.DeleteWebServerConfiguration", params, this, "deleteWebConfigReply"); } void NymeaConfiguration::deleteMqttServerConfiguration(const QString &id) { QVariantMap params; params.insert("id", id); m_client->sendCommand("Configuration.DeleteMqttServerConfiguration", params, this, "deleteMqttConfigReply"); } void NymeaConfiguration::updateMqttPolicy(MqttPolicy *policy) { QVariantMap params; QVariantMap policyMap; policyMap.insert("clientId", policy->clientId()); policyMap.insert("username", policy->username()); policyMap.insert("password", policy->password()); policyMap.insert("allowedPublishTopicFilters", policy->allowedPublishTopicFilters()); policyMap.insert("allowedSubscribeTopicFilters", policy->allowedSubscribeTopicFilters()); params.insert("policy", policyMap); m_client->sendCommand("Configuration.SetMqttPolicy", params, this, "setMqttPolicyReply"); } void NymeaConfiguration::deleteMqttPolicy(const QString &clientId) { QVariantMap params; params.insert("clientId", clientId); m_client->sendCommand("Configuration.DeleteMqttPolicy", params, this, "deleteMqttPolicyReply"); } void NymeaConfiguration::getConfigurationsResponse(int commandId, const QVariantMap ¶ms) { Q_UNUSED(commandId) // qDebug() << "have config reply" << params; QVariantMap basicConfig = params.value("basicConfiguration").toMap(); m_debugServerEnabled = basicConfig.value("debugServerEnabled").toBool(); emit debugServerEnabledChanged(); m_serverName = basicConfig.value("serverName").toString(); emit serverNameChanged(); QVariantMap cloudConfig = params.value("cloud").toMap(); m_cloudEnabled = cloudConfig.value("enabled").toBool(); emit cloudEnabledChanged(); tcpServerConfigurations()->clear(); foreach (const QVariant &tcpServerVariant, params.value("tcpServerConfigurations").toList()) { // qDebug() << "tcp server config:" << tcpServerVariant; QVariantMap tcpConfigMap = tcpServerVariant.toMap(); ServerConfiguration *config = new ServerConfiguration(tcpConfigMap.value("id").toString(), QHostAddress(tcpConfigMap.value("address").toString()), tcpConfigMap.value("port").toInt(), tcpConfigMap.value("authenticationEnabled").toBool(), tcpConfigMap.value("sslEnabled").toBool()); m_tcpServerConfigurations->addConfiguration(config); } webSocketServerConfigurations()->clear(); foreach (const QVariant &websocketServerVariant, params.value("webSocketServerConfigurations").toList()) { QVariantMap websocketConfigMap = websocketServerVariant.toMap(); ServerConfiguration *config = new ServerConfiguration(websocketConfigMap.value("id").toString(), QHostAddress(websocketConfigMap.value("address").toString()), websocketConfigMap.value("port").toInt(), websocketConfigMap.value("authenticationEnabled").toBool(), websocketConfigMap.value("sslEnabled").toBool()); m_webSocketServerConfigurations->addConfiguration(config); } webServerConfigurations()->clear(); foreach (const QVariant &webServerVariant, params.value("webServerConfigurations").toList()) { QVariantMap webServerConfigMap = webServerVariant.toMap(); WebServerConfiguration* config = new WebServerConfiguration(webServerConfigMap.value("id").toString(), QHostAddress(webServerConfigMap.value("address").toString()), webServerConfigMap.value("port").toInt(), webServerConfigMap.value("authenticationEnabled").toBool(), webServerConfigMap.value("sslEnabled").toBool()); config->setPublicFolder(webServerConfigMap.value("publicFolder").toString()); m_webServerConfigurations->addConfiguration(config); } } void NymeaConfiguration::setServerNameResponse(int commandId, const QVariantMap ¶ms) { qDebug() << "Server name set:" << commandId << params; } void NymeaConfiguration::setTimezoneResponse(int commandId, const QVariantMap ¶ms) { qDebug() << "Set timezone response" << commandId << params; } void NymeaConfiguration::getCloudConfigurationResponse(const QVariantMap ¶ms) { qDebug() << "Cloud config reply" << params; } void NymeaConfiguration::setCloudEnabledResponse(int commandId, const QVariantMap ¶ms) { qDebug() << "Set cloud enabled:" << commandId << params; } void NymeaConfiguration::setDebugServerEnabledResponse(int commandId, const QVariantMap ¶ms) { qDebug() << "Debug server set:" << commandId << params; } void NymeaConfiguration::setTcpConfigReply(int commandId, const QVariantMap ¶ms) { qDebug() << "Set TCP server config reply" << commandId << params; } void NymeaConfiguration::deleteTcpConfigReply(int commandId, const QVariantMap ¶ms) { qDebug() << "Deƶete TCP server config reply" << commandId << params; } void NymeaConfiguration::setWebSocketConfigReply(int commandId, const QVariantMap ¶ms) { qDebug() << "set websocket config reply" << commandId << params; } void NymeaConfiguration::setWebConfigReply(int commandId, const QVariantMap ¶ms) { qDebug() << "set web server config reply" << commandId << params; } void NymeaConfiguration::deleteWebConfigReply(int commandId, const QVariantMap ¶ms) { qDebug() << "Delete web server config reply" << commandId << params; } void NymeaConfiguration::deleteWebSocketConfigReply(int commandId, const QVariantMap ¶ms) { qDebug() << "Delete web socket server config reply" << commandId << params; } void NymeaConfiguration::getMqttServerConfigsReply(int commandId, const QVariantMap ¶ms) { Q_UNUSED(commandId) m_mqttServerConfigurations->clear(); foreach (const QVariant &mqttServerVariant, params.value("mqttServerConfigurations").toList()) { QVariantMap mqttConfigMap = mqttServerVariant.toMap(); ServerConfiguration *config = new ServerConfiguration(mqttConfigMap.value("id").toString(), QHostAddress(mqttConfigMap.value("address").toString()), mqttConfigMap.value("port").toInt(), mqttConfigMap.value("authenticationEnabled").toBool(), mqttConfigMap.value("sslEnabled").toBool()); m_mqttServerConfigurations->addConfiguration(config); } } void NymeaConfiguration::setMqttConfigReply(int commandId, const QVariantMap ¶ms) { qDebug() << "Set mqtt config reply" << commandId << params; } void NymeaConfiguration::deleteMqttConfigReply(int commandId, const QVariantMap ¶ms) { qDebug() << "Delete Mqtt Broker config reply:" << commandId << params; } void NymeaConfiguration::getMqttPoliciesReply(int commandId, const QVariantMap ¶ms) { Q_UNUSED(commandId) // qDebug() << "Mqtt polices:" << params; m_mqttPolicies->clear(); foreach (const QVariant &policyVariant, params.value("mqttPolicies").toList()) { QVariantMap policyMap = policyVariant.toMap(); MqttPolicy *policy = new MqttPolicy( policyMap.value("clientId").toString(), policyMap.value("username").toString(), policyMap.value("password").toString(), policyMap.value("allowedPublishTopicFilters").toStringList(), policyMap.value("allowedSubscribeTopicFilters").toStringList()); m_mqttPolicies->addPolicy(policy); } } void NymeaConfiguration::setMqttPolicyReply(int commandId, const QVariantMap ¶ms) { qDebug() << "Set MQTT policy reply" << commandId << params; } void NymeaConfiguration::deleteMqttPolicyReply(int commandId, const QVariantMap ¶ms) { qDebug() << "Delete MQTT policy reply" << commandId << params; } void NymeaConfiguration::notificationReceived(const QVariantMap ¬ification) { QString notif = notification.value("notification").toString(); if (notif == "Configuration.BasicConfigurationChanged") { QVariantMap params = notification.value("params").toMap().value("basicConfiguration").toMap(); m_debugServerEnabled = params.value("debugServerEnabled").toBool(); emit debugServerEnabledChanged(); m_serverName = params.value("serverName").toString(); emit serverNameChanged(); qCDebug(dcNymeaConfiguration()) << "Basic configuration changed. Server name:" << m_serverName << "Debug server enabled:" << m_debugServerEnabled; return; } if (notif == "Configuration.CloudConfigurationChanged") { QVariantMap params = notification.value("params").toMap().value("cloudConfiguration").toMap(); qCDebug(dcNymeaConfiguration()) << "Cloud coniguration changed" << params; m_cloudEnabled = params.value("enabled").toBool(); emit cloudEnabledChanged(); return; } if (notif.endsWith("ServerConfigurationChanged")) { ServerConfigurations *configModel = nullptr; ServerConfiguration *serverConfig = nullptr; QVariantMap params; if (notif == "Configuration.TcpServerConfigurationChanged") { configModel = m_tcpServerConfigurations; params = notification.value("params").toMap().value("tcpServerConfiguration").toMap(); } if (notif == "Configuration.WebSocketServerConfigurationChanged") { configModel = m_webSocketServerConfigurations; params = notification.value("params").toMap().value("webSocketServerConfiguration").toMap(); } if (notif == "Configuration.WebServerConfigurationChanged") { configModel = m_webServerConfigurations; params = notification.value("params").toMap().value("webServerConfiguration").toMap(); } if (notif == "Configuration.MqttServerConfigurationChanged") { configModel = m_mqttServerConfigurations; params = notification.value("params").toMap().value("mqttServerConfiguration").toMap(); } if (!configModel) { return; } for (int i = 0; i < configModel->rowCount(); i++) { ServerConfiguration* config = configModel->get(i); if (config->id() == params.value("id").toString()) { serverConfig = config; } } if (!serverConfig) { if (notif == "Configuration.WebServerConfigurationChanged") { serverConfig = new WebServerConfiguration(params.value("id").toString()); } else { serverConfig = new ServerConfiguration(params.value("id").toString()); } configModel->addConfiguration(serverConfig); } serverConfig->setAddress(params.value("address").toString()); serverConfig->setPort(params.value("port").toInt()); serverConfig->setAuthenticationEnabled(params.value("authenticationEnabled").toBool()); serverConfig->setSslEnabled(params.value("sslEnabled").toBool()); if (notif == "Configuration.WebServerConfigurationChanged") { qobject_cast(serverConfig)->setPublicFolder(params.value("publicFolder").toString()); } return; } if (notif == "Configuration.TcpServerConfigurationRemoved") { m_tcpServerConfigurations->removeConfiguration(notification.value("params").toMap().value("id").toString()); return; } if (notif == "Configuration.WebSocketServerConfigurationRemoved") { m_webSocketServerConfigurations->removeConfiguration(notification.value("params").toMap().value("id").toString()); return; } if (notif == "Configuration.WebServerConfigurationRemoved") { m_webServerConfigurations->removeConfiguration(notification.value("params").toMap().value("id").toString()); return; } if (notif == "Configuration.MqttServerConfigurationRemoved") { m_mqttServerConfigurations->removeConfiguration(notification.value("params").toMap().value("id").toString()); return; } if (notif == "Configuration.MqttPolicyChanged") { MqttPolicy *policy = nullptr; QVariantMap policyMap = notification.value("params").toMap().value("policy").toMap(); for (int i = 0; i < m_mqttPolicies->rowCount(); i++) { if (m_mqttPolicies->get(i)->clientId() == policyMap.value("clientId").toString()) { policy = m_mqttPolicies->get(i); break; } } if (!policy) { policy = new MqttPolicy(policyMap.value("clientId").toString()); m_mqttPolicies->addPolicy(policy); } policy->setUsername(policyMap.value("username").toString()); policy->setPassword(policyMap.value("password").toString()); policy->setAllowedPublishTopicFilters(policyMap.value("allowedPublishTopicFilters").toStringList()); policy->setAllowedSubscribeTopicFilters(policyMap.value("allowedSubscribeTopicFilters").toStringList()); qCDebug(dcNymeaConfiguration()) << "MQTT policy changed" << policy->clientId() << policy->username() << policy->password(); return; } if (notif == "Configuration.MqttPolicyRemoved") { MqttPolicy* policy = m_mqttPolicies->getPolicy(notification.value("params").toMap().value("clientId").toString()); if (!policy) { qCWarning(dcNymeaConfiguration()) << "Reveived a policy removed notification for apolicy we don't know"; return; } qCDebug(dcNymeaConfiguration()) << "MQTT policy removed" << policy->clientId() << policy->username() << policy->password(); m_mqttPolicies->removePolicy(policy); return; } qCWarning(dcNymeaConfiguration) << "Unhandled Configuration notification" << qUtf8Printable(QJsonDocument::fromVariant(notification).toJson()); }