diff options
author | Lorn Potter <lorn.potter@gmail.com> | 2014-11-13 13:06:49 +1000 |
---|---|---|
committer | Lorn Potter <lorn.potter@gmail.com> | 2014-11-20 20:45:13 +0100 |
commit | f217a8096b3c6188dd1d1520d854f330dbb17264 (patch) | |
tree | 024b22aeda47911503e44e84e4e1df1af8e23525 /src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp | |
parent | f20af07e82f010273fd68b0545467c495e3c64f9 (diff) |
QtBearer networkmanager make sure to set flag Active
Also, no need to create objects to get properties, when the properties
can be had for free.
Make plugin more robust to network-manager or ofono crashes
Change-Id: Ibadb46bd51aa27f130f8d245e8c50aa7bff5f9c8
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Reviewed-by: Timo Jyrinki <timo.jyrinki@canonical.com>
Diffstat (limited to 'src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp')
-rw-r--r-- | src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp | 310 |
1 files changed, 211 insertions, 99 deletions
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index a8244f05cf..f0977b4735 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -56,29 +56,34 @@ QT_BEGIN_NAMESPACE QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) : QBearerEngineImpl(parent), - managerInterface(new QNetworkManagerInterface(this)), - systemSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this)), - ofonoManager(new QOfonoManagerInterface(this)) + managerInterface(NULL), + systemSettings(NULL), + ofonoManager(NULL), + nmAvailable(false) { - - if (!managerInterface->isValid()) - return; - qDBusRegisterMetaType<QNmSettingsMap>(); - connect(managerInterface, SIGNAL(deviceAdded(QDBusObjectPath)), - this, SLOT(deviceAdded(QDBusObjectPath))); - connect(managerInterface, SIGNAL(deviceRemoved(QDBusObjectPath)), - this, SLOT(deviceRemoved(QDBusObjectPath))); - connect(managerInterface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), - this, SLOT(activationFinished(QDBusPendingCallWatcher*))); - connect(managerInterface, SIGNAL(propertiesChanged(QMap<QString,QVariant>)), - this, SLOT(interfacePropertiesChanged(QMap<QString,QVariant>))); - managerInterface->setConnections(); - - connect(systemSettings, SIGNAL(newConnection(QDBusObjectPath)), - this, SLOT(newConnection(QDBusObjectPath))); - systemSettings->setConnections(); + nmWatcher = new QDBusServiceWatcher(NM_DBUS_SERVICE,QDBusConnection::systemBus(), + QDBusServiceWatcher::WatchForRegistration | + QDBusServiceWatcher::WatchForUnregistration, this); + connect(nmWatcher, SIGNAL(serviceRegistered(QString)), + this, SLOT(nmRegistered(QString))); + connect(nmWatcher, SIGNAL(serviceUnregistered(QString)), + this, SLOT(nmUnRegistered(QString))); + + ofonoWatcher = new QDBusServiceWatcher("org.ofono",QDBusConnection::systemBus(), + QDBusServiceWatcher::WatchForRegistration | + QDBusServiceWatcher::WatchForUnregistration, this); + connect(ofonoWatcher, SIGNAL(serviceRegistered(QString)), + this, SLOT(ofonoRegistered(QString))); + connect(ofonoWatcher, SIGNAL(serviceUnregistered(QString)), + this, SLOT(ofonoUnRegistered(QString))); + + if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.ofono")) + ofonoRegistered(); + + if (QDBusConnection::systemBus().interface()->isServiceRegistered(NM_DBUS_SERVICE)) + nmRegistered(); } QNetworkManagerEngine::~QNetworkManagerEngine() @@ -105,15 +110,13 @@ QNetworkManagerEngine::~QNetworkManagerEngine() void QNetworkManagerEngine::initialize() { - QMutexLocker locker(&mutex); + if (nmAvailable) + setupConfigurations(); +} - if (ofonoManager->isValid()) { - Q_FOREACH (const QString &modem, ofonoManager->getModems()) { - QOfonoDataConnectionManagerInterface *ofonoContextManager - = new QOfonoDataConnectionManagerInterface(modem,this); - ofonoContextManagers.insert(modem, ofonoContextManager); - } - } +void QNetworkManagerEngine::setupConfigurations() +{ + QMutexLocker locker(&mutex); // Get active connections. foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { @@ -151,7 +154,7 @@ void QNetworkManagerEngine::initialize() bool QNetworkManagerEngine::networkManagerAvailable() const { - return managerInterface->isValid(); + return nmAvailable; } QString QNetworkManagerEngine::getInterfaceFromId(const QString &settingsPath) @@ -180,6 +183,9 @@ void QNetworkManagerEngine::connectToId(const QString &id) const QString settingsPath = connection->connectionInterface()->path(); QString specificPath = configuredAccessPoints.key(settingsPath); + if (isConnectionActive(settingsPath)) + return; + QHashIterator<QString, QNetworkManagerInterfaceDevice*> i(interfaceDevices); while (i.hasNext()) { i.next(); @@ -229,7 +235,7 @@ void QNetworkManagerEngine::disconnectFromId(const QString &id) void QNetworkManagerEngine::requestUpdate() { - if (managerInterface->wirelessEnabled()) { + if (managerInterface && managerInterface->wirelessEnabled()) { QHashIterator<QString, QNetworkManagerInterfaceDeviceWireless *> i(wirelessDevices); while (i.hasNext()) { i.next(); @@ -282,8 +288,9 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QMap<QString, QVari if (ptr) { ptr->mutex.lock(); if (activeConnection->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED && - ptr->state != QNetworkConfiguration::Active) { - ptr->state = QNetworkConfiguration::Active; + (ptr->state & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) { + + ptr->state |= QNetworkConfiguration::Active; if (activeConnectionsList.value(id) && activeConnectionsList.value(id)->defaultRoute() && managerInterface->state() < QNetworkManagerInterface::NM_STATE_CONNECTED_GLOBAL) { @@ -339,23 +346,25 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QMap<QString QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); if (ptr) { - ptr->mutex.lock(); - if (properties.value("State").toUInt() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - QStringList devices = activeConnection->devices(); - if (!devices.isEmpty()) { - QNetworkManagerInterfaceDevice device(devices.at(0),this); - connectionInterfaces.insert(id,device.networkInterface()); - } + if (properties.contains(QStringLiteral("State"))) { + ptr->mutex.lock(); + if (properties.value("State").toUInt() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + QStringList devices = activeConnection->devices(); + if (!devices.isEmpty()) { + QNetworkManagerInterfaceDevice device(devices.at(0),this); + connectionInterfaces.insert(id,device.networkInterface()); + } - ptr->state |= QNetworkConfiguration::Active; - ptr->mutex.unlock(); + ptr->state |= QNetworkConfiguration::Active; + ptr->mutex.unlock(); - locker.unlock(); - emit configurationChanged(ptr); - locker.relock(); - } else { - connectionInterfaces.remove(id); - ptr->mutex.unlock(); + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); + } else { + connectionInterfaces.remove(id); + ptr->mutex.unlock(); + } } } } @@ -403,9 +412,6 @@ void QNetworkManagerEngine::deviceAdded(const QDBusObjectPath &path) connect(wirelessDevice,SIGNAL(scanDone()),this,SLOT(scanFinished())); wirelessDevice->setConnections(); - foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints()) - newAccessPoint(apPath.path()); - wirelessDevices.insert(path.path(), wirelessDevice); } @@ -518,14 +524,9 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, parseConnection(settingsPath, connection->getSettings()); // Check if connection is active. - QHashIterator<QString, QNetworkManagerConnectionActive*> i(activeConnectionsList); - while (i.hasNext()) { - i.next(); - if (i.value()->connection().path() == settingsPath) { - cpPriv->state |= QNetworkConfiguration::Active; - break; - } - } + if (isConnectionActive(settingsPath)) + cpPriv->state |= QNetworkConfiguration::Active; + if (deviceType == DEVICE_TYPE_ETHERNET) { QHashIterator<QString, QNetworkManagerInterfaceDevice*> i(interfaceDevices); while (i.hasNext()) { @@ -539,12 +540,36 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, } } } + QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ptr->id, ptr); locker.unlock(); emit configurationAdded(ptr); } +bool QNetworkManagerEngine::isConnectionActive(const QString &settingsPath) +{ + QHashIterator<QString, QNetworkManagerConnectionActive*> i(activeConnectionsList); + while (i.hasNext()) { + i.next(); + if (i.value()->connection().path() == settingsPath) { + if (i.value()->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATING + || i.value()->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + return true; + } else { + break; + } + } + } + + QNetworkManagerSettingsConnection *settingsConnection = connectionFromId(settingsPath); + if (settingsConnection->getType() == DEVICE_TYPE_MODEM) { + return isActiveContext(settingsConnection->connectionInterface()->path()); + } + + return false; +} + void QNetworkManagerEngine::removeConnection(const QString &path) { QMutexLocker locker(&mutex); @@ -652,7 +677,6 @@ void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher) void QNetworkManagerEngine::newAccessPoint(const QString &path) { QMutexLocker locker(&mutex); - QNetworkManagerInterfaceAccessPoint *accessPoint = new QNetworkManagerInterfaceAccessPoint(path,this); @@ -683,6 +707,9 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path) ptr->mutex.lock(); QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined; ptr->state = (flag | QNetworkConfiguration::Discovered); + + if (isConnectionActive(settingsPath)) + ptr->state = (flag | QNetworkConfiguration::Active); ptr->mutex.unlock(); locker.unlock(); @@ -762,7 +789,6 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri QMutexLocker locker(&mutex); QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate; cpPriv->name = map.value("connection").value("id").toString(); - cpPriv->isValid = true; cpPriv->id = settingsPath; cpPriv->type = QNetworkConfiguration::InternetAccessPoint; @@ -811,18 +837,46 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri } } else if (connectionType == QLatin1String("gsm")) { - const QString contextPath = map.value("connection").value("id").toString(); - cpPriv->name = contextName(contextPath); - cpPriv->bearerType = currentBearerType(contextPath); - - if (map.value("connection").contains("timestamp")) { - cpPriv->state |= QNetworkConfiguration::Discovered; + const QString connectionPath = map.value("connection").value("id").toString(); + cpPriv->name = contextName(connectionPath); + cpPriv->bearerType = currentBearerType(connectionPath); + + if (ofonoManager && ofonoManager->isValid()) { + const QString contextPart = connectionPath.section('/', -1); + QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers); + while (i.hasNext()) { + i.next(); + const QString path = i.key() +"/"+contextPart; + if (isActiveContext(path)) { + cpPriv->state |= QNetworkConfiguration::Active; + break; + } + } } } return cpPriv; } +bool QNetworkManagerEngine::isActiveContext(const QString &contextPath) +{ + if (ofonoManager && ofonoManager->isValid()) { + const QString contextPart = contextPath.section('/', -1); + QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers); + while (i.hasNext()) { + i.next(); + PathPropertiesList list = i.value()->contextsWithProperties(); + for (int i = 0; i < list.size(); ++i) { + if (list.at(i).path.path().contains(contextPart)) { + return list.at(i).properties.value(QStringLiteral("Active")).toBool(); + + } + } + } + } + return false; +} + QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const QString &id) const { for (int i = 0; i < connections.count(); ++i) { @@ -967,53 +1021,111 @@ QNetworkConfigurationPrivatePointer QNetworkManagerEngine::defaultConfiguration( QNetworkConfiguration::BearerType QNetworkManagerEngine::currentBearerType(const QString &id) { - if (ofonoManager->isValid()) { - QString contextPart = id.section('/', -1); - - QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers); - while (i.hasNext()) { - i.next(); - QString contextPath = i.key() +"/"+contextPart; - if (i.value()->contexts().contains(contextPath)) { - - QString bearer = i.value()->bearer(); - if (bearer == QStringLiteral("gsm")) { - return QNetworkConfiguration::Bearer2G; - } else if (bearer == QStringLiteral("edge")) { - return QNetworkConfiguration::Bearer2G; - } else if (bearer == QStringLiteral("umts")) { - return QNetworkConfiguration::BearerWCDMA; - } else if (bearer == QStringLiteral("hspa") - || bearer == QStringLiteral("hsdpa") - || bearer == QStringLiteral("hsupa")) { - return QNetworkConfiguration::BearerHSPA; - } else if (bearer == QStringLiteral("lte")) { - return QNetworkConfiguration::BearerLTE; - } + QString contextPart = id.section('/', -1); + QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers); + while (i.hasNext()) { + i.next(); + QString contextPath = i.key() +"/"+contextPart; + + if (i.value()->contexts().contains(contextPath)) { + + QString bearer = i.value()->bearer(); + + if (bearer == QStringLiteral("gsm")) { + return QNetworkConfiguration::Bearer2G; + } else if (bearer == QStringLiteral("edge")) { + return QNetworkConfiguration::Bearer2G; + } else if (bearer == QStringLiteral("umts")) { + return QNetworkConfiguration::BearerWCDMA; + } else if (bearer == QStringLiteral("hspa") + || bearer == QStringLiteral("hsdpa") + || bearer == QStringLiteral("hsupa")) { + return QNetworkConfiguration::BearerHSPA; + } else if (bearer == QStringLiteral("lte")) { + return QNetworkConfiguration::BearerLTE; } } } + return QNetworkConfiguration::BearerUnknown; } QString QNetworkManagerEngine::contextName(const QString &path) { - if (ofonoManager->isValid()) { - QString contextPart = path.section('/', -1); - QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers); - while (i.hasNext()) { - i.next(); - Q_FOREACH (const QString &oContext, i.value()->contexts()) { - if (oContext.contains(contextPart)) { - QOfonoConnectionContextInterface contextInterface(oContext,this); - return contextInterface.name(); - } + QString contextPart = path.section('/', -1); + QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers); + while (i.hasNext()) { + i.next(); + PathPropertiesList list = i.value()->contextsWithProperties(); + for (int i = 0; i < list.size(); ++i) { + if (list.at(i).path.path().contains(contextPart)) { + return list.at(i).properties.value(QStringLiteral("Name")).toString(); } } } return path; } +void QNetworkManagerEngine::nmRegistered(const QString &) +{ + if (ofonoManager) { + delete ofonoManager; + ofonoManager = NULL; + } + managerInterface = new QNetworkManagerInterface(this); + systemSettings = new QNetworkManagerSettings(NM_DBUS_SERVICE, this); + + connect(managerInterface, SIGNAL(deviceAdded(QDBusObjectPath)), + this, SLOT(deviceAdded(QDBusObjectPath))); + connect(managerInterface, SIGNAL(deviceRemoved(QDBusObjectPath)), + this, SLOT(deviceRemoved(QDBusObjectPath))); + connect(managerInterface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), + this, SLOT(activationFinished(QDBusPendingCallWatcher*))); + connect(managerInterface, SIGNAL(propertiesChanged(QMap<QString,QVariant>)), + this, SLOT(interfacePropertiesChanged(QMap<QString,QVariant>))); + managerInterface->setConnections(); + + connect(systemSettings, SIGNAL(newConnection(QDBusObjectPath)), + this, SLOT(newConnection(QDBusObjectPath))); + systemSettings->setConnections(); + nmAvailable = true; + + setupConfigurations(); +} + +void QNetworkManagerEngine::nmUnRegistered(const QString &) +{ + if (systemSettings) { + delete systemSettings; + systemSettings = NULL; + } + if (managerInterface) { + delete managerInterface; + managerInterface = NULL; + } +} + +void QNetworkManagerEngine::ofonoRegistered(const QString &) +{ + if (ofonoManager) { + delete ofonoManager; + ofonoManager = NULL; + } + ofonoManager = new QOfonoManagerInterface(this); + if (ofonoManager && ofonoManager->isValid()) { + Q_FOREACH (const QString &modem, ofonoManager->getModems()) { + QOfonoDataConnectionManagerInterface *ofonoContextManager + = new QOfonoDataConnectionManagerInterface(modem,this); + ofonoContextManagers.insert(modem, ofonoContextManager); + } + } +} + +void QNetworkManagerEngine::ofonoUnRegistered(const QString &) +{ + ofonoContextManagers.clear(); +} + QT_END_NAMESPACE #endif // QT_NO_DBUS |