diff options
Diffstat (limited to 'network/networkeventhandler.cpp')
-rw-r--r-- | network/networkeventhandler.cpp | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/network/networkeventhandler.cpp b/network/networkeventhandler.cpp new file mode 100644 index 0000000..3023e45 --- /dev/null +++ b/network/networkeventhandler.cpp @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2022 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 <QDebug> +#include <QThread> + +#include "networkeventhandler.h" +#include "network.h" +#include "networkadapter.h" + + +NetworkEventHandler::NetworkEventHandler(Network *network, + bool register_agent, + QQmlContext *context, + QObject * parent) : + QObject(parent), + m_network(network), + m_agent(register_agent) +{ + connman_add_manager_event_callback(manager_event_cb, this); + connman_add_technology_property_event_callback(technology_event_cb, this); + connman_add_service_property_event_callback(service_event_cb, this); + if (register_agent) + connman_add_agent_event_callback(agent_event_cb, this); +} + +NetworkEventHandler::~NetworkEventHandler() +{ +} + +bool NetworkEventHandler::populateAdapterProperties(GVariant *in, QVariantMap &out) +{ + GVariantDict *props_dict = g_variant_dict_new(in); + if (!props_dict) + return false; + + gchar *p = NULL; + gboolean value = FALSE; + if (g_variant_dict_lookup(props_dict, "Connected", "b", &value)) + out.insert(QString("Connected"), QVariant((bool) value)); + + if (g_variant_dict_lookup(props_dict, "Powered", "b", &value)) + out.insert(QString("Powered"), QVariant((bool) value)); + + g_variant_dict_unref(props_dict); + + return true; +} + +bool NetworkEventHandler::populateServiceProperties(GVariant *in, QVariantMap &out) +{ + GVariantDict *props_dict = g_variant_dict_new(in); + if (!props_dict) + return false; + + gchar *p = NULL; + if (g_variant_dict_lookup(props_dict, "Type", "&s", &p)) + out.insert(QString("Type"), QVariant(QString(p))); + + if (g_variant_dict_lookup(props_dict, "Name", "&s", &p)) + out.insert(QString("Name"), QVariant(QString(p))); + + if (g_variant_dict_lookup(props_dict, "State", "&s", &p)) + out.insert(QString("State"), QVariant(QString(p))); + + guchar strength = 0; + if (g_variant_dict_lookup(props_dict, "Strength", "y", &strength)) + out.insert(QString("Strength"), QVariant((int) strength)); + + GVariant *v = NULL; + if (g_variant_dict_lookup(props_dict, "IPv4", "@a{sv}", &v)) { + GVariantDict *ip4_dict = g_variant_dict_new(v); + QVariantMap ip4_map; + + if (g_variant_dict_lookup(ip4_dict, "Address", "&s", &p)) + ip4_map.insert(QString("Address"), QVariant(QString(p))); + + if (g_variant_dict_lookup(ip4_dict, "Netmask", "&s", &p)) + ip4_map.insert(QString("Netmask"), QVariant(QString(p))); + + if (g_variant_dict_lookup(ip4_dict, "Gateway", "&s", &p)) + ip4_map.insert(QString("Gateway"), QVariant(QString(p))); + + if (g_variant_dict_lookup(ip4_dict, "Method", "&s", &p)) + ip4_map.insert(QString("Method"), QVariant(QString(p))); + + g_variant_dict_unref(ip4_dict); + g_variant_unref(v); + + if (!ip4_map.isEmpty()) + out.insert(QString("IPv4"), QVariant(ip4_map)); + } + + if (g_variant_dict_lookup(props_dict, "Nameservers", "&s", &v)) + out.insert(QString("Nameservers"), QVariant(QString(p))); + + GVariantIter *array = NULL; + if (g_variant_dict_lookup(props_dict, "Security", "as", &array)) { + QVariantList security; + + while (g_variant_iter_loop(array, "&s", &p)) + security.push_back(QVariant(QString(p))); + + if (!security.isEmpty()) + out.insert(QString("Security"), QVariant(security)); + + g_variant_iter_free(array); + } + + g_variant_dict_unref(props_dict); + + return !out.isEmpty(); +} + +void NetworkEventHandler::handle_connect_event(const gchar *service, gboolean status, const gchar *error) +{ + if (!status) + qDebug() << "connect failed, error " << error; + + emit connectResponseReceived(QString(service), status, QString(error)); +} + +void NetworkEventHandler::handle_manager_event(const gchar *path, + connman_manager_event_t event, + GVariant *properties) +{ +#if LIBQTAPPFW_NETWORK_DEBUG + QString props("NULL"); + QString event_str(""); + switch(event) { + case CONNMAN_MANAGER_EVENT_TECHNOLOGY_ADD: + event_str = "TECHNOLOGY_ADD"; + break; + case CONNMAN_MANAGER_EVENT_TECHNOLOGY_REMOVE: + event_str = "TECHNOLOGY_REMOVE"; + break; + case CONNMAN_MANAGER_EVENT_SERVICE_CHANGE: + event_str = "SERVICE_CHANGE"; + break; + case CONNMAN_MANAGER_EVENT_SERVICE_REMOVE: + event_str = "SERVICE_REMOVE"; + break; + case CONNMAN_MANAGER_EVENT_PROPERTY_CHANGE: + event_str = "PROPERTY_CHANGE"; + break; + } + if (event != CONNMAN_MANAGER_EVENT_TECHNOLOGY_REMOVE && + event != CONNMAN_MANAGER_EVENT_SERVICE_REMOVE) { + gchar *p = g_variant_print(properties, TRUE); + props = p; + g_free(p); + } + + qDebug() << "NetworkEventHandler::handle_manager_event: received " << + event_str << ", path = " << path << ", properties = " << props; +#endif + + switch(event) { + case CONNMAN_MANAGER_EVENT_TECHNOLOGY_ADD: + case CONNMAN_MANAGER_EVENT_TECHNOLOGY_REMOVE: + break; + case CONNMAN_MANAGER_EVENT_SERVICE_CHANGE: + { + QVariantMap props_map; + if (populateServiceProperties(properties, props_map)) { + emit serviceAdded(path, props_map); + } + } + break; + case CONNMAN_MANAGER_EVENT_SERVICE_REMOVE: + emit serviceRemoved(QString(path)); + break; + case CONNMAN_MANAGER_EVENT_PROPERTY_CHANGE: + break; + default: + break; + } + +} + +void NetworkEventHandler::handle_technology_event(const gchar *technology, + GVariant *property) +{ + if (!(technology && property)) + return; + +#if LIBQTAPPFW_NETWORK_DEBUG + gchar *p = g_variant_print(property, TRUE); + qDebug() << "NetworkEventHandler::handle_technology_event: technology = " << + technology << ", property = " << p; + g_free(p); +#endif + + // Convert (sv) tuple to a a{sv} dict for parsing + const gchar *key = NULL; + GVariant *var = NULL; + g_variant_get(property, "(sv)", &key, &var); + if (!key) + return; + + // Build QVariantMap for updateStatus + QVariantMap props_map; + if ((g_strcmp0(key, "Connected") == 0 || + g_strcmp0(key, "Powered") == 0) && + g_variant_is_of_type(var, G_VARIANT_TYPE_BOOLEAN)) { + gboolean value; + g_variant_get(var, "b", &value); + props_map.insert(QString(key), QVariant((bool) value)); + + // Update properties + emit adapterStatusChanged(QString(technology), props_map); + } + g_variant_unref(var); +} + +void NetworkEventHandler::handle_service_event(const gchar *service, + GVariant *property) +{ + if (!(service && property)) + return; + +#if LIBQTAPPFW_NETWORK_DEBUG + + gchar *p = g_variant_print(property, TRUE); + qDebug() << "NetworkEventHandler::handle_service_event: service = " << + service << ", property = " << p; + g_free(p); +#endif + // Convert (sv) tuple to a a{sv} dict for updateProperties + const gchar *key = NULL; + GVariant *var = NULL; + g_variant_get(property, "(sv)", &key, &var); + if (!key) + return; + GVariantDict *props_dict = g_variant_dict_new(NULL); + if (!props_dict) { + qWarning() << "g_variant_dict_new failed"; + return; + } + g_variant_dict_insert_value(props_dict, key, var); + GVariant *props_var = g_variant_dict_end(props_dict); + g_variant_dict_unref(props_dict); + g_variant_unref(var); + + QVariantMap props_map; + if (populateServiceProperties(props_var, props_map)) { + // Update adapter properties + emit servicePropertiesChanged(QString(service), props_map); + } + g_variant_unref(props_var); +} + +void NetworkEventHandler::handle_agent_event(const gchar *service, + const int id, + GVariant *properties) +{ + if (!(service && properties)) + return; + +#if LIBQTAPPFW_NETWORK_DEBUG + gchar *props = g_variant_print(properties, TRUE); + qDebug() << "Network::handle_agent_event: properties = " << props; + g_free(props); +#endif + + GVariantDict *props_dict = g_variant_dict_new(properties); + if (!props_dict) + return; + + GVariant *v = NULL; + QVariantMap props_map; + if (g_variant_dict_lookup(props_dict, "Passphrase", "@a{sv}", &v)) { + GVariantDict *passphrase_dict = g_variant_dict_new(v); + gchar *p = NULL; + + if (g_variant_dict_lookup(passphrase_dict, "Type", "&s", &p)) + props_map.insert(QString("Type"), QVariant(QString(p))); + + if (g_variant_dict_lookup(passphrase_dict, "Requirement", "&s", &p)) + props_map.insert(QString("Requirement"), QVariant(QString(p))); + + g_variant_dict_unref(passphrase_dict); + g_variant_unref(v); + } + g_variant_dict_unref(props_dict); + + if (!props_map.isEmpty()) + emit inputRequested(id, props_map); +} |