Make use of new notifications subscription mechanism

This commit is contained in:
Michael Zanetti 2019-10-15 11:42:31 +02:00
parent bc5c826583
commit 21992c4240
9 changed files with 105 additions and 60 deletions

View File

@ -4,18 +4,45 @@
#include "types/wirelessaccesspoint.h" #include "types/wirelessaccesspoint.h"
#include "types/wirelessaccesspoints.h" #include "types/wirelessaccesspoints.h"
#include "engine.h"
#include "jsonrpc/jsonrpcclient.h" #include "jsonrpc/jsonrpcclient.h"
#include <QMetaEnum> #include <QMetaEnum>
#include <QJsonDocument> #include <QJsonDocument>
NetworkManager::NetworkManager(JsonRpcClient *jsonClient, QObject *parent): NetworkManager::NetworkManager(QObject *parent):
JsonHandler(parent), JsonHandler(parent),
m_jsonClient(jsonClient),
m_wiredNetworkDevices(new WiredNetworkDevices(this)), m_wiredNetworkDevices(new WiredNetworkDevices(this)),
m_wirelessNetworkDevices(new WirelessNetworkDevices(this)) m_wirelessNetworkDevices(new WirelessNetworkDevices(this))
{ {
m_jsonClient->registerNotificationHandler(this, "notificationReceived"); }
NetworkManager::~NetworkManager()
{
if (m_engine) {
m_engine->jsonRpcClient()->unregisterNotificationHandler(this);
}
}
void NetworkManager::setEngine(Engine *engine)
{
if (m_engine && m_engine != engine) {
// clean up
m_engine->jsonRpcClient()->unregisterNotificationHandler(this);
}
m_engine = engine;
emit engineChanged();
m_engine->jsonRpcClient()->registerNotificationHandler(this, "notificationReceived");
init();
connect(m_engine->jsonRpcClient(), &JsonRpcClient::connectedChanged, this, &NetworkManager::init);
}
Engine *NetworkManager::engine() const
{
return m_engine;
} }
QString NetworkManager::nameSpace() const QString NetworkManager::nameSpace() const
@ -28,9 +55,13 @@ void NetworkManager::init()
m_wiredNetworkDevices->clear(); m_wiredNetworkDevices->clear();
m_wirelessNetworkDevices->clear(); m_wirelessNetworkDevices->clear();
m_jsonClient->sendCommand("NetworkManager.GetNetworkStatus", QVariantMap(), this, "getStatusReply"); if (!m_engine->jsonRpcClient()->connected()) {
m_jsonClient->sendCommand("NetworkManager.GetNetworkDevices", QVariantMap(), this, "getDevicesReply"); // Not ready yet...
// m_jsonClient->sendCommand("NetworkManager.GetWirelessAccessPoints", QVariantMap(), this, "getAccessPointsReply"); return;
}
m_engine->jsonRpcClient()->sendCommand("NetworkManager.GetNetworkStatus", QVariantMap(), this, "getStatusReply");
m_engine->jsonRpcClient()->sendCommand("NetworkManager.GetNetworkDevices", QVariantMap(), this, "getDevicesReply");
} }
NetworkManager::NetworkManagerState NetworkManager::state() const NetworkManager::NetworkManagerState NetworkManager::state() const
@ -62,21 +93,21 @@ void NetworkManager::enableNetworking(bool enable)
{ {
QVariantMap params; QVariantMap params;
params.insert("enable", enable); params.insert("enable", enable);
m_jsonClient->sendCommand("NetworkManager.EnableNetworking", params, this, "enableNetworkingReply"); m_engine->jsonRpcClient()->sendCommand("NetworkManager.EnableNetworking", params, this, "enableNetworkingReply");
} }
void NetworkManager::enableWirelessNetworking(bool enable) void NetworkManager::enableWirelessNetworking(bool enable)
{ {
QVariantMap params; QVariantMap params;
params.insert("enable", enable); params.insert("enable", enable);
m_jsonClient->sendCommand("NetworkManager.EnableWirelessNetworking", params, this, "enableNetworkingReply"); m_engine->jsonRpcClient()->sendCommand("NetworkManager.EnableWirelessNetworking", params, this, "enableNetworkingReply");
} }
void NetworkManager::refreshWifis(const QString &interface) void NetworkManager::refreshWifis(const QString &interface)
{ {
QVariantMap params; QVariantMap params;
params.insert("interface", interface); params.insert("interface", interface);
int requestId = m_jsonClient->sendCommand("NetworkManager.GetWirelessAccessPoints", params, this, "getAccessPointsReply"); int requestId = m_engine->jsonRpcClient()->sendCommand("NetworkManager.GetWirelessAccessPoints", params, this, "getAccessPointsReply");
m_apRequests.insert(requestId, interface); m_apRequests.insert(requestId, interface);
} }
@ -86,14 +117,14 @@ void NetworkManager::connectToWiFi(const QString &interface, const QString &ssid
params.insert("interface", interface); params.insert("interface", interface);
params.insert("ssid", ssid); params.insert("ssid", ssid);
params.insert("password", passphrase); params.insert("password", passphrase);
m_jsonClient->sendCommand("NetworkManager.ConnectWifiNetwork", params, this, "connectToWiFiReply"); m_engine->jsonRpcClient()->sendCommand("NetworkManager.ConnectWifiNetwork", params, this, "connectToWiFiReply");
} }
void NetworkManager::disconnectInterface(const QString &interface) void NetworkManager::disconnectInterface(const QString &interface)
{ {
QVariantMap params; QVariantMap params;
params.insert("interface", interface); params.insert("interface", interface);
m_jsonClient->sendCommand("NetworkManager.DisconnectInterface", params, this, "disconnectReply"); m_engine->jsonRpcClient()->sendCommand("NetworkManager.DisconnectInterface", params, this, "disconnectReply");
} }
void NetworkManager::getStatusReply(const QVariantMap &params) void NetworkManager::getStatusReply(const QVariantMap &params)

