diff options
Diffstat (limited to 'src/plugins/bearer/connman/qconnmanengine.cpp')
-rw-r--r-- | src/plugins/bearer/connman/qconnmanengine.cpp | 401 |
1 files changed, 197 insertions, 204 deletions
diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index eac0d2b813..aee56eb034 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -41,7 +41,6 @@ #include "qconnmanengine.h" #include "qconnmanservice_linux_p.h" -#include "qofonoservice_linux_p.h" #include "../qnetworksession_impl.h" #include <QtNetwork/private/qnetworkconfiguration_p.h> @@ -55,7 +54,11 @@ #include <QtDBus/QDBusInterface> #include <QtDBus/QDBusMessage> #include <QtDBus/QDBusReply> - +#ifdef QT_HAS_CONNECTIONAGENT +#include <sys/inotify.h> +#include <fcntl.h> +#include <qcore_unix_p.h> +#endif #ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_DBUS @@ -63,7 +66,10 @@ QT_BEGIN_NAMESPACE QConnmanEngine::QConnmanEngine(QObject *parent) : QBearerEngineImpl(parent), - connmanManager(new QConnmanManagerInterface(this)) + connmanManager(new QConnmanManagerInterface(this)), + ofonoManager(new QOfonoManagerInterface(this)), + ofonoNetwork(0), + ofonoContextManager(0) { qDBusRegisterMetaType<ConnmanMap>(); qDBusRegisterMetaType<ConnmanMapList>(); @@ -72,6 +78,9 @@ QConnmanEngine::QConnmanEngine(QObject *parent) QConnmanEngine::~QConnmanEngine() { +#ifdef QT_HAS_CONNECTIONAGENT + qt_safe_close(inotifyFileDescriptor); +#endif } bool QConnmanEngine::connmanAvailable() const @@ -82,26 +91,56 @@ bool QConnmanEngine::connmanAvailable() const void QConnmanEngine::initialize() { - connect(connmanManager,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), - this,SLOT(propertyChangedContext(QString,QString,QDBusVariant))); + QMutexLocker locker(&mutex); + connect(ofonoManager,SIGNAL(modemChanged()),this,SLOT(changedModem())); + + ofonoNetwork = new QOfonoNetworkRegistrationInterface(ofonoManager->currentModem(),this); + ofonoContextManager = new QOfonoDataConnectionManagerInterface(ofonoManager->currentModem(),this); + connect(ofonoContextManager,SIGNAL(roamingAllowedChanged(bool)),this,SLOT(reEvaluateCellular())); connect(connmanManager,SIGNAL(servicesChanged(ConnmanMapList, QList<QDBusObjectPath>)), this, SLOT(updateServices(ConnmanMapList, QList<QDBusObjectPath>))); - foreach (const QString &techPath, connmanManager->getTechnologies()) { - QConnmanTechnologyInterface *tech; - tech = new QConnmanTechnologyInterface(techPath, this); + connect(connmanManager,SIGNAL(servicesReady(QStringList)),this,SLOT(servicesReady(QStringList))); + connect(connmanManager,SIGNAL(scanFinished()),this,SLOT(finishedScan())); - connect(tech,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), - this,SLOT(technologyPropertyChangedContext(QString,QString,QDBusVariant))); + foreach (const QString &servPath, connmanManager->getServices()) { + addServiceConfiguration(servPath); + } + Q_EMIT updateCompleted(); +#ifdef QT_HAS_CONNECTIONAGENT + QSettings confFile(QStringLiteral("nemomobile"),QStringLiteral("connectionagent")); + + inotifyFileDescriptor = ::inotify_init(); + inotifyWatcher = ::inotify_add_watch(inotifyFileDescriptor, QFile::encodeName(confFile.fileName()), IN_MODIFY); + if (inotifyWatcher > 0) { + QSocketNotifier *notifier = new QSocketNotifier(inotifyFileDescriptor, QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), this, SLOT(inotifyActivated())); } +#endif +} - foreach (const QString &servPath, connmanManager->getServices()) { +void QConnmanEngine::changedModem() +{ + QMutexLocker locker(&mutex); + if (ofonoNetwork) + delete ofonoNetwork; + + ofonoNetwork = new QOfonoNetworkRegistrationInterface(ofonoManager->currentModem(),this); + + if (ofonoContextManager) + delete ofonoContextManager; + ofonoContextManager = new QOfonoDataConnectionManagerInterface(ofonoManager->currentModem(),this); +} + +void QConnmanEngine::servicesReady(const QStringList &list) +{ + QMutexLocker locker(&mutex); + foreach (const QString &servPath, list) { addServiceConfiguration(servPath); } - // Get current list of access points. - getConfigurations(); + Q_EMIT updateCompleted(); } QList<QNetworkConfigurationPrivate *> QConnmanEngine::getConfigurations() @@ -129,13 +168,6 @@ QList<QNetworkConfigurationPrivate *> QConnmanEngine::getConfigurations() return fetchedConfigurations; } -void QConnmanEngine::doRequestUpdate() -{ - connmanManager->requestScan(""); - getConfigurations(); - emit updateCompleted(); -} - QString QConnmanEngine::getInterfaceFromId(const QString &id) { QMutexLocker locker(&mutex); @@ -151,24 +183,25 @@ bool QConnmanEngine::hasIdentifier(const QString &id) void QConnmanEngine::connectToId(const QString &id) { QMutexLocker locker(&mutex); - QString servicePath = serviceFromId(id); - QConnmanServiceInterface serv(servicePath); - if(!serv.isValid()) { + + QConnmanServiceInterface *serv = connmanServiceInterfaces.value(id); + + if (!serv->isValid()) { emit connectionError(id, QBearerEngineImpl::InterfaceLookupError); } else { - serv.connect(); + serv->connect(); } } void QConnmanEngine::disconnectFromId(const QString &id) { QMutexLocker locker(&mutex); - QString servicePath = serviceFromId(id); - QConnmanServiceInterface serv(servicePath); - if(!serv.isValid()) { + QConnmanServiceInterface *serv = connmanServiceInterfaces.value(id); + + if (!serv->isValid()) { emit connectionError(id, DisconnectionError); } else { - serv.disconnect(); + serv->disconnect(); } } @@ -178,31 +211,32 @@ void QConnmanEngine::requestUpdate() QTimer::singleShot(0, this, SLOT(doRequestUpdate())); } +void QConnmanEngine::doRequestUpdate() +{ + connmanManager->requestScan("wifi"); +} + +void QConnmanEngine::finishedScan() +{ +} + void QConnmanEngine::updateServices(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed) { + QMutexLocker locker(&mutex); + foreach (const QDBusObjectPath &objectPath, removed) { - removeConfiguration(QString::number(qHash(objectPath.path()))); + removeConfiguration(objectPath.path()); } foreach (const ConnmanMap &connmanMap, changed) { - const QString id = QString::number(qHash(connmanMap.objectPath.path())); + const QString id = connmanMap.objectPath.path(); if (accessPointConfigurations.contains(id)) { - configurationChange(id); + configurationChange(connmanServiceInterfaces.value(id)); } else { addServiceConfiguration(connmanMap.objectPath.path()); } } -} - -QString QConnmanEngine::serviceFromId(const QString &id) -{ - QMutexLocker locker(&mutex); - foreach (const QString &service, serviceNetworks) { - if (id == QString::number(qHash(service))) - return service; - } - - return QString(); + Q_EMIT updateCompleted(); } QNetworkSession::State QConnmanEngine::sessionStateForId(const QString &id) @@ -211,25 +245,24 @@ QNetworkSession::State QConnmanEngine::sessionStateForId(const QString &id) QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - if (!ptr) + if (!ptr || !ptr->isValid) return QNetworkSession::Invalid; - if (!ptr->isValid) { - return QNetworkSession::Invalid; + QString service = id; + QConnmanServiceInterface *serv = connmanServiceInterfaces.value(service); - } - QString service = serviceFromId(id); - QConnmanServiceInterface serv(service); - QString servState = serv.getState(); + QString servState = serv->state(); - if(serv.isFavorite() && (servState == "idle" || servState == "failure")) { + if (serv->favorite() && (servState == QLatin1String("idle") || servState == QLatin1String("failure"))) { return QNetworkSession::Disconnected; } - if(servState == "association" || servState == "configuration" || servState == "login") { + if (servState == QLatin1String("association") || servState == QLatin1String("configuration") + || servState == QLatin1String("ready")) { return QNetworkSession::Connecting; } - if(servState == "ready" || servState == "online") { + + if (servState == QLatin1String("online")) { return QNetworkSession::Connected; } @@ -300,88 +333,36 @@ QNetworkSessionPrivate *QConnmanEngine::createSessionBackend() QNetworkConfigurationPrivatePointer QConnmanEngine::defaultConfiguration() { - return QNetworkConfigurationPrivatePointer(); -} - -void QConnmanEngine::propertyChangedContext(const QString &path,const QString &item, const QDBusVariant &value) -{ - Q_UNUSED(path); - - QMutexLocker locker(&mutex); - if(item == "Services") { - QDBusArgument arg = qvariant_cast<QDBusArgument>(value.variant()); - QStringList list = qdbus_cast<QStringList>(arg); - - if(list.count() > accessPointConfigurations.count()) { - foreach (const QString &service, list) { - addServiceConfiguration(service); - } - } - } - - if(item == "Technologies") { - QDBusArgument arg = qvariant_cast<QDBusArgument>(value.variant()); - QStringList newlist = qdbus_cast<QStringList>(arg); - if(newlist.count() > 0) { - QMap<QString,QConnmanTechnologyInterface *> oldtech = technologies; - - foreach (const QString &listPath, newlist) { - if(!oldtech.contains(listPath)) { - QConnmanTechnologyInterface *tech; - tech = new QConnmanTechnologyInterface(listPath,this); - connect(tech,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), - this,SLOT(technologyPropertyChangedContext(QString,QString,QDBusVariant))); - technologies.insert(listPath, tech); - } - } - } - } - if(item == "State") { -// qDebug() << value.variant(); - } -} - -void QConnmanEngine::servicePropertyChangedContext(const QString &path,const QString &item, const QDBusVariant &value) -{ - QMutexLocker locker(&mutex); - if(item == "State") { - configurationChange(QString::number(qHash(path))); - - if(value.variant().toString() == "failure") { - QConnmanServiceInterface serv(path); - emit connectionError(QString::number(qHash(path)), ConnectError); + const QMutexLocker locker(&mutex); + Q_FOREACH (const QString &servPath, connmanManager->getServices()) { + if (connmanServiceInterfaces.contains(servPath)) { + if (accessPointConfigurations.contains(servPath)) + return accessPointConfigurations.value(servPath); } } + return QNetworkConfigurationPrivatePointer(); } -void QConnmanEngine::technologyPropertyChangedContext(const QString & path, const QString &item, const QDBusVariant &value) +void QConnmanEngine::serviceStateChanged(const QString &state) { - if(item == "State") { - if(value.variant().toString() == "offline") { - QConnmanTechnologyInterface tech(path); - disconnect(&tech,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), - this,SLOT(technologyPropertyChangedContext(QString,QString,QDBusVariant))); + QConnmanServiceInterface *service = qobject_cast<QConnmanServiceInterface *>(sender()); + configurationChange(service); - technologies.remove(path); - } + if (state == QStringLiteral("failure")) { + emit connectionError(service->path(), ConnectError); } } -void QConnmanEngine::configurationChange(const QString &id) +void QConnmanEngine::configurationChange(QConnmanServiceInterface *serv) { QMutexLocker locker(&mutex); + QString id = serv->path(); if (accessPointConfigurations.contains(id)) { bool changed = false; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - - QString servicePath = serviceFromId(id); - QConnmanServiceInterface *serv; - serv = new QConnmanServiceInterface(servicePath); - QString networkName = serv->getName(); - - QNetworkConfiguration::StateFlags curState = getStateForService(servicePath); - + QString networkName = serv->name(); + QNetworkConfiguration::StateFlags curState = getStateForService(serv->path()); ptr->mutex.lock(); if (!ptr->isValid) { @@ -414,26 +395,31 @@ void QConnmanEngine::configurationChange(const QString &id) QNetworkConfiguration::StateFlags QConnmanEngine::getStateForService(const QString &service) { QMutexLocker locker(&mutex); - QConnmanServiceInterface serv(service); + QConnmanServiceInterface *serv = connmanServiceInterfaces.value(service); + QString state = serv->state(); + QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined; - if (serv.getType() == "cellular") { - if (serv.isSetupRequired() || !serv.isAutoConnect() || (serv.isRoaming() && isAlwaysAskRoaming())) { - flag = ( flag | QNetworkConfiguration::Defined); + + if (serv->type() == QLatin1String("cellular")) { + + if (!serv->autoConnect() + || (serv->roaming() + && (isAlwaysAskRoaming() || !isRoamingAllowed(serv->path())))) { + flag = (flag | QNetworkConfiguration::Defined); } else { - flag = ( flag | QNetworkConfiguration::Discovered); + flag = (flag | QNetworkConfiguration::Discovered); } } else { - if (serv.isFavorite()) { - if (serv.isAutoConnect()) { - flag = ( flag | QNetworkConfiguration::Discovered); + if (serv->favorite()) { + if (serv->autoConnect()) { + flag = (flag | QNetworkConfiguration::Discovered); } } else { flag = QNetworkConfiguration::Undefined; } } - - if (serv.getState() == "ready" || serv.getState() == "online") { - flag = ( flag | QNetworkConfiguration::Active); + if (state == QLatin1String("online")) { + flag = (flag | QNetworkConfiguration::Active); } return flag; @@ -441,51 +427,35 @@ QNetworkConfiguration::StateFlags QConnmanEngine::getStateForService(const QStri QNetworkConfiguration::BearerType QConnmanEngine::typeToBearer(const QString &type) { - if (type == "wifi") + if (type == QLatin1String("wifi")) return QNetworkConfiguration::BearerWLAN; - if (type == "ethernet") + if (type == QLatin1String("ethernet")) return QNetworkConfiguration::BearerEthernet; - if (type == "bluetooth") + if (type == QLatin1String("bluetooth")) return QNetworkConfiguration::BearerBluetooth; - if (type == "cellular") { + if (type == QLatin1String("cellular")) { return ofonoTechToBearerType(type); } - if (type == "wimax") + if (type == QLatin1String("wimax")) return QNetworkConfiguration::BearerWiMAX; -// if(type == "gps") -// if(type == "vpn") - return QNetworkConfiguration::BearerUnknown; } QNetworkConfiguration::BearerType QConnmanEngine::ofonoTechToBearerType(const QString &/*type*/) { - QOfonoManagerInterface ofonoManager(this); - QOfonoNetworkRegistrationInterface ofonoNetwork(ofonoManager.currentModem().path(),this); - - if(ofonoNetwork.isValid()) { - foreach (const QDBusObjectPath &op,ofonoNetwork.getOperators() ) { - QOfonoNetworkOperatorInterface opIface(op.path(),this); - - foreach (const QString &opTech, opIface.getTechnologies()) { - - if(opTech == "gsm") { - return QNetworkConfiguration::Bearer2G; - } - if(opTech == "edge"){ - return QNetworkConfiguration::BearerCDMA2000; //wrong, I know - } - if(opTech == "umts"){ - return QNetworkConfiguration::BearerWCDMA; - } - if(opTech == "hspa"){ - return QNetworkConfiguration::BearerHSPA; - } - if(opTech == "lte"){ - return QNetworkConfiguration::BearerWiMAX; //not exact - } - } + if (ofonoNetwork) { + QString currentTechnology = ofonoNetwork->getTechnology(); + if (currentTechnology == QLatin1String("gsm")) { + return QNetworkConfiguration::Bearer2G; + } else if (currentTechnology == QLatin1String("edge")) { + return QNetworkConfiguration::BearerCDMA2000; //wrong, I know + } else if (currentTechnology == QLatin1String("umts")) { + return QNetworkConfiguration::BearerWCDMA; + } else if (currentTechnology == QLatin1String("hspa")) { + return QNetworkConfiguration::BearerHSPA; + } else if (currentTechnology == QLatin1String("lte")) { + return QNetworkConfiguration::BearerWiMAX; //not exact } } return QNetworkConfiguration::BearerUnknown; @@ -493,12 +463,9 @@ QNetworkConfiguration::BearerType QConnmanEngine::ofonoTechToBearerType(const QS bool QConnmanEngine::isRoamingAllowed(const QString &context) { - QOfonoManagerInterface ofonoManager(this); - QString modemPath = ofonoManager.currentModem().path(); - QOfonoDataConnectionManagerInterface dc(modemPath,this); - foreach (const QDBusObjectPath &dcPath,dc.getPrimaryContexts()) { - if(dcPath.path().contains(context.section("_",-1))) { - return dc.isRoamingAllowed(); + foreach (const QString &dcPath, ofonoContextManager->contexts()) { + if (dcPath.contains(context.section("_",-1))) { + return ofonoContextManager->roamingAllowed(); } } return false; @@ -510,14 +477,11 @@ void QConnmanEngine::removeConfiguration(const QString &id) if (accessPointConfigurations.contains(id)) { - QString service = serviceFromId(id); - QConnmanServiceInterface serv(service); - - disconnect(&serv,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), - this,SLOT(servicePropertyChangedContext(QString,QString,QDBusVariant))); - - serviceNetworks.removeOne(service); - + disconnect(connmanServiceInterfaces.value(id),SIGNAL(stateChanged(QString)), + this,SLOT(serviceStateChanged(QString))); + serviceNetworks.removeOne(id); + QConnmanServiceInterface *service = connmanServiceInterfaces.take(id); + delete service; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id); foundConfigurations.removeOne(ptr.data()); locker.unlock(); @@ -529,35 +493,32 @@ void QConnmanEngine::removeConfiguration(const QString &id) void QConnmanEngine::addServiceConfiguration(const QString &servicePath) { QMutexLocker locker(&mutex); - QConnmanServiceInterface *serv; - serv = new QConnmanServiceInterface(servicePath); + if (!connmanServiceInterfaces.contains(servicePath)) { + QConnmanServiceInterface *serv = new QConnmanServiceInterface(servicePath); + connmanServiceInterfaces.insert(serv->path(),serv); + } - const QString id = QString::number(qHash(servicePath)); + if (!accessPointConfigurations.contains(servicePath)) { - if (!accessPointConfigurations.contains(id)) { serviceNetworks.append(servicePath); - connect(serv,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), - this,SLOT(servicePropertyChangedContext(QString,QString,QDBusVariant))); + connect(connmanServiceInterfaces.value(servicePath),SIGNAL(stateChanged(QString)), + this,SLOT(serviceStateChanged(QString))); + QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); + QConnmanServiceInterface *service = connmanServiceInterfaces.value(servicePath); - QString networkName = serv->getName(); + QString networkName = service->name(); - const QString connectionType = serv->getType(); - if (connectionType == "ethernet") { + const QString connectionType = service->type(); + if (connectionType == QLatin1String("ethernet")) { cpPriv->bearerType = QNetworkConfiguration::BearerEthernet; - } else if (connectionType == "wifi") { + } else if (connectionType == QLatin1String("wifi")) { cpPriv->bearerType = QNetworkConfiguration::BearerWLAN; - } else if (connectionType == "cellular") { - cpPriv->bearerType = ofonoTechToBearerType("cellular"); - if(servicePath.isEmpty()) { - networkName = serv->getAPN(); - if(networkName.isEmpty()) { - networkName = serv->getName(); - } - } - cpPriv->roamingSupported = isRoamingAllowed(servicePath); - } else if (connectionType == "wimax") { + } else if (connectionType == QLatin1String("cellular")) { + cpPriv->bearerType = ofonoTechToBearerType(QLatin1String("cellular")); + cpPriv->roamingSupported = service->roaming() && isRoamingAllowed(servicePath); + } else if (connectionType == QLatin1String("wimax")) { cpPriv->bearerType = QNetworkConfiguration::BearerWiMAX; } else { cpPriv->bearerType = QNetworkConfiguration::BearerUnknown; @@ -565,10 +526,10 @@ void QConnmanEngine::addServiceConfiguration(const QString &servicePath) cpPriv->name = networkName; cpPriv->isValid = true; - cpPriv->id = id; + cpPriv->id = servicePath; cpPriv->type = QNetworkConfiguration::InternetAccessPoint; - if(serv->getSecurity() == "none") { + if (service->security() == QStringLiteral("none")) { cpPriv->purpose = QNetworkConfiguration::PublicPurpose; } else { cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; @@ -578,13 +539,16 @@ void QConnmanEngine::addServiceConfiguration(const QString &servicePath) QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ptr->id, ptr); - foundConfigurations.append(cpPriv); - configInterfaces[cpPriv->id] = serv->getInterface(); + if (connectionType == QLatin1String("cellular")) { + foundConfigurations.append(cpPriv); + } else { + foundConfigurations.prepend(cpPriv); + } + configInterfaces[cpPriv->id] = service->serviceInterface(); locker.unlock(); - emit configurationAdded(ptr); + Q_EMIT configurationAdded(ptr); locker.relock(); - emit updateCompleted(); } } @@ -595,10 +559,39 @@ bool QConnmanEngine::requiresPolling() const bool QConnmanEngine::isAlwaysAskRoaming() { - QSettings confFile(QStringLiteral("nemomobile"), QStringLiteral("connectionagent")); +#ifdef QT_HAS_CONNECTIONAGENT + QSettings confFile(QStringLiteral("nemomobile"),QStringLiteral("connectionagent")); confFile.beginGroup(QStringLiteral("Connectionagent")); return confFile.value(QStringLiteral("askForRoaming")).toBool(); +#else + return false; +#endif } + +void QConnmanEngine::reEvaluateCellular() +{ + Q_FOREACH (const QString &servicePath, connmanManager->getServices()) { + if (servicePath.contains("cellular") && accessPointConfigurations.contains(servicePath)) { + configurationChange(connmanServiceInterfaces.value(servicePath)); + } + } +} + +void QConnmanEngine::inotifyActivated() +{ +#ifdef QT_HAS_CONNECTIONAGENT + + char buffer[1024]; + int len = qt_safe_read(inotifyFileDescriptor, (void *)buffer, sizeof(buffer)); + if (len > 0) { + struct inotify_event *event = (struct inotify_event *)buffer; + if (event->wd == inotifyWatcher && (event->mask & IN_MODIFY) == 0) { + QTimer::singleShot(1000, this, SLOT(reEvaluateCellular())); //give this time to finish write + } + } +#endif +} + QT_END_NAMESPACE #endif // QT_NO_DBUS |