605 TRequestStatus status; |
607 TRequestStatus status; |
606 TUint connectionCount; |
608 TUint connectionCount; |
607 iConnectionMonitor.GetConnectionCount(connectionCount, status); |
609 iConnectionMonitor.GetConnectionCount(connectionCount, status); |
608 User::WaitForRequest(status); |
610 User::WaitForRequest(status); |
609 |
611 |
610 // Go through all connections and set state of related IAPs to Active |
612 // Go through all connections and set state of related IAPs to Active. |
|
613 // Status needs to be checked carefully, because ConnMon lists also e.g. |
|
614 // WLAN connections that are being currently tried --> we don't want to |
|
615 // state these as active. |
611 TUint connectionId; |
616 TUint connectionId; |
612 TUint subConnectionCount; |
617 TUint subConnectionCount; |
613 TUint apId; |
618 TUint apId; |
|
619 TInt connectionStatus; |
614 if (status.Int() == KErrNone) { |
620 if (status.Int() == KErrNone) { |
615 for (TUint i = 1; i <= connectionCount; i++) { |
621 for (TUint i = 1; i <= connectionCount; i++) { |
616 iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount); |
622 iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount); |
617 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
623 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
618 User::WaitForRequest(status); |
624 User::WaitForRequest(status); |
619 QString ident = QString::number(qHash(apId)); |
625 QString ident = QString::number(qHash(apId)); |
620 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
626 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
621 if (priv.data()) { |
627 if (priv.data()) { |
622 online = true; |
628 iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status); |
623 inactiveConfigs.removeOne(ident); |
629 User::WaitForRequest(status); |
624 priv.data()->connectionId = connectionId; |
630 if (connectionStatus == KLinkLayerOpen) { |
625 // Configuration is Active |
631 online = true; |
626 changeConfigurationStateTo(priv, QNetworkConfiguration::Active); |
632 inactiveConfigs.removeOne(ident); |
|
633 priv.data()->connectionId = connectionId; |
|
634 // Configuration is Active |
|
635 changeConfigurationStateTo(priv, QNetworkConfiguration::Active); |
|
636 } |
627 } |
637 } |
628 } |
638 } |
629 } |
639 } |
630 |
640 |
631 // Make sure that state of rest of the IAPs won't be Active |
641 // Make sure that state of rest of the IAPs won't be Active |
806 } |
816 } |
807 |
817 |
808 void QNetworkConfigurationManagerPrivate::RunL() |
818 void QNetworkConfigurationManagerPrivate::RunL() |
809 { |
819 { |
810 if (iIgnoringUpdates) { |
820 if (iIgnoringUpdates) { |
811 #ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG |
821 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
812 qDebug("CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently)."); |
822 qDebug("QNCM CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently)."); |
813 #endif |
823 #endif |
814 return; |
824 return; |
815 } |
825 } |
816 if (iStatus != KErrCancel) { |
826 if (iStatus != KErrCancel) { |
817 RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); |
827 RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); |
|
828 |
818 switch (event) { |
829 switch (event) { |
819 case RDbNotifier::EUnlock: /** All read locks have been removed. */ |
830 case RDbNotifier::EUnlock: /** All read locks have been removed. */ |
820 case RDbNotifier::ECommit: /** A transaction has been committed. */ |
831 case RDbNotifier::ECommit: /** A transaction has been committed. */ |
821 case RDbNotifier::ERollback: /** A transaction has been rolled back */ |
832 case RDbNotifier::ERollback: /** A transaction has been rolled back */ |
822 case RDbNotifier::ERecover: /** The database has been recovered */ |
833 case RDbNotifier::ERecover: /** The database has been recovered */ |
823 #ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG |
834 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
824 qDebug("CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int()); |
835 qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int()); |
825 #endif |
836 #endif |
826 iIgnoringUpdates = true; |
837 iIgnoringUpdates = true; |
827 // Other events than ECommit get lower priority. In practice with those events, |
838 // Other events than ECommit get lower priority. In practice with those events, |
828 // we delay_before_updating methods, whereas |
839 // we delay_before_updating methods, whereas |
829 // with ECommit we _update_before_delaying the reaction to next event. |
840 // with ECommit we _update_before_delaying the reaction to next event. |
865 void QNetworkConfigurationManagerPrivate::DoCancel() |
876 void QNetworkConfigurationManagerPrivate::DoCancel() |
866 { |
877 { |
867 ipCommsDB->CancelRequestNotification(); |
878 ipCommsDB->CancelRequestNotification(); |
868 } |
879 } |
869 |
880 |
870 |
|
871 void QNetworkConfigurationManagerPrivate::EventL(const CConnMonEventBase& aEvent) |
881 void QNetworkConfigurationManagerPrivate::EventL(const CConnMonEventBase& aEvent) |
872 { |
882 { |
873 switch (aEvent.EventType()) { |
883 switch (aEvent.EventType()) { |
874 case EConnMonCreateConnection: |
884 case EConnMonConnectionStatusChange: |
875 { |
885 { |
876 CConnMonCreateConnection* realEvent; |
886 CConnMonConnectionStatusChange* realEvent; |
877 realEvent = (CConnMonCreateConnection*) &aEvent; |
887 realEvent = (CConnMonConnectionStatusChange*) &aEvent; |
878 TUint subConnectionCount = 0; |
888 TInt connectionStatus = realEvent->ConnectionStatus(); |
879 TUint apId; |
889 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
880 TUint connectionId = realEvent->ConnectionId(); |
890 qDebug() << "QNCM Connection status : " << QString::number(connectionStatus) << " , connection monitor Id : " << realEvent->ConnectionId(); |
881 TRequestStatus status; |
891 #endif |
882 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
892 if (connectionStatus == KConfigDaemonStartingRegistration) { |
883 User::WaitForRequest(status); |
893 TUint connectionId = realEvent->ConnectionId(); |
884 QString ident = QString::number(qHash(apId)); |
894 TUint subConnectionCount = 0; |
885 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
895 TUint apId; |
886 if (priv.data()) { |
896 TRequestStatus status; |
887 priv.data()->connectionId = connectionId; |
897 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
888 // Configuration is Active |
898 User::WaitForRequest(status); |
889 if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) { |
899 QString ident = QString::number(qHash(apId)); |
890 updateStatesToSnaps(); |
900 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
891 } |
901 if (priv.data()) { |
892 if (!iOnline) { |
902 priv.data()->connectionId = connectionId; |
893 iOnline = true; |
903 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connecting); |
|
904 } |
|
905 } else if (connectionStatus == KLinkLayerOpen) { |
|
906 // Connection has been successfully opened |
|
907 TUint connectionId = realEvent->ConnectionId(); |
|
908 TUint subConnectionCount = 0; |
|
909 TUint apId; |
|
910 TRequestStatus status; |
|
911 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
912 User::WaitForRequest(status); |
|
913 QString ident = QString::number(qHash(apId)); |
|
914 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
915 if (priv.data()) { |
|
916 priv.data()->connectionId = connectionId; |
|
917 // Configuration is Active |
|
918 if (changeConfigurationStateTo(priv, QNetworkConfiguration::Active)) { |
|
919 updateStatesToSnaps(); |
|
920 } |
|
921 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Connected); |
|
922 if (!iOnline) { |
|
923 iOnline = true; |
|
924 emit this->onlineStateChanged(iOnline); |
|
925 } |
|
926 } |
|
927 } else if (connectionStatus == KConfigDaemonStartingDeregistration) { |
|
928 TUint connectionId = realEvent->ConnectionId(); |
|
929 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId); |
|
930 if (priv.data()) { |
|
931 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Closing); |
|
932 } |
|
933 } else if (connectionStatus == KLinkLayerClosed || |
|
934 connectionStatus == KConnectionClosed) { |
|
935 // Connection has been closed. Which of the above events is reported, depends on the Symbian |
|
936 // platform. |
|
937 TUint connectionId = realEvent->ConnectionId(); |
|
938 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId); |
|
939 if (priv.data()) { |
|
940 // Configuration is either Defined or Discovered |
|
941 if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) { |
|
942 updateStatesToSnaps(); |
|
943 } |
|
944 emit this->configurationStateChanged(priv.data()->numericId, connectionId, QNetworkSession::Disconnected); |
|
945 } |
|
946 |
|
947 bool online = false; |
|
948 foreach (const QString &iface, accessPointConfigurations.keys()) { |
|
949 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
950 if (priv.data()->state == QNetworkConfiguration::Active) { |
|
951 online = true; |
|
952 break; |
|
953 } |
|
954 } |
|
955 if (iOnline != online) { |
|
956 iOnline = online; |
894 emit this->onlineStateChanged(iOnline); |
957 emit this->onlineStateChanged(iOnline); |
895 } |
958 } |
896 } |
959 } |
897 } |
960 } |
898 break; |
961 break; |
899 |
|
900 case EConnMonDeleteConnection: |
|
901 { |
|
902 CConnMonDeleteConnection* realEvent; |
|
903 realEvent = (CConnMonDeleteConnection*) &aEvent; |
|
904 TUint connectionId = realEvent->ConnectionId(); |
|
905 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = dataByConnectionId(connectionId); |
|
906 if (priv.data()) { |
|
907 priv.data()->connectionId = 0; |
|
908 // Configuration is either Defined or Discovered |
|
909 if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) { |
|
910 updateStatesToSnaps(); |
|
911 } |
|
912 } |
|
913 |
|
914 bool online = false; |
|
915 foreach (const QString &iface, accessPointConfigurations.keys()) { |
|
916 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iface); |
|
917 if (priv.data()->state == QNetworkConfiguration::Active) { |
|
918 online = true; |
|
919 break; |
|
920 } |
|
921 } |
|
922 if (iOnline != online) { |
|
923 iOnline = online; |
|
924 emit this->onlineStateChanged(iOnline); |
|
925 } |
|
926 } |
|
927 break; |
|
928 |
962 |
929 case EConnMonIapAvailabilityChange: |
963 case EConnMonIapAvailabilityChange: |
930 { |
964 { |
931 CConnMonIapAvailabilityChange* realEvent; |
965 CConnMonIapAvailabilityChange* realEvent; |
932 realEvent = (CConnMonIapAvailabilityChange*) &aEvent; |
966 realEvent = (CConnMonIapAvailabilityChange*) &aEvent; |
949 } |
983 } |
950 } |
984 } |
951 } |
985 } |
952 break; |
986 break; |
953 |
987 |
|
988 case EConnMonCreateConnection: |
|
989 { |
|
990 // This event is caught to keep connection monitor IDs up-to-date. |
|
991 CConnMonCreateConnection* realEvent; |
|
992 realEvent = (CConnMonCreateConnection*) &aEvent; |
|
993 TUint subConnectionCount = 0; |
|
994 TUint apId; |
|
995 TUint connectionId = realEvent->ConnectionId(); |
|
996 TRequestStatus status; |
|
997 iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); |
|
998 User::WaitForRequest(status); |
|
999 QString ident = QString::number(qHash(apId)); |
|
1000 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
1001 if (priv.data()) { |
|
1002 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
1003 qDebug() << "QNCM updating connection monitor ID : from, to, whose: " << priv.data()->connectionId << connectionId << priv->name; |
|
1004 #endif |
|
1005 priv.data()->connectionId = connectionId; |
|
1006 } |
|
1007 } |
|
1008 break; |
954 default: |
1009 default: |
955 // For unrecognized events |
1010 // For unrecognized events |
956 break; |
1011 break; |
957 } |
1012 } |
958 } |
1013 } |
959 |
1014 |
960 // Waits for 1..4 seconds. |
1015 // Sessions may use this function to report configuration state changes, |
|
1016 // because on some Symbian platforms (especially Symbian^3) all state changes are not |
|
1017 // reported by the RConnectionMonitor, in particular in relation to stop() call, |
|
1018 // whereas they _are_ reported on RConnection progress notifier used by sessions --> centralize |
|
1019 // this data here so that other sessions may benefit from it too (not all sessions necessarily have |
|
1020 // RConnection progress notifiers available but they relay on having e.g. disconnected information from |
|
1021 // manager). Currently only 'Disconnected' state is of interest because it has proven to be troublesome. |
|
1022 void QNetworkConfigurationManagerPrivate::configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState) |
|
1023 { |
|
1024 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
|
1025 qDebug() << "QNCM A session reported state change for IAP ID: " << accessPointId << " whose new state is: " << newState; |
|
1026 #endif |
|
1027 switch (newState) { |
|
1028 case QNetworkSession::Disconnected: |
|
1029 { |
|
1030 QString ident = QString::number(qHash(accessPointId)); |
|
1031 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(ident); |
|
1032 if (priv.data()) { |
|
1033 // Configuration is either Defined or Discovered |
|
1034 if (changeConfigurationStateAtMaxTo(priv, QNetworkConfiguration::Discovered)) { |
|
1035 updateStatesToSnaps(); |
|
1036 } |
|
1037 emit this->configurationStateChanged( |
|
1038 priv.data()->numericId, priv.data()->connectionId, QNetworkSession::Disconnected); |
|
1039 } |
|
1040 } |
|
1041 break; |
|
1042 default: |
|
1043 break; |
|
1044 } |
|
1045 } |
|
1046 |
|
1047 // Waits for 2..6 seconds. |
961 void QNetworkConfigurationManagerPrivate::waitRandomTime() |
1048 void QNetworkConfigurationManagerPrivate::waitRandomTime() |
962 { |
1049 { |
963 iTimeToWait = (qAbs(qrand()) % 5) * 1000; |
1050 iTimeToWait = (qAbs(qrand()) % 7) * 1000; |
964 if (iTimeToWait < 1000) { |
1051 if (iTimeToWait < 2000) { |
965 iTimeToWait = 1000; |
1052 iTimeToWait = 2000; |
966 } |
1053 } |
967 #ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG |
1054 #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG |
968 qDebug("QNetworkConfigurationManager waiting random time: %d ms", iTimeToWait); |
1055 qDebug("QNCM waiting random time: %d ms", iTimeToWait); |
969 #endif |
1056 #endif |
970 QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit())); |
1057 QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit())); |
971 iIgnoreEventLoop->exec(); |
1058 iIgnoreEventLoop->exec(); |
972 } |
1059 } |
973 |
1060 |
974 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::dataByConnectionId(TUint aConnectionId) |
1061 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationManagerPrivate::dataByConnectionId(TUint aConnectionId) |
975 { |
1062 { |
976 QNetworkConfiguration item; |
1063 QNetworkConfiguration item; |
977 |
|
978 QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i = |
1064 QHash<QString, QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> >::const_iterator i = |
979 accessPointConfigurations.constBegin(); |
1065 accessPointConfigurations.constBegin(); |
980 while (i != accessPointConfigurations.constEnd()) { |
1066 while (i != accessPointConfigurations.constEnd()) { |
981 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = i.value(); |
1067 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = i.value(); |
982 if (priv.data()->connectionId == aConnectionId) { |
1068 if (priv.data()->connectionId == aConnectionId) { |