View File

@ -6,7 +6,7 @@
#include "jsonrpc/jsonhandler.h" #include "jsonrpc/jsonhandler.h"
class JsonRpcClient; class Engine;
class NetworkDevices; class NetworkDevices;
class WiredNetworkDevices; class WiredNetworkDevices;
class WirelessNetworkDevices; class WirelessNetworkDevices;
@ -14,6 +14,8 @@ class WirelessNetworkDevices;
class NetworkManager : public JsonHandler class NetworkManager : public JsonHandler
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(Engine *engine READ engine WRITE setEngine NOTIFY engineChanged)
Q_PROPERTY(NetworkManagerState state READ state NOTIFY stateChanged) Q_PROPERTY(NetworkManagerState state READ state NOTIFY stateChanged)
Q_PROPERTY(bool networkingEnabled READ networkingEnabled NOTIFY networkingEnabledChanged) Q_PROPERTY(bool networkingEnabled READ networkingEnabled NOTIFY networkingEnabledChanged)
Q_PROPERTY(bool wirelessNetworkingEnabled READ wirelessNetworkingEnabled NOTIFY wirelessNetworkingEnabledChanged) Q_PROPERTY(bool wirelessNetworkingEnabled READ wirelessNetworkingEnabled NOTIFY wirelessNetworkingEnabledChanged)
@ -34,12 +36,14 @@ public:
}; };
Q_ENUM(NetworkManagerState) Q_ENUM(NetworkManagerState)
explicit NetworkManager(JsonRpcClient *jsonClient, QObject *parent = nullptr); explicit NetworkManager(QObject *parent = nullptr);
~NetworkManager();
void setEngine(Engine *engine);
Engine *engine() const;
QString nameSpace() const override; QString nameSpace() const override;
void init();
NetworkManagerState state() const; NetworkManagerState state() const;
bool networkingEnabled() const; bool networkingEnabled() const;
bool wirelessNetworkingEnabled() const; bool wirelessNetworkingEnabled() const;
@ -56,6 +60,8 @@ public:
Q_INVOKABLE void disconnectInterface(const QString &interface); Q_INVOKABLE void disconnectInterface(const QString &interface);
private slots: private slots:
void init();
void getStatusReply(const QVariantMap &params); void getStatusReply(const QVariantMap &params);
void getDevicesReply(const QVariantMap &params); void getDevicesReply(const QVariantMap &params);
void getAccessPointsReply(const QVariantMap &params); void getAccessPointsReply(const QVariantMap &params);
@ -66,12 +72,13 @@ private slots:
void notificationReceived(const QVariantMap &params); void notificationReceived(const QVariantMap &params);
signals: signals:
void engineChanged();
void stateChanged(); void stateChanged();
void networkingEnabledChanged(); void networkingEnabledChanged();
void wirelessNetworkingEnabledChanged(); void wirelessNetworkingEnabledChanged();
private: private:
JsonRpcClient *m_jsonClient = nullptr; Engine *m_engine = nullptr;
NetworkManagerState m_state = NetworkManagerStateUnknown; NetworkManagerState m_state = NetworkManagerStateUnknown;
bool m_networkingEnabled = false; bool m_networkingEnabled = false;

