qtmobility/src/bearer/qnetworksession_s60_p.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
    51 
    51 
    52 QTM_BEGIN_NAMESPACE
    52 QTM_BEGIN_NAMESPACE
    53 
    53 
    54 QNetworkSessionPrivate::QNetworkSessionPrivate()
    54 QNetworkSessionPrivate::QNetworkSessionPrivate()
    55     : CActive(CActive::EPriorityUserInput), state(QNetworkSession::Invalid),
    55     : CActive(CActive::EPriorityUserInput), state(QNetworkSession::Invalid),
    56       isOpen(false), ipConnectionNotifier(0), iHandleStateNotificationsFromManager(false),
    56       isOpen(false), iDynamicUnSetdefaultif(0), ipConnectionNotifier(0),
    57       iFirstSync(true), iStoppedByUser(false), iClosedByUser(false), iDeprecatedConnectionId(0),
    57       iHandleStateNotificationsFromManager(false), iFirstSync(true), iStoppedByUser(false),
    58       iError(QNetworkSession::UnknownSessionError), iALREnabled(0), iConnectInBackground(false)
    58       iClosedByUser(false), iDeprecatedConnectionId(0), iError(QNetworkSession::UnknownSessionError),
       
    59       iALREnabled(0), iConnectInBackground(false)
    59 {
    60 {
    60     CActiveScheduler::Add(this);
    61     CActiveScheduler::Add(this);
    61 
    62 
    62 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
    63 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
    63     iMobility = NULL;
    64     iMobility = NULL;
       
    65 #endif
       
    66     // Try to load "Open C" dll dynamically and
       
    67     // try to attach to unsetdefaultif function dynamically.
       
    68     // This is to avoid build breaks with old OpenC versions.
       
    69     if (iOpenCLibrary.Load(_L("libc")) == KErrNone) {
       
    70         iDynamicUnSetdefaultif = (TOpenCUnSetdefaultifFunction)iOpenCLibrary.Lookup(597);
       
    71     }
       
    72 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
    73     qDebug() << "QNS this : " << QString::number((uint)this) << " - ";
       
    74     if (iDynamicUnSetdefaultif)
       
    75         qDebug() << "dynamic setdefaultif() resolution succeeded. ";
       
    76     else
       
    77         qDebug() << "dynamic setdefaultif() resolution failed. ";
    64 #endif
    78 #endif
    65 
    79 
    66     TRAP_IGNORE(iConnectionMonitor.ConnectL());
    80     TRAP_IGNORE(iConnectionMonitor.ConnectL());
    67 }
    81 }
    68 
    82 
    74     // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start()
    88     // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start()
    75     //       => deleting ipConnectionNotifier results RConnection::CancelProgressNotification()
    89     //       => deleting ipConnectionNotifier results RConnection::CancelProgressNotification()
    76     delete ipConnectionNotifier;
    90     delete ipConnectionNotifier;
    77     ipConnectionNotifier = NULL;
    91     ipConnectionNotifier = NULL;
    78 
    92 
    79     // Cancel possible RConnection::Start()
       
    80     Cancel();
       
    81     
       
    82 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
    93 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
    83     if (iMobility) {
    94     if (iMobility) {
    84         delete iMobility;
    95         delete iMobility;
    85         iMobility = NULL;
    96         iMobility = NULL;
    86     }
    97     }
    87 #endif
    98 #endif
    88 
    99 
    89     iConnection.Close();
   100     // Cancel possible RConnection::Start()
       
   101     Cancel();
    90     iSocketServ.Close();
   102     iSocketServ.Close();
    91     
   103     
    92     // Close global 'Open C' RConnection
   104     // Close global 'Open C' RConnection
       
   105     // Clears also possible unsetdefaultif() flags.
    93     setdefaultif(0);
   106     setdefaultif(0);
    94     
   107     
    95     iConnectionMonitor.Close();
   108     iConnectionMonitor.Close();
       
   109     iOpenCLibrary.Close();
    96 }
   110 }
    97 
   111 
    98 void QNetworkSessionPrivate::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState)
   112 void QNetworkSessionPrivate::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState)
    99 {
   113 {
   100     if (iHandleStateNotificationsFromManager) {
   114     if (iHandleStateNotificationsFromManager) {
   350     if (ipConnectionNotifier) {
   364     if (ipConnectionNotifier) {
   351         ipConnectionNotifier->StartNotifications();
   365         ipConnectionNotifier->StartNotifications();
   352     }
   366     }
   353     
   367     
   354     if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
   368     if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
   355         // Search through existing connections.
       
   356         // If there is already connection which matches to given IAP
       
   357         // try to attach to existing connection.
       
   358         TBool connected(EFalse);
       
   359         TConnectionInfoBuf connInfo;
       
   360         TUint count;
       
   361         if (iConnection.EnumerateConnections(count) == KErrNone) {
       
   362             for (TUint i=1; i<=count; i++) {
       
   363                 // Note: GetConnectionInfo expects 1-based index.
       
   364                 if (iConnection.GetConnectionInfo(i, connInfo) == KErrNone) {
       
   365                     if (connInfo().iIapId == publicConfig.d.data()->numericId) {
       
   366                         if (iConnection.Attach(connInfo, RConnection::EAttachTypeNormal) == KErrNone) {
       
   367                             activeConfig = publicConfig;
       
   368                             activeInterface = interface(activeConfig.d.data()->numericId);
       
   369                             connected = ETrue;
       
   370                             startTime = QDateTime::currentDateTime();
       
   371                             // Use name of the IAP to open global 'Open C' RConnection
       
   372                             QByteArray nameAsByteArray = publicConfig.name().toUtf8();
       
   373                             ifreq ifr;
       
   374                             memset(&ifr, 0, sizeof(struct ifreq));
       
   375                             strcpy(ifr.ifr_name, nameAsByteArray.constData());
       
   376                             error = setdefaultif(&ifr);
       
   377                             isOpen = true;
       
   378                             // Make sure that state will be Connected
       
   379                             newState(QNetworkSession::Connected);
       
   380                             emit quitPendingWaitsForOpened();
       
   381                             break;
       
   382                         }
       
   383                     }
       
   384                 }
       
   385             }
       
   386         }
       
   387         if (!connected) {
       
   388 #ifdef OCC_FUNCTIONALITY_AVAILABLE
   369 #ifdef OCC_FUNCTIONALITY_AVAILABLE
   389             // With One Click Connectivity (Symbian^3 onwards) it is possible
   370             // With One Click Connectivity (Symbian^3 onwards) it is possible
   390             // to connect silently, without any popups.
   371             // to connect silently, without any popups.
   391             TConnPrefList pref;
   372             TConnPrefList pref;
   392             TExtendedConnPref prefs;
   373             TExtendedConnPref prefs;
   403             iConnection.Start(pref, iStatus);
   384             iConnection.Start(pref, iStatus);
   404             if (!IsActive()) {
   385             if (!IsActive()) {
   405                 SetActive();
   386                 SetActive();
   406             }
   387             }
   407             newState(QNetworkSession::Connecting);
   388             newState(QNetworkSession::Connecting);
   408         }
       
   409     } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
   389     } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
   410 #ifdef OCC_FUNCTIONALITY_AVAILABLE
   390 #ifdef OCC_FUNCTIONALITY_AVAILABLE
       
   391         // On Symbian^3 if service network is not reachable, it triggers a UI (aka EasyWLAN) where
       
   392         // user can create new IAPs. To detect this, we need to store the number of IAPs
       
   393         // there was before connection was started.
       
   394         iKnownConfigsBeforeConnectionStart = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.keys();
   411         TConnPrefList snapPref;
   395         TConnPrefList snapPref;
   412         TExtendedConnPref prefs;
   396         TExtendedConnPref prefs;
   413         prefs.SetSnapId(publicConfig.d.data()->numericId);
   397         prefs.SetSnapId(publicConfig.d.data()->numericId);
   414         if (iConnectInBackground) {
   398         if (iConnectInBackground) {
   415             prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent );
   399             prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent );
   475 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
   459 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
   476     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
   460     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
   477             << "close() called, session state is: " << state << " and isOpen is : "
   461             << "close() called, session state is: " << state << " and isOpen is : "
   478             << isOpen;
   462             << isOpen;
   479 #endif
   463 #endif
   480     if (!isOpen) {
   464 
       
   465     if (!isOpen && state != QNetworkSession::Connecting) {
   481         return;
   466         return;
   482     }
   467     }
   483     // Mark this session as closed-by-user so that we are able to report
   468     // Mark this session as closed-by-user so that we are able to report
   484     // distinguish between stop() and close() state transitions
   469     // distinguish between stop() and close() state transitions
   485     // when reporting.
   470     // when reporting.
   486     iClosedByUser = true;
   471     iClosedByUser = true;
   487 
       
   488     TUint activeIap = activeConfig.d.data()->numericId;
       
   489     isOpen = false;
   472     isOpen = false;
       
   473 
       
   474 #ifndef OCC_FUNCTIONALITY_AVAILABLE
       
   475     // On Symbian^3 we need to keep track of active configuration longer
       
   476     // in case of empty-SNAP-triggered EasyWLAN.
   490     activeConfig = QNetworkConfiguration();
   477     activeConfig = QNetworkConfiguration();
       
   478 #endif
   491     serviceConfig = QNetworkConfiguration();
   479     serviceConfig = QNetworkConfiguration();
   492     
   480     
   493     Cancel();
       
   494 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   481 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   495     if (iMobility) {
   482     if (iMobility) {
   496         delete iMobility;
   483         delete iMobility;
   497         iMobility = NULL;
   484         iMobility = NULL;
   498     }
   485     }
   502         ipConnectionNotifier->StopNotifications();
   489         ipConnectionNotifier->StopNotifications();
   503         // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
   490         // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
   504         iHandleStateNotificationsFromManager = true;
   491         iHandleStateNotificationsFromManager = true;
   505     }
   492     }
   506     
   493     
   507     iConnection.Close();
   494     Cancel(); // closes iConnection
   508     iSocketServ.Close();
   495     iSocketServ.Close();
   509     
   496     
   510     // Close global 'Open C' RConnection
   497     // Close global 'Open C' RConnection. If OpenC supports,
   511     setdefaultif(0);
   498     // close the defaultif for good to avoid difficult timing
   512 
   499     // and bouncing issues of network going immediately back up
   513 #ifdef Q_CC_NOKIAX86
   500     //  because of e.g. select() thread etc.
   514     if ((allowSignals && iapClientCount(activeIap) <= 0) ||
   501     if (iDynamicUnSetdefaultif) {
   515 #else
   502         iDynamicUnSetdefaultif();
   516     if ((allowSignals && iapClientCount(activeIap) <= 1) ||
   503     } else {
   517 #endif
   504         setdefaultif(0);
   518         (publicConfig.type() == QNetworkConfiguration::UserChoice)) {
   505     }
       
   506 
       
   507     // If UserChoice, go down immediately. If some other configuration,
       
   508     // go down immediately if there is no reports expected from the platform;
       
   509     // in practice Connection Monitor is aware of connections only after
       
   510     // KFinishedSelection event, and hence reports only after that event, but
       
   511     // that does not seem to be trusted on all Symbian versions --> safest
       
   512     // to go down.
       
   513     if (publicConfig.type() == QNetworkConfiguration::UserChoice || state == QNetworkSession::Connecting) {
       
   514 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   515     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   516             << "going Disconnected right away. Deprecating connection monitor ID: " << publicConfig.d.data()->connectionId;
       
   517 #endif
       
   518 
       
   519         // The connection has gone down, and processing of status updates must be
       
   520         // stopped. Depending on platform, there may come 'connecting/connected' states
       
   521         // considerably later (almost a second). Connection id is an increasing
       
   522         // number, so this does not affect next _real_ 'conneting/connected' states.
       
   523         iDeprecatedConnectionId = publicConfig.d.data()->connectionId;
   519         newState(QNetworkSession::Closing);
   524         newState(QNetworkSession::Closing);
   520     }
   525         newState(QNetworkSession::Disconnected);
   521     
   526     }
   522     if (allowSignals) {
   527     if (allowSignals) {
   523         if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
       
   524             newState(QNetworkSession::Disconnected);
       
   525         }
       
   526         emit q->closed();
   528         emit q->closed();
   527     }
   529     }
   528 }
   530 }
   529 
   531 
   530 void QNetworkSessionPrivate::stop()
   532 void QNetworkSessionPrivate::stop()
   553         if (status.Int() != KErrNone) {
   555         if (status.Int() != KErrNone) {
   554             return;
   556             return;
   555         }
   557         }
   556         TUint numSubConnections; // Not used but needed by GetConnectionInfo i/f
   558         TUint numSubConnections; // Not used but needed by GetConnectionInfo i/f
   557         TUint connectionId;
   559         TUint connectionId;
   558         for (TInt i = 1; i <= count; ++i) {
   560         for (TUint i = 1; i <= count; ++i) {
   559             // Get (connection monitor's assigned) connection ID
   561             // Get (connection monitor's assigned) connection ID
   560             TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);            
   562             TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);            
   561             if (ret == KErrNone) {
   563             if (ret == KErrNone) {
   562                 // See if connection Id matches with our Id. If so, stop() it.
   564                 // See if connection Id matches with our Id. If so, stop() it.
   563                 if (publicConfig.d.data()->connectionId == connectionId) {
   565                 if (publicConfig.d.data()->connectionId == connectionId) {
   595 
   597 
   596 void QNetworkSessionPrivate::migrate()
   598 void QNetworkSessionPrivate::migrate()
   597 {
   599 {
   598 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   600 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   599     if (iMobility) {
   601     if (iMobility) {
   600         // Close global 'Open C' RConnection
   602         // Close global 'Open C' RConnection. If openC supports, use the 'heavy'
   601         setdefaultif(0);
   603         // version to block all subsequent requests.
       
   604         if (iDynamicUnSetdefaultif) {
       
   605             iDynamicUnSetdefaultif();
       
   606         } else {
       
   607             setdefaultif(0);
       
   608         }
   602         // Start migrating to new IAP
   609         // Start migrating to new IAP
   603         iMobility->MigrateToPreferredCarrier();
   610         iMobility->MigrateToPreferredCarrier();
   604     }
   611     }
   605 #endif
   612 #endif
   606 }
   613 }
   676     if (iALREnabled > 0) {
   683     if (iALREnabled > 0) {
   677         iALRUpgradingConnection = aIsUpgrade;
   684         iALRUpgradingConnection = aIsUpgrade;
   678         QList<QNetworkConfiguration> configs = publicConfig.children();
   685         QList<QNetworkConfiguration> configs = publicConfig.children();
   679         for (int i=0; i < configs.count(); i++) {
   686         for (int i=0; i < configs.count(); i++) {
   680             if (configs[i].d.data()->numericId == aNewAPInfo.AccessPoint()) {
   687             if (configs[i].d.data()->numericId == aNewAPInfo.AccessPoint()) {
   681                 emit q->preferredConfigurationChanged(configs[i],aIsSeamless);
   688                 // Any slot connected to the signal might throw an std::exception,
       
   689                 // which must not propagate into Symbian code (this function is a callback
       
   690                 // from platform). We could convert exception to a symbian Leave, but since the
       
   691                 // prototype of this function bans this (no trailing 'L'), we just catch
       
   692                 // and drop.
       
   693                 QT_TRY {
       
   694                     emit q->preferredConfigurationChanged(configs[i],aIsSeamless);
       
   695                 }
       
   696                 QT_CATCH (std::exception&) {}
   682             }
   697             }
   683         }
   698         }
   684     } else {
   699     } else {
   685         migrate();
   700         migrate();
   686     }
   701     }
   687 }
   702 }
   688 
   703 
   689 void QNetworkSessionPrivate::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsSeamless*/)
   704 void QNetworkSessionPrivate::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsSeamless*/)
   690 {
   705 {
   691     if (iALREnabled > 0) {
   706     if (iALREnabled > 0) {
   692         emit q->newConfigurationActivated();
   707         QT_TRY {
       
   708             emit q->newConfigurationActivated();
       
   709         }
       
   710         QT_CATCH (std::exception&) {}
   693     } else {
   711     } else {
   694         accept();
   712         accept();
   695     }
   713     }
   696 }
   714 }
   697 
   715 
   698 void QNetworkSessionPrivate::Error(TInt /*aError*/)
   716 void QNetworkSessionPrivate::Error(TInt /*aError*/)
   699 {
   717 {
   700 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
   718 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
   701     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
   719     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
   702             << "roaming Error() occured";
   720             << "roaming Error() occured, isOpen is: " << isOpen;
   703 #endif
   721 #endif
   704     if (isOpen) {
   722     if (isOpen) {
   705         isOpen = false;
   723         isOpen = false;
   706         activeConfig = QNetworkConfiguration();
   724         activeConfig = QNetworkConfiguration();
   707         serviceConfig = QNetworkConfiguration();
   725         serviceConfig = QNetworkConfiguration();
   709         emit q->error(iError);
   727         emit q->error(iError);
   710         Cancel();
   728         Cancel();
   711         if (ipConnectionNotifier) {
   729         if (ipConnectionNotifier) {
   712             ipConnectionNotifier->StopNotifications();
   730             ipConnectionNotifier->StopNotifications();
   713         }
   731         }
   714         syncStateWithInterface();
   732         QT_TRY {
   715         // In some cases IAP is still in Connected state when
   733             syncStateWithInterface();
   716         // syncStateWithInterface(); is called
   734             // In some cases IAP is still in Connected state when
   717         // => Following call makes sure that Session state
   735             // syncStateWithInterface(); is called
   718         //    changes immediately to Disconnected.
   736             // => Following call makes sure that Session state
   719         newState(QNetworkSession::Disconnected);
   737             //    changes immediately to Disconnected.
   720         emit q->closed();
   738             newState(QNetworkSession::Disconnected);
       
   739             emit q->closed();
       
   740         }
       
   741         QT_CATCH (std::exception&) {}
   721     } else if (iStoppedByUser) {
   742     } else if (iStoppedByUser) {
   722         // If the user of this session has called the stop() and
   743         // If the user of this session has called the stop() and
   723         // configuration is based on internet SNAP, this needs to be
   744         // configuration is based on internet SNAP, this needs to be
   724         // done here because platform might roam.
   745         // done here because platform might roam.
   725         newState(QNetworkSession::Disconnected);
   746         QT_TRY {
       
   747             newState(QNetworkSession::Disconnected);
       
   748         }
       
   749         QT_CATCH (std::exception&) {}
   726     }
   750     }
   727 }
   751 }
   728 #endif
   752 #endif
   729 
   753 
   730 void QNetworkSessionPrivate::setALREnabled(bool enabled)
   754 void QNetworkSessionPrivate::setALREnabled(bool enabled)
   845 {
   869 {
   846     if (iapId == 0) {
   870     if (iapId == 0) {
   847         _LIT(KSetting, "IAP\\Id");
   871         _LIT(KSetting, "IAP\\Id");
   848         iConnection.GetIntSetting(KSetting, iapId);
   872         iConnection.GetIntSetting(KSetting, iapId);
   849     }
   873     }
   850  
   874 
   851 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   875 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   852     if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
   876     if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
   853         // Try to search IAP from the used SNAP using IAP Id
   877         // Try to search IAP from the used SNAP using IAP Id
   854         QList<QNetworkConfiguration> children = publicConfig.children();
   878         QList<QNetworkConfiguration> children = publicConfig.children();
   855         for (int i=0; i < children.count(); i++) {
   879         for (int i=0; i < children.count(); i++) {
   866         //      3. "Dial-up number" for "Data call Bearer" or "High Speed (GSM)" Bearer
   890         //      3. "Dial-up number" for "Data call Bearer" or "High Speed (GSM)" Bearer
   867         //    <=> Note: It's possible that in this case reported IAP is
   891         //    <=> Note: It's possible that in this case reported IAP is
   868         //              clone of the one of the IAPs of the used SNAP
   892         //              clone of the one of the IAPs of the used SNAP
   869         //              => If mappingName matches, clone has been found
   893         //              => If mappingName matches, clone has been found
   870         QNetworkConfiguration pt;
   894         QNetworkConfiguration pt;
   871         pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(QString::number(qHash(iapId)));
   895         pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)));
   872         if (pt.d) {
   896         if (pt.d) {
   873             for (int i=0; i < children.count(); i++) {
   897             for (int i=0; i < children.count(); i++) {
   874                 if (children[i].d.data()->mappingName == pt.d.data()->mappingName) {
   898                 if (children[i].d.data()->mappingName == pt.d.data()->mappingName) {
   875                     return children[i];
   899                     return children[i];
   876                 }
   900                 }
   877             }
   901             }
   878         } else {
   902         } else {
       
   903 #ifdef OCC_FUNCTIONALITY_AVAILABLE
       
   904             // On Symbian^3 (only, not earlier or Symbian^4) if the SNAP was not reachable, it triggers
       
   905             // user choice type of activity (EasyWLAN). As a result, a new IAP may be created, and
       
   906             // hence if was not found yet. Therefore update configurations and see if there is something new.
       
   907             // 1. Update knowledge from the databases.
       
   908             ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->updateConfigurations();
       
   909             // 2. Check if new configuration was created during connection creation
       
   910             QList<QString> knownConfigs = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.keys();
       
   911 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   912             qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   913                     << "opened configuration was not known beforehand, looking for new.";
       
   914 #endif
       
   915             if (knownConfigs.count() > iKnownConfigsBeforeConnectionStart.count()) {
       
   916                 // Configuration count increased => new configuration was created
       
   917                 // => Search new, created configuration
       
   918                 QString newIapId;
       
   919                 for (int i=0; i < iKnownConfigsBeforeConnectionStart.count(); i++) {
       
   920                     if (knownConfigs[i] != iKnownConfigsBeforeConnectionStart[i]) {
       
   921                         newIapId = knownConfigs[i];
       
   922                         break;
       
   923                     }
       
   924                 }
       
   925                 if (newIapId.isEmpty()) {
       
   926                     newIapId = knownConfigs[knownConfigs.count()-1];
       
   927                 }
       
   928                 pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(newIapId);
       
   929                 if (pt.d) {
       
   930 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   931                     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   932                             << "new configuration was found, name, IAP id: " << pt.name() << pt.identifier();
       
   933 #endif
       
   934                     return pt;
       
   935                 }
       
   936             }
       
   937 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   938             qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   939                     << "configuration was not found, returning invalid.";
       
   940 #endif
       
   941 #endif // OCC_FUNCTIONALITY_AVAILABLE
   879             // Given IAP Id was not found from known IAPs array
   942             // Given IAP Id was not found from known IAPs array
   880             return QNetworkConfiguration();
   943             return QNetworkConfiguration();
   881         }
   944         }
   882 
       
   883         // Matching IAP was not found from used SNAP
   945         // Matching IAP was not found from used SNAP
   884         // => IAP from another SNAP is returned
   946         // => IAP from another SNAP is returned
   885         //    (Note: Returned IAP matches to given IAP Id)
   947         //    (Note: Returned IAP matches to given IAP Id)
   886         return pt;
   948         return pt;
   887     }
   949     }
   888 #endif
   950 #endif
   889     
       
   890     if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   951     if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   891         if (publicConfig.d.data()->manager) {
   952         if (publicConfig.d.data()->manager) {
   892             QNetworkConfiguration pt;
   953             QNetworkConfiguration pt;
   893             // Try to found User Selected IAP from known IAPs (accessPointConfigurations)
   954             // Try to found User Selected IAP from known IAPs (accessPointConfigurations)
   894             pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(QString::number(qHash(iapId)));
   955             pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)));
   895             if (pt.d) {
   956             if (pt.d) {
   896                 return pt;
   957                 return pt;
   897             } else {
   958             } else {
   898                 // Check if new (WLAN) IAP was created in IAP/SNAP dialog
   959                 // Check if new (WLAN) IAP was created in IAP/SNAP dialog
   899                 // 1. Sync internal configurations array to commsdb first
   960                 // 1. Sync internal configurations array to commsdb first
   926     return publicConfig;
   987     return publicConfig;
   927 }
   988 }
   928 
   989 
   929 void QNetworkSessionPrivate::RunL()
   990 void QNetworkSessionPrivate::RunL()
   930 {
   991 {
       
   992 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   993     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   994             << "RConnection::RunL with status code: " << iStatus.Int();
       
   995 #endif
   931     TInt statusCode = iStatus.Int();
   996     TInt statusCode = iStatus.Int();
   932 
   997 
   933     switch (statusCode) {
   998     switch (statusCode) {
   934         case KErrNone: // Connection created successfully
   999         case KErrNone: // Connection created successfully
   935             {
  1000             {
   947             }
  1012             }
   948             
  1013             
   949             if (error != KErrNone) {
  1014             if (error != KErrNone) {
   950                 isOpen = false;
  1015                 isOpen = false;
   951                 iError = QNetworkSession::UnknownSessionError;
  1016                 iError = QNetworkSession::UnknownSessionError;
   952                 emit q->error(iError);
  1017                 QT_TRYCATCH_LEAVING(emit q->error(iError));
   953                 Cancel();
  1018                 Cancel();
   954                 if (ipConnectionNotifier) {
  1019                 if (ipConnectionNotifier) {
   955                     ipConnectionNotifier->StopNotifications();
  1020                     ipConnectionNotifier->StopNotifications();
   956                 }
  1021                 }
   957                 syncStateWithInterface();
  1022                 QT_TRYCATCH_LEAVING(syncStateWithInterface());
   958                 return;
  1023                 return;
   959             }
  1024             }
   960  
  1025  
   961 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
  1026 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   962             if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
  1027             if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
   973                 serviceConfig = pt;
  1038                 serviceConfig = pt;
   974             }
  1039             }
   975             
  1040             
   976             startTime = QDateTime::currentDateTime();
  1041             startTime = QDateTime::currentDateTime();
   977 
  1042 
   978             newState(QNetworkSession::Connected);
  1043             QT_TRYCATCH_LEAVING({
   979             emit quitPendingWaitsForOpened();
  1044                     newState(QNetworkSession::Connected);
       
  1045                     emit quitPendingWaitsForOpened();
       
  1046                 });
   980             }
  1047             }
   981             break;
  1048             break;
   982         case KErrNotFound: // Connection failed
  1049         case KErrNotFound: // Connection failed
   983             isOpen = false;
  1050             isOpen = false;
   984             activeConfig = QNetworkConfiguration();
  1051             activeConfig = QNetworkConfiguration();
   985             serviceConfig = QNetworkConfiguration();
  1052             serviceConfig = QNetworkConfiguration();
   986             iError = QNetworkSession::InvalidConfigurationError;
  1053             iError = QNetworkSession::InvalidConfigurationError;
   987             emit q->error(iError);
  1054             QT_TRYCATCH_LEAVING(emit q->error(iError));
   988             Cancel();
  1055             Cancel();
   989             if (ipConnectionNotifier) {
  1056             if (ipConnectionNotifier) {
   990                 ipConnectionNotifier->StopNotifications();
  1057                 ipConnectionNotifier->StopNotifications();
   991             }
  1058             }
   992             syncStateWithInterface();
  1059             QT_TRYCATCH_LEAVING(syncStateWithInterface());
   993             break;
  1060             break;
   994         case KErrCancel: // Connection attempt cancelled
  1061         case KErrCancel: // Connection attempt cancelled
   995         case KErrAlreadyExists: // Connection already exists
  1062         case KErrAlreadyExists: // Connection already exists
   996         default:
  1063         default:
   997             isOpen = false;
  1064             isOpen = false;
  1001                 publicConfig.state() == QNetworkConfiguration::Defined) {
  1068                 publicConfig.state() == QNetworkConfiguration::Defined) {
  1002                 iError = QNetworkSession::InvalidConfigurationError;
  1069                 iError = QNetworkSession::InvalidConfigurationError;
  1003             } else {
  1070             } else {
  1004                 iError = QNetworkSession::UnknownSessionError;
  1071                 iError = QNetworkSession::UnknownSessionError;
  1005             }
  1072             }
  1006             emit q->error(iError);
  1073             QT_TRYCATCH_LEAVING(emit q->error(iError));
  1007             Cancel();
  1074             Cancel();
  1008             if (ipConnectionNotifier) {
  1075             if (ipConnectionNotifier) {
  1009                 ipConnectionNotifier->StopNotifications();
  1076                 ipConnectionNotifier->StopNotifications();
  1010             }
  1077             }
  1011             syncStateWithInterface();
  1078             QT_TRYCATCH_LEAVING(syncStateWithInterface());
  1012             break;
  1079             break;
  1013     }
  1080     }
  1014 }
  1081 }
  1015 
  1082 
  1016 void QNetworkSessionPrivate::DoCancel()
  1083 void QNetworkSessionPrivate::DoCancel()
  1115             }
  1182             }
  1116         } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
  1183         } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
  1117             QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
  1184             QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
  1118             for (int i = 0; i < subConfigurations.count(); i++) {
  1185             for (int i = 0; i < subConfigurations.count(); i++) {
  1119                 if (subConfigurations[i].d.data()->numericId == accessPointId) {
  1186                 if (subConfigurations[i].d.data()->numericId == accessPointId) {
  1120                     if (newState == QNetworkSession::Connected) {
  1187                     if (newState != QNetworkSession::Disconnected) {
  1121                         state = newState;
  1188                         state = newState;
  1122 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
  1189 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
  1123                         qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed D  to: " << state;
  1190                         qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed D  to: " << state;
  1124 #endif
  1191 #endif
  1125                         emit q->stateChanged(state);
  1192                         emit q->stateChanged(state);
  1126                         retVal = true;
  1193                         retVal = true;
  1127                     } else {
  1194                     } else {
  1128                         QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
  1195                         QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
  1129                         if ((config.state() == QNetworkConfiguration::Defined) ||
  1196                         if ((config.state() == QNetworkConfiguration::Defined) ||
  1130                             (config.state() == QNetworkConfiguration::Discovered)) {
  1197                             (config.state() == QNetworkConfiguration::Discovered)) {
       
  1198                             activeConfig = QNetworkConfiguration();
  1131                             state = newState;
  1199                             state = newState;
  1132 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
  1200 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
  1133                             qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed E  to: " << state;
  1201                             qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed E  to: " << state;
  1134 #endif
  1202 #endif
  1135                             emit q->stateChanged(state);
  1203                             emit q->stateChanged(state);
  1136                             retVal = true;
  1204                             retVal = true;
       
  1205                         } else if (config.state() == QNetworkConfiguration::Active) {
       
  1206                             // Connection to used IAP was closed, but there is another
       
  1207                             // IAP that's active in used SNAP
       
  1208                             // => Change state back to Connected
       
  1209                             state =  QNetworkSession::Connected;
       
  1210                             emit q->stateChanged(state);
       
  1211                             retVal = true;
       
  1212 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1213                             qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed F  to: " << state;
       
  1214 #endif
  1137                         }
  1215                         }
  1138                     }
  1216                     }
  1139                 }
  1217                 }
  1140             }
  1218             }
       
  1219 #ifdef OCC_FUNCTIONALITY_AVAILABLE
       
  1220             // If the retVal is not true here, it means that the status update may apply to an IAP outside of
       
  1221             // SNAP (session is based on SNAP but follows IAP outside of it), which may occur on Symbian^3 EasyWlan.
       
  1222             if (retVal == false && activeConfig.d.data() && activeConfig.d.data()->numericId == accessPointId) {
       
  1223 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1224                 qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed G  to: " << state;
       
  1225 #endif
       
  1226                 if (newState == QNetworkSession::Disconnected) {
       
  1227                     activeConfig = QNetworkConfiguration();
       
  1228                 }
       
  1229                 state = newState;
       
  1230                 emit q->stateChanged(state);
       
  1231                 retVal = true;
       
  1232             }
       
  1233 #endif
  1141         }
  1234         }
  1142     }
  1235     }
  1143     
  1236     
  1144     if (emitSessionClosed) {
  1237     if (emitSessionClosed) {
  1145         emit q->closed();
  1238         emit q->closed();
  1148         // The connection has gone down, and processing of status updates must be
  1241         // The connection has gone down, and processing of status updates must be
  1149         // stopped. Depending on platform, there may come 'connecting/connected' states
  1242         // stopped. Depending on platform, there may come 'connecting/connected' states
  1150         // considerably later (almost a second). Connection id is an increasing
  1243         // considerably later (almost a second). Connection id is an increasing
  1151         // number, so this does not affect next _real_ 'conneting/connected' states.
  1244         // number, so this does not affect next _real_ 'conneting/connected' states.
  1152         iDeprecatedConnectionId = publicConfig.d.data()->connectionId;
  1245         iDeprecatedConnectionId = publicConfig.d.data()->connectionId;
  1153     }
  1246 #ifdef OCC_FUNCTIONALITY_AVAILABLE
  1154 
  1247         // Just in case clear activeConfiguration.
       
  1248         activeConfig = QNetworkConfiguration();
       
  1249 #endif
       
  1250     }
  1155     return retVal;
  1251     return retVal;
  1156 }
  1252 }
  1157 
  1253 
  1158 void QNetworkSessionPrivate::handleSymbianConnectionStatusChange(TInt aConnectionStatus,
  1254 void QNetworkSessionPrivate::handleSymbianConnectionStatusChange(TInt aConnectionStatus,
  1159                                                                  TInt aError,
  1255                                                                  TInt aError,
  1174 
  1270 
  1175         // Selection finished
  1271         // Selection finished
  1176         case KFinishedSelection:
  1272         case KFinishedSelection:
  1177             if (aError == KErrNone)
  1273             if (aError == KErrNone)
  1178                 {
  1274                 {
  1179                 // The user successfully selected an IAP to be used
       
  1180                 break;
  1275                 break;
  1181                 }
  1276                 }
  1182             else
  1277             else
  1183                 {
  1278                 {
  1184                 // The user pressed e.g. "Cancel" and did not select an IAP
  1279                 // The user pressed e.g. "Cancel" and did not select an IAP
  1284 }
  1379 }
  1285 
  1380 
  1286 void ConnectionProgressNotifier::RunL()
  1381 void ConnectionProgressNotifier::RunL()
  1287 {
  1382 {
  1288     if (iStatus == KErrNone) {
  1383     if (iStatus == KErrNone) {
  1289         iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError);
  1384         QT_TRYCATCH_LEAVING(iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError));
  1290     
  1385     
  1291         SetActive();
  1386         SetActive();
  1292         iConnection.ProgressNotification(iProgress, iStatus);
  1387         iConnection.ProgressNotification(iProgress, iStatus);
  1293     }
  1388     }
  1294 }
  1389 }