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; |
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; |
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; |
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) |
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; |
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() |