Warning, file /frameworks/networkmanager-qt/src/device.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: 2008, 2010 Will Stephenson <wstephenson@kde.org>
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 "connection.h"
0010 #include "device_p.h"
0011 #include "manager.h"
0012 #include "manager_p.h"
0013 #include "nmdebug.h"
0014 #include "settings.h"
0015 
0016 #include <arpa/inet.h>
0017 
0018 #include <QDBusObjectPath>
0019 
0020 // logging category for this framework, default: log stuff >= warning
0021 Q_LOGGING_CATEGORY(NMQT, "kf.networkmanagerqt", QtWarningMsg)
0022 
0023 namespace NetworkManager
0024 {
0025 class DeviceStateReasonPrivate
0026 {
0027 public:
0028     DeviceStateReasonPrivate(Device::State st, Device::StateChangeReason rsn)
0029         : state(st)
0030         , reason(rsn)
0031     {
0032     }
0033     DeviceStateReasonPrivate()
0034         : state(Device::UnknownState)
0035         , reason(Device::UnknownReason)
0036     {
0037     }
0038     Device::State state;
0039     Device::StateChangeReason reason;
0040 };
0041 }
0042 
0043 NetworkManager::DeviceStateReason::DeviceStateReason(Device::State state, Device::StateChangeReason reason)
0044     : d_ptr(new DeviceStateReasonPrivate(state, reason))
0045 {
0046 }
0047 
0048 NetworkManager::DeviceStateReason::DeviceStateReason(const NetworkManager::DeviceStateReason &other)
0049     : d_ptr(new DeviceStateReasonPrivate(*other.d_ptr))
0050 {
0051 }
0052 
0053 NetworkManager::DeviceStateReason::~DeviceStateReason()
0054 {
0055     delete d_ptr;
0056 }
0057 
0058 NetworkManager::Device::State NetworkManager::DeviceStateReason::state() const
0059 {
0060     Q_D(const DeviceStateReason);
0061     return d->state;
0062 }
0063 
0064 NetworkManager::Device::StateChangeReason NetworkManager::DeviceStateReason::reason() const
0065 {
0066     Q_D(const DeviceStateReason);
0067     return d->reason;
0068 }
0069 
0070 NetworkManager::DeviceStateReason &NetworkManager::DeviceStateReason::operator=(const NetworkManager::DeviceStateReason &other)
0071 {
0072     if (&other != this) {
0073         *d_ptr = *other.d_ptr;
0074     }
0075     return *this;
0076 }
0077 
0078 NetworkManager::DevicePrivate::DevicePrivate(const QString &path, NetworkManager::Device *q)
0079 #ifdef NMQT_STATIC
0080     : deviceIface(NetworkManagerPrivate::DBUS_SERVICE, path, QDBusConnection::sessionBus())
0081 #else
0082     : deviceIface(NetworkManagerPrivate::DBUS_SERVICE, path, QDBusConnection::systemBus())
0083 #endif
0084     , uni(path)
0085     , designSpeed(0)
0086     , deviceType(Device::UnknownType)
0087     , dhcp4Config(nullptr)
0088     , dhcp6Config(nullptr)
0089     , mtu(0)
0090     , q_ptr(q)
0091 {
0092 }
0093 
0094 NetworkManager::DevicePrivate::~DevicePrivate()
0095 {
0096 }
0097 
0098 void NetworkManager::DevicePrivate::init()
0099 {
0100     qDBusRegisterMetaType<UIntList>();
0101     qDBusRegisterMetaType<UIntListList>();
0102     qDBusRegisterMetaType<IpV6DBusAddress>();
0103     qDBusRegisterMetaType<IpV6DBusAddressList>();
0104     qDBusRegisterMetaType<IpV6DBusNameservers>();
0105     qDBusRegisterMetaType<IpV6DBusRoute>();
0106     qDBusRegisterMetaType<IpV6DBusRouteList>();
0107     qDBusRegisterMetaType<DeviceDBusStateReason>();
0108 
0109     QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
0110                                          uni,
0111                                          NetworkManagerPrivate::FDO_DBUS_PROPERTIES,
0112                                          QLatin1String("PropertiesChanged"),
0113                                          this,
0114                                          SLOT(dbusPropertiesChanged(QString, QVariantMap, QStringList)));
0115     QObject::connect(&deviceIface, &OrgFreedesktopNetworkManagerDeviceInterface::StateChanged, this, &DevicePrivate::deviceStateChanged);
0116 
0117 
0118     deviceStatistics = DeviceStatistics::Ptr(new NetworkManager::DeviceStatistics(uni), &QObject::deleteLater);
0119 
0120     // Get all Device's properties at once
0121     QVariantMap initialProperties = NetworkManagerPrivate::retrieveInitialProperties(deviceIface.staticInterfaceName(), uni);
0122     if (!initialProperties.isEmpty()) {
0123         propertiesChanged(initialProperties);
0124     }
0125 
0126 }
0127 
0128 NetworkManager::Device::MeteredStatus NetworkManager::DevicePrivate::convertMeteredStatus(uint metered)
0129 {
0130     NetworkManager::Device::MeteredStatus ourMeteredStatus = (NetworkManager::Device::MeteredStatus)metered;
0131     return ourMeteredStatus;
0132 }
0133 
0134 NetworkManager::Device::Capabilities NetworkManager::DevicePrivate::convertCapabilities(uint theirCaps)
0135 {
0136     NetworkManager::Device::Capabilities ourCaps = (NetworkManager::Device::Capabilities)theirCaps;
0137     return ourCaps;
0138 }
0139 
0140 NetworkManager::Device::State NetworkManager::DevicePrivate::convertState(uint theirState)
0141 {
0142     NetworkManager::Device::State ourState = static_cast<NetworkManager::Device::State>(theirState);
0143     return ourState;
0144 }
0145 
0146 NetworkManager::Device::StateChangeReason NetworkManager::DevicePrivate::convertReason(uint theirReason)
0147 {
0148     NetworkManager::Device::StateChangeReason ourReason = (NetworkManager::Device::StateChangeReason)theirReason;
0149     return ourReason;
0150 }
0151 
0152 NetworkManager::Device::Type NetworkManager::DevicePrivate::convertType(uint type)
0153 {
0154     // These are identical to NM enums
0155     if (type <= NM_DEVICE_TYPE_TEAM) {
0156         return (NetworkManager::Device::Type)type;
0157     }
0158 
0159     switch (type) {
0160     case 16:
0161         // NM_DEVICE_TYPE_TUN
0162         return NetworkManager::Device::Tun;
0163     case 17:
0164         // NM_DEVICE_TYPE_IP_TUNNEL
0165         return NetworkManager::Device::IpTunnel;
0166     case 18:
0167         // NM_DEVICE_TYPE_MACVLAN
0168         return NetworkManager::Device::MacVlan;
0169     case 19:
0170         // NM_DEVICE_TYPE_VXLAN
0171         return NetworkManager::Device::VxLan;
0172     case 20:
0173         // NM_DEVICE_TYPE_VETH
0174         return NetworkManager::Device::Veth;
0175     case 21:
0176         // NM_DEVICE_TYPE_MACSEC
0177         return NetworkManager::Device::MacSec;
0178     case 22:
0179         // NM_DEVICE_TYPE_DUMMY
0180         return NetworkManager::Device::Dummy;
0181     case 23:
0182         // NM_DEVICE_TYPE_PPP
0183         return NetworkManager::Device::Ppp;
0184     case 24:
0185         // NM_DEVICE_TYPE_OVS_INTERFACE
0186         return NetworkManager::Device::OvsInterface;
0187     case 25:
0188         // NM_DEVICE_TYPE_OVS_PORT
0189         return NetworkManager::Device::OvsPort;
0190     case 26:
0191         // NM_DEVICE_TYPE_OVS_BRIDGE
0192         return NetworkManager::Device::OvsBridge;
0193     case 27:
0194         // NM_DEVICE_TYPE_WPAN
0195         return NetworkManager::Device::Wpan;
0196     case 28:
0197         // NM_DEVICE_TYPE_6LOWPAN
0198         return NetworkManager::Device::Lowpan;
0199     case 29:
0200         // NM_DEVICE_TYPE_NM_DEVICE_TYPE_WIREGUARD
0201         return NetworkManager::Device::WireGuard;
0202     case 30:
0203         // NM_DEVICE_TYPE_WIFI_P2P
0204         return NetworkManager::Device::WifiP2P;
0205     }
0206 
0207     return NetworkManager::Device::UnknownType;
0208 }
0209 
0210 NetworkManager::Device::Device(const QString &path, QObject *parent)
0211     : QObject(parent)
0212     , d_ptr(new DevicePrivate(path, this))
0213 {
0214     Q_D(Device);
0215 
0216     d->init();
0217 }
0218 
0219 NetworkManager::Device::Device(DevicePrivate &dd, QObject *parent)
0220     : QObject(parent)
0221     , d_ptr(&dd)
0222 {
0223     Q_D(Device);
0224 
0225     d->init();
0226 }
0227 
0228 void NetworkManager::DevicePrivate::propertyChanged(const QString &property, const QVariant &value)
0229 {
0230     Q_Q(Device);
0231 
0232     // qCDebug(NMQT) << property  << " - " << value;
0233     if (property == QLatin1String("ActiveConnection")) {
0234         // FIXME workaround, because NM doesn't Q_EMIT correct value
0235         // d->activeConnection = value.value<QDBusObjectPath>.path();
0236         activeConnection = deviceIface.activeConnection().path();
0237         Q_EMIT q->activeConnectionChanged();
0238     } else if (property == QLatin1String("Autoconnect")) {
0239         autoconnect = value.toBool();
0240         Q_EMIT q->autoconnectChanged();
0241     } else if (property == QLatin1String("AvailableConnections")) {
0242         QStringList newAvailableConnections;
0243         const QList<QDBusObjectPath> availableConnectionsTmp = qdbus_cast<QList<QDBusObjectPath>>(value);
0244         for (const QDBusObjectPath &availableConnection : availableConnectionsTmp) {
0245             newAvailableConnections << availableConnection.path();
0246             if (!availableConnections.contains(availableConnection.path())) {
0247                 availableConnections << availableConnection.path();
0248                 Q_EMIT q->availableConnectionAppeared(availableConnection.path());
0249             }
0250         }
0251         auto it = availableConnections.begin();
0252         while (it != availableConnections.end()) {
0253             const QString availableConnection = *it;
0254             if (!newAvailableConnections.contains(availableConnection)) {
0255                 it = availableConnections.erase(it);
0256                 Q_EMIT q->availableConnectionDisappeared(availableConnection);
0257             } else {
0258                 ++it;
0259             }
0260         }
0261         Q_EMIT q->availableConnectionChanged();
0262     } else if (property == QLatin1String("Capabilities")) {
0263         capabilities = NetworkManager::DevicePrivate::convertCapabilities(value.toUInt());
0264         Q_EMIT q->capabilitiesChanged();
0265     } else if (property == QLatin1String("DeviceType")) {
0266         deviceType = convertType(value.toUInt());
0267     } else if (property == QLatin1String("Dhcp4Config")) {
0268         QDBusObjectPath dhcp4ConfigPathTmp = value.value<QDBusObjectPath>();
0269         if (dhcp4ConfigPathTmp.path().isNull()) {
0270             dhcp4Config.clear();
0271             dhcp4ConfigPath.clear();
0272         } else if (!dhcp4Config || dhcp4Config->path() != dhcp4ConfigPathTmp.path()) {
0273             dhcp4Config.clear();
0274             dhcp4ConfigPath = dhcp4ConfigPathTmp.path();
0275         }
0276         Q_EMIT q->dhcp4ConfigChanged();
0277     } else if (property == QLatin1String("Dhcp6Config")) {
0278         QDBusObjectPath dhcp6ConfigPathTmp = value.value<QDBusObjectPath>();
0279         if (dhcp6ConfigPathTmp.path().isNull()) {
0280             dhcp6Config.clear();
0281             dhcp6ConfigPath.clear();
0282         } else if (!dhcp6Config || dhcp6Config->path() != dhcp6ConfigPathTmp.path()) {
0283             dhcp6Config.clear();
0284             dhcp6ConfigPath = dhcp6ConfigPathTmp.path();
0285         }
0286         Q_EMIT q->dhcp6ConfigChanged();
0287     } else if (property == QLatin1String("Driver")) {
0288         driver = value.toString();
0289         Q_EMIT q->driverChanged();
0290     } else if (property == QLatin1String("DriverVersion")) {
0291         driverVersion = value.toString();
0292         Q_EMIT q->driverVersionChanged();
0293     } else if (property == QLatin1String("FirmwareMissing")) {
0294         firmwareMissing = value.toBool();
0295         Q_EMIT q->firmwareMissingChanged();
0296     } else if (property == QLatin1String("FirmwareVersion")) {
0297         firmwareVersion = value.toString();
0298         Q_EMIT q->firmwareVersionChanged();
0299     } else if (property == QLatin1String("Interface")) {
0300         interfaceName = value.toString();
0301         Q_EMIT q->interfaceNameChanged();
0302     } else if (property == QLatin1String("Ip4Address")) {
0303         ipV4Address = QHostAddress(ntohl(value.toUInt()));
0304         Q_EMIT q->ipV4AddressChanged();
0305     } else if (property == QLatin1String("Ip4Config")) {
0306         QDBusObjectPath ip4ConfigObjectPathTmp = value.value<QDBusObjectPath>();
0307         if (ip4ConfigObjectPathTmp.path().isNull() || ip4ConfigObjectPathTmp.path() == QLatin1String("/")) {
0308             ipV4ConfigPath.clear();
0309         } else {
0310             ipV4ConfigPath = ip4ConfigObjectPathTmp.path();
0311         }
0312         ipV4Config = IpConfig();
0313         Q_EMIT q->ipV4ConfigChanged();
0314     } else if (property == QLatin1String("Ip6Config")) {
0315         QDBusObjectPath ip6ConfigObjectPathTmp = value.value<QDBusObjectPath>();
0316         if (ip6ConfigObjectPathTmp.path().isNull() || ip6ConfigObjectPathTmp.path() == QLatin1String("/")) {
0317             ipV6ConfigPath.clear();
0318         } else {
0319             ipV6ConfigPath = ip6ConfigObjectPathTmp.path();
0320         }
0321         ipV6Config = IpConfig();
0322         Q_EMIT q->ipV6ConfigChanged();
0323     } else if (property == QLatin1String("IpInterface")) {
0324         ipInterface = value.toString();
0325         Q_EMIT q->ipInterfaceChanged();
0326     } else if (property == QLatin1String("Managed")) {
0327         managed = value.toBool();
0328         Q_EMIT q->managedChanged();
0329     } else if (property == QLatin1String("State")) {
0330         connectionState = NetworkManager::DevicePrivate::convertState(value.toUInt());
0331         // FIXME NetworkManager 0.9.8 (maybe greater) doesn't
0332         // update ActiveConnection when disconnected
0333         // This is fixed in NM 73d128bbd17120225bb4986e3f05566f10fab581
0334         if (connectionState == NetworkManager::Device::Disconnected && activeConnection != QLatin1String("/")) {
0335             activeConnection = QLatin1Char('/');
0336             Q_EMIT q->activeConnectionChanged();
0337         }
0338         Q_EMIT q->connectionStateChanged();
0339     } else if (property == QLatin1String("StateReason")) { // just extracting the reason
0340         reason = NetworkManager::DevicePrivate::convertReason(qdbus_cast<DeviceDBusStateReason>(value).reason);
0341         Q_EMIT q->stateReasonChanged();
0342     } else if (property == QLatin1String("Udi")) {
0343         udi = value.toString();
0344         Q_EMIT q->udiChanged();
0345     } else if (property == QLatin1String("PhysicalPortId")) {
0346         physicalPortId = value.toString();
0347         Q_EMIT q->physicalPortIdChanged();
0348     } else if (property == QLatin1String("Mtu")) {
0349         mtu = value.toUInt();
0350         Q_EMIT q->mtuChanged();
0351     } else if (property == QLatin1String("NmPluginMissing")) {
0352         nmPluginMissing = value.toBool();
0353         Q_EMIT q->nmPluginMissingChanged(nmPluginMissing);
0354     } else if (property == QLatin1String("Metered")) {
0355         metered = NetworkManager::DevicePrivate::convertMeteredStatus(value.toUInt());
0356         Q_EMIT q->meteredChanged(metered);
0357     } else {
0358         qCDebug(NMQT) << Q_FUNC_INFO << "Unhandled property" << property;
0359     }
0360 }
0361 
0362 NetworkManager::Device::~Device()
0363 {
0364     Q_D(Device);
0365     delete d;
0366 }
0367 
0368 QString NetworkManager::Device::uni() const
0369 {
0370     Q_D(const Device);
0371     return d->uni;
0372 }
0373 
0374 QString NetworkManager::Device::interfaceName() const
0375 {
0376     Q_D(const Device);
0377     return d->interfaceName;
0378 }
0379 
0380 QString NetworkManager::Device::ipInterfaceName() const
0381 {
0382     Q_D(const Device);
0383     return d->ipInterface;
0384 }
0385 
0386 QString NetworkManager::Device::driver() const
0387 {
0388     Q_D(const Device);
0389     return d->driver;
0390 }
0391 
0392 QString NetworkManager::Device::driverVersion() const
0393 {
0394     Q_D(const Device);
0395     return d->driverVersion;
0396 }
0397 
0398 QString NetworkManager::Device::firmwareVersion() const
0399 {
0400     Q_D(const Device);
0401     return d->firmwareVersion;
0402 }
0403 
0404 NetworkManager::ActiveConnection::Ptr NetworkManager::Device::activeConnection() const
0405 {
0406     Q_D(const Device);
0407     return NetworkManager::findActiveConnection(d->activeConnection);
0408 }
0409 
0410 NetworkManager::Connection::List NetworkManager::Device::availableConnections()
0411 {
0412     Q_D(const Device);
0413 
0414     NetworkManager::Connection::List list;
0415     for (const QString &availableConnection : std::as_const(d->availableConnections)) {
0416         NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(availableConnection);
0417         if (connection) {
0418             list << connection;
0419         }
0420     }
0421 
0422     return list;
0423 }
0424 
0425 bool NetworkManager::Device::firmwareMissing() const
0426 {
0427     Q_D(const Device);
0428     return d->firmwareMissing;
0429 }
0430 
0431 bool NetworkManager::Device::autoconnect() const
0432 {
0433     Q_D(const Device);
0434     return d->autoconnect;
0435 }
0436 
0437 void NetworkManager::Device::setAutoconnect(bool autoconnect)
0438 {
0439     Q_D(Device);
0440     d->deviceIface.setAutoconnect(autoconnect);
0441 }
0442 
0443 QString NetworkManager::Device::udi() const
0444 {
0445     Q_D(const Device);
0446     return d->udi;
0447 }
0448 
0449 QString NetworkManager::Device::physicalPortId() const
0450 {
0451     Q_D(const Device);
0452     return d->physicalPortId;
0453 }
0454 
0455 QHostAddress NetworkManager::Device::ipV4Address() const
0456 {
0457     Q_D(const Device);
0458     return d->ipV4Address;
0459 }
0460 
0461 NetworkManager::DeviceStateReason NetworkManager::Device::stateReason() const
0462 {
0463     Q_D(const Device);
0464     return DeviceStateReason(d->connectionState, d->reason);
0465 }
0466 
0467 NetworkManager::IpConfig NetworkManager::Device::ipV4Config() const
0468 {
0469     Q_D(const Device);
0470     if (!d->ipV4Config.isValid() && !d->ipV4ConfigPath.isNull()) {
0471         d->ipV4Config.setIPv4Path(d->ipV4ConfigPath);
0472     }
0473     return d->ipV4Config;
0474 }
0475 
0476 NetworkManager::IpConfig NetworkManager::Device::ipV6Config() const
0477 {
0478     Q_D(const Device);
0479     if (!d->ipV6Config.isValid() && !d->ipV6ConfigPath.isNull()) {
0480         d->ipV6Config.setIPv6Path(d->ipV6ConfigPath);
0481     }
0482     return d->ipV6Config;
0483 }
0484 
0485 NetworkManager::Dhcp4Config::Ptr NetworkManager::Device::dhcp4Config() const
0486 {
0487     Q_D(const Device);
0488     if (!d->dhcp4Config && !d->dhcp4ConfigPath.isNull()) {
0489         d->dhcp4Config = NetworkManager::Dhcp4Config::Ptr(new Dhcp4Config(d->dhcp4ConfigPath), &QObject::deleteLater);
0490     }
0491     return d->dhcp4Config;
0492 }
0493 
0494 NetworkManager::Dhcp6Config::Ptr NetworkManager::Device::dhcp6Config() const
0495 {
0496     Q_D(const Device);
0497     if (!d->dhcp6Config && !d->dhcp6ConfigPath.isNull()) {
0498         d->dhcp6Config = NetworkManager::Dhcp6Config::Ptr(new Dhcp6Config(d->dhcp6ConfigPath), &QObject::deleteLater);
0499     }
0500     return d->dhcp6Config;
0501 }
0502 
0503 bool NetworkManager::Device::isActive() const
0504 {
0505     Q_D(const Device);
0506     /* clang-format off */
0507     return !(d->connectionState == NetworkManager::Device::Unavailable
0508              || d->connectionState == NetworkManager::Device::Unmanaged
0509              || d->connectionState == NetworkManager::Device::Disconnected
0510              || d->connectionState == NetworkManager::Device::Failed);
0511     /* clang-format on */
0512 }
0513 
0514 bool NetworkManager::Device::isValid() const
0515 {
0516     Q_D(const Device);
0517     return d->deviceIface.isValid();
0518 }
0519 
0520 bool NetworkManager::Device::managed() const
0521 {
0522     Q_D(const Device);
0523     return d->managed;
0524 }
0525 
0526 uint NetworkManager::Device::mtu() const
0527 {
0528     Q_D(const Device);
0529     return d->mtu;
0530 }
0531 
0532 bool NetworkManager::Device::nmPluginMissing() const
0533 {
0534     Q_D(const Device);
0535     return d->nmPluginMissing;
0536 }
0537 
0538 NetworkManager::Device::MeteredStatus NetworkManager::Device::metered() const
0539 {
0540     Q_D(const Device);
0541     return d->metered;
0542 }
0543 
0544 QDBusPendingReply<> NetworkManager::Device::reapplyConnection(const NMVariantMapMap &connection, qulonglong version_id, uint flags)
0545 {
0546     Q_D(Device);
0547     return d->deviceIface.Reapply(connection, version_id, flags);
0548 }
0549 
0550 QDBusPendingReply<> NetworkManager::Device::disconnectInterface()
0551 {
0552     Q_D(Device);
0553     return d->deviceIface.Disconnect();
0554 }
0555 
0556 QDBusPendingReply<> NetworkManager::Device::deleteInterface()
0557 {
0558     if (NetworkManager::checkVersion(1, 0, 0)) {
0559         Q_D(Device);
0560         return d->deviceIface.Delete();
0561     } else {
0562         return QDBusPendingReply<>();
0563     }
0564 }
0565 
0566 NetworkManager::Device::State NetworkManager::Device::state() const
0567 {
0568     Q_D(const Device);
0569     return d->connectionState;
0570 }
0571 
0572 int NetworkManager::Device::designSpeed() const
0573 {
0574     Q_D(const Device);
0575     return d->designSpeed;
0576 }
0577 
0578 NetworkManager::Device::Capabilities NetworkManager::Device::capabilities() const
0579 {
0580     Q_D(const Device);
0581     return d->capabilities;
0582 }
0583 
0584 QVariant NetworkManager::Device::capabilitiesV() const
0585 {
0586     Q_D(const Device);
0587     return QVariant(d->capabilities);
0588 }
0589 
0590 NetworkManager::DeviceStatistics::Ptr NetworkManager::Device::deviceStatistics() const
0591 {
0592     Q_D(const Device);
0593     return d->deviceStatistics;
0594 }
0595 
0596 void NetworkManager::DevicePrivate::deviceStateChanged(uint newState, uint oldState, uint reason)
0597 {
0598     Q_Q(Device);
0599     connectionState = NetworkManager::DevicePrivate::convertState(newState);
0600     reason = NetworkManager::DevicePrivate::convertReason(reason);
0601 
0602     Q_EMIT q->stateChanged(connectionState, NetworkManager::DevicePrivate::convertState(oldState), NetworkManager::DevicePrivate::convertReason(reason));
0603 }
0604 
0605 void NetworkManager::DevicePrivate::dbusPropertiesChanged(const QString &interfaceName, const QVariantMap &properties, const QStringList &invalidatedProperties)
0606 {
0607     Q_UNUSED(invalidatedProperties);
0608     if (interfaceName.contains(QLatin1String("org.freedesktop.NetworkManager.Device"))
0609         && interfaceName != QLatin1String("org.freedesktop.NetworkManager.Device.Statistics")) {
0610         propertiesChanged(properties);
0611     }
0612 }
0613 
0614 void NetworkManager::DevicePrivate::propertiesChanged(const QVariantMap &properties)
0615 {
0616     // qCDebug(NMQT) << Q_FUNC_INFO << properties;
0617 
0618     QVariantMap::const_iterator it = properties.constBegin();
0619     while (it != properties.constEnd()) {
0620         propertyChanged(it.key(), it.value());
0621         ++it;
0622     }
0623 
0624     // FIXME workaround, we need to get a path to updated IPv[46]Config,
0625     // because NM doesn't Q_EMIT the updated value when the device is activated
0626     // BUG: https://bugzilla.gnome.org/show_bug.cgi?id=725657
0627     if (properties.contains(QLatin1String("State")) && connectionState == NetworkManager::Device::Activated) {
0628         propertyChanged(QLatin1String("Ip4Config"), QVariant::fromValue<QDBusObjectPath>(deviceIface.ip4Config()));
0629         propertyChanged(QLatin1String("Ip6Config"), QVariant::fromValue<QDBusObjectPath>(deviceIface.ip6Config()));
0630     }
0631 }
0632 
0633 NetworkManager::Device::Type NetworkManager::Device::type() const
0634 {
0635     Q_D(const Device);
0636     return d->deviceType;
0637 }