qtmobility/src/bearer/qnetworkconfigmanager_s60_p.cpp
changeset 11 06b8e2af4411
parent 4 90517678cc4f
child 14 6fbed849b4f4
equal deleted inserted replaced
8:71781823f776 11:06b8e2af4411
    42 #include "qnetworkconfigmanager_s60_p.h"
    42 #include "qnetworkconfigmanager_s60_p.h"
    43 
    43 
    44 #include <commdb.h>
    44 #include <commdb.h>
    45 #include <cdbcols.h>
    45 #include <cdbcols.h>
    46 #include <d32dbms.h>
    46 #include <d32dbms.h>
       
    47 #include <nifvar.h>
    47 #include <QEventLoop>
    48 #include <QEventLoop>
    48 #include <QTimer>
    49 #include <QTimer>
    49 #include <QTime>  // For randgen seeding
    50 #include <QTime>  // For randgen seeding
    50 #include <QtCore> // For randgen seeding
    51 #include <QtCore> // For randgen seeding
    51 
    52 
    52 // #define QT_BEARERMGMT_CONFIGMGR_DEBUG
    53 
    53 
    54 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
    54 #ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
       
    55 #include <QDebug>
    55 #include <QDebug>
    56 #endif
    56 #endif
    57 
    57 
    58 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
    58 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
    59     #include <cmdestination.h>
    59     #include <cmdestination.h>
    68     #include <aputils.h> 
    68     #include <aputils.h> 
    69 #endif
    69 #endif
    70 
    70 
    71 QTM_BEGIN_NAMESPACE
    71 QTM_BEGIN_NAMESPACE
    72 
    72 
    73 static const int KValueThatWillBeAddedToSNAPId = 1000;
    73 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
       
    74     static const int KValueThatWillBeAddedToSNAPId = 1000;
       
    75 #endif
    74 static const int KUserChoiceIAPId = 0;
    76 static const int KUserChoiceIAPId = 0;
    75 
    77 
    76 QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
    78 QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
    77     : QObject(0), CActive(CActive::EPriorityIdle), capFlags(0),
    79     : QObject(0), CActive(CActive::EPriorityIdle), capFlags(0),
    78     iFirstUpdate(true), iInitOk(true), iIgnoringUpdates(false),
    80     iFirstUpdate(true), iInitOk(true), iIgnoringUpdates(false),
   605     TRequestStatus status;
   607     TRequestStatus status;
   606     TUint connectionCount;
   608     TUint connectionCount;
   607     iConnectionMonitor.GetConnectionCount(connectionCount, status);
   609     iConnectionMonitor.GetConnectionCount(connectionCount, status);
   608     User::WaitForRequest(status);
   610     User::WaitForRequest(status);
   609     
   611     
   610     // Go through all connections and set state of related IAPs to Active
   612     // Go through all connections and set state of related IAPs to Active.
       
   613     // Status needs to be checked carefully, because ConnMon lists also e.g.
       
   614     // WLAN connections that are being currently tried --> we don't want to
       
   615     // state these as active.
   611     TUint connectionId;
   616     TUint connectionId;
   612     TUint subConnectionCount;
   617     TUint subConnectionCount;
   613     TUint apId;
   618     TUint apId;
       
   619     TInt connectionStatus;
   614     if (status.Int() == KErrNone) {
   620     if (status.Int() == KErrNone) {
   615         for (TUint i = 1; i <= connectionCount; i++) {
   621         for (TUint i = 1; i <= connectionCount; i++) {
   616             iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
   622             iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
   617             iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
   623             iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
   618             User::WaitForRequest(status);
   624             User::WaitForRequest(status);
   619             QString ident = QString::number(qHash(apId));
   625             QString ident = QString::number(qHash(apId));
   620             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
   626             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
   621             if (priv.data()) {
   627             if (priv.data()) {
   622                 online = true;
   628                 iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status);
   623                 inactiveConfigs.removeOne(ident);
   629                 User::WaitForRequest(status);          
   624                 priv.data()->connectionId = connectionId;
   630                 if (connectionStatus == KLinkLayerOpen) {
   625                 // Configuration is Active
   631                     online = true;
   626                 changeConfigurationStateTo(priv, QNetworkConfiguration::Active);
   632                     inactiveConfigs.removeOne(ident);
       
   633                     priv.data()->connectionId = connectionId;
       
   634                     // Configuration is Active
       
   635                     changeConfigurationStateTo(priv, QNetworkConfiguration::Active);
       
   636                 }
   627             }
   637             }
   628         }
   638         }
   629     }
   639     }
   630 
   640 
   631     // Make sure that state of rest of the IAPs won't be Active
   641     // Make sure that state of rest of the IAPs won't be Active
   672                     changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered);
   682                     changeConfigurationStateAtMinTo(priv, QNetworkConfiguration::Discovered);
   673                 }
   683                 }
   674             }
   684             }
   675         }
   685         }
   676         
   686         
   677         // Make sure that state of rest of the IAPs won't be Discovered or Active
   687         // Make sure that state of rest of the IAPs won't be Active
   678         foreach (const QString &iface, unavailableConfigs) {
   688         foreach (const QString &iface, unavailableConfigs) {
   679             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
   689             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
   680             if (priv.data()) {
   690             if (priv.data()) {
   681                 // Configuration is Defined
   691                 // Configuration is Defined
   682                 changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Defined);
   692                 changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered);
   683             }
   693             }
   684         }
   694         }
   685     }
   695     }
   686 
   696 
   687     updateStatesToSnaps();
   697     updateStatesToSnaps();
   806 }
   816 }
   807 
   817 
   808 void QNetworkConfigurationManagerPrivate::RunL()
   818 void QNetworkConfigurationManagerPrivate::RunL()
   809 {
   819 {
   810     if (iIgnoringUpdates) {
   820     if (iIgnoringUpdates) {
   811 #ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
   821 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
   812         qDebug("CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently).");
   822         qDebug("QNCM CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently).");
   813 #endif
   823 #endif
   814         return;
   824         return;
   815     }
   825     }
   816     if (iStatus != KErrCancel) {
   826     if (iStatus != KErrCancel) {
   817         RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int());
   827         RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int());
       
   828 
   818         switch (event) {
   829         switch (event) {
   819         case RDbNotifier::EUnlock:   /** All read locks have been removed.  */
   830         case RDbNotifier::EUnlock:   /** All read locks have been removed.  */
   820         case RDbNotifier::ECommit:   /** A transaction has been committed.  */ 
   831         case RDbNotifier::ECommit:   /** A transaction has been committed.  */ 
   821         case RDbNotifier::ERollback: /** A transaction has been rolled back */
   832         case RDbNotifier::ERollback: /** A transaction has been rolled back */
   822         case RDbNotifier::ERecover:  /** The database has been recovered    */
   833         case RDbNotifier::ERecover:  /** The database has been recovered    */
   823 #ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
   834 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
   824             qDebug("CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
   835             qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
   825 #endif
   836 #endif
   826             iIgnoringUpdates = true;
   837             iIgnoringUpdates = true;
   827             // Other events than ECommit get lower priority. In practice with those events,
   838             // Other events than ECommit get lower priority. In practice with those events,
   828             // we delay_before_updating methods, whereas
   839             // we delay_before_updating methods, whereas
   829             // with ECommit we _update_before_delaying the reaction to next event.
   840             // with ECommit we _update_before_delaying the reaction to next event.
   865 void QNetworkConfigurationManagerPrivate::DoCancel()
   876 void QNetworkConfigurationManagerPrivate::DoCancel()
   866 {
   877 {
   867     ipCommsDB->CancelRequestNotification();
   878     ipCommsDB->CancelRequestNotification();
   868 }
   879 }
   869 
   880 
   870 
       
   871 void QNetworkConfigurationManagerPrivate::EventL(const CConnMonEventBase& aEvent)
   881 void QNetworkConfigurationManagerPrivate::EventL(const CConnMonEventBase& aEvent)
   872 {
   882 {
   873     switch (aEvent.EventType()) {
   883     switch (aEvent.EventType()) {
   874     case EConnMonCreateConnection:
   884     case EConnMonConnectionStatusChange:
   875         {
   885         {
   876         CConnMonCreateConnection* realEvent;
   886         CConnMonConnectionStatusChange* realEvent;
   877         realEvent = (CConnMonCreateConnection*) &aEvent;
   887         realEvent = (CConnMonConnectionStatusChange*) &aEvent;
   878         TUint subConnectionCount = 0;
   888         TInt connectionStatus = realEvent->ConnectionStatus();
   879         TUint apId;            
   889 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
   880         TUint connectionId = realEvent->ConnectionId();
   890         qDebug() << "QNCM Connection status : " << QString::number(connectionStatus) << " , connection monitor Id : " << realEvent->ConnectionId();
   881         TRequestStatus status;
   891 #endif
   882         iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
   892         if (connectionStatus == KConfigDaemonStartingRegistration) {
   883         User::WaitForRequest(status);
   893             TUint connectionId = realEvent->ConnectionId();
   884         QString ident = QString::number(qHash(apId));
   894             TUint subConnectionCount = 0;
   885         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
   895             TUint apId;            
   886         if (priv.data()) {
   896             TRequestStatus status;
   887             priv.data()->connectionId = connectionId;
   897             iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
   888             // Configuration is Active
   898             User::WaitForRequest(status);
   889             if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) {
   899             QString ident = QString::number(qHash(apId));
   890                 updateStatesToSnaps();
   900             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
   891             }
   901             if (priv.data()) {
   892             if (!iOnline) {
   902                 priv.data()->connectionId = connectionId;
   893                 iOnline = true;
   903                 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connecting);
       
   904             }
       
   905         } else if (connectionStatus == KLinkLayerOpen) {
       
   906             // Connection has been successfully opened
       
   907             TUint connectionId = realEvent->ConnectionId();
       
   908             TUint subConnectionCount = 0;
       
   909             TUint apId;            
       
   910             TRequestStatus status;
       
   911             iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
       
   912             User::WaitForRequest(status);
       
   913             QString ident = QString::number(qHash(apId));
       
   914             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
       
   915             if (priv.data()) {
       
   916                 priv.data()->connectionId = connectionId;
       
   917                 // Configuration is Active
       
   918                 if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) {
       
   919                     updateStatesToSnaps();
       
   920                 }
       
   921                 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connected);
       
   922                 if (!iOnline) {
       
   923                     iOnline = true;
       
   924                     emit this->onlineStateChanged(iOnline);
       
   925                 }
       
   926             }
       
   927         } else if (connectionStatus == KConfigDaemonStartingDeregistration) {
       
   928             TUint connectionId = realEvent->ConnectionId();
       
   929             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId);
       
   930             if (priv.data()) {
       
   931                 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Closing);
       
   932             }
       
   933         } else if (connectionStatus == KLinkLayerClosed ||
       
   934                    connectionStatus == KConnectionClosed) {
       
   935             // Connection has been closed. Which of the above events is reported, depends on the Symbian
       
   936             // platform.
       
   937             TUint connectionId = realEvent->ConnectionId();
       
   938             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId);
       
   939             if (priv.data()) {
       
   940                 // Configuration is either Defined or Discovered
       
   941                 if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) {
       
   942                     updateStatesToSnaps();
       
   943                 }
       
   944                 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Disconnected);
       
   945             }
       
   946             
       
   947             bool online = false;
       
   948             foreach (const QString &iface, accessPointConfigurations.keys()) {
       
   949                 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
       
   950                 if (priv.data()->state == QNetworkConfiguration::Active) {
       
   951                     online = true;
       
   952                     break;
       
   953                 }
       
   954             }
       
   955             if (iOnline != online) {
       
   956                 iOnline = online;
   894                 emit this->onlineStateChanged(iOnline);
   957                 emit this->onlineStateChanged(iOnline);
   895             }
   958             }
   896         }
   959         }
   897         }
   960         }
   898         break;
   961         break;    
   899 
       
   900     case EConnMonDeleteConnection:
       
   901         {
       
   902         CConnMonDeleteConnection* realEvent;
       
   903         realEvent = (CConnMonDeleteConnection*) &aEvent;
       
   904         TUint connectionId = realEvent->ConnectionId();
       
   905         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId);
       
   906         if (priv.data()) {
       
   907             priv.data()->connectionId = 0;
       
   908             // Configuration is either Defined or Discovered
       
   909             if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) {
       
   910                 updateStatesToSnaps();
       
   911             }
       
   912         }
       
   913         
       
   914         bool online = false;
       
   915         foreach (const QString &iface, accessPointConfigurations.keys()) {
       
   916             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface);
       
   917             if (priv.data()->state == QNetworkConfiguration::Active) {
       
   918                 online = true;
       
   919                 break;
       
   920             }
       
   921         }
       
   922         if (iOnline != online) {
       
   923             iOnline = online;
       
   924             emit this->onlineStateChanged(iOnline);
       
   925         }
       
   926         }
       
   927         break;
       
   928 
   962 
   929     case EConnMonIapAvailabilityChange:
   963     case EConnMonIapAvailabilityChange:
   930         {
   964         {
   931         CConnMonIapAvailabilityChange* realEvent;
   965         CConnMonIapAvailabilityChange* realEvent;
   932         realEvent = (CConnMonIapAvailabilityChange*) &aEvent;
   966         realEvent = (CConnMonIapAvailabilityChange*) &aEvent;
   949             }
   983             }
   950         }
   984         }
   951         }
   985         }
   952         break;
   986         break;
   953 
   987 
       
   988     case EConnMonCreateConnection:
       
   989         {
       
   990         // This event is caught to keep connection monitor IDs up-to-date.
       
   991         CConnMonCreateConnection* realEvent;
       
   992         realEvent = (CConnMonCreateConnection*) &aEvent;
       
   993         TUint subConnectionCount = 0;
       
   994         TUint apId;
       
   995         TUint connectionId = realEvent->ConnectionId();
       
   996         TRequestStatus status;
       
   997         iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
       
   998         User::WaitForRequest(status);
       
   999         QString ident = QString::number(qHash(apId));
       
  1000         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
       
  1001         if (priv.data()) {
       
  1002 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1003             qDebug() << "QNCM updating connection monitor ID : from, to, whose: " << priv.data()->connectionId << connectionId << priv->name;
       
  1004 #endif
       
  1005             priv.data()->connectionId = connectionId;
       
  1006         }
       
  1007         }
       
  1008         break;
   954     default:
  1009     default:
   955         // For unrecognized events
  1010         // For unrecognized events
   956         break;
  1011         break;
   957     }
  1012     }
   958 }
  1013 }
   959 
  1014 
   960 // Waits for 1..4 seconds.
  1015 // Sessions may use this function to report configuration state changes,
       
  1016 // because on some Symbian platforms (especially Symbian^3) all state changes are not
       
  1017 // reported by the RConnectionMonitor, in particular in relation to stop() call,
       
  1018 // whereas they _are_ reported on RConnection progress notifier used by sessions --> centralize
       
  1019 // this data here so that other sessions may benefit from it too (not all sessions necessarily have
       
  1020 // RConnection progress notifiers available but they relay on having e.g. disconnected information from
       
  1021 // manager). Currently only 'Disconnected' state is of interest because it has proven to be troublesome.
       
  1022 void QNetworkConfigurationManagerPrivate::configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState)
       
  1023 {
       
  1024 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1025     qDebug() << "QNCM A session reported state change for IAP ID: " << accessPointId << " whose new state is: " << newState;
       
  1026 #endif
       
  1027     switch (newState) {
       
  1028     case QNetworkSession::Disconnected:
       
  1029         {
       
  1030             QString ident = QString::number(qHash(accessPointId));
       
  1031             QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident);
       
  1032             if (priv.data()) {
       
  1033                 // Configuration is either Defined or Discovered
       
  1034                 if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) {
       
  1035                     updateStatesToSnaps();
       
  1036                 }
       
  1037                 emit this->configurationStateChanged(
       
  1038                         priv.data()->numericId, priv.data()->connectionId, QNetworkSession::Disconnected);
       
  1039             }
       
  1040         }
       
  1041         break;
       
  1042     default:
       
  1043         break;
       
  1044     }
       
  1045 }
       
  1046 
       
  1047 // Waits for 2..6 seconds.
   961 void QNetworkConfigurationManagerPrivate::waitRandomTime()
  1048 void QNetworkConfigurationManagerPrivate::waitRandomTime()
   962 {
  1049 {
   963     iTimeToWait = (qAbs(qrand()) % 5) * 1000;
  1050     iTimeToWait = (qAbs(qrand()) % 7) * 1000;
   964     if (iTimeToWait < 1000) {
  1051     if (iTimeToWait < 2000) {
   965         iTimeToWait = 1000;
  1052         iTimeToWait = 2000;
   966     }
  1053     }
   967 #ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
  1054 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
   968     qDebug("QNetworkConfigurationManager waiting random time: %d ms", iTimeToWait);
  1055     qDebug("QNCM waiting random time: %d ms", iTimeToWait);
   969 #endif
  1056 #endif
   970     QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit()));
  1057     QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit()));
   971     iIgnoreEventLoop->exec();
  1058     iIgnoreEventLoop->exec();
   972 }
  1059 }
   973 
  1060 
   974 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::dataByConnectionId(TUint aConnectionId)
  1061 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::dataByConnectionId(TUint aConnectionId)
   975 {
  1062 {
   976     QNetworkConfiguration item;
  1063     QNetworkConfiguration item;
   977     
       
   978     QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i =
  1064     QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i =
   979             accessPointConfigurations.constBegin();
  1065             accessPointConfigurations.constBegin();
   980     while (i != accessPointConfigurations.constEnd()) {
  1066     while (i != accessPointConfigurations.constEnd()) {
   981         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = i.value();
  1067         QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = i.value();
   982         if (priv.data()->connectionId == aConnectionId) {
  1068         if (priv.data()->connectionId == aConnectionId) {