1/*
2 SPDX-FileCopyrightText: 2011 Ilia Kats <ilia-kats@gmx.net>
3 SPDX-FileCopyrightText: 2013 Daniel Nicoletti <dantti12@gmail.com>
4 SPDX-FileCopyrightText: 2013 Jan Grulich <jgrulich@redhat.com>
5
6 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7*/
8
9#include "activeconnection.h"
10#include "activeconnection_p.h"
11#include "device.h"
12#include "manager.h"
13#include "nmdebug.h"
14#include "settings.h"
15
16#include <QDBusObjectPath>
17
18#include "manager_p.h"
19
20NetworkManager::ActiveConnectionPrivate::ActiveConnectionPrivate(const QString &dbusPath, ActiveConnection *q)
21#ifdef NMQT_STATIC
22 : iface(NetworkManagerPrivate::DBUS_SERVICE, dbusPath, QDBusConnection::sessionBus())
23#else
24 : iface(NetworkManagerPrivate::DBUS_SERVICE, dbusPath, QDBusConnection::systemBus())
25#endif
26 , dhcp4Config(nullptr)
27 , dhcp6Config(nullptr)
28 , state(ActiveConnection::Unknown)
29 , q_ptr(q)
30{
31 path = dbusPath;
32}
33
34NetworkManager::ActiveConnectionPrivate::~ActiveConnectionPrivate()
35{
36}
37
38NetworkManager::ActiveConnection::State NetworkManager::ActiveConnectionPrivate::convertActiveConnectionState(uint state)
39{
40 return (NetworkManager::ActiveConnection::State)state;
41}
42
43NetworkManager::ActiveConnection::Reason NetworkManager::ActiveConnectionPrivate::convertActiveConnectionReason(uint reason)
44{
45 return (NetworkManager::ActiveConnection::Reason)reason;
46}
47
48NetworkManager::ActiveConnection::ActiveConnection(const QString &path, QObject *parent)
49 : QObject(parent)
50 , d_ptr(new ActiveConnectionPrivate(path, this))
51{
52 Q_D(ActiveConnection);
53
54#ifndef NMQT_STATIC
55 QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
56 d->path,
57 NetworkManagerPrivate::FDO_DBUS_PROPERTIES,
58 QLatin1String("PropertiesChanged"),
59 d,
60 SLOT(dbusPropertiesChanged(QString, QVariantMap, QStringList)));
61 QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
62 d->path,
63 d->iface.staticInterfaceName(),
64 QLatin1String("StateChanged"),
65 d,
66 SLOT(stateChanged(uint, uint)));
67#endif
68
69#ifdef NMQT_STATIC
70 connect(&d->iface, &OrgFreedesktopNetworkManagerConnectionActiveInterface::PropertiesChanged, d, &ActiveConnectionPrivate::propertiesChanged);
71 connect(&d->iface, &OrgFreedesktopNetworkManagerConnectionActiveInterface::StateChanged, d, &ActiveConnectionPrivate::stateChanged);
72#endif
73
74 // Get all ActiveConnection's at once
75 QVariantMap initialProperties = NetworkManagerPrivate::retrieveInitialProperties(d->iface.staticInterfaceName(), path);
76 if (!initialProperties.isEmpty()) {
77 d->propertiesChanged(initialProperties);
78 }
79}
80
81NetworkManager::ActiveConnection::ActiveConnection(ActiveConnectionPrivate &dd, QObject *parent)
82 : QObject(parent)
83 , d_ptr(&dd)
84{
85 Q_D(ActiveConnection);
86
87#ifndef NMQT_STATIC
88 QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
89 d->path,
90 NetworkManagerPrivate::FDO_DBUS_PROPERTIES,
91 QLatin1String("PropertiesChanged"),
92 d,
93 SLOT(dbusPropertiesChanged(QString, QVariantMap, QStringList)));
94 QDBusConnection::systemBus().connect(NetworkManagerPrivate::DBUS_SERVICE,
95 d->path,
96 d->iface.staticInterfaceName(),
97 QLatin1String("StateChanged"),
98 d,
99 SLOT(stateChanged(uint, uint)));
100#endif
101
102#ifdef NMQT_STATIC
103 connect(&d->iface, &OrgFreedesktopNetworkManagerConnectionActiveInterface::PropertiesChanged, d, &ActiveConnectionPrivate::propertiesChanged);
104 connect(&d->iface, &OrgFreedesktopNetworkManagerConnectionActiveInterface::StateChanged, d, &ActiveConnectionPrivate::stateChanged);
105#endif
106}
107
108NetworkManager::ActiveConnection::~ActiveConnection()
109{
110 delete d_ptr;
111}
112
113bool NetworkManager::ActiveConnection::isValid() const
114{
115 Q_D(const ActiveConnection);
116 return !d->connection.isNull();
117}
118
119NetworkManager::Connection::Ptr NetworkManager::ActiveConnection::connection() const
120{
121 Q_D(const ActiveConnection);
122 return d->connection;
123}
124
125QString NetworkManager::ActiveConnection::path() const
126{
127 Q_D(const ActiveConnection);
128 return d->path;
129}
130
131bool NetworkManager::ActiveConnection::default4() const
132{
133 Q_D(const ActiveConnection);
134 return d->default4;
135}
136
137bool NetworkManager::ActiveConnection::default6() const
138{
139 Q_D(const ActiveConnection);
140 return d->default6;
141}
142
143NetworkManager::Dhcp4Config::Ptr NetworkManager::ActiveConnection::dhcp4Config() const
144{
145 Q_D(const ActiveConnection);
146 if (!d->dhcp4Config && !d->dhcp4ConfigPath.isNull()) {
147 d->dhcp4Config = NetworkManager::Dhcp4Config::Ptr(new Dhcp4Config(d->dhcp4ConfigPath), &QObject::deleteLater);
148 }
149 return d->dhcp4Config;
150}
151
152NetworkManager::Dhcp6Config::Ptr NetworkManager::ActiveConnection::dhcp6Config() const
153{
154 Q_D(const ActiveConnection);
155 if (!d->dhcp6Config && !d->dhcp6ConfigPath.isNull()) {
156 d->dhcp6Config = NetworkManager::Dhcp6Config::Ptr(new Dhcp6Config(d->dhcp6ConfigPath), &QObject::deleteLater);
157 }
158 return d->dhcp6Config;
159}
160
161NetworkManager::IpConfig NetworkManager::ActiveConnection::ipV4Config() const
162{
163 Q_D(const ActiveConnection);
164 if (!d->ipV4Config.isValid() && !d->ipV4ConfigPath.isNull()) {
165 d->ipV4Config.setIPv4Path(d->ipV4ConfigPath);
166 }
167 return d->ipV4Config;
168}
169
170NetworkManager::IpConfig NetworkManager::ActiveConnection::ipV6Config() const
171{
172 Q_D(const ActiveConnection);
173 if (!d->ipV6Config.isValid() && !d->ipV6ConfigPath.isNull()) {
174 d->ipV6Config.setIPv6Path(d->ipV6ConfigPath);
175 }
176 return d->ipV6Config;
177}
178
179QString NetworkManager::ActiveConnection::id() const
180{
181 Q_D(const ActiveConnection);
182 return d->id;
183}
184
185NetworkManager::ConnectionSettings::ConnectionType NetworkManager::ActiveConnection::type() const
186{
187 Q_D(const ActiveConnection);
188 return NetworkManager::ConnectionSettings::typeFromString(d->type);
189}
190
191QString NetworkManager::ActiveConnection::master() const
192{
193 Q_D(const ActiveConnection);
194 return d->master;
195}
196
197QString NetworkManager::ActiveConnection::specificObject() const
198{
199 Q_D(const ActiveConnection);
200 return d->specificObject;
201}
202
203NetworkManager::ActiveConnection::State NetworkManager::ActiveConnection::state() const
204{
205 Q_D(const ActiveConnection);
206 return d->state;
207}
208
209bool NetworkManager::ActiveConnection::vpn() const
210{
211 Q_D(const ActiveConnection);
212 return d->vpn;
213}
214
215QString NetworkManager::ActiveConnection::uuid() const
216{
217 Q_D(const ActiveConnection);
218 return d->uuid;
219}
220
221QStringList NetworkManager::ActiveConnection::devices() const
222{
223 Q_D(const ActiveConnection);
224 return d->devices;
225}
226
227void NetworkManager::ActiveConnectionPrivate::dbusPropertiesChanged(const QString &interfaceName,
228 const QVariantMap &properties,
229 const QStringList &invalidatedProperties)
230{
231 Q_UNUSED(invalidatedProperties);
232
233 if (interfaceName == QLatin1String("org.freedesktop.NetworkManager.Connection.Active")) {
234 propertiesChanged(properties);
235 }
236}
237
238void NetworkManager::ActiveConnectionPrivate::propertiesChanged(const QVariantMap &properties)
239{
240 // qCDebug(NMQT) << Q_FUNC_INFO << properties;
241
242 QVariantMap::const_iterator it = properties.constBegin();
243 while (it != properties.constEnd()) {
244 propertyChanged(it.key(), it.value());
245 ++it;
246 }
247}
248
249void NetworkManager::ActiveConnectionPrivate::stateChanged(uint state, uint reason)
250{
251 Q_Q(ActiveConnection);
252
253 Q_EMIT q->stateChangedReason(convertActiveConnectionState(state), convertActiveConnectionReason(reason));
254}
255
256void NetworkManager::ActiveConnectionPrivate::propertyChanged(const QString &property, const QVariant &value)
257{
258 Q_Q(ActiveConnection);
259
260 // qCDebug(NMQT) << property << " - " << value;
261
262 if (property == QLatin1String("Connection")) {
263 connection = NetworkManager::findConnection(qdbus_cast<QDBusObjectPath>(value).path());
264 Q_EMIT q->connectionChanged(connection);
265 const QString tmpId = connection->settings()->id();
266 const QString tmpType = connection->settings()->typeAsString(connection->settings()->connectionType());
267 if (tmpId != id) {
268 id = tmpId;
269 Q_EMIT q->idChanged(id);
270 }
271
272 if (tmpType != type) {
273 Q_EMIT q->typeChanged(NetworkManager::ConnectionSettings::typeFromString(type));
274 }
275 } else if (property == QLatin1String("Default")) {
276 default4 = value.toBool();
277 Q_EMIT q->default4Changed(default4);
278 } else if (property == QLatin1String("Default6")) {
279 default6 = value.toBool();
280 Q_EMIT q->default6Changed(default6);
281 } else if (property == QLatin1String("Dhcp4Config")) {
282 QDBusObjectPath dhcp4ConfigPathTmp = (value).value<QDBusObjectPath>();
283 if (dhcp4ConfigPathTmp.path().isNull()) {
284 dhcp4Config.clear();
285 dhcp4ConfigPath.clear();
286 } else if (!dhcp4Config || dhcp4Config->path() != dhcp4ConfigPathTmp.path()) {
287 dhcp4Config.clear();
288 dhcp4ConfigPath = dhcp4ConfigPathTmp.path();
289 }
290 Q_EMIT q->dhcp4ConfigChanged();
291 } else if (property == QLatin1String("Dhcp6Config")) {
292 QDBusObjectPath dhcp6ConfigPathTmp = (value).value<QDBusObjectPath>();
293 if (dhcp6ConfigPathTmp.path().isNull()) {
294 dhcp6Config.clear();
295 dhcp6ConfigPath.clear();
296 } else if (!dhcp6Config || dhcp6Config->path() != dhcp6ConfigPathTmp.path()) {
297 dhcp6Config.clear();
298 dhcp6ConfigPath = dhcp6ConfigPathTmp.path();
299 }
300 Q_EMIT q->dhcp6ConfigChanged();
301 } else if (property == QLatin1String("Ip4Config")) {
302 QDBusObjectPath ip4ConfigObjectPathTmp = (value).value<QDBusObjectPath>();
303 if (ip4ConfigObjectPathTmp.path().isNull() || ip4ConfigObjectPathTmp.path() == QLatin1String("/")) {
304 ipV4ConfigPath.clear();
305 } else {
306 ipV4ConfigPath = ip4ConfigObjectPathTmp.path();
307 }
308 ipV4Config = IpConfig();
309 Q_EMIT q->ipV4ConfigChanged();
310 } else if (property == QLatin1String("Ip6Config")) {
311 QDBusObjectPath ip6ConfigObjectPathTmp = (value).value<QDBusObjectPath>();
312 if (ip6ConfigObjectPathTmp.path().isNull() || ip6ConfigObjectPathTmp.path() == QLatin1String("/")) {
313 ipV6ConfigPath.clear();
314 } else {
315 ipV6ConfigPath = ip6ConfigObjectPathTmp.path();
316 }
317 ipV6Config = IpConfig();
318 Q_EMIT q->ipV6ConfigChanged();
319 } else if (property == QLatin1String("Id")) {
320 id = value.toString();
321 Q_EMIT q->idChanged(id);
322 } else if (property == QLatin1String("Type")) {
323 type = value.toString();
324 Q_EMIT q->typeChanged(NetworkManager::ConnectionSettings::typeFromString(type));
325 } else if (property == QLatin1String("Master")) {
326 master = qdbus_cast<QDBusObjectPath>(value).path();
327 Q_EMIT q->masterChanged(master);
328 } else if (property == QLatin1String("SpecificObject")) {
329 specificObject = qdbus_cast<QDBusObjectPath>(value).path();
330 Q_EMIT q->specificObjectChanged(specificObject);
331 } else if (property == QLatin1String("State")) {
332 state = NetworkManager::ActiveConnectionPrivate::convertActiveConnectionState(state: value.toUInt());
333 Q_EMIT q->stateChanged(state);
334 } else if (property == QLatin1String("Vpn")) {
335 vpn = value.toBool();
336 Q_EMIT q->vpnChanged(vpn);
337 } else if (property == QLatin1String("Uuid")) {
338 uuid = value.toString();
339 Q_EMIT q->uuidChanged(uuid);
340 } else if (property == QLatin1String("Devices")) {
341 devices.clear();
342 const QList<QDBusObjectPath> opList = qdbus_cast<QList<QDBusObjectPath>>(value);
343 for (const QDBusObjectPath &path : opList) {
344 devices.append(path.path());
345 }
346 Q_EMIT q->devicesChanged();
347 } else {
348 qCDebug(NMQT) << Q_FUNC_INFO << "Unhandled property" << property;
349 }
350}
351
352#include "moc_activeconnection.cpp"
353#include "moc_activeconnection_p.cpp"
354

source code of networkmanager-qt/src/activeconnection.cpp