View File

@ -42,8 +42,7 @@ Engine::Engine(QObject *parent) :
m_logManager(new LogManager(m_jsonRpcClient, this)), m_logManager(new LogManager(m_jsonRpcClient, this)),
m_tagsManager(new TagsManager(m_jsonRpcClient, this)), m_tagsManager(new TagsManager(m_jsonRpcClient, this)),
m_nymeaConfiguration(new NymeaConfiguration(m_jsonRpcClient, this)), m_nymeaConfiguration(new NymeaConfiguration(m_jsonRpcClient, this)),
m_systemController(new SystemController(m_jsonRpcClient, this)), m_systemController(new SystemController(m_jsonRpcClient, this))
m_networkManager(new NetworkManager(m_jsonRpcClient, this))
{ {
m_connection->registerTransport(new TcpSocketTransportFactory()); m_connection->registerTransport(new TcpSocketTransportFactory());
m_connection->registerTransport(new WebsocketTransportFactory()); m_connection->registerTransport(new WebsocketTransportFactory());
@ -106,11 +105,6 @@ SystemController *Engine::systemController() const
return m_systemController; return m_systemController;
} }
NetworkManager *Engine::networkManager() const
{
return m_networkManager;
}
void Engine::deployCertificate() void Engine::deployCertificate()
{ {
if (!m_jsonRpcClient->connected()) { if (!m_jsonRpcClient->connected()) {
@ -144,7 +138,6 @@ void Engine::onConnectedChanged()
m_ruleManager->init(); m_ruleManager->init();
m_nymeaConfiguration->init(); m_nymeaConfiguration->init();
m_systemController->init(); m_systemController->init();
m_networkManager->init();
} }
} }
} }

View File

