File indexing completed on 2024-04-21 04:00:09

0001 /*
0002     SPDX-FileCopyrightText: 2011 Ilia Kats <ilia-kats@gmx.net>
0003     SPDX-FileCopyrightText: 2013 Daniel Nicoletti <dantti12@gmail.com>
0004     SPDX-FileCopyrightText: 2013 Jan Grulich <jgrulich@redhat.com>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "activeconnection.h"
0010 #include "activeconnection_p.h"
0011 #include "device.h"
0012 #include "manager.h"
0013 #include "nmdebug.h"
0014 #include "settings.h"
0015 
0016 #include <QDBusObjectPath>
0017 
0018 #include "manager_p.h"
0019 
0020 NetworkManager::ActiveConnectionPrivate::ActiveConnectionPrivate(const QString &dbusPath, ActiveConnection *q)
0021 #ifdef NMQT_STATIC
0022     : iface(NetworkManagerPrivate::DBUS_SERVICE, dbusPath, QDBusConnection::sessionBus())
0023 #else
0024     : iface(NetworkManagerPrivate::DBUS_SERVICE, dbusPath, QDBusConnection::systemBus())
0025 #endif
0026     , dhcp4Config(nullptr)
0027     , dhcp6Config(nullptr)
0028     , state(ActiveConnection::Unknown)
0029     , q_ptr(q)
0030 {
0031     path = dbusPath;
0032 }
0033 
0034 NetworkManager::ActiveConnectionPrivate::~ActiveConnectionPrivate()
0035 {
0036 }
0037 
0038 NetworkManager::ActiveConnection::State NetworkManager::ActiveConnectionPrivate::convertActiveConnectionState(uint state)
0039 {
0040     return (NetworkManager::ActiveConnection::State)state;
0041 }
0042 
0043 NetworkManager::ActiveConnection::Reason NetworkManager::ActiveConnectionPrivate::convertActiveConnectionReason(uint reason)
0044 {
0045     return (NetworkManager::ActiveConnection::Reason)reason;
0046 }
0047 
0048 NetworkManager::ActiveConnection::ActiveConnection(const QString &path, QObject *parent)
0049     : QObject(parent)
0050     , d_ptr(new ActiveConnectionPrivate(path, this))
0051 {
0052     Q_D(ActiveConnection);
0053 
0054 #ifndef NMQT_STATIC
0055     QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
0056                                          d->path,
0057                                          NetworkManagerPrivate::FDO_DBUS_PROPERTIES,
0058                                          QLatin1String("PropertiesChanged"),
0059                                          d,
0060                                          SLOT(dbusPropertiesChanged(QString, QVariantMap, QStringList)));
0061     QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
0062                                          d->path,
0063                                          d->iface.staticInterfaceName(),
0064                                          QLatin1String("StateChanged"),
0065                                          d,
0066                                          SLOT(stateChanged(uint, uint)));
0067 #endif
0068 
0069 #ifdef NMQT_STATIC
0070     connect(&d->iface, &OrgFreedesktopNetworkManagerConnectionActiveInterface::PropertiesChanged, d, &ActiveConnectionPrivate::propertiesChanged);
0071     connect(&d->iface, &OrgFreedesktopNetworkManagerConnectionActiveInterface::StateChanged, d, &ActiveConnectionPrivate::stateChanged);
0072 #endif
0073 
0074     // Get all ActiveConnection's at once
0075     QVariantMap initialProperties = NetworkManagerPrivate::retrieveInitialProperties(d->iface.staticInterfaceName(), path);
0076     if (!initialProperties.isEmpty()) {
0077         d->propertiesChanged(initialProperties);
0078     }
0079 }
0080 
0081 NetworkManager::ActiveConnection::ActiveConnection(ActiveConnectionPrivate &dd, QObject *parent)
0082     : QObject(parent)
0083     , d_ptr(&dd)
0084 {
0085     Q_D(ActiveConnection);
0086 
0087 #ifndef NMQT_STATIC
0088     QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
0089                                          d->path,
0090                                          NetworkManagerPrivate::FDO_DBUS_PROPERTIES,
0091                                          QLatin1String("PropertiesChanged"),
0092                                          d,
0093                                          SLOT(dbusPropertiesChanged(QString, QVariantMap, QStringList)));
0094     QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
0095                                          d->path,
0096                                          d->iface.staticInterfaceName(),
0097                                          QLatin1String("StateChanged"),
0098                                          d,
0099                                          SLOT(stateChanged(uint, uint)));
0100 #endif
0101 
0102 #ifdef NMQT_STATIC
0103     connect(&d->iface, &OrgFreedesktopNetworkManagerConnectionActiveInterface::PropertiesChanged, d, &ActiveConnectionPrivate::propertiesChanged);
0104     connect(&d->iface, &OrgFreedesktopNetworkManagerConnectionActiveInterface::StateChanged, d, &ActiveConnectionPrivate::stateChanged);
0105 #endif
0106 }
0107 
0108 NetworkManager::ActiveConnection::~ActiveConnection()
0109 {
0110     delete d_ptr;
0111 }
0112 
0113 bool NetworkManager::ActiveConnection::isValid() const
0114 {
0115     Q_D(const ActiveConnection);
0116     return !d->connection.isNull();
0117 }
0118 
0119 NetworkManager::Connection::Ptr NetworkManager::ActiveConnection::connection() const
0120 {
0121     Q_D(const ActiveConnection);
0122     return d->connection;
0123 }
0124 
0125 QString NetworkManager::ActiveConnection::path() const
0126 {
0127     Q_D(const ActiveConnection);
0128     return d->path;
0129 }
0130 
0131 bool NetworkManager::ActiveConnection::default4() const
0132 {
0133     Q_D(const ActiveConnection);
0134     return d->default4;
0135 }
0136 
0137 bool NetworkManager::ActiveConnection::default6() const
0138 {
0139     Q_D(const ActiveConnection);
0140     return d->default6;
0141 }
0142 
0143 NetworkManager::Dhcp4Config::Ptr NetworkManager::ActiveConnection::dhcp4Config() const
0144 {
0145     Q_D(const ActiveConnection);
0146     if (!d->dhcp4Config && !d->dhcp4ConfigPath.isNull()) {
0147         d->dhcp4Config = NetworkManager::Dhcp4Config::Ptr(new Dhcp4Config(d->dhcp4ConfigPath), &QObject::deleteLater);
0148     }
0149     return d->dhcp4Config;
0150 }
0151 
0152 NetworkManager::Dhcp6Config::Ptr NetworkManager::ActiveConnection::dhcp6Config() const
0153 {
0154     Q_D(const ActiveConnection);
0155     if (!d->dhcp6Config && !d->dhcp6ConfigPath.isNull()) {
0156         d->dhcp6Config = NetworkManager::Dhcp6Config::Ptr(new Dhcp6Config(d->dhcp6ConfigPath), &QObject::deleteLater);
0157     }
0158     return d->dhcp6Config;
0159 }
0160 
0161 NetworkManager::IpConfig NetworkManager::ActiveConnection::ipV4Config() const
0162 {
0163     Q_D(const ActiveConnection);
0164     if (!d->ipV4Config.isValid() && !d->ipV4ConfigPath.isNull()) {
0165         d->ipV4Config.setIPv4Path(d->ipV4ConfigPath);
0166     }
0167     return d->ipV4Config;
0168 }
0169 
0170 NetworkManager::IpConfig NetworkManager::ActiveConnection::ipV6Config() const
0171 {
0172     Q_D(const ActiveConnection);
0173     if (!d->ipV6Config.isValid() && !d->ipV6ConfigPath.isNull()) {
0174         d->ipV6Config.setIPv6Path(d->ipV6ConfigPath);
0175     }
0176     return d->ipV6Config;
0177 }
0178 
0179 QString NetworkManager::ActiveConnection::id() const
0180 {
0181     Q_D(const ActiveConnection);
0182     return d->id;
0183 }
0184 
0185 NetworkManager::ConnectionSettings::ConnectionType NetworkManager::ActiveConnection::type() const
0186 {
0187     Q_D(const ActiveConnection);
0188     return NetworkManager::ConnectionSettings::typeFromString(d->type);
0189 }
0190 
0191 QString NetworkManager::ActiveConnection::master() const
0192 {
0193     Q_D(const ActiveConnection);
0194     return d->master;
0195 }
0196 
0197 QString NetworkManager::ActiveConnection::specificObject() const
0198 {
0199     Q_D(const ActiveConnection);
0200     return d->specificObject;
0201 }
0202 
0203 NetworkManager::ActiveConnection::State NetworkManager::ActiveConnection::state() const
0204 {
0205     Q_D(const ActiveConnection);
0206     return d->state;
0207 }
0208 
0209 bool NetworkManager::ActiveConnection::vpn() const
0210 {
0211     Q_D(const ActiveConnection);
0212     return d->vpn;
0213 }
0214 
0215 QString NetworkManager::ActiveConnection::uuid() const
0216 {
0217     Q_D(const ActiveConnection);
0218     return d->uuid;
0219 }
0220 
0221 QStringList NetworkManager::ActiveConnection::devices() const
0222 {
0223     Q_D(const ActiveConnection);
0224     return d->devices;
0225 }
0226 
0227 void NetworkManager::ActiveConnectionPrivate::dbusPropertiesChanged(const QString &interfaceName,
0228                                                                     const QVariantMap &properties,
0229                                                                     const QStringList &invalidatedProperties)
0230 {
0231     Q_UNUSED(invalidatedProperties);
0232 
0233     if (interfaceName == QLatin1String("org.freedesktop.NetworkManager.Connection.Active")) {
0234         propertiesChanged(properties);
0235     }
0236 }
0237 
0238 void NetworkManager::ActiveConnectionPrivate::propertiesChanged(const QVariantMap &properties)
0239 {
0240     // qCDebug(NMQT) << Q_FUNC_INFO << properties;
0241 
0242     QVariantMap::const_iterator it = properties.constBegin();
0243     while (it != properties.constEnd()) {
0244         propertyChanged(it.key(), it.value());
0245         ++it;
0246     }
0247 }
0248 
0249 void NetworkManager::ActiveConnectionPrivate::stateChanged(uint state, uint reason)
0250 {
0251     Q_Q(ActiveConnection);
0252 
0253     Q_EMIT q->stateChangedReason(convertActiveConnectionState(state), convertActiveConnectionReason(reason));
0254 }
0255 
0256 void NetworkManager::ActiveConnectionPrivate::propertyChanged(const QString &property, const QVariant &value)
0257 {
0258     Q_Q(ActiveConnection);
0259 
0260     // qCDebug(NMQT) << property  << " - " << value;
0261 
0262     if (property == QLatin1String("Connection")) {
0263         connection = NetworkManager::findConnection(qdbus_cast<QDBusObjectPath>(value).path());
0264         Q_EMIT q->connectionChanged(connection);
0265         const QString tmpId = connection->settings()->id();
0266         const QString tmpType = connection->settings()->typeAsString(connection->settings()->connectionType());
0267         if (tmpId != id) {
0268             id = tmpId;
0269             Q_EMIT q->idChanged(id);
0270         }
0271 
0272         if (tmpType != type) {
0273             Q_EMIT q->typeChanged(NetworkManager::ConnectionSettings::typeFromString(type));
0274         }
0275     } else if (property == QLatin1String("Default")) {
0276         default4 = value.toBool();
0277         Q_EMIT q->default4Changed(default4);
0278     } else if (property == QLatin1String("Default6")) {
0279         default6 = value.toBool();
0280         Q_EMIT q->default6Changed(default6);
0281     } else if (property == QLatin1String("Dhcp4Config")) {
0282         QDBusObjectPath dhcp4ConfigPathTmp = (value).value<QDBusObjectPath>();
0283         if (dhcp4ConfigPathTmp.path().isNull()) {
0284             dhcp4Config.clear();
0285             dhcp4ConfigPath.clear();
0286         } else if (!dhcp4Config || dhcp4Config->path() != dhcp4ConfigPathTmp.path()) {
0287             dhcp4Config.clear();
0288             dhcp4ConfigPath = dhcp4ConfigPathTmp.path();
0289         }
0290         Q_EMIT q->dhcp4ConfigChanged();
0291     } else if (property == QLatin1String("Dhcp6Config")) {
0292         QDBusObjectPath dhcp6ConfigPathTmp = (value).value<QDBusObjectPath>();
0293         if (dhcp6ConfigPathTmp.path().isNull()) {
0294             dhcp6Config.clear();
0295             dhcp6ConfigPath.clear();
0296         } else if (!dhcp6Config || dhcp6Config->path() != dhcp6ConfigPathTmp.path()) {
0297             dhcp6Config.clear();
0298             dhcp6ConfigPath = dhcp6ConfigPathTmp.path();
0299         }
0300         Q_EMIT q->dhcp6ConfigChanged();
0301     } else if (property == QLatin1String("Ip4Config")) {
0302         QDBusObjectPath ip4ConfigObjectPathTmp = (value).value<QDBusObjectPath>();
0303         if (ip4ConfigObjectPathTmp.path().isNull() || ip4ConfigObjectPathTmp.path() == QLatin1String("/")) {
0304             ipV4ConfigPath.clear();
0305         } else {
0306             ipV4ConfigPath = ip4ConfigObjectPathTmp.path();
0307         }
0308         ipV4Config = IpConfig();
0309         Q_EMIT q->ipV4ConfigChanged();
0310     } else if (property == QLatin1String("Ip6Config")) {
0311         QDBusObjectPath ip6ConfigObjectPathTmp = (value).value<QDBusObjectPath>();
0312         if (ip6ConfigObjectPathTmp.path().isNull() || ip6ConfigObjectPathTmp.path() == QLatin1String("/")) {
0313             ipV6ConfigPath.clear();
0314         } else {
0315             ipV6ConfigPath = ip6ConfigObjectPathTmp.path();
0316         }
0317         ipV6Config = IpConfig();
0318         Q_EMIT q->ipV6ConfigChanged();
0319     } else if (property == QLatin1String("Id")) {
0320         id = value.toString();
0321         Q_EMIT q->idChanged(id);
0322     } else if (property == QLatin1String("Type")) {
0323         type = value.toString();
0324         Q_EMIT q->typeChanged(NetworkManager::ConnectionSettings::typeFromString(type));
0325     } else if (property == QLatin1String("Master")) {
0326         master = qdbus_cast<QDBusObjectPath>(value).path();
0327         Q_EMIT q->masterChanged(master);
0328     } else if (property == QLatin1String("SpecificObject")) {
0329         specificObject = qdbus_cast<QDBusObjectPath>(value).path();
0330         Q_EMIT q->specificObjectChanged(specificObject);
0331     } else if (property == QLatin1String("State")) {
0332         state = NetworkManager::ActiveConnectionPrivate::convertActiveConnectionState(value.toUInt());
0333         Q_EMIT q->stateChanged(state);
0334     } else if (property == QLatin1String("Vpn")) {
0335         vpn = value.toBool();
0336         Q_EMIT q->vpnChanged(vpn);
0337     } else if (property == QLatin1String("Uuid")) {
0338         uuid = value.toString();
0339         Q_EMIT q->uuidChanged(uuid);
0340     } else if (property == QLatin1String("Devices")) {
0341         devices.clear();
0342         const QList<QDBusObjectPath> opList = qdbus_cast<QList<QDBusObjectPath>>(value);
0343         for (const QDBusObjectPath &path : opList) {
0344             devices.append(path.path());
0345         }
0346         Q_EMIT q->devicesChanged();
0347     } else {
0348         qCDebug(NMQT) << Q_FUNC_INFO << "Unhandled property" << property;
0349     }
0350 }
0351 
0352 #include "moc_activeconnection.cpp"
0353 #include "moc_activeconnection_p.cpp"