1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the plugins of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qnetworkmanagerengine.h"
41#include "qnetworkmanagerservice.h"
42#include "../qnetworksession_impl.h"
43
44#include <QtNetwork/private/qnetworkconfiguration_p.h>
45
46#include <QtNetwork/qnetworksession.h>
47
48#include <QtCore/qdebug.h>
49
50#include <QtDBus>
51#include <QDBusConnection>
52#include <QDBusError>
53#include <QDBusInterface>
54#include <QDBusMessage>
55#include <QDBusReply>
56#include "../linux_common/qofonoservice_linux_p.h"
57
58#ifndef QT_NO_DBUS
59
60QT_BEGIN_NAMESPACE
61
62QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent)
63: QBearerEngineImpl(parent),
64 managerInterface(NULL),
65 systemSettings(NULL),
66 ofonoManager(NULL),
67 nmAvailable(false)
68{
69 qDBusRegisterMetaType<QNmSettingsMap>();
70
71 nmWatcher = new QDBusServiceWatcher(NM_DBUS_SERVICE,QDBusConnection::systemBus(),
72 QDBusServiceWatcher::WatchForRegistration |
73 QDBusServiceWatcher::WatchForUnregistration, this);
74 connect(sender: nmWatcher, SIGNAL(serviceRegistered(QString)),
75 receiver: this, SLOT(nmRegistered(QString)));
76 connect(sender: nmWatcher, SIGNAL(serviceUnregistered(QString)),
77 receiver: this, SLOT(nmUnRegistered(QString)));
78
79 ofonoWatcher = new QDBusServiceWatcher("org.ofono",QDBusConnection::systemBus(),
80 QDBusServiceWatcher::WatchForRegistration |
81 QDBusServiceWatcher::WatchForUnregistration, this);
82 connect(sender: ofonoWatcher, SIGNAL(serviceRegistered(QString)),
83 receiver: this, SLOT(ofonoRegistered(QString)));
84 connect(sender: ofonoWatcher, SIGNAL(serviceUnregistered(QString)),
85 receiver: this, SLOT(ofonoUnRegistered(QString)));
86
87 QDBusConnectionInterface *interface = QDBusConnection::systemBus().interface();
88
89 if (!interface) return;
90
91 if (interface->isServiceRegistered(serviceName: "org.ofono"))
92 QMetaObject::invokeMethod(obj: this, member: "ofonoRegistered", type: Qt::QueuedConnection);
93
94 if (interface->isServiceRegistered(NM_DBUS_SERVICE))
95 QMetaObject::invokeMethod(obj: this, member: "nmRegistered", type: Qt::QueuedConnection);
96}
97
98QNetworkManagerEngine::~QNetworkManagerEngine()
99{
100 qDeleteAll(c: connections);
101 connections.clear();
102 qDeleteAll(c: accessPoints);
103 accessPoints.clear();
104 qDeleteAll(c: wirelessDevices);
105 wirelessDevices.clear();
106 qDeleteAll(c: activeConnectionsList);
107 activeConnectionsList.clear();
108 qDeleteAll(c: interfaceDevices);
109 interfaceDevices.clear();
110
111 connectionInterfaces.clear();
112
113 qDeleteAll(c: ofonoContextManagers);
114 ofonoContextManagers.clear();
115
116 qDeleteAll(c: wiredDevices);
117 wiredDevices.clear();
118}
119
120void QNetworkManagerEngine::initialize()
121{
122 if (nmAvailable)
123 setupConfigurations();
124}
125
126void QNetworkManagerEngine::setupConfigurations()
127{
128 QMutexLocker locker(&mutex);
129 // Get active connections.
130 const auto acPaths = managerInterface->activeConnections();
131 for (const QDBusObjectPath &acPath : acPaths) {
132
133 if (activeConnectionsList.contains(akey: acPath.path()))
134 continue;
135
136 QNetworkManagerConnectionActive *activeConnection =
137 new QNetworkManagerConnectionActive(acPath.path(),this);
138 activeConnectionsList.insert(akey: acPath.path(), avalue: activeConnection);
139 connect(sender: activeConnection, SIGNAL(propertiesChanged(QMap<QString,QVariant>)),
140 receiver: this, SLOT(activeConnectionPropertiesChanged(QMap<QString,QVariant>)));
141
142 QStringList devices = activeConnection->devices();
143 if (!devices.isEmpty()) {
144 QNetworkManagerInterfaceDevice device(devices.at(i: 0),this);
145 connectionInterfaces.insert(akey: activeConnection->connection().path(),avalue: device.networkInterface());
146 }
147 }
148
149 // Get connections.
150 const auto settingsPaths = systemSettings->listConnections();
151 for (const QDBusObjectPath &settingsPath : settingsPaths) {
152 locker.unlock();
153 if (!hasIdentifier(id: settingsPath.path()))
154 newConnection(path: settingsPath, settings: systemSettings); //add system connection configs
155 locker.relock();
156 }
157
158 Q_EMIT updateCompleted();
159}
160
161bool QNetworkManagerEngine::networkManagerAvailable() const
162{
163 return nmAvailable;
164}
165
166QString QNetworkManagerEngine::getInterfaceFromId(const QString &settingsPath)
167{
168 return connectionInterfaces.value(akey: settingsPath);
169}
170
171bool QNetworkManagerEngine::hasIdentifier(const QString &id)
172{
173 QMutexLocker locker(&mutex);
174 return accessPointConfigurations.contains(akey: id);
175}
176
177void QNetworkManagerEngine::connectToId(const QString &id)
178{
179 QMutexLocker locker(&mutex);
180
181 QNetworkManagerSettingsConnection *connection = connectionFromId(id);
182
183 if (!connection)
184 return;
185
186 NMDeviceType connectionType = connection->getType();
187
188 QString dbusDevicePath;
189 const QString settingsPath = connection->path();
190 QString specificPath = configuredAccessPoints.key(avalue: settingsPath);
191
192 if (isConnectionActive(settingsPath))
193 return;
194
195 for (auto i = interfaceDevices.cbegin(), end = interfaceDevices.cend(); i != end; ++i) {
196 const auto type = i.value()->deviceType();
197 if (type == DEVICE_TYPE_ETHERNET || type == DEVICE_TYPE_WIFI || type == DEVICE_TYPE_MODEM) {
198 if (type == connectionType) {
199 dbusDevicePath = i.key();
200 break;
201 }
202 }
203 }
204
205 if (specificPath.isEmpty())
206 specificPath = "/";
207
208 managerInterface->activateConnection(connection: QDBusObjectPath(settingsPath),
209 device: QDBusObjectPath(dbusDevicePath), specificObject: QDBusObjectPath(specificPath));
210}
211
212void QNetworkManagerEngine::disconnectFromId(const QString &id)
213{
214 QMutexLocker locker(&mutex);
215
216 QNetworkManagerSettingsConnection *connection = connectionFromId(id);
217
218 if (!connection)
219 return;
220
221 QNmSettingsMap map = connection->getSettings();
222 bool connectionAutoconnect = map.value(akey: "connection").value(akey: "autoconnect",adefaultValue: true).toBool(); //if not present is true !!
223 if (connectionAutoconnect) { //autoconnect connections will simply be reconnected by nm
224 emit connectionError(id, error: QBearerEngineImpl::OperationNotSupported);
225 return;
226 }
227
228 for (auto i = activeConnectionsList.cbegin(), end = activeConnectionsList.cend(); i != end; ++i) {
229 if (id == i.value()->connection().path() && accessPointConfigurations.contains(akey: id)) {
230 managerInterface->deactivateConnection(connectionPath: QDBusObjectPath(i.key()));
231 break;
232 }
233 }
234}
235
236void QNetworkManagerEngine::requestUpdate()
237{
238 if (managerInterface && managerInterface->wirelessEnabled()) {
239 for (auto *wirelessDevice : qAsConst(t&: wirelessDevices))
240 wirelessDevice->requestScan();
241 }
242 QMetaObject::invokeMethod(obj: this, member: "updateCompleted", type: Qt::QueuedConnection);
243}
244
245void QNetworkManagerEngine::interfacePropertiesChanged(const QMap<QString, QVariant> &properties)
246{
247 QMutexLocker locker(&mutex);
248
249 for (auto i = properties.cbegin(), end = properties.cend(); i != end; ++i) {
250 if (i.key() == QLatin1String("ActiveConnections")) {
251 // Active connections changed, update configurations.
252
253 const auto activeConnections = qdbus_cast<QList<QDBusObjectPath> >(arg: qvariant_cast<QDBusArgument>(v: i.value()));
254
255 QStringList identifiers = accessPointConfigurations.keys();
256 QStringList priorActiveConnections = activeConnectionsList.keys();
257
258 for (const QDBusObjectPath &acPath : activeConnections) {
259 priorActiveConnections.removeOne(t: acPath.path());
260 QNetworkManagerConnectionActive *activeConnection =
261 activeConnectionsList.value(akey: acPath.path());
262
263 if (!activeConnection) {
264 activeConnection = new QNetworkManagerConnectionActive(acPath.path(),this);
265 activeConnectionsList.insert(akey: acPath.path(), avalue: activeConnection);
266
267 connect(sender: activeConnection, SIGNAL(propertiesChanged(QMap<QString,QVariant>)),
268 receiver: this, SLOT(activeConnectionPropertiesChanged(QMap<QString,QVariant>)));
269 }
270
271 const QString id = activeConnection->connection().path();
272
273 identifiers.removeOne(t: id);
274
275 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(akey: id);
276 if (ptr) {
277 ptr->mutex.lock();
278 if (activeConnection->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED &&
279 (ptr->state & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) {
280
281 ptr->state |= QNetworkConfiguration::Active;
282
283 if (activeConnectionsList.value(akey: id) && activeConnectionsList.value(akey: id)->defaultRoute()
284 && managerInterface->state() < QNetworkManagerInterface::NM_STATE_CONNECTED_GLOBAL) {
285 ptr->purpose = QNetworkConfiguration::PrivatePurpose;
286 }
287 ptr->mutex.unlock();
288
289 locker.unlock();
290 emit configurationChanged(config: ptr);
291 locker.relock();
292 } else {
293 ptr->mutex.unlock();
294 }
295 }
296 }
297
298 while (!priorActiveConnections.isEmpty())
299 delete activeConnectionsList.take(akey: priorActiveConnections.takeFirst());
300
301 while (!identifiers.isEmpty()) {
302 QNetworkConfigurationPrivatePointer ptr =
303 accessPointConfigurations.value(akey: identifiers.takeFirst());
304
305 ptr->mutex.lock();
306 if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
307 QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined;
308 ptr->state = (flag | QNetworkConfiguration::Discovered);
309 ptr->mutex.unlock();
310
311 locker.unlock();
312 emit configurationChanged(config: ptr);
313 locker.relock();
314 } else {
315 ptr->mutex.unlock();
316 }
317 }
318 }
319 }
320}
321
322void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QMap<QString, QVariant> &properties)
323{
324 QMutexLocker locker(&mutex);
325
326 Q_UNUSED(properties)
327
328 QNetworkManagerConnectionActive *activeConnection = qobject_cast<QNetworkManagerConnectionActive *>(object: sender());
329
330 if (!activeConnection)
331 return;
332
333 const QString id = activeConnection->connection().path();
334
335 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(akey: id);
336 if (ptr) {
337 if (properties.contains(QStringLiteral("State"))) {
338 ptr->mutex.lock();
339 if (properties.value(akey: "State").toUInt() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
340 QStringList devices = activeConnection->devices();
341 if (!devices.isEmpty()) {
342 QNetworkManagerInterfaceDevice device(devices.at(i: 0),this);
343 connectionInterfaces.insert(akey: id,avalue: device.networkInterface());
344 }
345
346 ptr->state |= QNetworkConfiguration::Active;
347 ptr->mutex.unlock();
348
349 locker.unlock();
350 emit configurationChanged(config: ptr);
351 locker.relock();
352 } else {
353 connectionInterfaces.remove(akey: id);
354 ptr->mutex.unlock();
355 }
356 }
357 }
358}
359
360void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &connectionsList)
361{
362 QMutexLocker locker(&mutex);
363 for (int i = 0; i < connections.count(); ++i) {
364 if (connectionsList.contains(str: connections.at(i)->path()))
365 continue;
366
367 const QString settingsPath = connections.at(i)->path();
368
369 QNetworkConfigurationPrivatePointer ptr =
370 accessPointConfigurations.value(akey: settingsPath);
371 ptr->mutex.lock();
372 QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined;
373 ptr->state = (flag | QNetworkConfiguration::Discovered);
374 ptr->mutex.unlock();
375
376 locker.unlock();
377 emit configurationChanged(config: ptr);
378 locker.relock();
379 Q_EMIT updateCompleted();
380 }
381}
382
383void QNetworkManagerEngine::wiredCarrierChanged(bool carrier)
384{
385 QNetworkManagerInterfaceDeviceWired *deviceWired = qobject_cast<QNetworkManagerInterfaceDeviceWired *>(object: sender());
386 if (!deviceWired)
387 return;
388 QMutexLocker locker(&mutex);
389 const auto settingsPaths = systemSettings->listConnections();
390 for (const QDBusObjectPath &settingsPath : settingsPaths) {
391 for (int i = 0; i < connections.count(); ++i) {
392 QNetworkManagerSettingsConnection *connection = connections.at(i);
393 if (connection->getType() == DEVICE_TYPE_ETHERNET
394 && settingsPath.path() == connection->path()) {
395 QNetworkConfigurationPrivatePointer ptr =
396 accessPointConfigurations.value(akey: settingsPath.path());
397
398 if (ptr) {
399 ptr->mutex.lock();
400 if (carrier)
401 ptr->state |= QNetworkConfiguration::Discovered;
402 else
403 ptr->state = QNetworkConfiguration::Defined;
404 ptr->mutex.unlock();
405 locker.unlock();
406 emit configurationChanged(config: ptr);
407 return;
408 }
409 }
410 }
411 }
412}
413
414void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path,
415 QNetworkManagerSettings *settings)
416{
417 QMutexLocker locker(&mutex);
418 if (!settings)
419 settings = qobject_cast<QNetworkManagerSettings *>(object: sender());
420
421 if (!settings) {
422 return;
423 }
424
425 QNetworkManagerSettingsConnection *connection =
426 new QNetworkManagerSettingsConnection(settings->service(),
427 path.path(),this);
428 const QString settingsPath = connection->path();
429 if (accessPointConfigurations.contains(akey: settingsPath)) {
430 return;
431 }
432
433 connections.append(t: connection);
434
435 connect(sender: connection,SIGNAL(removed(QString)),receiver: this,SLOT(removeConnection(QString)));
436 connect(sender: connection,SIGNAL(updated()),receiver: this,SLOT(updateConnection()));
437 connection->setConnections();
438
439 NMDeviceType deviceType = connection->getType();
440
441 if (deviceType == DEVICE_TYPE_WIFI) {
442 QString apPath;
443 for (int i = 0; i < accessPoints.count(); ++i) {
444 if (connection->getSsid() == accessPoints.at(i)->ssid()) {
445 // remove the corresponding accesspoint from configurations
446 apPath = accessPoints.at(i)->path();
447 QNetworkConfigurationPrivatePointer ptr
448 = accessPointConfigurations.take(akey: apPath);
449 if (ptr) {
450 locker.unlock();
451 emit configurationRemoved(config: ptr);
452 locker.relock();
453 }
454 }
455 }
456 if (!configuredAccessPoints.contains(akey: settingsPath))
457 configuredAccessPoints.insert(akey: apPath,avalue: settingsPath);
458 }
459
460 QNetworkConfigurationPrivate *cpPriv =
461 parseConnection(settingsPath, map: connection->getSettings());
462
463 // Check if connection is active.
464 if (isConnectionActive(settingsPath))
465 cpPriv->state |= QNetworkConfiguration::Active;
466
467 if (deviceType == DEVICE_TYPE_ETHERNET) {
468 for (auto interfaceDevice : qAsConst(t&: interfaceDevices)) {
469 if (interfaceDevice->deviceType() == deviceType) {
470 auto *wiredDevice = wiredDevices.value(akey: interfaceDevice->path());
471 if (wiredDevice && wiredDevice->carrier()) {
472 cpPriv->state |= QNetworkConfiguration::Discovered;
473 }
474 }
475 }
476 }
477
478 QNetworkConfigurationPrivatePointer ptr(cpPriv);
479 accessPointConfigurations.insert(akey: ptr->id, avalue: ptr);
480 locker.unlock();
481 emit configurationAdded(config: ptr);
482}
483
484bool QNetworkManagerEngine::isConnectionActive(const QString &settingsPath) const
485{
486 for (QNetworkManagerConnectionActive *activeConnection : activeConnectionsList) {
487 if (activeConnection->connection().path() == settingsPath) {
488 const auto state = activeConnection->state();
489 if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING
490 || state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
491 return true;
492 } else {
493 break;
494 }
495 }
496 }
497
498 QNetworkManagerSettingsConnection *settingsConnection = connectionFromId(id: settingsPath);
499 if (settingsConnection && settingsConnection->getType() == DEVICE_TYPE_MODEM) {
500 return isActiveContext(contextPath: settingsConnection->path());
501 }
502
503 return false;
504}
505
506void QNetworkManagerEngine::removeConnection(const QString &path)
507{
508 QMutexLocker locker(&mutex);
509
510 QNetworkManagerSettingsConnection *connection =
511 qobject_cast<QNetworkManagerSettingsConnection *>(object: sender());
512
513 if (!connection)
514 return;
515
516 connection->deleteLater();
517 connections.removeAll(t: connection);
518
519 const QString id = path;
520
521 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(akey: id);
522
523 if (ptr) {
524 locker.unlock();
525 emit configurationRemoved(config: ptr);
526 locker.relock();
527 }
528
529 // add base AP back into configurations
530
531 // removed along with all AP props code...
532}
533
534void QNetworkManagerEngine::updateConnection()
535{
536 QMutexLocker locker(&mutex);
537
538 QNetworkManagerSettingsConnection *connection =
539 qobject_cast<QNetworkManagerSettingsConnection *>(object: sender());
540 if (!connection)
541 return;
542 const QString settingsPath = connection->path();
543
544 QNetworkConfigurationPrivate *cpPriv = parseConnection(settingsPath, map: connection->getSettings());
545
546 // Check if connection is active.
547 const auto acPaths = managerInterface->activeConnections();
548 for (const QDBusObjectPath &acPath : acPaths) {
549 QNetworkManagerConnectionActive activeConnection(acPath.path());
550
551 if (activeConnection.connection().path() == settingsPath &&
552 activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
553 cpPriv->state |= QNetworkConfiguration::Active;
554 break;
555 }
556 }
557
558 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(akey: cpPriv->id);
559
560 ptr->mutex.lock();
561
562 ptr->isValid = cpPriv->isValid;
563 ptr->name = cpPriv->name;
564 ptr->id = cpPriv->id;
565 ptr->state = cpPriv->state;
566
567 ptr->mutex.unlock();
568
569 locker.unlock();
570 emit configurationChanged(config: ptr);
571 locker.relock();
572 delete cpPriv;
573}
574
575void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher)
576{
577 QMutexLocker locker(&mutex);
578 QDBusPendingReply<QDBusObjectPath> reply(*watcher);
579 watcher->deleteLater();
580
581 if (!reply.isError()) {
582 QDBusObjectPath result = reply.value();
583
584 QNetworkManagerConnectionActive activeConnection(result.path());
585
586 const QString id = activeConnection.connection().path();
587
588 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(akey: id);
589 if (ptr) {
590 ptr->mutex.lock();
591 if (activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED &&
592 ptr->state != QNetworkConfiguration::Active) {
593 ptr->state |= QNetworkConfiguration::Active;
594 ptr->mutex.unlock();
595
596 locker.unlock();
597 emit configurationChanged(config: ptr);
598 locker.relock();
599 } else {
600 ptr->mutex.unlock();
601 }
602 }
603 }
604}
605
606QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QString &settingsPath,
607 const QNmSettingsMap &map)
608{
609 QMutexLocker locker(&mutex);
610 QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate;
611 cpPriv->name = map.value(akey: "connection").value(akey: "id").toString();
612 cpPriv->isValid = true;
613 cpPriv->id = settingsPath;
614 cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
615
616 cpPriv->purpose = QNetworkConfiguration::PublicPurpose;
617
618 cpPriv->state = QNetworkConfiguration::Defined;
619 const QString connectionType = map.value(akey: "connection").value(akey: "type").toString();
620
621 if (connectionType == QLatin1String("802-3-ethernet")) {
622 cpPriv->bearerType = QNetworkConfiguration::BearerEthernet;
623
624 const auto devicePaths = managerInterface->getDevices();
625 for (const QDBusObjectPath &devicePath : devicePaths) {
626 QNetworkManagerInterfaceDevice device(devicePath.path(),this);
627 if (device.deviceType() == DEVICE_TYPE_ETHERNET) {
628 QNetworkManagerInterfaceDeviceWired *wiredDevice = wiredDevices.value(akey: device.path());
629 if (wiredDevice && wiredDevice->carrier()) {
630 cpPriv->state |= QNetworkConfiguration::Discovered;
631 break;
632 }
633 }
634 }
635 } else if (connectionType == QLatin1String("802-11-wireless")) {
636 cpPriv->bearerType = QNetworkConfiguration::BearerWLAN;
637
638 const QString connectionSsid = map.value(akey: "802-11-wireless").value(akey: "ssid").toString();
639 for (int i = 0; i < accessPoints.count(); ++i) {
640 if (connectionSsid == accessPoints.at(i)->ssid()
641 && map.value(akey: "802-11-wireless").value(akey: "seen-bssids").toStringList().contains(str: accessPoints.at(i)->hwAddress())) {
642 cpPriv->state |= QNetworkConfiguration::Discovered;
643 if (!configuredAccessPoints.contains(akey: accessPoints.at(i)->path())) {
644 configuredAccessPoints.insert(akey: accessPoints.at(i)->path(),avalue: settingsPath);
645
646 const QString accessPointId = accessPoints.at(i)->path();
647 QNetworkConfigurationPrivatePointer ptr =
648 accessPointConfigurations.take(akey: accessPointId);
649
650 if (ptr) {
651 locker.unlock();
652 emit configurationRemoved(config: ptr);
653 locker.relock();
654 }
655 }
656 break;
657 }
658 }
659 } else if (connectionType == QLatin1String("gsm")) {
660
661 const QString connectionPath = map.value(akey: "connection").value(akey: "id").toString();
662 cpPriv->name = contextName(path: connectionPath);
663 cpPriv->bearerType = currentBearerType(id: connectionPath);
664
665 if (ofonoManager && ofonoManager->isValid()) {
666 const QString contextPart = connectionPath.section(asep: '/', astart: -1);
667 for (auto i = ofonoContextManagers.cbegin(), end = ofonoContextManagers.cend(); i != end; ++i) {
668 const QString path = i.key() + QLatin1Char('/') +contextPart;
669 if (isActiveContext(contextPath: path)) {
670 cpPriv->state |= QNetworkConfiguration::Active;
671 break;
672 }
673 }
674 }
675 }
676
677 return cpPriv;
678}
679
680bool QNetworkManagerEngine::isActiveContext(const QString &contextPath) const
681{
682 if (ofonoManager && ofonoManager->isValid()) {
683 const QString contextPart = contextPath.section(asep: '/', astart: -1);
684 for (QOfonoDataConnectionManagerInterface *iface : ofonoContextManagers) {
685 const PathPropertiesList list = iface->contextsWithProperties();
686 for (int i = 0; i < list.size(); ++i) {
687 if (list.at(i).path.path().contains(s: contextPart)) {
688 return list.at(i).properties.value(QStringLiteral("Active")).toBool();
689
690 }
691 }
692 }
693 }
694 return false;
695}
696
697QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const QString &id) const
698{
699 for (int i = 0; i < connections.count(); ++i) {
700 QNetworkManagerSettingsConnection *connection = connections.at(i);
701 if (id == connection->path())
702 return connection;
703 }
704
705 return 0;
706}
707
708QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &id)
709{
710 QMutexLocker locker(&mutex);
711 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(akey: id);
712
713 if (!ptr)
714 return QNetworkSession::Invalid;
715
716 if (!ptr->isValid)
717 return QNetworkSession::Invalid;
718
719 for (QNetworkManagerConnectionActive *activeConnection : qAsConst(t&: activeConnectionsList)) {
720 const QString identifier = activeConnection->connection().path();
721
722 if (id == identifier) {
723 switch (activeConnection->state()) {
724 case 0:
725 return QNetworkSession::Disconnected;
726 case 1:
727 return QNetworkSession::Connecting;
728 case 2:
729 return QNetworkSession::Connected;
730 }
731 }
732 }
733
734 if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered)
735 return QNetworkSession::Disconnected;
736 else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined)
737 return QNetworkSession::NotAvailable;
738 else if ((ptr->state & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined)
739 return QNetworkSession::NotAvailable;
740
741 return QNetworkSession::Invalid;
742}
743
744quint64 QNetworkManagerEngine::bytesWritten(const QString &id)
745{
746 QMutexLocker locker(&mutex);
747
748 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(akey: id);
749 if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
750 const QString networkInterface = connectionInterfaces.value(akey: id);
751 if (!networkInterface.isEmpty()) {
752 const QString devFile = QLatin1String("/sys/class/net/") +
753 networkInterface +
754 QLatin1String("/statistics/tx_bytes");
755
756 quint64 result = Q_UINT64_C(0);
757
758 QFile tx(devFile);
759 if (tx.open(flags: QIODevice::ReadOnly | QIODevice::Text)) {
760 QTextStream in(&tx);
761 in >> result;
762 tx.close();
763 }
764
765 return result;
766 }
767 }
768
769 return Q_UINT64_C(0);
770}
771
772quint64 QNetworkManagerEngine::bytesReceived(const QString &id)
773{
774 QMutexLocker locker(&mutex);
775
776 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(akey: id);
777 if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
778 const QString networkInterface = connectionInterfaces.value(akey: id);
779 if (!networkInterface.isEmpty()) {
780 const QString devFile = QLatin1String("/sys/class/net/") +
781 networkInterface +
782 QLatin1String("/statistics/rx_bytes");
783
784 quint64 result = Q_UINT64_C(0);
785
786 QFile tx(devFile);
787 if (tx.open(flags: QIODevice::ReadOnly | QIODevice::Text)) {
788 QTextStream in(&tx);
789 in >> result;
790 tx.close();
791 }
792
793 return result;
794 }
795 }
796
797 return Q_UINT64_C(0);
798}
799
800quint64 QNetworkManagerEngine::startTime(const QString &id)
801{
802 QMutexLocker locker(&mutex);
803
804 QNetworkManagerSettingsConnection *connection = connectionFromId(id);
805 if (connection)
806 return connection->getTimestamp();
807 else
808 return Q_UINT64_C(0);
809}
810
811QNetworkConfigurationManager::Capabilities QNetworkManagerEngine::capabilities() const
812{
813 return QNetworkConfigurationManager::ForcedRoaming |
814 QNetworkConfigurationManager::DataStatistics |
815 QNetworkConfigurationManager::CanStartAndStopInterfaces;
816}
817
818QNetworkSessionPrivate *QNetworkManagerEngine::createSessionBackend()
819{
820 return new QNetworkSessionPrivateImpl;
821}
822
823QNetworkConfigurationPrivatePointer QNetworkManagerEngine::defaultConfiguration()
824{
825 for (QNetworkManagerConnectionActive *activeConnection : qAsConst(t&: activeConnectionsList)) {
826 if ((activeConnection->defaultRoute() || activeConnection->default6Route())) {
827 return accessPointConfigurations.value(akey: activeConnection->connection().path());
828 }
829 }
830
831 return QNetworkConfigurationPrivatePointer();
832}
833
834QNetworkConfiguration::BearerType QNetworkManagerEngine::currentBearerType(const QString &id) const
835{
836 QString contextPart = id.section(asep: '/', astart: -1);
837 for (auto i = ofonoContextManagers.begin(), end = ofonoContextManagers.end(); i != end; ++i) {
838 QString contextPath = i.key() + QLatin1Char('/') +contextPart;
839
840 if (i.value()->contexts().contains(str: contextPath)) {
841
842 QString bearer = i.value()->bearer();
843
844 if (bearer == QLatin1String("gsm")) {
845 return QNetworkConfiguration::Bearer2G;
846 } else if (bearer == QLatin1String("edge")) {
847 return QNetworkConfiguration::Bearer2G;
848 } else if (bearer == QLatin1String("umts")) {
849 return QNetworkConfiguration::BearerWCDMA;
850 } else if (bearer == QLatin1String("hspa")
851 || bearer == QLatin1String("hsdpa")
852 || bearer == QLatin1String("hsupa")) {
853 return QNetworkConfiguration::BearerHSPA;
854 } else if (bearer == QLatin1String("lte")) {
855 return QNetworkConfiguration::BearerLTE;
856 }
857 }
858 }
859
860 return QNetworkConfiguration::BearerUnknown;
861}
862
863QString QNetworkManagerEngine::contextName(const QString &path) const
864{
865 QString contextPart = path.section(asep: '/', astart: -1);
866 for (QOfonoDataConnectionManagerInterface *iface : ofonoContextManagers) {
867 const PathPropertiesList list = iface->contextsWithProperties();
868 for (int i = 0; i < list.size(); ++i) {
869 if (list.at(i).path.path().contains(s: contextPart)) {
870 return list.at(i).properties.value(QStringLiteral("Name")).toString();
871 }
872 }
873 }
874 return path;
875}
876
877void QNetworkManagerEngine::nmRegistered(const QString &)
878{
879 if (ofonoManager) {
880 delete ofonoManager;
881 ofonoManager = NULL;
882 }
883 managerInterface = new QNetworkManagerInterface(this);
884 systemSettings = new QNetworkManagerSettings(NM_DBUS_SERVICE, this);
885
886 connect(sender: managerInterface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)),
887 receiver: this, SLOT(activationFinished(QDBusPendingCallWatcher*)));
888 connect(sender: managerInterface, SIGNAL(propertiesChanged(QMap<QString,QVariant>)),
889 receiver: this, SLOT(interfacePropertiesChanged(QMap<QString,QVariant>)));
890 managerInterface->setConnections();
891
892 connect(sender: systemSettings, SIGNAL(newConnection(QDBusObjectPath)),
893 receiver: this, SLOT(newConnection(QDBusObjectPath)));
894 systemSettings->setConnections();
895 nmAvailable = true;
896
897 setupConfigurations();
898}
899
900void QNetworkManagerEngine::nmUnRegistered(const QString &)
901{
902 if (systemSettings) {
903 delete systemSettings;
904 systemSettings = NULL;
905 }
906 if (managerInterface) {
907 delete managerInterface;
908 managerInterface = NULL;
909 }
910}
911
912void QNetworkManagerEngine::ofonoRegistered(const QString &)
913{
914 if (ofonoManager) {
915 delete ofonoManager;
916 ofonoManager = NULL;
917 }
918 ofonoManager = new QOfonoManagerInterface(this);
919 if (ofonoManager && ofonoManager->isValid()) {
920 const auto modems = ofonoManager->getModems();
921 for (const QString &modem : modems) {
922 QOfonoDataConnectionManagerInterface *ofonoContextManager
923 = new QOfonoDataConnectionManagerInterface(modem,this);
924 ofonoContextManagers.insert(akey: modem, avalue: ofonoContextManager);
925 }
926 }
927}
928
929void QNetworkManagerEngine::ofonoUnRegistered(const QString &)
930{
931 ofonoContextManagers.clear();
932}
933
934QT_END_NAMESPACE
935
936#endif // QT_NO_DBUS
937

source code of qtbase/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp