Improve network management

pull/2/head
cutefishd 4 years ago
parent 8407119c2e
commit f79b8f3feb

@ -6,7 +6,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(GenerateExportHeader)

@ -11,9 +11,6 @@ set(NETWORKMGR_SRCS
networkmodelitem.cpp
networkmodelitem.h
networking.cpp
networking.h
network.cpp
network.h
@ -32,6 +29,21 @@ set(NETWORKMGR_SRCS
identitymodel.cpp
identitymodel.h
handler.cpp
handler.h
configuration.cpp
configuration.h
enabledconnections.cpp
enabledconnections.h
enums.cpp
enums.h
wifisettings.cpp
wifisettings.h
qmlplugins.cpp
qmlplugins.h
)

@ -0,0 +1,163 @@
/*
Copyright 2017 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "configuration.h"
#include <QSettings>
#include <sys/types.h>
#include <pwd.h>
static bool propManageVirtualConnectionsInitialized = false;
static bool propManageVirtualConnections = false;
Configuration::Configuration()
{
::passwd *pw = ::getpwuid(::getuid());
m_userName = QString::fromLocal8Bit(pw->pw_name);
}
Configuration &Configuration::self()
{
static Configuration c;
return c;
}
bool Configuration::unlockModemOnDetection()
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
return config.value("UnlockModemOnDetection", true).toBool();
}
void Configuration::setUnlockModemOnDetection(bool unlock)
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
config.setValue(QLatin1String("UnlockModemOnDetection"), unlock);
}
bool Configuration::manageVirtualConnections()
{
// Avoid reading from the config file over and over
if (propManageVirtualConnectionsInitialized) {
return propManageVirtualConnections;
}
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
propManageVirtualConnections = config.value(QLatin1String("ManageVirtualConnections"), false).toBool();
propManageVirtualConnectionsInitialized = true;
return propManageVirtualConnections;
}
void Configuration::setManageVirtualConnections(bool manage)
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
config.setValue(QLatin1String("ManageVirtualConnections"), manage);
propManageVirtualConnections = manage;
}
bool Configuration::airplaneModeEnabled()
{
// Check whether other devices are disabled to assume airplane mode is enabled
// after suspend
const bool isWifiDisabled = !NetworkManager::isWirelessEnabled() || !NetworkManager::isWirelessHardwareEnabled();
const bool isWwanDisabled = !NetworkManager::isWwanEnabled() || !NetworkManager::isWwanHardwareEnabled();
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
if (config.value(QLatin1String("AirplaneModeEnabled"), false).toBool()) {
// We can assume that airplane mode is still activated after resume
if (isWifiDisabled && isWwanDisabled)
return true;
else {
setAirplaneModeEnabled(false);
}
}
return false;
}
void Configuration::setAirplaneModeEnabled(bool enabled)
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
config.setValue(QLatin1String("AirplaneModeEnabled"), enabled);
}
QString Configuration::hotspotName()
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
const QString defaultName = m_userName + QLatin1String("-hotspot");
return config.value(QLatin1String("HotspotName"), defaultName).toString();
}
void Configuration::setHotspotName(const QString &name)
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
config.setValue(QLatin1String("HotspotName"), name);
}
QString Configuration::hotspotPassword()
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
return config.value(QLatin1String("HotspotPassword"), QString()).toString();
}
void Configuration::setHotspotPassword(const QString &password)
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
config.setValue(QLatin1String("HotspotPassword"), password);
}
QString Configuration::hotspotConnectionPath()
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
return config.value(QLatin1String("HotspotConnectionPath"), QString()).toString();
}
void Configuration::setHotspotConnectionPath(const QString &path)
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
config.setValue(QLatin1String("HotspotConnectionPath"), path);
}
bool Configuration::showPasswordDialog()
{
QSettings config(QSettings::UserScope, "cutefishos", "nm");
config.beginGroup(QLatin1String("General"));
return config.value(QLatin1String("ShowPasswordDialog"), true).toBool();
}

@ -0,0 +1,71 @@
/*
Copyright 2017 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PLASMA_NM_CONFIGURATION_H
#define PLASMA_NM_CONFIGURATION_H
#include <QObject>
#include <NetworkManagerQt/Manager>
class Q_DECL_EXPORT Configuration : public QObject
{
Q_PROPERTY(bool unlockModemOnDetection READ unlockModemOnDetection WRITE setUnlockModemOnDetection)
Q_PROPERTY(bool manageVirtualConnections READ manageVirtualConnections WRITE setManageVirtualConnections)
Q_PROPERTY(bool airplaneModeEnabled READ airplaneModeEnabled WRITE setAirplaneModeEnabled)
Q_PROPERTY(QString hotspotName READ hotspotName WRITE setHotspotName)
Q_PROPERTY(QString hotspotPassword READ hotspotPassword WRITE setHotspotPassword)
Q_PROPERTY(QString hotspotConnectionPath READ hotspotConnectionPath WRITE setHotspotConnectionPath)
//Readonly constant property, as this value should only be set by the platform
Q_PROPERTY(bool showPasswordDialog READ showPasswordDialog CONSTANT)
Q_OBJECT
public:
Configuration();
bool unlockModemOnDetection();
void setUnlockModemOnDetection(bool unlock);
bool manageVirtualConnections();
void setManageVirtualConnections(bool manage);
bool airplaneModeEnabled();
void setAirplaneModeEnabled(bool enabled);
QString hotspotName();
void setHotspotName(const QString &name);
QString hotspotPassword();
void setHotspotPassword(const QString &password);
QString hotspotConnectionPath();
void setHotspotConnectionPath(const QString &path);
bool showPasswordDialog();
static Configuration &self();
private:
QString m_userName;
};
#endif // PLAMA_NM_CONFIGURATION_H

@ -0,0 +1,96 @@
/*
Copyright 2013 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "enabledconnections.h"
EnabledConnections::EnabledConnections(QObject* parent)
: QObject(parent)
, m_networkingEnabled(NetworkManager::isNetworkingEnabled())
, m_wirelessEnabled(NetworkManager::isWirelessEnabled())
, m_wirelessHwEnabled(NetworkManager::isWirelessHardwareEnabled())
, m_wwanEnabled(NetworkManager::isWwanEnabled())
, m_wwanHwEnabled(NetworkManager::isWwanHardwareEnabled())
{
connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &EnabledConnections::onNetworkingEnabled);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &EnabledConnections::onWirelessEnabled);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessHardwareEnabledChanged, this, &EnabledConnections::onWirelessHwEnabled);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanEnabledChanged, this, &EnabledConnections::onWwanEnabled);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanHardwareEnabledChanged, this, &EnabledConnections::onWwanHwEnabled);
}
EnabledConnections::~EnabledConnections()
{
}
bool EnabledConnections::isNetworkingEnabled() const
{
return m_networkingEnabled;
}
bool EnabledConnections::isWirelessEnabled() const
{
return m_wirelessEnabled;
}
bool EnabledConnections::isWirelessHwEnabled() const
{
return m_wirelessHwEnabled;
}
bool EnabledConnections::isWwanEnabled() const
{
return m_wwanEnabled;
}
bool EnabledConnections::isWwanHwEnabled() const
{
return m_wwanHwEnabled;
}
void EnabledConnections::onNetworkingEnabled(bool enabled)
{
m_networkingEnabled = enabled;
Q_EMIT networkingEnabled(enabled);
}
void EnabledConnections::onWirelessEnabled(bool enabled)
{
m_wirelessEnabled = enabled;
Q_EMIT wirelessEnabled(enabled);
}
void EnabledConnections::onWirelessHwEnabled(bool enabled)
{
m_wirelessHwEnabled = enabled;
Q_EMIT wirelessHwEnabled(enabled);
}
void EnabledConnections::onWwanEnabled(bool enabled)
{
m_wwanEnabled = enabled;
Q_EMIT wwanEnabled(enabled);
}
void EnabledConnections::onWwanHwEnabled(bool enabled)
{
m_wwanHwEnabled = enabled;
Q_EMIT wwanHwEnabled(enabled);
}

@ -0,0 +1,84 @@
/*
Copyright 2013 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PLASMA_NM_ENABLED_CONNECTIONS_H
#define PLASMA_NM_ENABLED_CONNECTIONS_H
#include <QObject>
#include <NetworkManagerQt/Manager>
class EnabledConnections : public QObject
{
/**
* Indicates if overall networking is currently enabled or not
*/
Q_PROPERTY(bool networkingEnabled READ isNetworkingEnabled NOTIFY networkingEnabled)
/**
* Indicates if wireless is currently enabled or not
*/
Q_PROPERTY(bool wirelessEnabled READ isWirelessEnabled NOTIFY wirelessEnabled)
/**
* Indicates if the wireless hardware is currently enabled, i.e. the state of the RF kill switch
*/
Q_PROPERTY(bool wirelessHwEnabled READ isWirelessHwEnabled NOTIFY wirelessHwEnabled)
/**
* Indicates if mobile broadband devices are currently enabled or not.
*/
Q_PROPERTY(bool wwanEnabled READ isWwanEnabled NOTIFY wwanEnabled)
/**
* Indicates if the mobile broadband hardware is currently enabled, i.e. the state of the RF kill switch.
*/
Q_PROPERTY(bool wwanHwEnabled READ isWwanHwEnabled NOTIFY wwanHwEnabled)
Q_OBJECT
public:
explicit EnabledConnections(QObject* parent = nullptr);
~EnabledConnections() override;
bool isNetworkingEnabled() const;
bool isWirelessEnabled() const;
bool isWirelessHwEnabled() const;
bool isWwanEnabled() const;
bool isWwanHwEnabled() const;
public Q_SLOTS:
void onNetworkingEnabled(bool enabled);
void onWirelessEnabled(bool enabled);
void onWirelessHwEnabled(bool enabled);
void onWwanEnabled(bool enabled);
void onWwanHwEnabled(bool enabled);
Q_SIGNALS:
void networkingEnabled(bool enabled);
void wirelessEnabled(bool enabled);
void wirelessHwEnabled(bool enabled);
void wwanEnabled(bool enabled);
void wwanHwEnabled(bool enabled);
private:
bool m_networkingEnabled;
bool m_wirelessEnabled;
bool m_wirelessHwEnabled;
bool m_wwanEnabled;
bool m_wwanHwEnabled;
};
#endif // PLASMA_NM_ENABLED_CONNECTIONS_H

