51 |
51 |
52 QTM_BEGIN_NAMESPACE |
52 QTM_BEGIN_NAMESPACE |
53 |
53 |
54 QNetworkSessionPrivate::QNetworkSessionPrivate() |
54 QNetworkSessionPrivate::QNetworkSessionPrivate() |
55 : CActive(CActive::EPriorityUserInput), state(QNetworkSession::Invalid), |
55 : CActive(CActive::EPriorityUserInput), state(QNetworkSession::Invalid), |
56 isOpen(false), ipConnectionNotifier(0), iHandleStateNotificationsFromManager(false), |
56 isOpen(false), iDynamicUnSetdefaultif(0), ipConnectionNotifier(0), |
57 iFirstSync(true), iStoppedByUser(false), iClosedByUser(false), iDeprecatedConnectionId(0), |
57 iHandleStateNotificationsFromManager(false), iFirstSync(true), iStoppedByUser(false), |
58 iError(QNetworkSession::UnknownSessionError), iALREnabled(0), iConnectInBackground(false) |
58 iClosedByUser(false), iDeprecatedConnectionId(0), iError(QNetworkSession::UnknownSessionError), |
|
59 iALREnabled(0), iConnectInBackground(false) |
59 { |
60 { |
60 CActiveScheduler::Add(this); |
61 CActiveScheduler::Add(this); |
61 |
62 |
62 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
63 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
63 iMobility = NULL; |
64 iMobility = NULL; |
|
65 #endif |
|
66 // Try to load "Open C" dll dynamically and |
|
67 // try to attach to unsetdefaultif function dynamically. |
|
68 // This is to avoid build breaks with old OpenC versions. |
|
69 if (iOpenCLibrary.Load(_L("libc")) == KErrNone) { |
|
70 iDynamicUnSetdefaultif = (TOpenCUnSetdefaultifFunction)iOpenCLibrary.Lookup(597); |
|
71 } |
|
72 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
73 qDebug() << "QNS this : " << QString::number((uint)this) << " - "; |
|
74 if (iDynamicUnSetdefaultif) |
|
75 qDebug() << "dynamic setdefaultif() resolution succeeded. "; |
|
76 else |
|
77 qDebug() << "dynamic setdefaultif() resolution failed. "; |
64 #endif |
78 #endif |
65 |
79 |
66 TRAP_IGNORE(iConnectionMonitor.ConnectL()); |
80 TRAP_IGNORE(iConnectionMonitor.ConnectL()); |
67 } |
81 } |
68 |
82 |
74 // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start() |
88 // Note: ConnectionNotifier must be destroyed before Canceling RConnection::Start() |
75 // => deleting ipConnectionNotifier results RConnection::CancelProgressNotification() |
89 // => deleting ipConnectionNotifier results RConnection::CancelProgressNotification() |
76 delete ipConnectionNotifier; |
90 delete ipConnectionNotifier; |
77 ipConnectionNotifier = NULL; |
91 ipConnectionNotifier = NULL; |
78 |
92 |
79 // Cancel possible RConnection::Start() |
|
80 Cancel(); |
|
81 |
|
82 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
93 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
83 if (iMobility) { |
94 if (iMobility) { |
84 delete iMobility; |
95 delete iMobility; |
85 iMobility = NULL; |
96 iMobility = NULL; |
86 } |
97 } |
87 #endif |
98 #endif |
88 |
99 |
89 iConnection.Close(); |
100 // Cancel possible RConnection::Start() |
|
101 Cancel(); |
90 iSocketServ.Close(); |
102 iSocketServ.Close(); |
91 |
103 |
92 // Close global 'Open C' RConnection |
104 // Close global 'Open C' RConnection |
|
105 // Clears also possible unsetdefaultif() flags. |
93 setdefaultif(0); |
106 setdefaultif(0); |
94 |
107 |
95 iConnectionMonitor.Close(); |
108 iConnectionMonitor.Close(); |
|
109 iOpenCLibrary.Close(); |
96 } |
110 } |
97 |
111 |
98 void QNetworkSessionPrivate::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState) |
112 void QNetworkSessionPrivate::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState) |
99 { |
113 { |
100 if (iHandleStateNotificationsFromManager) { |
114 if (iHandleStateNotificationsFromManager) { |
350 if (ipConnectionNotifier) { |
364 if (ipConnectionNotifier) { |
351 ipConnectionNotifier->StartNotifications(); |
365 ipConnectionNotifier->StartNotifications(); |
352 } |
366 } |
353 |
367 |
354 if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { |
368 if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) { |
355 // Search through existing connections. |
|
356 // If there is already connection which matches to given IAP |
|
357 // try to attach to existing connection. |
|
358 TBool connected(EFalse); |
|
359 TConnectionInfoBuf connInfo; |
|
360 TUint count; |
|
361 if (iConnection.EnumerateConnections(count) == KErrNone) { |
|
362 for (TUint i=1; i<=count; i++) { |
|
363 // Note: GetConnectionInfo expects 1-based index. |
|
364 if (iConnection.GetConnectionInfo(i, connInfo) == KErrNone) { |
|
365 if (connInfo().iIapId == publicConfig.d.data()->numericId) { |
|
366 if (iConnection.Attach(connInfo, RConnection::EAttachTypeNormal) == KErrNone) { |
|
367 activeConfig = publicConfig; |
|
368 activeInterface = interface(activeConfig.d.data()->numericId); |
|
369 connected = ETrue; |
|
370 startTime = QDateTime::currentDateTime(); |
|
371 // Use name of the IAP to open global 'Open C' RConnection |
|
372 QByteArray nameAsByteArray = publicConfig.name().toUtf8(); |
|
373 ifreq ifr; |
|
374 memset(&ifr, 0, sizeof(struct ifreq)); |
|
375 strcpy(ifr.ifr_name, nameAsByteArray.constData()); |
|
376 error = setdefaultif(&ifr); |
|
377 isOpen = true; |
|
378 // Make sure that state will be Connected |
|
379 newState(QNetworkSession::Connected); |
|
380 emit quitPendingWaitsForOpened(); |
|
381 break; |
|
382 } |
|
383 } |
|
384 } |
|
385 } |
|
386 } |
|
387 if (!connected) { |
|
388 #ifdef OCC_FUNCTIONALITY_AVAILABLE |
369 #ifdef OCC_FUNCTIONALITY_AVAILABLE |
389 // With One Click Connectivity (Symbian^3 onwards) it is possible |
370 // With One Click Connectivity (Symbian^3 onwards) it is possible |
390 // to connect silently, without any popups. |
371 // to connect silently, without any popups. |
391 TConnPrefList pref; |
372 TConnPrefList pref; |
392 TExtendedConnPref prefs; |
373 TExtendedConnPref prefs; |
403 iConnection.Start(pref, iStatus); |
384 iConnection.Start(pref, iStatus); |
404 if (!IsActive()) { |
385 if (!IsActive()) { |
405 SetActive(); |
386 SetActive(); |
406 } |
387 } |
407 newState(QNetworkSession::Connecting); |
388 newState(QNetworkSession::Connecting); |
408 } |
|
409 } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { |
389 } else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { |
410 #ifdef OCC_FUNCTIONALITY_AVAILABLE |
390 #ifdef OCC_FUNCTIONALITY_AVAILABLE |
|
391 // On Symbian^3 if service network is not reachable, it triggers a UI (aka EasyWLAN) where |
|
392 // user can create new IAPs. To detect this, we need to store the number of IAPs |
|
393 // there was before connection was started. |
|
394 iKnownConfigsBeforeConnectionStart = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.keys(); |
411 TConnPrefList snapPref; |
395 TConnPrefList snapPref; |
412 TExtendedConnPref prefs; |
396 TExtendedConnPref prefs; |
413 prefs.SetSnapId(publicConfig.d.data()->numericId); |
397 prefs.SetSnapId(publicConfig.d.data()->numericId); |
414 if (iConnectInBackground) { |
398 if (iConnectInBackground) { |
415 prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent ); |
399 prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent ); |
475 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
459 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
476 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
460 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
477 << "close() called, session state is: " << state << " and isOpen is : " |
461 << "close() called, session state is: " << state << " and isOpen is : " |
478 << isOpen; |
462 << isOpen; |
479 #endif |
463 #endif |
480 if (!isOpen) { |
464 |
|
465 if (!isOpen && state != QNetworkSession::Connecting) { |
481 return; |
466 return; |
482 } |
467 } |
483 // Mark this session as closed-by-user so that we are able to report |
468 // Mark this session as closed-by-user so that we are able to report |
484 // distinguish between stop() and close() state transitions |
469 // distinguish between stop() and close() state transitions |
485 // when reporting. |
470 // when reporting. |
486 iClosedByUser = true; |
471 iClosedByUser = true; |
487 |
|
488 isOpen = false; |
472 isOpen = false; |
|
473 |
|
474 #ifndef OCC_FUNCTIONALITY_AVAILABLE |
|
475 // On Symbian^3 we need to keep track of active configuration longer |
|
476 // in case of empty-SNAP-triggered EasyWLAN. |
489 activeConfig = QNetworkConfiguration(); |
477 activeConfig = QNetworkConfiguration(); |
|
478 #endif |
490 serviceConfig = QNetworkConfiguration(); |
479 serviceConfig = QNetworkConfiguration(); |
491 |
480 |
492 Cancel(); |
|
493 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
481 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
494 if (iMobility) { |
482 if (iMobility) { |
495 delete iMobility; |
483 delete iMobility; |
496 iMobility = NULL; |
484 iMobility = NULL; |
497 } |
485 } |
501 ipConnectionNotifier->StopNotifications(); |
489 ipConnectionNotifier->StopNotifications(); |
502 // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate |
490 // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate |
503 iHandleStateNotificationsFromManager = true; |
491 iHandleStateNotificationsFromManager = true; |
504 } |
492 } |
505 |
493 |
506 iConnection.Close(); |
494 Cancel(); // closes iConnection |
507 iSocketServ.Close(); |
495 iSocketServ.Close(); |
508 |
496 |
509 // Close global 'Open C' RConnection |
497 // Close global 'Open C' RConnection. If OpenC supports, |
510 setdefaultif(0); |
498 // close the defaultif for good to avoid difficult timing |
511 |
499 // and bouncing issues of network going immediately back up |
512 if (publicConfig.type() == QNetworkConfiguration::UserChoice) { |
500 // because of e.g. select() thread etc. |
|
501 if (iDynamicUnSetdefaultif) { |
|
502 iDynamicUnSetdefaultif(); |
|
503 } else { |
|
504 setdefaultif(0); |
|
505 } |
|
506 |
|
507 // If UserChoice, go down immediately. If some other configuration, |
|
508 // go down immediately if there is no reports expected from the platform; |
|
509 // in practice Connection Monitor is aware of connections only after |
|
510 // KFinishedSelection event, and hence reports only after that event, but |
|
511 // that does not seem to be trusted on all Symbian versions --> safest |
|
512 // to go down. |
|
513 if (publicConfig.type() == QNetworkConfiguration::UserChoice || state == QNetworkSession::Connecting) { |
|
514 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
515 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
|
516 << "going Disconnected right away. Deprecating connection monitor ID: " << publicConfig.d.data()->connectionId; |
|
517 #endif |
|
518 |
|
519 // The connection has gone down, and processing of status updates must be |
|
520 // stopped. Depending on platform, there may come 'connecting/connected' states |
|
521 // considerably later (almost a second). Connection id is an increasing |
|
522 // number, so this does not affect next _real_ 'conneting/connected' states. |
|
523 iDeprecatedConnectionId = publicConfig.d.data()->connectionId; |
513 newState(QNetworkSession::Closing); |
524 newState(QNetworkSession::Closing); |
514 newState(QNetworkSession::Disconnected); |
525 newState(QNetworkSession::Disconnected); |
515 } |
526 } |
516 |
|
517 if (allowSignals) { |
527 if (allowSignals) { |
518 emit q->closed(); |
528 emit q->closed(); |
519 } |
529 } |
520 } |
530 } |
521 |
531 |
854 { |
869 { |
855 if (iapId == 0) { |
870 if (iapId == 0) { |
856 _LIT(KSetting, "IAP\\Id"); |
871 _LIT(KSetting, "IAP\\Id"); |
857 iConnection.GetIntSetting(KSetting, iapId); |
872 iConnection.GetIntSetting(KSetting, iapId); |
858 } |
873 } |
859 |
874 |
860 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
875 #ifdef SNAP_FUNCTIONALITY_AVAILABLE |
861 if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { |
876 if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) { |
862 // Try to search IAP from the used SNAP using IAP Id |
877 // Try to search IAP from the used SNAP using IAP Id |
863 QList<QNetworkConfiguration> children = publicConfig.children(); |
878 QList<QNetworkConfiguration> children = publicConfig.children(); |
864 for (int i=0; i < children.count(); i++) { |
879 for (int i=0; i < children.count(); i++) { |
875 // 3. "Dial-up number" for "Data call Bearer" or "High Speed (GSM)" Bearer |
890 // 3. "Dial-up number" for "Data call Bearer" or "High Speed (GSM)" Bearer |
876 // <=> Note: It's possible that in this case reported IAP is |
891 // <=> Note: It's possible that in this case reported IAP is |
877 // clone of the one of the IAPs of the used SNAP |
892 // clone of the one of the IAPs of the used SNAP |
878 // => If mappingName matches, clone has been found |
893 // => If mappingName matches, clone has been found |
879 QNetworkConfiguration pt; |
894 QNetworkConfiguration pt; |
880 pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(QString::number(qHash(iapId))); |
895 pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId))); |
881 if (pt.d) { |
896 if (pt.d) { |
882 for (int i=0; i < children.count(); i++) { |
897 for (int i=0; i < children.count(); i++) { |
883 if (children[i].d.data()->mappingName == pt.d.data()->mappingName) { |
898 if (children[i].d.data()->mappingName == pt.d.data()->mappingName) { |
884 return children[i]; |
899 return children[i]; |
885 } |
900 } |
886 } |
901 } |
887 } else { |
902 } else { |
|
903 #ifdef OCC_FUNCTIONALITY_AVAILABLE |
|
904 // On Symbian^3 (only, not earlier or Symbian^4) if the SNAP was not reachable, it triggers |
|
905 // user choice type of activity (EasyWLAN). As a result, a new IAP may be created, and |
|
906 // hence if was not found yet. Therefore update configurations and see if there is something new. |
|
907 // 1. Update knowledge from the databases. |
|
908 ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->updateConfigurations(); |
|
909 // 2. Check if new configuration was created during connection creation |
|
910 QList<QString> knownConfigs = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.keys(); |
|
911 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
912 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
|
913 << "opened configuration was not known beforehand, looking for new."; |
|
914 #endif |
|
915 if (knownConfigs.count() > iKnownConfigsBeforeConnectionStart.count()) { |
|
916 // Configuration count increased => new configuration was created |
|
917 // => Search new, created configuration |
|
918 QString newIapId; |
|
919 for (int i=0; i < iKnownConfigsBeforeConnectionStart.count(); i++) { |
|
920 if (knownConfigs[i] != iKnownConfigsBeforeConnectionStart[i]) { |
|
921 newIapId = knownConfigs[i]; |
|
922 break; |
|
923 } |
|
924 } |
|
925 if (newIapId.isEmpty()) { |
|
926 newIapId = knownConfigs[knownConfigs.count()-1]; |
|
927 } |
|
928 pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(newIapId); |
|
929 if (pt.d) { |
|
930 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
931 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
|
932 << "new configuration was found, name, IAP id: " << pt.name() << pt.identifier(); |
|
933 #endif |
|
934 return pt; |
|
935 } |
|
936 } |
|
937 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
938 qDebug() << "QNS this : " << QString::number((uint)this) << " - " |
|
939 << "configuration was not found, returning invalid."; |
|
940 #endif |
|
941 #endif // OCC_FUNCTIONALITY_AVAILABLE |
888 // Given IAP Id was not found from known IAPs array |
942 // Given IAP Id was not found from known IAPs array |
889 return QNetworkConfiguration(); |
943 return QNetworkConfiguration(); |
890 } |
944 } |
891 |
|
892 // Matching IAP was not found from used SNAP |
945 // Matching IAP was not found from used SNAP |
893 // => IAP from another SNAP is returned |
946 // => IAP from another SNAP is returned |
894 // (Note: Returned IAP matches to given IAP Id) |
947 // (Note: Returned IAP matches to given IAP Id) |
895 return pt; |
948 return pt; |
896 } |
949 } |
897 #endif |
950 #endif |
898 |
|
899 if (publicConfig.type() == QNetworkConfiguration::UserChoice) { |
951 if (publicConfig.type() == QNetworkConfiguration::UserChoice) { |
900 if (publicConfig.d.data()->manager) { |
952 if (publicConfig.d.data()->manager) { |
901 QNetworkConfiguration pt; |
953 QNetworkConfiguration pt; |
902 // Try to found User Selected IAP from known IAPs (accessPointConfigurations) |
954 // Try to found User Selected IAP from known IAPs (accessPointConfigurations) |
903 pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(QString::number(qHash(iapId))); |
955 pt.d = ((QNetworkConfigurationManagerPrivate*)publicConfig.d.data()->manager)->accessPointConfigurations.value(QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId))); |
904 if (pt.d) { |
956 if (pt.d) { |
905 return pt; |
957 return pt; |
906 } else { |
958 } else { |
907 // Check if new (WLAN) IAP was created in IAP/SNAP dialog |
959 // Check if new (WLAN) IAP was created in IAP/SNAP dialog |
908 // 1. Sync internal configurations array to commsdb first |
960 // 1. Sync internal configurations array to commsdb first |
1169 // The connection has gone down, and processing of status updates must be |
1241 // The connection has gone down, and processing of status updates must be |
1170 // stopped. Depending on platform, there may come 'connecting/connected' states |
1242 // stopped. Depending on platform, there may come 'connecting/connected' states |
1171 // considerably later (almost a second). Connection id is an increasing |
1243 // considerably later (almost a second). Connection id is an increasing |
1172 // number, so this does not affect next _real_ 'conneting/connected' states. |
1244 // number, so this does not affect next _real_ 'conneting/connected' states. |
1173 iDeprecatedConnectionId = publicConfig.d.data()->connectionId; |
1245 iDeprecatedConnectionId = publicConfig.d.data()->connectionId; |
1174 } |
1246 #ifdef OCC_FUNCTIONALITY_AVAILABLE |
1175 |
1247 // Just in case clear activeConfiguration. |
|
1248 activeConfig = QNetworkConfiguration(); |
|
1249 #endif |
|
1250 } |
1176 return retVal; |
1251 return retVal; |
1177 } |
1252 } |
1178 |
1253 |
1179 void QNetworkSessionPrivate::handleSymbianConnectionStatusChange(TInt aConnectionStatus, |
1254 void QNetworkSessionPrivate::handleSymbianConnectionStatusChange(TInt aConnectionStatus, |
1180 TInt aError, |
1255 TInt aError, |