wlan_bearer/wlanengine/wlan_symbian/wlanengine_symbian_3.1/src/wlanscanresultcache.cpp
changeset 0 c40eb8fe8501
child 32 c01ef7f246fd
--- /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<u32_t>& aIapIdList,
+    RArray<TWlanAvailableNetwork>& 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<TWlanAvailableNetwork> 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<TUint>* CWlanScanResultCache::AvailableIaps(
+    RArray<TWlanLimitedIapData>& aIapList,
+    TUint aCacheLifetime )
+    {
+    DEBUG( "CWlanScanResultCache::AvailableIaps()" );
+
+    /**
+     * Take a copy of the previous IAP list since GetIapDataList() will overwrite
+     * the member variable.
+     */
+    RArray<TWlanLimitedIapData> 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<TWlanLimitedIapData>& 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<SWlanIAPId> 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<EConnectionMode>( iapData.ConnectionMode );
+            iap.securityMode = static_cast<EWlanSecurityMode>( 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<TWlanLimitedIapData>& aFirst,
+    const RArray<TWlanLimitedIapData>& 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<TWlanLimitedIapData>& 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<TWlanLimitedIapData>& CWlanScanResultCache::CachedIapDataList() const
+    {
+    return iIapList;
+    }
+
+// -----------------------------------------------------------------------------
+// CWlanScanResultCache::InvalidateAvailabilityCache
+// -----------------------------------------------------------------------------
+//
+void CWlanScanResultCache::InvalidateAvailabilityCache()
+    {
+    iIapListTimeStamp = 0;
+    }