convergedconnectionhandler/cchserver/src/cchcommdbwatcher.cpp
branchRCL_3
changeset 21 f742655b05bf
parent 20 65a3ef1d5bd0
child 22 d38647835c2e
equal deleted inserted replaced
20:65a3ef1d5bd0 21:f742655b05bf
     1 /*
       
     2 * Copyright (c) 2007 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:  CCCHCommDbWatcher implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <cmdestination.h>
       
    21 #include <cmconnectionmethoddef.h>
       
    22 #include <cmpluginwlandef.h>
       
    23 #include <cmpluginvpndef.h>
       
    24 #include <centralrepository.h>
       
    25 #include <commsdat.h>
       
    26 
       
    27 #include "cchcommdbwatcher.h"
       
    28 #include "cchcommdbwatcherobserver.h"
       
    29 #include "cchlogger.h"
       
    30 #include "d32dbms.h"
       
    31 
       
    32 // EXTERNAL DATA STRUCTURES
       
    33 // None
       
    34 
       
    35 // EXTERNAL FUNCTION PROTOTYPES
       
    36 // None
       
    37 
       
    38 // CONSTANTS
       
    39 // None
       
    40 
       
    41 // MACROS
       
    42 // None
       
    43 
       
    44 // LOCAL CONSTANTS AND MACROS
       
    45 const TInt KDefaultGranularity = 5;
       
    46 const TInt KMaxCheckAttempts   = 3;
       
    47 // Repository for CommsDat
       
    48 const TUid KCDCommsRepositoryId = { 0xCCCCCC00 };
       
    49 
       
    50 // MODULE DATA STRUCTURES
       
    51 // None
       
    52 
       
    53 // LOCAL FUNCTION PROTOTYPES
       
    54 // None
       
    55 
       
    56 // FORWARD DECLARATIONS
       
    57 // None
       
    58 
       
    59 // ============================= LOCAL FUNCTIONS =============================
       
    60 
       
    61 // ============================ MEMBER FUNCTIONS =============================
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // CCCHCommDbWatcher::CCCHCommDbWatcher
       
    65 // C++ default constructor can NOT contain any code, that might leave.
       
    66 // ---------------------------------------------------------------------------
       
    67 //
       
    68 CCCHCommDbWatcher::CCCHCommDbWatcher( MCCHCommDbWatcherObserver& aObserver ) :
       
    69     CActive( CActive::EPriorityStandard ), 
       
    70     iObserver( aObserver ), 
       
    71     iTableId( KCDTIdIAPRecord )
       
    72     {
       
    73     CActiveScheduler::Add( this );
       
    74     }
       
    75 
       
    76 // ---------------------------------------------------------------------------
       
    77 // CCCHCommsDbWatcher::ConstructL
       
    78 // Symbian 2nd phase constructor can leave.
       
    79 // ---------------------------------------------------------------------------
       
    80 //
       
    81 void CCCHCommDbWatcher::ConstructL()
       
    82     {
       
    83     CCHLOGSTRING( "CCCHCommDbWatcher::ConstructL IN" );
       
    84     
       
    85     iRepository = CRepository::NewL( KCDCommsRepositoryId );
       
    86     iDestinations = RArray<TDestinationData>( KDefaultGranularity );
       
    87     
       
    88     InitializeDestination();
       
    89     TInt err( RequestNotifications() );
       
    90     User::LeaveIfError( err );
       
    91     CCHLOGSTRING( "CCCHCommDbWatcher::ConstructL OUT" );
       
    92     }
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 // CCCHCommsDbWatcher::NewL
       
    96 // Two-phased constructor.
       
    97 // ---------------------------------------------------------------------------
       
    98 //
       
    99 CCCHCommDbWatcher* CCCHCommDbWatcher::NewL( 
       
   100     MCCHCommDbWatcherObserver& aObserver )
       
   101     {
       
   102     CCCHCommDbWatcher* self = CCCHCommDbWatcher::NewLC( aObserver );
       
   103     CleanupStack::Pop( self );
       
   104     return self;
       
   105     }
       
   106 
       
   107 // ---------------------------------------------------------------------------
       
   108 // CCCHCommsDbWatcher::NewLC
       
   109 // Two-phased constructor.
       
   110 // ---------------------------------------------------------------------------
       
   111 //
       
   112 CCCHCommDbWatcher* CCCHCommDbWatcher::NewLC( 
       
   113     MCCHCommDbWatcherObserver& aObserver )
       
   114     {
       
   115     CCCHCommDbWatcher* self = new (ELeave) CCCHCommDbWatcher( aObserver );
       
   116     CleanupStack::PushL( self );
       
   117     self->ConstructL();
       
   118     return self;
       
   119     }
       
   120 
       
   121 // Destructor
       
   122 CCCHCommDbWatcher::~CCCHCommDbWatcher()
       
   123     {
       
   124     CCHLOGSTRING( "CCCHCommDbWatcher::~CCCHCommDbWatcher" );
       
   125     iDestinations.Close();
       
   126     // Cancel outstanding request, if exists
       
   127     Cancel();
       
   128     delete iRepository;
       
   129     if ( iCmmOpen )
       
   130         {
       
   131         iCmm.Close();
       
   132         }
       
   133     }
       
   134 
       
   135 // ---------------------------------------------------------------------------
       
   136 // CCCHCommsDbWatcher::RequestNotifications()
       
   137 // 
       
   138 // ---------------------------------------------------------------------------
       
   139 //
       
   140 TInt CCCHCommDbWatcher::RequestNotifications()
       
   141     {
       
   142     CCHLOGSTRING( "CCCHCommDbWatcher::RequestNotifications()" );   
       
   143     CCHLOGSTRING2( "Calling iRepository->NotifyRequest() for table 0x%08X", iTableId );
       
   144     TInt err = iRepository->NotifyRequest( iTableId, KCDMaskShowRecordType, iStatus );
       
   145 
       
   146     if ( KErrNone == err )
       
   147         {
       
   148         SetActive();
       
   149         }
       
   150     else
       
   151         {
       
   152         CCHLOGSTRING2( "ERROR, iRepository->NotifyRequest() <%d>", err );
       
   153         }
       
   154     return err;
       
   155     }
       
   156 
       
   157 // ---------------------------------------------------------------------------
       
   158 // CCCHCommsDbWatcher::CmManagerL
       
   159 // 
       
   160 // ---------------------------------------------------------------------------
       
   161 //
       
   162 RCmManager& CCCHCommDbWatcher::CmManagerL()
       
   163     {
       
   164     // Remove this method and open cmmanager connection in ConstructL
       
   165     // after cmmanager is refactored -> to become a server, schedule is unknown
       
   166     if ( !iCmmOpen )
       
   167         {
       
   168         CCHLOGSTRING( "CCCHCommDbWatcher::CmManagerL open connection" );
       
   169         iCmm.OpenL();
       
   170         iCmmOpen = ETrue;
       
   171         }
       
   172     
       
   173     return iCmm; 
       
   174     }
       
   175 
       
   176 // ---------------------------------------------------------------------------
       
   177 // CCCHCommsDbWatcher::GetWLANIapCountFromSnap
       
   178 //
       
   179 // ---------------------------------------------------------------------------
       
   180 //
       
   181 TInt CCCHCommDbWatcher::GetIapCountFromSnap( 
       
   182     TInt aSNAPId, 
       
   183     TBool aWLANIapsOnly,
       
   184     TBool aUpdateDestinations )
       
   185     {
       
   186     CCHLOGSTRING( "CCCHCommDbWatcher::GetIapCountFromSnap - Forced CheckIapsL" );
       
   187 
       
   188     // Remove this error check after cmmanager is refactored -> to become 
       
   189     // a server, schedule is unknown
       
   190     // Force destination update if we are pending unlock event
       
   191     if ( iLastError || iUseForce || aUpdateDestinations )
       
   192         {
       
   193         CCHLOGSTRING( "CCCHCommDbWatcher::GetIapCountFromSnap - Forced DESTINATION UPDATE" );
       
   194         InitializeDestination();
       
   195         iUseForce = EFalse;
       
   196         }
       
   197     
       
   198     TInt iaps( KErrNotFound );
       
   199     for ( TInt i = 0; iaps == KErrNotFound && i < iDestinations.Count(); i++ )
       
   200         {
       
   201         if ( iDestinations[ i ].iDestId == aSNAPId )
       
   202             {
       
   203             iaps = 0; //if destination is not found, KErrNotFound is returned
       
   204             if ( aWLANIapsOnly )
       
   205                 {
       
   206                 iaps = iDestinations[ i ].iWlanIaps;
       
   207                 }
       
   208             else
       
   209                 {
       
   210                 iaps = iDestinations[ i ].iIapCount;
       
   211                 }
       
   212             }
       
   213         }
       
   214         
       
   215     return iaps;
       
   216     }
       
   217 
       
   218 // ---------------------------------------------------------------------------
       
   219 // CCCHCommsDbWatcher::IsVpnApL
       
   220 //
       
   221 // ---------------------------------------------------------------------------
       
   222 //
       
   223 TBool CCCHCommDbWatcher::IsVpnApL(
       
   224     TInt aIapId )
       
   225     {
       
   226     CCHLOGSTRING( "CCCHCommDbWatcher::IsVpnApL: IN" );
       
   227     TBool response( KPluginVPNBearerTypeUid == GetBearerL( aIapId ) );
       
   228     CCHLOGSTRING3( "CCCHCommDbWatcher::IsVpnApL: iap id: %d is vpn ap: %d", 
       
   229             aIapId, response );
       
   230     return response;
       
   231     }
       
   232 
       
   233 // ---------------------------------------------------------------------------
       
   234 // CCCHCommsDbWatcher::IsWLANAPL
       
   235 //
       
   236 // ---------------------------------------------------------------------------
       
   237 //
       
   238 TBool CCCHCommDbWatcher::IsWlanApL( 
       
   239     TInt aIapId )
       
   240     {
       
   241     CCHLOGSTRING( "CCCHCommDbWatcher::IsWLANAPL: IN" );
       
   242     TBool response( KUidWlanBearerType == GetBearerL( aIapId ) );
       
   243     
       
   244     CCHLOGSTRING3( "CCCHCommDbWatcher::IsWLANAPL: iap id: %d is wlan ap: %d", 
       
   245         aIapId, response );
       
   246     return response;
       
   247     }
       
   248    
       
   249 // ---------------------------------------------------------------------------
       
   250 // CCCHCommsDbWatcher::GetBearerL
       
   251 //
       
   252 // ---------------------------------------------------------------------------
       
   253 //
       
   254 TUint32 CCCHCommDbWatcher::GetBearerL( 
       
   255     TInt aIapId )
       
   256     {
       
   257     return CmManagerL().ConnectionMethodL( aIapId ).GetIntAttributeL( 
       
   258             CMManager::ECmBearerType );
       
   259     }
       
   260     
       
   261 // ---------------------------------------------------------------------------
       
   262 // CCCHCommsDbWatcher::RunL
       
   263 //
       
   264 // ---------------------------------------------------------------------------
       
   265 //
       
   266 void CCCHCommDbWatcher::RunL()
       
   267     {
       
   268     if ( iStatus.Int() < KErrNone )
       
   269         {
       
   270         CCHLOGSTRING2( "CCCHCommDbWatcher::RunL: error <%d>", iStatus.Int() );
       
   271         iErrorCounter++;
       
   272         if ( iErrorCounter > KCchConnCenRepErrorThreshold )
       
   273             {
       
   274             CCHLOGSTRING2( "Over %d consecutive errors, stopping notifications permanently",
       
   275                     KCchConnCenRepErrorThreshold );
       
   276             return;
       
   277             }
       
   278         }
       
   279     else
       
   280         {
       
   281         iErrorCounter = 0;
       
   282         UpdateIapTable();
       
   283         }
       
   284 
       
   285     CCHLOGSTRING2( "CCCHCommDbWatcher::RunL: CenRep event 0x%08X", iStatus.Int() );
       
   286 
       
   287     TInt err( RequestNotifications() );
       
   288     User::LeaveIfError( err );
       
   289     }
       
   290 
       
   291 // ---------------------------------------------------------------------------
       
   292 // CCCHCommsDbWatcher::DoCancel
       
   293 //
       
   294 // ---------------------------------------------------------------------------
       
   295 //
       
   296 void CCCHCommDbWatcher::DoCancel()
       
   297     {
       
   298     iRepository->NotifyCancel( iTableId, KCDMaskShowRecordType );
       
   299     }
       
   300 
       
   301 // ---------------------------------------------------------------------------
       
   302 // CCCHCommsDbWatcher::RunError
       
   303 //
       
   304 // ---------------------------------------------------------------------------
       
   305 //
       
   306 
       
   307 TInt CCCHCommDbWatcher::RunError( TInt /*aError*/ )
       
   308     {
       
   309     TInt err( RequestNotifications() );
       
   310     return KErrNone;
       
   311     }
       
   312 
       
   313 // ---------------------------------------------------------------------------
       
   314 // CCCHCommsDbWatcher::CheckIapsL
       
   315 //
       
   316 // ---------------------------------------------------------------------------
       
   317 //
       
   318 void CCCHCommDbWatcher::CheckIapsL( TBool& aChanged, TInt& aSNAPId )
       
   319 	{
       
   320     CCHLOGSTRING2( "CCCHCommDbWatcher::CheckIapsL: IN Current iap count %d",
       
   321             CountIapsFromArray( iDestinations ) );
       
   322 
       
   323 
       
   324   	RArray<TUint32> destIdArray = RArray<TUint32>( KDefaultGranularity );
       
   325     CleanupClosePushL( destIdArray ); // CS:1
       
   326   	RArray<TDestinationData> currentDestinations = RArray<TDestinationData>( 
       
   327   		KDefaultGranularity ); 
       
   328     CleanupClosePushL( currentDestinations );	 // CS:2
       
   329 
       
   330     //Get count of iaps that do not belong to any destination
       
   331     RArray<TUint32> cmMethods = RArray<TUint32>( KDefaultGranularity );
       
   332     CleanupClosePushL( cmMethods ); // CS:3
       
   333     CmManagerL().ConnectionMethodL( cmMethods );
       
   334         
       
   335     TDestinationData destinationlessIaps( KErrNotFound, cmMethods.Count() );
       
   336     CCHLOGSTRING2( "CCCHCommDbWatcher::CheckIapsL: cmMethods count %d",
       
   337             cmMethods.Count() );
       
   338     for ( TInt i = 0; i < cmMethods.Count(); i++ )
       
   339         {
       
   340    	    RCmConnectionMethod cm = CmManagerL().ConnectionMethodL( cmMethods[ i ] );
       
   341         CleanupClosePushL( cm ); // CS:4
       
   342         
       
   343         if( KUidWlanBearerType == 
       
   344             cm.GetIntAttributeL( CMManager::ECmBearerType ) )
       
   345             {
       
   346             destinationlessIaps.iWlanIaps++;
       
   347             }
       
   348         CleanupStack::PopAndDestroy( &cm ); // CS:3
       
   349         }
       
   350         
       
   351     CleanupStack::PopAndDestroy( &cmMethods ); // CS:2
       
   352     currentDestinations.Append( destinationlessIaps ); 
       
   353 
       
   354     //Get count of iaps per destination
       
   355     CmManagerL().AllDestinationsL( destIdArray );
       
   356     CCHLOGSTRING2( "CCCHCommDbWatcher::CheckIapsL: destination count %d",
       
   357                 destIdArray.Count() )
       
   358     for ( TInt i = 0; i < destIdArray.Count(); i++ )
       
   359         {
       
   360         RCmDestination destination = CmManagerL().DestinationL( destIdArray[ i ] );
       
   361         CleanupClosePushL( destination ); // CS:3
       
   362         TDestinationData destinationInfo( 
       
   363             destination.Id(), destination.ConnectionMethodCount() );
       
   364 		 
       
   365          for ( TInt k = 0; k < destinationInfo.iIapCount; k++ )
       
   366 			 {
       
   367 			 RCmConnectionMethod cm = destination.ConnectionMethodL( k );
       
   368 			 CleanupClosePushL( cm ); // CS:4
       
   369              
       
   370 			 if( KUidWlanBearerType == 
       
   371 			 	 cm.GetIntAttributeL( CMManager::ECmBearerType ) )
       
   372 				 {
       
   373 				 destinationInfo.iWlanIaps++;				 	
       
   374 				 }
       
   375 		     CleanupStack::PopAndDestroy( &cm ); // CS:3
       
   376 			 }
       
   377             
       
   378 		 currentDestinations.Append( destinationInfo );
       
   379 		 CleanupStack::PopAndDestroy( &destination ); // CS:2
       
   380 	     }
       
   381     
       
   382 	destIdArray.Close();
       
   383     
       
   384     UpdateDestinationStore( currentDestinations, aChanged, aSNAPId );
       
   385     
       
   386     CleanupStack::PopAndDestroy( &currentDestinations ); // CS:1
       
   387     CleanupStack::PopAndDestroy( &destIdArray ); // CS:0
       
   388 	
       
   389     CCHLOGSTRING2( "CCCHCommDbWatcher::CheckIapsL: OUT changed: %d", aChanged );
       
   390 	}
       
   391 
       
   392 // ---------------------------------------------------------------------------
       
   393 // CCCHCommsDbWatcher::CountIapsFromArray
       
   394 //
       
   395 // ---------------------------------------------------------------------------
       
   396 //
       
   397 TInt CCCHCommDbWatcher::CountIapsFromArray( 
       
   398     RArray<TDestinationData>& aArray ) const
       
   399 	{
       
   400 	TInt iaps = 0;
       
   401 	for ( TInt i=0; i<aArray.Count(); i++ )
       
   402 		{
       
   403 		iaps+= aArray[i].iIapCount;
       
   404 		}
       
   405 	return iaps;	
       
   406 	}
       
   407 
       
   408 // ---------------------------------------------------------------------------
       
   409 // CCCHCommsDbWatcher::UpdateDestinationStore
       
   410 //
       
   411 // ---------------------------------------------------------------------------
       
   412 //
       
   413 void CCCHCommDbWatcher::UpdateDestinationStore( 
       
   414     RArray<TDestinationData>& aDestinations,
       
   415     TBool& aChanged,
       
   416     TInt& aSNAPId )
       
   417     {
       
   418 	//Now compare fetched data with store
       
   419 	TInt iapsBefore = CountIapsFromArray ( iDestinations );
       
   420 	TInt iapsAfter  = CountIapsFromArray ( aDestinations );
       
   421 
       
   422     aSNAPId = KErrNotFound;
       
   423     aChanged = EFalse;
       
   424 
       
   425     //no further checking is needed if iap count decreased
       
   426     if ( iapsAfter >= iapsBefore )
       
   427 		{
       
   428         //compare store with current setup for changes
       
   429         //only change in WLAN iap count is reported
       
   430 		for ( TInt i = 0; !aChanged && i < aDestinations.Count(); i++ )
       
   431 			{
       
   432             TBool alreadyexists = EFalse;
       
   433 			for ( TInt j = 0; !aChanged && j < iDestinations.Count(); j++ )
       
   434 				{
       
   435                 if ( aDestinations[i].iDestId == iDestinations[j].iDestId )
       
   436                     {
       
   437                     alreadyexists = ETrue;
       
   438                     // Do not update snap id if destination is -1, this means 
       
   439                     // that cmmanager hasn't moved iap to the right destination yet
       
   440                     if ( aDestinations[i].iWlanIaps > 
       
   441                          iDestinations[j].iWlanIaps )
       
   442 					    {
       
   443                         if ( KErrNotFound == aDestinations[ i ].iDestId )
       
   444                             {
       
   445                             // If destination -1 is the only updated destination
       
   446                             // we have to use force next time when asking GetIapCountFromSnap
       
   447                             iUseForce = ETrue;
       
   448                             CCHLOGSTRING( "CCCHCommDbWatcher - USE THE FORCE NEXT TIME" );
       
   449                             }
       
   450                         else
       
   451                             {
       
   452                             //wlan iap count increased in comp[i]
       
   453                             aSNAPId = aDestinations[i].iDestId;
       
   454                             aChanged = ETrue;
       
   455                             iUseForce = EFalse;
       
   456                             CCHLOGSTRING2( "CCCHCommDbWatcher - snap id: %d", aSNAPId );
       
   457                             }
       
   458                         }
       
   459                     }
       
   460 				}
       
   461                 
       
   462             //if there is a new SNAP, check wlan iap count in the new IAP
       
   463             if ( !alreadyexists && aDestinations[i].iWlanIaps > 0 )
       
   464                 {
       
   465                 aSNAPId = aDestinations[i].iDestId;
       
   466                 aChanged = ETrue;
       
   467                 CCHLOGSTRING2( "CCCHCommDbWatcher new snap id: %d", aSNAPId );
       
   468                 }
       
   469 			}
       
   470 		}
       
   471 		
       
   472 	//update store
       
   473 	iDestinations.Reset();
       
   474 	for ( TInt i=0; i < aDestinations.Count(); i++ )
       
   475 		{
       
   476 		iDestinations.Append( aDestinations[i] );					
       
   477         // Destinations are refreshed, set last error to kerrnone
       
   478         iLastError = KErrNone;
       
   479 		}
       
   480     }
       
   481 
       
   482 // ---------------------------------------------------------------------------
       
   483 // CCCHCommsDbWatcher::UpdateIapTable
       
   484 //
       
   485 // ---------------------------------------------------------------------------
       
   486 //
       
   487 TInt CCCHCommDbWatcher::UpdateIapTable()
       
   488     {
       
   489     TBool configurationChanged( EFalse );
       
   490     TInt changedSnapId( KErrNotFound );
       
   491     TInt error( KErrNone );
       
   492     TRAP( error, CheckIapsL( configurationChanged, changedSnapId ) );
       
   493             
       
   494     if ( error == KErrNone )
       
   495         {
       
   496         if( configurationChanged )
       
   497             {
       
   498             // new IAP(s) added, notify observer
       
   499             iObserver.HandleWLANIapAdded( changedSnapId );
       
   500             }
       
   501         }
       
   502     
       
   503     CCHLOGSTRING2( "CCCHCommDbWatcher::UpdateIapTable: CActive iStatus : %d", iStatus.Int() );
       
   504     return error;
       
   505     }
       
   506 
       
   507 // ---------------------------------------------------------------------------
       
   508 // CCCHCommsDbWatcher::InitializeDestination
       
   509 //
       
   510 // ---------------------------------------------------------------------------
       
   511 //
       
   512 void CCCHCommDbWatcher::InitializeDestination()
       
   513     {
       
   514     //call CheckWLANIapsL to get initial iap/snap list to array 
       
   515     //we're not interested in the return value at this point
       
   516     TBool configurationChanged( EFalse );
       
   517     TInt changedSnapId( 0 );
       
   518     // Loop, because transaction might pend and error(KErrLocked) may occur
       
   519     TInt error( KErrNone );
       
   520     for ( TInt i( 0 ); i < KMaxCheckAttempts; i++ )
       
   521         {
       
   522         TRAP( error, CheckIapsL( configurationChanged, changedSnapId ) ); 
       
   523         CCHLOGSTRING2( 
       
   524             "CCCHCommDbWatcher::InitializeDestination; error: %d", error );
       
   525         if( KErrNone == error || KErrNotFound == error )
       
   526             {
       
   527             break;
       
   528             }
       
   529         }
       
   530         
       
   531     if( error )
       
   532         {
       
   533         iLastError = error;
       
   534         }
       
   535     }
       
   536 
       
   537 // ---------------------------------------------------------------------------
       
   538 // CCCHCommsDbWatcher::RemoveOtherThanVpnIapsL
       
   539 //
       
   540 // ---------------------------------------------------------------------------
       
   541 //
       
   542 void CCCHCommDbWatcher::RemoveOtherThanVpnIapsL(
       
   543     RArray<TUint>& aIapIds,
       
   544     TUint aIAPId )
       
   545     {
       
   546     CCHLOGSTRING2( "CCCHCommDbWatcher::RemoveOtherThanVpnIapsL; IAP ID:  %d", aIAPId );
       
   547     CCHLOGSTRING2( "CCCHCommDbWatcher::RemoveOtherThanVpnIapsL; IAPs count before: %d", aIapIds.Count() );
       
   548     
       
   549     TUint32 iapId( KErrNone );
       
   550     RArray<TUint> iaps;
       
   551     CleanupClosePushL( iaps );
       
   552     RCmConnectionMethod cm = CmManagerL().ConnectionMethodL( aIAPId );
       
   553     CleanupClosePushL( cm );
       
   554 	
       
   555     TUint32 realIap( cm.GetIntAttributeL( CMManager::ECmNextLayerIapId ) );
       
   556     CCHLOGSTRING2( "CCCHCommDbWatcher::RemoveOtherThanVpnIapsL: real iap  %d ", realIap );
       
   557     TUint32 realSnap( cm.GetIntAttributeL( CMManager::ECmNextLayerSNAPId ) );
       
   558     CCHLOGSTRING2( "CCCHCommDbWatcher::RemoveOtherThanVpnIapsL: real snap %d", realSnap );
       
   559             
       
   560     if ( realIap )
       
   561         {
       
   562         CCHLOGSTRING( "CCCHCommDbWatcher::RemoveOtherThanVpnIapsL: VPN linked to IAP" );
       
   563         
       
   564         if ( KErrNotFound != aIapIds.Find( realIap ) )
       
   565             {
       
   566             iaps.Append( realIap );
       
   567             }
       
   568         }
       
   569     else
       
   570         {
       
   571         CCHLOGSTRING( "CCCHCommDbWatcher::RemoveOtherThanVpnIapsL: VPN linked to SNAP" );
       
   572         
       
   573         RCmDestination realDestination = CmManagerL().DestinationL( realSnap );
       
   574         CleanupClosePushL( realDestination );
       
   575         
       
   576         for ( TInt i = 0; i < realDestination.ConnectionMethodCount(); i++ )
       
   577             {
       
   578             RCmConnectionMethod realCm = realDestination.ConnectionMethodL( i );
       
   579             CleanupClosePushL( realCm );
       
   580             iapId = realCm.GetIntAttributeL( CMManager::ECmIapId );
       
   581         
       
   582             if ( KErrNotFound != aIapIds.Find( iapId ) )
       
   583                 {
       
   584                 iaps.Append( iapId );
       
   585                 }
       
   586             
       
   587             CleanupStack::PopAndDestroy( &realCm );
       
   588             }
       
   589         
       
   590         CleanupStack::PopAndDestroy( &realDestination );
       
   591         }
       
   592             
       
   593     aIapIds.Reset();
       
   594     for ( TInt j( 0 ); j < iaps.Count(); j++ )
       
   595         {
       
   596         aIapIds.Append( iaps[ j ] );
       
   597         }
       
   598     
       
   599     CleanupStack::PopAndDestroy( &cm );
       
   600     CleanupStack::PopAndDestroy( &iaps ); 
       
   601     
       
   602     CCHLOGSTRING2( "CCCHCommDbWatcher::RemoveOtherThanVpnIapsL; IAPs count after:  %d", aIapIds.Count() );
       
   603     }
       
   604     
       
   605 // ========================== OTHER EXPORTED FUNCTIONS =======================
       
   606 
       
   607 //  End of File