qtmobility/src/bearer/qnmwifiengine_unix.cpp
changeset 0 cfcbf08528c4
child 1 5822d84012fb
equal deleted inserted replaced
-1:000000000000 0:cfcbf08528c4
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qnmwifiengine_unix_p.h"
       
    43 #include "qnetworkconfiguration_p.h"
       
    44 #include <qnetworkconfiguration.h>
       
    45 
       
    46 #include <QtCore/qstringlist.h>
       
    47 #include <QScopedPointer>
       
    48 
       
    49 #include <QtNetwork/qnetworkinterface.h>
       
    50 #include <qnetworkmanagerservice_p.h>
       
    51 
       
    52 #include <QNetworkInterface>
       
    53 
       
    54 QTM_BEGIN_NAMESPACE
       
    55 Q_GLOBAL_STATIC(QNmWifiEngine, nmWifiEngine)
       
    56 typedef  QList<QList<uint> > QNmSettingsAddressMap;
       
    57 QTM_END_NAMESPACE
       
    58 
       
    59 Q_DECLARE_METATYPE(QTM_PREPEND_NAMESPACE(QNmSettingsAddressMap))
       
    60 
       
    61 QTM_BEGIN_NAMESPACE
       
    62 
       
    63 QNmWifiEngine::QNmWifiEngine(QObject *parent)
       
    64 :   QNetworkSessionEngine(parent)
       
    65 {
       
    66     iface = new QNetworkManagerInterface(this);
       
    67     if(!iface->isValid()) {
       
    68         return;
       
    69     }
       
    70     iface->setConnections();
       
    71     connect(iface,SIGNAL(deviceAdded(QDBusObjectPath)),
       
    72             this,SLOT(addDevice(QDBusObjectPath)));
       
    73 //     connect(iface,SIGNAL(deviceRemoved(QDBusObjectPath)),
       
    74 //             this,SLOT(removeDevice(QDBusObjectPath)));
       
    75     connect(iface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)),
       
    76             this, SLOT(slotActivationFinished(QDBusPendingCallWatcher*)));
       
    77 
       
    78     QList<QDBusObjectPath> list = iface->getDevices();
       
    79 
       
    80     foreach(QDBusObjectPath path, list) {
       
    81         addDevice(path);
       
    82     }
       
    83 
       
    84     QStringList connectionServices;
       
    85     connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS;
       
    86     connectionServices << NM_DBUS_SERVICE_USER_SETTINGS;
       
    87     QNetworkManagerSettings *settingsiface;
       
    88     foreach (QString service, connectionServices) {
       
    89         settingsiface = new QNetworkManagerSettings(service, this);
       
    90         settingsiface->setConnections();
       
    91         connect(settingsiface,SIGNAL(newConnection(QDBusObjectPath)),
       
    92                 this,(SLOT(newConnection(QDBusObjectPath))));
       
    93     }
       
    94 
       
    95     updated = false;
       
    96 }
       
    97 
       
    98 QNmWifiEngine::~QNmWifiEngine()
       
    99 {
       
   100 }
       
   101 
       
   102 QString QNmWifiEngine::getNameForConfiguration(QNetworkManagerInterfaceDevice *devIface)
       
   103 {
       
   104     QString newname;
       
   105     if (devIface->state() == NM_DEVICE_STATE_ACTIVATED) {
       
   106         QString path = devIface->ip4config().path();
       
   107         QNetworkManagerIp4Config * ipIface;
       
   108         ipIface = new QNetworkManagerIp4Config(path);
       
   109         newname = ipIface->domains().join(" ");
       
   110         delete ipIface;
       
   111     }
       
   112     //fallback to interface name
       
   113     if(newname.isEmpty())
       
   114         newname = devIface->networkInterface().name();
       
   115     return newname;
       
   116 }
       
   117 
       
   118 
       
   119 QList<QNetworkConfigurationPrivate *> QNmWifiEngine::getConfigurations(bool *ok)
       
   120 {
       
   121     if (ok)
       
   122         *ok = false;
       
   123 
       
   124     if(!updated) {
       
   125         foundConfigurations.clear();
       
   126         if(knownSsids.isEmpty())
       
   127             updateKnownSsids(); 
       
   128 
       
   129         scanForAccessPoints();
       
   130         updateActiveConnectionsPaths();
       
   131         knownConnections();
       
   132 
       
   133         accessPointConnections();
       
   134 
       
   135         updated = true;
       
   136     }
       
   137     return foundConfigurations;
       
   138 }
       
   139 
       
   140 void QNmWifiEngine::knownConnections()
       
   141 {
       
   142     QStringList connectionServices;
       
   143     connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS;
       
   144     connectionServices << NM_DBUS_SERVICE_USER_SETTINGS;
       
   145 
       
   146     QString connPath;
       
   147 
       
   148     QScopedPointer<QNetworkManagerSettings> settingsiface;
       
   149     foreach (QString service, connectionServices) {
       
   150         QString ident;
       
   151         settingsiface.reset(new QNetworkManagerSettings(service));
       
   152         QList<QDBusObjectPath> list = settingsiface->listConnections();
       
   153 
       
   154         QNetworkManagerSettingsConnection *sysIface;
       
   155         foreach(QDBusObjectPath path, list) { 
       
   156             ident = path.path();
       
   157             bool addIt = false;
       
   158             QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
       
   159             sysIface = new QNetworkManagerSettingsConnection(service, path.path(), this);
       
   160             sysIface->setConnections();
       
   161             connect(sysIface, SIGNAL(removed(QString)),
       
   162                     this,SLOT(settingsConnectionRemoved(QString)));
       
   163 
       
   164             cpPriv->name = sysIface->getId();
       
   165             cpPriv->isValid = true;
       
   166             cpPriv->id = sysIface->getUuid();
       
   167             cpPriv->internet = true;
       
   168             cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
       
   169             cpPriv->state = getStateForId(cpPriv->id);
       
   170 
       
   171             cpPriv->purpose = QNetworkConfiguration::PrivatePurpose;
       
   172 
       
   173 
       
   174             if(sysIface->getType() == DEVICE_TYPE_802_3_ETHERNET) {
       
   175                 QString mac = sysIface->getMacAddress();
       
   176                 if(!mac.length() > 2) {
       
   177                     QString devPath;
       
   178                     devPath = deviceConnectionPath(mac);
       
   179 
       
   180                     QNetworkManagerInterfaceDevice devIface(devPath);
       
   181                     cpPriv->serviceInterface = devIface.networkInterface();
       
   182                     QScopedPointer<QNetworkManagerInterfaceDeviceWired> devWiredIface;
       
   183                     devWiredIface.reset(new QNetworkManagerInterfaceDeviceWired(devIface.connectionInterface()->path()));
       
   184                     cpPriv->internet = devWiredIface->carrier();
       
   185 
       
   186                     // use this mac addy
       
   187                 } else {
       
   188                     cpPriv->serviceInterface = getBestInterface( DEVICE_TYPE_802_3_ETHERNET, cpPriv->id);
       
   189                 }
       
   190 
       
   191                 cpPriv->internet = true;
       
   192 
       
   193                 addIt = true;
       
   194             } else if(sysIface->getType() == DEVICE_TYPE_802_11_WIRELESS) {
       
   195                 QString mac = sysIface->getMacAddress();;
       
   196                 if(!mac.length() > 2) {
       
   197                     QString devPath;
       
   198                     devPath = deviceConnectionPath(mac);
       
   199 
       
   200                     QNetworkManagerInterfaceDevice devIface(devPath);
       
   201                     cpPriv->serviceInterface = devIface.networkInterface();
       
   202                     // use this mac addy
       
   203                 } else {
       
   204                     cpPriv->serviceInterface = getBestInterface( DEVICE_TYPE_802_11_WIRELESS, cpPriv->id);
       
   205                 }
       
   206                 addIt = true;
       
   207                 // get the wifi interface state first.. do we need this?
       
   208                 //   QString activeAPPath = devWirelessIface->activeAccessPoint().path();
       
   209             }
       
   210             if(addIt) {
       
   211                 foundConfigurations.append(cpPriv);
       
   212                 configurationInterface[cpPriv->id] = cpPriv->serviceInterface.name();
       
   213                 cpPriv->bearer = bearerName(cpPriv->id);
       
   214             }
       
   215         } 
       
   216     }
       
   217 }
       
   218 
       
   219 void QNmWifiEngine::accessPointConnections()
       
   220 {
       
   221     QList<QDBusObjectPath> list = iface->getDevices();
       
   222     QScopedPointer<QNetworkManagerInterfaceDevice> devIface;
       
   223     foreach(QDBusObjectPath path, list) {
       
   224         devIface.reset(new QNetworkManagerInterfaceDevice(path.path()));
       
   225         if(devIface->deviceType() == DEVICE_TYPE_802_11_WIRELESS) {
       
   226             QList<QString> apList = availableAccessPoints.uniqueKeys();
       
   227 
       
   228             QList<QString>::const_iterator i;
       
   229             for (i = apList.constBegin(); i != apList.constEnd(); ++i) {
       
   230                 QNetworkConfigurationPrivate* cpPriv;
       
   231                 cpPriv = addAccessPoint( devIface->connectionInterface()->path(), availableAccessPoints[*i]);
       
   232                 if(cpPriv->isValid) {
       
   233                     foundConfigurations.append(cpPriv);
       
   234                     configurationInterface[cpPriv->id] = cpPriv->serviceInterface.name();
       
   235                     cpPriv->bearer = bearerName(cpPriv->id);
       
   236                 }
       
   237             }
       
   238         }
       
   239     }
       
   240 }
       
   241 
       
   242 QString QNmWifiEngine::getInterfaceFromId(const QString &id)
       
   243 {
       
   244     return configurationInterface.value(id);
       
   245 }
       
   246 
       
   247 bool QNmWifiEngine::hasIdentifier(const QString &id)
       
   248 {
       
   249     if (configurationInterface.contains(id))
       
   250         return true;
       
   251 
       
   252     return false;
       
   253 }
       
   254 
       
   255 QString QNmWifiEngine::bearerName(const QString &id)
       
   256 {
       
   257     QString interface = getInterfaceFromId(id);
       
   258     QScopedPointer<QNetworkManagerInterfaceDevice> devIface;
       
   259     QList<QDBusObjectPath> list = iface->getDevices();
       
   260     foreach(QDBusObjectPath path, list) {
       
   261         devIface.reset(new QNetworkManagerInterfaceDevice(path.path()));
       
   262 
       
   263         if(interface == devIface->networkInterface().name()) {
       
   264 
       
   265             switch(devIface->deviceType()) {
       
   266                 case DEVICE_TYPE_802_3_ETHERNET:
       
   267                     return QLatin1String("Ethernet");
       
   268                     break;
       
   269                 case DEVICE_TYPE_802_11_WIRELESS:
       
   270                     return QLatin1String("WLAN");
       
   271                     break;
       
   272                 case DEVICE_TYPE_GSM:
       
   273                     return QLatin1String("2G");
       
   274                     break;
       
   275                 case DEVICE_TYPE_CDMA:
       
   276                     return QLatin1String("CDMA2000");
       
   277                     break;
       
   278                 default:
       
   279                     break;
       
   280             }
       
   281         }
       
   282     }
       
   283     return QLatin1String("Unknown");
       
   284 }
       
   285 
       
   286 void QNmWifiEngine::connectToId(const QString &id)
       
   287 {
       
   288     activatingConnectionPath = id;
       
   289     QStringList connectionSettings = getConnectionPathForId(id);
       
   290     if(connectionSettings.isEmpty()) {
       
   291         emit connectionError(id, OperationNotSupported);
       
   292         return;
       
   293     }
       
   294 
       
   295     QDBusObjectPath connectionPath(connectionSettings.at(1));
       
   296     QString interface = getInterfaceFromId(id);
       
   297 
       
   298     interface = QNetworkInterface::interfaceFromName(interface).hardwareAddress().toLower();
       
   299     QString devPath;
       
   300     devPath = deviceConnectionPath(interface);
       
   301     QDBusObjectPath devicePath(devPath);
       
   302 
       
   303     iface->activateConnection(
       
   304             connectionSettings.at(0),
       
   305             connectionPath,
       
   306             devicePath,
       
   307             connectionPath);
       
   308 }
       
   309 
       
   310 void QNmWifiEngine::disconnectFromId(const QString &id)
       
   311 {
       
   312     QString activeConnectionPath = getActiveConnectionPath(id);
       
   313 
       
   314     if (!activeConnectionPath.isEmpty()) {
       
   315         QScopedPointer<QNetworkManagerConnectionActive> activeCon;
       
   316         activeCon.reset(new QNetworkManagerConnectionActive(activeConnectionPath));
       
   317         QScopedPointer<QNetworkManagerSettingsConnection> settingsCon;
       
   318         settingsCon.reset(new QNetworkManagerSettingsConnection(activeCon->serviceName(), activeCon->connection().path()));
       
   319 
       
   320         if(settingsCon->getType() ==  DEVICE_TYPE_802_3_ETHERNET) { //use depreciated value for now
       
   321             emit connectionError(id, OperationNotSupported);
       
   322         } else {
       
   323             QDBusObjectPath dbpath(activeConnectionPath);
       
   324             iface->deactivateConnection(dbpath);
       
   325             activatingConnectionPath = "";
       
   326         }
       
   327     }
       
   328 }
       
   329 
       
   330 void QNmWifiEngine::requestUpdate()
       
   331 {
       
   332     updated = false;
       
   333     knownSsids.clear();
       
   334     availableAccessPoints.clear();
       
   335     emitConfigurationsChanged();
       
   336 }
       
   337 
       
   338 QNmWifiEngine *QNmWifiEngine::instance()
       
   339 {
       
   340     QDBusConnection dbusConnection = QDBusConnection::systemBus();
       
   341     if (dbusConnection.isConnected()) {
       
   342         QDBusConnectionInterface *dbiface = dbusConnection.interface();
       
   343         QDBusReply<bool> reply = dbiface->isServiceRegistered("org.freedesktop.NetworkManager");
       
   344         if (reply.isValid() && reply.value())
       
   345             return nmWifiEngine();
       
   346     }
       
   347 
       
   348     return 0;
       
   349 }
       
   350 
       
   351 void  QNmWifiEngine::updateKnownSsids()
       
   352 {
       
   353     QStringList connectionServices;
       
   354     connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS;
       
   355     connectionServices << NM_DBUS_SERVICE_USER_SETTINGS;
       
   356 
       
   357     QScopedPointer<QNetworkManagerSettings> settingsiface;
       
   358     foreach (QString service, connectionServices) {
       
   359         settingsiface.reset(new QNetworkManagerSettings(service));
       
   360         QList<QDBusObjectPath> list = settingsiface->listConnections();
       
   361         foreach(QDBusObjectPath path, list) {
       
   362             QNetworkManagerSettingsConnection sysIface(service, path.path());
       
   363             knownSsids << sysIface.getSsid();
       
   364         }
       
   365     }
       
   366 }
       
   367 
       
   368 void QNmWifiEngine::updateActiveConnectionsPaths()
       
   369 { //need to know which connection paths are currently active/connected
       
   370     QScopedPointer<QNetworkManagerInterface> dbIface;
       
   371     activeConnectionPaths.clear();
       
   372     dbIface.reset(new QNetworkManagerInterface);
       
   373     QList <QDBusObjectPath> connections = dbIface->activeConnections();
       
   374     foreach(QDBusObjectPath conpath, connections) {
       
   375            activeConnectionPaths << conpath.path();
       
   376        }
       
   377 }
       
   378 
       
   379 QNetworkConfigurationPrivate * QNmWifiEngine::addAccessPoint( const QString &iPath, QDBusObjectPath path)
       
   380 {
       
   381 
       
   382     QScopedPointer<QNetworkManagerInterfaceDevice> devIface(new QNetworkManagerInterfaceDevice(iPath));
       
   383     QScopedPointer<QNetworkManagerInterfaceDeviceWireless> devWirelessIface(new QNetworkManagerInterfaceDeviceWireless(iPath));
       
   384 
       
   385     QString activeAPPath = devWirelessIface->activeAccessPoint().path();
       
   386 
       
   387     QScopedPointer<QNetworkManagerInterfaceAccessPoint> accessPointIface(new QNetworkManagerInterfaceAccessPoint(path.path()));
       
   388 
       
   389     QString ident = accessPointIface->connectionInterface()->path();
       
   390     quint32 nmState = devIface->state();
       
   391 
       
   392     QString ssid = accessPointIface->ssid();
       
   393     QString hwAddy = accessPointIface->hwAddress();
       
   394     QString sInterface = devIface->networkInterface().name();
       
   395 
       
   396     QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
       
   397     bool addIt = true;
       
   398 
       
   399     if(addIt) {
       
   400 
       
   401         cpPriv->name = ssid;
       
   402         cpPriv->isValid = true;
       
   403         cpPriv->id = ident;
       
   404         cpPriv->internet = true;
       
   405         cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
       
   406         cpPriv->serviceInterface = devIface->networkInterface();
       
   407 
       
   408         cpPriv->state = getAPState(nmState, knownSsids.contains(cpPriv->name));
       
   409 
       
   410         if(activeAPPath == accessPointIface->connectionInterface()->path()) {
       
   411             cpPriv->state = ( cpPriv->state | QNetworkConfiguration::Active);
       
   412         }
       
   413         if(accessPointIface->flags() == NM_802_11_AP_FLAGS_PRIVACY)
       
   414             cpPriv->purpose = QNetworkConfiguration::PrivatePurpose;
       
   415         else
       
   416             cpPriv->purpose = QNetworkConfiguration::PublicPurpose;
       
   417         return cpPriv;
       
   418     } else {
       
   419         cpPriv->isValid = false;
       
   420     }
       
   421     return cpPriv;
       
   422 }
       
   423 
       
   424 
       
   425  QNetworkConfiguration::StateFlags QNmWifiEngine::getAPState(qint32 nmState, bool isKnown)
       
   426 {
       
   427     QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
       
   428     // this is the state of the wifi device interface
       
   429     if(isKnown)
       
   430         state = ( QNetworkConfiguration::Defined);
       
   431 
       
   432     switch(nmState) { //device interface state, not AP state
       
   433     case  NM_DEVICE_STATE_UNKNOWN:
       
   434     case  NM_DEVICE_STATE_UNMANAGED:
       
   435     case NM_DEVICE_STATE_UNAVAILABLE:
       
   436         state = (QNetworkConfiguration::Undefined);
       
   437         break;
       
   438     case NM_DEVICE_STATE_DISCONNECTED:
       
   439         {
       
   440             if(isKnown)
       
   441                 state = ( state  | QNetworkConfiguration::Discovered);
       
   442         }
       
   443         break;
       
   444     case NM_DEVICE_STATE_PREPARE:
       
   445     case NM_DEVICE_STATE_CONFIG:
       
   446     case NM_DEVICE_STATE_NEED_AUTH:
       
   447     case NM_DEVICE_STATE_IP_CONFIG:
       
   448         if(isKnown)
       
   449             state = ( state | QNetworkConfiguration::Discovered);
       
   450         break;
       
   451     case NM_DEVICE_STATE_ACTIVATED:
       
   452         {
       
   453             if(isKnown)
       
   454                 state = ( state | QNetworkConfiguration::Discovered);
       
   455         }
       
   456         break;
       
   457     };
       
   458     return state;
       
   459 }
       
   460 
       
   461 QString QNmWifiEngine::getActiveConnectionPath(const QString &id)
       
   462 {
       
   463     QStringList connectionSettings = getConnectionPathForId(id);
       
   464     QNetworkManagerInterface ifaceD;
       
   465     QList<QDBusObjectPath> connections = ifaceD.activeConnections();
       
   466     QScopedPointer<QNetworkManagerConnectionActive> conDetailsD;
       
   467     foreach(QDBusObjectPath path, connections) {
       
   468         conDetailsD.reset(new QNetworkManagerConnectionActive( path.path()));
       
   469         if(conDetailsD->connection().path() == connectionSettings.at(1)
       
   470             && conDetailsD->serviceName() == connectionSettings.at(0))
       
   471             return path.path();
       
   472     }
       
   473     return QString();
       
   474 }
       
   475 
       
   476  QNetworkConfiguration::StateFlags QNmWifiEngine::getStateFlag(quint32 nmstate)
       
   477  {
       
   478      QNetworkConfiguration::StateFlags flag;
       
   479      switch (nmstate) {
       
   480      case  NM_DEVICE_STATE_UNKNOWN:
       
   481      case NM_DEVICE_STATE_FAILED:
       
   482      case NM_DEVICE_STATE_UNMANAGED:
       
   483          flag = (QNetworkConfiguration::Undefined);
       
   484          break;
       
   485      case NM_DEVICE_STATE_PREPARE:
       
   486      case NM_DEVICE_STATE_CONFIG:
       
   487      case NM_DEVICE_STATE_NEED_AUTH:
       
   488      case NM_DEVICE_STATE_IP_CONFIG:
       
   489      case  NM_DEVICE_STATE_UNAVAILABLE:
       
   490          flag = (QNetworkConfiguration::Defined);
       
   491          break;
       
   492      case NM_DEVICE_STATE_DISCONNECTED:
       
   493          flag = ( flag | QNetworkConfiguration::Discovered );
       
   494         break;
       
   495      case NM_DEVICE_STATE_ACTIVATED:
       
   496          {
       
   497              flag = ( flag | QNetworkConfiguration::Discovered
       
   498                       | QNetworkConfiguration::Active );
       
   499          }
       
   500          break;
       
   501      default:
       
   502          flag = ( QNetworkConfiguration::Defined);
       
   503          break;
       
   504      };
       
   505      return flag;
       
   506  }
       
   507 
       
   508 void QNmWifiEngine::updateDeviceInterfaceState(const QString &/*path*/, quint32 nmState)
       
   509 {
       
   510     if(nmState == NM_DEVICE_STATE_ACTIVATED
       
   511        || nmState == NM_DEVICE_STATE_DISCONNECTED
       
   512        || nmState == NM_DEVICE_STATE_UNAVAILABLE
       
   513        || nmState == NM_DEVICE_STATE_FAILED) {
       
   514 
       
   515         QNetworkConfiguration::StateFlags state = (QNetworkConfiguration::Defined);
       
   516         switch (nmState) {
       
   517                 case  NM_DEVICE_STATE_UNKNOWN:
       
   518                 case NM_DEVICE_STATE_FAILED:
       
   519             state = (QNetworkConfiguration::Undefined);
       
   520             emit connectionError(activatingConnectionPath, ConnectError);
       
   521             requestUpdate();
       
   522             break;
       
   523                 case  NM_DEVICE_STATE_UNAVAILABLE:
       
   524             state = (QNetworkConfiguration::Defined);
       
   525             requestUpdate();
       
   526             break;
       
   527                 case NM_DEVICE_STATE_DISCONNECTED:
       
   528             state = ( state | QNetworkConfiguration::Discovered );
       
   529             requestUpdate();
       
   530             break;
       
   531                 case NM_DEVICE_STATE_ACTIVATED:
       
   532             {
       
   533                 state = ( state | QNetworkConfiguration::Discovered
       
   534                           | QNetworkConfiguration::Active );
       
   535                 requestUpdate();
       
   536             }
       
   537             break;
       
   538                 default:
       
   539             state = ( QNetworkConfiguration::Defined);
       
   540             break;
       
   541         };
       
   542     }
       
   543 }
       
   544 
       
   545 void QNmWifiEngine::addDevice(QDBusObjectPath path)
       
   546 {
       
   547     QNetworkManagerInterfaceDevice *devIface = new QNetworkManagerInterfaceDevice(path.path(), this);
       
   548     devIface->setConnections();
       
   549     connect(devIface,SIGNAL(stateChanged(const QString &, quint32)),
       
   550             this, SLOT(updateDeviceInterfaceState(const QString&, quint32)));
       
   551 
       
   552     if(!devicePaths.contains(path.path()))
       
   553         devicePaths << path.path();
       
   554 
       
   555     switch(devIface->deviceType()) {
       
   556     case DEVICE_TYPE_802_3_ETHERNET:
       
   557         {
       
   558             QNetworkManagerInterfaceDeviceWired * devWiredIface;
       
   559             devWiredIface = new QNetworkManagerInterfaceDeviceWired(devIface->connectionInterface()->path(), this);
       
   560             devWiredIface->setConnections();
       
   561             connect(devWiredIface, SIGNAL(propertiesChanged(const QString &,QMap<QString,QVariant>)),
       
   562                     this,SLOT(cmpPropertiesChanged( const QString &, QMap<QString,QVariant>)));
       
   563             requestUpdate();
       
   564         }
       
   565         break;
       
   566     case DEVICE_TYPE_802_11_WIRELESS:
       
   567         {
       
   568             QNetworkManagerInterfaceDeviceWireless *devWirelessIface;
       
   569             devWirelessIface = new QNetworkManagerInterfaceDeviceWireless(devIface->connectionInterface()->path(), this);
       
   570             devWirelessIface->setConnections();
       
   571 
       
   572             connect(devWirelessIface, SIGNAL(propertiesChanged(const QString &,QMap<QString,QVariant>)),
       
   573                     this,SLOT(cmpPropertiesChanged( const QString &, QMap<QString,QVariant>)));
       
   574 
       
   575             connect(devWirelessIface, SIGNAL(accessPointAdded(const QString &,QDBusObjectPath)),
       
   576                     this,SLOT(accessPointAdded(const QString &,QDBusObjectPath)));
       
   577 
       
   578             connect(devWirelessIface, SIGNAL(accessPointRemoved(const QString &,QDBusObjectPath)),
       
   579                     this,SLOT(accessPointRemoved(const QString &,QDBusObjectPath)));
       
   580             requestUpdate();
       
   581 
       
   582         }
       
   583         break;
       
   584             default:
       
   585         break;
       
   586     };
       
   587 }
       
   588 
       
   589 void QNmWifiEngine::cmpPropertiesChanged(const QString &path, QMap<QString,QVariant> map)
       
   590 {
       
   591    QMapIterator<QString, QVariant> i(map);
       
   592    while (i.hasNext()) {
       
   593        i.next();
       
   594        if( i.key() == "State") { //only applies to device interfaces
       
   595            updateDeviceInterfaceState(path, i.value().toUInt());
       
   596        }
       
   597        if( i.key() == "ActiveAccessPoint") {
       
   598        }
       
   599        if( i.key() == "Carrier") { //someone got plugged in
       
   600        }
       
   601    }
       
   602 }
       
   603 
       
   604 void QNmWifiEngine::accessPointRemoved( const QString &aPath, QDBusObjectPath /*oPath*/)
       
   605 {
       
   606     if(aPath.contains("devices")) {
       
   607         requestUpdate();
       
   608     }
       
   609 }
       
   610 
       
   611 void QNmWifiEngine::accessPointAdded( const QString &/*aPath*/, QDBusObjectPath /*oPath*/)
       
   612 {
       
   613    requestUpdate();
       
   614 }
       
   615 
       
   616 QNetworkConfiguration::StateFlags QNmWifiEngine::getStateForId(const QString &id)
       
   617 {
       
   618     bool isAvailable = false;
       
   619     QStringList conPath = getConnectionPathForId(id);
       
   620     QString aconpath = getActiveConnectionPath(id);
       
   621 
       
   622     if(!aconpath.isEmpty()) {
       
   623         //active connection
       
   624         QNetworkManagerConnectionActive aConn(aconpath);
       
   625 
       
   626         QList <QDBusObjectPath> devs = aConn.devices();
       
   627 
       
   628         QScopedPointer<QNetworkManagerInterfaceDevice> ifaceDevice;
       
   629         QScopedPointer<QNetworkManagerInterfaceDeviceWired> devWiredIface;
       
   630         foreach(QDBusObjectPath dev, devs) {
       
   631             ifaceDevice.reset(new QNetworkManagerInterfaceDevice(dev.path()));
       
   632 
       
   633             if(ifaceDevice->deviceType() == DEVICE_TYPE_802_3_ETHERNET) {
       
   634 
       
   635                 if(isAddressOfConnection(id, ifaceDevice->ip4Address())) {
       
   636                     // this is it!
       
   637                     return getStateFlag(ifaceDevice->state());
       
   638                 } else {
       
   639                     continue;
       
   640                 }
       
   641 
       
   642                 if(ifaceDevice->state() == NM_DEVICE_STATE_UNAVAILABLE ||
       
   643                    ifaceDevice->state() == NM_DEVICE_STATE_DISCONNECTED) {
       
   644                     isAvailable = true;
       
   645 
       
   646                     devWiredIface.reset(new QNetworkManagerInterfaceDeviceWired(ifaceDevice->connectionInterface()->path()));
       
   647                     if(!devWiredIface->carrier())
       
   648                         return QNetworkConfiguration::Defined;
       
   649                 } 
       
   650             } else if(ifaceDevice->deviceType() == DEVICE_TYPE_802_11_WIRELESS) {
       
   651 
       
   652             }
       
   653 
       
   654             return getStateFlag(ifaceDevice->state());
       
   655         }
       
   656     } else {
       
   657         // not active
       
   658         QScopedPointer<QNetworkManagerSettingsConnection> sysIface;
       
   659         sysIface.reset(new QNetworkManagerSettingsConnection(conPath.at(0),conPath.at(1)));
       
   660         if(sysIface->isValid()) {
       
   661             if(sysIface->getType() == DEVICE_TYPE_802_11_WIRELESS) {
       
   662                 QString ssid = sysIface->getSsid();
       
   663                 bool ok = false;
       
   664 
       
   665                 if(knownSsids.contains(ssid, Qt::CaseSensitive)) {
       
   666                     foreach(QString onessid, knownSsids) {
       
   667                         if(onessid == ssid && availableAccessPoints.contains(ssid)) {
       
   668                             ok = true;
       
   669                             break;
       
   670                         }
       
   671                     }
       
   672                 }   
       
   673                 if(ok)
       
   674                     return getStateFlag(NM_DEVICE_STATE_DISCONNECTED);
       
   675                 else
       
   676                     return getStateFlag(NM_DEVICE_STATE_UNAVAILABLE);
       
   677             }
       
   678         }
       
   679     }
       
   680 
       
   681     return QNetworkConfiguration::Defined; //not active, but we know this connection
       
   682 }
       
   683 
       
   684 bool QNmWifiEngine::isAddressOfConnection(const QString &id, quint32 ipaddress)
       
   685 {
       
   686     QStringList conPath = getConnectionPathForId(id);
       
   687     QString aConPath = getActiveConnectionPath(id);
       
   688     if(aConPath.isEmpty()) {
       
   689         // not active
       
   690         return false;
       
   691     }
       
   692 
       
   693     QScopedPointer<QNetworkManagerConnectionActive> aConn;
       
   694     aConn.reset(new QNetworkManagerConnectionActive(aConPath));
       
   695     QScopedPointer<QNetworkManagerInterfaceDevice> ifaceDevice;
       
   696     QList<QDBusObjectPath> devices = aConn->devices();
       
   697     foreach(QDBusObjectPath device, devices) {
       
   698         ifaceDevice.reset(new QNetworkManagerInterfaceDevice(device.path()));
       
   699         if(ifaceDevice->ip4Address() == ipaddress) {
       
   700             return true;
       
   701         }
       
   702     }
       
   703     return false;
       
   704 }
       
   705 
       
   706 QNetworkInterface QNmWifiEngine::getBestInterface( quint32 type, const QString &id)
       
   707 {
       
   708     // check active connections first.
       
   709     QStringList conIdPath = getConnectionPathForId(id);
       
   710 
       
   711     QNetworkInterface interface;
       
   712     QScopedPointer<QNetworkManagerConnectionActive> aConn;
       
   713 
       
   714     foreach(QString conpath, activeConnectionPaths) {
       
   715         aConn.reset(new QNetworkManagerConnectionActive(conpath));
       
   716         if(aConn->connection().path() == conIdPath.at(1)
       
   717             && aConn->serviceName() == conIdPath.at(0)) {
       
   718 
       
   719             QList <QDBusObjectPath> devs = aConn->devices();
       
   720             QNetworkManagerInterfaceDevice ifaceDevice(devs[0].path()); //just take the first one
       
   721             return ifaceDevice.networkInterface();
       
   722         }
       
   723     }
       
   724 
       
   725     //try guessing
       
   726     QList<QDBusObjectPath> list = iface->getDevices();
       
   727     QScopedPointer<QNetworkManagerInterfaceDevice> devIface;
       
   728     foreach(QDBusObjectPath path, list) {
       
   729         devIface.reset(new QNetworkManagerInterfaceDevice(path.path()));
       
   730         if(devIface->deviceType() == type ) {
       
   731             if(devIface->state() ==  NM_DEVICE_STATE_DISCONNECTED) {
       
   732                 return devIface->networkInterface();
       
   733             }
       
   734         }
       
   735     }
       
   736     return QNetworkInterface();
       
   737 }
       
   738 
       
   739 quint64 QNmWifiEngine::receivedDataForId(const QString &id) const
       
   740 {
       
   741     if(configurationInterface.count() > 1)
       
   742         return 0;
       
   743     quint64 result = 0;
       
   744 
       
   745     QString devFile;
       
   746     devFile =  configurationInterface.value(id);
       
   747     QFile rx("/sys/class/net/"+devFile+"/statistics/rx_bytes");
       
   748     if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   749         QTextStream in(&rx);
       
   750         in >> result;
       
   751         rx.close();
       
   752     }
       
   753     return result;
       
   754 }
       
   755 
       
   756 quint64 QNmWifiEngine::sentDataForId(const QString &id) const
       
   757 {
       
   758     if(configurationInterface.count() > 1)
       
   759         return 0;
       
   760     quint64 result = 0;
       
   761     QString devFile;
       
   762     devFile =  configurationInterface.value(id);
       
   763 
       
   764     QFile tx("/sys/class/net/"+devFile+"/statistics/tx_bytes");
       
   765     if(tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   766         QTextStream in(&tx);
       
   767         in >> result;
       
   768         tx.close();
       
   769     }
       
   770     return result;
       
   771 }
       
   772 
       
   773 void QNmWifiEngine::newConnection(QDBusObjectPath /*path*/)
       
   774 {
       
   775     requestUpdate();
       
   776 }
       
   777 
       
   778 void QNmWifiEngine::settingsConnectionRemoved(const QString &/*path*/)
       
   779 {
       
   780     requestUpdate();
       
   781 }
       
   782 
       
   783 void QNmWifiEngine::slotActivationFinished(QDBusPendingCallWatcher *openCall)
       
   784 {
       
   785     QDBusPendingReply<QDBusObjectPath> reply = *openCall;
       
   786     if (reply.isError()) {
       
   787         qWarning() <<"Error" <<  reply.error().name() << reply.error().message()
       
   788                 <<activatingConnectionPath;
       
   789         emit connectionError(activatingConnectionPath, ConnectError);
       
   790     }
       
   791 }
       
   792 
       
   793 void QNmWifiEngine::scanForAccessPoints()
       
   794 {
       
   795     availableAccessPoints.clear();
       
   796     QList<QDBusObjectPath> list = iface->getDevices();
       
   797 
       
   798     QScopedPointer<QNetworkManagerInterfaceDevice> devIface;
       
   799     QScopedPointer<QNetworkManagerInterfaceDeviceWireless> devWirelessIface;
       
   800     QScopedPointer<QNetworkManagerInterfaceAccessPoint> accessPointIface;
       
   801     foreach(QDBusObjectPath path, list) {
       
   802         devIface.reset(new QNetworkManagerInterfaceDevice(path.path()));
       
   803 
       
   804         if(devIface->deviceType() == DEVICE_TYPE_802_11_WIRELESS) {
       
   805 
       
   806             devWirelessIface.reset(new QNetworkManagerInterfaceDeviceWireless(devIface->connectionInterface()->path()));
       
   807             ////////////// AccessPoints
       
   808             QList<QDBusObjectPath> apList = devWirelessIface->getAccessPoints();
       
   809 
       
   810             foreach(QDBusObjectPath path, apList) {
       
   811                 accessPointIface.reset(new QNetworkManagerInterfaceAccessPoint(path.path()));
       
   812                 QString ssid = accessPointIface->ssid();
       
   813                 availableAccessPoints.insert(ssid, path);
       
   814             }
       
   815         }
       
   816     }
       
   817 }
       
   818 
       
   819 QString QNmWifiEngine::deviceConnectionPath(const QString &mac)
       
   820 {
       
   821     QString newMac = mac;
       
   822     newMac = newMac.replace(":","_").toLower();
       
   823     //device object path might not contain just mac address
       
   824     //might contain extra numbers on the end. thanks HAL
       
   825     foreach(QString device, devicePaths) {
       
   826         if(device.contains(newMac)) {
       
   827             newMac = device;
       
   828             break;
       
   829         }
       
   830     }
       
   831     return newMac;
       
   832 }
       
   833 
       
   834 QStringList QNmWifiEngine::getConnectionPathForId(const QString &uuid)
       
   835 {
       
   836     QStringList connectionServices;
       
   837     connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS;
       
   838     connectionServices << NM_DBUS_SERVICE_USER_SETTINGS;
       
   839     QScopedPointer<QNetworkManagerSettings> settingsiface;
       
   840     foreach (QString service, connectionServices) {
       
   841         settingsiface.reset(new QNetworkManagerSettings(service));
       
   842         QList<QDBusObjectPath> list = settingsiface->listConnections();
       
   843         QScopedPointer<QNetworkManagerSettingsConnection> sysIface;
       
   844         foreach(QDBusObjectPath path, list) {
       
   845             sysIface.reset(new QNetworkManagerSettingsConnection(service, path.path()));
       
   846             if(sysIface->getUuid() == uuid)
       
   847                 return QStringList() << service << sysIface->connectionInterface()->path();
       
   848         }
       
   849     }
       
   850     return QStringList();
       
   851 }
       
   852 
       
   853 #include "moc_qnmwifiengine_unix_p.cpp"
       
   854 
       
   855 QTM_END_NAMESPACE
       
   856