@ -45,7 +45,6 @@ class Engine : public QObject
Q_PROPERTY(JsonRpcClient* jsonRpcClient READ jsonRpcClient CONSTANT) Q_PROPERTY(JsonRpcClient* jsonRpcClient READ jsonRpcClient CONSTANT)
Q_PROPERTY(NymeaConfiguration* nymeaConfiguration READ nymeaConfiguration CONSTANT) Q_PROPERTY(NymeaConfiguration* nymeaConfiguration READ nymeaConfiguration CONSTANT)
Q_PROPERTY(SystemController* systemController READ systemController CONSTANT) Q_PROPERTY(SystemController* systemController READ systemController CONSTANT)
Q_PROPERTY(NetworkManager* networkManager READ networkManager CONSTANT)
public: public:
explicit Engine(QObject *parent = nullptr); explicit Engine(QObject *parent = nullptr);
@ -61,7 +60,6 @@ public:
LogManager *logManager() const; LogManager *logManager() const;
NymeaConfiguration *nymeaConfiguration() const; NymeaConfiguration *nymeaConfiguration() const;
SystemController *systemController() const; SystemController *systemController() const;
NetworkManager *networkManager() const;
Q_INVOKABLE void deployCertificate(); Q_INVOKABLE void deployCertificate();
@ -74,7 +72,6 @@ private:
TagsManager *m_tagsManager; TagsManager *m_tagsManager;
NymeaConfiguration *m_nymeaConfiguration; NymeaConfiguration *m_nymeaConfiguration;
SystemController *m_systemController; SystemController *m_systemController;
NetworkManager *m_networkManager;
private slots: private slots:
void onConnectedChanged(); void onConnectedChanged();

View File

