From 1fbfc103a8fba891ee20735e5355045e46ce184c Mon Sep 17 00:00:00 2001 From: Raquel Medina Date: Fri, 26 Apr 2019 03:06:33 +0300 Subject: network: refactor network class Refactor network class to prepare for wired connections. - extract Wifi model and flags into new WifiAdapter class - fix wifi networks disappearing for prolonged periods after disconnecting from a wifi service (this issue is intermittent, depends on the wifi signal variability) Bug-AGL: SPEC-2293 Change-Id: I75f3076d094daa9c8d04e05fe2944df98f5cfb81 Signed-off-by: Raquel Medina --- network/CMakeLists.txt | 4 +- network/network.cpp | 174 ++++++++++++++++--------------------------- network/network.h | 31 +++----- network/networkadapter.cpp | 110 +++++++++++++++++++++++++++ network/networkadapter.h | 79 ++++++++++++++++++++ network/wifinetworkmodel.cpp | 6 +- 6 files changed, 267 insertions(+), 137 deletions(-) create mode 100644 network/networkadapter.cpp create mode 100644 network/networkadapter.h diff --git a/network/CMakeLists.txt b/network/CMakeLists.txt index 0a53327..5c15f46 100644 --- a/network/CMakeLists.txt +++ b/network/CMakeLists.txt @@ -1,2 +1,2 @@ -add_headers(network.h networkmessage.h wifinetworkmodel.h) -add_sources(network.cpp networkmessage.cpp wifinetworkmodel.cpp) +add_headers(network.h networkmessage.h networkadapter.h wifinetworkmodel.h) +add_sources(network.cpp networkmessage.cpp networkadapter.cpp wifinetworkmodel.cpp) diff --git a/network/network.cpp b/network/network.cpp index 496638f..e3a4545 100644 --- a/network/network.cpp +++ b/network/network.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#include -#include #include #include @@ -25,36 +23,25 @@ #include "network.h" #include "networkmessage.h" #include "responsemessage.h" -#include "wifinetworkmodel.h" +#include "networkadapter.h" Network::Network (QUrl &url, QQmlContext *context, QObject * parent) : QObject(parent), - m_mloop(nullptr), - m_wifi(nullptr), - m_wifiConnected(false), - m_wifiEnabled(false), - m_wifiStrength(0) + m_mloop(nullptr) { m_mloop = new MessageEngine(url); - m_wifi = new WifiNetworkModel(); - - QSortFilterProxyModel *m_model = new QSortFilterProxyModel(); - m_model->setSourceModel(m_wifi); - m_model->setSortRole(WifiNetworkModel::WifiNetworkRoles::SsidRole); - m_model->setSortCaseSensitivity(Qt::CaseInsensitive); - m_model->sort(0); - context->setContextProperty("WifiNetworkModel", m_model); + m_adapters.append(new WifiAdapter(this, context, parent)); QObject::connect(m_mloop, &MessageEngine::connected, this, &Network::onConnected); QObject::connect(m_mloop, &MessageEngine::disconnected, this, &Network::onDisconnected); QObject::connect(m_mloop, &MessageEngine::messageReceived, this, &Network::onMessageReceived); - QObject::connect(m_wifi, &WifiNetworkModel::strengthChanged, this, &Network::updateWifiStrength); } Network::~Network() { delete m_mloop; - delete m_wifi; + while (!m_adapters.isEmpty()) + m_adapters.takeLast(); } void Network::connect(QString service) @@ -93,6 +80,14 @@ void Network::remove(QString service) delete nmsg; } +void Network::power(bool on, QString type) +{ + if (on) + enableTechnology(type); + else + disableTechnology(type); +} + void Network::input(int id, QString passphrase) { NetworkMessage *nmsg = new NetworkMessage(); @@ -107,91 +102,52 @@ void Network::input(int id, QString passphrase) delete nmsg; } -void Network::power(bool on) -{ - if (on) - enableTechnology("wifi"); - else - disableTechnology("wifi"); -} - -void Network::enableTechnology(QString type) +void Network::getServices() { NetworkMessage *nmsg = new NetworkMessage(); QJsonObject parameter; - parameter.insert("technology", type); - nmsg->createRequest("enable_technology", parameter); + nmsg->createRequest("services", parameter); m_mloop->sendMessage(nmsg); - delete nmsg; } -void Network::disableTechnology(QString type) +AdapterIf* Network::findAdapter(QString type) { - NetworkMessage *nmsg = new NetworkMessage(); - QJsonObject parameter; - - parameter.insert("technology", type); - nmsg->createRequest("disable_technology", parameter); - m_mloop->sendMessage(nmsg); - - delete nmsg; + QList::iterator iter; + for (iter = m_adapters.begin(); iter != m_adapters.end(); ++iter) + if ((*iter)->getType() == type) + return (*iter); } -void Network::scanServices(QString type) +void Network::updateServiceProperties(QJsonObject data) { - NetworkMessage *nmsg = new NetworkMessage(); - QJsonObject parameter; - - parameter.insert("technology", type); - nmsg->createRequest("scan_services", parameter); - m_mloop->sendMessage(nmsg); + QString service = data.value("service").toString(); + QJsonObject properties = data.value("properties").toObject(); + QList::iterator iter; + for (iter = m_adapters.begin(); iter != m_adapters.end(); ++iter) + (*iter)->updateProperties(service, properties); - delete nmsg; } bool Network::addService(QJsonObject service) { - // Ignore services that are already added - QString id = service.value("service").toString(); - if (m_wifi->getNetwork(id)) - return false; - - QJsonObject properties = service.value("properties").toObject(); - - // Ignore hidden SSIDs - QString ssid = properties.value("name").toString(); - if (ssid == "") - return false; - - // Ignore technologies other than WiFi - QString type = properties.value("type").toString(); - if (type != "wifi") - return false; - - // Initially support only IPv4 and the first security method found - QString address = properties.value("ipv4").toObject().value("address").toString(); - QString security = properties.value("security").toArray().at(0).toString(); - QString state = properties.value("state").toString(); - int strength = properties.value("strength").toInt(); - - WifiNetwork *network = new WifiNetwork(address, security, id, ssid, state, strength); - m_wifi->addNetwork(network); - - if ((state == "ready") || (state == "online")) - updateWifiStrength(strength); + QString id = service.value("service").toString(); + QJsonObject properties = service.value("properties").toObject(); + QList::iterator iter; + for (iter = m_adapters.begin(); iter != m_adapters.end(); ++iter) + if ((*iter)->addService(id, properties)) + return true; - return true; + return false; } void Network::removeService(QJsonObject service) { QString id = service.value("service").toString(); - WifiNetwork *network = m_wifi->getNetwork(id); - - if (network) - m_wifi->removeNetwork(network); + QList::iterator iter; + for (iter = m_adapters.begin(); iter != m_adapters.end(); ++iter) + (*iter)->removeService(id); } void Network::addServices(QJsonArray services) @@ -200,35 +156,40 @@ void Network::addServices(QJsonArray services) addService(service.toObject()); } -void Network::getServices() +void Network::scanServices(QString type) { NetworkMessage *nmsg = new NetworkMessage(); QJsonObject parameter; - nmsg->createRequest("services", parameter); + parameter.insert("technology", type); + nmsg->createRequest("scan_services", parameter); m_mloop->sendMessage(nmsg); + delete nmsg; } -void Network::updateWifiStatus(QJsonObject properties) +void Network::disableTechnology(QString type) { - if (properties.contains("connected")) { - m_wifiConnected = properties.value("connected").toBool(); - emit wifiConnectedChanged(m_wifiConnected); - } + NetworkMessage *nmsg = new NetworkMessage(); + QJsonObject parameter; - if (properties.contains("powered")) { - m_wifiEnabled = properties.value("powered").toBool(); - emit wifiEnabledChanged(m_wifiEnabled); - if (m_wifiEnabled) - getServices(); - } + parameter.insert("technology", type); + nmsg->createRequest("disable_technology", parameter); + m_mloop->sendMessage(nmsg); + + delete nmsg; } -void Network::updateWifiStrength(int strength) +void Network::enableTechnology(QString type) { - m_wifiStrength = strength; - emit wifiStrengthChanged(m_wifiStrength); + NetworkMessage *nmsg = new NetworkMessage(); + QJsonObject parameter; + + parameter.insert("technology", type); + nmsg->createRequest("enable_technology", parameter); + m_mloop->sendMessage(nmsg); + + delete nmsg; } void Network::parseTechnologies(QJsonArray technologies) @@ -237,11 +198,10 @@ void Network::parseTechnologies(QJsonArray technologies) QJsonObject technology = value.toObject(); QJsonObject properties = technology.value("properties").toObject(); QString type = properties.value("type").toString(); + if (type == "wifi") { - updateWifiStatus(properties); - if (m_wifiEnabled) - getServices(); - break; + WifiAdapter* wifi_a = static_cast(findAdapter(type)); + wifi_a->updateWifiStatus(properties); } } } @@ -256,13 +216,6 @@ void Network::getTechnologies() delete nmsg; } -void Network::updateServiceProperties(QJsonObject data) -{ - QString service = data.value("service").toString(); - QJsonObject properties = data.value("properties").toObject(); - m_wifi->updateProperties(service, properties); -} - void Network::processEvent(NetworkMessage *nmsg) { if (nmsg->eventName() == "agent") { @@ -284,7 +237,7 @@ void Network::processEvent(NetworkMessage *nmsg) if (action == "changed") { addService(service); } else if (action == "removed") { - removeService(service); + removeService(service); } } } else if (nmsg->eventName() == "service_properties") { @@ -293,7 +246,8 @@ void Network::processEvent(NetworkMessage *nmsg) QJsonObject technology = nmsg->eventData(); if (technology.value("technology").toString() == "wifi") { QJsonObject properties = technology.value("properties").toObject(); - updateWifiStatus(properties); + WifiAdapter* wifi_a = static_cast(findAdapter("wifi")); + wifi_a->updateWifiStatus(properties); } } } @@ -353,5 +307,5 @@ void Network::onDisconnected() delete nmsg; } - m_wifi->removeAllNetworks(); + getTechnologies(); } diff --git a/network/network.h b/network/network.h index 0a158ec..21720bc 100644 --- a/network/network.h +++ b/network/network.h @@ -1,4 +1,4 @@ -/* + /* * Copyright (C) 2018 Konsulko Group * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,7 +26,7 @@ #include "messageengine.h" #include "networkmessage.h" #include "responsemessage.h" -#include "wifinetworkmodel.h" +#include "networkadapter.h" class Network : public QObject { @@ -39,40 +39,28 @@ class Network : public QObject Q_INVOKABLE void connect(QString service); Q_INVOKABLE void disconnect(QString service); Q_INVOKABLE void remove(QString service); - Q_INVOKABLE void power(bool on); + Q_INVOKABLE void power(bool on, QString type = "wifi"); Q_INVOKABLE void input(int id, QString passphrase); - Q_PROPERTY(bool wifiConnected READ wifiConnected NOTIFY wifiConnectedChanged) - Q_PROPERTY(bool wifiEnabled READ wifiEnabled NOTIFY wifiEnabledChanged) - Q_PROPERTY(int wifiStrength READ wifiStrength NOTIFY wifiStrengthChanged) - - bool wifiConnected() const { return m_wifiConnected; } - bool wifiEnabled() const { return m_wifiEnabled; } - int wifiStrength() const { return m_wifiStrength; } + void getServices(); + AdapterIf* findAdapter(QString type); signals: void inputRequest(int id); void invalidPassphrase(QString service); void searchResults(QString name); - void statusChanged(bool connected); - void wifiConnectedChanged(bool connected); - void wifiEnabledChanged(bool enabled); - void wifiStrengthChanged(int strength); private: MessageEngine *m_mloop; QQmlContext *m_context; - WifiNetworkModel *m_wifi; - bool m_wifiConnected; - bool m_wifiEnabled; - int m_wifiStrength; + QList m_adapters; - void updateWifiStatus(QJsonObject properties); void updateServiceProperties(QJsonObject data); bool addService(QJsonObject service); void removeService(QJsonObject remove); + void addServices(QJsonArray services); - void getServices(); + void scanServices(QString type); void disableTechnology(QString type); void enableTechnology(QString type); @@ -82,10 +70,9 @@ class Network : public QObject void processReply(ResponseMessage *rmsg); // slots + void onMessageReceived(MessageType, Message*); void onConnected(); void onDisconnected(); - void onMessageReceived(MessageType, Message*); - void updateWifiStrength(int); const QStringList events { "agent", diff --git a/network/networkadapter.cpp b/network/networkadapter.cpp new file mode 100644 index 0000000..2ba3cfc --- /dev/null +++ b/network/networkadapter.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2019 Konsulko Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "network.h" +#include "networkadapter.h" +#include "wifinetworkmodel.h" + +WifiAdapter::WifiAdapter(Network *network, QQmlContext *context, QObject *parent) : + QObject(parent), + AdapterIf(), + m_wifiConnected(false), + m_wifiEnabled(false), + m_wifiStrength(0), + m_model(nullptr), + nw(network) +{ + m_model = new WifiNetworkModel(); + QSortFilterProxyModel *model = new QSortFilterProxyModel(); + model->setSourceModel(m_model); + model->setSortRole(WifiNetworkModel::WifiNetworkRoles::SsidRole); + model->setSortCaseSensitivity(Qt::CaseInsensitive); + model->sort(0); + + context->setContextProperty("WifiNetworkModel", m_model); + QObject::connect(m_model, &WifiNetworkModel::strengthChanged, this, &WifiAdapter::updateWifiStrength); + context->setContextProperty("WifiAdapter", this); +} + +WifiAdapter::~WifiAdapter() +{ + delete m_model; +} + +void WifiAdapter::updateWifiStatus(QJsonObject properties) +{ + if (properties.contains("connected")) { + m_wifiConnected = properties.value("connected").toBool(); + emit wifiConnectedChanged(m_wifiConnected); + } + + if (properties.contains("powered")) { + m_wifiEnabled = properties.value("powered").toBool(); + emit wifiEnabledChanged(m_wifiEnabled); + if (m_wifiEnabled) + nw->getServices(); + } +} + +void WifiAdapter::updateWifiStrength(int strength) +{ + m_wifiStrength = strength; + emit wifiStrengthChanged(m_wifiStrength); +} + +void WifiAdapter::updateProperties(QString id, QJsonObject properties) +{ + if (m_model->getNetwork(id)) + m_model->updateProperties(id, properties); +} + +bool WifiAdapter::addService(QString id, QJsonObject properties) +{ + QString ssid = properties.value("name").toString(); + QString state = properties.value("state").toString(); + QString type = properties.value("type").toString(); + int strength = properties.value("strength").toInt(); + // Initially support only IPv4 and the first security method found + QString address = properties.value("ipv4").toObject().value("address").toString(); + QString security = properties.value("security").toArray().at(0).toString(); + + // Ignore hidden SSIDs or services already added + if (m_model->getNetwork(id) || (ssid == "")) + return false; + + // only process wifi services + if (type != getType()) + return false; + + WifiNetwork *network = new WifiNetwork(address, security, id, ssid, state, strength); + m_model->addNetwork(network); + + if ((state == "ready") || (state == "online")) + updateWifiStrength(strength); + + return true; +} + +void WifiAdapter::removeService(QString id) +{ + m_model->removeNetwork(m_model->getNetwork(id)); + +} + diff --git a/network/networkadapter.h b/network/networkadapter.h new file mode 100644 index 0000000..4aac701 --- /dev/null +++ b/network/networkadapter.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2019 Konsulko Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ADAPTER_H +#define ADAPTER_H + +#include +#include +#include +#include + +class Network; +class WifiNetworkModel; + +class AdapterIf +{ + public: + virtual ~AdapterIf() {}; + + virtual bool addService(QString id, QJsonObject properties) = 0; + virtual void removeService(QString id) = 0; + virtual void updateProperties(QString service, QJsonObject properties) = 0; + virtual QString getType() = 0; +}; + +Q_DECLARE_INTERFACE(AdapterIf, "AdapterIf") + +class WifiAdapter : public QObject, public AdapterIf +{ + Q_OBJECT + Q_INTERFACES(AdapterIf) + Q_PROPERTY(bool wifiConnected READ wifiConnected NOTIFY wifiConnectedChanged) + Q_PROPERTY(bool wifiEnabled READ wifiEnabled NOTIFY wifiEnabledChanged) + Q_PROPERTY(int wifiStrength READ wifiStrength NOTIFY wifiStrengthChanged) + + public: + explicit WifiAdapter(Network *network, QQmlContext *context, QObject *parent); + virtual ~WifiAdapter(); + + bool wifiConnected() const { return m_wifiConnected; } + bool wifiEnabled() const { return m_wifiEnabled; } + int wifiStrength() const { return m_wifiStrength; } + void updateWifiStatus(QJsonObject properties); + + bool addService(QString id, QJsonObject properties) override; + void removeService(QString id) override; + void updateProperties(QString service, QJsonObject properties) override; + QString getType() override { return "wifi"; } + + //slots + void updateWifiStrength(int); + + signals: + void wifiConnectedChanged(bool connected); + void wifiEnabledChanged(bool enabled); + void wifiStrengthChanged(int strength); + + private: + bool m_wifiConnected; + bool m_wifiEnabled; + int m_wifiStrength; + WifiNetworkModel *m_model; + Network *nw; +}; + +#endif // ADAPTER_H diff --git a/network/wifinetworkmodel.cpp b/network/wifinetworkmodel.cpp index 3837278..2691d6e 100644 --- a/network/wifinetworkmodel.cpp +++ b/network/wifinetworkmodel.cpp @@ -164,9 +164,9 @@ void WifiNetworkModel::updateProperties(QString service, QJsonObject properties) if (properties.contains("strength")) { network->setStrength(properties.value("strength").toInt()); emit dataChanged(indexOf(network), indexOf(network)); - if ((network->state() == "ready") || - (network->state() == "online")) - emit strengthChanged(network->strength()); + if ((network->state() == "ready") || + (network->state() == "online")) + emit strengthChanged(network->strength()); } } } -- cgit 1.2.3-korg