Warning, file /plasma/plasma-nm/libs/declarative/networkstatus.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2013 Jan Grulich <jgrulich@redhat.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "networkstatus.h"
0008 #include "uiutils.h"
0009 
0010 #include <QDBusConnection>
0011 #include <QDBusConnectionInterface>
0012 
0013 #include <NetworkManagerQt/ActiveConnection>
0014 #include <NetworkManagerQt/Connection>
0015 
0016 #include <KLocalizedString>
0017 
0018 NetworkStatus::SortedConnectionType NetworkStatus::connectionTypeToSortedType(NetworkManager::ConnectionSettings::ConnectionType type)
0019 {
0020     switch (type) {
0021     case NetworkManager::ConnectionSettings::Adsl:
0022         return NetworkStatus::NetworkStatus::Adsl;
0023         break;
0024     case NetworkManager::ConnectionSettings::Bluetooth:
0025         return NetworkStatus::Bluetooth;
0026         break;
0027     case NetworkManager::ConnectionSettings::Cdma:
0028         return NetworkStatus::Cdma;
0029         break;
0030     case NetworkManager::ConnectionSettings::Gsm:
0031         return NetworkStatus::Gsm;
0032         break;
0033     case NetworkManager::ConnectionSettings::Infiniband:
0034         return NetworkStatus::Infiniband;
0035         break;
0036     case NetworkManager::ConnectionSettings::OLPCMesh:
0037         return NetworkStatus::OLPCMesh;
0038         break;
0039     case NetworkManager::ConnectionSettings::Pppoe:
0040         return NetworkStatus::Pppoe;
0041         break;
0042     case NetworkManager::ConnectionSettings::Vpn:
0043         return NetworkStatus::Vpn;
0044         break;
0045     case NetworkManager::ConnectionSettings::Wired:
0046         return NetworkStatus::Wired;
0047         break;
0048     case NetworkManager::ConnectionSettings::Wireless:
0049         return NetworkStatus::Wireless;
0050         break;
0051     case NetworkManager::ConnectionSettings::WireGuard:
0052         return NetworkStatus::Wireguard;
0053         break;
0054     default:
0055         return NetworkStatus::Other;
0056         break;
0057     }
0058 }
0059 
0060 NetworkStatus::NetworkStatus(QObject *parent)
0061     : QObject(parent)
0062 {
0063     connect(NetworkManager::notifier(), &NetworkManager::Notifier::connectivityChanged, this, &NetworkStatus::changeActiveConnections);
0064     connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged, this, &NetworkStatus::statusChanged);
0065     connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionsChanged, this, QOverload<>::of(&NetworkStatus::activeConnectionsChanged));
0066 
0067     activeConnectionsChanged();
0068     statusChanged(NetworkManager::status());
0069 }
0070 
0071 NetworkStatus::~NetworkStatus() = default;
0072 
0073 QString NetworkStatus::activeConnections() const
0074 {
0075     return m_activeConnections;
0076 }
0077 
0078 QString NetworkStatus::networkStatus() const
0079 {
0080     return m_networkStatus;
0081 }
0082 
0083 void NetworkStatus::activeConnectionsChanged()
0084 {
0085     for (const NetworkManager::ActiveConnection::Ptr &active : NetworkManager::activeConnections()) {
0086         connect(active.data(), &NetworkManager::ActiveConnection::default4Changed, this, &NetworkStatus::defaultChanged, Qt::UniqueConnection);
0087         connect(active.data(), &NetworkManager::ActiveConnection::default6Changed, this, &NetworkStatus::defaultChanged, Qt::UniqueConnection);
0088         connect(active.data(), &NetworkManager::ActiveConnection::stateChanged, this, &NetworkStatus::changeActiveConnections);
0089     }
0090 
0091     changeActiveConnections();
0092 }
0093 
0094 void NetworkStatus::defaultChanged()
0095 {
0096     statusChanged(NetworkManager::status());
0097 }
0098 
0099 void NetworkStatus::statusChanged(NetworkManager::Status status)
0100 {
0101     const auto oldNetworkStatus = m_networkStatus;
0102     switch (status) {
0103     case NetworkManager::ConnectedLinkLocal:
0104         m_networkStatus = i18nc("A network device is connected, but there is only link-local connectivity", "Connected");
0105         break;
0106     case NetworkManager::ConnectedSiteOnly:
0107         m_networkStatus = i18nc("A network device is connected, but there is only site-local connectivity", "Connected");
0108         break;
0109     case NetworkManager::Connected:
0110         m_networkStatus = i18nc("A network device is connected, with global network connectivity", "Connected");
0111         break;
0112     case NetworkManager::Asleep:
0113         m_networkStatus = i18nc("Networking is inactive and all devices are disabled", "Inactive");
0114         break;
0115     case NetworkManager::Disconnected:
0116         m_networkStatus = i18nc("There is no active network connection", "Disconnected");
0117         break;
0118     case NetworkManager::Disconnecting:
0119         m_networkStatus = i18nc("Network connections are being cleaned up", "Disconnecting");
0120         break;
0121     case NetworkManager::Connecting:
0122         m_networkStatus = i18nc("A network device is connecting to a network and there is no other available network connection", "Connecting");
0123         break;
0124     default:
0125         m_networkStatus = checkUnknownReason();
0126         break;
0127     }
0128 
0129     if (status == NetworkManager::ConnectedLinkLocal || status == NetworkManager::ConnectedSiteOnly || status == NetworkManager::Connected) {
0130         changeActiveConnections();
0131     } else if (m_activeConnections != m_networkStatus) {
0132         m_activeConnections = m_networkStatus;
0133         Q_EMIT activeConnectionsChanged(m_activeConnections);
0134     }
0135 
0136     if (oldNetworkStatus != m_networkStatus) {
0137         Q_EMIT networkStatusChanged(m_networkStatus);
0138     }
0139 }
0140 
0141 void NetworkStatus::changeActiveConnections()
0142 {
0143     if (NetworkManager::status() != NetworkManager::Connected && NetworkManager::status() != NetworkManager::ConnectedLinkLocal
0144         && NetworkManager::status() != NetworkManager::ConnectedSiteOnly) {
0145         return;
0146     }
0147 
0148     QString activeConnections;
0149     const QString format = QStringLiteral("%1: %2");
0150 
0151     QList<NetworkManager::ActiveConnection::Ptr> activeConnectionList = NetworkManager::activeConnections();
0152     std::sort(activeConnectionList.begin(),
0153               activeConnectionList.end(),
0154               [](const NetworkManager::ActiveConnection::Ptr &left, const NetworkManager::ActiveConnection::Ptr &right) {
0155                   return NetworkStatus::connectionTypeToSortedType(left->type()) < NetworkStatus::connectionTypeToSortedType(right->type());
0156               });
0157 
0158     for (const NetworkManager::ActiveConnection::Ptr &active : activeConnectionList) {
0159         if (!active->devices().isEmpty() && UiUtils::isConnectionTypeSupported(active->type())) {
0160             NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(active->devices().first());
0161             if (device
0162                 && ((device->type() != NetworkManager::Device::Generic && device->type() <= NetworkManager::Device::Team)
0163                     || device->type() == 29) // TODO: Change to WireGuard enum value when it is added
0164                 && device->interfaceName() != QLatin1String("lo")) { // TODO change to comparison with LocalHost enum value when it is added
0165                 bool connecting = false;
0166                 bool connected = false;
0167                 QString conType;
0168                 QString status;
0169                 NetworkManager::VpnConnection::Ptr vpnConnection;
0170 
0171                 if (active->vpn()) {
0172                     conType = i18n("VPN");
0173                     vpnConnection = active.objectCast<NetworkManager::VpnConnection>();
0174                 } else {
0175                     conType = UiUtils::interfaceTypeLabel(device->type(), device);
0176                 }
0177 
0178                 if (vpnConnection && active->vpn()) {
0179                     if (vpnConnection->state() >= NetworkManager::VpnConnection::Prepare
0180                         && vpnConnection->state() <= NetworkManager::VpnConnection::GettingIpConfig) {
0181                         connecting = true;
0182                     } else if (vpnConnection->state() == NetworkManager::VpnConnection::Activated) {
0183                         connected = true;
0184                     }
0185                 } else {
0186                     if (active->state() == NetworkManager::ActiveConnection::Activated) {
0187                         connected = true;
0188                     } else if (active->state() == NetworkManager::ActiveConnection::Activating) {
0189                         connecting = true;
0190                     }
0191                 }
0192 
0193                 if (active->type() == NetworkManager::ConnectionSettings::ConnectionType::WireGuard) {
0194                     conType = i18n("WireGuard");
0195                     connected = true;
0196                 }
0197 
0198                 NetworkManager::Connection::Ptr connection = active->connection();
0199                 if (connecting) {
0200                     status = i18n("Connecting to %1", connection->name());
0201                 } else if (connected) {
0202                     switch (NetworkManager::connectivity()) {
0203                     case NetworkManager::NoConnectivity:
0204                         status = i18n("Connected to %1 (no connectivity)", connection->name());
0205                         break;
0206                     case NetworkManager::Limited:
0207                         status = i18n("Connected to %1 (limited connectivity)", connection->name());
0208                         break;
0209                     case NetworkManager::Portal:
0210                         status = i18n("Connected to %1 (log in required)", connection->name());
0211                         break;
0212                     default:
0213                         status = i18n("Connected to %1", connection->name());
0214                         break;
0215                     }
0216                 }
0217 
0218                 if (!activeConnections.isEmpty()) {
0219                     activeConnections += QLatin1Char('\n');
0220                 }
0221                 activeConnections += format.arg(conType, status);
0222 
0223                 connect(connection.data(), &NetworkManager::Connection::updated, this, &NetworkStatus::changeActiveConnections, Qt::UniqueConnection);
0224             }
0225         }
0226     }
0227 
0228     if (m_activeConnections != activeConnections) {
0229         m_activeConnections = activeConnections;
0230         Q_EMIT activeConnectionsChanged(activeConnections);
0231     }
0232 }
0233 
0234 QString NetworkStatus::checkUnknownReason() const
0235 {
0236     // Check if NetworkManager is running.
0237     if (!QDBusConnection::systemBus().interface()->isServiceRegistered(QStringLiteral(NM_DBUS_INTERFACE))) {
0238         return i18n("NetworkManager not running");
0239     }
0240 
0241     // Check for compatible NetworkManager version.
0242     if (NetworkManager::compareVersion(0, 9, 8) < 0) {
0243         return i18n("NetworkManager 0.9.8 required, found %1.", NetworkManager::version());
0244     }
0245 
0246     return i18nc("global connection state", "Unknown");
0247 }