@ -50,11 +50,20 @@ QString JsonRpcClient::nameSpace() const
void JsonRpcClient::registerNotificationHandler(JsonHandler *handler, const QString &method) void JsonRpcClient::registerNotificationHandler(JsonHandler *handler, const QString &method)
{ {
if (m_notificationHandlers.contains(handler->nameSpace())) { if (m_notificationHandlerMethods.contains(handler)) {
qWarning() << "Already have a notification handler for" << handler->nameSpace(); qWarning() << "Notification handler" << handler << " already registered";
return; return;
} }
m_notificationHandlers.insert(handler->nameSpace(), qMakePair<JsonHandler*, QString>(handler, method)); m_notificationHandlers.insert(handler->nameSpace(), handler);
m_notificationHandlerMethods.insert(handler, method);
setNotificationsEnabled();
}
void JsonRpcClient::unregisterNotificationHandler(JsonHandler *handler)
{
m_notificationHandlers.remove(handler->nameSpace(), handler);
m_notificationHandlerMethods.remove(handler);
setNotificationsEnabled();
} }
int JsonRpcClient::sendCommand(const QString &method, const QVariantMap &params, QObject *caller, const QString &callbackMethod) int JsonRpcClient::sendCommand(const QString &method, const QVariantMap &params, QObject *caller, const QString &callbackMethod)
@ -70,15 +79,6 @@ int JsonRpcClient::sendCommand(const QString &method, QObject *caller, const QSt
return sendCommand(method, QVariantMap(), caller, callbackMethod); return sendCommand(method, QVariantMap(), caller, callbackMethod);
} }
void JsonRpcClient::setNotificationsEnabled(bool enabled)
{
QVariantMap params;
params.insert("enabled", enabled);
JsonRpcReply *reply = createReply("JSONRPC.SetNotificationStatus", params, this, "setNotificationsEnabledResponse");
m_replies.insert(reply->commandId(), reply);
sendRequest(reply->requestMap());
}
void JsonRpcClient::getCloudConnectionStatus() void JsonRpcClient::getCloudConnectionStatus()
{ {
JsonRpcReply *reply = createReply("JSONRPC.IsCloudConnected", QVariantMap(), this, "isCloudConnectedReply"); JsonRpcReply *reply = createReply("JSONRPC.IsCloudConnected", QVariantMap(), this, "isCloudConnectedReply");
@ -90,9 +90,10 @@ void JsonRpcClient::setNotificationsEnabledResponse(const QVariantMap &params)
{ {
qDebug() << "Notifications enabled:" << params; qDebug() << "Notifications enabled:" << params;
m_connected = true; if (!m_connected) {
emit connectedChanged(true); m_connected = true;
emit connectedChanged(true);
}
} }
void JsonRpcClient::notificationReceived(const QVariantMap &data) void JsonRpcClient::notificationReceived(const QVariantMap &data)
@ -114,7 +115,7 @@ void JsonRpcClient::notificationReceived(const QVariantMap &data)
settings.endGroup(); settings.endGroup();
emit authenticationRequiredChanged(); emit authenticationRequiredChanged();
setNotificationsEnabled(true); setNotificationsEnabled();
} else { } else {
emit pushButtonAuthFailed(); emit pushButtonAuthFailed();
} }
@ -261,7 +262,7 @@ void JsonRpcClient::processAuthenticate(const QVariantMap &data)
settings.endGroup(); settings.endGroup();
emit authenticationRequiredChanged(); emit authenticationRequiredChanged();
setNotificationsEnabled(true); setNotificationsEnabled();
} else { } else {
qWarning() << "Authentication failed" << data; qWarning() << "Authentication failed" << data;
emit authenticationFailed(); emit authenticationFailed();
@ -302,6 +303,25 @@ JsonRpcReply *JsonRpcClient::createReply(const QString &method, const QVariantMa
return new JsonRpcReply(m_id, callParts.first(), callParts.last(), params, caller, callback); return new JsonRpcReply(m_id, callParts.first(), callParts.last(), params, caller, callback);
} }
void JsonRpcClient::setNotificationsEnabled()
{
QStringList namespaces;
foreach (const QString &nameSpace, m_notificationHandlers.keys()) {
namespaces.append(nameSpace);
}
QVariantMap params;
if (ensureServerVersion("3.1")) {
params.insert("namespaces", namespaces);
} else {
params.insert("enabled", namespaces.count() > 0);
}
JsonRpcReply *reply = createReply("JSONRPC.SetNotificationStatus", params, this, "setNotificationsEnabledResponse");
m_replies.insert(reply->commandId(), reply);
sendRequest(reply->requestMap());
}
void JsonRpcClient::sendRequest(const QVariantMap &request) void JsonRpcClient::sendRequest(const QVariantMap &request)
{ {
QVariantMap newRequest = request; QVariantMap newRequest = request;
@ -358,15 +378,9 @@ void JsonRpcClient::dataReceived(const QByteArray &data)
// qDebug() << "Incoming notification:" << jsonDoc.toJson(); // qDebug() << "Incoming notification:" << jsonDoc.toJson();
QStringList notification = dataMap.value("notification").toString().split("."); QStringList notification = dataMap.value("notification").toString().split(".");
QString nameSpace = notification.first(); QString nameSpace = notification.first();
JsonHandler *handler = m_notificationHandlers.value(nameSpace).first; foreach (JsonHandler *handler, m_notificationHandlers.values(nameSpace)) {
QMetaObject::invokeMethod(handler, m_notificationHandlerMethods.value(handler).toLatin1().data(), Q_ARG(QVariantMap, dataMap));
if (!handler) {
// qWarning() << "JsonRpc: handler not implemented:" << nameSpace;
return;
} }
// qDebug() << "Incoming notification:" << jsonDoc.toJson();
QMetaObject::invokeMethod(handler, m_notificationHandlers.value(nameSpace).second.toLatin1().data(), Q_ARG(QVariantMap, dataMap));
return; return;
} }
@ -454,7 +468,7 @@ void JsonRpcClient::helloReply(const QVariantMap &params)
} }
} }
setNotificationsEnabled(true); setNotificationsEnabled();
getCloudConnectionStatus(); getCloudConnectionStatus();
} }

View File

