diff -r 000000000000 -r c40eb8fe8501 wlan_bearer/wlanengine/wlan_symbian/wlanengine_symbian_3.1/src/wlanscanresultcache.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlan_bearer/wlanengine/wlan_symbian/wlanengine_symbian_3.1/src/wlanscanresultcache.cpp Tue Feb 02 02:03:13 2010 +0200 @@ -0,0 +1,505 @@ +/* +* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Factory class for timers +* +*/ + + +#include "wlanscanresultcache.h" +#include "am_debug.h" + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::NewL +// ----------------------------------------------------------------------------- +// +CWlanScanResultCache* CWlanScanResultCache::NewL() + { + DEBUG( "CWlanScanResultCache::NewL()" ); + CWlanScanResultCache* self = new(ELeave)CWlanScanResultCache(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::ConstructL +// ----------------------------------------------------------------------------- +// +void CWlanScanResultCache::ConstructL() + { + DEBUG( "CWlanScanResultCache::ConstructL()" ); + + iScanList = new(ELeave) ScanList(); + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::CWlanScanResultCache +// ----------------------------------------------------------------------------- +// +CWlanScanResultCache::CWlanScanResultCache() : + iScanList( NULL ), + iScanListTimeStamp( 0 ), + iIapListTimeStamp( 0 ) + { + DEBUG( "CWlanScanResultCache::CWlanScanResultCache()" ); + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::~CWlanScanResultCache +// ----------------------------------------------------------------------------- +// +CWlanScanResultCache::~CWlanScanResultCache() + { + DEBUG( "CWlanScanResultCache::~CWlanScanResultCache()" ); + + delete iScanList; + iIapList.Close(); + iAvailableIapList.Close(); + iAvailableNetworkList.Close(); + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::UpdateScanList +// ----------------------------------------------------------------------------- +// +void CWlanScanResultCache::UpdateScanList( + ScanList* aScanList ) + { + DEBUG( "CWlanScanResultCache::UpdateScanList()" ); + + delete iScanList; + iScanList = aScanList; // take ownership + iScanListTimeStamp.HomeTime(); + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::GetScanList +// ----------------------------------------------------------------------------- +// +ScanList* CWlanScanResultCache::GetScanList( + TUint aCacheLifetime ) + { + DEBUG( "CWlanScanResultCache::GetScanList()" ); + + TTime currentTime(0); + currentTime.HomeTime(); + TTimeIntervalSeconds difference(0); + + TInt overflow = currentTime.SecondsFrom( iScanListTimeStamp, difference ); + if( difference.Int() > aCacheLifetime || difference.Int() < 0 || overflow ) + { + DEBUG2( "CWlanScanResultCache::GetScanList() - results are too old, difference is %d, overflow is %d", + difference.Int(), overflow ); + return NULL; + } + else + { + DEBUG1( "CWlanScanResultCache::GetScanList() - old results are still valid, difference is %u", + difference.Int() ); + return iScanList; + } + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::UpdateAvailableNetworksList +// ----------------------------------------------------------------------------- +// +void CWlanScanResultCache::UpdateAvailableNetworksList( + core_type_list_c& aIapIdList, + RArray& aNetworkList, + TBool& aNewIapsAvailable, + TBool& aOldIapsLost ) + { + DEBUG( "CWlanScanResultCache::UpdateAvailableNetworksList()" ); + + DEBUG1( "CWlanScanResultCache::UpdateAvailableNetworksList() - %u IAP(s) available", + aIapIdList.count() ); + DEBUG1( "CWlanScanResultCache::UpdateAvailableNetworksList() - %u IAP(s) previously available", + iAvailableIapList.Count() ); + DEBUG1( "CWlanScanResultCache::UpdateAvailableNetworksList() - %u networks(s) available", + aNetworkList.Count() ); + DEBUG1( "CWlanScanResultCache::UpdateAvailableNetworksList() - %u networks(s) previously available", + iAvailableNetworkList.Count() ); + + const TInt oldIapCount( iAvailableIapList.Count() ); + const TInt newNetworkCount( aNetworkList.Count() ); + const TInt oldNetworkCount( iAvailableNetworkList.Count() ); + aNewIapsAvailable = EFalse; + aOldIapsLost = EFalse; + TIdentityRelation isEqual( CWlanScanResultCache::IsNetworkEqual ); + + // Iterate through previously available IAPs to find lost IAPs. + TInt idx( 0 ); + //while( idx < oldIapCount && !aOldIapsLost ) + while( idx < oldIapCount ) + { + const TUint32* newId = aIapIdList.first(); + + while( newId ) + { + if( *newId == iAvailableIapList[idx] ) + { + break; + } + + newId = aIapIdList.next(); + } + + if( !newId ) + { + DEBUG1( "CWlanScanResultCache::UpdateAvailableNetworksList() - old IAP %u has been lost", + iAvailableIapList[idx] ); + aOldIapsLost = ETrue; + } + + ++idx; + } + + // Iterate through available IAPs to find new IAPs. + const TUint32* newId = aIapIdList.first(); + //while( newId && !aNewIapsAvailable ) + while( newId ) + { + if ( iAvailableIapList.Find( *newId ) == KErrNotFound ) + { + DEBUG1( "CWlanScanResultCache::UpdateAvailableNetworksList() - new IAP %u has been detected", + *newId ); + aNewIapsAvailable = ETrue; + } + + newId = aIapIdList.next(); + } + + // Iterate through previously available networks to find lost networks. + idx = 0; + //while ( idx < oldNetworkCount && !aOldIapsLost ) + while ( idx < oldNetworkCount ) + { + if ( aNetworkList.Find( iAvailableNetworkList[idx], isEqual ) == KErrNotFound ) + { + DEBUG1S( "CWlanScanResultCache::UpdateAvailableNetworksList() - old network has been lost, SSID ", + iAvailableNetworkList[idx].ssid.Length(), iAvailableNetworkList[idx].ssid.Ptr() ); + aOldIapsLost = ETrue; + } + ++idx; + } + + // Iterate through available networks to find new networks. + idx = 0; + //while( idx < newNetworkCount && !aNewIapsAvailable ) + while( idx < newNetworkCount ) + { + if ( iAvailableNetworkList.Find( aNetworkList[idx], isEqual ) == KErrNotFound ) + { + DEBUG1S( "CWlanScanResultCache::UpdateAvailableNetworksList() - new network has been detected, SSID ", + aNetworkList[idx].ssid.Length(), aNetworkList[idx].ssid.Ptr() ); + aNewIapsAvailable = ETrue; + } + ++idx; + } + + // Update the list + iAvailableIapList.Reset(); + iAvailableNetworkList.Reset(); + iIapListTimeStamp.HomeTime(); + + newId = aIapIdList.first(); + while( newId ) + { + iAvailableIapList.Append( *newId ); + newId = aIapIdList.next(); + } + + idx = 0; + while( idx < newNetworkCount ) + { + iAvailableNetworkList.Append( aNetworkList[idx] ); + ++idx; + } + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::AvailableIaps +// ----------------------------------------------------------------------------- +// +RArray* CWlanScanResultCache::AvailableIaps( + RArray& aIapList, + TUint aCacheLifetime ) + { + DEBUG( "CWlanScanResultCache::AvailableIaps()" ); + + /** + * Take a copy of the previous IAP list since GetIapDataList() will overwrite + * the member variable. + */ + RArray iapList; + for( TInt idx( 0 ); idx < iIapList.Count(); ++idx ) + { + iapList.Append( iIapList[idx] ); + } + + TInt ret = GetIapDataList( aIapList ); + if ( ret != KErrNone ) + { + DEBUG( "CWlanScanResultCache::AvailableIaps() - unable to read list of IAPs, assuming no cache" ); + iapList.Close(); + + return NULL; + } + + TTime currentTime(0); + currentTime.HomeTime(); + TTimeIntervalSeconds difference(0); + + TInt overflow = currentTime.SecondsFrom( iIapListTimeStamp, difference ); + if( difference.Int() > aCacheLifetime || difference.Int() < 0 || overflow ) + { + DEBUG2( "CWlanScanResultCache::AvailableIaps() - results are too old, difference is %d, overflow is %d", + difference.Int(), overflow ); + iapList.Close(); + + return NULL; + } + + /** + * Check whether the list of IAPs has change since last GetIapDataList(). + */ + if ( !IsIapListEqual( aIapList, iapList ) ) + { + DEBUG( "CWlanScanResultCache::AvailableIaps() - cache time is still valid but IAPs have changed" ); + iapList.Close(); + + return NULL; + } + + DEBUG1( "CWlanScanResultCache::AvailableIaps() - old results are still valid, difference is %u", + difference.Int() ); + iapList.Close(); + + return &iAvailableIapList; + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::GetIapDataList +// ----------------------------------------------------------------------------- +// +TInt CWlanScanResultCache::GetIapDataList( + RArray& aIapList ) + { + DEBUG( "CWlanScanResultCache::GetIapDataList()" ); + + aIapList.Reset(); + + /** + * Read all WLAN IAPs from commsdat. + */ + CWLanSettings wlanSettings; + TInt ret = wlanSettings.Connect(); + if ( ret != KErrNone ) + { + DEBUG1( "CWlanScanResultCache::GetIapDataList() - CWLanSettings::Connect() failed (%d)", + ret ); + + return ret; + } + + RArray wlanIapIds; + TRAP( ret, wlanSettings.GetIAPWlanServicesL( wlanIapIds ) ); + if( ret != KErrNone ) + { + DEBUG1( "CWlanScanResultCache::GetIapDataList() - CWLanSettings::GetIAPWlanServicesL() failed (%d)", + ret ); + wlanIapIds.Close(); + wlanSettings.Disconnect(); + + return ret; + } + + /** + * Retrieve IAP data for each IAP id. + */ + DEBUG1( "CWlanScanResultCache::GetIapDataList() - reading %u WLAN IAPs", + wlanIapIds.Count() ); + + for( TInt i( 0 ); i < wlanIapIds.Count(); i++ ) + { + TWlanLimitedIapData iap; + iap.iapId = wlanIapIds[i].iIAPId; + iap.serviceId = wlanIapIds[i].iWLANRecordId; + + DEBUG1( "CWlanScanResultCache::GetIapDataList() - reading IAP %u", + wlanIapIds[i].iIAPId ); + + SWLANSettings iapData; + ret = wlanSettings.GetWlanSettings( + wlanIapIds[i].iWLANRecordId, + iapData ); + if( ret != KErrNone ) + { + DEBUG2( "CWlanScanResultCache::GetIapDataList() - reading of IAP %u failed (%d), ignoring", + wlanIapIds[i].iIAPId, ret ); + } + else if( iapData.SSID.Length() ) // filter out EasyWlan IAP + { + iap.ssid.Copy( iapData.SSID ); + iap.usedSsid.Copy( iapData.UsedSSID ); + iap.networkType = static_cast( iapData.ConnectionMode ); + iap.securityMode = static_cast( iapData.SecurityMode ); + iap.isPskEnabled = iapData.EnableWpaPsk; + iap.isHidden = iapData.ScanSSID; + + aIapList.Append( iap ); + } + } + + UpdateIapList( aIapList ); + wlanIapIds.Close(); + wlanSettings.Disconnect(); + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::IsNetworkEqual +// ----------------------------------------------------------------------------- +// +TBool CWlanScanResultCache::IsNetworkEqual( + const TWlanAvailableNetwork& aFirst, + const TWlanAvailableNetwork& aSecond ) + { + if ( aFirst.ssid != aSecond.ssid || + aFirst.networkType != aSecond.networkType || + aFirst.securityMode != aSecond.securityMode ) + { + return EFalse; + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::IsIapListEqual +// ----------------------------------------------------------------------------- +// +TBool CWlanScanResultCache::IsIapListEqual( + const RArray& aFirst, + const RArray& aSecond ) + { + /** + * If the amount of IAPs is different, it's an obvious fault. + */ + if ( aFirst.Count() != aSecond.Count() ) + { + DEBUG2( "CWlanScanResultCache::GetIapDataList() - false, amount of IAPs is different (%u vs %u)", + aFirst.Count(), aSecond.Count() ); + + return EFalse; + } + + /** + * Some of the settings might have changed. + */ + for( TInt i( 0 ); i < aFirst.Count(); ++i ) + { + TBool isFound( EFalse ); + for ( TInt j( 0 ); j < aSecond.Count() && !isFound; ++j ) + { + if ( aFirst[i].iapId == aSecond[j].iapId ) + { + isFound = ETrue; + if ( aFirst[i].ssid != aSecond[j].ssid ) + { + DEBUG1( "CWlanScanResultCache::GetIapDataList() - false, IAP %u has mismatching SSID", + aFirst[i].iapId ); + + return EFalse; + } + else if ( aFirst[i].networkType != aSecond[j].networkType ) + { + DEBUG1( "CWlanScanResultCache::GetIapDataList() - false, IAP %u has mismatching network mode", + aFirst[i].iapId ); + + return EFalse; + } + else if ( aFirst[i].securityMode != aSecond[j].securityMode || + aFirst[i].isPskEnabled != aSecond[j].isPskEnabled ) + { + DEBUG1( "CWlanScanResultCache::GetIapDataList() - false, IAP %u has mismatching security mode", + aFirst[i].iapId ); + + return EFalse; + } + else if ( aFirst[i].isHidden != aSecond[j].isHidden ) + { + DEBUG1( "CWlanScanResultCache::GetIapDataList() - false, IAP %u has mismatching hidden setting", + aFirst[i].iapId ); + + return EFalse; + } + } + } + if ( !isFound ) + { + DEBUG1( "CWlanScanResultCache::GetIapDataList() - false, IAP %u not found in previous list", + aFirst[i].iapId ); + + return EFalse; + } + } + + DEBUG( "CWlanScanResultCache::GetIapDataList() - true, IAP lists are equal" ); + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::UpdateIapList +// ----------------------------------------------------------------------------- +// +void CWlanScanResultCache::UpdateIapList( + const RArray& aIapDataList ) + { + iIapList.Reset(); + TUint32 arraySize( 0 ); + + for( TInt idx( 0 ); idx < aIapDataList.Count(); ++idx ) + { + arraySize += sizeof( aIapDataList[idx] ); + iIapList.Append( aIapDataList[idx] ); + } + + DEBUG1( "CWlanScanResultCache::UpdateIapList() - total size of IAP list is %u bytes", + arraySize ); + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::CachedIapDataList +// ----------------------------------------------------------------------------- +// +const RArray& CWlanScanResultCache::CachedIapDataList() const + { + return iIapList; + } + +// ----------------------------------------------------------------------------- +// CWlanScanResultCache::InvalidateAvailabilityCache +// ----------------------------------------------------------------------------- +// +void CWlanScanResultCache::InvalidateAvailabilityCache() + { + iIapListTimeStamp = 0; + }