@ -0,0 +1,30 @@
/*
Copyright 2013 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "enums.h"
Enums::Enums(QObject* parent)
: QObject(parent)
{
}
Enums::~Enums()
{
}

@ -0,0 +1,77 @@
/*
Copyright 2013 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PLASMA_NM_ENUMS_H
#define PLASMA_NM_ENUMS_H
#include <QObject>
class Enums : public QObject
{
Q_OBJECT
Q_ENUMS(ConnectionStatus)
Q_ENUMS(ConnectionType)
Q_ENUMS(SecurityType)
public:
explicit Enums(QObject* parent = nullptr);
~Enums() override;
enum ConnectionStatus {
UnknownState = 0,
Activating,
Activated,
Deactivating,
Deactivated
};
enum ConnectionType {
UnknownConnectionType = 0,
Adsl,
Bluetooth,
Bond,
Bridge,
Cdma,
Gsm,
Infiniband,
OLPCMesh,
Pppoe,
Vlan,
Vpn,
Wimax,
Wired,
Wireless
};
enum SecurityType {
UnknownSecurity = -1,
NoneSecurity = 0,
StaticWep,
DynamicWep,
Leap,
WpaPsk,
WpaEap,
Wpa2Psk,
Wpa2Eap,
SAE
};
};
#endif // PLASMA_NM_ENUMS_H

@ -0,0 +1,867 @@
/*
Copyright 2013-2014 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "handler.h"
#include "configuration.h"
#include "uiutils.h"
#include <NetworkManagerQt/Manager>
#include <NetworkManagerQt/AccessPoint>
#include <NetworkManagerQt/WiredDevice>
#include <NetworkManagerQt/WirelessDevice>
#include <NetworkManagerQt/Setting>
#include <NetworkManagerQt/GsmSetting>
#include <NetworkManagerQt/WiredSetting>
#include <NetworkManagerQt/WirelessSetting>
#include <NetworkManagerQt/ActiveConnection>
#include <NetworkManagerQt/Ipv4Setting>
#include <libnm/nm-vpn-plugin-info.h>
#if WITH_MODEMMANAGER_SUPPORT
#include <ModemManagerQt/Manager>
#include <ModemManagerQt/ModemDevice>
#endif
#include <QDBusError>
#include <QDBusMetaType>
#include <QDBusPendingReply>
#include <QIcon>
#include <sys/types.h>
#include <pwd.h>
#define AGENT_SERVICE "org.kde.kded5"
#define AGENT_PATH "/modules/networkmanagement"
#define AGENT_IFACE "org.kde.plasmanetworkmanagement"
// 10 seconds
#define NM_REQUESTSCAN_LIMIT_RATE 10000
Handler::Handler(QObject *parent)
: QObject(parent)
, m_tmpWirelessEnabled(NetworkManager::isWirelessEnabled())
, m_tmpWwanEnabled(NetworkManager::isWwanEnabled())
{
::passwd *pw = ::getpwuid(::getuid());
m_userName = QString::fromLocal8Bit(pw->pw_name);
QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE),
QStringLiteral(AGENT_PATH),
QStringLiteral(AGENT_IFACE),
QStringLiteral("secretsError"),
this, SLOT(secretAgentError(QString, QString)));
if (!Configuration::self().hotspotConnectionPath().isEmpty()) {
NetworkManager::ActiveConnection::Ptr hotspot = NetworkManager::findActiveConnection(Configuration::self().hotspotConnectionPath());
if (!hotspot) {
Configuration::self().setHotspotConnectionPath(QString());
}
}
m_hotspotSupported = checkHotspotSupported();
if (NetworkManager::checkVersion(1, 16, 0)) {
connect(NetworkManager::notifier(), &NetworkManager::Notifier::primaryConnectionTypeChanged, this, &Handler::primaryConnectionTypeChanged);
}
}
Handler::~Handler()
{
}
void Handler::activateConnection(const QString& connection, const QString& device, const QString& specificObject)
{
NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection);
if (!con) {
qWarning() << "Not possible to activate this connection";
return;
}
if (con->settings()->connectionType() == NetworkManager::ConnectionSettings::Vpn) {
NetworkManager::VpnSetting::Ptr vpnSetting = con->settings()->setting(NetworkManager::Setting::Vpn).staticCast<NetworkManager::VpnSetting>();
if (vpnSetting) {
qDebug() << "Checking VPN" << con->name() << "type:" << vpnSetting->serviceType();
// bool pluginMissing = false;
// // Check missing plasma-nm VPN plugin
// const KService::List services = KServiceTypeTrader::self()->query("PlasmaNetworkManagement/VpnUiPlugin",
// QString::fromLatin1("[X-NetworkManager-Services]=='%1'").arg(vpnSetting->serviceType()));
// pluginMissing = services.isEmpty();
// // Check missing NetworkManager VPN plugin
// if (!pluginMissing) {
// GSList *plugins = nullptr;
// plugins = nm_vpn_plugin_info_list_load();
// NMVpnPluginInfo *plugin_info = nm_vpn_plugin_info_list_find_by_service(plugins, vpnSetting->serviceType().toStdString().c_str());
// pluginMissing = !plugin_info;
// }
// if (pluginMissing) {
// qWarning() << "VPN" << vpnSetting->serviceType() << "not found, skipping";
// KNotification *notification = new KNotification("MissingVpnPlugin", KNotification::CloseOnTimeout, this);
// notification->setComponentName("networkmanagement");
// notification->setTitle(con->name());
// notification->setText(i18n("Missing VPN plugin"));
// notification->setIconName(QStringLiteral("dialog-warning"));
// notification->sendEvent();
// return;
// }
}
}
#if WITH_MODEMMANAGER_SUPPORT
if (con->settings()->connectionType() == NetworkManager::ConnectionSettings::Gsm) {
NetworkManager::ModemDevice::Ptr nmModemDevice = NetworkManager::findNetworkInterface(device).objectCast<NetworkManager::ModemDevice>();
if (nmModemDevice) {
ModemManager::ModemDevice::Ptr mmModemDevice = ModemManager::findModemDevice(nmModemDevice->udi());
if (mmModemDevice) {
ModemManager::Modem::Ptr modem = mmModemDevice->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>();
NetworkManager::GsmSetting::Ptr gsmSetting = con->settings()->setting(NetworkManager::Setting::Gsm).staticCast<NetworkManager::GsmSetting>();
if (gsmSetting && gsmSetting->pinFlags() == NetworkManager::Setting::NotSaved &&
modem && modem->unlockRequired() > MM_MODEM_LOCK_NONE) {
QDBusInterface managerIface("org.kde.plasmanetworkmanagement", "/org/kde/plasmanetworkmanagement", "org.kde.plasmanetworkmanagement", QDBusConnection::sessionBus(), this);
managerIface.call("unlockModem", mmModemDevice->uni());
connect(modem.data(), &ModemManager::Modem::unlockRequiredChanged, this, &Handler::unlockRequiredChanged);
m_tmpConnectionPath = connection;
m_tmpDevicePath = device;
m_tmpSpecificPath = specificObject;
return;
}
}
}
}
#endif
QDBusPendingReply<QDBusObjectPath> reply = NetworkManager::activateConnection(connection, device, specificObject);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("action", Handler::ActivateConnection);
watcher->setProperty("connection", con->name());
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished);
}
QString Handler::wifiCode(const QString& connectionPath, const QString& ssid, int _securityType) const
{
NetworkManager::WirelessSecurityType securityType = static_cast<NetworkManager::WirelessSecurityType>(_securityType);
QString ret = QStringLiteral("WIFI:S:") + ssid + QLatin1Char(';');
if (securityType != NetworkManager::NoneSecurity) {
switch (securityType) {
case NetworkManager::NoneSecurity:
break;
case NetworkManager::StaticWep:
ret += "T:WEP;";
break;
case NetworkManager::WpaPsk:
case NetworkManager::Wpa2Psk:
ret += "T:WPA;";
break;
case NetworkManager::SAE:
ret += "T:SAE;";
break;
default:
case NetworkManager::DynamicWep:
case NetworkManager::WpaEap:
case NetworkManager::Wpa2Eap:
case NetworkManager::Leap:
return {};
}
}
NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(connectionPath);
if(!connection)
return {};
const auto key = QStringLiteral("802-11-wireless-security");
auto reply = connection->secrets(key);
const auto secret = reply.argumentAt<0>()[key];
QString pass;
switch (securityType) {
case NetworkManager::NoneSecurity:
break;
case NetworkManager::WpaPsk:
case NetworkManager::Wpa2Psk:
case NetworkManager::SAE:
pass = secret["psk"].toString();
break;
default:
return {};
}
if (!pass.isEmpty())
ret += QStringLiteral("P:") + pass + QLatin1Char(';');
return ret + QLatin1Char(';');
}
void Handler::addAndActivateConnection(const QString& device, const QString& specificObject, const QString& password)
{
NetworkManager::AccessPoint::Ptr ap;
NetworkManager::WirelessDevice::Ptr wifiDev;
for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) {
if (dev->type() == NetworkManager::Device::Wifi) {
wifiDev = dev.objectCast<NetworkManager::WirelessDevice>();
ap = wifiDev->findAccessPoint(specificObject);
if (ap) {
break;
}
}
}
if (!ap) {
return;
}
NetworkManager::ConnectionSettings::Ptr settings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless));
settings->setId(ap->ssid());
settings->setUuid(NetworkManager::ConnectionSettings::createNewUuid());
settings->setAutoconnect(true);
settings->addToPermissions(m_userName, QString());
NetworkManager::WirelessSetting::Ptr wifiSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>();
wifiSetting->setInitialized(true);
wifiSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>();
wifiSetting->setSsid(ap->ssid().toUtf8());
if (ap->mode() == NetworkManager::AccessPoint::Adhoc) {
wifiSetting->setMode(NetworkManager::WirelessSetting::Adhoc);
}
NetworkManager::WirelessSecuritySetting::Ptr wifiSecurity = settings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast<NetworkManager::WirelessSecuritySetting>();
NetworkManager::WirelessSecurityType securityType = NetworkManager::findBestWirelessSecurity(wifiDev->wirelessCapabilities(), true, (ap->mode() == NetworkManager::AccessPoint::Adhoc), ap->capabilities(), ap->wpaFlags(), ap->rsnFlags());
if (securityType != NetworkManager::NoneSecurity) {
wifiSecurity->setInitialized(true);
wifiSetting->setSecurity("802-11-wireless-security");
}
if (securityType == NetworkManager::Leap ||
securityType == NetworkManager::DynamicWep ||
securityType == NetworkManager::Wpa2Eap ||
securityType == NetworkManager::WpaEap) {
if (securityType == NetworkManager::DynamicWep || securityType == NetworkManager::Leap) {
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Ieee8021x);
if (securityType == NetworkManager::Leap) {
wifiSecurity->setAuthAlg(NetworkManager::WirelessSecuritySetting::Leap);
}
} else {
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaEap);
}
m_tmpConnectionUuid = settings->uuid();
m_tmpDevicePath = device;
m_tmpSpecificPath = specificObject;
// QPointer<ConnectionEditorDialog> editor = new ConnectionEditorDialog(settings);
// editor->show();
// KWindowSystem::setState(editor->winId(), NET::KeepAbove);
// KWindowSystem::forceActiveWindow(editor->winId());
// connect(editor.data(), &ConnectionEditorDialog::accepted,
// [editor, this] () {
// addConnection(editor->setting());
// });
// connect(editor.data(), &ConnectionEditorDialog::finished,
// [editor] () {
// if (editor) {
// editor->deleteLater();
// }
// });
// editor->setModal(true);
// editor->show();
} else {
if (securityType == NetworkManager::StaticWep) {
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Wep);
wifiSecurity->setWepKey0(password);
// if (KWallet::Wallet::isEnabled()) {
// wifiSecurity->setWepKeyFlags(NetworkManager::Setting::AgentOwned);
// }
} else {
if (ap->mode() == NetworkManager::AccessPoint::Adhoc) {
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone);
} else {
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk);
}
wifiSecurity->setPsk(password);
// if (KWallet::Wallet::isEnabled()) {
// wifiSecurity->setPskFlags(NetworkManager::Setting::AgentOwned);
// }
}
QDBusPendingReply<QDBusObjectPath> reply = NetworkManager::addAndActivateConnection(settings->toMap(), device, specificObject);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("action", Handler::AddAndActivateConnection);
watcher->setProperty("connection", settings->name());
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished);
}
settings.clear();
}
void Handler::addConnection(const NMVariantMapMap& map)
{
QDBusPendingReply<QDBusObjectPath> reply = NetworkManager::addConnection(map);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("action", AddConnection);
watcher->setProperty("connection", map.value("connection").value("id"));
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished);
}
void Handler::deactivateConnection(const QString& connection, const QString& device)
{
NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection);
if (!con) {
qWarning() << "Not possible to deactivate this connection";
return;
}
QDBusPendingReply<> reply;
for (const NetworkManager::ActiveConnection::Ptr &active : NetworkManager::activeConnections()) {
if (active->uuid() == con->uuid() && ((!active->devices().isEmpty() && active->devices().first() == device) ||
active->vpn())) {
if (active->vpn()) {
reply = NetworkManager::deactivateConnection(active->path());
} else {
NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(active->devices().first());
if (device) {
reply = device->disconnectInterface();
}
}
}
}
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("action", Handler::DeactivateConnection);
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished);
}
void Handler::disconnectAll()
{
for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) {
device->disconnectInterface();
}
}
void Handler::enableAirplaneMode(bool enable)
{
if (enable) {
m_tmpWirelessEnabled = NetworkManager::isWirelessEnabled();
m_tmpWwanEnabled = NetworkManager::isWwanEnabled();
enableBluetooth(false);
enableWireless(false);
enableWwan(false);
} else {
enableBluetooth(true);
if (m_tmpWirelessEnabled) {
enableWireless(true);
}
if (m_tmpWwanEnabled) {
enableWwan(true);
}
}
}
template<typename T>
void makeDBusCall(const QDBusMessage &message, QObject *context, std::function<void(QDBusPendingReply<T>)> func)
{
QDBusPendingReply<T> reply = QDBusConnection::systemBus().asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, context);
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, context, [func] (QDBusPendingCallWatcher *watcher) {
const QDBusPendingReply<T> reply = *watcher;
if (!reply.isValid()) {
qWarning() << reply.error().message();
return;
}
func(reply);
watcher->deleteLater();
});
}
void setBluetoothEnabled(QString path, bool enabled)
{
QDBusMessage message = QDBusMessage::createMethodCall("org.bluez", path, "org.freedesktop.DBus.Properties", "Set");
QList<QVariant> arguments;
arguments << QLatin1String("org.bluez.Adapter1");
arguments << QLatin1String("Powered");
arguments << QVariant::fromValue(QDBusVariant(QVariant(enabled)));
message.setArguments(arguments);
QDBusConnection::systemBus().asyncCall(message);
}
void Handler::enableBluetooth(bool enable)
{
qDBusRegisterMetaType< QMap<QDBusObjectPath, NMVariantMapMap > >();
const QDBusMessage getObjects = QDBusMessage::createMethodCall("org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
makeDBusCall<QMap<QDBusObjectPath, NMVariantMapMap>>(getObjects, this, [enable, this](const auto reply) {
for (const QDBusObjectPath &path : reply.value().keys()) {
const QString objPath = path.path();
qDebug() << "inspecting path" << objPath;
const QStringList interfaces = reply.value().value(path).keys();
qDebug() << "interfaces:" << interfaces;
if (!interfaces.contains("org.bluez.Adapter1")) {
continue;
}
// We need to check previous state first
if (!enable) {
QDBusMessage getPowered = QDBusMessage::createMethodCall("org.bluez", objPath, "org.freedesktop.DBus.Properties", "Get");
const QList<QVariant> arguments { QLatin1String("org.bluez.Adapter1"), QLatin1String("Powered") };
getPowered.setArguments(arguments);
makeDBusCall<QVariant>(getPowered, this, [objPath, this](const auto reply){
m_bluetoothAdapters.insert(objPath, reply.value().toBool());
setBluetoothEnabled(objPath, false);
});
} else if (m_bluetoothAdapters.value(objPath)) {
setBluetoothEnabled(objPath, true);
}
}
});
}
void Handler::enableNetworking(bool enable)
{
NetworkManager::setNetworkingEnabled(enable);
}
void Handler::enableWireless(bool enable)
{
NetworkManager::setWirelessEnabled(enable);
}
void Handler::enableWwan(bool enable)
{
NetworkManager::setWwanEnabled(enable);
}
void Handler::removeConnection(const QString& connection)
{
NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection);
if (!con || con->uuid().isEmpty()) {
qWarning() << "Not possible to remove connection " << connection;
return;
}
// Remove slave connections
for (const NetworkManager::Connection::Ptr &connection : NetworkManager::listConnections()) {
NetworkManager::ConnectionSettings::Ptr settings = connection->settings();
if (settings->master() == con->uuid()) {
connection->remove();
}
}
QDBusPendingReply<> reply = con->remove();
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("action", Handler::RemoveConnection);
watcher->setProperty("connection", con->name());
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished);
}
void Handler::updateConnection(const NetworkManager::Connection::Ptr& connection, const NMVariantMapMap& map)
{
QDBusPendingReply<> reply = connection->update(map);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("action", UpdateConnection);
watcher->setProperty("connection", connection->name());
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished);
}
void Handler::requestScan(const QString &interface)
{
for (NetworkManager::Device::Ptr device : NetworkManager::networkInterfaces()) {
if (device->type() == NetworkManager::Device::Wifi) {
NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast<NetworkManager::WirelessDevice>();
if (wifiDevice && wifiDevice->state() != NetworkManager::WirelessDevice::Unavailable) {
if (!interface.isEmpty() && interface != wifiDevice->interfaceName()) {
continue;
}
if (!checkRequestScanRateLimit(wifiDevice)) {
QDateTime now = QDateTime::currentDateTime();
// for NM < 1.12, lastScan is not available
QDateTime lastScan = wifiDevice->lastScan();
QDateTime lastRequestScan = wifiDevice->lastRequestScan();
// Compute the next time we can run a scan
int timeout = NM_REQUESTSCAN_LIMIT_RATE;
if (lastScan.isValid() && lastScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE) {
timeout = NM_REQUESTSCAN_LIMIT_RATE - lastScan.msecsTo(now);
} else if (lastRequestScan.isValid() && lastRequestScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE) {
timeout = NM_REQUESTSCAN_LIMIT_RATE - lastRequestScan.msecsTo(now);
}
qDebug() << "Rescheduling a request scan for" << wifiDevice->interfaceName() << "in" << timeout;
scheduleRequestScan(wifiDevice->interfaceName(), timeout);
if (!interface.isEmpty()) {
return;
}
continue;
} else if (m_wirelessScanRetryTimer.contains(interface)){
m_wirelessScanRetryTimer.value(interface)->stop();
delete m_wirelessScanRetryTimer.take(interface);
}
qDebug() << "Requesting wifi scan on device" << wifiDevice->interfaceName();
QDBusPendingReply<> reply = wifiDevice->requestScan();
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("action", Handler::RequestScan);
watcher->setProperty("interface", wifiDevice->interfaceName());
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished);
}
}
}
}
void Handler::createHotspot()
{
bool foundInactive = false;
bool useApMode = false;
NetworkManager::WirelessDevice::Ptr wifiDev;
NetworkManager::ConnectionSettings::Ptr connectionSettings;
connectionSettings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless));
NetworkManager::WirelessSetting::Ptr wifiSetting = connectionSettings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>();
wifiSetting->setMode(NetworkManager::WirelessSetting::Adhoc);
wifiSetting->setSsid(Configuration::self().hotspotName().toUtf8());
for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) {
if (device->type() == NetworkManager::Device::Wifi) {
wifiDev = device.objectCast<NetworkManager::WirelessDevice>();
if (wifiDev) {
if (!wifiDev->isActive()) {
foundInactive = true;
} else {
// Prefer previous device if it was inactive
if (foundInactive) {
break;
}
}
if (wifiDev->wirelessCapabilities().testFlag(NetworkManager::WirelessDevice::ApCap)) {
useApMode = true;
}
// We prefer inactive wireless card with AP capabilities
if (foundInactive && useApMode) {
break;
}
}
}
}
if (!wifiDev) {
qWarning() << "Failed to create hotspot: missing wireless device";
return;
}
wifiSetting->setInitialized(true);
wifiSetting->setMode(useApMode ? NetworkManager::WirelessSetting::Ap :NetworkManager::WirelessSetting::Adhoc);
if (!Configuration::self().hotspotPassword().isEmpty()) {
NetworkManager::WirelessSecuritySetting::Ptr wifiSecurity = connectionSettings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast<NetworkManager::WirelessSecuritySetting>();
wifiSecurity->setInitialized(true);
if (useApMode) {
// Use WPA2
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk);
wifiSecurity->setPsk(Configuration::self().hotspotPassword());
wifiSecurity->setPskFlags(NetworkManager::Setting::AgentOwned);
} else {
// Use WEP
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Wep);
wifiSecurity->setWepKeyType(NetworkManager::WirelessSecuritySetting::Passphrase);
wifiSecurity->setWepTxKeyindex(0);
wifiSecurity->setWepKey0(Configuration::self().hotspotPassword());
wifiSecurity->setWepKeyFlags(NetworkManager::Setting::AgentOwned);
wifiSecurity->setAuthAlg(NetworkManager::WirelessSecuritySetting::Open);
}
}
NetworkManager::Ipv4Setting::Ptr ipv4Setting = connectionSettings->setting(NetworkManager::Setting::Ipv4).dynamicCast<NetworkManager::Ipv4Setting>();
ipv4Setting->setMethod(NetworkManager::Ipv4Setting::Shared);
ipv4Setting->setInitialized(true);
connectionSettings->setId(Configuration::self().hotspotName());
connectionSettings->setAutoconnect(false);
connectionSettings->setUuid(NetworkManager::ConnectionSettings::createNewUuid());
const QVariantMap options = { {QLatin1String("persist"), QLatin1String("volatile")} };
QDBusPendingReply<QDBusObjectPath, QDBusObjectPath, QVariantMap> reply = NetworkManager::addAndActivateConnection2(connectionSettings->toMap(), wifiDev->uni(), QString(), options);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("action", Handler::CreateHotspot);
watcher->setProperty("connection", Configuration::self().hotspotName());
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished);
connect(watcher, &QDBusPendingCallWatcher::finished, this, QOverload<QDBusPendingCallWatcher *>::of(&Handler::hotspotCreated));
}
void Handler::stopHotspot()
{
const QString activeConnectionPath = Configuration::self().hotspotConnectionPath();
if (activeConnectionPath.isEmpty()) {
return;
}
NetworkManager::ActiveConnection::Ptr hotspot = NetworkManager::findActiveConnection(activeConnectionPath);
if (!hotspot) {
return;
}
NetworkManager::deactivateConnection(activeConnectionPath);
Configuration::self().setHotspotConnectionPath(QString());
Q_EMIT hotspotDisabled();
}
bool Handler::checkRequestScanRateLimit(const NetworkManager::WirelessDevice::Ptr &wifiDevice)
{
QDateTime now = QDateTime::currentDateTime();
QDateTime lastScan = wifiDevice->lastScan();
QDateTime lastRequestScan = wifiDevice->lastRequestScan();
// if the last scan finished within the last 10 seconds
bool ret = lastScan.isValid() && lastScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE;
// or if the last Request was sent within the last 10 seconds
ret |= lastRequestScan.isValid() && lastRequestScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE;
// skip the request scan
if (ret) {
qDebug() << "Last scan finished " << lastScan.msecsTo(now) << "ms ago and last request scan was sent "
<< lastRequestScan.msecsTo(now) << "ms ago, Skipping scanning interface:" << wifiDevice->interfaceName();
return false;
}
return true;
}
bool Handler::checkHotspotSupported()
{
if (NetworkManager::checkVersion(1, 16, 0)) {
bool unusedWifiFound = false;
bool wifiFound = false;
for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) {
if (device->type() == NetworkManager::Device::Wifi) {
wifiFound = true;
NetworkManager::WirelessDevice::Ptr wifiDev = device.objectCast<NetworkManager::WirelessDevice>();
if (wifiDev && !wifiDev->isActive()) {
unusedWifiFound = true;
}
}
}
if (!wifiFound) {
return false;
}
if (unusedWifiFound) {
return true;
}
// Check if the primary connection which is used for internet connectivity is not using WiFi
if (NetworkManager::primaryConnectionType() != NetworkManager::ConnectionSettings::Wireless) {
return true;
}
}
return false;
}
void Handler::scheduleRequestScan(const QString &interface, int timeout)
{
QTimer *timer;
if (!m_wirelessScanRetryTimer.contains(interface)) {
// create a timer for the interface
timer = new QTimer();
timer->setSingleShot(true);
m_wirelessScanRetryTimer.insert(interface, timer);
auto retryAction = [this, interface]() {
requestScan(interface);
};
connect(timer, &QTimer::timeout, this, retryAction);
} else {
// set the new value for an existing timer
timer = m_wirelessScanRetryTimer.value(interface);
if (timer->isActive()) {
timer->stop();
}
}
// +1 ms is added to avoid having the scan being rejetted by nm
// because it is run at the exact last millisecond of the requestScan threshold
timer->setInterval(timeout + 1);
timer->start();
}
void Handler::scanRequestFailed(const QString &interface)
{
scheduleRequestScan(interface, 2000);
}
void Handler::secretAgentError(const QString &connectionPath, const QString &message)
{
// If the password was wrong, forget it
removeConnection(connectionPath);
emit connectionActivationFailed(connectionPath, message);
}
void Handler::replyFinished(QDBusPendingCallWatcher * watcher)
{
// QDBusPendingReply<> reply = *watcher;
// if (reply.isError() || !reply.isValid()) {
// KNotification *notification = nullptr;
// QString error = reply.error().message();
// Handler::HandlerAction action = (Handler::HandlerAction)watcher->property("action").toUInt();
// switch (action) {
// case Handler::ActivateConnection:
// notification = new KNotification("FailedToActivateConnection", KNotification::CloseOnTimeout, this);
// notification->setTitle(i18n("Failed to activate %1", watcher->property("connection").toString()));
// break;
// case Handler::AddAndActivateConnection:
// notification = new KNotification("FailedToAddConnection", KNotification::CloseOnTimeout, this);
// notification->setTitle(i18n("Failed to add %1", watcher->property("connection").toString()));
// break;
// case Handler::AddConnection:
// notification = new KNotification("FailedToAddConnection", KNotification::CloseOnTimeout, this);
// notification->setTitle(i18n("Failed to add connection %1", watcher->property("connection").toString()));
// break;
// case Handler::DeactivateConnection:
// notification = new KNotification("FailedToDeactivateConnection", KNotification::CloseOnTimeout, this);
// notification->setTitle(i18n("Failed to deactivate %1", watcher->property("connection").toString()));
// break;
// case Handler::RemoveConnection:
// notification = new KNotification("FailedToRemoveConnection", KNotification::CloseOnTimeout, this);
// notification->setTitle(i18n("Failed to remove %1", watcher->property("connection").toString()));
// break;
// case Handler::UpdateConnection:
// notification = new KNotification("FailedToUpdateConnection", KNotification::CloseOnTimeout, this);
// notification->setTitle(i18n("Failed to update connection %1", watcher->property("connection").toString()));
// break;
// case Handler::RequestScan:
// {
// const QString interface = watcher->property("interface").toString();
// qWarning() << "Wireless scan on" << interface << "failed:" << error;
// scanRequestFailed(interface);
// break;
// }
// case Handler::CreateHotspot:
// notification = new KNotification("FailedToCreateHotspot", KNotification::CloseOnTimeout, this);
// notification->setTitle(i18n("Failed to create hotspot %1", watcher->property("connection").toString()));
// break;
// default:
// break;
// }
// if (notification) {
// notification->setComponentName("networkmanagement");
// notification->setText(error);
// notification->setIconName(QStringLiteral("dialog-warning"));
// notification->sendEvent();
// }
// } else {
// KNotification *notification = nullptr;
// Handler::HandlerAction action = (Handler::HandlerAction)watcher->property("action").toUInt();
// switch (action) {
// case Handler::AddConnection:
// notification = new KNotification("ConnectionAdded", KNotification::CloseOnTimeout, this);
// notification->setText(i18n("Connection %1 has been added", watcher->property("connection").toString()));
// break;
// case Handler::RemoveConnection:
// notification = new KNotification("ConnectionRemoved", KNotification::CloseOnTimeout, this);
// notification->setText(i18n("Connection %1 has been removed", watcher->property("connection").toString()));
// break;
// case Handler::UpdateConnection:
// notification = new KNotification("ConnectionUpdated", KNotification::CloseOnTimeout, this);
// notification->setText(i18n("Connection %1 has been updated", watcher->property("connection").toString()));
// break;
// case Handler::RequestScan:
// qDebug() << "Wireless scan on" << watcher->property("interface").toString() << "succeeded";
// break;
// default:
// break;
// }
// if (notification) {
// notification->setComponentName("networkmanagement");
// notification->setTitle(watcher->property("connection").toString());
// notification->setIconName(QStringLiteral("dialog-information"));
// notification->sendEvent();
// }
// }
watcher->deleteLater();
}
void Handler::hotspotCreated(QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<QDBusObjectPath, QDBusObjectPath, QVariantMap> reply = *watcher;
if (!reply.isError() && reply.isValid()) {
const QString activeConnectionPath = reply.argumentAt(1).value<QDBusObjectPath>().path();
if (activeConnectionPath.isEmpty()) {
return;
}
Configuration::self().setHotspotConnectionPath(activeConnectionPath);
NetworkManager::ActiveConnection::Ptr hotspot = NetworkManager::findActiveConnection(activeConnectionPath);
if (!hotspot) {
return;
}
connect(hotspot.data(), &NetworkManager::ActiveConnection::stateChanged, [=] (NetworkManager::ActiveConnection::State state) {
if (state > NetworkManager::ActiveConnection::Activated) {
Configuration::self().setHotspotConnectionPath(QString());
Q_EMIT hotspotDisabled();
}
});
Q_EMIT hotspotCreated();
}
}
void Handler::primaryConnectionTypeChanged(NetworkManager::ConnectionSettings::ConnectionType type)
{
Q_UNUSED(type)
m_hotspotSupported = checkHotspotSupported();
Q_EMIT hotspotSupportedChanged(m_hotspotSupported);
}
#if WITH_MODEMMANAGER_SUPPORT
void Handler::unlockRequiredChanged(MMModemLock modemLock)
{
if (modemLock == MM_MODEM_LOCK_NONE) {
activateConnection(m_tmpConnectionPath, m_tmpDevicePath, m_tmpSpecificPath);
}
}
#endif

@ -0,0 +1,161 @@
/*
Copyright 2013-2014 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PLASMA_NM_HANDLER_H
#define PLASMA_NM_HANDLER_H
#include <QDBusInterface>
#include <QTimer>
#include <NetworkManagerQt/Connection>
#include <NetworkManagerQt/Settings>
#include <NetworkManagerQt/ConnectionSettings>
#include <NetworkManagerQt/Utils>
#if WITH_MODEMMANAGER_SUPPORT
#include <ModemManagerQt/GenericTypes>
#endif
class Q_DECL_EXPORT Handler : public QObject
{
Q_OBJECT
public:
enum HandlerAction {
ActivateConnection,
AddAndActivateConnection,
AddConnection,
DeactivateConnection,
RemoveConnection,
RequestScan,
UpdateConnection,
CreateHotspot,
};
explicit Handler(QObject* parent = nullptr);
~Handler() override;
Q_PROPERTY(bool hotspotSupported READ hotspotSupported NOTIFY hotspotSupportedChanged);
public:
bool hotspotSupported() const { return m_hotspotSupported; };
public Q_SLOTS:
/**
* Activates given connection
* @connection - d-bus path of the connection you want to activate
* @device - d-bus path of the device where the connection should be activated
* @specificParameter - d-bus path of the specific object you want to use for this activation, i.e access point
*/
void activateConnection(const QString &connection, const QString &device, const QString &specificParameter);
/**
* Adds and activates a new wireless connection
* @device - d-bus path of the wireless device where the connection should be activated
* @specificParameter - d-bus path of the accesspoint you want to connect to
* @password - pre-filled password which should be used for the new wireless connection
* @autoConnect - boolean value whether this connection should be activated automatically when it's available
*
* Works automatically for wireless connections with WEP/WPA security, for wireless connections with WPA/WPA
* it will open the connection editor for advanced configuration.
* */
void addAndActivateConnection(const QString &device, const QString &specificParameter, const QString &password = QString());
/**
* Returns a code that includes the credentials to a said wifi connection
* Here's some information on how this information is created, it's generally used to put in QR codes to share.
* https://github.com/zxing/zxing/wiki/Barcode-Contents#wi-fi-network-config-android-ios-11
*
* @param connectionPath the d-bus path to the connection we want to read
* @param ssid the name of the network being displayed
* @param securityType the authentication protocol used for this specific ssid
*/
QString wifiCode(const QString& connectionPath, const QString& ssid, /*NetworkManager::WirelessSecurityType*/ int securityType) const;
/**
* Adds a new connection
* @map - NMVariantMapMap with connection settings
*/
void addConnection(const NMVariantMapMap &map);
/**
* Deactivates given connection
* @connection - d-bus path of the connection you want to deactivate
* @device - d-bus path of the connection where the connection is activated
*/
void deactivateConnection(const QString &connection, const QString &device);
/**
* Disconnects all connections
*/
void disconnectAll();
void enableAirplaneMode(bool enable);
void enableNetworking(bool enable);
void enableWireless(bool enable);
void enableWwan(bool enable);
/**
* Removes given connection
* @connection - d-bus path of the connection you want to edit
*/
void removeConnection(const QString & connection);
/**
* Updates given connection
* @connection - connection which should be updated
* @map - NMVariantMapMap with new connection settings
*/
void updateConnection(const NetworkManager::Connection::Ptr &connection, const NMVariantMapMap &map);
void requestScan(const QString &interface = QString());
void createHotspot();
void stopHotspot();
private Q_SLOTS:
void secretAgentError(const QString &connectionPath, const QString &message);
void replyFinished(QDBusPendingCallWatcher *watcher);
void hotspotCreated(QDBusPendingCallWatcher *watcher);
void primaryConnectionTypeChanged(NetworkManager::ConnectionSettings::ConnectionType type);
#if WITH_MODEMMANAGER_SUPPORT
void unlockRequiredChanged(MMModemLock modemLock);
#endif
Q_SIGNALS:
void connectionActivationFailed(const QString &connectionPath, const QString &message);
void hotspotCreated();
void hotspotDisabled();
void hotspotSupportedChanged(bool hotspotSupported);
private:
QString m_userName;
bool m_hotspotSupported;
bool m_tmpWirelessEnabled;
bool m_tmpWwanEnabled;
#if WITH_MODEMMANAGER_SUPPORT
QString m_tmpConnectionPath;
#endif
QString m_tmpConnectionUuid;
QString m_tmpDevicePath;
QString m_tmpSpecificPath;
QMap<QString, bool> m_bluetoothAdapters;
QMap<QString, QTimer*> m_wirelessScanRetryTimer;
void enableBluetooth(bool enable);
void scanRequestFailed(const QString &interface);
bool checkRequestScanRateLimit(const NetworkManager::WirelessDevice::Ptr &wifiDevice);
bool checkHotspotSupported();
void scheduleRequestScan(const QString &interface, int timeout);
};
#endif // PLASMA_NM_HANDLER_H

