qtmobility/src/bearer/qnetworksession_s60_p.cpp
branchRCL_3
changeset 5 4ea83c148e84
parent 3 eb34711bcc75
child 6 4203353e74ea
equal deleted inserted replaced
4:d965ea371a4f 5:4ea83c148e84
    50 #include <stdapis/net/if.h>
    50 #include <stdapis/net/if.h>
    51 
    51 
    52 QTM_BEGIN_NAMESPACE
    52 QTM_BEGIN_NAMESPACE
    53 
    53 
    54 QNetworkSessionPrivate::QNetworkSessionPrivate()
    54 QNetworkSessionPrivate::QNetworkSessionPrivate()
    55     : CActive(CActive::EPriorityStandard), state(QNetworkSession::Invalid),
    55     : CActive(CActive::EPriorityUserInput), state(QNetworkSession::Invalid),
    56       isOpen(false), ipConnectionNotifier(0), iError(QNetworkSession::UnknownSessionError),
    56       isOpen(false), ipConnectionNotifier(0), iHandleStateNotificationsFromManager(false),
    57       iALREnabled(0), iConnectInBackground(false)
    57       iFirstSync(true), iStoppedByUser(false), iClosedByUser(false), iDeprecatedConnectionId(0),
       
    58       iError(QNetworkSession::UnknownSessionError), iALREnabled(0), iConnectInBackground(false)
    58 {
    59 {
    59     CActiveScheduler::Add(this);
    60     CActiveScheduler::Add(this);
    60 
    61 
    61 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
    62 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
    62     iMobility = NULL;
    63     iMobility = NULL;
    63 #endif
    64 #endif
       
    65 
    64     TRAP_IGNORE(iConnectionMonitor.ConnectL());
    66     TRAP_IGNORE(iConnectionMonitor.ConnectL());
    65 }
    67 }
    66 
    68 
    67 QNetworkSessionPrivate::~QNetworkSessionPrivate()
    69 QNetworkSessionPrivate::~QNetworkSessionPrivate()
    68 {
    70 {
    87     iConnection.Close();
    89     iConnection.Close();
    88     iSocketServ.Close();
    90     iSocketServ.Close();
    89     
    91     
    90     // Close global 'Open C' RConnection
    92     // Close global 'Open C' RConnection
    91     setdefaultif(0);
    93     setdefaultif(0);
    92 
    94     
    93     iConnectionMonitor.CancelNotifications();
       
    94     iConnectionMonitor.Close();
    95     iConnectionMonitor.Close();
       
    96 }
       
    97 
       
    98 void QNetworkSessionPrivate::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState)
       
    99 {
       
   100     if (iHandleStateNotificationsFromManager) {
       
   101 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   102         qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   103                 << "configurationStateChanged from manager for IAP : " << QString::number(accessPointId)
       
   104                 << "configurationStateChanged connMon ID : " << QString::number(connMonId)
       
   105                 << " : to a state: " << newState
       
   106                 << " whereas my current state is: " << state;
       
   107 #endif
       
   108         if (connMonId == iDeprecatedConnectionId) {
       
   109 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   110             qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   111                     << "however status update from manager ignored because it related to already closed connection.";
       
   112 #endif
       
   113             return;
       
   114         }
       
   115         this->newState(newState, accessPointId);
       
   116     }
       
   117 }
       
   118 
       
   119 void QNetworkSessionPrivate::configurationRemoved(const QNetworkConfiguration& config)
       
   120 {
       
   121     if (!publicConfig.d.data()) {
       
   122         return;
       
   123     }
       
   124     if (config.d.data()->numericId == publicConfig.d.data()->numericId) {
       
   125 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   126         qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   127                  << "configurationRemoved IAP: " << QString::number(publicConfig.d.data()->numericId) << " : going to State: Invalid";
       
   128 #endif
       
   129         this->newState(QNetworkSession::Invalid, publicConfig.d.data()->numericId);
       
   130     }
    95 }
   131 }
    96 
   132 
    97 void QNetworkSessionPrivate::syncStateWithInterface()
   133 void QNetworkSessionPrivate::syncStateWithInterface()
    98 {
   134 {
    99     if (!publicConfig.d) {
   135     if (!publicConfig.d) {
   100         return;
   136         return;
   101     }
   137     }
   102 
   138 
   103     // Start monitoring changes in IAP states
   139     if (iFirstSync && publicConfig.d.data()) {
   104     TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
   140         QObject::connect(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager), SIGNAL(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)),
       
   141                          this, SLOT(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)));
       
   142         // Listen to configuration removals, so that in case the configuration
       
   143         // this session is based on is removed, session knows to enter Invalid -state.
       
   144         QObject::connect(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager),
       
   145                          SIGNAL(configurationRemoved(QNetworkConfiguration)),
       
   146                          this, SLOT(configurationRemoved(QNetworkConfiguration)));
       
   147     }
       
   148     // Start listening IAP state changes from QNetworkConfigurationManagerPrivate
       
   149     iHandleStateNotificationsFromManager = true;    
   105 
   150 
   106     // Check open connections to see if there is already
   151     // Check open connections to see if there is already
   107     // an open connection to selected IAP or SNAP
   152     // an open connection to selected IAP or SNAP
   108     TUint count;
   153     TUint count;
   109     TRequestStatus status;
   154     TRequestStatus status;
   135             }
   180             }
   136         }
   181         }
   137     }
   182     }
   138 
   183 
   139     if (state != QNetworkSession::Connected) {
   184     if (state != QNetworkSession::Connected) {
   140         // There were no open connections to used IAP or SNAP
   185         if ((publicConfig.d.data()->state & QNetworkConfiguration::Discovered) ==
   141         if (iError == QNetworkSession::InvalidConfigurationError) {
       
   142             newState(QNetworkSession::Invalid);
       
   143         }
       
   144         else if ((publicConfig.d.data()->state & QNetworkConfiguration::Discovered) ==
       
   145             QNetworkConfiguration::Discovered) {
   186             QNetworkConfiguration::Discovered) {
   146             newState(QNetworkSession::Disconnected);
   187             newState(QNetworkSession::Disconnected);
   147         } else {
   188         } else {
   148             newState(QNetworkSession::NotAvailable);
   189             newState(QNetworkSession::NotAvailable);
   149         }
   190         }
   240     return iError;
   281     return iError;
   241 }
   282 }
   242 
   283 
   243 void QNetworkSessionPrivate::open()
   284 void QNetworkSessionPrivate::open()
   244 {
   285 {
       
   286 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   287         qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   288                 << "open() called, session state is: " << state << " and isOpen is: "
       
   289                 << isOpen;
       
   290 #endif
   245     if (isOpen || (state == QNetworkSession::Connecting)) {
   291     if (isOpen || (state == QNetworkSession::Connecting)) {
   246         return;
   292         return;
   247     }
   293     }
   248 
   294     
   249     // Cancel notifications from RConnectionMonitor
   295     // Stop handling IAP state change signals from QNetworkConfigurationManagerPrivate
   250     // => RConnection::ProgressNotification will be used for IAP/SNAP monitoring
   296     // => RConnection::ProgressNotification will be used for IAP/SNAP monitoring
   251     iConnectionMonitor.CancelNotifications();
   297     iHandleStateNotificationsFromManager = false;
   252 
   298 
   253     // Configuration may have been invalidated after session creation by platform
   299     // Configuration may have been invalidated after session creation by platform
   254     // (e.g. configuration has been deleted).
   300     // (e.g. configuration has been deleted).
   255     if (!publicConfig.isValid()) {
   301     if (!publicConfig.isValid()) {
   256         newState(QNetworkSession::Invalid);
   302         newState(QNetworkSession::Invalid);
   257         iError = QNetworkSession::InvalidConfigurationError;
   303         iError = QNetworkSession::InvalidConfigurationError;
   258         emit q->error(iError);
   304         emit q->error(iError);
   259         syncStateWithInterface();
       
   260         return;
   305         return;
   261     }
   306     }
   262     // If opening a (un)defined configuration, session emits error and enters
   307     // If opening a undefined configuration, session emits error and enters
   263     // NotAvailable -state.
   308     // NotAvailable -state. Note that we will try ones in 'defined' state to avoid excessive
   264     if (publicConfig.state() == QNetworkConfiguration::Undefined ||
   309     // need for WLAN scans (via updateConfigurations()), because user may have walked
   265         publicConfig.state() == QNetworkConfiguration::Defined) {
   310     // into a WLAN range, but periodic background scan has not occurred yet -->
       
   311     // we don't want to force application to make frequent updateConfigurations() calls
       
   312     // to be able to try if e.g. home WLAN is available.
       
   313     if (publicConfig.state() == QNetworkConfiguration::Undefined) {
   266         newState(QNetworkSession::NotAvailable);
   314         newState(QNetworkSession::NotAvailable);
   267         iError = QNetworkSession::InvalidConfigurationError;
   315         iError = QNetworkSession::InvalidConfigurationError;
   268         emit q->error(iError);
   316         emit q->error(iError);
   269         return;
   317         return;
   270     }
   318     }
   271     
   319     // Clear possible previous states
       
   320     iStoppedByUser = false;
       
   321     iClosedByUser = false;
       
   322     iDeprecatedConnectionId = 0;
       
   323 
   272     TInt error = iSocketServ.Connect();
   324     TInt error = iSocketServ.Connect();
   273     if (error != KErrNone) {
   325     if (error != KErrNone) {
   274         // Could not open RSocketServ
   326         // Could not open RSocketServ
   275         newState(QNetworkSession::Invalid);
   327         newState(QNetworkSession::Invalid);
   276         iError = QNetworkSession::UnknownSessionError;
   328         iError = QNetworkSession::UnknownSessionError;
   418     return 0;
   470     return 0;
   419 }
   471 }
   420 
   472 
   421 void QNetworkSessionPrivate::close(bool allowSignals)
   473 void QNetworkSessionPrivate::close(bool allowSignals)
   422 {
   474 {
       
   475 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   476     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   477             << "close() called, session state is: " << state << " and isOpen is : "
       
   478             << isOpen;
       
   479 #endif
   423     if (!isOpen) {
   480     if (!isOpen) {
   424         return;
   481         return;
   425     }
   482     }
   426 
   483     // Mark this session as closed-by-user so that we are able to report
   427     TUint activeIap = activeConfig.d.data()->numericId;
   484     // distinguish between stop() and close() state transitions
       
   485     // when reporting.
       
   486     iClosedByUser = true;
       
   487 
   428     isOpen = false;
   488     isOpen = false;
   429     activeConfig = QNetworkConfiguration();
   489     activeConfig = QNetworkConfiguration();
   430     serviceConfig = QNetworkConfiguration();
   490     serviceConfig = QNetworkConfiguration();
   431     
   491     
   432     Cancel();
   492     Cancel();
   435         delete iMobility;
   495         delete iMobility;
   436         iMobility = NULL;
   496         iMobility = NULL;
   437     }
   497     }
   438 #endif
   498 #endif
   439 
   499 
   440     if (ipConnectionNotifier) {
   500     if (ipConnectionNotifier && !iHandleStateNotificationsFromManager) {
   441         ipConnectionNotifier->StopNotifications();
   501         ipConnectionNotifier->StopNotifications();
       
   502         // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
       
   503         iHandleStateNotificationsFromManager = true;
   442     }
   504     }
   443     
   505     
   444     iConnection.Close();
   506     iConnection.Close();
   445     iSocketServ.Close();
   507     iSocketServ.Close();
   446     
   508     
   447     // Close global 'Open C' RConnection
   509     // Close global 'Open C' RConnection
   448     setdefaultif(0);
   510     setdefaultif(0);
   449 
   511 
   450 #ifdef Q_CC_NOKIAX86
   512     if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
   451     if ((allowSignals && iapClientCount(activeIap) <= 0) ||
       
   452 #else
       
   453     if ((allowSignals && iapClientCount(activeIap) <= 1) ||
       
   454 #endif
       
   455         (publicConfig.type() == QNetworkConfiguration::UserChoice)) {
       
   456         newState(QNetworkSession::Closing);
   513         newState(QNetworkSession::Closing);
   457     }
   514         newState(QNetworkSession::Disconnected);
   458     
   515     }
   459     syncStateWithInterface();
   516     
   460     if (allowSignals) {
   517     if (allowSignals) {
   461         if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
       
   462             newState(QNetworkSession::Disconnected);
       
   463         }
       
   464         emit q->closed();
   518         emit q->closed();
   465     }
   519     }
   466 }
   520 }
   467 
   521 
   468 void QNetworkSessionPrivate::stop()
   522 void QNetworkSessionPrivate::stop()
   469 {
   523 {
       
   524 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   525     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   526             << "stop() called, session state is: " << state << " and isOpen is : "
       
   527             << isOpen;
       
   528 #endif
   470     if (!isOpen &&
   529     if (!isOpen &&
   471         publicConfig.isValid() &&
   530         publicConfig.isValid() &&
   472         publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
   531         publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
       
   532 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   533     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   534             << "since session is not open, using RConnectionMonitor to stop() the interface";
       
   535 #endif
       
   536         iStoppedByUser = true;
   473         // If the publicConfig is type of IAP, enumerate through connections at
   537         // If the publicConfig is type of IAP, enumerate through connections at
   474         // connection monitor. If publicConfig is active in that list, stop it.
   538         // connection monitor. If publicConfig is active in that list, stop it.
   475         // Otherwise there is nothing to stop. Note: because this QNetworkSession is not open,
   539         // Otherwise there is nothing to stop. Note: because this QNetworkSession is not open,
   476         // activeConfig is not usable.
   540         // activeConfig is not usable.
   477         TUint count;
   541         TUint count;
   481         if (status.Int() != KErrNone) {
   545         if (status.Int() != KErrNone) {
   482             return;
   546             return;
   483         }
   547         }
   484         TUint numSubConnections; // Not used but needed by GetConnectionInfo i/f
   548         TUint numSubConnections; // Not used but needed by GetConnectionInfo i/f
   485         TUint connectionId;
   549         TUint connectionId;
   486         for (TInt i = 1; i <= count; ++i) {
   550         for (TUint i = 1; i <= count; ++i) {
   487             // Get (connection monitor's assigned) connection ID
   551             // Get (connection monitor's assigned) connection ID
   488             TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);            
   552             TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);            
   489             if (ret == KErrNone) {
   553             if (ret == KErrNone) {
   490                 // See if connection Id matches with our Id. If so, stop() it.
   554                 // See if connection Id matches with our Id. If so, stop() it.
   491                 if (publicConfig.d.data()->connectionId == connectionId) {
   555                 if (publicConfig.d.data()->connectionId == connectionId) {
   493                                                               0, // subConnectionId don't care
   557                                                               0, // subConnectionId don't care
   494                                                               KConnectionStop,
   558                                                               KConnectionStop,
   495                                                               ETrue);
   559                                                               ETrue);
   496                 }
   560                 }
   497             }
   561             }
       
   562             // Enter disconnected state right away since the session is not even open.
       
   563             // Symbian^3 connection monitor does not emit KLinkLayerClosed when
       
   564             // connection is stopped via connection monitor.
       
   565             newState(QNetworkSession::Disconnected);
   498         }
   566         }
   499     } else if (isOpen) {
   567     } else if (isOpen) {
       
   568 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   569     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   570             << "since session is open, using RConnection to stop() the interface";
       
   571 #endif
   500         // Since we are open, use RConnection to stop the interface
   572         // Since we are open, use RConnection to stop the interface
   501         isOpen = false;
   573         isOpen = false;
       
   574         iStoppedByUser = true;
   502         newState(QNetworkSession::Closing);
   575         newState(QNetworkSession::Closing);
       
   576         if (ipConnectionNotifier) {
       
   577             ipConnectionNotifier->StopNotifications();
       
   578             // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
       
   579             iHandleStateNotificationsFromManager = true;
       
   580         }
   503         iConnection.Stop(RConnection::EStopAuthoritative);
   581         iConnection.Stop(RConnection::EStopAuthoritative);
   504         isOpen = true;
   582         isOpen = true;
   505         close(false);
   583         close(false);
   506         emit q->closed();
   584         emit q->closed();
   507     }
   585     }
   590     if (iALREnabled > 0) {
   668     if (iALREnabled > 0) {
   591         iALRUpgradingConnection = aIsUpgrade;
   669         iALRUpgradingConnection = aIsUpgrade;
   592         QList<QNetworkConfiguration> configs = publicConfig.children();
   670         QList<QNetworkConfiguration> configs = publicConfig.children();
   593         for (int i=0; i < configs.count(); i++) {
   671         for (int i=0; i < configs.count(); i++) {
   594             if (configs[i].d.data()->numericId == aNewAPInfo.AccessPoint()) {
   672             if (configs[i].d.data()->numericId == aNewAPInfo.AccessPoint()) {
   595                 emit q->preferredConfigurationChanged(configs[i],aIsSeamless);
   673                 // Any slot connected to the signal might throw an std::exception,
       
   674                 // which must not propagate into Symbian code (this function is a callback
       
   675                 // from platform). We could convert exception to a symbian Leave, but since the
       
   676                 // prototype of this function bans this (no trailing 'L'), we just catch
       
   677                 // and drop.
       
   678                 QT_TRY {
       
   679                     emit q->preferredConfigurationChanged(configs[i],aIsSeamless);
       
   680                 }
       
   681                 QT_CATCH (std::exception&) {}
   596             }
   682             }
   597         }
   683         }
   598     } else {
   684     } else {
   599         migrate();
   685         migrate();
   600     }
   686     }
   601 }
   687 }
   602 
   688 
   603 void QNetworkSessionPrivate::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsSeamless*/)
   689 void QNetworkSessionPrivate::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*/, TBool /*aIsSeamless*/)
   604 {
   690 {
   605     if (iALREnabled > 0) {
   691     if (iALREnabled > 0) {
   606         emit q->newConfigurationActivated();
   692         QT_TRY {
       
   693             emit q->newConfigurationActivated();
       
   694         }
       
   695         QT_CATCH (std::exception&) {}
   607     } else {
   696     } else {
   608         accept();
   697         accept();
   609     }
   698     }
   610 }
   699 }
   611 
   700 
   612 void QNetworkSessionPrivate::Error(TInt /*aError*/)
   701 void QNetworkSessionPrivate::Error(TInt /*aError*/)
   613 {
   702 {
       
   703 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
   704     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
   705             << "roaming Error() occured";
       
   706 #endif
   614     if (isOpen) {
   707     if (isOpen) {
   615         isOpen = false;
   708         isOpen = false;
   616         activeConfig = QNetworkConfiguration();
   709         activeConfig = QNetworkConfiguration();
   617         serviceConfig = QNetworkConfiguration();
   710         serviceConfig = QNetworkConfiguration();
   618         iError = QNetworkSession::RoamingError;
   711         iError = QNetworkSession::RoamingError;
   619         emit q->error(iError);
   712         emit q->error(iError);
   620         Cancel();
   713         Cancel();
   621         if (ipConnectionNotifier) {
   714         if (ipConnectionNotifier) {
   622             ipConnectionNotifier->StopNotifications();
   715             ipConnectionNotifier->StopNotifications();
   623         }
   716         }
   624         syncStateWithInterface();
   717         QT_TRY {
   625         // In some cases IAP is still in Connected state when
   718             syncStateWithInterface();
   626         // syncStateWithInterface(); is called
   719             // In some cases IAP is still in Connected state when
   627         // => Following call makes sure that Session state
   720             // syncStateWithInterface(); is called
   628         //    changes immediately to Disconnected.
   721             // => Following call makes sure that Session state
   629         newState(QNetworkSession::Disconnected);
   722             //    changes immediately to Disconnected.
   630         emit q->closed();
   723             newState(QNetworkSession::Disconnected);
       
   724             emit q->closed();
       
   725         }
       
   726         QT_CATCH (std::exception&) {}
       
   727     } else if (iStoppedByUser) {
       
   728         // If the user of this session has called the stop() and
       
   729         // configuration is based on internet SNAP, this needs to be
       
   730         // done here because platform might roam.
       
   731         QT_TRY {
       
   732             newState(QNetworkSession::Disconnected);
       
   733         }
       
   734         QT_CATCH (std::exception&) {}
   631     }
   735     }
   632 }
   736 }
   633 #endif
   737 #endif
   634 
   738 
   635 void QNetworkSessionPrivate::setALREnabled(bool enabled)
   739 void QNetworkSessionPrivate::setALREnabled(bool enabled)
   852             }
   956             }
   853             
   957             
   854             if (error != KErrNone) {
   958             if (error != KErrNone) {
   855                 isOpen = false;
   959                 isOpen = false;
   856                 iError = QNetworkSession::UnknownSessionError;
   960                 iError = QNetworkSession::UnknownSessionError;
   857                 emit q->error(iError);
   961                 QT_TRYCATCH_LEAVING(emit q->error(iError));
   858                 Cancel();
   962                 Cancel();
   859                 if (ipConnectionNotifier) {
   963                 if (ipConnectionNotifier) {
   860                     ipConnectionNotifier->StopNotifications();
   964                     ipConnectionNotifier->StopNotifications();
   861                 }
   965                 }
   862                 syncStateWithInterface();
   966                 QT_TRYCATCH_LEAVING(syncStateWithInterface());
   863                 return;
   967                 return;
   864             }
   968             }
   865  
   969  
   866 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   970 #ifdef SNAP_FUNCTIONALITY_AVAILABLE
   867             if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
   971             if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
   878                 serviceConfig = pt;
   982                 serviceConfig = pt;
   879             }
   983             }
   880             
   984             
   881             startTime = QDateTime::currentDateTime();
   985             startTime = QDateTime::currentDateTime();
   882 
   986 
   883             newState(QNetworkSession::Connected);
   987             QT_TRYCATCH_LEAVING({
   884             emit quitPendingWaitsForOpened();
   988                     newState(QNetworkSession::Connected);
       
   989                     emit quitPendingWaitsForOpened();
       
   990                 });
   885             }
   991             }
   886             break;
   992             break;
   887         case KErrNotFound: // Connection failed
   993         case KErrNotFound: // Connection failed
   888             isOpen = false;
   994             isOpen = false;
   889             activeConfig = QNetworkConfiguration();
   995             activeConfig = QNetworkConfiguration();
   890             serviceConfig = QNetworkConfiguration();
   996             serviceConfig = QNetworkConfiguration();
   891             iError = QNetworkSession::InvalidConfigurationError;
   997             iError = QNetworkSession::InvalidConfigurationError;
   892             emit q->error(iError);
   998             QT_TRYCATCH_LEAVING(emit q->error(iError));
   893             Cancel();
   999             Cancel();
   894             if (ipConnectionNotifier) {
  1000             if (ipConnectionNotifier) {
   895                 ipConnectionNotifier->StopNotifications();
  1001                 ipConnectionNotifier->StopNotifications();
   896             }
  1002             }
   897             syncStateWithInterface();
  1003             QT_TRYCATCH_LEAVING(syncStateWithInterface());
   898             break;
  1004             break;
   899         case KErrCancel: // Connection attempt cancelled
  1005         case KErrCancel: // Connection attempt cancelled
   900         case KErrAlreadyExists: // Connection already exists
  1006         case KErrAlreadyExists: // Connection already exists
   901         default:
  1007         default:
   902             isOpen = false;
  1008             isOpen = false;
   903             activeConfig = QNetworkConfiguration();
  1009             activeConfig = QNetworkConfiguration();
   904             serviceConfig = QNetworkConfiguration();
  1010             serviceConfig = QNetworkConfiguration();
   905             iError = QNetworkSession::UnknownSessionError;
  1011             if (publicConfig.state() == QNetworkConfiguration::Undefined ||
   906             emit q->error(iError);
  1012                 publicConfig.state() == QNetworkConfiguration::Defined) {
       
  1013                 iError = QNetworkSession::InvalidConfigurationError;
       
  1014             } else {
       
  1015                 iError = QNetworkSession::UnknownSessionError;
       
  1016             }
       
  1017             QT_TRYCATCH_LEAVING(emit q->error(iError));
   907             Cancel();
  1018             Cancel();
   908             if (ipConnectionNotifier) {
  1019             if (ipConnectionNotifier) {
   909                 ipConnectionNotifier->StopNotifications();
  1020                 ipConnectionNotifier->StopNotifications();
   910             }
  1021             }
   911             syncStateWithInterface();
  1022             QT_TRYCATCH_LEAVING(syncStateWithInterface());
   912             break;
  1023             break;
   913     }
  1024     }
   914 }
  1025 }
   915 
  1026 
   916 void QNetworkSessionPrivate::DoCancel()
  1027 void QNetworkSessionPrivate::DoCancel()
   917 {
  1028 {
   918     iConnection.Close();
  1029     iConnection.Close();
   919 }
  1030 }
   920 
  1031 
       
  1032 // Enters newState if feasible according to current state.
       
  1033 // AccessPointId may be given as parameter. If it is zero, state-change is assumed to
       
  1034 // concern this session's configuration. If non-zero, the configuration is looked up
       
  1035 // and checked if it matches the configuration this session is based on.
   921 bool QNetworkSessionPrivate::newState(QNetworkSession::State newState, TUint accessPointId)
  1036 bool QNetworkSessionPrivate::newState(QNetworkSession::State newState, TUint accessPointId)
   922 {
  1037 {
       
  1038 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1039     qDebug() << "QNS this : " << QString::number((uint)this) << " - "
       
  1040              << "NEW STATE, IAP ID : " << QString::number(accessPointId) << " , newState : " << QString::number(newState);
       
  1041 #endif
   923     // Make sure that activeConfig is always updated when SNAP is signaled to be
  1042     // Make sure that activeConfig is always updated when SNAP is signaled to be
   924     // connected.
  1043     // connected.
   925     if (isOpen && publicConfig.type() == QNetworkConfiguration::ServiceNetwork &&
  1044     if (isOpen && publicConfig.type() == QNetworkConfiguration::ServiceNetwork &&
   926         newState == QNetworkSession::Connected) {
  1045         newState == QNetworkSession::Connected) {
   927         activeConfig = activeConfiguration(accessPointId);
  1046         activeConfig = activeConfiguration(accessPointId);
   935 
  1054 
   936     // Make sure that Connecting state does not overwrite Roaming state
  1055     // Make sure that Connecting state does not overwrite Roaming state
   937     if (state == QNetworkSession::Roaming && newState == QNetworkSession::Connecting) {
  1056     if (state == QNetworkSession::Roaming && newState == QNetworkSession::Connecting) {
   938         return false;
  1057         return false;
   939     }
  1058     }
       
  1059     
       
  1060     // Make sure that Connected state is not reported when Connection is
       
  1061     // already Closing.
       
  1062     // Note: Stopping connection results sometimes KLinkLayerOpen
       
  1063     //       to be reported first (just before KLinkLayerClosed).
       
  1064     if (state == QNetworkSession::Closing && newState == QNetworkSession::Connected) {
       
  1065         return false;
       
  1066     }
       
  1067 
       
  1068     // Make sure that some lagging 'closing' state-changes do not overwrite
       
  1069     // if we are already disconnected or closed.
       
  1070     if (state == QNetworkSession::Disconnected && newState == QNetworkSession::Closing) {
       
  1071         return false;
       
  1072     }
   940 
  1073 
   941     bool emitSessionClosed = false;
  1074     bool emitSessionClosed = false;
   942     if (isOpen && state == QNetworkSession::Connected && newState == QNetworkSession::Disconnected) {
  1075 
       
  1076     // If we abruptly go down and user hasn't closed the session, we've been aborted.
       
  1077     // Note that session may be in 'closing' state and not in 'connected' state, because
       
  1078     // depending on platform the platform may report KConfigDaemonStartingDeregistration
       
  1079     // event before KLinkLayerClosed
       
  1080     if ((isOpen && state == QNetworkSession::Connected && newState == QNetworkSession::Disconnected) ||
       
  1081         (isOpen && !iClosedByUser && newState == QNetworkSession::Disconnected)) {
   943         // Active & Connected state should change directly to Disconnected state
  1082         // Active & Connected state should change directly to Disconnected state
   944         // only when something forces connection to close (eg. when another
  1083         // only when something forces connection to close (eg. when another
   945         // application or session stops connection or when network drops
  1084         // application or session stops connection or when network drops
   946         // unexpectedly).
  1085         // unexpectedly).
   947         isOpen = false;
  1086         isOpen = false;
   951         emit q->error(iError);
  1090         emit q->error(iError);
   952         Cancel();
  1091         Cancel();
   953         if (ipConnectionNotifier) {
  1092         if (ipConnectionNotifier) {
   954             ipConnectionNotifier->StopNotifications();
  1093             ipConnectionNotifier->StopNotifications();
   955         }
  1094         }
   956         // Start monitoring changes in IAP states
  1095         // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
   957         TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
  1096         iHandleStateNotificationsFromManager = true;
   958         emitSessionClosed = true; // Emit SessionClosed after state change has been reported
  1097         emitSessionClosed = true; // Emit SessionClosed after state change has been reported
   959     }
  1098     }
   960 
  1099 
   961     bool retVal = false;
  1100     bool retVal = false;
   962     if (accessPointId == 0) {
  1101     if (accessPointId == 0) {
   963         state = newState;
  1102         state = newState;
       
  1103 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1104         qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed A to: " << state;
       
  1105 #endif
   964         emit q->stateChanged(state);
  1106         emit q->stateChanged(state);
   965         retVal = true;
  1107         retVal = true;
   966     } else {
  1108     } else {
   967         if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
  1109         if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
   968             if (publicConfig.d.data()->numericId == accessPointId) {
  1110             if (publicConfig.d.data()->numericId == accessPointId) {
   969                 state = newState;
  1111                 state = newState;
       
  1112 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1113                 qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed B to: " << state;
       
  1114 #endif
   970                 emit q->stateChanged(state);
  1115                 emit q->stateChanged(state);
   971                 retVal = true;
  1116                 retVal = true;
   972             }
  1117             }
   973         } else if (publicConfig.type() == QNetworkConfiguration::UserChoice && isOpen) {
  1118         } else if (publicConfig.type() == QNetworkConfiguration::UserChoice && isOpen) {
   974             if (activeConfig.d.data()->numericId == accessPointId) {
  1119             if (activeConfig.d.data()->numericId == accessPointId) {
   975                 state = newState;
  1120                 state = newState;
       
  1121 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1122                 qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed C to: " << state;
       
  1123 #endif
   976                 emit q->stateChanged(state);
  1124                 emit q->stateChanged(state);
   977                 retVal = true;
  1125                 retVal = true;
   978             }
  1126             }
   979         } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
  1127         } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
   980             QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
  1128             QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
   981             for (int i = 0; i < subConfigurations.count(); i++) {
  1129             for (int i = 0; i < subConfigurations.count(); i++) {
   982                 if (subConfigurations[i].d.data()->numericId == accessPointId) {
  1130                 if (subConfigurations[i].d.data()->numericId == accessPointId) {
   983                     if (newState == QNetworkSession::Connected) {
  1131                     if (newState != QNetworkSession::Disconnected) {
   984                         // Make sure that when AccessPoint is reported to be Connected
       
   985                         // also state of the related configuration changes to Active.
       
   986                         subConfigurations[i].d.data()->state = QNetworkConfiguration::Active;
       
   987     
       
   988                         state = newState;
  1132                         state = newState;
       
  1133 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1134                         qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed D  to: " << state;
       
  1135 #endif
   989                         emit q->stateChanged(state);
  1136                         emit q->stateChanged(state);
   990                         retVal = true;
  1137                         retVal = true;
   991                     } else {
  1138                     } else {
   992                         if (newState == QNetworkSession::Disconnected) {
       
   993                             // Make sure that when AccessPoint is reported to be disconnected
       
   994                             // also state of the related configuration changes from Active to Defined.
       
   995                             subConfigurations[i].d.data()->state = QNetworkConfiguration::Defined;
       
   996                         }
       
   997                         QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
  1139                         QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
   998                         if ((config.state() == QNetworkConfiguration::Defined) ||
  1140                         if ((config.state() == QNetworkConfiguration::Defined) ||
   999                             (config.state() == QNetworkConfiguration::Discovered)) {
  1141                             (config.state() == QNetworkConfiguration::Discovered)) {
  1000                             state = newState;
  1142                             state = newState;
       
  1143 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1144                             qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed E  to: " << state;
       
  1145 #endif
  1001                             emit q->stateChanged(state);
  1146                             emit q->stateChanged(state);
  1002                             retVal = true;
  1147                             retVal = true;
       
  1148                         } else if (config.state() == QNetworkConfiguration::Active) {
       
  1149                             // Connection to used IAP was closed, but there is another
       
  1150                             // IAP that's active in used SNAP
       
  1151                             // => Change state back to Connected
       
  1152                             state =  QNetworkSession::Connected;
       
  1153                             emit q->stateChanged(state);
       
  1154                             retVal = true;
       
  1155 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1156                             qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed F  to: " << state;
       
  1157 #endif
  1003                         }
  1158                         }
  1004                     }
  1159                     }
  1005                 }
  1160                 }
  1006             }
  1161             }
  1007         }
  1162         }
  1008     }
  1163     }
  1009     
  1164     
  1010     if (emitSessionClosed) {
  1165     if (emitSessionClosed) {
  1011         emit q->closed();
  1166         emit q->closed();
  1012     }
  1167     }
       
  1168     if (state == QNetworkSession::Disconnected) {
       
  1169         // The connection has gone down, and processing of status updates must be
       
  1170         // stopped. Depending on platform, there may come 'connecting/connected' states
       
  1171         // considerably later (almost a second). Connection id is an increasing
       
  1172         // number, so this does not affect next _real_ 'conneting/connected' states.
       
  1173         iDeprecatedConnectionId = publicConfig.d.data()->connectionId;
       
  1174     }
  1013 
  1175 
  1014     return retVal;
  1176     return retVal;
  1015 }
  1177 }
  1016 
  1178 
  1017 void QNetworkSessionPrivate::handleSymbianConnectionStatusChange(TInt aConnectionStatus,
  1179 void QNetworkSessionPrivate::handleSymbianConnectionStatusChange(TInt aConnectionStatus,
  1018                                                                  TInt aError,
  1180                                                                  TInt aError,
  1019                                                                  TUint accessPointId)
  1181                                                                  TUint accessPointId)
  1020 {
  1182 {
       
  1183 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1184     qDebug() << "QNS this : " << QString::number((uint)this) << " - " << QString::number(accessPointId) << " , status : " << QString::number(aConnectionStatus);
       
  1185 #endif
  1021     switch (aConnectionStatus)
  1186     switch (aConnectionStatus)
  1022         {
  1187         {
  1023         // Connection unitialised
  1188         // Connection unitialised
  1024         case KConnectionUninitialised:
  1189         case KConnectionUninitialised:
  1025             break;
  1190             break;
  1054         case KCsdScanningScript:
  1219         case KCsdScanningScript:
  1055         case KCsdGettingLoginInfo:
  1220         case KCsdGettingLoginInfo:
  1056         case KCsdGotLoginInfo:
  1221         case KCsdGotLoginInfo:
  1057             break;
  1222             break;
  1058 
  1223 
       
  1224         case KConfigDaemonStartingRegistration:
  1059         // Creating connection (e.g. GPRS activation)
  1225         // Creating connection (e.g. GPRS activation)
  1060         case KCsdStartingConnect:
  1226         case KCsdStartingConnect:
  1061         case KCsdFinishedConnect:
  1227         case KCsdFinishedConnect:
  1062             newState(QNetworkSession::Connecting,accessPointId);
  1228             newState(QNetworkSession::Connecting,accessPointId);
  1063             break;
  1229             break;
  1080 
  1246 
  1081         // Connection blocked or suspended
  1247         // Connection blocked or suspended
  1082         case KDataTransferTemporarilyBlocked:
  1248         case KDataTransferTemporarilyBlocked:
  1083             break;
  1249             break;
  1084 
  1250 
       
  1251         case KConfigDaemonStartingDeregistration:
  1085         // Hangup or GRPS deactivation
  1252         // Hangup or GRPS deactivation
  1086         case KConnectionStartingClose:
  1253         case KConnectionStartingClose:
  1087             newState(QNetworkSession::Closing,accessPointId);
  1254             newState(QNetworkSession::Closing,accessPointId);
  1088             break;
  1255             break;
  1089 
  1256 
  1090         // Connection closed
  1257         // Connection closed
  1091         case KConnectionClosed:
  1258         case KConnectionClosed:
  1092             break;
       
  1093 
       
  1094         case KLinkLayerClosed:
  1259         case KLinkLayerClosed:
  1095             newState(QNetworkSession::Disconnected,accessPointId);
  1260             newState(QNetworkSession::Disconnected,accessPointId);
  1096             break;
  1261             // Report manager about this to make sure this event
  1097 
  1262             // is received by all interseted parties (mediated by
       
  1263             // manager because it does always receive all events from
       
  1264             // connection monitor).
       
  1265 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
       
  1266             qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "reporting disconnection to manager.";
       
  1267 #endif
       
  1268             if (publicConfig.d.data()) {
       
  1269                 ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->configurationStateChangeReport(publicConfig.d.data()->numericId, QNetworkSession::Disconnected);
       
  1270             }
       
  1271             break;
  1098         // Unhandled state
  1272         // Unhandled state
  1099         default:
  1273         default:
  1100             break;
  1274             break;
  1101         }
  1275         }
  1102 }
  1276 }
  1103 
  1277 
  1104 void QNetworkSessionPrivate::EventL(const CConnMonEventBase& aEvent)
       
  1105 {
       
  1106     switch (aEvent.EventType())
       
  1107     {
       
  1108         case EConnMonConnectionStatusChange:
       
  1109             {
       
  1110             CConnMonConnectionStatusChange* realEvent;
       
  1111             realEvent = (CConnMonConnectionStatusChange*) &aEvent;
       
  1112 
       
  1113             TUint connectionId = realEvent->ConnectionId();
       
  1114             TInt connectionStatus = realEvent->ConnectionStatus();
       
  1115 
       
  1116             // Try to Find IAP Id using connection Id
       
  1117             TUint apId = 0;
       
  1118             if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
       
  1119                 QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
       
  1120                 for (int i = 0; i < subConfigurations.count(); i++ ) {
       
  1121                     if (subConfigurations[i].d.data()->connectionId == connectionId) {
       
  1122                         apId = subConfigurations[i].d.data()->numericId;
       
  1123                         break;
       
  1124                     }
       
  1125                 }
       
  1126             } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
       
  1127                 if (publicConfig.d.data()->connectionId == connectionId) {
       
  1128                     apId = publicConfig.d.data()->numericId;
       
  1129                 }
       
  1130             }
       
  1131 
       
  1132             if (apId > 0) {
       
  1133                 handleSymbianConnectionStatusChange(connectionStatus, KErrNone, apId);
       
  1134             }
       
  1135             }
       
  1136             break;
       
  1137 
       
  1138         case EConnMonCreateConnection:
       
  1139             {
       
  1140             CConnMonCreateConnection* realEvent;
       
  1141             realEvent = (CConnMonCreateConnection*) &aEvent;
       
  1142             TUint apId;
       
  1143             TUint connectionId = realEvent->ConnectionId();
       
  1144             TRequestStatus status;
       
  1145             iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status);
       
  1146             User::WaitForRequest(status);
       
  1147             if (status.Int() == KErrNone) {
       
  1148                 // Store connection id to related AccessPoint Configuration
       
  1149                 if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
       
  1150                     QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
       
  1151                     for (int i = 0; i < subConfigurations.count(); i++ ) {
       
  1152                         if (subConfigurations[i].d.data()->numericId == apId) {
       
  1153                             subConfigurations[i].d.data()->connectionId = connectionId;
       
  1154                             break;
       
  1155                         }
       
  1156                     }
       
  1157                 } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
       
  1158                     if (publicConfig.d.data()->numericId == apId) {
       
  1159                         publicConfig.d.data()->connectionId = connectionId;
       
  1160                     }
       
  1161                 }
       
  1162             }
       
  1163             }
       
  1164             break;
       
  1165 
       
  1166         case EConnMonDeleteConnection:
       
  1167             {
       
  1168             CConnMonDeleteConnection* realEvent;
       
  1169             realEvent = (CConnMonDeleteConnection*) &aEvent;
       
  1170             TUint connectionId = realEvent->ConnectionId();
       
  1171             // Remove connection id from related AccessPoint Configuration
       
  1172             if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
       
  1173                 QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
       
  1174                 for (int i = 0; i < subConfigurations.count(); i++ ) {
       
  1175                     if (subConfigurations[i].d.data()->connectionId == connectionId) {
       
  1176                         subConfigurations[i].d.data()->connectionId = 0;
       
  1177                         break;
       
  1178                     }
       
  1179                 }
       
  1180             } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
       
  1181                 if (publicConfig.d.data()->connectionId == connectionId) {
       
  1182                     publicConfig.d.data()->connectionId = 0;
       
  1183                 }
       
  1184             }
       
  1185             }
       
  1186             break;
       
  1187 
       
  1188         default:
       
  1189             // For unrecognized events
       
  1190             break;
       
  1191     }
       
  1192 }
       
  1193 
       
  1194 ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivate& owner, RConnection& connection)
  1278 ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivate& owner, RConnection& connection)
  1195     : CActive(CActive::EPriorityStandard), iOwner(owner), iConnection(connection)
  1279     : CActive(CActive::EPriorityUserInput), iOwner(owner), iConnection(connection)
  1196 {
  1280 {
  1197     CActiveScheduler::Add(this);
  1281     CActiveScheduler::Add(this);
  1198 }
  1282 }
  1199 
  1283 
  1200 ConnectionProgressNotifier::~ConnectionProgressNotifier()
  1284 ConnectionProgressNotifier::~ConnectionProgressNotifier()
  1221 }
  1305 }
  1222 
  1306 
  1223 void ConnectionProgressNotifier::RunL()
  1307 void ConnectionProgressNotifier::RunL()
  1224 {
  1308 {
  1225     if (iStatus == KErrNone) {
  1309     if (iStatus == KErrNone) {
  1226         iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError);
  1310         QT_TRYCATCH_LEAVING(iOwner.handleSymbianConnectionStatusChange(iProgress().iStage, iProgress().iError));
  1227     
  1311     
  1228         SetActive();
  1312         SetActive();
  1229         iConnection.ProgressNotification(iProgress, iStatus);
  1313         iConnection.ProgressNotification(iProgress, iStatus);
  1230     }
  1314     }
  1231 }
  1315 }