connectionmonitoring/connmon/connectionmonitor/src/connmoncommsdatcache.cpp
changeset 0 5a93021fdf25
child 56 dd6aaa97e7b1
equal deleted inserted replaced
-1:000000000000 0:5a93021fdf25
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Provides cached information on IAPs and SNAPs in CommsDat.
       
    15 *
       
    16 */
       
    17 
       
    18 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    19 #include <commsdat_partner.h>
       
    20 #endif
       
    21 #include <datamobilitycommsdattypes.h>
       
    22 
       
    23 #include "ConnMonServ.h"
       
    24 #include "CEventQueue.h"
       
    25 #include "ConnMonIAP.h"
       
    26 #include "ConnMonBearer.h"
       
    27 #include "connmoncommsdatcache.h"
       
    28 #include "log.h"
       
    29 
       
    30 using namespace CommsDat;
       
    31 
       
    32 TConnMonSnapEntry::TConnMonSnapEntry()
       
    33     {
       
    34     iId = 0;
       
    35     iNextLayerIapId = 0;
       
    36     iNextLayerSnapId = 0;
       
    37     iAvailability = 0;
       
    38     iNextLayerIndex = KErrNotFound;
       
    39     }
       
    40 
       
    41 TConnMonSnapEntry::TConnMonSnapEntry(
       
    42         TUint aId,
       
    43         TUint aNextLayerIapId,
       
    44         TUint aNextLayerSnapId )
       
    45         :
       
    46         iId( aId ),
       
    47         iNextLayerIapId( aNextLayerIapId ),
       
    48         iNextLayerSnapId( aNextLayerSnapId )
       
    49     {
       
    50     iAvailability = 0;
       
    51     iNextLayerIndex = KErrNotFound;
       
    52     }
       
    53 
       
    54 TInt TConnMonSnapEntry::Compare(
       
    55         const TConnMonSnapEntry& aFirst,
       
    56         const TConnMonSnapEntry& aSecond )
       
    57     {
       
    58     // Availability info is ignored
       
    59     if ( aFirst.iId < aSecond.iId ) return -1;
       
    60     if ( aFirst.iId > aSecond.iId ) return 1;
       
    61     if ( aFirst.iNextLayerSnapId < aSecond.iNextLayerSnapId ) return -1;
       
    62     if ( aFirst.iNextLayerSnapId > aSecond.iNextLayerSnapId ) return 1;
       
    63     if ( aFirst.iNextLayerIapId < aSecond.iNextLayerIapId ) return -1;
       
    64     if ( aFirst.iNextLayerIapId > aSecond.iNextLayerIapId ) return 1;
       
    65     return 0;
       
    66     }
       
    67 
       
    68 TInt TConnMonSnapEntry::FindCompare(
       
    69         const TInt* aKey,
       
    70         const TConnMonSnapEntry& aEntry )
       
    71     {
       
    72     // Zero if match, negative if first is smaller, positive otherwise
       
    73     return ( *aKey ) - aEntry.iId;
       
    74     }
       
    75 
       
    76 TBool TConnMonSnapEntry::Match(
       
    77         const TConnMonSnapEntry& aFirst,
       
    78         const TConnMonSnapEntry& aSecond )
       
    79     {
       
    80     // Availability info is ignored
       
    81     if ( ( aFirst.iId == aSecond.iId ) &&
       
    82             ( aFirst.iNextLayerIapId == aSecond.iNextLayerIapId ) &&
       
    83             ( aFirst.iNextLayerSnapId == aSecond.iNextLayerSnapId ) )
       
    84         {
       
    85         return ETrue;
       
    86         }
       
    87     return EFalse;
       
    88     }
       
    89 
       
    90 
       
    91 TConnMonIapEntry::TConnMonIapEntry()
       
    92     {
       
    93     iId = 0;
       
    94     iBearerType = 0;
       
    95     iServiceType = 0;
       
    96     iAvailability = 0;
       
    97     iNextLayerIapId = 0;
       
    98     iNextLayerSnapId = 0;
       
    99     iNextLayerIndex = KErrNotFound;
       
   100     }
       
   101 
       
   102 TConnMonIapEntry::TConnMonIapEntry(
       
   103         TUint aId,
       
   104         TUint aBearerType,
       
   105         TUint aServiceType )
       
   106         :
       
   107         iId( aId ),
       
   108         iBearerType( aBearerType ),
       
   109         iServiceType( aServiceType )
       
   110     {
       
   111     iAvailability = 0;
       
   112     iNextLayerIndex = KErrNotFound;
       
   113     iNextLayerIapId = 0;
       
   114     iNextLayerSnapId = 0;
       
   115     }
       
   116 
       
   117 TInt TConnMonIapEntry::Compare(
       
   118         const TConnMonIapEntry& aFirst,
       
   119         const TConnMonIapEntry& aSecond )
       
   120     {
       
   121     // Zero if match, negative if first is smaller, positive otherwise
       
   122     // Availability info is ignored
       
   123     return aFirst.iId - aSecond.iId;
       
   124     }
       
   125 
       
   126 TInt TConnMonIapEntry::FindCompare(
       
   127         const TInt* aKey,
       
   128         const TConnMonIapEntry& aEntry )
       
   129     {
       
   130     // Zero if match, negative if first is smaller, positive otherwise
       
   131     return ( *aKey ) - aEntry.iId;
       
   132     }
       
   133 
       
   134 TBool TConnMonIapEntry::Match(
       
   135         const TConnMonIapEntry& aFirst,
       
   136         const TConnMonIapEntry& aSecond )
       
   137     {
       
   138     // Availability info is ignored
       
   139     if ( ( aFirst.iId == aSecond.iId ) &&
       
   140             ( aFirst.iBearerType == aSecond.iBearerType ) &&
       
   141             ( aFirst.iServiceType == aSecond.iServiceType ) )
       
   142         {
       
   143         return ETrue;
       
   144         }
       
   145     return EFalse;
       
   146     }
       
   147 
       
   148 
       
   149 TConnMonVirtualIapEntry::TConnMonVirtualIapEntry()
       
   150     {
       
   151     iId = 0;
       
   152     iNextLayerIapId = 0;
       
   153     iNextLayerSnapId = 0;
       
   154     }
       
   155 
       
   156 TConnMonVirtualIapEntry::TConnMonVirtualIapEntry(
       
   157         TUint aId,
       
   158         TUint aNextLayerIapId,
       
   159         TUint aNextLayerSnapId )
       
   160         :
       
   161         iId( aId ),
       
   162         iNextLayerIapId( aNextLayerIapId ),
       
   163         iNextLayerSnapId( aNextLayerSnapId )
       
   164     {
       
   165     }
       
   166 
       
   167 TInt TConnMonVirtualIapEntry::Compare(
       
   168         const TConnMonVirtualIapEntry& aFirst,
       
   169         const TConnMonVirtualIapEntry& aSecond )
       
   170     {
       
   171     // Zero if match, negative if first is smaller, positive otherwise
       
   172     return aFirst.iId - aSecond.iId;
       
   173     }
       
   174 
       
   175 TInt TConnMonVirtualIapEntry::FindCompare(
       
   176         const TInt* aKey,
       
   177         const TConnMonVirtualIapEntry& aEntry )
       
   178     {
       
   179     // Zero if match, negative if first is smaller, positive otherwise
       
   180     return ( *aKey ) - aEntry.iId;
       
   181     }
       
   182 
       
   183 TBool TConnMonVirtualIapEntry::Match(
       
   184         const TConnMonVirtualIapEntry& aFirst,
       
   185         const TConnMonVirtualIapEntry& aSecond )
       
   186     {
       
   187     if ( ( aFirst.iId == aSecond.iId ) &&
       
   188             ( aFirst.iNextLayerIapId == aSecond.iNextLayerIapId ) &&
       
   189             ( aFirst.iNextLayerSnapId == aSecond.iNextLayerSnapId ) )
       
   190         {
       
   191         return ETrue;
       
   192         }
       
   193     return EFalse;
       
   194     }
       
   195 
       
   196 
       
   197 // ---------------------------------------------------------------------------
       
   198 // Two phased constructor.
       
   199 // ---------------------------------------------------------------------------
       
   200 //
       
   201 CConnMonCommsDatCache* CConnMonCommsDatCache::NewL()
       
   202     {
       
   203     //LOGENTRFN("CConnMonCommsDatCache::NewL()")
       
   204 
       
   205     CConnMonCommsDatCache* self = CConnMonCommsDatCache::NewLC();
       
   206     CleanupStack::Pop( self );
       
   207 
       
   208     //LOGEXITFN("CConnMonCommsDatCache::NewL()")
       
   209     return self;
       
   210     }
       
   211 
       
   212 // ---------------------------------------------------------------------------
       
   213 // Two phased constructor.
       
   214 // ---------------------------------------------------------------------------
       
   215 //
       
   216 CConnMonCommsDatCache* CConnMonCommsDatCache::NewLC()
       
   217     {
       
   218     //LOGENTRFN("CConnMonCommsDatCache::NewLC()")
       
   219 
       
   220     CConnMonCommsDatCache* self = new( ELeave ) CConnMonCommsDatCache;
       
   221     CleanupStack::PushL( self );
       
   222     self->ConstructL();
       
   223 
       
   224     //LOGEXITFN("CConnMonCommsDatCache::NewLC()")
       
   225     return self;
       
   226     }
       
   227 
       
   228 // ---------------------------------------------------------------------------
       
   229 // Destructor.
       
   230 // ---------------------------------------------------------------------------
       
   231 //
       
   232 CConnMonCommsDatCache::~CConnMonCommsDatCache()
       
   233     {
       
   234     LOGENTRFN("CConnMonCommsDatCache::~CConnMonCommsDatCache()")
       
   235 
       
   236     if ( iSnapCache )
       
   237         {
       
   238         iSnapCache->Close();
       
   239         delete iSnapCache;
       
   240         iSnapCache = NULL;
       
   241         }
       
   242     if ( iIapCache )
       
   243         {
       
   244         iIapCache->Close();
       
   245         delete iIapCache;
       
   246         iIapCache = NULL;
       
   247         }
       
   248     if ( iVirtualIapCache )
       
   249         {
       
   250         iVirtualIapCache->Close();
       
   251         delete iVirtualIapCache;
       
   252         iVirtualIapCache = NULL;
       
   253         }
       
   254 
       
   255     iWlanIapIdCache.Close();
       
   256     iIapIdCache.Close();
       
   257     iSnapIdCache.Close();
       
   258 
       
   259     LOGEXITFN("CConnMonCommsDatCache::~CConnMonCommsDatCache()")
       
   260     }
       
   261 
       
   262 // ---------------------------------------------------------------------------
       
   263 // Reads all IAP and SNAP information from CommsDat and initializes the cache
       
   264 // with it.
       
   265 // ---------------------------------------------------------------------------
       
   266 //
       
   267 void CConnMonCommsDatCache::Init(
       
   268         CConnMonServer* aServer,
       
   269         CConnMonIAP* aConnMonIap,
       
   270         RPointerArray<TConnMonBearer>* aBearers )
       
   271     {
       
   272     LOGENTRFN("CConnMonCommsDatCache::Init()")
       
   273 
       
   274     iServer = aServer;
       
   275     iIap = aConnMonIap;
       
   276     iBearers = aBearers;
       
   277 
       
   278     if ( iInitStatus != EConnMonCacheInitNotStarted )
       
   279         {
       
   280         LOGIT("Init: ERROR, ConnMon CommsDat cache init called too many times")
       
   281         return;
       
   282         }
       
   283     iInitStatus = EConnMonCacheInitInProgress;
       
   284 
       
   285     // Check if WLAN bearer is available
       
   286     for ( TInt i = 0; i < iBearers->Count(); i++ )
       
   287         {
       
   288         if ( (*iBearers)[i]->BearerId() == EBearerIdWLAN )
       
   289             {
       
   290             iWlanSupportEnabled = ETrue;
       
   291             break;
       
   292             }
       
   293         }
       
   294 
       
   295     TRAPD( leaveCode, InitCommsDatCacheL() );
       
   296     if ( leaveCode )
       
   297         {
       
   298         LOGIT1("Init: ERROR (Ok if empty), LEAVE in ConnMon CommsDat cache init <%d>", leaveCode)
       
   299         }
       
   300 
       
   301     RefreshAvailabilityInfo( EFalse ); // Never send events in Init phase
       
   302     iInitStatus = EConnMonCacheInitCompleted;
       
   303 
       
   304     LOGEXITFN("CConnMonCommsDatCache::Init()")
       
   305     }
       
   306 
       
   307 // ---------------------------------------------------------------------------
       
   308 // Calls the correct method to read the CommsDat table, refered to with
       
   309 // parameter aTableId, to cache. This should be called when a change is
       
   310 // detected in CommsDat through central repository events.
       
   311 // ---------------------------------------------------------------------------
       
   312 //
       
   313 void CConnMonCommsDatCache::RefreshCommsDatCacheL( const TUint32 aTableId )
       
   314     {
       
   315     //LOGENTRFN("CConnMonCommsDatCache::RefreshCommsDatCacheL()")
       
   316 
       
   317     CMDBSession* db = CMDBSession::NewLC( CMDBSession::LatestVersion() );
       
   318     db->SetAttributeMask( ECDHidden | ECDProtectedWrite );
       
   319 
       
   320     if ( aTableId == iIapRecordTableId )
       
   321         {
       
   322         LOGIT("RefreshCommsDatCacheL: IAP table change event")
       
   323         RefreshCommsDatIapCacheL( *db );
       
   324         }
       
   325     else if ( aTableId == iSnapRecordTableId )
       
   326         {
       
   327         LOGIT("RefreshCommsDatCacheL: SNAP table change event")
       
   328         RefreshCommsDatSnapCacheL( *db );
       
   329         }
       
   330     else if ( aTableId == iVirtualRecordTableId )
       
   331         {
       
   332         LOGIT("RefreshCommsDatCacheL: Virtual record table change event")
       
   333         RefreshCommsDatVirtualIapCacheL( *db );
       
   334         }
       
   335     else if ( aTableId == 0 )
       
   336         {
       
   337         // This option is not currently used, but provided to support the
       
   338         // possibility to read CommsDat information again when client is
       
   339         // asking for IAP/SNAP availability information as a request.
       
   340         // This would be needed in the case that CenRep change events
       
   341         // become unreliable for some reason, and thus the CommsDat cache
       
   342         // would not be reliably up to date.
       
   343         LOGIT("RefreshCommsDatCacheL: Reading all commsdat tables")
       
   344         RefreshCommsDatIapCacheL( *db );
       
   345         RefreshCommsDatSnapCacheL( *db );
       
   346         RefreshCommsDatVirtualIapCacheL( *db );
       
   347         }
       
   348 
       
   349     CleanupStack::PopAndDestroy( db );
       
   350 
       
   351     //LOGEXITFN("CConnMonCommsDatCache::RefreshCommsDatCacheL()")
       
   352     }
       
   353 
       
   354 // ---------------------------------------------------------------------------
       
   355 // Solves IAP and SNAP availability. The availability information in the cache
       
   356 // tables will be up to date after a call to this method.
       
   357 // If parameter aCanSendEvents is true, availability changed events will be
       
   358 // sent to clients if any changes from previous availability state is detected.
       
   359 // ---------------------------------------------------------------------------
       
   360 //
       
   361 void CConnMonCommsDatCache::RefreshAvailabilityInfo( const TBool aCanSendEvents )
       
   362     {
       
   363     LOGENTRFN("CConnMonCommsDatCache::RefreshAvailabilityInfo()")
       
   364 
       
   365     // If any relevant commsdat table changed.
       
   366     //
       
   367     // These flags are set to true only when CommsDat change event is received,
       
   368     // CommsDat information is read into ConnMon cache, and that information
       
   369     // has changed.
       
   370     if ( iIapsChanged || iSnapsChanged || iVirtualIapsChanged )
       
   371         {
       
   372         UpdateSnapAndVirtualIapLinks();
       
   373         iIapsChanged = EFalse;
       
   374         iSnapsChanged = EFalse;
       
   375         iVirtualIapsChanged = EFalse;
       
   376         }
       
   377 
       
   378     ResetAllAvailabilityInfo();
       
   379     for ( TInt i = 0; i < iBearers->Count(); i++ )
       
   380         {
       
   381         (*iBearers)[i]->FlagAvailableIaps();
       
   382         }
       
   383     SolveSnapAndVirtualIapAvailability();
       
   384 
       
   385     LOGIT(".")
       
   386     TBool availableIapsChanged = UpdateAvailableIaps();
       
   387 
       
   388     #ifdef _DEBUG
       
   389     // Print available IAP IDs to log
       
   390     for ( TInt j = 0; j < iIapCache->Count(); j++ )
       
   391         {
       
   392         if ( (*iIapCache)[j].iAvailability == EConnMonAvailabilityAvailable )
       
   393             {
       
   394             TUint currentId = (*iIapCache)[j].iId;
       
   395             if ( (*iIapCache)[j].iBearerType == EConnMonCacheBearerTypeVirtual )
       
   396                 {
       
   397                 switch ( (*iIapCache)[j].iServiceType )
       
   398                     {
       
   399                     case EConnMonCacheServiceTypeCsd:
       
   400                         LOGIT1("  %3d: CSD, virtual", currentId) break;
       
   401                     case EConnMonCacheServiceTypeGprs:
       
   402                         LOGIT1("  %3d: GPRS, virtual", currentId) break;
       
   403                     case EConnMonCacheServiceTypeLan:
       
   404                         LOGIT1("  %3d: LAN, virtual", currentId) break;
       
   405                     case EConnMonCacheServiceTypeWlan:
       
   406                         LOGIT1("  %3d: WLAN, virtual", currentId) break;
       
   407                     default:
       
   408                         LOGIT1("  %3d: Unknown, virtual", currentId) break;
       
   409                     }
       
   410                 }
       
   411             else
       
   412                 {
       
   413                 switch ( (*iIapCache)[j].iServiceType )
       
   414                     {
       
   415                     case EConnMonCacheServiceTypeCsd:
       
   416                         LOGIT1("  %3d: CSD", currentId) break;
       
   417                     case EConnMonCacheServiceTypeGprs:
       
   418                         LOGIT1("  %3d: GPRS", currentId) break;
       
   419                     case EConnMonCacheServiceTypeLan:
       
   420                         LOGIT1("  %3d: LAN", currentId) break;
       
   421                     case EConnMonCacheServiceTypeWlan:
       
   422                         LOGIT1("  %3d: WLAN", currentId) break;
       
   423                     default:
       
   424                         LOGIT1("  %3d: Unknown", currentId) break;
       
   425                     }
       
   426                 }
       
   427             }
       
   428         }
       
   429     #endif // _DEBUG
       
   430 
       
   431     TBool availableSnapsChanged = UpdateAvailableSnaps();
       
   432 
       
   433     // Print available SNAP IDs to log
       
   434     #ifdef _DEBUG
       
   435     TUint lastSnapId( 0 );
       
   436     for ( TInt k = 0; k < iSnapCache->Count(); k++ )
       
   437         {
       
   438         TUint currentId = (*iSnapCache)[k].iId;
       
   439         if ( currentId != lastSnapId )
       
   440             {
       
   441             lastSnapId = currentId;
       
   442             if ( (*iSnapCache)[k].iAvailability == EConnMonAvailabilityAvailable )
       
   443                 {
       
   444                 LOGIT1("  %4d", currentId)
       
   445                 }
       
   446             }
       
   447         }
       
   448     LOGIT(".")
       
   449     #endif // _DEBUG
       
   450 
       
   451     if ( aCanSendEvents )
       
   452         {
       
   453         if ( availableIapsChanged )
       
   454             {
       
   455             LOGIT("RefreshAvailabilityInfo: sending IAP availability event")
       
   456             SendIapAvailabilityEvent();
       
   457             }
       
   458         if ( availableSnapsChanged )
       
   459             {
       
   460             LOGIT("RefreshAvailabilityInfo: sending SNAP availability event")
       
   461             SendSnapAvailabilityEvent();
       
   462             }
       
   463         }
       
   464 
       
   465     LOGEXITFN("CConnMonCommsDatCache::RefreshAvailabilityInfo()")
       
   466     }
       
   467 
       
   468 // ---------------------------------------------------------------------------
       
   469 // Set as available all IAPs which correspond to the given bearer ID
       
   470 // (converted to service type).
       
   471 // ---------------------------------------------------------------------------
       
   472 //
       
   473 void CConnMonCommsDatCache::SetAvailableIapsWithBearerId( const TUint aBearerId )
       
   474     {
       
   475     //LOGENTRFN("CConnMonCommsDatCache::SetAvailableIapsWithBearerId()")
       
   476     TInt err( KErrNone );
       
   477 
       
   478     TUint serviceType;
       
   479     err = ConvertBearerIdToServiceType( aBearerId, serviceType );
       
   480 
       
   481     if ( !err )
       
   482         {
       
   483         const TInt iapCount = iIapCache->Count();
       
   484         for ( TInt i = 0; i < iapCount; i++ )
       
   485             {
       
   486             if ( (*iIapCache)[i].iServiceType == serviceType )
       
   487                 {
       
   488                 (*iIapCache)[i].iAvailability = EConnMonAvailabilityAvailable;
       
   489                 }
       
   490             }
       
   491         }
       
   492 
       
   493     //LOGEXITFN("CConnMonCommsDatCache::SetAvailableIapsWithBearerId()")
       
   494     }
       
   495 
       
   496 // ---------------------------------------------------------------------------
       
   497 // Set as available the IAP with matching ID.
       
   498 // ---------------------------------------------------------------------------
       
   499 //
       
   500 void CConnMonCommsDatCache::SetAvailableIapWithId( const TUint aId )
       
   501     {
       
   502     //LOGENTRFN("CConnMonCommsDatCache::SetAvailableIapWithId()")
       
   503 
       
   504     TInt index = iIapCache->FindInOrder<TInt>( aId, TConnMonIapEntry::FindCompare );
       
   505     if ( index >= 0)
       
   506         {
       
   507         (*iIapCache)[index].iAvailability = EConnMonAvailabilityAvailable;
       
   508         }
       
   509 
       
   510     //LOGEXITFN("CConnMonCommsDatCache::SetAvailableIapWithId()")
       
   511     }
       
   512 
       
   513 // ---------------------------------------------------------------------------
       
   514 // Get available IAP IDs for the requested bearer ID. IAP availability is
       
   515 // re-solved first.
       
   516 // Maximum number of IAP IDs is limited by KConnMonMaxIAPCount.
       
   517 // ---------------------------------------------------------------------------
       
   518 //
       
   519 TInt CConnMonCommsDatCache::GetAvailableIaps(
       
   520         const TUint aBearerId,
       
   521         TConnMonIapInfo& aIapInfo )
       
   522     {
       
   523     LOGENTRFN("CConnMonCommsDatCache::GetAvailableIaps()")
       
   524     TInt err( KErrNone );
       
   525 
       
   526     TBool availabilityEventsEnabled( EFalse );
       
   527     if ( ( aBearerId == EBearerIdAll ) || ( aBearerId == EBearerIdVirtualVPN ) )
       
   528         {
       
   529         // If WLAN background scanning is on, and client is asking IAP
       
   530         // availability for all- or virtual IAPs, send IAP availability changed
       
   531         // events if any changes detected.
       
   532         TRAPD( traperr, availabilityEventsEnabled = IsWlanBackgroundScanningEnabledL() );
       
   533         if ( traperr )
       
   534             {
       
   535             // If error here, continue as WLAN background scanning is disabled.
       
   536             availabilityEventsEnabled = EFalse;
       
   537             LOGIT1("ERROR, WLAN background scan discovery failed with <%d>", traperr)
       
   538             }
       
   539         }
       
   540 
       
   541     RefreshAvailabilityInfo( availabilityEventsEnabled );
       
   542 
       
   543     TInt iapCount( 0 );
       
   544     TUint bearerType( 0 );
       
   545     TUint serviceType( 0 );
       
   546     TBool done( EFalse );
       
   547 
       
   548     switch ( aBearerId )
       
   549         {
       
   550         case EBearerIdAll:
       
   551             {
       
   552             iapCount = iIapIdCache.Count();
       
   553             if ( iapCount > KConnMonMaxIAPCount )
       
   554                 {
       
   555                 iapCount = KConnMonMaxIAPCount;
       
   556                 }
       
   557             aIapInfo.iCount = iapCount;
       
   558             for ( TInt i = 0; i < iapCount; i++ )
       
   559                 {
       
   560                 aIapInfo.iIap[i].iIapId = iIapIdCache[i];
       
   561                 }
       
   562             done = ETrue;
       
   563             }
       
   564             break;
       
   565         case EBearerIdGPRS:
       
   566         case EBearerIdWCDMA:
       
   567             serviceType = EConnMonCacheServiceTypeGprs;
       
   568             break;
       
   569         case EBearerIdWLAN:
       
   570             serviceType = EConnMonCacheServiceTypeWlan;
       
   571             break;
       
   572         case EBearerIdCSD:
       
   573         case EBearerIdWcdmaCSD:
       
   574             serviceType = EConnMonCacheServiceTypeCsd;
       
   575             break;
       
   576         case EBearerIdVirtualVPN:
       
   577             bearerType = EConnMonCacheBearerTypeVirtual;
       
   578             break;
       
   579         case EBearerIdLAN:
       
   580             serviceType = EConnMonCacheServiceTypeLan;
       
   581             break;
       
   582         default:
       
   583             err = KErrArgument;
       
   584             done = ETrue;
       
   585             break;
       
   586         }
       
   587 
       
   588     if ( !done )
       
   589         {
       
   590         TInt totalCount = iIapCache->Count();
       
   591         for ( TInt i = 0; i < totalCount && iapCount < KConnMonMaxIAPCount; i++ )
       
   592             {
       
   593             if ( serviceType )
       
   594                 {
       
   595                 if ( (*iIapCache)[i].iAvailability == EConnMonAvailabilityAvailable &&
       
   596                         (*iIapCache)[i].iServiceType == serviceType )
       
   597                     {
       
   598                     aIapInfo.iIap[iapCount].iIapId = (*iIapCache)[i].iId;
       
   599                     iapCount++;
       
   600                     }
       
   601                 }
       
   602             else if ( bearerType )
       
   603                 {
       
   604                 if ( (*iIapCache)[i].iAvailability == EConnMonAvailabilityAvailable &&
       
   605                         (*iIapCache)[i].iBearerType == bearerType )
       
   606                     {
       
   607                     aIapInfo.iIap[iapCount].iIapId = (*iIapCache)[i].iId;
       
   608                     iapCount++;
       
   609                     }
       
   610                 }
       
   611             }
       
   612         aIapInfo.iCount = iapCount;
       
   613         }
       
   614 
       
   615     LOGEXITFN1("CConnMonCommsDatCache::GetAvailableIaps()", err)
       
   616     return err;
       
   617     }
       
   618 
       
   619 // ---------------------------------------------------------------------------
       
   620 // Get available SNAP IDs. SNAP availability is re-solved first.
       
   621 // Maximum number of SNAP IDs is limited by KConnMonMaxSNAPsCount.
       
   622 // ---------------------------------------------------------------------------
       
   623 //
       
   624 void CConnMonCommsDatCache::GetAvailableSnaps( TConnMonSNAPInfo& aSnapInfo )
       
   625     {
       
   626     LOGENTRFN("CConnMonCommsDatCache::GetAvailableSnaps()")
       
   627 
       
   628     TBool availabilityEventsEnabled( EFalse );
       
   629     // If WLAN background scanning is on, and client is asking SNAP
       
   630     // availability, send SNAP availability changed events if any changes
       
   631     // detected.
       
   632     TRAPD( traperr, availabilityEventsEnabled = IsWlanBackgroundScanningEnabledL() );
       
   633     if ( traperr )
       
   634         {
       
   635         // If error here, continue as WLAN background scanning is disabled.
       
   636         availabilityEventsEnabled = EFalse;
       
   637         LOGIT1("ERROR, WLAN background scan discovery failed: <%d>", traperr)
       
   638         }
       
   639 
       
   640     RefreshAvailabilityInfo( availabilityEventsEnabled );
       
   641 
       
   642     TInt snapCount = iSnapIdCache.Count();
       
   643     if ( snapCount > KConnMonMaxSNAPsCount )
       
   644         {
       
   645         snapCount = KConnMonMaxSNAPsCount;
       
   646         }
       
   647     aSnapInfo.iCount = snapCount;
       
   648     for ( TInt i = 0; i < snapCount; i++ )
       
   649         {
       
   650         aSnapInfo.iSNAP[i].iSNAPId = iSnapIdCache[i];
       
   651         }
       
   652 
       
   653     LOGEXITFN("CConnMonCommsDatCache::GetAvailableSnaps()")
       
   654     }
       
   655 
       
   656 // ---------------------------------------------------------------------------
       
   657 // Get available SNAP IDs. SNAP availability is re-solved first.
       
   658 // ---------------------------------------------------------------------------
       
   659 //
       
   660 TInt CConnMonCommsDatCache::GetAvailableSnaps( RArray<TConnMonId>& aSnapIds )
       
   661     {
       
   662     LOGENTRFN("CConnMonCommsDatCache::GetAvailableSnaps()")
       
   663 
       
   664     TBool availabilityEventsEnabled( EFalse );
       
   665     // If WLAN background scanning is on, and client is asking SNAP
       
   666     // availability, send SNAP availability changed events if any changes
       
   667     // detected.
       
   668     TRAPD( traperr, availabilityEventsEnabled = IsWlanBackgroundScanningEnabledL() );
       
   669     if ( traperr )
       
   670         {
       
   671         // If error here, continue as WLAN background scanning is disabled.
       
   672         availabilityEventsEnabled = EFalse;
       
   673         LOGIT1("ERROR, WLAN background scan discovery failed: <%d>", traperr)
       
   674         }
       
   675 
       
   676     RefreshAvailabilityInfo( availabilityEventsEnabled );
       
   677 
       
   678     // Return KErrNoMemory only if RArray fails to allocate memory, KErrNone otherwise
       
   679     TInt err( KErrNone );
       
   680     err = aSnapIds.Reserve( iSnapIdCache.Count() );
       
   681     if ( !err )
       
   682         {
       
   683         for ( TInt i = 0; i < iSnapIdCache.Count(); i++ )
       
   684             {
       
   685             aSnapIds.Append( TConnMonId( iSnapIdCache[i] ) );
       
   686             }
       
   687         }
       
   688 
       
   689     LOGEXITFN1("CConnMonCommsDatCache::GetAvailableSnaps()", err)
       
   690     return err;
       
   691     }
       
   692 
       
   693 // ---------------------------------------------------------------------------
       
   694 // Constructor
       
   695 // ---------------------------------------------------------------------------
       
   696 //
       
   697 CConnMonCommsDatCache::CConnMonCommsDatCache()
       
   698     {
       
   699     //LOGENTRFN("CConnMonCommsDatCache::CConnMonCommsDatCache()")
       
   700     //LOGEXITFN("CConnMonCommsDatCache::CConnMonCommsDatCache()")
       
   701     }
       
   702 
       
   703 // ---------------------------------------------------------------------------
       
   704 // 2nd phase constructor
       
   705 // ---------------------------------------------------------------------------
       
   706 //
       
   707 void CConnMonCommsDatCache::ConstructL()
       
   708     {
       
   709     //LOGENTRFN("CConnMonCommsDatCache::ConstructL()")
       
   710 
       
   711     iIap = NULL;
       
   712     iInitStatus = EConnMonCacheInitNotStarted;
       
   713     iVirtualIapCount = 0;
       
   714     iWlanSupportEnabled = EFalse; // Set in Init()-method
       
   715 
       
   716     iIapsChanged = EFalse;
       
   717     iSnapsChanged = EFalse;
       
   718     iVirtualIapsChanged = EFalse;
       
   719 
       
   720     iIapRecordTableId = KCDTIdIAPRecord;
       
   721     iSnapRecordTableId = 0;     // Read from CommsDat when needed for first time
       
   722     iVirtualRecordTableId = 0;  // Read from CommsDat when needed for first time
       
   723 
       
   724     iIapCache = new( ELeave ) RArray<TConnMonIapEntry>();
       
   725     iSnapCache = new( ELeave ) RArray<TConnMonSnapEntry>();
       
   726     iVirtualIapCache = new( ELeave ) RArray<TConnMonVirtualIapEntry>();
       
   727 
       
   728     //LOGEXITFN("CConnMonCommsDatCache::ConstructL()")
       
   729     }
       
   730 
       
   731 // ---------------------------------------------------------------------------
       
   732 // Reads all relevant CommsDat information to cache and initializes the SNAP
       
   733 // and virtual IAP table IDs.
       
   734 // ---------------------------------------------------------------------------
       
   735 //
       
   736 void CConnMonCommsDatCache::InitCommsDatCacheL()
       
   737     {
       
   738     //LOGENTRFN("CConnMonCommsDatCache::InitCommsDatCacheL()")
       
   739 
       
   740     CMDBSession* db = CMDBSession::NewLC( CMDBSession::LatestVersion() );
       
   741     db->SetAttributeMask( ECDHidden | ECDProtectedWrite );
       
   742 
       
   743     // Find out the table IDs for CCDDataMobilitySelectionPolicyRecord and
       
   744     // CCDVirtualIAPNextLayerRecord, only need to do this once.
       
   745     iVirtualRecordTableId = CCDVirtualIAPNextLayerRecord::TableIdL( *db );
       
   746     iSnapRecordTableId = CCDDataMobilitySelectionPolicyRecord::TableIdL( *db );
       
   747 
       
   748     LOGIT("InitCommsDatCacheL: reading commsdat tables")
       
   749     RefreshCommsDatIapCacheL( *db );
       
   750     RefreshCommsDatSnapCacheL( *db );
       
   751     RefreshCommsDatVirtualIapCacheL( *db );
       
   752 
       
   753     CleanupStack::PopAndDestroy( db );
       
   754 
       
   755     //LOGEXITFN("CConnMonCommsDatCache::InitCommsDatCacheL()")
       
   756     }
       
   757 
       
   758 // ---------------------------------------------------------------------------
       
   759 // Reads all IAP information from CommsDat and updates the cache if necessary.
       
   760 // ---------------------------------------------------------------------------
       
   761 //
       
   762 TBool CConnMonCommsDatCache::RefreshCommsDatIapCacheL( CMDBSession& aDb )
       
   763     {
       
   764     LOGENTRFN("CConnMonCommsDatCache::RefreshCommsDatIapCacheL()")
       
   765 
       
   766     // Will only leave if device runs out of memory or LoadL fails on IAP
       
   767     // record set. This will result in an empty IAP cache and thus no IAP
       
   768     // will be reported available through ConnMon API.
       
   769 
       
   770     RArray<TUint> currentWlanIapIds;
       
   771     CleanupClosePushL( currentWlanIapIds );
       
   772 
       
   773     RArray<TConnMonIapEntry>* currentIapData;
       
   774     if ( iInitStatus == EConnMonCacheInitCompleted )
       
   775         {
       
   776         // Array to read current CommsDat info into.
       
   777         currentIapData = new( ELeave ) RArray<TConnMonIapEntry>; // Heap used by design
       
   778         CleanupClosePushL( *currentIapData );
       
   779         }
       
   780     else
       
   781         {
       
   782         // Init-phase, read current CommsDat info directly into cache array,
       
   783         // since it is still empty. Then stop (don't send any events).
       
   784         iWlanIapIdCache.Reset();
       
   785         currentIapData = iIapCache;
       
   786         }
       
   787     currentIapData->Reset();
       
   788 
       
   789     ReadCommsDatIapTableL( aDb, *currentIapData, currentWlanIapIds );
       
   790 
       
   791     if ( iInitStatus != EConnMonCacheInitCompleted )
       
   792         {
       
   793         // This is Init pass. CommsDat has been read and stored in cache. return now.
       
   794         // Note, currentIapData not in cleanup stack
       
   795 
       
   796         // If no WLAN, this will just be an empty array
       
   797         DeepCopy( currentWlanIapIds, iWlanIapIdCache );
       
   798         CleanupStack::Pop( &currentWlanIapIds );
       
   799         currentWlanIapIds.Close();
       
   800 
       
   801         iIapsChanged = ETrue;
       
   802         LOGEXITFN1("CConnMonCommsDatCache::RefreshCommsDatIapCache()", iIapsChanged)
       
   803         return iIapsChanged;
       
   804         }
       
   805 
       
   806     CleanupStack::Pop( currentIapData );
       
   807     iIapsChanged = EFalse;
       
   808 
       
   809     // WLAN IAPs are most likely to change. Check those first for changes.
       
   810     if ( iWlanSupportEnabled )
       
   811         {
       
   812         iIapsChanged = CompareSortedArrays( currentWlanIapIds, iWlanIapIdCache );
       
   813         if ( iIapsChanged )
       
   814             {
       
   815             if ( iIap )
       
   816                 {
       
   817                 iIap->EnableWlanScan(); // Important
       
   818                 }
       
   819             DeepCopy( currentWlanIapIds, iWlanIapIdCache );
       
   820             }
       
   821         }
       
   822     CleanupStack::Pop( &currentWlanIapIds );
       
   823     currentWlanIapIds.Close();
       
   824 
       
   825     // If WLAN IAPs didn't change, check the rest of the IAPs for changes.
       
   826     if ( !iIapsChanged )
       
   827         {
       
   828         iIapsChanged = CompareSortedArrays( *currentIapData, *iIapCache );
       
   829         }
       
   830 
       
   831     // Delete the obsolete IAP cache table. Either the new table that was just
       
   832     // read, or the old table if the new one is different.
       
   833     if ( iIapsChanged )
       
   834         {
       
   835         iIapCache->Close();
       
   836         delete iIapCache;
       
   837         iIapCache = currentIapData;
       
   838         LOGIT("RefreshCommsDatIapCacheL: updated IAP cache")
       
   839         }
       
   840     else
       
   841         {
       
   842         currentIapData->Close();
       
   843         delete currentIapData;
       
   844         currentIapData = NULL;
       
   845         LOGIT("RefreshCommsDatIapCacheL: IAP cache did not change")
       
   846         }
       
   847 
       
   848     LOGEXITFN1("CConnMonCommsDatCache::RefreshCommsDatIapCacheL()", iIapsChanged)
       
   849     return iIapsChanged;
       
   850     }
       
   851 
       
   852 // ---------------------------------------------------------------------------
       
   853 // Reads all IAP table information from CommsDat into an array.
       
   854 // ---------------------------------------------------------------------------
       
   855 //
       
   856 void CConnMonCommsDatCache::ReadCommsDatIapTableL(
       
   857         CMDBSession& aDb,
       
   858         RArray<TConnMonIapEntry>& aCurrentIapData,
       
   859         RArray<TUint>& aCurrentWlanIapIds )
       
   860     {
       
   861     LOGENTRFN("CConnMonCommsDatCache::ReadCommsDatIapTableL()")
       
   862 
       
   863     // Explicitly build a TLinearOrder<class>. Used as parameter to RArray::InsertInOrder().
       
   864     TLinearOrder<TConnMonIapEntry> iapEntryOrderingLogic( TConnMonIapEntry::Compare );
       
   865 
       
   866     CMDBRecordSet<CCDIAPRecord>* ptrIapRecordSet = new( ELeave )
       
   867             CMDBRecordSet<CCDIAPRecord>( iIapRecordTableId );
       
   868     CleanupStack::PushL( ptrIapRecordSet );
       
   869     ptrIapRecordSet->LoadL( aDb );
       
   870 
       
   871     // Check LAN bearer table for WLAN bearer entries and store results in array.
       
   872     // This information is used to separate LAN and WLAN IAPs from each other.
       
   873     RArray<TLanBearerEntry> lanBearerTableCache;
       
   874     CleanupClosePushL( lanBearerTableCache );
       
   875     TRAPD( leaveCode, ReadCommsDatLanBearerTableL( aDb, lanBearerTableCache ) );
       
   876     if ( leaveCode )
       
   877         {
       
   878         LOGIT1("ERROR reading LAN bearer table, LEAVE with <%d>", leaveCode)
       
   879         lanBearerTableCache.Reset();
       
   880         }
       
   881 
       
   882     iVirtualIapCount = 0;
       
   883     TInt iapRecordCount( ptrIapRecordSet->iRecords.Count() );
       
   884     LOGIT1("ReadCommsDatIapTableL: IAP record count %d (commsdat)", iapRecordCount)
       
   885 
       
   886     TUint iapId( 0 );
       
   887     TUint bearerType( 0 );
       
   888     TUint serviceType( 0 );
       
   889 
       
   890     for ( TInt i = 0; i < iapRecordCount; i++ )
       
   891         {
       
   892         TRAP( leaveCode, ReadCommsDatIapEntryL(
       
   893                 (CCDIAPRecord*)ptrIapRecordSet->iRecords[i],
       
   894                 lanBearerTableCache,
       
   895                 bearerType,
       
   896                 serviceType ) );
       
   897 
       
   898         if ( leaveCode )
       
   899             {
       
   900             // Skip this IAP and continue with next one
       
   901             LOGIT1("ERROR reading IAP entry, LEAVE with <%d>", leaveCode)
       
   902             break;
       
   903             }
       
   904 
       
   905         iapId = ptrIapRecordSet->iRecords[i]->RecordId();
       
   906 
       
   907         if ( serviceType == EConnMonCacheServiceTypeWlan && iWlanSupportEnabled )
       
   908             {
       
   909             // Add WLAN IAP ID to WLAN IAP cache
       
   910             TInt err = aCurrentWlanIapIds.InsertInOrder( iapId );
       
   911             if ( err )
       
   912                 {
       
   913                 LOGIT1("ERROR inserting WLAN IAP ID to WLAN cache <%d>", err)
       
   914                 serviceType = 0;
       
   915                 }
       
   916             }
       
   917 
       
   918         // Unknown IAP or error while reading it
       
   919         if ( !serviceType && !bearerType )
       
   920             {
       
   921             LOGIT1("WARNING, unknown IAP in CommsDat IAP table with id %d", iapId)
       
   922             iapId = 0; // ID to zero so this IAP will be ignored
       
   923             }
       
   924 
       
   925         if ( iapId )
       
   926             {
       
   927             // Adding IAP to cache
       
   928             TConnMonIapEntry iapEntry( iapId, bearerType, serviceType );
       
   929 
       
   930             TInt err = aCurrentIapData.InsertInOrder( iapEntry , iapEntryOrderingLogic );
       
   931             if ( err )
       
   932                 {
       
   933                 LOGIT1("ERROR inserting IAP to current IAP data <%d>", err)
       
   934                 }
       
   935             }
       
   936         }
       
   937 
       
   938     CleanupStack::Pop( &lanBearerTableCache );
       
   939     lanBearerTableCache.Close();
       
   940     CleanupStack::PopAndDestroy( ptrIapRecordSet );
       
   941     LOGIT1("ReadCommsDatIapTableL: IAP record count %d (cache)", aCurrentIapData.Count())
       
   942 
       
   943     LOGEXITFN("CConnMonCommsDatCache::ReadCommsDatIapTableL()")
       
   944     }
       
   945 
       
   946 // ---------------------------------------------------------------------------
       
   947 // Reads one record from IAP table and finds out the service and bearer types.
       
   948 // ---------------------------------------------------------------------------
       
   949 //
       
   950 void CConnMonCommsDatCache::ReadCommsDatIapEntryL(
       
   951         CCDIAPRecord* aIapEntry,
       
   952         RArray<TLanBearerEntry>& aLanBearerTableCache,
       
   953         TUint& aBearerType,
       
   954         TUint& aServiceType )
       
   955     {
       
   956     //LOGENTRFN("CConnMonCommsDatCache::ReadCommsDatIapEntryL()")
       
   957 
       
   958     aBearerType = 0;
       
   959     aServiceType = 0;
       
   960     TBuf<KMaxTextLength> bearerTypeName( aIapEntry->iBearerType.GetL() );
       
   961     TBuf<KMaxTextLength> serviceTypeName( aIapEntry->iServiceType.GetL() );
       
   962 
       
   963     if ( serviceTypeName == TPtrC( KCDTypeNameOutgoingWCDMA ) ||
       
   964             serviceTypeName == TPtrC( KCDTypeNameIncomingWCDMA ) )
       
   965         {
       
   966         aServiceType = EConnMonCacheServiceTypeGprs; // GPRS IAP
       
   967         }
       
   968     else if ( serviceTypeName == TPtrC( KCDTypeNameLANService ) )
       
   969         {
       
   970         // LAN or WLAN IAP
       
   971         TUint32 bearerId( aIapEntry->iBearer );
       
   972         if ( bearerTypeName == TPtrC( KCDTypeNameLANBearer ) &&
       
   973                 HasWlanBearer( bearerId, aLanBearerTableCache ) )
       
   974             {
       
   975             aServiceType = EConnMonCacheServiceTypeWlan; // WLAN IAP
       
   976             }
       
   977         else
       
   978             {
       
   979             aServiceType = EConnMonCacheServiceTypeLan; // LAN IAP
       
   980             }
       
   981         }
       
   982     else if ( ( serviceTypeName == TPtrC( KCDTypeNameDialOutISP ) ) ||
       
   983             ( serviceTypeName == TPtrC( KCDTypeNameDialInISP ) ) )
       
   984         {
       
   985         aServiceType = EConnMonCacheServiceTypeCsd; // CSD IAP
       
   986         }
       
   987 
       
   988     if ( bearerTypeName == TPtrC( KCDTypeNameVirtualBearer ) )
       
   989         {
       
   990         iVirtualIapCount++;
       
   991         aBearerType = EConnMonCacheBearerTypeVirtual; // Virtual IAP
       
   992         }
       
   993 
       
   994     //LOGEXITFN("CConnMonCommsDatCache::ReadCommsDatIapEntryL()")
       
   995     }
       
   996 
       
   997 // ---------------------------------------------------------------------------
       
   998 // Reads all records from the LAN bearer table and checks if they are WLAN
       
   999 // bearer type. Results are stored in an array.
       
  1000 // ---------------------------------------------------------------------------
       
  1001 //
       
  1002 void CConnMonCommsDatCache::ReadCommsDatLanBearerTableL(
       
  1003         CMDBSession& aDb,
       
  1004         RArray<TLanBearerEntry>& aLanBearerTableCache )
       
  1005     {
       
  1006     LOGENTRFN("CConnMonCommsDatCache::ReadCommsDatLanBearerTableL()")
       
  1007 
       
  1008     CMDBRecordSet<CCDLANBearerRecord>* ptrLanBearerRecordSet = new( ELeave )
       
  1009             CMDBRecordSet<CCDLANBearerRecord>( KCDTIdLANBearerRecord );
       
  1010     CleanupStack::PushL( ptrLanBearerRecordSet );
       
  1011     ptrLanBearerRecordSet->LoadL( aDb );
       
  1012 
       
  1013     TInt lanBearerRecordCount( ptrLanBearerRecordSet->iRecords.Count() );
       
  1014     for ( TInt i = 0; i < lanBearerRecordCount; i++ )
       
  1015         {
       
  1016         TLanBearerEntry lanBearerEntry;
       
  1017         lanBearerEntry.iId = ptrLanBearerRecordSet->iRecords[i]->RecordId();
       
  1018 
       
  1019         TBuf<KMaxTextLength> bearerRecordName(
       
  1020                 ( (CCDLANBearerRecord*)ptrLanBearerRecordSet->iRecords[i] )->iRecordName.GetL() );
       
  1021 
       
  1022         if ( bearerRecordName == TPtrC( KWlanBearerRecordName ) )
       
  1023             {
       
  1024             lanBearerEntry.iWlanBearer = ETrue;
       
  1025             }
       
  1026         else
       
  1027             {
       
  1028             lanBearerEntry.iWlanBearer = EFalse;
       
  1029             }
       
  1030         aLanBearerTableCache.Append( lanBearerEntry );
       
  1031         }
       
  1032     CleanupStack::PopAndDestroy( ptrLanBearerRecordSet );
       
  1033     LOGIT2("LAN bearer record count %d/%d", aLanBearerTableCache.Count(), lanBearerRecordCount)
       
  1034 
       
  1035     LOGEXITFN("CConnMonCommsDatCache::ReadCommsDatLanBearerTableL()")
       
  1036     }
       
  1037 
       
  1038 // ---------------------------------------------------------------------------
       
  1039 // Reads all SNAP information from CommsDat and updates the cache if necessary.
       
  1040 // ---------------------------------------------------------------------------
       
  1041 //
       
  1042 TBool CConnMonCommsDatCache::RefreshCommsDatSnapCacheL( CMDBSession& aDb )
       
  1043     {
       
  1044     LOGENTRFN("CConnMonCommsDatCache::RefreshCommsDatSnapCacheL()")
       
  1045 
       
  1046     RArray<TConnMonSnapEntry>* currentSnapData;
       
  1047     if ( iInitStatus == EConnMonCacheInitCompleted )
       
  1048         {
       
  1049         // Array to read current CommsDat info into.
       
  1050         currentSnapData = new( ELeave ) RArray<TConnMonSnapEntry>; // Heap used by design
       
  1051         CleanupClosePushL( *currentSnapData );
       
  1052         }
       
  1053     else
       
  1054         {
       
  1055         // Init phase. Read CommsDat and store to cache. Then stop. (no events)
       
  1056         currentSnapData = iSnapCache; // Cache is still empty at init-phase.
       
  1057         }
       
  1058     currentSnapData->Reset();
       
  1059 
       
  1060     ReadCommsDatSnapTableL( aDb, *currentSnapData );
       
  1061 
       
  1062     if ( iInitStatus != EConnMonCacheInitCompleted )
       
  1063         {
       
  1064         // This is Init pass. CommsDat SNAPs have been read and stored in cache. return now.
       
  1065         // Note, currentSnapData not in cleanup stack
       
  1066         iSnapsChanged = ETrue;
       
  1067         LOGEXITFN1("CConnMonCommsDatCache::RefreshCommsDatSnapCache()", iSnapsChanged)
       
  1068         return iSnapsChanged;
       
  1069         }
       
  1070 
       
  1071     CleanupStack::Pop( currentSnapData );
       
  1072     iSnapsChanged = CompareSortedArrays( *currentSnapData, *iSnapCache );
       
  1073 
       
  1074     // Delete the obsolete SNAP cache table. Either the new table that was just
       
  1075     // read, or the old table if the new one is different.
       
  1076     if ( iSnapsChanged )
       
  1077         {
       
  1078         iSnapCache->Close();
       
  1079         delete iSnapCache;
       
  1080         iSnapCache = currentSnapData;
       
  1081         LOGIT("RefreshCommsDatSnapCacheL: updated SNAP cache")
       
  1082         }
       
  1083     else
       
  1084         {
       
  1085         currentSnapData->Close();
       
  1086         delete currentSnapData;
       
  1087         currentSnapData = NULL;
       
  1088         }
       
  1089 
       
  1090     LOGEXITFN1("CConnMonCommsDatCache::RefreshCommsDatSnapCacheL()", iSnapsChanged)
       
  1091     return iSnapsChanged;
       
  1092     }
       
  1093 
       
  1094 // ---------------------------------------------------------------------------
       
  1095 // Reads all SNAP information from CommsDat to an array.
       
  1096 // ---------------------------------------------------------------------------
       
  1097 //
       
  1098 void CConnMonCommsDatCache::ReadCommsDatSnapTableL(
       
  1099         CommsDat::CMDBSession& aDb,
       
  1100         RArray<TConnMonSnapEntry>& aCurrentSnapData )
       
  1101     {
       
  1102     LOGENTRFN("CConnMonCommsDatCache::ReadCommsDatSnapTableL()")
       
  1103     // Explicitly build a TLinearOrder<class>. Used as parameter to RArray::InsertInOrder().
       
  1104     TLinearOrder<TConnMonSnapEntry> snapEntryOrderingLogic( TConnMonSnapEntry::Compare );
       
  1105 
       
  1106     CMDBRecordSet<CCDDataMobilitySelectionPolicyRecord>* ptrSnapRecordSet = new( ELeave )
       
  1107             CMDBRecordSet<CCDDataMobilitySelectionPolicyRecord>( iSnapRecordTableId );
       
  1108     CleanupStack::PushL( ptrSnapRecordSet );
       
  1109 
       
  1110     CCDDataMobilitySelectionPolicyRecord* ptrSnapRecord = new( ELeave )
       
  1111             CCDDataMobilitySelectionPolicyRecord( iSnapRecordTableId );
       
  1112     CleanupStack::PushL( ptrSnapRecord );
       
  1113 
       
  1114     ptrSnapRecordSet->LoadL( aDb );
       
  1115     TInt snapRecordCount( ptrSnapRecordSet->iRecords.Count() );
       
  1116     LOGIT1("ReadCommsDatSnapTableL: SNAP record count %d (commsdat)", snapRecordCount)
       
  1117 
       
  1118     TUint snapId( 0 );
       
  1119     TUint includedIapId( 0 );
       
  1120     TUint embeddedSnapId( 0 );
       
  1121     TInt tempSnapId( 0 );
       
  1122     TInt tempEmbeddedSnapId( 0 );
       
  1123 
       
  1124     for ( TInt i = 0; i < snapRecordCount; i++ )
       
  1125         {
       
  1126         ptrSnapRecord->SetElementId( ptrSnapRecordSet->iRecords[i]->ElementId() );
       
  1127         ptrSnapRecord->LoadL( aDb );
       
  1128 
       
  1129         // SNAP ID records in CCDDataMobilitySelectionPolicyRecord-table were changed
       
  1130         // from record links to TInt type, as part of new CommsInfra changes.
       
  1131         tempSnapId = ptrSnapRecord->iSNAP;
       
  1132         if ( tempSnapId < 0 )
       
  1133             {
       
  1134             tempSnapId = 0;
       
  1135             }
       
  1136         snapId = (TUint) tempSnapId;
       
  1137 
       
  1138         includedIapId = ( ptrSnapRecord->iIAP & KCDMaskShowRecordId ) >> KBitsInByte;
       
  1139 
       
  1140         tempEmbeddedSnapId = ptrSnapRecord->iEmbeddedSNAP;
       
  1141         if ( tempEmbeddedSnapId < 0 )
       
  1142             {
       
  1143             tempEmbeddedSnapId = 0;
       
  1144             }
       
  1145         embeddedSnapId = (TUint) tempEmbeddedSnapId;
       
  1146 
       
  1147         // Empty SNAPs are not included in cache
       
  1148         if ( includedIapId || embeddedSnapId )
       
  1149             {
       
  1150             TConnMonSnapEntry snapEntry( snapId, includedIapId, embeddedSnapId );
       
  1151             TInt err = aCurrentSnapData.InsertInOrder( snapEntry , snapEntryOrderingLogic );
       
  1152             if ( err )
       
  1153                 {
       
  1154                 LOGIT1("ERROR inserting SNAP record to current SNAP data <%d>", err)
       
  1155                 }
       
  1156             }
       
  1157         }
       
  1158     CleanupStack::PopAndDestroy( ptrSnapRecord );
       
  1159     CleanupStack::PopAndDestroy( ptrSnapRecordSet );
       
  1160     LOGIT1("ReadCommsDatSnapTableL: SNAP record count %d (cache)", aCurrentSnapData.Count())
       
  1161     LOGEXITFN("CConnMonCommsDatCache::ReadCommsDatSnapTableL()")
       
  1162     }
       
  1163 
       
  1164 // ---------------------------------------------------------------------------
       
  1165 // Reads all virtual IAP link information from CommsDat and updates the cache
       
  1166 // if necessary. CommsDat is not read if IAP table did not contain any virtual
       
  1167 // IAPs. Returns ETrue if cache information was changed, EFalse otherwise.
       
  1168 // ---------------------------------------------------------------------------
       
  1169 //
       
  1170 TBool CConnMonCommsDatCache::RefreshCommsDatVirtualIapCacheL( CMDBSession& aDb )
       
  1171     {
       
  1172     LOGENTRFN("CConnMonCommsDatCache::RefreshCommsDatVirtualIapCacheL()")
       
  1173 
       
  1174     RArray<TConnMonVirtualIapEntry>* currentVirtualIapData;
       
  1175     if ( iInitStatus == EConnMonCacheInitCompleted )
       
  1176         {
       
  1177         // Array to read current CommsDat info into.
       
  1178         currentVirtualIapData = new( ELeave ) RArray<TConnMonVirtualIapEntry>; // Heap used by design
       
  1179         CleanupClosePushL( *currentVirtualIapData );
       
  1180         }
       
  1181     else
       
  1182         {
       
  1183         // Init-phase, read current CommsDat info directly into cache array,
       
  1184         // since it is still empty. Then stop (don't send any events.)
       
  1185         currentVirtualIapData = iVirtualIapCache;
       
  1186         }
       
  1187     currentVirtualIapData->Reset();
       
  1188 
       
  1189     // If there is no virtual IAPs, there is no need to read virtual IAP link
       
  1190     // information, and virtual IAP cache will be left empty.
       
  1191     if ( iVirtualIapCount )
       
  1192         {
       
  1193         TRAPD( leaveCode, ReadCommsDatVirtualIapTableL( aDb, *currentVirtualIapData ) );
       
  1194         if ( leaveCode )
       
  1195             {
       
  1196             LOGIT1("ERROR reading virtual IAP table, LEAVE with <%d>", leaveCode)
       
  1197             }
       
  1198         }
       
  1199     else
       
  1200         {
       
  1201         LOGIT("RefreshCommsDatVirtualIapCacheL: no virtual IAPs, skipping")
       
  1202         }
       
  1203 
       
  1204     if ( iInitStatus != EConnMonCacheInitCompleted )
       
  1205         {
       
  1206         // This is Init pass. CommsDat has been read and stored in cache. return now.
       
  1207         // Note, currentVirtualIapData not in cleanup stack
       
  1208         iVirtualIapsChanged = ETrue;
       
  1209         LOGEXITFN1("CConnMonCommsDatCache::RefreshCommsDatVirtualIapCacheL()", iVirtualIapsChanged)
       
  1210         return iVirtualIapsChanged;
       
  1211         }
       
  1212 
       
  1213     CleanupStack::Pop( currentVirtualIapData );
       
  1214     iVirtualIapsChanged = CompareSortedArrays( *currentVirtualIapData, *iVirtualIapCache );
       
  1215 
       
  1216     // Delete the obsolete virtual IAP cache table. Either the new table that
       
  1217     // was just read, or the old table if the new one is different.
       
  1218     if ( iVirtualIapsChanged )
       
  1219         {
       
  1220         iVirtualIapCache->Close();
       
  1221         delete iVirtualIapCache;
       
  1222         iVirtualIapCache = currentVirtualIapData;
       
  1223         LOGIT("RefreshCommsDatVirtualIapCacheL: updated virtual IAP cache")
       
  1224         }
       
  1225     else
       
  1226         {
       
  1227         currentVirtualIapData->Close();
       
  1228         delete currentVirtualIapData;
       
  1229         currentVirtualIapData = NULL;
       
  1230         }
       
  1231 
       
  1232     LOGEXITFN1("CConnMonCommsDatCache::RefreshCommsDatVirtualIapCacheL()", iVirtualIapsChanged)
       
  1233     return iVirtualIapsChanged;
       
  1234     }
       
  1235 
       
  1236 // ---------------------------------------------------------------------------
       
  1237 // Reads all virtual IAP link information from CommsDat to an array.
       
  1238 // ---------------------------------------------------------------------------
       
  1239 //
       
  1240 void CConnMonCommsDatCache::ReadCommsDatVirtualIapTableL(
       
  1241         CommsDat::CMDBSession& aDb,
       
  1242         RArray<TConnMonVirtualIapEntry>& aCurrentVirtualIapData )
       
  1243     {
       
  1244     LOGENTRFN("CConnMonCommsDatCache::ReadCommsDatVirtualIapTableL()")
       
  1245 
       
  1246     // Explicitly build a TLinearOrder<class>. Used as parameter to RArray::InsertInOrder().
       
  1247     TLinearOrder<TConnMonVirtualIapEntry> virtualEntryOrderingLogic(
       
  1248             TConnMonVirtualIapEntry::Compare );
       
  1249 
       
  1250     CMDBRecordSet<CCDVirtualIAPNextLayerRecord>* ptrVirtualRecordSet = new( ELeave )
       
  1251             CMDBRecordSet<CCDVirtualIAPNextLayerRecord>( iVirtualRecordTableId );
       
  1252     CleanupStack::PushL( ptrVirtualRecordSet );
       
  1253 
       
  1254     CCDVirtualIAPNextLayerRecord* ptrVirtualRecord = new( ELeave )
       
  1255             CCDVirtualIAPNextLayerRecord( iVirtualRecordTableId );
       
  1256     CleanupStack::PushL( ptrVirtualRecord );
       
  1257 
       
  1258     // Load and loop through the records.
       
  1259     ptrVirtualRecordSet->LoadL( aDb );
       
  1260     TInt virtualRecordCount( ptrVirtualRecordSet->iRecords.Count() );
       
  1261     LOGIT1("ReadCommsDatVirtualIapTableL: virtual record count %d (commsdat)", virtualRecordCount)
       
  1262 
       
  1263     TUint iapId( 0 );
       
  1264     TUint nextLayerSnap( 0 );
       
  1265     TUint nextLayerIap( 0 );
       
  1266 
       
  1267     for ( TInt i = 0; i < virtualRecordCount; i++ )
       
  1268         {
       
  1269         ptrVirtualRecord->SetElementId( ptrVirtualRecordSet->iRecords[i]->ElementId() );
       
  1270         ptrVirtualRecord->LoadL( aDb );
       
  1271 
       
  1272         iapId = ptrVirtualRecord->iIAP;
       
  1273         nextLayerSnap = ptrVirtualRecord->iNextLayerSNAP;
       
  1274         nextLayerIap = ptrVirtualRecord->iNextLayerIAP;
       
  1275 
       
  1276         // Either iNextLayerSNAP or iNextLayerIAP must be NULL. Only 1 link.
       
  1277         if ( iapId && ( ( nextLayerSnap && !nextLayerIap ) ||
       
  1278                 ( nextLayerIap && !nextLayerSnap ) ) )
       
  1279             {
       
  1280             TConnMonVirtualIapEntry virtualEntry( iapId, nextLayerIap, nextLayerSnap );
       
  1281             TInt err = aCurrentVirtualIapData.InsertInOrder(
       
  1282                     virtualEntry,
       
  1283                     virtualEntryOrderingLogic );
       
  1284             if ( err )
       
  1285                 {
       
  1286                 LOGIT1("ERROR inserting virtual IAP link record to cache <%d>", err)
       
  1287                 }
       
  1288             }
       
  1289         else
       
  1290             {
       
  1291             LOGIT2("WARNING, invalid virtual record, iap: %d, snap: %d", nextLayerIap, nextLayerSnap )
       
  1292             }
       
  1293         }
       
  1294     CleanupStack::PopAndDestroy( ptrVirtualRecord );
       
  1295     CleanupStack::PopAndDestroy( ptrVirtualRecordSet );
       
  1296 
       
  1297     LOGIT1("ReadCommsDatVirtualIapTableL: virtual record count %d (cache)", aCurrentVirtualIapData.Count())
       
  1298     LOGEXITFN("CConnMonCommsDatCache::ReadCommsDatVirtualIapTableL()")
       
  1299     }
       
  1300 
       
  1301 // ---------------------------------------------------------------------------
       
  1302 // Compares two sorted RArray<TUint> arrays. Returns ETrue if the arrays are
       
  1303 // not identical.
       
  1304 // ---------------------------------------------------------------------------
       
  1305 //
       
  1306 TBool CConnMonCommsDatCache::CompareSortedArrays(
       
  1307         const RArray<TUint>& aFirstArray,
       
  1308         const RArray<TUint>& aSecondArray )
       
  1309     {
       
  1310     //LOGENTRFN("CConnMonCommsDatCache::CompareSortedArrays()")
       
  1311     TBool arraysDiffer( EFalse );
       
  1312 
       
  1313     const TInt firstCount = aFirstArray.Count();
       
  1314     if ( firstCount != aSecondArray.Count() )
       
  1315         {
       
  1316         arraysDiffer = ETrue;
       
  1317         }
       
  1318     else
       
  1319         {
       
  1320         for ( TInt i = 0; i < firstCount; i++ )
       
  1321             {
       
  1322             if ( aFirstArray[i] != aSecondArray[i] )
       
  1323                 {
       
  1324                 arraysDiffer = ETrue;
       
  1325                 break; // No need to continue
       
  1326                 }
       
  1327             }
       
  1328         }
       
  1329 
       
  1330     //LOGEXITFN1("CConnMonCommsDatCache::CompareSortedArrays()", arraysDiffer)
       
  1331     return arraysDiffer;
       
  1332     }
       
  1333 
       
  1334 // ---------------------------------------------------------------------------
       
  1335 // Compares two sorted RArray<TConnMonIapEntry> arrays. Returns ETrue if the
       
  1336 // arrays are not identical.
       
  1337 // ---------------------------------------------------------------------------
       
  1338 //
       
  1339 TBool CConnMonCommsDatCache::CompareSortedArrays(
       
  1340         const RArray<TConnMonIapEntry>& aFirstArray,
       
  1341         const RArray<TConnMonIapEntry>& aSecondArray )
       
  1342     {
       
  1343     //LOGENTRFN("CConnMonCommsDatCache::CompareSortedArrays()")
       
  1344     TBool arraysDiffer( EFalse );
       
  1345 
       
  1346     const TInt firstCount = aFirstArray.Count();
       
  1347     if ( firstCount != aSecondArray.Count() )
       
  1348         {
       
  1349         arraysDiffer = ETrue;
       
  1350         }
       
  1351     else
       
  1352         {
       
  1353         for ( TInt i = 0; i < firstCount; i++ )
       
  1354             {
       
  1355             if ( !TConnMonIapEntry::Match( aFirstArray[i], aSecondArray[i] ) )
       
  1356                 {
       
  1357                 arraysDiffer = ETrue;
       
  1358                 break; // No need to continue
       
  1359                 }
       
  1360             }
       
  1361         }
       
  1362 
       
  1363     //LOGEXITFN1("CConnMonCommsDatCache::CompareSortedArrays()", arraysDiffer)
       
  1364     return arraysDiffer;
       
  1365     }
       
  1366 
       
  1367 // ---------------------------------------------------------------------------
       
  1368 // Compares two sorted RArray<TConnMonSnapEntry> arrays. Returns ETrue if the
       
  1369 // arrays are not identical.
       
  1370 // ---------------------------------------------------------------------------
       
  1371 //
       
  1372 TBool CConnMonCommsDatCache::CompareSortedArrays(
       
  1373         const RArray<TConnMonSnapEntry>& aFirstArray,
       
  1374         const RArray<TConnMonSnapEntry>& aSecondArray )
       
  1375     {
       
  1376     //LOGENTRFN("CConnMonCommsDatCache::CompareSortedArrays()")
       
  1377     TBool arraysDiffer( EFalse );
       
  1378 
       
  1379     const TInt firstCount = aFirstArray.Count();
       
  1380     if ( firstCount != aSecondArray.Count() )
       
  1381         {
       
  1382         arraysDiffer = ETrue;
       
  1383         }
       
  1384     else
       
  1385         {
       
  1386         for ( TInt i = 0; i < firstCount; i++ )
       
  1387             {
       
  1388             if ( !TConnMonSnapEntry::Match( aFirstArray[i], aSecondArray[i] ) )
       
  1389                 {
       
  1390                 arraysDiffer = ETrue;
       
  1391                 break; // No need to continue
       
  1392                 }
       
  1393             }
       
  1394         }
       
  1395 
       
  1396     //LOGEXITFN1("CConnMonCommsDatCache::CompareSortedArrays()", arraysDiffer)
       
  1397     return arraysDiffer;
       
  1398     }
       
  1399 
       
  1400 // ---------------------------------------------------------------------------
       
  1401 // Compares two sorted RArray<TConnMonVirtualIapEntry> arrays. Returns ETrue
       
  1402 // if the arrays are not identical.
       
  1403 // ---------------------------------------------------------------------------
       
  1404 //
       
  1405 TBool CConnMonCommsDatCache::CompareSortedArrays(
       
  1406         const RArray<TConnMonVirtualIapEntry>& aFirstArray,
       
  1407         const RArray<TConnMonVirtualIapEntry>& aSecondArray )
       
  1408     {
       
  1409     //LOGENTRFN("CConnMonCommsDatCache::CompareSortedArrays()")
       
  1410     TBool arraysDiffer( EFalse );
       
  1411 
       
  1412     const TInt firstCount = aFirstArray.Count();
       
  1413     if ( firstCount != aSecondArray.Count() )
       
  1414         {
       
  1415         arraysDiffer = ETrue;
       
  1416         }
       
  1417     else
       
  1418         {
       
  1419         for ( TInt i = 0; i < firstCount; i++ )
       
  1420             {
       
  1421             if ( !TConnMonVirtualIapEntry::Match( aFirstArray[i], aSecondArray[i] ) )
       
  1422                 {
       
  1423                 arraysDiffer = ETrue;
       
  1424                 break; // No need to continue
       
  1425                 }
       
  1426             }
       
  1427         }
       
  1428 
       
  1429     //LOGEXITFN1("CConnMonCommsDatCache::CompareSortedArrays()", arraysDiffer)
       
  1430     return arraysDiffer;
       
  1431     }
       
  1432 
       
  1433 // ---------------------------------------------------------------------------
       
  1434 // Copy new data into a RArray<TUint> array.
       
  1435 // ---------------------------------------------------------------------------
       
  1436 //
       
  1437 void CConnMonCommsDatCache::DeepCopy(
       
  1438         const RArray<TUint>& aSourceArray,
       
  1439         RArray<TUint>& aTargetArray )
       
  1440     {
       
  1441     //LOGENTRFN("CConnMonCommsDatCache::DeepCopy()")
       
  1442 
       
  1443     const TInt count = aSourceArray.Count();
       
  1444     aTargetArray.Reset();
       
  1445     TInt err = aTargetArray.Reserve( count );
       
  1446     if ( KErrNone == err )
       
  1447         {
       
  1448         for ( TInt i = 0; i < count; i++ )
       
  1449             {
       
  1450             aTargetArray.Append( aSourceArray[i] );
       
  1451             }
       
  1452         }
       
  1453 
       
  1454     //LOGEXITFN("CConnMonCommsDatCache::DeepCopy()")
       
  1455     }
       
  1456 
       
  1457 // ---------------------------------------------------------------------------
       
  1458 // Updates the index links for SNAPs and virtual IAPs.
       
  1459 // ---------------------------------------------------------------------------
       
  1460 //
       
  1461 void CConnMonCommsDatCache::UpdateSnapAndVirtualIapLinks()
       
  1462     {
       
  1463     LOGENTRFN("CConnMonCommsDatCache::UpdateSnapAndVirtualIapLinks()")
       
  1464 
       
  1465     TInt count = iSnapCache->Count();
       
  1466     for ( TInt i = 0; i < count; i++ )
       
  1467         {
       
  1468         TConnMonSnapEntry* pSnap = &(*iSnapCache)[i];
       
  1469         if ( pSnap->iNextLayerIapId )
       
  1470             {
       
  1471             pSnap->iNextLayerIndex = FindIapIndex( pSnap->iNextLayerIapId );
       
  1472             }
       
  1473         else if ( pSnap->iNextLayerSnapId )
       
  1474             {
       
  1475             pSnap->iNextLayerIndex = FindSnapIndex( pSnap->iNextLayerSnapId );
       
  1476             }
       
  1477         }
       
  1478 
       
  1479     count = iIapCache->Count();
       
  1480     for ( TInt i = 0; i < count; i++ )
       
  1481         {
       
  1482         TConnMonIapEntry* pIap = &(*iIapCache)[i];
       
  1483         // Only virtual IAPs can have links
       
  1484         if ( pIap->iBearerType == EConnMonCacheBearerTypeVirtual )
       
  1485             {
       
  1486             TInt index = iVirtualIapCache->FindInOrder<TInt>(
       
  1487                     pIap->iId,
       
  1488                     TConnMonVirtualIapEntry::FindCompare );
       
  1489 
       
  1490             if ( index < 0)
       
  1491                 {
       
  1492                 pIap->iNextLayerIapId = 0;
       
  1493                 pIap->iNextLayerSnapId = 0;
       
  1494                 pIap->iNextLayerIndex = KErrNotFound;
       
  1495                 }
       
  1496             else
       
  1497                 {
       
  1498                 pIap->iNextLayerIapId = (*iVirtualIapCache)[index].iNextLayerIapId;
       
  1499                 pIap->iNextLayerSnapId = (*iVirtualIapCache)[index].iNextLayerSnapId;
       
  1500 
       
  1501                 // Either iNextLayerIapId or iNextLayerSnapId is 0. (already checked)
       
  1502                 // Link to SNAP is more likely than link to IAP
       
  1503                 if ( pIap->iNextLayerSnapId )
       
  1504                     {
       
  1505                     // Returns KErrNotFound if not found
       
  1506                     pIap->iNextLayerIndex = FindSnapIndex( pIap->iNextLayerSnapId );
       
  1507                     }
       
  1508                 else if ( pIap->iNextLayerIapId )
       
  1509                     {
       
  1510                     // Returns KErrNotFound if not found
       
  1511                     pIap->iNextLayerIndex = FindIapIndex( pIap->iNextLayerIapId );
       
  1512                     }
       
  1513                 }
       
  1514             }
       
  1515         }
       
  1516 
       
  1517     LOGEXITFN("CConnMonCommsDatCache::UpdateSnapAndVirtualIapLinks()")
       
  1518     }
       
  1519 
       
  1520 // ---------------------------------------------------------------------------
       
  1521 // Resets the availability status for all SNAPs and IAPs. SNAPs and virtual
       
  1522 // IAPs are set to unknown, because their availability depends on real IAPs
       
  1523 // and needs to be solved using recursive algorithms. Real IAPs are set to
       
  1524 // unavailable. The next step should be to find the real IAPs that are
       
  1525 // available.
       
  1526 // ---------------------------------------------------------------------------
       
  1527 //
       
  1528 void CConnMonCommsDatCache::ResetAllAvailabilityInfo()
       
  1529     {
       
  1530     //LOGENTRFN("CConnMonCommsDatCache::ResetAllAvailabilityInfo()")
       
  1531 
       
  1532     TInt count = iIapCache->Count();
       
  1533     for ( TInt i = 0; i < count; i++ )
       
  1534         {
       
  1535         if ( (*iIapCache)[i].iBearerType == EConnMonCacheBearerTypeVirtual )
       
  1536             {
       
  1537             (*iIapCache)[i].iAvailability = EConnMonAvailabilityUnknown;
       
  1538             }
       
  1539         else
       
  1540             {
       
  1541             (*iIapCache)[i].iAvailability = EConnMonAvailabilityUnavailable;
       
  1542             }
       
  1543         }
       
  1544 
       
  1545     count = iSnapCache->Count();
       
  1546     for ( TInt i = 0; i < count; i++ )
       
  1547         {
       
  1548         (*iSnapCache)[i].iAvailability = EConnMonAvailabilityUnknown;
       
  1549         }
       
  1550 
       
  1551     //LOGEXITFN("CConnMonCommsDatCache::ResetAllAvailabilityInfo()")
       
  1552     }
       
  1553 
       
  1554 // ---------------------------------------------------------------------------
       
  1555 // Solve SNAP and virtual IAP availability. The results depend on real IAP
       
  1556 // availability, so those need to be set when this method is called.
       
  1557 // ---------------------------------------------------------------------------
       
  1558 //
       
  1559 void CConnMonCommsDatCache::SolveSnapAndVirtualIapAvailability()
       
  1560     {
       
  1561     LOGENTRFN("CConnMonCommsDatCache::SolveSnapAndVirtualIapAvailability()")
       
  1562 
       
  1563     TInt count = iSnapCache->Count();
       
  1564     for ( TInt i = 0; i < count; i++ )
       
  1565         {
       
  1566         // Check SNAP availability recursively at index i
       
  1567         CheckSnapAvailability( i );
       
  1568         }
       
  1569 
       
  1570     count = iIapCache->Count();
       
  1571     for ( TInt i = 0; i < count; i++ )
       
  1572         {
       
  1573         if ( (*iIapCache)[i].iBearerType == EConnMonCacheBearerTypeVirtual )
       
  1574             {
       
  1575             // Check IAP availability recursively at index i
       
  1576             CheckIapAvailability( i );
       
  1577             }
       
  1578         }
       
  1579 
       
  1580     LOGEXITFN("CConnMonCommsDatCache::SolveSnapAndVirtualIapAvailability()")
       
  1581     }
       
  1582 
       
  1583 // ---------------------------------------------------------------------------
       
  1584 // Create a EConnMonIapAvailabilityChange event and add it to the event
       
  1585 // queue to be sent to clients.
       
  1586 // ---------------------------------------------------------------------------
       
  1587 //
       
  1588 TInt CConnMonCommsDatCache::SendIapAvailabilityEvent()
       
  1589     {
       
  1590     LOGENTRFN("CConnMonCommsDatCache::SendIapAvailabilityEvent()")
       
  1591     TInt err( KErrNone );
       
  1592 
       
  1593     TInt iapCount = iIapIdCache.Count();
       
  1594     if ( iapCount > KConnMonMaxIAPCount )
       
  1595         {
       
  1596         // If too many IAPs available, clip the extras away from event.
       
  1597         LOGIT1("WARNING, too many IAPs (%d), all did not fit into event", iapCount)
       
  1598         iapCount = KConnMonMaxIAPCount;
       
  1599         }
       
  1600 
       
  1601     TEventInfo info;
       
  1602     info.Reset();
       
  1603     info.iEventType = EConnMonIapAvailabilityChange;
       
  1604     info.iConnectionId = EBearerIdAll;
       
  1605     info.iData = iapCount;
       
  1606 
       
  1607     // Create event data area. Leave left out intentionally, check for NULL instead
       
  1608     TConnMonIapInfo* eventIaps = new TConnMonIapInfo; // No (ELeave)
       
  1609     if ( !eventIaps )
       
  1610         {
       
  1611         err = KErrNoMemory;
       
  1612         }
       
  1613     else
       
  1614         {
       
  1615         eventIaps->iCount = iapCount;
       
  1616         TInt i = 0;
       
  1617         for ( ; i < iapCount; i++ )
       
  1618             {
       
  1619             eventIaps->iIap[i].iIapId = iIapIdCache[i];
       
  1620             }
       
  1621         for ( ; i < KConnMonMaxIAPCount; i++ )
       
  1622             {
       
  1623             eventIaps->iIap[i].iIapId = 0;
       
  1624             }
       
  1625 
       
  1626         // EventQueue will finally destroy the memory area pointed by eventIaps.
       
  1627         // However, if all the clients can't receive the event right away the
       
  1628         // event queue will keep it until the last client has received it.
       
  1629         iServer->EventQueue()->Add(
       
  1630                 info,
       
  1631                 reinterpret_cast<const TUint8*>( eventIaps ),
       
  1632                 sizeof( TConnMonIapInfo ) );
       
  1633         }
       
  1634 
       
  1635     LOGEXITFN1("CConnMonCommsDatCache::SendIapAvailabilityEvent()", err)
       
  1636     return err;
       
  1637     }
       
  1638 
       
  1639 // ---------------------------------------------------------------------------
       
  1640 // Create a EConnMonSNAPsAvailabilityChange event and add it to the event
       
  1641 // queue to be sent to clients.
       
  1642 // ---------------------------------------------------------------------------
       
  1643 //
       
  1644 TInt CConnMonCommsDatCache::SendSnapAvailabilityEvent()
       
  1645     {
       
  1646     LOGENTRFN("CConnMonCommsDatCache::SendSnapAvailabilityEvent()")
       
  1647     TInt err( KErrNone );
       
  1648 
       
  1649     TInt snapCount = iSnapIdCache.Count();
       
  1650 
       
  1651     TEventInfo info;
       
  1652     info.Reset();
       
  1653     info.iEventType = EConnMonSNAPsAvailabilityChange;
       
  1654     info.iConnectionId = EBearerIdAll;
       
  1655     info.iData = snapCount; // Total amount of available SNAPs
       
  1656 
       
  1657     if ( snapCount > KConnMonMaxSNAPsCount )
       
  1658         {
       
  1659         // If too many SNAPs available, clip the extras away from event.
       
  1660         LOGIT1("WARNING, too many SNAPs (%d), all did not fit into event", snapCount)
       
  1661         snapCount = KConnMonMaxSNAPsCount;
       
  1662         }
       
  1663 
       
  1664     // Create event data area. Leave left out intentionally, check for NULL instead
       
  1665     TConnMonSNAPInfo* eventSnaps = new TConnMonSNAPInfo; // No (ELeave)
       
  1666     if ( !eventSnaps )
       
  1667         {
       
  1668         err = KErrNoMemory;
       
  1669         }
       
  1670     else
       
  1671         {
       
  1672         eventSnaps->iCount = snapCount;
       
  1673         TInt i = 0;
       
  1674         for ( ; i < snapCount; i++ )
       
  1675             {
       
  1676             eventSnaps->iSNAP[i].iSNAPId = iSnapIdCache[i];
       
  1677             }
       
  1678         for ( ; i < KConnMonMaxSNAPsCount; i++ )
       
  1679             {
       
  1680             eventSnaps->iSNAP[i].iSNAPId = 0;
       
  1681             }
       
  1682 
       
  1683         // EventQueue will finally destroy the memory area pointed by eventSnaps.
       
  1684         // However, if all the clients can't receive the event right away the
       
  1685         // event queue will keep it until the last client has received it.
       
  1686         iServer->EventQueue()->Add(
       
  1687                 info,
       
  1688                 reinterpret_cast<const TUint8*>( eventSnaps ),
       
  1689                 sizeof( TConnMonSNAPInfo ) );
       
  1690         }
       
  1691 
       
  1692     LOGEXITFN1("CConnMonCommsDatCache::SendSnapAvailabilityEvent()", err)
       
  1693     return err;
       
  1694     }
       
  1695 
       
  1696 // ---------------------------------------------------------------------------
       
  1697 // Finds the index in cache for IAP with id aId. Returns KErrNotFound (-1) if
       
  1698 // no match is found.
       
  1699 // ---------------------------------------------------------------------------
       
  1700 //
       
  1701 TInt CConnMonCommsDatCache::FindIapIndex( const TUint aId )
       
  1702     {
       
  1703     TInt index = iIapCache->FindInOrder<TInt>( aId, TConnMonIapEntry::FindCompare );
       
  1704     return index;
       
  1705     }
       
  1706 
       
  1707 // ---------------------------------------------------------------------------
       
  1708 // Finds the first index in cache for SNAP with ID aId. Returns KErrNotFound
       
  1709 // (-1) if no match is found.
       
  1710 // The SNAP cache is sorted by ID, so the first index is found by traversing
       
  1711 // decrementally from the initial index returned by RArray's FindInOrder.
       
  1712 // ---------------------------------------------------------------------------
       
  1713 //
       
  1714 TInt CConnMonCommsDatCache::FindSnapIndex( const TUint aId )
       
  1715     {
       
  1716     TInt index  = iSnapCache->FindInOrder<TInt>( aId, TConnMonSnapEntry::FindCompare );
       
  1717     for ( ; index > 0; index-- )
       
  1718         {
       
  1719         if ( (*iSnapCache)[index-1].iId != aId )
       
  1720             {
       
  1721             return index;
       
  1722             }
       
  1723         }
       
  1724     return index;
       
  1725     }
       
  1726 
       
  1727 // ---------------------------------------------------------------------------
       
  1728 // Takes a SNAP cache index and reads the ID from that entry. Then adjusts the
       
  1729 // availability for each cache entry related to that ID.
       
  1730 // ---------------------------------------------------------------------------
       
  1731 //
       
  1732 void CConnMonCommsDatCache::SetSnapAvailabilityAtIndex( TUint aIndex, TInt aAvailability )
       
  1733     {
       
  1734     //LOGENTRFN("CConnMonCommsDatCache::SetSnapAvailabilityAtIndex()")
       
  1735 
       
  1736     TUint id = (*iSnapCache)[aIndex].iId;
       
  1737     (*iSnapCache)[aIndex].iAvailability = aAvailability;
       
  1738 
       
  1739     TInt count = iSnapCache->Count();
       
  1740     for ( TInt i = aIndex+1; i < count; i++ )
       
  1741         {
       
  1742         if ( (*iSnapCache)[i].iId != id )
       
  1743             {
       
  1744             return;
       
  1745             }
       
  1746         (*iSnapCache)[i].iAvailability = aAvailability;
       
  1747         }
       
  1748 
       
  1749     //LOGEXITFN("CConnMonCommsDatCache::SetSnapAvailabilityAtIndex()")
       
  1750     }
       
  1751 
       
  1752 // ---------------------------------------------------------------------------
       
  1753 // Check IAP availability by index. In case of virtual IAP, keeps checking
       
  1754 // recursively until something is found available or all link chains are
       
  1755 // checked.
       
  1756 // ---------------------------------------------------------------------------
       
  1757 //
       
  1758 TInt CConnMonCommsDatCache::CheckIapAvailability( TUint aIndex )
       
  1759     {
       
  1760     TConnMonIapEntry* pIap = &(*iIapCache)[aIndex];
       
  1761     TInt currentAvailability = pIap->iAvailability;
       
  1762     switch ( currentAvailability )
       
  1763         {
       
  1764         // Real IAPs should have availability status of either available or unavailable at this
       
  1765         // point. Unprocessed virtual IAPs and SNAPs should have availability status unknown.
       
  1766         //
       
  1767         case EConnMonAvailabilityProcessing: // Loop. Fallthrough intended
       
  1768         case EConnMonAvailabilityUnavailable:
       
  1769             return EConnMonAvailabilityUnavailable;
       
  1770         case EConnMonAvailabilityAvailable:
       
  1771             return EConnMonAvailabilityAvailable;
       
  1772         case EConnMonAvailabilityUnknown:
       
  1773             {
       
  1774             if ( pIap->iNextLayerIndex >= 0 )
       
  1775                 {
       
  1776                 // Set availability status to processing (to detect/prevent loops)
       
  1777                 pIap->iAvailability = EConnMonAvailabilityProcessing;
       
  1778                 if ( pIap->iNextLayerSnapId )
       
  1779                     {
       
  1780                     pIap->iAvailability = CheckSnapAvailability( pIap->iNextLayerIndex );
       
  1781                     }
       
  1782                 else
       
  1783                     {
       
  1784                     pIap->iAvailability = CheckIapAvailability( pIap->iNextLayerIndex );
       
  1785                     }
       
  1786                 }
       
  1787             else
       
  1788                 {
       
  1789                 // Virtual IAP that does not point anywhere
       
  1790                 pIap->iAvailability = EConnMonAvailabilityUnavailable;
       
  1791                 }
       
  1792             }
       
  1793             break;
       
  1794         default:
       
  1795             LOGIT1("ERROR, IAP entry contained invalid availability value: %d", currentAvailability)
       
  1796             return EConnMonAvailabilityUnavailable;
       
  1797         }
       
  1798     return pIap->iAvailability;
       
  1799     }
       
  1800 
       
  1801 // ---------------------------------------------------------------------------
       
  1802 // Check SNAP availability by index. Keeps checking recursively until something
       
  1803 // is found available inside or all contents of this SNAP have are checked.
       
  1804 // ---------------------------------------------------------------------------
       
  1805 //
       
  1806 TInt CConnMonCommsDatCache::CheckSnapAvailability( TUint aIndex )
       
  1807     {
       
  1808     TInt currentAvailability = (*iSnapCache)[aIndex].iAvailability;
       
  1809     switch ( currentAvailability )
       
  1810         {
       
  1811         case EConnMonAvailabilityProcessing: // Loop. Fallthrough intended
       
  1812         case EConnMonAvailabilityUnavailable:
       
  1813             return EConnMonAvailabilityUnavailable;
       
  1814         case EConnMonAvailabilityAvailable:
       
  1815             return EConnMonAvailabilityAvailable;
       
  1816         case EConnMonAvailabilityUnknown:
       
  1817             {
       
  1818             // Set availability status to processing (to detect/prevent loops)
       
  1819             SetSnapAvailabilityAtIndex( aIndex, EConnMonAvailabilityProcessing );
       
  1820 
       
  1821             const TUint id = (*iSnapCache)[aIndex].iId;
       
  1822             const TInt count = iSnapCache->Count();
       
  1823 
       
  1824             currentAvailability = EConnMonAvailabilityUnavailable;
       
  1825             for ( TInt i = aIndex; i < count; i++ )
       
  1826                 {
       
  1827                 if ( (*iSnapCache)[i].iId != id )
       
  1828                     {
       
  1829                     // This line belongs to next SNAP, finish here
       
  1830                     break;
       
  1831                     }
       
  1832                 TInt link = (*iSnapCache)[i].iNextLayerIndex;
       
  1833                 if ( link >= 0 )
       
  1834                     {
       
  1835                     if ( (*iSnapCache)[i].iNextLayerIapId )
       
  1836                         {
       
  1837                         currentAvailability = CheckIapAvailability( link );
       
  1838                         }
       
  1839                     else
       
  1840                         {
       
  1841                         currentAvailability = CheckSnapAvailability( link );
       
  1842                         }
       
  1843                     }
       
  1844                 if ( currentAvailability == EConnMonAvailabilityAvailable )
       
  1845                     {
       
  1846                     // Something inside this SNAP is available, no need to continue
       
  1847                     break;
       
  1848                     }
       
  1849                 }
       
  1850             // Set this SNAP as available (all lines in cache that belong to this SNAP)
       
  1851             SetSnapAvailabilityAtIndex( aIndex, currentAvailability );
       
  1852             }
       
  1853             break;
       
  1854         default:
       
  1855             LOGIT("ERROR, SNAP entry contained invalid availability value")
       
  1856             return EConnMonAvailabilityUnavailable;
       
  1857         }
       
  1858     return currentAvailability;
       
  1859     }
       
  1860 
       
  1861 // ---------------------------------------------------------------------------
       
  1862 // Updates the internal list of available IAP IDs and returns ETrue if it has
       
  1863 // changed.
       
  1864 // ---------------------------------------------------------------------------
       
  1865 //
       
  1866 TBool CConnMonCommsDatCache::UpdateAvailableIaps()
       
  1867     {
       
  1868     //LOGENTRFN("CConnMonCommsDatCache::UpdateAvailableIaps()")
       
  1869 
       
  1870     RArray<TUint> currentIapIds;
       
  1871 
       
  1872     // Read available IAP IDs from IAP cache
       
  1873     const TInt count = iIapCache->Count();
       
  1874     for ( TInt i = 0; i < count; i++ )
       
  1875         {
       
  1876         if ( (*iIapCache)[i].iAvailability == EConnMonAvailabilityAvailable )
       
  1877             {
       
  1878             TInt err = currentIapIds.InsertInOrder( (*iIapCache)[i].iId );
       
  1879             if ( KErrNone != err )
       
  1880                 {
       
  1881                 LOGIT1("ERROR inserting IAP ID to available IAPs cache <%d>", err)
       
  1882                 break;
       
  1883                 }
       
  1884             }
       
  1885         }
       
  1886 
       
  1887     // Check for changes
       
  1888     TBool arrayChanged = CompareSortedArrays( currentIapIds, iIapIdCache );
       
  1889     if ( arrayChanged )
       
  1890         {
       
  1891         LOGIT1("Available IAP count: %d (changed)", currentIapIds.Count())
       
  1892         DeepCopy( currentIapIds, iIapIdCache );
       
  1893         }
       
  1894     else
       
  1895         {
       
  1896         LOGIT1("Available IAP count: %d", currentIapIds.Count())
       
  1897         }
       
  1898     currentIapIds.Close();
       
  1899 
       
  1900     //LOGEXITFN1("CConnMonCommsDatCache::UpdateAvailableIaps()", arrayChanged)
       
  1901     return arrayChanged;
       
  1902     }
       
  1903 
       
  1904 // ---------------------------------------------------------------------------
       
  1905 // Updates the internal list of available SNAP IDs and returns ETrue if it has
       
  1906 // changed.
       
  1907 // ---------------------------------------------------------------------------
       
  1908 //
       
  1909 TBool CConnMonCommsDatCache::UpdateAvailableSnaps()
       
  1910     {
       
  1911     //LOGENTRFN("CConnMonCommsDatCache::UpdateAvailableSnaps()")
       
  1912 
       
  1913     TUint lastSnapId( 0 );
       
  1914     RArray<TUint> currentSnapIds;
       
  1915 
       
  1916     // Read available SNAP IDs from SNAP cache.
       
  1917     // If there is n items inside a SNAP, then SNAP cache will contain n entries for that SNAP
       
  1918     const TInt count = iSnapCache->Count();
       
  1919     for ( TInt i = 0; i < count; i++ )
       
  1920         {
       
  1921         TUint currentId = (*iSnapCache)[i].iId;
       
  1922         if ( currentId != lastSnapId )
       
  1923             {
       
  1924             lastSnapId = currentId;
       
  1925             if ( (*iSnapCache)[i].iAvailability == EConnMonAvailabilityAvailable )
       
  1926                 {
       
  1927                 TInt err = currentSnapIds.InsertInOrder( currentId );
       
  1928                 if ( KErrNone != err )
       
  1929                     {
       
  1930                     LOGIT1("ERROR inserting SNAP ID to available SNAPs cache <%d>", err)
       
  1931                     break;
       
  1932                     }
       
  1933                 }
       
  1934             }
       
  1935         }
       
  1936 
       
  1937     // Check for changes
       
  1938     TBool arrayChanged = CompareSortedArrays( currentSnapIds, iSnapIdCache );
       
  1939     if ( arrayChanged )
       
  1940         {
       
  1941         LOGIT1("Available SNAP count: %d (changed)", currentSnapIds.Count())
       
  1942         DeepCopy( currentSnapIds, iSnapIdCache );
       
  1943         }
       
  1944     else
       
  1945         {
       
  1946         LOGIT1("Available SNAP count: %d", currentSnapIds.Count())
       
  1947         }
       
  1948     currentSnapIds.Close();
       
  1949 
       
  1950     //LOGEXITFN1("CConnMonCommsDatCache::UpdateAvailableSnaps()", arrayChanged)
       
  1951     return arrayChanged;
       
  1952     }
       
  1953 
       
  1954 // ---------------------------------------------------------------------------
       
  1955 // Checks from 'LAN bearer table' array if given ID has a WLAN bearer
       
  1956 // ---------------------------------------------------------------------------
       
  1957 //
       
  1958 TBool CConnMonCommsDatCache::HasWlanBearer(
       
  1959         TUint32 aId,
       
  1960         RArray<TLanBearerEntry>& aLanBearerTableCache )
       
  1961     {
       
  1962     //LOGENTRFN("CConnMonCommsDatCache::HasWlanBearer()")
       
  1963     TBool wlanBearer( EFalse );
       
  1964 
       
  1965     for ( TInt i = 0; i < aLanBearerTableCache.Count(); i++ )
       
  1966         {
       
  1967         if ( aLanBearerTableCache[i].iId == aId )
       
  1968             {
       
  1969             wlanBearer = aLanBearerTableCache[i].iWlanBearer;
       
  1970             break;
       
  1971             }
       
  1972         }
       
  1973 
       
  1974     //LOGEXITFN1("CConnMonCommsDatCache::HasWlanBearer()", wlanBearer)
       
  1975     return wlanBearer;
       
  1976     }
       
  1977 
       
  1978 // ---------------------------------------------------------------------------
       
  1979 // Convert a bearer ID to (cache internal) service type
       
  1980 // ---------------------------------------------------------------------------
       
  1981 //
       
  1982 TInt CConnMonCommsDatCache::ConvertBearerIdToServiceType(
       
  1983         const TUint aBearerId,
       
  1984         TUint& aServiceType )
       
  1985     {
       
  1986     //LOGENTRFN("CConnMonCommsDatCache::ConvertBearerIdToServiceType()")
       
  1987     TInt err( KErrNone );
       
  1988 
       
  1989     switch ( aBearerId )
       
  1990         {
       
  1991         case EBearerIdGPRS:
       
  1992         case EBearerIdWCDMA:
       
  1993             aServiceType = EConnMonCacheServiceTypeGprs;
       
  1994             break;
       
  1995         case EBearerIdCSD:
       
  1996             aServiceType = EConnMonCacheServiceTypeCsd;
       
  1997             break;
       
  1998         case EBearerIdWLAN:
       
  1999             aServiceType = EConnMonCacheServiceTypeWlan;
       
  2000             break;
       
  2001         case EBearerIdLAN:
       
  2002             aServiceType = EConnMonCacheServiceTypeLan;
       
  2003             break;
       
  2004         default:
       
  2005             LOGIT1("WARNING, ConvertBearerIdToServiceType() called with bad bearerId: %d", aBearerId)
       
  2006             aServiceType = EConnMonCacheServiceTypeUnknown;
       
  2007             err = KErrNotFound;
       
  2008         }
       
  2009 
       
  2010     //LOGEXITFN1("CConnMonCommsDatCache::ConvertBearerIdToServiceType()", err)
       
  2011     return err;
       
  2012     }
       
  2013 
       
  2014 // ---------------------------------------------------------------------------
       
  2015 // Checks from CommsDat if WLAN background scans are enabled.
       
  2016 // ---------------------------------------------------------------------------
       
  2017 //
       
  2018 TBool CConnMonCommsDatCache::IsWlanBackgroundScanningEnabledL()
       
  2019     {
       
  2020     LOGENTRFN("CConnMonCommsDatCache::IsWlanBackgroundScanningEnabledL()")
       
  2021 
       
  2022     TBool bgScanEnabled( EFalse );
       
  2023     CMDBSession* db = CMDBSession::NewLC( CMDBSession::LatestVersion() );
       
  2024 
       
  2025     CCDWlanDeviceSettingsRecord* ptrWlanDevSettingsRecord = new( ELeave )
       
  2026     CCDWlanDeviceSettingsRecord( CCDWlanDeviceSettingsRecord::TableIdL( *db ) );
       
  2027     CleanupStack::PushL( ptrWlanDevSettingsRecord );
       
  2028 
       
  2029     ptrWlanDevSettingsRecord->iWlanDeviceSettingsType = KWlanUserSettings;
       
  2030     if( ptrWlanDevSettingsRecord->FindL( *db ) )
       
  2031         {
       
  2032         ptrWlanDevSettingsRecord->LoadL( *db );
       
  2033         if ( ptrWlanDevSettingsRecord->iBgScanInterval > 0 )
       
  2034             {
       
  2035             bgScanEnabled = ETrue;
       
  2036             LOGIT1("WLAN background scans are enabled, interval: %d", (TUint)ptrWlanDevSettingsRecord->iBgScanInterval)
       
  2037             }
       
  2038         }
       
  2039     CleanupStack::PopAndDestroy( ptrWlanDevSettingsRecord );
       
  2040     CleanupStack::PopAndDestroy( db );
       
  2041 
       
  2042     LOGEXITFN1("CConnMonCommsDatCache::IsWlanBackgroundScanningEnabledL()", bgScanEnabled)
       
  2043     return bgScanEnabled;
       
  2044     }
       
  2045 
       
  2046 // End-of-file