@ -59,6 +59,7 @@ public:
QString nameSpace() const override; QString nameSpace() const override;
void registerNotificationHandler(JsonHandler *handler, const QString &method); void registerNotificationHandler(JsonHandler *handler, const QString &method);
void unregisterNotificationHandler(JsonHandler *handler);
int sendCommand(const QString &method, const QVariantMap &params, QObject *caller = nullptr, const QString &callbackMethod = QString()); int sendCommand(const QString &method, const QVariantMap &params, QObject *caller = nullptr, const QString &callbackMethod = QString());
int sendCommand(const QString &method, QObject *caller = nullptr, const QString &callbackMethod = QString()); int sendCommand(const QString &method, QObject *caller = nullptr, const QString &callbackMethod = QString());
@ -107,8 +108,9 @@ private slots:
private: private:
int m_id; int m_id;
// < namespace, <Handler, method> > // < namespace, method> >
QHash<QString, QPair<JsonHandler*, QString> > m_notificationHandlers; QHash<JsonHandler*, QString> m_notificationHandlerMethods;
QMultiHash<QString, JsonHandler*> m_notificationHandlers;
QHash<int, JsonRpcReply *> m_replies; QHash<int, JsonRpcReply *> m_replies;
NymeaConnection *m_connection = nullptr; NymeaConnection *m_connection = nullptr;
@ -126,7 +128,7 @@ private:
QByteArray m_token; QByteArray m_token;
QByteArray m_receiveBuffer; QByteArray m_receiveBuffer;
void setNotificationsEnabled(bool enabled); void setNotificationsEnabled();
void getCloudConnectionStatus(); void getCloudConnectionStatus();
// json handler // json handler

View File

@ -221,7 +221,7 @@ void registerQmlTypes() {
qmlRegisterUncreatableType<Repository>(uri, 1, 0, "Repository", "Get it from Repositories"); qmlRegisterUncreatableType<Repository>(uri, 1, 0, "Repository", "Get it from Repositories");
qmlRegisterType<PackagesFilterModel>(uri, 1, 0, "PackagesFilterModel"); qmlRegisterType<PackagesFilterModel>(uri, 1, 0, "PackagesFilterModel");
qmlRegisterUncreatableType<NetworkManager>(uri, 1, 0, "NetworkManager", "Get it from Engine"); qmlRegisterType<NetworkManager>(uri, 1, 0, "NetworkManager");
qmlRegisterUncreatableType<NetworkDevices>(uri, 1, 0, "NetworkDevices", "Get it from NetworkManager"); qmlRegisterUncreatableType<NetworkDevices>(uri, 1, 0, "NetworkDevices", "Get it from NetworkManager");
qmlRegisterUncreatableType<WiredNetworkDevices>(uri, 1, 0, "WiredNetworkDevices", "Get it from NetworkManager"); qmlRegisterUncreatableType<WiredNetworkDevices>(uri, 1, 0, "WiredNetworkDevices", "Get it from NetworkManager");
qmlRegisterUncreatableType<WirelessNetworkDevices>(uri, 1, 0, "WirelessNetworkDevices", "Get it from NetworkManager"); qmlRegisterUncreatableType<WirelessNetworkDevices>(uri, 1, 0, "WirelessNetworkDevices", "Get it from NetworkManager");

View File

@ -145,7 +145,6 @@ Item {
labelsFont.pixelSize: app.smallFont labelsFont.pixelSize: app.smallFont
labelsColor: app.foregroundColor labelsColor: app.foregroundColor
property int timeDiff: (xAxis.max.getTime() - xAxis.min.getTime()) / 1000 property int timeDiff: (xAxis.max.getTime() - xAxis.min.getTime()) / 1000
onTimeDiffChanged: print("timeDiff is:", timeDiff)
function getTimeSpanString() { function getTimeSpanString() {
var td = timeDiff var td = timeDiff
@ -403,7 +402,6 @@ Item {
interval: 1000 interval: 1000
repeat: true repeat: true
onTriggered: { onTriggered: {
print("autoscrolling chart")
scrollMouseArea.scrollRightLimited(10) scrollMouseArea.scrollRightLimited(10)
} }
} }

View File

@ -14,7 +14,10 @@ Page {
} }
} }
readonly property NetworkManager networkManager: engine.networkManager NetworkManager {
id: networkManager
engine: _engine
}
function networkStateToString(networkState) { function networkStateToString(networkState) {
switch (networkState) { switch (networkState) {