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), iDynamicUnSetdefaultif(0), ipConnectionNotifier(0), |
56 isOpen(false), iDynamicUnSetdefaultif(0), ipConnectionNotifier(0), |
57 iHandleStateNotificationsFromManager(false), iFirstSync(true), iStoppedByUser(false), |
57 iHandleStateNotificationsFromManager(false), iFirstSync(true), iStoppedByUser(false), |
58 iClosedByUser(false), iDeprecatedConnectionId(0), iError(QNetworkSession::UnknownSessionError), |
58 iClosedByUser(false), iError(QNetworkSession::UnknownSessionError), iALREnabled(0), |
59 iALREnabled(0), iConnectInBackground(false) |
59 iConnectInBackground(false), isOpening(false) |
60 { |
60 { |
61 CActiveScheduler::Add(this); |
61 CActiveScheduler::Add(this); |
62 |
62 |
63 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
63 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
64 iMobility = NULL; |
64 iMobility = NULL; |
70 iDynamicUnSetdefaultif = (TOpenCUnSetdefaultifFunction)iOpenCLibrary.Lookup(597); |
70 iDynamicUnSetdefaultif = (TOpenCUnSetdefaultifFunction)iOpenCLibrary.Lookup(597); |
71 } |
71 } |
72 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
72 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
73 qDebug() << "QNS this : " << QString::number((uint)this) << " - "; |
73 qDebug() << "QNS this : " << QString::number((uint)this) << " - "; |
74 if (iDynamicUnSetdefaultif) |
74 if (iDynamicUnSetdefaultif) |
75 qDebug() << "dynamic setdefaultif() resolution succeeded. "; |
75 qDebug() << "dynamic unsetdefaultif() is present in PIPS library. "; |
76 else |
76 else |
77 qDebug() << "dynamic setdefaultif() resolution failed. "; |
77 qDebug() << "dynamic unsetdefaultif() not present in PIPS library. "; |
78 #endif |
78 #endif |
79 |
79 |
80 TRAP_IGNORE(iConnectionMonitor.ConnectL()); |
80 TRAP_IGNORE(iConnectionMonitor.ConnectL()); |
81 } |
81 } |
82 |
82 |
83 QNetworkSessionPrivate::~QNetworkSessionPrivate() |
83 QNetworkSessionPrivate::~QNetworkSessionPrivate() |
84 { |
84 { |
85 isOpen = false; |
85 isOpen = false; |
|
86 isOpening = false; |
86 |
87 |
87 // Cancel Connection Progress Notifications first. |
88 // Cancel Connection Progress Notifications first. |
88 // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start() |
89 // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start() |
89 // => deleting ipConnectionNotifier results RConnection::CancelProgressNotification() |
90 // => deleting ipConnectionNotifier results RConnection::CancelProgressNotification() |
90 delete ipConnectionNotifier; |
91 delete ipConnectionNotifier; |
105 // Clears also possible unsetdefaultif() flags. |
106 // Clears also possible unsetdefaultif() flags. |
106 setdefaultif(0); |
107 setdefaultif(0); |
107 |
108 |
108 iConnectionMonitor.Close(); |
109 iConnectionMonitor.Close(); |
109 iOpenCLibrary.Close(); |
110 iOpenCLibrary.Close(); |
|
111 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
112 qDebug() << "QNS this : " << QString::number((uint)this) << " - destroyed (and setdefaultif(0))"; |
|
113 #endif |
110 } |
114 } |
111 |
115 |
112 void QNetworkSessionPrivate::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState) |
116 void QNetworkSessionPrivate::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState) |
113 { |
117 { |
114 if (iHandleStateNotificationsFromManager) { |
118 if (iHandleStateNotificationsFromManager) { |
115 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
119 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
116 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
120 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
117 << "configurationStateChanged from manager for IAP : " << QString::number(accessPointId) |
121 << "configurationStateChanged from manager for IAP : " << QString::number(accessPointId) |
118 << "configurationStateChanged connMon ID : " << QString::number(connMonId) |
122 << "connMon ID : " << QString::number(connMonId) << " : to a state: " << newState |
119 << " : to a state: " << newState |
123 << "whereas my current state is: " << state; |
120 << " whereas my current state is: " << state; |
124 #else |
121 #endif |
125 Q_UNUSED(connMonId); |
122 if (connMonId == iDeprecatedConnectionId) { |
126 #endif |
123 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
124 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
|
125 << "however status update from manager ignored because it related to already closed connection."; |
|
126 #endif |
|
127 return; |
|
128 } |
|
129 this->newState(newState, accessPointId); |
127 this->newState(newState, accessPointId); |
130 } |
128 } |
131 } |
129 } |
132 |
130 |
133 void QNetworkSessionPrivate::configurationRemoved(const QNetworkConfiguration& config) |
131 void QNetworkSessionPrivate::configurationRemoved(const QNetworkConfiguration& config) |
142 #endif |
140 #endif |
143 this->newState(QNetworkSession::Invalid, publicConfig.d.data()->numericId); |
141 this->newState(QNetworkSession::Invalid, publicConfig.d.data()->numericId); |
144 } |
142 } |
145 } |
143 } |
146 |
144 |
|
145 void QNetworkSessionPrivate::configurationAdded(const QNetworkConfiguration& config) |
|
146 { |
|
147 Q_UNUSED(config); |
|
148 // If session is based on service network, some other app may create new access points |
|
149 // to the SNAP --> synchronize session's state with that of interface's. |
|
150 if (!publicConfig.d.data() || publicConfig.type() != QNetworkConfiguration::ServiceNetwork) { |
|
151 return; |
|
152 } |
|
153 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
154 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
|
155 << "configurationAdded IAP: " << QString::number(config.d.data()->numericId); |
|
156 #endif |
|
157 syncStateWithInterface(); |
|
158 } |
|
159 |
|
160 // Function sets the state of the session to match the state |
|
161 // of the underlying interface (the configuration this session is based on) |
147 void QNetworkSessionPrivate::syncStateWithInterface() |
162 void QNetworkSessionPrivate::syncStateWithInterface() |
148 { |
163 { |
149 if (!publicConfig.d) { |
164 if (!publicConfig.d || !publicConfig.d.data()) { |
150 return; |
165 return; |
151 } |
166 } |
152 |
167 if (iFirstSync) { |
153 if (iFirstSync && publicConfig.d.data()) { |
|
154 QObject::connect(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager), SIGNAL(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)), |
168 QObject::connect(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager), SIGNAL(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)), |
155 this, SLOT(configurationStateChanged(TUint32, TUint32, QNetworkSession::State))); |
169 this, SLOT(configurationStateChanged(TUint32, TUint32, QNetworkSession::State))); |
156 // Listen to configuration removals, so that in case the configuration |
170 // Listen to configuration removals, so that in case the configuration |
157 // this session is based on is removed, session knows to enter Invalid -state. |
171 // this session is based on is removed, session knows to enter Invalid -state. |
158 QObject::connect(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager), |
172 QObject::connect(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager), |
159 SIGNAL(configurationRemoved(QNetworkConfiguration)), |
173 SIGNAL(configurationRemoved(QNetworkConfiguration)), |
160 this, SLOT(configurationRemoved(QNetworkConfiguration))); |
174 this, SLOT(configurationRemoved(QNetworkConfiguration))); |
|
175 // Connect to configuration additions, so that in case a configuration is added |
|
176 // in a SNAP this session is based on, the session knows to synch its state with its |
|
177 // interface. |
|
178 QObject::connect(((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager), |
|
179 SIGNAL(configurationAdded(QNetworkConfiguration)), |
|
180 this, SLOT(configurationAdded(QNetworkConfiguration))); |
161 } |
181 } |
162 // Start listening IAP state changes from QNetworkConfigurationManagerPrivate |
182 // Start listening IAP state changes from QNetworkConfigurationManagerPrivate |
163 iHandleStateNotificationsFromManager = true; |
183 iHandleStateNotificationsFromManager = true; |
164 |
184 |
165 // Check open connections to see if there is already |
185 // Check what is the state of the configuration this session is based on |
166 // an open connection to selected IAP or SNAP |
186 // and set the session in appropriate state. |
167 TUint count; |
187 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
168 TRequestStatus status; |
188 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
169 iConnectionMonitor.GetConnectionCount(count, status); |
189 << "syncStateWithInterface() state of publicConfig is: " << publicConfig.d.data()->state; |
170 User::WaitForRequest(status); |
190 #endif |
171 if (status.Int() != KErrNone) { |
191 switch (publicConfig.d.data()->state) { |
172 return; |
192 case QNetworkConfiguration::Active: |
173 } |
193 newState(QNetworkSession::Connected); |
174 |
194 break; |
175 TUint numSubConnections; |
195 case QNetworkConfiguration::Discovered: |
176 TUint connectionId; |
196 newState(QNetworkSession::Disconnected); |
177 for (TUint i = 1; i <= count; i++) { |
197 break; |
178 TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections); |
198 case QNetworkConfiguration::Defined: |
179 if (ret == KErrNone) { |
199 newState(QNetworkSession::NotAvailable); |
180 TUint apId; |
200 break; |
181 iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status); |
201 case QNetworkConfiguration::Undefined: |
182 User::WaitForRequest(status); |
202 default: |
183 if (status.Int() == KErrNone) { |
203 newState(QNetworkSession::Invalid); |
184 TInt connectionStatus; |
|
185 iConnectionMonitor.GetIntAttribute(connectionId, 0, KConnectionStatus, connectionStatus, status); |
|
186 User::WaitForRequest(status); |
|
187 if (connectionStatus == KLinkLayerOpen) { |
|
188 if (state != QNetworkSession::Closing) { |
|
189 if (newState(QNetworkSession::Connected, apId)) { |
|
190 return; |
|
191 } |
|
192 } |
|
193 } |
|
194 } |
|
195 } |
|
196 } |
|
197 |
|
198 if (state != QNetworkSession::Connected) { |
|
199 if ((publicConfig.d.data()->state & QNetworkConfiguration::Discovered) == |
|
200 QNetworkConfiguration::Discovered) { |
|
201 newState(QNetworkSession::Disconnected); |
|
202 } else { |
|
203 newState(QNetworkSession::NotAvailable); |
|
204 } |
|
205 } |
204 } |
206 } |
205 } |
207 |
206 |
208 QNetworkInterface QNetworkSessionPrivate::interface(TUint iapId) const |
207 QNetworkInterface QNetworkSessionPrivate::interface(TUint iapId) const |
209 { |
208 { |
383 #endif |
391 #endif |
384 iConnection.Start(pref, iStatus); |
392 iConnection.Start(pref, iStatus); |
385 if (!IsActive()) { |
393 if (!IsActive()) { |
386 SetActive(); |
394 SetActive(); |
387 } |
395 } |
388 newState(QNetworkSession::Connecting); |
396 // Avoid flip flop of states if the configuration is already |
|
397 // active. IsOpen/opened() will indicate when ready. |
|
398 if (state != QNetworkSession::Connected) { |
|
399 newState(QNetworkSession::Connecting); |
|
400 } |
389 } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { |
401 } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { |
390 #ifdef OCC_FUNCTIONALITY_AVAILABLE |
402 #if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE) |
391 // On Symbian^3 if service network is not reachable, it triggers a UI (aka EasyWLAN) where |
403 // 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 |
404 // user can create new IAPs. To detect this, we need to store the number of IAPs |
393 // there was before connection was started. |
405 // there was before connection was started. |
394 iKnownConfigsBeforeConnectionStart = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.keys(); |
406 iKnownConfigsBeforeConnectionStart = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.keys(); |
395 TConnPrefList snapPref; |
407 TConnPrefList snapPref; |
510 // KFinishedSelection event, and hence reports only after that event, but |
523 // KFinishedSelection event, and hence reports only after that event, but |
511 // that does not seem to be trusted on all Symbian versions --> safest |
524 // that does not seem to be trusted on all Symbian versions --> safest |
512 // to go down. |
525 // to go down. |
513 if (publicConfig.type() == QNetworkConfiguration::UserChoice || state == QNetworkSession::Connecting) { |
526 if (publicConfig.type() == QNetworkConfiguration::UserChoice || state == QNetworkSession::Connecting) { |
514 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
527 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
515 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
528 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
516 << "going Disconnected right away. Deprecating connection monitor ID: " << publicConfig.d.data()->connectionId; |
529 << "going disconnected right away, since either UserChoice or Connecting"; |
517 #endif |
530 #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; |
|
524 newState(QNetworkSession::Closing); |
531 newState(QNetworkSession::Closing); |
525 newState(QNetworkSession::Disconnected); |
532 newState(QNetworkSession::Disconnected); |
526 } |
533 } |
527 if (allowSignals) { |
534 if (allowSignals) { |
528 emit q->closed(); |
535 emit q->closed(); |
579 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
586 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
580 << "since session is open, using RConnection to stop() the interface"; |
587 << "since session is open, using RConnection to stop() the interface"; |
581 #endif |
588 #endif |
582 // Since we are open, use RConnection to stop the interface |
589 // Since we are open, use RConnection to stop the interface |
583 isOpen = false; |
590 isOpen = false; |
|
591 isOpening = false; |
584 iStoppedByUser = true; |
592 iStoppedByUser = true; |
585 newState(QNetworkSession::Closing); |
593 newState(QNetworkSession::Closing); |
586 if (ipConnectionNotifier) { |
594 if (ipConnectionNotifier) { |
587 ipConnectionNotifier->StopNotifications(); |
595 ipConnectionNotifier->StopNotifications(); |
588 // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate |
596 // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate |
589 iHandleStateNotificationsFromManager = true; |
597 iHandleStateNotificationsFromManager = true; |
590 } |
598 } |
591 iConnection.Stop(RConnection::EStopAuthoritative); |
599 iConnection.Stop(RConnection::EStopAuthoritative); |
592 isOpen = true; |
600 isOpen = true; |
|
601 isOpening = false; |
593 close(false); |
602 close(false); |
594 emit q->closed(); |
603 emit q->closed(); |
595 } |
604 } |
596 } |
605 } |
597 |
606 |
868 QNetworkConfiguration QNetworkSessionPrivate::activeConfiguration(TUint32 iapId) const |
878 QNetworkConfiguration QNetworkSessionPrivate::activeConfiguration(TUint32 iapId) const |
869 { |
879 { |
870 if (iapId == 0) { |
880 if (iapId == 0) { |
871 _LIT(KSetting, "IAP\\Id"); |
881 _LIT(KSetting, "IAP\\Id"); |
872 iConnection.GetIntSetting(KSetting, iapId); |
882 iConnection.GetIntSetting(KSetting, iapId); |
|
883 #if defined(OCC_FUNCTIONALITY_AVAILABLE) && defined(SNAP_FUNCTIONALITY_AVAILABLE) |
|
884 // Check if this is an Easy WLAN configuration. On Symbian^3 RConnection may report |
|
885 // the used configuration as 'EasyWLAN' IAP ID if someone has just opened the configuration |
|
886 // from WLAN Scan dialog, _and_ that connection is still up. We need to find the |
|
887 // real matching configuration. Function alters the Easy WLAN ID to real IAP ID (only if easy WLAN): |
|
888 ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->easyWlanTrueIapId(iapId); |
|
889 #endif |
873 } |
890 } |
874 |
891 |
875 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
892 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
876 if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { |
893 if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { |
877 // Try to search IAP from the used SNAP using IAP Id |
894 // Try to search IAP from the used SNAP using IAP Id |
999 case KErrNone: // Connection created successfully |
1016 case KErrNone: // Connection created successfully |
1000 { |
1017 { |
1001 TInt error = KErrNone; |
1018 TInt error = KErrNone; |
1002 QNetworkConfiguration newActiveConfig = activeConfiguration(); |
1019 QNetworkConfiguration newActiveConfig = activeConfiguration(); |
1003 if (!newActiveConfig.isValid()) { |
1020 if (!newActiveConfig.isValid()) { |
|
1021 // RConnection startup was successfull but no configuration |
|
1022 // was found. That indicates that user has chosen to create a |
|
1023 // new WLAN configuration (from scan results), but that new |
|
1024 // configuration does not have access to Internet (Internet |
|
1025 // Connectivity Test, ICT, failed). |
1004 error = KErrGeneral; |
1026 error = KErrGeneral; |
1005 } else { |
1027 } else { |
1006 // Use name of the IAP to open global 'Open C' RConnection |
1028 // Use name of the IAP to open global 'Open C' RConnection |
1007 ifreq ifr; |
1029 ifreq ifr; |
1008 memset(&ifr, 0, sizeof(struct ifreq)); |
1030 memset(&ifr, 0, sizeof(struct ifreq)); |
1009 QByteArray nameAsByteArray = newActiveConfig.name().toUtf8(); |
1031 QByteArray nameAsByteArray = newActiveConfig.name().toUtf8(); |
1010 strcpy(ifr.ifr_name, nameAsByteArray.constData()); |
1032 strcpy(ifr.ifr_name, nameAsByteArray.constData()); |
1011 error = setdefaultif(&ifr); |
1033 error = setdefaultif(&ifr); |
1012 } |
1034 } |
1013 |
|
1014 if (error != KErrNone) { |
1035 if (error != KErrNone) { |
1015 isOpen = false; |
1036 isOpen = false; |
|
1037 isOpening = false; |
1016 iError = QNetworkSession::UnknownSessionError; |
1038 iError = QNetworkSession::UnknownSessionError; |
1017 QT_TRYCATCH_LEAVING(emit q->error(iError)); |
1039 QT_TRYCATCH_LEAVING(emit q->error(iError)); |
1018 Cancel(); |
|
1019 if (ipConnectionNotifier) { |
1040 if (ipConnectionNotifier) { |
1020 ipConnectionNotifier->StopNotifications(); |
1041 ipConnectionNotifier->StopNotifications(); |
|
1042 } |
|
1043 if (!newActiveConfig.isValid()) { |
|
1044 // No valid configuration, bail out. |
|
1045 // Status updates from QNCM won't be received correctly |
|
1046 // because there is no configuration to associate them with so transit here. |
|
1047 iConnection.Close(); |
|
1048 newState(QNetworkSession::Closing); |
|
1049 newState(QNetworkSession::Disconnected); |
|
1050 } else { |
|
1051 Cancel(); |
1021 } |
1052 } |
1022 QT_TRYCATCH_LEAVING(syncStateWithInterface()); |
1053 QT_TRYCATCH_LEAVING(syncStateWithInterface()); |
1023 return; |
1054 return; |
1024 } |
1055 } |
1025 |
1056 |