summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Porter <mporter@konsulko.com>2018-07-13 15:28:17 -0400
committerMatt Porter <mporter@konsulko.com>2018-07-25 19:20:05 -0400
commitcd445ba31ca2f4ca4cec0ce7d451f50fa6c5fa72 (patch)
treea916c3309ccd01ba8f04d88c247c8293a19fbcb6
parent1cc398602a32f2a5a816efe643ff2fe35b1cd42f (diff)
network: add network model
Add the top-level network model. Supports connect, disconnect, power, and input invokables. Supports high-level WiFi enabled (powered) and connection status properties. Exposes the ConnMan-managed WiFi network list to QML. Bug-AGL: SPEC-1541 Change-Id: I623579aa6753ece4b4c0b78adef528732e1b41f3 Signed-off-by: Matt Porter <mporter@konsulko.com>
-rw-r--r--network/CMakeLists.txt4
-rw-r--r--network/network.cpp324
-rw-r--r--network/network.h93
3 files changed, 419 insertions, 2 deletions
diff --git a/network/CMakeLists.txt b/network/CMakeLists.txt
index e3d4812..0a53327 100644
--- a/network/CMakeLists.txt
+++ b/network/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(networkmessage.h wifinetworkmodel.h)
-add_sources(networkmessage.cpp wifinetworkmodel.cpp)
+add_headers(network.h networkmessage.h wifinetworkmodel.h)
+add_sources(network.cpp networkmessage.cpp wifinetworkmodel.cpp)
diff --git a/network/network.cpp b/network/network.cpp
new file mode 100644
index 0000000..d2a00ff
--- /dev/null
+++ b/network/network.cpp
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2018 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 <QMetaEnum>
+#include <QtQml/QQmlEngine>
+
+#include <vcard/vcard.h>
+
+#include "message.h"
+#include "messageengine.h"
+#include "network.h"
+#include "networkmessage.h"
+#include "responsemessage.h"
+#include "wifinetworkmodel.h"
+
+Network::Network (QUrl &url, QQmlContext *context, QObject * parent) :
+ QObject(parent),
+ m_mloop(nullptr),
+ m_wifi(nullptr),
+ m_wifiConnected(false),
+ m_wifiEnabled(false)
+{
+ m_mloop = new MessageEngine(url);
+ m_wifi = new WifiNetworkModel();
+
+ context->setContextProperty("WifiNetworkModel", m_wifi);
+
+ 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);
+}
+
+Network::~Network()
+{
+ delete m_mloop;
+ delete m_wifi;
+}
+
+void Network::connect(QString service)
+{
+ NetworkMessage *nmsg = new NetworkMessage();
+ QJsonObject parameter;
+
+ parameter.insert("service", service);
+
+ nmsg->createRequest("connect_service", parameter);
+ m_mloop->sendMessage(nmsg);
+ nmsg->deleteLater();
+}
+
+void Network::disconnect(QString service)
+{
+ NetworkMessage *nmsg = new NetworkMessage();
+ QJsonObject parameter;
+
+ parameter.insert("service", service);
+
+ nmsg->createRequest("disconnect_service", parameter);
+ m_mloop->sendMessage(nmsg);
+ nmsg->deleteLater();
+}
+
+void Network::input(int id, QString passphrase)
+{
+ NetworkMessage *nmsg = new NetworkMessage();
+ QJsonObject parameter, fields;
+
+ parameter.insert("id", id);
+ fields.insert("passphrase", passphrase);
+ parameter.insert("fields", fields);
+
+ nmsg->createRequest("agent_response", parameter);
+ m_mloop->sendMessage(nmsg);
+ nmsg->deleteLater();
+}
+
+void Network::power(bool on)
+{
+ if (on)
+ enableTechnology("wifi");
+ else
+ disableTechnology("wifi");
+}
+
+void Network::enableTechnology(QString type)
+{
+ NetworkMessage *nmsg = new NetworkMessage();
+ QJsonObject parameter;
+
+ parameter.insert("technology", type);
+ nmsg->createRequest("enable_technology", parameter);
+ m_mloop->sendMessage(nmsg);
+
+ nmsg->deleteLater();
+}
+
+void Network::disableTechnology(QString type)
+{
+ NetworkMessage *nmsg = new NetworkMessage();
+ QJsonObject parameter;
+
+ parameter.insert("technology", type);
+ nmsg->createRequest("disable_technology", parameter);
+ m_mloop->sendMessage(nmsg);
+
+ nmsg->deleteLater();
+}
+
+void Network::scanServices(QString type)
+{
+ NetworkMessage *nmsg = new NetworkMessage();
+ QJsonObject parameter;
+
+ parameter.insert("technology", type);
+ nmsg->createRequest("scan_services", parameter);
+ m_mloop->sendMessage(nmsg);
+
+ nmsg->deleteLater();
+}
+
+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);
+
+ return true;
+}
+
+void Network::removeService(QJsonObject service)
+{
+ QString id = service.value("service").toString();
+ WifiNetwork *network = m_wifi->getNetwork(id);
+
+ if (network)
+ m_wifi->removeNetwork(network);
+}
+
+void Network::addServices(QJsonArray services)
+{
+ for (auto service : services)
+ addService(service.toObject());
+}
+
+void Network::getServices()
+{
+ NetworkMessage *nmsg = new NetworkMessage();
+ QJsonObject parameter;
+
+ nmsg->createRequest("services", parameter);
+ m_mloop->sendMessage(nmsg);
+ nmsg->deleteLater();
+}
+
+void Network::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)
+ getServices();
+ }
+}
+
+void Network::parseTechnologies(QJsonArray technologies)
+{
+ for (auto value : 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;
+ }
+ }
+}
+
+void Network::getTechnologies()
+{
+ NetworkMessage *nmsg = new NetworkMessage();
+ QJsonObject parameter;
+
+ nmsg->createRequest("technologies", parameter);
+ m_mloop->sendMessage(nmsg);
+ nmsg->deleteLater();
+}
+
+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") {
+ QJsonObject agent = nmsg->eventData();
+ QJsonObject fields = agent.value("fields").toObject();
+ QJsonObject passphrase = fields.value("passphrase").toObject();
+ QString type = passphrase.value("type").toString();
+ QString reqmt = passphrase.value("requirement").toString();
+ if (((type == "psk") || (type == "wep")) && (reqmt == "mandatory")) {
+ int id = agent.value("id").toInt();
+ emit inputRequest(id);
+ }
+ } else if (nmsg->eventName() == "services") {
+ QJsonArray services = nmsg->eventData().value("values").toArray();
+ for (auto value : services) {
+ QJsonObject service = value.toObject();
+ QString action = service.value("action").toString();
+ QString id = service.value("service").toString();
+ if (action == "changed") {
+ addService(service);
+ } else if (action == "removed") {
+ removeService(service);
+ }
+ }
+ } else if (nmsg->eventName() == "service_properties") {
+ updateServiceProperties(nmsg->eventData());
+ } else if (nmsg->eventName() == "technology_properties") {
+ QJsonObject technology = nmsg->eventData();
+ if (technology.value("technology").toString() == "wifi") {
+ QJsonObject properties = technology.value("properties").toObject();
+ updateWifiStatus(properties);
+ }
+ }
+}
+
+void Network::processReply(ResponseMessage *rmsg)
+{
+ if (rmsg->requestVerb() == "services") {
+ addServices(rmsg->replyData().value("values").toArray());
+ } else if (rmsg->requestVerb() == "technologies") {
+ parseTechnologies(rmsg->replyData().value("values").toArray());
+ }
+}
+
+void Network::onMessageReceived(MessageType type, Message *msg)
+{
+ if (msg->isEvent() && (type == NetworkEventMessage)) {
+ processEvent(qobject_cast<NetworkMessage*>(msg));
+ } else if (msg->isReply() && (type == ResponseRequestMessage)) {
+ processReply(qobject_cast<ResponseMessage*>(msg));
+ }
+
+ msg->deleteLater();
+}
+
+void Network::onConnected()
+{
+ QStringListIterator eventIterator(events);
+ NetworkMessage *nmsg;
+
+ while (eventIterator.hasNext()) {
+ nmsg = new NetworkMessage();
+ QJsonObject parameter;
+ parameter.insert("value", eventIterator.next());
+ nmsg->createRequest("subscribe", parameter);
+ m_mloop->sendMessage(nmsg);
+ nmsg->deleteLater();
+ }
+
+ getTechnologies();
+}
+
+void Network::onDisconnected()
+{
+ QStringListIterator eventIterator(events);
+ NetworkMessage *nmsg;
+
+ while (eventIterator.hasNext()) {
+ nmsg = new NetworkMessage();
+ QJsonObject parameter;
+ parameter.insert("value", eventIterator.next());
+ nmsg->createRequest("unsubscribe", parameter);
+ m_mloop->sendMessage(nmsg);
+ nmsg->deleteLater();
+ }
+
+ m_wifi->removeAllNetworks();
+}
diff --git a/network/network.h b/network/network.h
new file mode 100644
index 0000000..dc52dd2
--- /dev/null
+++ b/network/network.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 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 NETWORK_H
+#define NETWORK_H
+
+#include <QDebug>
+#include <QObject>
+#include <QJsonArray>
+#include <QtQml/QQmlContext>
+#include <QtQml/QQmlListProperty>
+
+#include "messageengine.h"
+#include "networkmessage.h"
+#include "responsemessage.h"
+#include "wifinetworkmodel.h"
+
+class Network : public QObject
+{
+ Q_OBJECT
+
+ public:
+ explicit Network(QUrl &url, QQmlContext *context, QObject * parent = Q_NULLPTR);
+ virtual ~Network();
+
+ Q_INVOKABLE void connect(QString service);
+ Q_INVOKABLE void disconnect(QString service);
+ Q_INVOKABLE void power(bool on);
+ Q_INVOKABLE void input(int id, QString passphrase);
+
+ Q_PROPERTY(bool wifiConnected READ wifiConnected NOTIFY wifiConnectedChanged)
+ Q_PROPERTY(bool wifiEnabled READ wifiEnabled NOTIFY wifiEnabledChanged)
+
+ bool wifiConnected() const { return m_wifiConnected; }
+ bool wifiEnabled() const { return m_wifiEnabled; }
+
+ signals:
+ void inputRequest(int id);
+ void searchResults(QString name);
+ void statusChanged(bool connected);
+ void wifiConnectedChanged(bool connected);
+ void wifiEnabledChanged(bool enabled);
+
+ private:
+ MessageEngine *m_mloop;
+ QQmlContext *m_context;
+ WifiNetworkModel *m_wifi;
+ bool m_wifiConnected;
+ bool m_wifiEnabled;
+
+ 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);
+ void parseTechnologies(QJsonArray technologies);
+ void getTechnologies();
+ void processEvent(NetworkMessage *nmsg);
+ void processReply(ResponseMessage *rmsg);
+
+ // slots
+ void onConnected();
+ void onDisconnected();
+ void onMessageReceived(MessageType, Message*);
+
+ const QStringList events {
+ "agent",
+ "global_state",
+ "services",
+ "service_properties",
+ "technologies",
+ "technology_properties",
+ };
+};
+
+#endif // NETWORK_H