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