@ -1,525 +0,0 @@
/*
Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
Copyright 2013-2014 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <NetworkManagerQt/ConnectionSettings>
#include <NetworkManagerQt/Manager>
#include <NetworkManagerQt/VpnSetting>
#include <NetworkManagerQt/Settings>
#include <QDBusConnectionInterface>
#if WITH_MODEMMANAGER_SUPPORT
# include <NetworkManagerQt/GsmSetting>
# include <NetworkManagerQt/ModemDevice>
# include <ModemManagerQt/ModemDevice>
#endif
#include "uiutils.h"
#include "networking.h"
#include "networkmodel.h"
#include <sys/types.h>
#include <pwd.h>
#include <QDebug>
Networking::Networking(QObject *parent)
: QObject(parent)
, m_lastWirelessEnabled(isWirelessEnabled())
, m_lastMobileEnabled(isMobileEnabled())
{
::passwd *pw = ::getpwuid(::getuid());
m_userName = QString::fromLocal8Bit(pw->pw_name);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged,
this, &Networking::enabledChanged);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged,
this, &Networking::wirelessEnabledChanged);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessHardwareEnabledChanged,
this, &Networking::wirelessHardwareEnabledChanged);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanEnabledChanged,
this, &Networking::mobileEnabledChanged);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanHardwareEnabledChanged,
this, &Networking::mobileHardwareEnabledChanged);
connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged,
this, &Networking::statusChanged);
doChangeActiveConnections();
statusChanged(NetworkManager::status());
}
bool Networking::isEnabled() const
{
return NetworkManager::isNetworkingEnabled();
}
void Networking::setEnabled(bool enabled)
{
NetworkManager::setNetworkingEnabled(enabled);
}
bool Networking::isWirelessEnabled() const
{
return NetworkManager::isWirelessEnabled();
}
void Networking::setWirelessEnabled(bool enabled)
{
NetworkManager::setWirelessEnabled(enabled);
}
bool Networking::isWirelessHardwareEnabled() const
{
return NetworkManager::isWirelessHardwareEnabled();
}
bool Networking::isMobileEnabled() const
{
return NetworkManager::isWwanEnabled();
}
void Networking::setMobileEnabled(bool enabled)
{
NetworkManager::setWwanEnabled(enabled);
}
bool Networking::isMobileHardwareEnabled() const
{
return NetworkManager::isWwanHardwareEnabled();
}
bool Networking::isAirplaneModeEnabled() const
{
return !isWirelessEnabled() && !isMobileEnabled();
}
void Networking::setAirplaneModeEnabled(bool enabled)
{
if (isAirplaneModeEnabled() == enabled)
return;
m_lastWirelessEnabled = isWirelessEnabled();
m_lastMobileEnabled = isMobileEnabled();
if (enabled) {
setWirelessEnabled(false);
setMobileEnabled(false);
} else {
if (m_lastWirelessEnabled)
setWirelessEnabled(true);
if (m_lastMobileEnabled)
setMobileEnabled(true);
}
Q_EMIT airplaneModeEnabledChanged();
}
QString Networking::activeConnections() const
{
return m_activeConnections;
}
QString Networking::networkStatus() const
{
return m_networkStatus;
}
void Networking::activateConnection(const QString &connectionPath, const QString &device, const QString &specificObject)
{
NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(connectionPath);
if (!connection) {
qCWarning(gLcNm, "Unable to activate connection \"%s\"", qPrintable(connectionPath));
return;
}
if (connection->settings()->connectionType() == NetworkManager::ConnectionSettings::Vpn) {
NetworkManager::VpnSetting::Ptr vpnSetting = connection->settings()->setting(NetworkManager::Setting::Vpn).staticCast<NetworkManager::VpnSetting>();
if (vpnSetting) {
qCDebug(gLcNm, "Checking VPN \"%s\" type \"%s\"", qPrintable(connection->name()), qPrintable(vpnSetting->serviceType()));
}
}
#if 0
#if WITH_MODEMMANAGER_SUPPORT
if (connection->settings()->connectionType() == NetworkManager::ConnectionSettings::Gsm) {
NetworkManager::ModemDevice::Ptr nmModemDevice = NetworkManager::findNetworkInterface(device).objectCast<NetworkManager::ModemDevice>();
if (nmModemDevice) {
ModemManager::ModemDevice::Ptr mmModemDevice = ModemManager::findModemDevice(nmModemDevice->udi());
if (mmModemDevice) {
ModemManager::Modem::Ptr modem = mmModemDevice->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>();
NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).staticCast<NetworkManager::GsmSetting>();
if (gsmSetting && gsmSetting->pinFlags() == NetworkManager::Setting::NotSaved &&
modem && modem->unlockRequired() > MM_MODEM_LOCK_NONE) {
QDBusInterface managerIface("org.kde.plasmanetworkmanagement", "/org/kde/plasmanetworkmanagement", "org.kde.plasmanetworkmanagement", QDBusConnection::sessionBus(), this);
managerIface.call("unlockModem", mmModemDevice->uni());
connect(modem.data(), &ModemManager::Modem::unlockRequiredChanged, this, &Handler::unlockRequiredChanged);
// m_tmpConnectionPath = connectionPath;
// m_tmpDevicePath = device;
// m_tmpSpecificPath = specificObject;
return;
}
}
}
}
#endif
#endif
QDBusPendingReply<QDBusObjectPath> reply = NetworkManager::activateConnection(connectionPath, device, specificObject);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("connectionName", connection->name());
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
QDBusPendingReply<> reply = *self;
if (reply.isError() || !reply.isValid()) {
const QString error = reply.error().message();
const QString connectionName = self->property("connectionName").toString();
}
self->deleteLater();
});
}
void Networking::addAndActivateConnection(const QString &device, const QString &specificObject, const QString &password)
{
NetworkManager::AccessPoint::Ptr ap;
NetworkManager::WirelessDevice::Ptr wifiDev;
for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) {
if (dev->type() == NetworkManager::Device::Wifi) {
wifiDev = dev.objectCast<NetworkManager::WirelessDevice>();
ap = wifiDev->findAccessPoint(specificObject);
if (ap)
break;
}
}
if (!ap)
return;
NetworkManager::ConnectionSettings::Ptr settings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless));
settings->setId(ap->ssid());
settings->setUuid(NetworkManager::ConnectionSettings::createNewUuid());
settings->setAutoconnect(true);
settings->addToPermissions(m_userName, QString());
NetworkManager::WirelessSetting::Ptr wifiSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>();
wifiSetting->setInitialized(true);
wifiSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast<NetworkManager::WirelessSetting>();
wifiSetting->setSsid(ap->ssid().toUtf8());
if (ap->mode() == NetworkManager::AccessPoint::Adhoc) {
wifiSetting->setMode(NetworkManager::WirelessSetting::Adhoc);
}
NetworkManager::WirelessSecuritySetting::Ptr wifiSecurity = settings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast<NetworkManager::WirelessSecuritySetting>();
NetworkManager::WirelessSecurityType securityType = NetworkManager::findBestWirelessSecurity(wifiDev->wirelessCapabilities(), true, (ap->mode() == NetworkManager::AccessPoint::Adhoc), ap->capabilities(), ap->wpaFlags(), ap->rsnFlags());
if (securityType != NetworkManager::NoneSecurity) {
wifiSecurity->setInitialized(true);
wifiSetting->setSecurity("802-11-wireless-security");
}
if (securityType == NetworkManager::Leap ||
securityType == NetworkManager::DynamicWep ||
securityType == NetworkManager::Wpa2Eap ||
securityType == NetworkManager::WpaEap) {
if (securityType == NetworkManager::DynamicWep || securityType == NetworkManager::Leap) {
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Ieee8021x);
if (securityType == NetworkManager::Leap)
wifiSecurity->setAuthAlg(NetworkManager::WirelessSecuritySetting::Leap);
} else {
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaEap);
}
// m_tmpConnectionUuid = settings->uuid();
// m_tmpDevicePath = device;
// m_tmpSpecificPath = specificObject;
// TODO: Edit connection?
} else {
if (securityType == NetworkManager::StaticWep) {
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Wep);
wifiSecurity->setWepKey0(password);
#if 0
if (KWallet::Wallet::isEnabled())
wifiSecurity->setWepKeyFlags(NetworkManager::Setting::AgentOwned);
#endif
} else {
if (ap->mode() == NetworkManager::AccessPoint::Adhoc)
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone);
else
wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk);
wifiSecurity->setPsk(password);
#if 0
if (KWallet::Wallet::isEnabled())
wifiSecurity->setPskFlags(NetworkManager::Setting::AgentOwned);
#endif
}
QDBusPendingReply<QDBusObjectPath> reply = NetworkManager::addAndActivateConnection(settings->toMap(), device, specificObject);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
watcher->setProperty("connectionName", settings->name());
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
QDBusPendingReply<> reply = *self;
if (reply.isError() || !reply.isValid()) {
const QString error = reply.error().message();
const QString connectionName = self->property("connectionName").toString();
}
self->deleteLater();
});
}
settings.clear();
}
void Networking::deactivateConnection(const QString &connectionName, const QString &device)
{
NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(connectionName);
if (!connection) {
qCWarning(gLcNm, "Failed to deactivate connection \"%s\"", qPrintable(connectionName));
return;
}
QDBusPendingReply<> reply;
for (const NetworkManager::ActiveConnection::Ptr &active : NetworkManager::activeConnections()) {
if (active->uuid() == connection->uuid() && ((!active->devices().isEmpty() && active->devices().first() == device) ||
active->vpn())) {
if (active->vpn()) {
reply = NetworkManager::deactivateConnection(active->path());
} else {
NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(active->devices().first());
if (device)
reply = device->disconnectInterface();
}
}
}
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
QDBusPendingReply<> reply = *self;
if (reply.isError() || !reply.isValid()) {
const QString error = reply.error().message();
const QString connectionName = self->property("connectionName").toString();
}
self->deleteLater();
});
}
void Networking::removeConnection(const QString &connectionPath)
{
NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connectionPath);
if (!con || con->uuid().isEmpty()) {
qCWarning(gLcNm) << "Not possible to remove connection " << connectionPath;
return;
}
// Remove slave connections
for (const NetworkManager::Connection::Ptr &connection : NetworkManager::listConnections()) {
NetworkManager::ConnectionSettings::Ptr settings = connection->settings();
if (settings->master() == con->uuid()) {
connection->remove();
}
}
QDBusPendingReply<> reply = con->remove();
// QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
// watcher->setProperty("action", Networking::RemoveConnection);
// watcher->setProperty("connection", con->name());
// connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher * watcher) {
// });
}
Networking::SortedConnectionType Networking::connectionTypeToSortedType(NetworkManager::ConnectionSettings::ConnectionType type)
{
switch (type) {
case NetworkManager::ConnectionSettings::Adsl:
return Networking::Adsl;
break;
case NetworkManager::ConnectionSettings::Bluetooth:
return Networking::Bluetooth;
break;
case NetworkManager::ConnectionSettings::Cdma:
return Networking::Cdma;
break;
case NetworkManager::ConnectionSettings::Gsm:
return Networking::Gsm;
break;
case NetworkManager::ConnectionSettings::Infiniband:
return Networking::Infiniband;
break;
case NetworkManager::ConnectionSettings::OLPCMesh:
return Networking::OLPCMesh;
break;
case NetworkManager::ConnectionSettings::Pppoe:
return Networking::Pppoe;
break;
case NetworkManager::ConnectionSettings::Vpn:
return Networking::Vpn;
break;
case NetworkManager::ConnectionSettings::Wired:
return Networking::Wired;
break;
case NetworkManager::ConnectionSettings::Wireless:
return Networking::Wireless;
break;
default:
return Networking::Other;
break;
}
}
void Networking::doChangeActiveConnections()
{
for (const NetworkManager::ActiveConnection::Ptr &active : NetworkManager::activeConnections()) {
connect(active.data(), &NetworkManager::ActiveConnection::default4Changed,
this, &Networking::defaultChanged,
Qt::UniqueConnection);
connect(active.data(), &NetworkManager::ActiveConnection::default6Changed,
this, &Networking::defaultChanged,
Qt::UniqueConnection);
connect(active.data(), &NetworkManager::ActiveConnection::stateChanged,
this, &Networking::changeActiveConnections);
}
changeActiveConnections();
}
QString Networking::checkUnknownReason() const
{
// Check if NetworkManager is running.
if (!QDBusConnection::systemBus().interface()->isServiceRegistered(QLatin1String(NM_DBUS_INTERFACE)))
return tr("NetworkManager not running");
// Check for compatible NetworkManager version.
if (NetworkManager::compareVersion(0, 9, 8) < 0)
return tr("NetworkManager 0.9.8 required, found %1").arg(NetworkManager::version());
return tr("Unknown");
}
void Networking::statusChanged(NetworkManager::Status status)
{
switch (status) {
case NetworkManager::ConnectedLinkLocal:
case NetworkManager::ConnectedSiteOnly:
case NetworkManager::Connected:
m_networkStatus = tr("Connected");
break;
case NetworkManager::Asleep:
m_networkStatus = tr("Inactive");
break;
case NetworkManager::Disconnected:
m_networkStatus = tr("Disconnected");
break;
case NetworkManager::Disconnecting:
m_networkStatus = tr("Disconnecting");
break;
case NetworkManager::Connecting:
m_networkStatus = tr("Connecting");
break;
default:
m_networkStatus = checkUnknownReason();
break;
}
if (status == NetworkManager::ConnectedLinkLocal ||
status == NetworkManager::ConnectedSiteOnly ||
status == NetworkManager::Connected) {
changeActiveConnections();
} else {
m_activeConnections = m_networkStatus;
Q_EMIT activeConnectionsChanged();
}
Q_EMIT networkStatusChanged();
}
void Networking::changeActiveConnections()
{
if (NetworkManager::status() != NetworkManager::Connected &&
NetworkManager::status() != NetworkManager::ConnectedLinkLocal &&
NetworkManager::status() != NetworkManager::ConnectedSiteOnly)
return;
QString activeConnections;
const QString format = tr("%1: %2");
QList<NetworkManager::ActiveConnection::Ptr> activeConnectionList = NetworkManager::activeConnections();
std::sort(activeConnectionList.begin(), activeConnectionList.end(), [](const NetworkManager::ActiveConnection::Ptr &left, const NetworkManager::ActiveConnection::Ptr &right) {
return Networking::connectionTypeToSortedType(left->type()) < Networking::connectionTypeToSortedType(right->type());
});
for (const NetworkManager::ActiveConnection::Ptr &active : activeConnectionList) {
if (!active->devices().isEmpty() && UiUtils::isConnectionTypeSupported(active->type())) {
NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(active->devices().first());
if (device && device->type() != NetworkManager::Device::Generic && device->type() <= NetworkManager::Device::Team) {
bool connecting = false;
bool connected = false;
QString conType;
QString status;
NetworkManager::VpnConnection::Ptr vpnConnection;
if (active->vpn()) {
conType = tr("VPN");
vpnConnection = active.objectCast<NetworkManager::VpnConnection>();
} else {
conType = UiUtils::interfaceTypeLabel(device->type(), device);
}
if (vpnConnection && active->vpn()) {
if (vpnConnection->state() >= NetworkManager::VpnConnection::Prepare &&
vpnConnection->state() <= NetworkManager::VpnConnection::GettingIpConfig)
connecting = true;
else if (vpnConnection->state() == NetworkManager::VpnConnection::Activated)
connected = true;
} else {
if (active->state() == NetworkManager::ActiveConnection::Activated)
connected = true;
else if (active->state() == NetworkManager::ActiveConnection::Activating)
connecting = true;
}
NetworkManager::Connection::Ptr connection = active->connection();
if (connecting) {
status = tr("Connecting to %1").arg(connection->name());
} else if (connected) {
status = tr("Connected to %1").arg(connection->name());
}
if (!activeConnections.isEmpty())
activeConnections += QLatin1Char('\n');
activeConnections += format.arg(conType, status);
connect(connection.data(), &NetworkManager::Connection::updated,
this, &Networking::changeActiveConnections,
Qt::UniqueConnection);
}
}
}
m_activeConnections = activeConnections;
Q_EMIT activeConnectionsChanged();
}
void Networking::defaultChanged()
{
statusChanged(NetworkManager::status());
}

@ -1,122 +0,0 @@
/*
Copyright (C) 2019 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
Copyright 2013-2014 Jan Grulich <jgrulich@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NETWORKING_H
#define NETWORKING_H
#include <networkmanager_export.h>
#include <QObject>
#include <NetworkManagerQt/Device>
#include <NetworkManagerQt/Manager>
class NETWORKMANAGER_EXPORT Networking : public QObject
{
Q_OBJECT
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool wirelessEnabled READ isWirelessEnabled WRITE setWirelessEnabled NOTIFY wirelessEnabledChanged)
Q_PROPERTY(bool wirelessHardwareEnabled READ isWirelessHardwareEnabled NOTIFY wirelessHardwareEnabledChanged)
Q_PROPERTY(bool mobileEnabled READ isMobileEnabled WRITE setMobileEnabled NOTIFY mobileEnabledChanged)
Q_PROPERTY(bool mobileHardwareEnabled READ isMobileHardwareEnabled NOTIFY mobileHardwareEnabledChanged)
Q_PROPERTY(bool airplaneModeEnabled READ isAirplaneModeEnabled WRITE setAirplaneModeEnabled NOTIFY airplaneModeEnabledChanged)
Q_PROPERTY(QString activeConnections READ activeConnections NOTIFY activeConnectionsChanged)
Q_PROPERTY(QString networkStatus READ networkStatus NOTIFY networkStatusChanged)
public:
enum SortedConnectionType {
Wired,
Wireless,
Gsm,
Cdma,
Pppoe,
Adsl,
Infiniband,
OLPCMesh,
Bluetooth,
Vpn,
Other
};
Q_ENUM(SortedConnectionType)
enum HandlerAction {
ActivateConnection,
AddAndActivateConnection,
AddConnection,
DeactivateConnection,
RemoveConnection,
RequestScan,
UpdateConnection,
CreateHotspot,
};
Q_ENUM(HandlerAction)
explicit Networking(QObject *parent = nullptr);
bool isEnabled() const;
void setEnabled(bool enabled);
bool isWirelessEnabled() const;
void setWirelessEnabled(bool enabled);
bool isWirelessHardwareEnabled() const;
bool isMobileEnabled() const;
void setMobileEnabled(bool enabled);
bool isMobileHardwareEnabled() const;
bool isAirplaneModeEnabled() const;
void setAirplaneModeEnabled(bool enabled);
QString activeConnections() const;
QString networkStatus() const;
Q_INVOKABLE void activateConnection(const QString &connectionPath, const QString &device, const QString &specificObject);
Q_INVOKABLE void addAndActivateConnection(const QString &device, const QString &specificObject, const QString &password = QString());
Q_INVOKABLE void deactivateConnection(const QString &connectionName, const QString &device);
Q_INVOKABLE void removeConnection(const QString &connectionPath);
static SortedConnectionType connectionTypeToSortedType(NetworkManager::ConnectionSettings::ConnectionType type);
Q_SIGNALS:
void enabledChanged();
void wirelessEnabledChanged();
void wirelessHardwareEnabledChanged();
void mobileEnabledChanged();
void mobileHardwareEnabledChanged();
void airplaneModeEnabledChanged();
void activeConnectionsChanged();
void networkStatusChanged();
private:
bool m_lastWirelessEnabled = false;
bool m_lastMobileEnabled = false;
QString m_userName;
QString m_activeConnections;
QString m_networkStatus;
void doChangeActiveConnections();
QString checkUnknownReason() const;
private Q_SLOTS:
void statusChanged(NetworkManager::Status status);
void changeActiveConnections();
void defaultChanged();
};
#endif // NETWORKING_H

@ -1,5 +1,4 @@
#include "qmlplugins.h"
#include "networking.h"
#include "networkmodel.h"
#include "networkmodelitem.h"
#include "appletproxymodel.h"
@ -8,6 +7,10 @@
#include "connectionicon.h"
#include "network.h"
#include "identitymodel.h"
#include "handler.h"
#include "enabledconnections.h"
#include "enums.h"
#include "wifisettings.h"
#include <QQmlEngine>
@ -16,11 +19,14 @@ void QmlPlugins::registerTypes(const char* uri)
qmlRegisterUncreatableType<NetworkModelItem>(uri, 1, 0, "NetworkModelItem",
QLatin1String("Cannot instantiate NetworkModelItem"));
qmlRegisterType<AppletProxyModel>(uri, 1, 0, "AppletProxyModel");
qmlRegisterType<Networking>(uri, 1, 0, "Networking");
qmlRegisterType<NetworkModel>(uri, 1, 0, "NetworkModel");
qmlRegisterType<TechnologyProxyModel>(uri, 1, 0, "TechnologyProxyModel");
qmlRegisterType<WirelessItemSettings>(uri, 1, 0, "WirelessItemSettings");
qmlRegisterType<ConnectionIcon>(uri, 1, 0, "ConnectionIcon");
qmlRegisterType<Network>(uri, 1, 0, "Network");
qmlRegisterType<IdentityModel>(uri, 1, 0, "IdentityModel");
qmlRegisterType<Handler>(uri, 1, 0, "Handler");
qmlRegisterType<EnabledConnections>(uri, 1, 0, "EnabledConnections");
qmlRegisterType<WifiSettings>(uri, 1, 0, "WifiSettings");
qmlRegisterUncreatableType<Enums>(uri, 1, 0, "Enums", "You cannot create Enums on yourself");
}

@ -0,0 +1,290 @@
/*
* Copyright 2018 Martin Kacej <m.kacej@atlas.sk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 or
* (at your option) any later version.
*
* This program 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 Library General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "wifisettings.h"
#include <NetworkManagerQt/ActiveConnection>
#include <NetworkManagerQt/AccessPoint>
#include <NetworkManagerQt/Connection>
#include <NetworkManagerQt/ConnectionSettings>
#include <NetworkManagerQt/GsmSetting>
#include <NetworkManagerQt/Ipv4Setting>
#include <NetworkManagerQt/Manager>
#include <NetworkManagerQt/Settings>
#include <NetworkManagerQt/Utils>
#include <NetworkManagerQt/WiredDevice>
#include <NetworkManagerQt/WiredSetting>
#include <NetworkManagerQt/WirelessDevice>
#include <NetworkManagerQt/WirelessSetting>
WifiSettings::WifiSettings(QObject* parent) : QObject(parent)
{
}
WifiSettings::~WifiSettings()
{
}
QVariantMap WifiSettings::getConnectionSettings(const QString &connection, const QString &type)
{
if (type.isEmpty())
return QVariantMap();
NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection);
if (!con)
return QVariantMap();
if (type == "secrets")
return con->secrets(QLatin1String("802-11-wireless-security")).value().value(QLatin1String("802-11-wireless-security"));
QVariantMap map = con->settings()->toMap().value(type);
if (type == "ipv4") {
NetworkManager::Ipv4Setting::Ptr ipSettings = NetworkManager::Ipv4Setting::Ptr(new NetworkManager::Ipv4Setting());
ipSettings->fromMap(map);
map.clear();
if (ipSettings->method() == NetworkManager::Ipv4Setting::Automatic) {
map.insert(QLatin1String("method"),QVariant(QLatin1String("auto")));
}
if (ipSettings->method() == NetworkManager::Ipv4Setting::Manual) {
map.insert(QLatin1String("method"),QVariant(QLatin1String("manual")));
map.insert(QLatin1String("address"),QVariant(ipSettings->addresses().first().ip().toString()));
map.insert(QLatin1String("prefix"),QVariant(ipSettings->addresses().first().prefixLength()));
map.insert(QLatin1String("gateway"),QVariant(ipSettings->addresses().first().gateway().toString()));
map.insert(QLatin1String("dns"),QVariant(ipSettings->dns().first().toString()));
}
}
return map;
}
QVariantMap WifiSettings::getActiveConnectionInfo(const QString &connection)
{
if (connection.isEmpty())
return QVariantMap();
NetworkManager::ActiveConnection::Ptr activeCon;
NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection);
foreach (const NetworkManager::ActiveConnection::Ptr &active, NetworkManager::activeConnections()) {
if (active->uuid() == con->uuid())
activeCon = active;
}
if (!activeCon) {
qWarning() << "Active" << connection << "not found";
return QVariantMap();
}
QVariantMap map;
if (activeCon->ipV4Config().addresses().count() > 0) {
map.insert("address",QVariant(activeCon->ipV4Config().addresses().first().ip().toString()));
map.insert("prefix",QVariant(activeCon->ipV4Config().addresses().first().netmask().toString()));
}
map.insert("gateway",QVariant(activeCon->ipV4Config().gateway()));
if (activeCon->ipV4Config().nameservers().count() > 0)
map.insert("dns",QVariant(activeCon->ipV4Config().nameservers().first().toString()));
//qWarning() << map;
return map;
}
void WifiSettings::addConnectionFromQML(const QVariantMap &QMLmap)
{
if (QMLmap.isEmpty())
return;
NetworkManager::ConnectionSettings::Ptr connectionSettings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless));
connectionSettings->setId(QMLmap.value(QLatin1String("id")).toString());
connectionSettings->setUuid(NetworkManager::ConnectionSettings::createNewUuid());
NetworkManager::WirelessSetting::Ptr wirelessSettings = NetworkManager::WirelessSetting::Ptr(new NetworkManager::WirelessSetting());
wirelessSettings->setSsid(QMLmap.value(QLatin1String("id")).toString().toUtf8());
if (QMLmap["mode"].toString() == "infrastructure") {
wirelessSettings->setMode(NetworkManager::WirelessSetting::Infrastructure);
connectionSettings->setAutoconnect(true);
}
if (QMLmap["mode"].toString() == "ap") {
wirelessSettings->setMode(NetworkManager::WirelessSetting::Ap);
connectionSettings->setAutoconnect(false);
}
if (QMLmap.contains("hidden")) {
wirelessSettings->setHidden(QMLmap.value("hidden").toBool());
}
NetworkManager::Ipv4Setting::Ptr ipSettings = NetworkManager::Ipv4Setting::Ptr(new NetworkManager::Ipv4Setting());
if (QMLmap["method"] == QLatin1String("auto")) {
ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Automatic);
}
if (QMLmap["method"] == QLatin1String("shared")) {
ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Shared);
}
if (QMLmap["method"] == QLatin1String("manual")) {
ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Manual);
NetworkManager::IpAddress ipaddr;
ipaddr.setIp(QHostAddress(QMLmap["address"].toString()));
ipaddr.setPrefixLength(QMLmap["prefix"].toInt());
ipaddr.setGateway(QHostAddress(QMLmap["gateway"].toString()));
ipSettings->setAddresses(QList<NetworkManager::IpAddress>({ipaddr}));
ipSettings->setDns(QList<QHostAddress>({QHostAddress(QMLmap["dns"].toString())}));
}
NMVariantMapMap map = connectionSettings->toMap();
map.insert("802-11-wireless",wirelessSettings->toMap());
map.insert("ipv4",ipSettings->toMap());
// TODO can't set password for AP
// needs further inspection
if (QMLmap.contains("802-11-wireless-security")) {
QVariantMap securMap = QMLmap["802-11-wireless-security"].toMap();
int type = securMap["type"].toInt();
if (!type == NetworkManager::NoneSecurity) {
NetworkManager::WirelessSecuritySetting::Ptr securitySettings = NetworkManager::WirelessSecuritySetting::Ptr(new NetworkManager::WirelessSecuritySetting());
if (type == NetworkManager::Wpa2Psk ) {
if (QMLmap["mode"].toString() == "ap") {
securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::WpaNone);
} else {
securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::WpaPsk);
}
securitySettings->setAuthAlg(NetworkManager::WirelessSecuritySetting::AuthAlg::Open);
securitySettings->setPskFlags(NetworkManager::Setting::SecretFlagType::AgentOwned);
securitySettings->setPsk(securMap["password"].toString());
}
if (type == NetworkManager::StaticWep) {
securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::Wep);
securitySettings->setAuthAlg(NetworkManager::WirelessSecuritySetting::AuthAlg::Open);
securitySettings->setWepKeyType(NetworkManager::WirelessSecuritySetting::WepKeyType::Hex);
securitySettings->setWepKeyFlags(NetworkManager::Setting::SecretFlagType::AgentOwned);
securitySettings->setWepKey0(securMap["password"].toString());
}
map.insert("802-11-wireless-security",securitySettings->toMap());
}
}
//qWarning() << map;
NetworkManager::addConnection(map);
}
void WifiSettings::updateConnectionFromQML(const QString &path, const QVariantMap &map)
{
NetworkManager::Connection::Ptr con = NetworkManager::findConnection(path);
if (!con)
return;
//qWarning() << map;
if (map.contains("id"))
con->settings()->setId(map.value("id").toString());
NMVariantMapMap toUpdateMap = con->settings()->toMap();
NetworkManager::Ipv4Setting::Ptr ipSetting = con->settings()->setting(NetworkManager::Setting::Ipv4).staticCast<NetworkManager::Ipv4Setting>();
if (ipSetting->method() == NetworkManager::Ipv4Setting::Automatic || ipSetting->method() == NetworkManager::Ipv4Setting::Manual) {
if (map.value("method") == "auto") {
ipSetting->setMethod(NetworkManager::Ipv4Setting::Automatic);
}
if (map.value("method") == "manual") {
ipSetting->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Manual);
NetworkManager::IpAddress ipaddr;
ipaddr.setIp(QHostAddress(map["address"].toString()));
ipaddr.setPrefixLength(map["prefix"].toInt());
ipaddr.setGateway(QHostAddress(map["gateway"].toString()));
ipSetting->setAddresses(QList<NetworkManager::IpAddress>({ipaddr}));
ipSetting->setDns(QList<QHostAddress>({QHostAddress(map["dns"].toString())}));
}
toUpdateMap.insert("ipv4",ipSetting->toMap());
}
NetworkManager::WirelessSetting::Ptr wirelessSetting = con->settings()->setting(NetworkManager::Setting::Wireless).staticCast<NetworkManager::WirelessSetting>();
if (map.contains("hidden")) {
wirelessSetting->setHidden(map.value("hidden").toBool());
}
if (map.contains("id")) {
wirelessSetting->setSsid(map.value("id").toByteArray());
}
toUpdateMap.insert("802-11-wireless",wirelessSetting->toMap());
if (map.contains("802-11-wireless-security")) {
QVariantMap secMap = map.value("802-11-wireless-security").toMap();
//qWarning() << secMap;
NetworkManager::WirelessSecuritySetting::Ptr securitySetting = con->settings()->setting(NetworkManager::Setting::WirelessSecurity).staticCast<NetworkManager::WirelessSecuritySetting>();
if ((securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::Wep)
&& (secMap.value("type") == NetworkManager::StaticWep))
{
securitySetting->setWepKey0(secMap["password"].toString());
}
if ((securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WpaPsk)
&& (secMap.value("type") == NetworkManager::Wpa2Psk))
{
securitySetting->setPsk(secMap["password"].toString());
}
// TODO can't set password for AP
// needs further inspection
if (wirelessSetting->mode() == NetworkManager::WirelessSetting::Ap) {
if (securitySetting->toMap().empty()) { //no security
if (secMap.value("type") == NetworkManager::Wpa2Psk) {
securitySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone);
securitySetting->setPsk(secMap.value("password").toString());
}
}
if (securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WpaNone) {
if (secMap.empty()) {
securitySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Unknown);
}
if (secMap.value("type") == NetworkManager::Wpa2Psk) {
securitySetting->setPsk(secMap.value("password").toString());
}
}
}
toUpdateMap.insert("802-11-wireless-security",securitySetting->toMap());
}
qWarning() << toUpdateMap;
con->update(toUpdateMap);
}
QString WifiSettings::getAccessPointDevice()
{
NetworkManager::WirelessDevice::Ptr device;
foreach (const NetworkManager::Device::Ptr &dev, NetworkManager::networkInterfaces()) {
if (dev->type() == NetworkManager::Device::Wifi){
device = dev.staticCast<NetworkManager::WirelessDevice>();
if (device->wirelessCapabilities().testFlag(NetworkManager::WirelessDevice::ApCap))
break; // we have wireless device with access point capability
}
}
if (device) {
return device->uni();
} else {
qWarning() << "No wireless device found";
}
return QString();
}
QString WifiSettings::getAccessPointConnection()
{
foreach (const NetworkManager::Connection::Ptr &con, NetworkManager::listConnections()) {
NetworkManager::Setting::Ptr d = con->settings()->setting(NetworkManager::Setting::Wireless);
if (!d.isNull()){
if( d.staticCast<NetworkManager::WirelessSetting>()->mode() == NetworkManager::WirelessSetting::Ap){
return con->path();
}
}
}
return QString();
}

@ -0,0 +1,40 @@
/*
* Copyright 2018 Martin Kacej <m.kacej@atlas.sk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 or
* (at your option) any later version.
*
* This program 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 Library General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef WIFISETTINGS_H
#define WIFISETTINGS_H
#include <QObject>
class WifiSettings : public QObject
{
Q_OBJECT
public:
WifiSettings(QObject *parent = nullptr);
Q_INVOKABLE QVariantMap getConnectionSettings(const QString &connection, const QString &type);
Q_INVOKABLE QVariantMap getActiveConnectionInfo(const QString &connection);
Q_INVOKABLE void addConnectionFromQML(const QVariantMap &QMLmap);
Q_INVOKABLE void updateConnectionFromQML(const QString &path, const QVariantMap &map);
Q_INVOKABLE QString getAccessPointDevice();
Q_INVOKABLE QString getAccessPointConnection();
virtual ~WifiSettings();
};
#endif // WIFISETTINGS_H
Loading…
Cancel
Save