cmmanager/cmmgr/cmmserver/src/cmmcache.cpp
branchRCL_3
changeset 58 83ca720e2b9a
parent 57 05bc53fe583b
child 62 bb1f80fb7db2
equal deleted inserted replaced
57:05bc53fe583b 58:83ca720e2b9a
     1 /*
       
     2 * Copyright (c) 2009-2010 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:
       
    15 * Database cache manager.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <e32base.h>
       
    21 #include <cmpluginbaseeng.h>
       
    22 #include <cmdefconnvalues.h>
       
    23 #include <cmpluginembdestinationdef.h>
       
    24 
       
    25 #include <es_sock.h>    // RSocketServ, RConnection
       
    26 #include <in_sock.h>    // KAfInet
       
    27 #include <es_enum.h>    // TConnectionInfo
       
    28 
       
    29 #include "cmmdestinationstruct.h"
       
    30 #include "cmmlistenermanager.h"
       
    31 #include "cmminstancemapping.h"
       
    32 
       
    33 #include "cmmcache.h"
       
    34 
       
    35 #include "cmmdestinationinstance.h"
       
    36 #include "cmmconnmethodinstance.h"
       
    37 
       
    38 #include "cmmtransactionhandler.h"
       
    39 #include "cmmanagerimpl.h"
       
    40 #include "cmmbearerprioritycache.h"
       
    41 
       
    42 #include "OstTraceDefinitions.h"
       
    43 #ifdef OST_TRACE_COMPILER_IN_USE
       
    44 #include "cmmcacheTraces.h"
       
    45 #endif
       
    46 
       
    47 
       
    48 // ---------------------------------------------------------------------------
       
    49 // Two phased construction.
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 CCmmCache* CCmmCache::NewL(
       
    53         CCmManagerImpl* aCmManagerImpl,
       
    54         CArrayPtrFlat<const CCmPluginBaseEng>* aPlugins )
       
    55     {
       
    56     OstTraceFunctionEntry0( CCMMCACHE_NEWL_ENTRY );
       
    57 
       
    58     CCmmCache* self = CCmmCache::NewLC( aCmManagerImpl, aPlugins );
       
    59     CleanupStack::Pop( self );
       
    60 
       
    61     OstTraceFunctionExit0( CCMMCACHE_NEWL_EXIT );
       
    62 
       
    63     return self;
       
    64     }
       
    65 
       
    66 // ---------------------------------------------------------------------------
       
    67 // Two phased construction.
       
    68 // ---------------------------------------------------------------------------
       
    69 //
       
    70 CCmmCache* CCmmCache::NewLC(
       
    71         CCmManagerImpl* aCmManagerImpl,
       
    72         CArrayPtrFlat<const CCmPluginBaseEng>* aPlugins )
       
    73     {
       
    74     OstTraceFunctionEntry0( CCMMCACHE_NEWLC_ENTRY );
       
    75 
       
    76     CCmmCache* self = new( ELeave ) CCmmCache( aCmManagerImpl, aPlugins );
       
    77     CleanupStack::PushL( self );
       
    78     self->ConstructL();
       
    79 
       
    80     OstTraceFunctionExit0( CCMMCACHE_NEWLC_EXIT );
       
    81 
       
    82     return self;
       
    83     }
       
    84 
       
    85 // ---------------------------------------------------------------------------
       
    86 // Destructor.
       
    87 // ---------------------------------------------------------------------------
       
    88 //
       
    89 CCmmCache::~CCmmCache()
       
    90     {
       
    91     OstTraceFunctionEntry0( CCMMCACHE_CCMMCACHE_ENTRY );
       
    92 
       
    93     delete iBearerPriorityCache;
       
    94     delete iListenerManager;
       
    95     delete iInstanceMapping;
       
    96 
       
    97     iConnMethodArray.ResetAndDestroy();
       
    98     iDestinationArray.ResetAndDestroy();
       
    99 
       
   100     iDeletedConnMethods.Close();
       
   101     iUpdatedConnMethods.Close();
       
   102     iUpdatedConnMethods2.Close(); // Does not own contents.
       
   103     iUpdatedDestinations.Close();
       
   104     iUpdatedDestinations2.Close(); // Does not own contents.
       
   105 
       
   106     OstTraceFunctionExit0( CCMMCACHE_CCMMCACHE_EXIT );
       
   107     }
       
   108 
       
   109 // ---------------------------------------------------------------------------
       
   110 // Constructor.
       
   111 // ---------------------------------------------------------------------------
       
   112 //
       
   113 CCmmCache::CCmmCache(
       
   114         CCmManagerImpl* aCmManagerImpl,
       
   115         CArrayPtrFlat<const CCmPluginBaseEng>* aPlugins )
       
   116         :
       
   117         iPlugins( aPlugins ),
       
   118         iCmManagerImpl( aCmManagerImpl )
       
   119     {
       
   120     OstTraceFunctionEntry0( DUP1_CCMMCACHE_CCMMCACHE_ENTRY );
       
   121 
       
   122     iListenerManager = NULL;
       
   123     iInstanceMapping = NULL;
       
   124     iTrans = NULL;
       
   125     iBearerPriorityCache = NULL;
       
   126     iCurrentTemporaryId = KTemporaryIdCounterStart;
       
   127 
       
   128     iSnapTableId = 0;
       
   129     iSnapMetadataTableId = 0;
       
   130 
       
   131     OstTraceFunctionExit0( DUP1_CCMMCACHE_CCMMCACHE_EXIT );
       
   132     }
       
   133 
       
   134 // ---------------------------------------------------------------------------
       
   135 // Second phase constructor.
       
   136 // ---------------------------------------------------------------------------
       
   137 //
       
   138 void CCmmCache::ConstructL()
       
   139     {
       
   140     OstTraceFunctionEntry0( CCMMCACHE_CONSTRUCTL_ENTRY );
       
   141 
       
   142     iTrans = iCmManagerImpl->GetTransactionHandler();
       
   143 
       
   144     iBearerPriorityCache = CCmmBearerPriorityCache::NewL(
       
   145             iTrans,
       
   146             iCmManagerImpl->TableId( ECmmDbBearerPriorityRecord ) );
       
   147     iListenerManager = CCmmListenerManager::NewL( this );
       
   148     iInstanceMapping = CCmmInstanceMapping::NewL( *this );
       
   149 
       
   150     // Create CommsDat listeners to detect changes to the database from external sources.
       
   151     RArray<TUint32> tableIdArray;
       
   152     CleanupClosePushL( tableIdArray );
       
   153 
       
   154     iSnapTableId = iCmManagerImpl->TableId( ECmmDbSnapRecord );
       
   155     iSnapMetadataTableId = iCmManagerImpl->TableId( ECmmDestMetadataRecord );
       
   156 
       
   157     // Instancemapping needs notifications on following tables.
       
   158     tableIdArray.Append( CommsDat::KCDTIdIAPRecord );
       
   159     tableIdArray.Append( CommsDat::KCDTIdVPNServiceRecord );
       
   160     tableIdArray.Append( iSnapTableId );
       
   161     tableIdArray.Append( iSnapMetadataTableId );
       
   162 
       
   163     // Destinations need notifications on following tables.
       
   164     tableIdArray.Append( CommsDat::KCDTIdNetworkRecord );
       
   165     tableIdArray.Append( CommsDat::KCDTIdAccessPointRecord );
       
   166     // Destination metadata table was already added.
       
   167 
       
   168     // Connection methods need notifications on following tables.
       
   169     TInt pluginCount( iPlugins->Count() );
       
   170     if ( pluginCount )
       
   171         {
       
   172         ( *iPlugins )[0]->GetGenericTableIdsToBeObservedL( tableIdArray );
       
   173         for( TInt i = 0; i < pluginCount; i++ )
       
   174             {
       
   175             ( *iPlugins )[i]->GetBearerTableIdsToBeObservedL( tableIdArray );
       
   176             }
       
   177         }
       
   178 
       
   179     for ( TInt i = 0; i < tableIdArray.Count(); i++ )
       
   180         {
       
   181         iListenerManager->AddListenerL( tableIdArray[i] );
       
   182         }
       
   183     CleanupStack::PopAndDestroy( &tableIdArray );
       
   184 
       
   185     OstTraceFunctionExit0( CCMMCACHE_CONSTRUCTL_EXIT );
       
   186     }
       
   187 
       
   188 // ---------------------------------------------------------------------------
       
   189 // Opens a destination with given ID (if not already opened), then copies the
       
   190 // relevant data to the session instance. Checks that destination ID is valid.
       
   191 // ---------------------------------------------------------------------------
       
   192 //
       
   193 void CCmmCache::OpenDestinationL(
       
   194         CCmmDestinationInstance& aDestinationInstance,
       
   195         const TUint32 aDestinationId )
       
   196     {
       
   197     OstTraceFunctionEntry0( CCMMCACHE_OPENDESTINATIONL_ENTRY );
       
   198 
       
   199     if ( !iInstanceMapping->ValidDestinationId( aDestinationId ) )
       
   200         {
       
   201         User::Leave( KErrNotFound );
       
   202         }
       
   203 
       
   204     TInt index = FindDestinationFromCache( aDestinationId );
       
   205     if ( index == KErrNotFound )
       
   206         {
       
   207         // Cache does not have a handle open to this destination. A new handle
       
   208         // needs to be created first.
       
   209         CCmmDestinationStruct* destination = CCmmDestinationStruct::NewLC(
       
   210                 this,
       
   211                 iTrans,
       
   212                 aDestinationId );
       
   213 
       
   214         // Now that cache has a handle on this destination, copy the relevant
       
   215         // data to the session instance.
       
   216         destination->CreateDestinationInstanceL( aDestinationInstance );
       
   217 
       
   218         iDestinationArray.AppendL( destination );
       
   219         CleanupStack::Pop( destination );
       
   220         }
       
   221     else
       
   222         {
       
   223         // Cache already has a handle on this destination. Copy the relevant
       
   224         // data to the session instance.
       
   225         iDestinationArray[index]->CreateDestinationInstanceL( aDestinationInstance );
       
   226         }
       
   227 
       
   228     // Add list of currently contained connection methods.
       
   229     iInstanceMapping->GetConnMethodsFromDestinationL(
       
   230             aDestinationId,
       
   231             aDestinationInstance.iConnMethodItemArray );
       
   232 
       
   233     OstTraceFunctionExit0( CCMMCACHE_OPENDESTINATIONL_EXIT );
       
   234     }
       
   235 
       
   236 // ---------------------------------------------------------------------------
       
   237 // Refresh the data contained in aDestinationInstance. This means reloading
       
   238 // the data from database if necessary. After this call the contents of
       
   239 // aDestinationInstance will reflect the current state in the database. 
       
   240 // ---------------------------------------------------------------------------
       
   241 //
       
   242 void CCmmCache::RefreshDestinationL( CCmmDestinationInstance& aDestinationInstance )
       
   243     {
       
   244     OstTraceFunctionEntry0( CCMMCACHE_REFRESHDESTINATIONL_ENTRY );
       
   245 
       
   246     TInt index = FindDestinationFromCache( aDestinationInstance.GetId() );
       
   247     if ( index == KErrNotFound )
       
   248         {
       
   249         index = FindNotSavedDestinationFromCacheL( aDestinationInstance.GetDestinationNameL(), 0 );
       
   250         if ( index == KErrNotFound )
       
   251             {
       
   252             User::Leave( KErrNotFound );
       
   253             }
       
   254         }
       
   255 
       
   256     // If this destination is a newly created one that doesn't yet exist in
       
   257     // database, just return silently.
       
   258     if ( iDestinationArray[index]->GetStatus() == ECmmDestinationStatusNotSaved )
       
   259         {
       
   260         OstTraceFunctionExit0( CCMMCACHE_REFRESHDESTINATIONL_EXIT );
       
   261         return;
       
   262         }
       
   263 
       
   264     iDestinationArray[index]->RefreshDestinationInstanceL( aDestinationInstance );
       
   265 
       
   266     OstTraceFunctionExit0( DUP1_CCMMCACHE_REFRESHDESTINATIONL_EXIT );
       
   267     }
       
   268 
       
   269 // ---------------------------------------------------------------------------
       
   270 // Create a new destination into cache (with name and ID) and copy the data
       
   271 // into session side handle.
       
   272 // ---------------------------------------------------------------------------
       
   273 //
       
   274 void CCmmCache::CreateDestinationL(
       
   275         CCmmDestinationInstance& aDestinationInstance,
       
   276         const TDesC& aName,
       
   277         const TUint32 aId )
       
   278     {
       
   279     OstTraceFunctionEntry0( CCMMCACHE_CREATEDESTINATIONL_ENTRY );
       
   280 
       
   281     // Create a new destination with given name.
       
   282     CCmmDestinationStruct* destination = CCmmDestinationStruct::NewLC( this, iTrans, aName, aId );
       
   283 
       
   284     destination->CreateDestinationInstanceL( aDestinationInstance );
       
   285 
       
   286     iDestinationArray.AppendL( destination );
       
   287     CleanupStack::Pop( destination );
       
   288 
       
   289     OstTraceFunctionExit0( CCMMCACHE_CREATEDESTINATIONL_EXIT );
       
   290     }
       
   291 
       
   292 // ---------------------------------------------------------------------------
       
   293 // Opens a connection method with given ID (if not already opened), then
       
   294 // creates and passes an instance of it to the caller.
       
   295 // If aDestinationInstance is not NULL, connection method is opened from
       
   296 // destination.
       
   297 // ---------------------------------------------------------------------------
       
   298 //
       
   299 void CCmmCache::OpenConnMethodL(
       
   300         CCmmConnMethodInstance& aConnMethodInstance,
       
   301         CCmmDestinationInstance* aDestinationInstance,
       
   302         const TUint32 aConnMethodId )
       
   303     {
       
   304     OstTraceFunctionEntry0( CCMMCACHE_OPENCONNMETHODL_ENTRY );
       
   305 
       
   306     // Check connection method ID.
       
   307     TBool validAttributes( EFalse );
       
   308     if ( !aDestinationInstance )
       
   309         {
       
   310         // Check connection method exists in database.
       
   311         // Embedded destinations not included.
       
   312         validAttributes = iInstanceMapping->ValidConnMethodId( aConnMethodId );
       
   313         }
       
   314     else
       
   315         {
       
   316         // Check connection method is inside the destination.
       
   317         if ( aDestinationInstance->
       
   318                 ValidConnMethodIdInDestinationIncludeEmbedded( aConnMethodId ) )
       
   319             {
       
   320             // Check connection method (can be embedded destination too)
       
   321             // exists in database.
       
   322             if ( iInstanceMapping->ValidConnMethodId( aConnMethodId ) ||
       
   323                     iInstanceMapping->ValidDestinationId( aConnMethodId ) )
       
   324                 {
       
   325                 validAttributes = ETrue;
       
   326                 }
       
   327             }
       
   328        }
       
   329     if ( !validAttributes )
       
   330         {
       
   331         User::Leave( KErrNotFound );
       
   332         }
       
   333 
       
   334     // Create the connection method instance.
       
   335 
       
   336     // Check if connection method is already opened in cache.
       
   337     TInt index = FindConnMethodFromCache( aConnMethodId );
       
   338     if ( index != KErrNotFound )
       
   339         {
       
   340         // Update data from commsdat if necessary.
       
   341         if ( iConnMethodArray[index]->GetRecordStatus() == ECmmRecordStatusExpired )
       
   342             {
       
   343             iConnMethodArray[index]->ReloadPluginDataIfNeededL();
       
   344             // CopyDataL() will set the internal state of aConnMethodInstance.
       
   345             }
       
   346 
       
   347         // Already open in cache. Copy the connection method data to session
       
   348         // instance.
       
   349         // Will increase reference counter.
       
   350         aConnMethodInstance.CopyDataL( iConnMethodArray[index] );
       
   351         }
       
   352     else
       
   353         {
       
   354         // Not yet open in cache, open now.
       
   355         OpenConnectionMethodInstanceL( aConnMethodInstance, aConnMethodId );
       
   356         }
       
   357 
       
   358     OstTraceFunctionExit0( CCMMCACHE_OPENCONNMETHODL_EXIT );
       
   359     }
       
   360 
       
   361 // ---------------------------------------------------------------------------
       
   362 // Refresh the data contained in aConnMethodInstance. This means reloading the
       
   363 // data from database if necessary. After this call the contents of
       
   364 // aConnMethodInstance will reflect the current state in the database. 
       
   365 // ---------------------------------------------------------------------------
       
   366 //
       
   367 void CCmmCache::RefreshConnMethodL( CCmmConnMethodInstance& aConnMethodInstance )
       
   368     {
       
   369     OstTraceFunctionEntry0( CCMMCACHE_REFRESHCONNMETHODL_ENTRY );
       
   370 
       
   371     // If embedded destination --> refresh through destination API.
       
   372     if ( aConnMethodInstance.IsEmbeddedDestination() )
       
   373         {
       
   374         return;
       
   375         }
       
   376 
       
   377     TInt index = FindConnMethodFromCache( aConnMethodInstance.GetId() );
       
   378     if ( index == KErrNotFound )
       
   379         {
       
   380         User::Leave( KErrNotFound );
       
   381         }
       
   382 
       
   383     // If this connection method is a newly created one that doesn't yet exist
       
   384     // in database, just return silently.
       
   385     if ( iConnMethodArray[index]->GetStatus() == ECmmConnMethodStatusNotSaved )
       
   386         {
       
   387         OstTraceFunctionExit0( CCMMCACHE_REFRESHCONNMETHODL_EXIT );
       
   388         return;
       
   389         }
       
   390 
       
   391     iConnMethodArray[index]->ReloadPluginDataIfNeededL();
       
   392     if ( iConnMethodArray[index]->GetStatus() == ECmmConnMethodStatusValid
       
   393             || iConnMethodArray[index]->GetStatus() == ECmmConnMethodStatusToBeDeleted )
       
   394         {
       
   395         iConnMethodArray[index]->GetPlugin()->GetPluginDataL( 
       
   396                 aConnMethodInstance.GetPluginDataInstance() );
       
   397         }
       
   398     // Internal state need to be set to the same state as after a successfull update.
       
   399     aConnMethodInstance.UpdateSuccessful();
       
   400 
       
   401     OstTraceFunctionExit0( DUP1_CCMMCACHE_REFRESHCONNMETHODL_EXIT );
       
   402     }
       
   403 
       
   404 // ---------------------------------------------------------------------------
       
   405 // Creates a new connection method (not embedded destinations) into database
       
   406 // with the given bearer type and optionally ID, then creates and passes an
       
   407 // instance of it to the caller.
       
   408 // If destination instance is provided (not NULL), connection method is
       
   409 // created in that destination.
       
   410 // If connection method ID is provided, it's availability is verified.
       
   411 // ---------------------------------------------------------------------------
       
   412 //
       
   413 void CCmmCache::CreateConnMethodL(
       
   414         CCmmConnMethodInstance& aConnMethodInstance,
       
   415         CCmmDestinationInstance* aDestinationInstance,
       
   416         const TUint32 aBearerType,
       
   417         const TUint32 aConnMethodId )
       
   418     {
       
   419     OstTraceFunctionEntry0( CCMMCACHE_CREATECONNMETHODL_ENTRY );
       
   420 
       
   421     // Check that the bearer type is not embedded destination.
       
   422     if ( aBearerType == KUidEmbeddedDestination )
       
   423         {
       
   424         User::Leave( KErrArgument );
       
   425         }
       
   426 
       
   427     TUint32 connMethodId( aConnMethodId );
       
   428     if ( aConnMethodId )
       
   429         {
       
   430         // Check if a connection method with given ID exists (or is already
       
   431         // created but not saved).
       
   432         if ( iInstanceMapping->ValidConnMethodId( aConnMethodId ) ||
       
   433                 ConnMethodOpenWithId( aConnMethodId ) )
       
   434             {
       
   435             User::Leave( KErrAlreadyExists );
       
   436             }
       
   437         }
       
   438     else
       
   439         {
       
   440         // Use a temporary ID until a real one is received from database.
       
   441         connMethodId = NextFreeTemporaryId();
       
   442         }
       
   443 
       
   444 
       
   445     // Check bearer type support and create plugin instance.
       
   446     CCmPluginBaseEng* plugin = NULL;
       
   447     for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
   448         {
       
   449         if ( ( *iPlugins )[i]->GetBearerInfoIntL( CMManager::ECmBearerType ) == aBearerType )
       
   450             {
       
   451             TCmPluginInitParam pluginParams( Session() );
       
   452             plugin = ( *iPlugins )[i]->CreateInstanceL( pluginParams );
       
   453             CleanupStack::PushL( plugin );
       
   454             plugin->CreateNewL( aConnMethodId ); // Use aConnMethodId here, so ID is either a real ID or 0.
       
   455             break;
       
   456             }
       
   457         }
       
   458     if ( !plugin )
       
   459         {
       
   460         User::Leave( KErrArgument );
       
   461         }
       
   462 
       
   463 
       
   464     // Store the connection method into cache.
       
   465     // Use connMethodId here, so ID is either a real ID or a temporary ID.
       
   466     CCmmConnMethodStruct* connMethodStruct = CCmmConnMethodStruct::NewL( connMethodId );
       
   467     connMethodStruct->SetPlugin( plugin, aBearerType, ECmmConnMethodStatusNotSaved );
       
   468     CleanupStack::Pop( plugin );
       
   469     CleanupStack::PushL( connMethodStruct );
       
   470     iConnMethodArray.AppendL( connMethodStruct );
       
   471     CleanupStack::Pop( connMethodStruct );
       
   472 
       
   473     // Copy the connection method data to session instance.
       
   474     aConnMethodInstance.CopyDataL( connMethodStruct ); // Will increase reference counter.
       
   475 
       
   476 
       
   477     if ( aDestinationInstance )
       
   478         {
       
   479         // Add connection method to destination.
       
   480         aDestinationInstance->AddConnMethodL( aConnMethodInstance );
       
   481         }
       
   482 
       
   483     OstTraceFunctionExit0( CCMMCACHE_CREATECONNMETHODL_EXIT );
       
   484     }
       
   485 
       
   486 // ---------------------------------------------------------------------------
       
   487 // Creates a new connection method into cache as a copy of an existing
       
   488 // connection method (exists in cache, not necessarily in database), and opens
       
   489 // a client side handle to it. The new connection method will get a new ID when
       
   490 // updated to database.
       
   491 // ---------------------------------------------------------------------------
       
   492 //
       
   493 void CCmmCache::CreateCopyOfConnMethodL(
       
   494         CCmmConnMethodInstance& aNewConnMethodInstance,
       
   495         CCmmConnMethodInstance& aConnMethodInstance )
       
   496     {
       
   497     OstTraceFunctionEntry0( CCMMCACHE_CREATECOPYOFCONNMETHODL_ENTRY );
       
   498 
       
   499     // Check bearer type support and create plugin instance.
       
   500     TInt index = FindConnMethodFromCache( aConnMethodInstance.GetId() );
       
   501     if ( index == KErrNotFound )
       
   502         {
       
   503         User::Leave( index );
       
   504         }
       
   505 
       
   506     CCmPluginBaseEng* plugin = iConnMethodArray[index]->GetPlugin();
       
   507     if ( !plugin )
       
   508         {
       
   509         User::Leave( KErrNotFound );
       
   510         }
       
   511 
       
   512     CCmPluginBaseEng* pluginCopy =
       
   513             plugin->CreateCopyL( aConnMethodInstance.GetPluginDataInstance() );
       
   514     CleanupStack::PushL( pluginCopy );
       
   515 
       
   516     // Store the connection method into cache.
       
   517     CCmmConnMethodStruct* connMethodStruct =
       
   518             CCmmConnMethodStruct::NewL( NextFreeTemporaryId() );
       
   519     connMethodStruct->SetPlugin(
       
   520             pluginCopy,
       
   521             aConnMethodInstance.GetBearerType(),
       
   522             ECmmConnMethodStatusNotSaved );
       
   523     CleanupStack::Pop( pluginCopy );
       
   524     CleanupStack::PushL( connMethodStruct );
       
   525     iConnMethodArray.AppendL( connMethodStruct );
       
   526     CleanupStack::Pop( connMethodStruct );
       
   527 
       
   528     // Copy the connection method data to session instance.
       
   529     aNewConnMethodInstance.CopyDataL( connMethodStruct ); // Will increase reference counter.
       
   530 
       
   531     OstTraceFunctionExit0( CCMMCACHE_CREATECOPYOFCONNMETHODL_EXIT );
       
   532     }
       
   533 
       
   534 // ---------------------------------------------------------------------------
       
   535 // Reloads a destination record if needed and copies the latest version to
       
   536 // the session instance given as parameter.
       
   537 // ---------------------------------------------------------------------------
       
   538 //
       
   539 void CCmmCache::LoadDestinationRecordL(
       
   540         CCmmDestinationInstance& aDestinationInstance,
       
   541         TCmmDbRecords aDestRecordType )
       
   542     {
       
   543     OstTraceFunctionEntry0( CCMMCACHE_LOADDESTINATIONRECORDL_ENTRY );
       
   544 
       
   545     TUint32 id = aDestinationInstance.GetId();
       
   546     // If ID is not in the valid range, it means the destination is a newly
       
   547     // created one, and doesn't yet exist in database. Thus, record data exists
       
   548     // only in session side and can't be loaded from cache. So this is an error.
       
   549     if ( id >= KTemporaryIdCounterStart )
       
   550         {
       
   551         User::Leave( KErrCorrupt );
       
   552         }
       
   553     TInt index = FindDestinationFromCache( id );
       
   554     if ( index < 0 )
       
   555         {
       
   556         User::Leave( index );
       
   557         }
       
   558 
       
   559     iDestinationArray[index]->LoadRecordL( aDestinationInstance, aDestRecordType );
       
   560 
       
   561     OstTraceFunctionExit0( CCMMCACHE_LOADDESTINATIONRECORDL_EXIT );
       
   562     }
       
   563 
       
   564 // ---------------------------------------------------------------------------
       
   565 // Saves the modifications in aDestinationInstance into the database. Also all
       
   566 // connection methods inside this destination are updated (including any
       
   567 // embedded destination).
       
   568 // ---------------------------------------------------------------------------
       
   569 //
       
   570 void CCmmCache::UpdateDestinationL( CCmmDestinationInstance& aDestinationInstance )
       
   571     {
       
   572     OstTraceFunctionEntry0( CCMMCACHE_UPDATEDESTINATIONL_ENTRY );
       
   573 
       
   574     // Arrays to temporarily store information of updated destinations and
       
   575     // connection methods. Used to update status and ID information after
       
   576     // successful commit to database.
       
   577     if ( iTrans->GetReferenceCount() == 0 )
       
   578         {
       
   579         iDeletedConnMethods.Reset();
       
   580         iUpdatedConnMethods.Reset();
       
   581         iUpdatedConnMethods2.Reset();
       
   582         iUpdatedDestinations.Reset();
       
   583         iUpdatedDestinations2.Reset();
       
   584         }
       
   585 
       
   586     TInt index = FindDestinationFromCache( aDestinationInstance.GetId() );
       
   587     if ( index < 0 )
       
   588         {
       
   589         User::Leave( index );
       
   590         }
       
   591 
       
   592     iTrans->OpenTransactionLC();
       
   593 
       
   594     // Check that the connection methods marked for deletion can be deleted.
       
   595     for ( TInt i = 0; i < aDestinationInstance.iConnMethodsToBeDeleted.Count(); i++ )
       
   596         {
       
   597         TUint32 id = aDestinationInstance.iConnMethodsToBeDeleted[i];
       
   598 
       
   599         // Remove connection method from delete list if ID is not valid or if
       
   600         // referenced from any other destination (in database or in any other
       
   601         // client-side destination handles).
       
   602         if ( !iInstanceMapping->ValidConnMethodId( id ) ||
       
   603                 iInstanceMapping->ConnMethodInOtherDestination(
       
   604                         id,
       
   605                         aDestinationInstance.GetId() ) ||
       
   606                 aDestinationInstance.ConnMethodInOtherDestinationInSession( id, 0 ) )
       
   607             {
       
   608             aDestinationInstance.iConnMethodsToBeDeleted.Remove( i );
       
   609             i--; // Adjust array index counter.
       
   610             }
       
   611         else if ( iInstanceMapping->ConnMethodPointedToByVirtualIap( id ) )
       
   612             {
       
   613             aDestinationInstance.iConnMethodsToBeDeleted.Remove( i );
       
   614             User::Leave( KErrLocked );
       
   615             }
       
   616         else if ( CheckIfCmConnected( id ) )
       
   617             {
       
   618             User::Leave( KErrInUse );
       
   619             }
       
   620         }
       
   621     // Delete connection methods marked for deletion.
       
   622     for ( TInt i = 0; i < aDestinationInstance.iConnMethodsToBeDeleted.Count(); i++ )
       
   623         {
       
   624         DeleteConnMethodAsPartOfDestinationUpdateL(
       
   625                 aDestinationInstance.iConnMethodsToBeDeleted[i] );
       
   626         }
       
   627 
       
   628     // Update the connection methods inside this destination.
       
   629     for ( TInt i = 0; i < aDestinationInstance.iConnMethodItemArray.Count(); i++ )
       
   630         {
       
   631         if ( aDestinationInstance.iConnMethodItemArray[i].IsEmbedded() )
       
   632             {
       
   633             // Embedded destination.
       
   634 
       
   635             //TODO, Maybe check other restrictions on embedded destination.
       
   636             // - Only one embedded destination per destination. Check.
       
   637             // - No embedded destinations in embedded destination. Check.
       
   638 
       
   639             TUint32 id( aDestinationInstance.iConnMethodItemArray[i].iId );
       
   640             CCmmDestinationInstance* destinationInstance =
       
   641                     aDestinationInstance.FindDestinationInstanceFromSessionById( id );
       
   642 
       
   643             if ( destinationInstance )
       
   644                 {
       
   645                 // Client has a handle open to this destination, update it.
       
   646                 destinationInstance->UpdateL();
       
   647                 }
       
   648             else
       
   649                 {
       
   650                 // TODO: Or, should we update the embedded destination if the
       
   651                 // client has an open handle to any of the embedded
       
   652                 // destinations connection methods.
       
   653                 //
       
   654                 // Skip update since client doesn't have an open handle to this
       
   655                 // destination.
       
   656                 if ( id >= KTemporaryIdCounterStart ||
       
   657                         !iInstanceMapping->ValidDestinationId( id ) )
       
   658                     {
       
   659                     // Remove destination item from array if:
       
   660                     // - New destination, but client has already closed the handle for it.
       
   661                     // - Destination ID was valid before, but it does not exist anymore.
       
   662                     aDestinationInstance.iConnMethodItemArray.Remove( i );
       
   663                     i--; // Adjust array index counter.
       
   664                     }
       
   665                 }
       
   666             }
       
   667         else
       
   668             {
       
   669             TBool temporaryConnMethodInstance( EFalse );
       
   670             TBool connMethodProtectionMustBeSet( EFalse );
       
   671             TBool cmProtected( EFalse );
       
   672 
       
   673             TUint32 id( aDestinationInstance.iConnMethodItemArray[i].iId );
       
   674             CCmmConnMethodInstance* connMethodInstance =
       
   675                     aDestinationInstance.FindConnMethodInstanceFromSessionById( id );
       
   676 
       
   677             if ( !connMethodInstance )
       
   678                 {
       
   679                 // Remove connection method item from the array if it is a new
       
   680                 // connection method but client has already closed the handle
       
   681                 // for it, or the connection method ID was valid before but
       
   682                 // does not exist anymore.
       
   683                 if ( id >= KTemporaryIdCounterStart || !iInstanceMapping->ValidConnMethodId( id ) )
       
   684                     {
       
   685                     aDestinationInstance.iConnMethodItemArray.Remove( i );
       
   686                     i--; // Adjust array index counter.
       
   687                     continue; // Jump to next connection method.
       
   688                     }
       
   689                 }
       
   690 
       
   691             if ( aDestinationInstance.ProtectionChanged() )
       
   692                 {
       
   693                 // Check if the connection method protection level needs to be set.
       
   694                 switch ( aDestinationInstance.CurrentProtectionLevelL() )
       
   695                     {
       
   696                     case CMManager::EProtLevel0:
       
   697                     case CMManager::EProtLevel2:
       
   698                         {
       
   699                         if ( aDestinationInstance.LastProtectionLevel() ==
       
   700                                 CMManager::EProtLevel1 ||
       
   701                                 aDestinationInstance.LastProtectionLevel() ==
       
   702                                 CMManager::EProtLevel3 )
       
   703                             {
       
   704                             connMethodProtectionMustBeSet = ETrue;
       
   705                             cmProtected = EFalse;
       
   706                             }
       
   707                         }
       
   708                         break;
       
   709                     case CMManager::EProtLevel1:
       
   710                     case CMManager::EProtLevel3:
       
   711                         {
       
   712                         connMethodProtectionMustBeSet = ETrue;
       
   713                         cmProtected = ETrue;
       
   714                         }
       
   715                         break;
       
   716                     default:
       
   717                         break;
       
   718                     }
       
   719                 }
       
   720 
       
   721             if ( connMethodProtectionMustBeSet && !connMethodInstance )
       
   722                 {
       
   723                 // Client doesn't have an open handle to this connection method,
       
   724                 // but it still needs to be updated because the destination's
       
   725                 // protection level has been changed in such a way that
       
   726                 // requires a change in all contained connection methods also.
       
   727                 temporaryConnMethodInstance = ETrue;
       
   728                 connMethodInstance = CCmmConnMethodInstance::NewLC( NULL, this );
       
   729                 OpenConnMethodL( *connMethodInstance, NULL, id );
       
   730 
       
   731                 // Read current protection level.
       
   732                 TBool current = connMethodInstance->GetBoolAttributeL( CMManager::ECmProtected );
       
   733                 if ( cmProtected == current )
       
   734                     {
       
   735                     // If the connection method already has the correct
       
   736                     // protection setting, skip the unnecessary update.
       
   737                     connMethodProtectionMustBeSet = EFalse;
       
   738                     temporaryConnMethodInstance = EFalse;
       
   739                     CleanupStack::PopAndDestroy( connMethodInstance );
       
   740                     connMethodInstance = NULL;
       
   741                     }
       
   742                 }
       
   743 
       
   744             // Update the connection method.
       
   745             if ( connMethodInstance )
       
   746                 {
       
   747                 if ( connMethodProtectionMustBeSet )
       
   748                     {
       
   749                     connMethodInstance->SetBoolAttributeL( CMManager::ECmProtected, cmProtected );
       
   750                     }
       
   751                 connMethodInstance->UpdateL( temporaryConnMethodInstance );
       
   752                 }
       
   753 
       
   754             // Cleanup connection method handle, if it was temporary.
       
   755             if ( temporaryConnMethodInstance )
       
   756                 {
       
   757                 CleanupStack::PopAndDestroy( connMethodInstance );
       
   758                 }
       
   759             connMethodInstance = NULL;
       
   760             }
       
   761         }
       
   762     // All connection methods requiring update in the destination should have
       
   763     // been updated to database now.
       
   764 
       
   765     iDestinationArray[index]->UpdateL( aDestinationInstance, this );
       
   766     iTrans->CommitTransactionL();
       
   767 
       
   768     TCmmIdStruct idStruct( iDestinationArray[index]->GetRealId(), 0 );
       
   769     if ( aDestinationInstance.GetId() >= KTemporaryIdCounterStart )
       
   770         {
       
   771         idStruct.iTemporaryId = aDestinationInstance.GetId();
       
   772         }
       
   773     iUpdatedDestinations.AppendL( idStruct );
       
   774     iUpdatedDestinations2.AppendL( &aDestinationInstance );
       
   775 
       
   776     // Check transaction handler reference count.
       
   777     if ( iTrans->GetReferenceCount() == 0 )
       
   778         {
       
   779         // Successful commit to database. Refresh instance mapping and all
       
   780         // necessary status information.
       
   781         for ( TInt i = 0; i < iUpdatedConnMethods.Count(); i++ )
       
   782             {
       
   783             aDestinationInstance.RefreshHandlesForAllSessions( iUpdatedConnMethods[i] );
       
   784             }
       
   785         for ( TInt i = 0; i < iUpdatedConnMethods2.Count(); i++ )
       
   786             {
       
   787             iUpdatedConnMethods2[i]->UpdateSuccessful();
       
   788 
       
   789             TInt cacheIndex = FindConnMethodFromCache( iUpdatedConnMethods2[i]->GetId() );
       
   790             if ( cacheIndex >= 0 )
       
   791                 {
       
   792                 iConnMethodArray[cacheIndex]->UpdateSuccessful();
       
   793                 }
       
   794             }
       
   795         for ( TInt i = 0; i < iDeletedConnMethods.Count(); i++ )
       
   796             {
       
   797             TInt cacheIndex = FindConnMethodFromCache( iDeletedConnMethods[i].iRealId );
       
   798             if ( cacheIndex >= 0 )
       
   799                 {
       
   800                 aDestinationInstance.RefreshHandlesForAllSessions( iDeletedConnMethods[i] );
       
   801                 iConnMethodArray[cacheIndex]->SetStatus( ECmmConnMethodStatusToBeDeleted );
       
   802                 iInstanceMapping->AddConnMethodToDeletedListL( iDeletedConnMethods[i].iRealId );
       
   803                 }
       
   804             }
       
   805         for ( TInt i = 0; i < iUpdatedDestinations.Count(); i++ )
       
   806             {
       
   807             aDestinationInstance.RefreshHandlesForAllSessions( iUpdatedDestinations[i] );
       
   808             }
       
   809         for ( TInt i = 0; i < iUpdatedDestinations2.Count(); i++ )
       
   810             {
       
   811             iUpdatedDestinations2[i]->UpdateSuccessful();
       
   812 
       
   813             TInt cacheIndex = FindDestinationFromCache( iUpdatedDestinations2[i]->GetId() );
       
   814             if ( cacheIndex >= 0 )
       
   815                 {
       
   816                 iDestinationArray[cacheIndex]->UpdateSuccessful();
       
   817                 }
       
   818             }
       
   819         iDeletedConnMethods.Reset();
       
   820         iUpdatedConnMethods.Reset();
       
   821         iUpdatedConnMethods2.Reset();
       
   822         iUpdatedDestinations.Reset();
       
   823         iUpdatedDestinations2.Reset();
       
   824 
       
   825         iInstanceMapping->RefreshL();
       
   826         }
       
   827 
       
   828     OstTraceFunctionExit0( CCMMCACHE_UPDATEDESTINATIONL_EXIT );
       
   829     }
       
   830 
       
   831 // ---------------------------------------------------------------------------
       
   832 // Saves the modifications in aConnMethodInstance into database.
       
   833 // The second attribute aTemporaryHandle must be true if the connection method
       
   834 // instance is only a temporary one created for the duration of this update
       
   835 // process only.
       
   836 // ---------------------------------------------------------------------------
       
   837 //
       
   838 void CCmmCache::UpdateConnMethodL(
       
   839         CCmmConnMethodInstance& aConnMethodInstance,
       
   840         TBool aTemporaryHandle )
       
   841     {
       
   842     OstTraceFunctionEntry0( CCMMCACHE_UPDATECONNMETHODL_ENTRY );
       
   843 
       
   844     // Embedded destinatios cannot be updated as connection methods.
       
   845     if ( aConnMethodInstance.IsEmbeddedDestination() )
       
   846         {
       
   847         User::Leave( KErrNotSupported );
       
   848         }
       
   849 
       
   850     // Find connection method from cache.
       
   851     TUint32 connMethodId( aConnMethodInstance.GetId() );
       
   852     TInt index = FindConnMethodFromCache( connMethodId );
       
   853     if ( index < 0 )
       
   854         {
       
   855         // Should never end up here.
       
   856         User::Leave( index );
       
   857         }
       
   858 
       
   859     iTrans->OpenTransactionLC();
       
   860     iConnMethodArray[index]->GetPlugin()->UpdateL( aConnMethodInstance.GetPluginDataInstance() );
       
   861     iTrans->CommitTransactionL();
       
   862 
       
   863     TCmmIdStruct idStruct( aConnMethodInstance.GetPluginDataInstance()->iIapId, 0 );
       
   864     if ( connMethodId >= KTemporaryIdCounterStart )
       
   865         {
       
   866         idStruct.iTemporaryId = connMethodId;
       
   867         }
       
   868 
       
   869     if ( iTrans->GetReferenceCount() == 0 )
       
   870         {
       
   871         // Writing to database is completed, refresh instance mapping and all
       
   872         // necessary status information.
       
   873         iInstanceMapping->RefreshL();
       
   874         aConnMethodInstance.RefreshHandlesForAllSessions( idStruct );
       
   875         aConnMethodInstance.UpdateSuccessful();
       
   876         iConnMethodArray[index]->UpdateSuccessful();
       
   877         }
       
   878     else
       
   879         {
       
   880         // Update request came from destination update. Add connection method
       
   881         // information to temporary arrays so it's status information can be
       
   882         // updated after successful commit to database.
       
   883         iUpdatedConnMethods.AppendL( idStruct );
       
   884         if ( !aTemporaryHandle )
       
   885             {
       
   886             // A temporary handle will be destroyed after update, and so won't
       
   887             // need any status updates after commit.
       
   888             iUpdatedConnMethods2.AppendL( &aConnMethodInstance );
       
   889             }
       
   890         }
       
   891 
       
   892     OstTraceFunctionExit0( CCMMCACHE_UPDATECONNMETHODL_EXIT );
       
   893     }
       
   894 
       
   895 // ---------------------------------------------------------------------------
       
   896 // Deletes the destination refered by aDestinationInstance from the database.
       
   897 // In case other sessions have open handles to the same destination, the status
       
   898 // is updated to deleted state, but it is not yet removed from database.
       
   899 // (ID must be kept reserved in commsdat until all handles are closed). The
       
   900 // same is done for the connection methods inside this destination.
       
   901 // ---------------------------------------------------------------------------
       
   902 //
       
   903 void CCmmCache::DeleteDestinationL(
       
   904         CCmmDestinationInstance& aDestinationInstance,
       
   905         TBool aForced ) //TODO, comment on aForced param?
       
   906     {
       
   907     OstTraceFunctionEntry0( CCMMCACHE_DELETEDESTINATIONL_ENTRY );
       
   908 
       
   909     TUint32 destinationId( aDestinationInstance.GetId() );
       
   910 
       
   911     // Array to temporarily store deleted connection method IDs. Status
       
   912     // information for these connection methods is updated after successful
       
   913     // commit to database.
       
   914     iDeletedConnMethods.Reset();
       
   915 
       
   916     // Find destination from cache.
       
   917     TInt index = FindDestinationFromCache( destinationId );
       
   918     if ( index == KErrNotFound )
       
   919         {
       
   920         User::Leave( KErrBadHandle );
       
   921         }
       
   922 
       
   923     // If not forced, check if the destination is already marked to be deleted.
       
   924     if ( !aForced && iDestinationArray[index]->GetStatus() == ECmmDestinationStatusToBeDeleted )
       
   925         {
       
   926         OstTraceFunctionExit0( CCMMCACHE_DELETEDESTINATIONL_EXIT );
       
   927         return;
       
   928         }
       
   929 
       
   930     // Check if there are any additional handles open. If yes, can't delete
       
   931     // detination from database just yet.
       
   932     if ( iDestinationArray[index]->GetReferenceCount() <= 1 )
       
   933         {
       
   934         // No other client handles open to this destination.
       
   935 
       
   936         // Get the connection methods in this destination, and then go through
       
   937         // them removing those that can't be deleted.
       
   938         RArray<TCmmConnMethodItem> connMethodArray;
       
   939         CleanupClosePushL( connMethodArray );
       
   940         if ( !aForced )
       
   941             {
       
   942             iInstanceMapping->GetConnMethodsFromDestinationL( destinationId, connMethodArray );
       
   943             }
       
   944         else
       
   945             {
       
   946             for ( TInt i = 0; i < aDestinationInstance.iConnMethodItemArray.Count() ; i++ )
       
   947                 {
       
   948                 connMethodArray.AppendL( aDestinationInstance.iConnMethodItemArray[i] );
       
   949                 }
       
   950             }
       
   951 
       
   952         // Remove embedded destination from list if found.
       
   953         TInt count( connMethodArray.Count() );
       
   954         if ( count )
       
   955             {
       
   956             if ( connMethodArray[count - 1].IsEmbedded() )
       
   957                 {
       
   958                 connMethodArray.Remove( count - 1 );
       
   959                 }
       
   960             }
       
   961         // Remove any connection method that belongs to any other destination.
       
   962         for ( TInt i = 0; i < connMethodArray.Count(); i++ )
       
   963             {
       
   964             if ( iInstanceMapping->ConnMethodInOtherDestination(
       
   965                     connMethodArray[i].iId,
       
   966                     destinationId ) )
       
   967                 {
       
   968                 connMethodArray.Remove( i );
       
   969                 i--;
       
   970                 }
       
   971             }
       
   972         // Remove any connection method that has a virtual IAP pointing to it.
       
   973         for ( TInt i = 0; i < connMethodArray.Count(); i++ )
       
   974             {
       
   975             if ( iInstanceMapping->ConnMethodPointedToByVirtualIap( connMethodArray[i].iId ) )
       
   976                 {
       
   977                 connMethodArray.Remove( i );
       
   978                 i--;
       
   979                 }
       
   980             }
       
   981 
       
   982         iTrans->OpenTransactionLC();
       
   983 
       
   984         // Delete each connection method inside this destination.
       
   985         for ( TInt i = 0; i < connMethodArray.Count(); i++ )
       
   986             {
       
   987             DeleteConnMethodAsPartOfDestinationDeleteL( connMethodArray[i].iId );
       
   988             }
       
   989 
       
   990         // Delete the destination.
       
   991         iDestinationArray[index]->DeleteL();
       
   992 
       
   993         iTrans->CommitTransactionL();
       
   994         CleanupStack::PopAndDestroy( &connMethodArray );
       
   995 
       
   996         for ( TInt i = 0; i < iDeletedConnMethods.Count(); i++ )
       
   997             {
       
   998             TInt index = FindConnMethodFromCache( iDeletedConnMethods[i].iRealId );
       
   999             if ( index == KErrNotFound )
       
  1000                 {
       
  1001                 // No handles open to this deleted connection method, so it was
       
  1002                 // removed from database. Remove it from instance mapping
       
  1003                 // structures. Refreshing instance mapping would do the same,
       
  1004                 // but more slowly.
       
  1005                 iInstanceMapping->RemoveConnMethod( iDeletedConnMethods[i].iRealId );
       
  1006                 }
       
  1007             else
       
  1008                 {
       
  1009                 // There is at least one handle open to this deleted connection
       
  1010                 // method, so it still exists in database for now. Remove it
       
  1011                 // from instance mapping structures and add it to the instance
       
  1012                 // mapping's deleted list, so the connection method is ignored
       
  1013                 // if refreshing structures from database. Also mark the
       
  1014                 // connection method handle on cache side as 'to be deleted'.
       
  1015                 //
       
  1016                 // If the connection method is updated from another existing
       
  1017                 // handle after this, the connection method is restored as
       
  1018                 // uncategorized.
       
  1019                 iInstanceMapping->AddConnMethodToDeletedListL( iDeletedConnMethods[i].iRealId );
       
  1020                 aDestinationInstance.RefreshHandlesForAllSessions( iDeletedConnMethods[i] );
       
  1021                 iConnMethodArray[index]->SetStatus( ECmmConnMethodStatusToBeDeleted );
       
  1022                 }
       
  1023             }
       
  1024         iInstanceMapping->RemoveDestination( destinationId );
       
  1025         }
       
  1026     else
       
  1027         {
       
  1028         // There are additional client handles open to this destination. Mark
       
  1029         // the destination as 'to be deleted'. When the other handles are
       
  1030         // closed and reference count goes to 0, the destination will be
       
  1031         // removed from database.
       
  1032         // If the destination is updated from another existing handle after
       
  1033         // this, the destination is restored to normal.
       
  1034         iDestinationArray[index]->SetStatus( ECmmDestinationStatusToBeDeleted );
       
  1035         iInstanceMapping->AddDestinationToDeletedListL( destinationId );
       
  1036         }
       
  1037 
       
  1038     // Update status for ALL related destination handles on client side to
       
  1039     // ECmmDestinationStatusChanged.
       
  1040     TCmmIdStruct idStruct( destinationId, 0 );
       
  1041     aDestinationInstance.RefreshHandlesForAllSessions( idStruct );
       
  1042 
       
  1043     iDeletedConnMethods.Reset();
       
  1044     OstTraceFunctionExit0( DUP1_CCMMCACHE_DELETEDESTINATIONL_EXIT );
       
  1045     }
       
  1046 
       
  1047 // ---------------------------------------------------------------------------
       
  1048 // Deletes a connection method as part of destination delete operation. It is
       
  1049 // already checked that the connection method given as parameter can be deleted
       
  1050 // and a transaction is already open.
       
  1051 // If there are client side handles open to the connection method, the
       
  1052 // connection method is marked as deleted, but the actual database removal will
       
  1053 // be done after the last handle is closed. Updating a connection method marked
       
  1054 // as deleted (through an already open handle) will restore it.
       
  1055 // ---------------------------------------------------------------------------
       
  1056 //
       
  1057 void CCmmCache::DeleteConnMethodAsPartOfDestinationDeleteL( const TUint32 aConnMethodId )
       
  1058     {
       
  1059     OstTraceFunctionEntry0( CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONDELETEL_ENTRY );
       
  1060 
       
  1061     // Find connection method from cache side.
       
  1062     TInt index = FindConnMethodFromCache( aConnMethodId );
       
  1063     if ( index == KErrNotFound )
       
  1064         {
       
  1065         // There is no open handles to this connection method. Open a temporary
       
  1066         // handle and delete it.
       
  1067 
       
  1068         // Find out the connection method bearer type.
       
  1069         TUint32 bearerType( 0 );
       
  1070         TInt err = iInstanceMapping->GetConnMethodBearerType( aConnMethodId, bearerType );
       
  1071         if ( err || bearerType == KUidEmbeddedDestination )
       
  1072             {
       
  1073             // If this is an embedded destination, or the bearer is not
       
  1074             // supported, skip. The connection method is simply removed from
       
  1075             // destination.
       
  1076             OstTraceFunctionExit0( CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONDELETEL_EXIT );
       
  1077             return;
       
  1078             }
       
  1079 
       
  1080         // Check bearer type support, create plugin instance and delete the
       
  1081         // connection method.
       
  1082         CCmPluginBaseEng* plugin = NULL;
       
  1083         for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
  1084             {
       
  1085             if ( ( *iPlugins )[i]->GetBearerInfoIntL( CMManager::ECmBearerType ) == bearerType )
       
  1086                 {
       
  1087                 TCmPluginInitParam pluginParams( Session() );
       
  1088                 plugin = ( *iPlugins )[i]->CreateInstanceL( pluginParams );
       
  1089                 CleanupStack::PushL( plugin );
       
  1090 
       
  1091                 // Transaction is already open.
       
  1092                 plugin->LoadL( aConnMethodId );
       
  1093                 plugin->DeleteL();
       
  1094 
       
  1095                 CleanupStack::Pop( plugin );
       
  1096                 break;
       
  1097                 }
       
  1098             }
       
  1099         if ( !plugin )
       
  1100             {
       
  1101             // Skip, if bearer is unsupported. Connection method is simply
       
  1102             // removed from destination.
       
  1103             OstTraceFunctionExit0( DUP1_CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONDELETEL_EXIT );
       
  1104             return;
       
  1105             }
       
  1106         delete plugin;
       
  1107         plugin = NULL;
       
  1108         }
       
  1109     else
       
  1110         {
       
  1111         // If the connection method is already open in cache side, we can't
       
  1112         // delete it from database just yet. It will only be marked as 'to be
       
  1113         // deleted' after a successful commit. When the other handles are
       
  1114         // closed and reference count goes to 0, the connection method will be
       
  1115         // removed from database.
       
  1116 
       
  1117         // Check destination status in cache.
       
  1118         switch ( iConnMethodArray[index]->GetStatus() )
       
  1119             {
       
  1120             case ECmmConnMethodStatusNotSaved:
       
  1121                 {
       
  1122                 // The connection methods that are deleted with the destination
       
  1123                 // are retrieved through instance mapping, so there can't be
       
  1124                 // any newly created unsaved connection methods among them.
       
  1125                 User::Leave( KErrCorrupt );
       
  1126                 }
       
  1127                 break;
       
  1128             case ECmmConnMethodStatusValid:
       
  1129                 // Proceed.
       
  1130                 break;
       
  1131             case ECmmConnMethodStatusToBeDeleted:
       
  1132                 // Connection method has already been deleted.
       
  1133                 OstTraceFunctionExit0( DUP2_CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONDELETEL_EXIT );
       
  1134                 return;
       
  1135             case ECmmConnMethodStatusChanged:
       
  1136             default:
       
  1137                 {
       
  1138                 ASSERT( 0 ); // Error, illegal status.
       
  1139                 User::Leave( KErrCorrupt );
       
  1140                 }
       
  1141                 break;
       
  1142             }
       
  1143         }
       
  1144 
       
  1145     // Add connection method ID to temporary array so it's status information
       
  1146     // can be updated after successful commit to database.
       
  1147     TCmmIdStruct idStruct( aConnMethodId, 0 );
       
  1148     iDeletedConnMethods.AppendL( idStruct );
       
  1149 
       
  1150     OstTraceFunctionExit0( DUP3_CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONDELETEL_EXIT );
       
  1151     }
       
  1152 
       
  1153 // ---------------------------------------------------------------------------
       
  1154 // Deletes a connection method as part of destination update operation. It is
       
  1155 // already checked that the connection method given as parameter can be deleted
       
  1156 // and a transaction is already open.
       
  1157 // If there are client side handles open to the connection method, the
       
  1158 // connection method is marked as deleted, but the actual database removal will
       
  1159 // be done after the last handle is closed. Updating a connection method marked
       
  1160 // as deleted (through an already open handle) will restore it.
       
  1161 // ---------------------------------------------------------------------------
       
  1162 //
       
  1163 void CCmmCache::DeleteConnMethodAsPartOfDestinationUpdateL(
       
  1164         const TUint32 aConnMethodId )
       
  1165     {
       
  1166     OstTraceFunctionEntry0( CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONUPDATEL_ENTRY );
       
  1167 
       
  1168     // Find connection method from cache side. If not found, open a temporary handle.
       
  1169     TInt index = FindConnMethodFromCache( aConnMethodId );
       
  1170     if ( index == KErrNotFound )
       
  1171         {
       
  1172         // There are no open handles to this connection method. Open a
       
  1173         // temporary handle and delete it.
       
  1174 
       
  1175         // Find out the connection method bearer type.
       
  1176         TUint32 bearerType( 0 );
       
  1177         TInt err = iInstanceMapping->GetConnMethodBearerType( aConnMethodId, bearerType );
       
  1178         if ( err || bearerType == KUidEmbeddedDestination )
       
  1179             {
       
  1180             // If this is an embedded destination, or the bearer is not
       
  1181             // supported, skip. The connection method is simply removed from
       
  1182             // destination.
       
  1183             OstTraceFunctionExit0( CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONUPDATEL_EXIT );
       
  1184             return;
       
  1185             }
       
  1186 
       
  1187         // Check bearer type support, create plugin instance and delete the connection method.
       
  1188         CCmPluginBaseEng* plugin = NULL;
       
  1189         for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
  1190             {
       
  1191             if ( ( *iPlugins )[i]->GetBearerInfoIntL( CMManager::ECmBearerType ) == bearerType )
       
  1192                 {
       
  1193                 TCmPluginInitParam pluginParams( Session() );
       
  1194                 plugin = ( *iPlugins )[i]->CreateInstanceL( pluginParams );
       
  1195                 CleanupStack::PushL( plugin );
       
  1196                 iTrans->OpenTransactionLC();
       
  1197 
       
  1198                 plugin->LoadL( aConnMethodId );
       
  1199                 plugin->DeleteL();
       
  1200 
       
  1201                 iTrans->CommitTransactionL();
       
  1202                 CleanupStack::Pop( plugin );
       
  1203                 break;
       
  1204                 }
       
  1205             }
       
  1206         if ( !plugin )
       
  1207             {
       
  1208             // Skip, if bearer is unsupported. Connection method is simply
       
  1209             // removed from destination.
       
  1210             OstTraceFunctionExit0( DUP1_CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONUPDATEL_EXIT );
       
  1211             return;
       
  1212             }
       
  1213         delete plugin;
       
  1214         plugin = NULL;
       
  1215 
       
  1216         // Destination update will refresh instance mapping anyway at the end,
       
  1217         // so no need to add this connection method to the temporary
       
  1218         // iDeletedConnMethods-array here.
       
  1219         }
       
  1220     else
       
  1221         {
       
  1222         // There is one or more open handles to this connection method. We
       
  1223         // can't delete it from database just yet. It will only be marked as
       
  1224         // 'to be deleted' after a successful commit. When the other handles
       
  1225         // are closed and reference count goes to 0, the connection method will
       
  1226         // be removed from database.
       
  1227 
       
  1228         // Check connection method status.
       
  1229         switch ( iConnMethodArray[index]->GetStatus() )
       
  1230             {
       
  1231             case ECmmConnMethodStatusNotSaved:
       
  1232                 {
       
  1233                 // Destination update will not attempt to delete any non-valid
       
  1234                 // connection methods.
       
  1235                 User::Leave( KErrCorrupt );
       
  1236                 }
       
  1237                 break;
       
  1238             case ECmmConnMethodStatusValid:
       
  1239                 // Proceed.
       
  1240                 break;
       
  1241             case ECmmConnMethodStatusToBeDeleted:
       
  1242                 // Connection method has already been deleted.
       
  1243                 OstTraceFunctionExit0( DUP2_CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONUPDATEL_EXIT );
       
  1244                 return;
       
  1245             case ECmmConnMethodStatusChanged:
       
  1246             default:
       
  1247                 {
       
  1248                 ASSERT( 0 ); // Error, illegal status.
       
  1249                 User::Leave( KErrCorrupt );
       
  1250                 }
       
  1251                 break;
       
  1252             }
       
  1253         // Add connection method ID to temporary array so it's status
       
  1254         // information can be updated after successful commit to database.
       
  1255         TCmmIdStruct idStruct( aConnMethodId, 0 );
       
  1256         iDeletedConnMethods.AppendL( idStruct );
       
  1257         }
       
  1258 
       
  1259     OstTraceFunctionExit0( DUP3_CCMMCACHE_DELETECONNMETHODASPARTOFDESTINATIONUPDATEL_EXIT );
       
  1260     }
       
  1261 
       
  1262 // ---------------------------------------------------------------------------
       
  1263 // Basic connection method delete. Removes a connection method from any
       
  1264 // destination it might belong to, and then deletes it.
       
  1265 // ---------------------------------------------------------------------------
       
  1266 //
       
  1267 void CCmmCache::DeleteConnMethodL( CCmmConnMethodInstance& aConnMethodInstance )
       
  1268     {
       
  1269     OstTraceFunctionEntry0( DUP1_CCMMCACHE_DELETECONNMETHODL_ENTRY );
       
  1270 
       
  1271     TUint32 cmId = aConnMethodInstance.GetId();
       
  1272 
       
  1273     // Find connection method from cache.
       
  1274     TInt index = FindConnMethodFromCache( cmId );
       
  1275     if ( index == KErrNotFound )
       
  1276         {
       
  1277         User::Leave( KErrBadHandle );
       
  1278         }
       
  1279 
       
  1280     // Check if the connection method is already deleted.
       
  1281     if ( iConnMethodArray[index]->GetStatus() == ECmmConnMethodStatusToBeDeleted )
       
  1282         {
       
  1283         OstTraceFunctionExit0( DUP1_CCMMCACHE_DELETECONNMETHODL_EXIT );
       
  1284         return;
       
  1285         }
       
  1286 
       
  1287     // Check if there are any additional handles open. If yes, can't delete
       
  1288     // connection method from database just yet.
       
  1289     if ( iConnMethodArray[index]->GetReferenceCounter() <= 1 )
       
  1290         {
       
  1291         // No other client handles open to this connection method.
       
  1292 
       
  1293         // Remove connection method from any destination in database and then delete it.
       
  1294         iTrans->OpenTransactionLC();
       
  1295         RemoveAllReferencesToConnMethodL( aConnMethodInstance );
       
  1296         iConnMethodArray[index]->GetPlugin()->DeleteL();
       
  1297         iTrans->CommitTransactionL();
       
  1298 
       
  1299         // Update instance mapping to reflect the current database state, and
       
  1300         // notify any possible client handles for the changed destinations.
       
  1301         RArray<TUint32> changedDestinations;
       
  1302         iInstanceMapping->RemoveConnMethod( cmId, changedDestinations );
       
  1303         for ( TInt i = 0; i < changedDestinations.Count(); i++ )
       
  1304             {
       
  1305             TCmmIdStruct idStruct( changedDestinations[i], 0 );
       
  1306             aConnMethodInstance.RefreshHandlesForAllSessions( idStruct );
       
  1307             }
       
  1308         changedDestinations.Close();
       
  1309 
       
  1310         // Set status for cache and client handles.
       
  1311         TUint32 newSecondaryId( NextFreeTemporaryId() );
       
  1312         aConnMethodInstance.DeleteSuccessful( newSecondaryId );
       
  1313         iConnMethodArray[index]->DeleteSuccessful( newSecondaryId );
       
  1314         }
       
  1315     else
       
  1316         {
       
  1317         // There are additional client handles open to this connection method.
       
  1318         // Mark the connection method as 'to be deleted' and remove it from any
       
  1319         // destinations in database. When the other handles are closed and
       
  1320         // reference count goes to 0, the connection method will be removed
       
  1321         // from database.
       
  1322         RemoveAllReferencesToConnMethodL( aConnMethodInstance );
       
  1323         iInstanceMapping->AddConnMethodToDeletedListL( cmId );
       
  1324         TCmmIdStruct idStruct( cmId, 0 );
       
  1325         aConnMethodInstance.RefreshHandlesForAllSessions( idStruct );
       
  1326         iConnMethodArray[index]->SetStatus( ECmmConnMethodStatusToBeDeleted );
       
  1327         }
       
  1328 
       
  1329     OstTraceFunctionExit0( DUP2_CCMMCACHE_DELETECONNMETHODL_EXIT );
       
  1330     }
       
  1331 
       
  1332 // ---------------------------------------------------------------------------
       
  1333 // Check if the given ID belongs to a valid existing destination. Attribute
       
  1334 // aId needs to be in the current valid range (0x1001 - 0x10FF atm).
       
  1335 // ---------------------------------------------------------------------------
       
  1336 //
       
  1337 TBool CCmmCache::DestinationExistsWithId( const TUint32 aId )
       
  1338     {
       
  1339     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONEXISTSWITHID_ENTRY );
       
  1340 
       
  1341     TBool exists = iInstanceMapping->ValidDestinationId( aId );
       
  1342 
       
  1343     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONEXISTSWITHID_EXIT );
       
  1344     return exists;
       
  1345     }
       
  1346 
       
  1347 // ---------------------------------------------------------------------------
       
  1348 // Check if the given name belongs to an existing destination.
       
  1349 // If a destination ID is given, that destination is skipped.
       
  1350 // ---------------------------------------------------------------------------
       
  1351 //
       
  1352 TBool CCmmCache::DestinationExistsWithNameL( const TDesC& aName, const TUint32 aDestinationId )
       
  1353     {
       
  1354     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONEXISTSWITHNAMEL_ENTRY );
       
  1355 
       
  1356     TBool found( EFalse );
       
  1357 
       
  1358     // Check AccessPoint-table.
       
  1359     CommsDat::CCDAccessPointRecord* destApRecord = static_cast<CommsDat::CCDAccessPointRecord*>(
       
  1360             CommsDat::CCDRecordBase::RecordFactoryL( CommsDat::KCDTIdAccessPointRecord ) );
       
  1361     CleanupStack::PushL( destApRecord );
       
  1362     destApRecord->iRecordName.SetL( aName );
       
  1363     if ( destApRecord->FindL( iTrans->Session() ) ) // Names should be unique.
       
  1364         {
       
  1365         if ( aDestinationId )
       
  1366             {
       
  1367             // Check the ID is different.
       
  1368             destApRecord->LoadL( iTrans->Session() );
       
  1369             if ( aDestinationId != destApRecord->iRecordTag )
       
  1370                 {
       
  1371                 found = ETrue;
       
  1372                 }
       
  1373             }
       
  1374         else
       
  1375             {
       
  1376             found = ETrue;
       
  1377             }
       
  1378         }
       
  1379     CleanupStack::PopAndDestroy( destApRecord );
       
  1380 
       
  1381     // Check also DataMobilitySelectionPolicy-table.
       
  1382     if ( !found )
       
  1383         {
       
  1384         CCDDataMobilitySelectionPolicyRecord* snapRecord =
       
  1385                 new( ELeave ) CCDDataMobilitySelectionPolicyRecord(
       
  1386                         iCmManagerImpl->TableId( ECmmDbSnapRecord ) );
       
  1387         CleanupStack::PushL( snapRecord );
       
  1388         snapRecord->iRecordName.SetL( aName );
       
  1389         if ( snapRecord->FindL( iTrans->Session() ) ) // Names should be unique.
       
  1390             {
       
  1391             if ( aDestinationId )
       
  1392                 {
       
  1393                 // Check the ID is different.
       
  1394                 snapRecord->LoadL( iTrans->Session() );
       
  1395                 if ( aDestinationId != snapRecord->iSNAP )
       
  1396                     {
       
  1397                     found = ETrue;
       
  1398                     }
       
  1399                 }
       
  1400             else
       
  1401                 {
       
  1402                 found = ETrue;
       
  1403                 }
       
  1404             }
       
  1405         CleanupStack::PopAndDestroy( snapRecord );
       
  1406         }
       
  1407 
       
  1408     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONEXISTSWITHNAMEL_EXIT );
       
  1409     return found;
       
  1410     }
       
  1411 
       
  1412 // ---------------------------------------------------------------------------
       
  1413 // Check if the given ID belongs to a destination that the cache has an open
       
  1414 // handle on. This will include any destinations created by any client, that
       
  1415 // are not yet saved to database.
       
  1416 // With this check, we can prevent two clients from creating a new destination
       
  1417 // with the same ID (The UpdateL() operation would fail for one of them anyway).
       
  1418 // ---------------------------------------------------------------------------
       
  1419 //
       
  1420 TBool CCmmCache::DestinationOpenWithId( const TUint32 aId )
       
  1421     {
       
  1422     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONOPENWITHID_ENTRY );
       
  1423 
       
  1424     TBool result( EFalse );
       
  1425     TInt index = FindDestinationFromCache( aId );
       
  1426     if ( index != KErrNotFound )
       
  1427         {
       
  1428         result = ETrue;
       
  1429         }
       
  1430 
       
  1431     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONOPENWITHID_EXIT );
       
  1432     return result;
       
  1433     }
       
  1434 
       
  1435 // ---------------------------------------------------------------------------
       
  1436 // Check if the given name belongs to any new unsaved destinations in the
       
  1437 // cache. This includes any destinations created byany client, that are not
       
  1438 // yet saved to database.
       
  1439 // If a destination ID is provided, the search will exclude the relevant
       
  1440 // destination.
       
  1441 // With this check, we can prevent two clients from creating a new destination
       
  1442 // with the same name (The UpdateL() operation would fail for one of them
       
  1443 // anyway).
       
  1444 // ---------------------------------------------------------------------------
       
  1445 //
       
  1446 TBool CCmmCache::NotSavedDestinationOpenWithNameL(
       
  1447         const TDesC& aName,
       
  1448         const TUint32 aDestinationId )
       
  1449     {
       
  1450     OstTraceFunctionEntry0( CCMMCACHE_NOTSAVEDDESTINATIONOPENWITHNAMEL_ENTRY );
       
  1451 
       
  1452     TBool res( EFalse );
       
  1453     TInt index = FindNotSavedDestinationFromCacheL( aName, aDestinationId );
       
  1454     if ( index != KErrNotFound )
       
  1455         {
       
  1456         res = ETrue;
       
  1457         }
       
  1458 
       
  1459     OstTraceFunctionExit0( CCMMCACHE_NOTSAVEDDESTINATIONOPENWITHNAMEL_EXIT );
       
  1460     return res;
       
  1461     }
       
  1462 
       
  1463 // ---------------------------------------------------------------------------
       
  1464 // Check if the given ID belongs to a valid existing connection method.
       
  1465 // ---------------------------------------------------------------------------
       
  1466 //
       
  1467 TBool CCmmCache::ConnMethodExistsWithId( const TUint32 aConnMethodId )
       
  1468     {
       
  1469     OstTraceFunctionEntry0( CCMMCACHE_CONNMETHODEXISTSWITHID_ENTRY );
       
  1470 
       
  1471     TBool exists = iInstanceMapping->ValidConnMethodId( aConnMethodId );
       
  1472 
       
  1473     OstTraceFunctionExit0( CCMMCACHE_CONNMETHODEXISTSWITHID_EXIT );
       
  1474     return exists;
       
  1475     }
       
  1476 
       
  1477 // ---------------------------------------------------------------------------
       
  1478 // Check if the given ID belongs to a connection method that the cache has an
       
  1479 // open handle on. This will include any connection methods created by any
       
  1480 // client, that are not yet saved to database.
       
  1481 // With this check, we can prevent two clients from creating a new connection
       
  1482 // method with the same ID (The UpdateL() operation would fail for one of them
       
  1483 // anyway).
       
  1484 // ---------------------------------------------------------------------------
       
  1485 //
       
  1486 TBool CCmmCache::ConnMethodOpenWithId( const TUint32 aConnMethodId )
       
  1487     {
       
  1488     OstTraceFunctionEntry0( CCMMCACHE_CONNMETHODOPENWITHID_ENTRY );
       
  1489 
       
  1490     TBool result( EFalse );
       
  1491     TInt index = FindConnMethodFromCache( aConnMethodId );
       
  1492     if ( index != KErrNotFound )
       
  1493         {
       
  1494         result = ETrue;
       
  1495         }
       
  1496 
       
  1497     OstTraceFunctionExit0( CCMMCACHE_CONNMETHODOPENWITHID_EXIT );
       
  1498     return result;
       
  1499     }
       
  1500 
       
  1501 // ---------------------------------------------------------------------------
       
  1502 // Checks if there are any destinations with metadata localization
       
  1503 // (ESnapMetadataDestinationIsLocalised) set to aValue. Also checks the
       
  1504 // relevant metadata purpose (ESnapMetadataPurpose) values.
       
  1505 // The destination connected to parameter aDestinationInstance is skipped.
       
  1506 // ---------------------------------------------------------------------------
       
  1507 //
       
  1508 TBool CCmmCache::DestinationExistsWithMetadataLocalizedL(
       
  1509         CCmmDestinationInstance& aDestinationInstance,
       
  1510         const TUint32 aValue )
       
  1511     {
       
  1512     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONEXISTSWITHMETADATALOCALIZEDL_ENTRY );
       
  1513 
       
  1514     TBool result( EFalse );
       
  1515 
       
  1516     if ( aValue != CMManager::ENotLocalisedDest )
       
  1517         {
       
  1518         // Check there is no destination in database that already has the same
       
  1519         // localization metadata value. Also checks metadata purpose.
       
  1520         CommsDat::CMDBRecordSet<CCDSNAPMetadataRecord>* metaSet =
       
  1521                 new( ELeave )CommsDat::CMDBRecordSet<CCDSNAPMetadataRecord>(
       
  1522                         iCmManagerImpl->TableId( ECmmDestMetadataRecord ) );
       
  1523         CleanupStack::PushL( metaSet );
       
  1524         TRAP_IGNORE( metaSet->LoadL( iTrans->Session() ) );
       
  1525         for ( TInt i = 0; i < metaSet->iRecords.Count(); i++ )
       
  1526             {
       
  1527             TInt id = ( ( CCDSNAPMetadataRecord* )metaSet->iRecords[i] )->iSNAP;
       
  1528             TUint32 metadata = ( ( CCDSNAPMetadataRecord* )metaSet->iRecords[i] )->iMetadata;
       
  1529             TUint32 localizationValue =
       
  1530                     ( metadata & CMManager::ESnapMetadataDestinationIsLocalised ) >> 4;
       
  1531             TUint32 purposeValue = ( metadata & CMManager::ESnapMetadataPurpose ) >> 8;
       
  1532 
       
  1533             if ( aDestinationInstance.GetId() != id )
       
  1534                 {
       
  1535                 if ( aValue == localizationValue )
       
  1536                     {
       
  1537                     result = ETrue;
       
  1538                     }
       
  1539                 switch ( aValue )
       
  1540                     {
       
  1541                     case CMManager::ELocalisedDestInternet:
       
  1542                         {
       
  1543                         if ( purposeValue == CMManager::ESnapPurposeInternet ||
       
  1544                                 ( metadata & CMManager::ESnapMetadataInternet ) )
       
  1545                             {
       
  1546                             result = ETrue;
       
  1547                             }
       
  1548                         }
       
  1549                         break;
       
  1550                     case CMManager::ELocalisedDestWap:
       
  1551                         {
       
  1552                         if ( purposeValue == CMManager::ESnapPurposeOperator )
       
  1553                             {
       
  1554                             result = ETrue;
       
  1555                             }
       
  1556                         }
       
  1557                         break;
       
  1558                     case CMManager::ELocalisedDestMMS:
       
  1559                         {
       
  1560                         if ( purposeValue == CMManager::ESnapPurposeMMS )
       
  1561                             {
       
  1562                             result = ETrue;
       
  1563                             }
       
  1564                         }
       
  1565                         break;
       
  1566                     case CMManager::ELocalisedDestIntranet:
       
  1567                         {
       
  1568                         if ( purposeValue == CMManager::ESnapPurposeIntranet )
       
  1569                             {
       
  1570                             result = ETrue;
       
  1571                             }
       
  1572                         }
       
  1573                         break;
       
  1574                     default:
       
  1575                         break;
       
  1576                     }
       
  1577                 }
       
  1578             }
       
  1579         CleanupStack::PopAndDestroy( metaSet );
       
  1580         }
       
  1581 
       
  1582     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONEXISTSWITHMETADATALOCALIZEDL_EXIT );
       
  1583     return result;
       
  1584     }
       
  1585 
       
  1586 // ---------------------------------------------------------------------------
       
  1587 // Checks if there are any destinations with metadata purpose
       
  1588 // (ESnapMetadataPurpose) set to aValue. Also checks the relevant metadata
       
  1589 // localization (ESnapMetadataDestinationIsLocalised) values.
       
  1590 // The destination connected to parameter aDestinationInstance is skipped.
       
  1591 // ---------------------------------------------------------------------------
       
  1592 //
       
  1593 TBool CCmmCache::DestinationExistsWithMetadataPurposeL(
       
  1594         CCmmDestinationInstance& aDestinationInstance,
       
  1595         const TUint32 aValue )
       
  1596     {
       
  1597     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONEXISTSWITHMETADATAPURPOSEL_ENTRY );
       
  1598 
       
  1599     TBool result( EFalse );
       
  1600 
       
  1601     if ( aValue != CMManager::ESnapPurposeUnknown )
       
  1602         {
       
  1603         // Check there is no destination in database that already has the same
       
  1604         // metadata purpose value. Also checks localization metadata.
       
  1605         CommsDat::CMDBRecordSet<CCDSNAPMetadataRecord>* metaSet =
       
  1606                 new( ELeave )CommsDat::CMDBRecordSet<CCDSNAPMetadataRecord>(
       
  1607                         iCmManagerImpl->TableId( ECmmDestMetadataRecord ) );
       
  1608         CleanupStack::PushL( metaSet );
       
  1609         TRAP_IGNORE( metaSet->LoadL( iTrans->Session() ) );
       
  1610         for ( TInt i = 0; i < metaSet->iRecords.Count(); i++ )
       
  1611             {
       
  1612             TInt id = ( ( CCDSNAPMetadataRecord* )metaSet->iRecords[i] )->iSNAP;
       
  1613             TUint32 metadata = ( ( CCDSNAPMetadataRecord* )metaSet->iRecords[i] )->iMetadata;
       
  1614             TUint32 localizationValue =
       
  1615                     ( metadata & CMManager::ESnapMetadataDestinationIsLocalised ) >> 4;
       
  1616             TUint32 purposeValue = ( metadata & CMManager::ESnapMetadataPurpose ) >> 8;
       
  1617 
       
  1618             if ( aDestinationInstance.GetId() != id )
       
  1619                 {
       
  1620                 if ( aValue == purposeValue )
       
  1621                     {
       
  1622                     result = ETrue;
       
  1623                     }
       
  1624                 switch ( aValue )
       
  1625                     {
       
  1626                     case CMManager::ESnapPurposeInternet:
       
  1627                         {
       
  1628                         if ( localizationValue == CMManager::ELocalisedDestInternet ||
       
  1629                                 ( metadata & CMManager::ESnapMetadataInternet ) )
       
  1630                             {
       
  1631                             result = ETrue;
       
  1632                             }
       
  1633                         }
       
  1634                         break;
       
  1635                     case CMManager::ESnapPurposeOperator:
       
  1636                         {
       
  1637                         if ( localizationValue == CMManager::ELocalisedDestWap )
       
  1638                             {
       
  1639                             result = ETrue;
       
  1640                             }
       
  1641                         }
       
  1642                         break;
       
  1643                     case CMManager::ESnapPurposeMMS:
       
  1644                         {
       
  1645                         if ( localizationValue == CMManager::ELocalisedDestMMS )
       
  1646                             {
       
  1647                             result = ETrue;
       
  1648                             }
       
  1649                         }
       
  1650                         break;
       
  1651                     case CMManager::ESnapPurposeIntranet:
       
  1652                         {
       
  1653                         if ( localizationValue == CMManager::ELocalisedDestIntranet )
       
  1654                             {
       
  1655                             result = ETrue;
       
  1656                             }
       
  1657                         }
       
  1658                         break;
       
  1659                     default:
       
  1660                         break;
       
  1661                     }
       
  1662                 }
       
  1663             }
       
  1664         CleanupStack::PopAndDestroy( metaSet );
       
  1665         }
       
  1666 
       
  1667     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONEXISTSWITHMETADATAPURPOSEL_EXIT );
       
  1668     return result;
       
  1669     }
       
  1670 
       
  1671 // ---------------------------------------------------------------------------
       
  1672 // Tells the cache that a database table has changed. If the SNAP/IAP structure
       
  1673 // has possibly changed, the cache will refresh that information immediately.
       
  1674 // For other database tables, the tables are flagged and will be refreshed when
       
  1675 // needed.
       
  1676 // ---------------------------------------------------------------------------
       
  1677 //
       
  1678 void CCmmCache::DbChangeDetectedL( const TUint32 aTableId )
       
  1679     {
       
  1680     OstTraceFunctionEntry0( CCMMCACHE_DBCHANGEDETECTED_ENTRY );
       
  1681 
       
  1682     if ( aTableId == iSnapMetadataTableId )
       
  1683         {
       
  1684         for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
       
  1685             {
       
  1686             iDestinationArray[i]->NotifyRecordChange( ECmmDestMetadataRecord );
       
  1687             }
       
  1688         }
       
  1689     else if ( aTableId == CommsDat::KCDTIdNetworkRecord )
       
  1690         {
       
  1691         // Affects destinations.
       
  1692         for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
       
  1693             {
       
  1694             iDestinationArray[i]->NotifyRecordChange( ECmmDestNetworkRecord );
       
  1695             }
       
  1696         }
       
  1697     else if ( aTableId == CommsDat::KCDTIdAccessPointRecord )
       
  1698         {
       
  1699         // Affects destinations.
       
  1700         for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
       
  1701             {
       
  1702             iDestinationArray[i]->NotifyRecordChange( ECmmDestApRecord );
       
  1703             }
       
  1704         }
       
  1705 
       
  1706     // Notify Connection Methods about the table changes in CommsDat.
       
  1707     NotifyPluginsForTableChangesL( aTableId );
       
  1708 
       
  1709     // Update instancemapping.
       
  1710     iInstanceMapping->RefreshL();
       
  1711 
       
  1712     OstTraceFunctionExit0( CCMMCACHE_DBCHANGEDETECTED_EXIT );
       
  1713     }
       
  1714 
       
  1715 // ---------------------------------------------------------------------------
       
  1716 // Informs all the loaded iaps if something related to their tables
       
  1717 // changed in commsdat.
       
  1718 // ---------------------------------------------------------------------------
       
  1719 //
       
  1720 void CCmmCache::NotifyPluginsForTableChangesL( const TUint32 aTableId )
       
  1721     {
       
  1722     OstTraceFunctionEntry0( CCMMCACHE_NOTIFYPLUGINSFORTABLECHANGESL_ENTRY );
       
  1723 
       
  1724     if ( iConnMethodArray.Count() )
       
  1725         {
       
  1726         RArray<TUint32> tableIdArray;
       
  1727         CleanupClosePushL( tableIdArray );
       
  1728 
       
  1729         // Check if change concerns some table generic for all iaps
       
  1730         ( *iPlugins )[0]->GetGenericTableIdsToBeObservedL( tableIdArray );
       
  1731         TBool generic( EFalse );
       
  1732         for( TInt i = 0; i < tableIdArray.Count(); i++ )
       
  1733             {
       
  1734             if ( aTableId == tableIdArray[i] )
       
  1735                 {
       
  1736                 generic = ETrue;
       
  1737                 break;
       
  1738                 }
       
  1739             }
       
  1740 
       
  1741         if ( generic )
       
  1742             {
       
  1743             // generic-->Notify all iaps
       
  1744             for( TInt i = 0; i < iConnMethodArray.Count(); i++ )
       
  1745                 {
       
  1746                 iConnMethodArray[i]->NotifyRecordChange( aTableId );
       
  1747                 }
       
  1748             }
       
  1749         else
       
  1750             {
       
  1751             // Not generic: Check bearer specific tables
       
  1752             RArray<TUint32> affectedBearersArray;
       
  1753             CleanupClosePushL( affectedBearersArray );
       
  1754             for( TInt i = 0; i < iPlugins->Count(); i++ )
       
  1755                 {
       
  1756                 tableIdArray.Reset();
       
  1757                 ( *iPlugins )[i]->GetBearerTableIdsToBeObservedL( tableIdArray );
       
  1758                 TInt idCount = tableIdArray.Count();
       
  1759                 for( TInt j = 0; j < idCount; j++ )
       
  1760                     {
       
  1761                     if ( aTableId == tableIdArray[j] )
       
  1762                         {
       
  1763                         // Save the bearer type id which is affected
       
  1764                         affectedBearersArray.AppendL(
       
  1765                                 ( *iPlugins )[i]->GetBearerInfoIntL(
       
  1766                                         CMManager::ECmBearerType ) );
       
  1767                         }
       
  1768                     }
       
  1769                 }
       
  1770 
       
  1771             // Go through all the loaded iaps and notify all the iaps
       
  1772             // which have the same bearer type saved above
       
  1773             for( TInt i = 0; i < iConnMethodArray.Count(); i++ )
       
  1774                 {
       
  1775                 for( TInt j = 0; j < affectedBearersArray.Count(); j++ )
       
  1776                     {
       
  1777                     if ( iConnMethodArray[i]->GetBearerType() == affectedBearersArray[j] )
       
  1778                         {
       
  1779                         iConnMethodArray[i]->NotifyRecordChange( aTableId );
       
  1780                         break;
       
  1781                         }
       
  1782                     }
       
  1783                 }
       
  1784             CleanupStack::PopAndDestroy( &affectedBearersArray );
       
  1785             }
       
  1786         CleanupStack::PopAndDestroy( &tableIdArray );
       
  1787         }
       
  1788     OstTraceFunctionExit0( CCMMCACHE_NOTIFYPLUGINSFORTABLECHANGESL_EXIT );
       
  1789     }
       
  1790 
       
  1791 // ---------------------------------------------------------------------------
       
  1792 // Tells the cache that an error has occured with a database listener. Any
       
  1793 // reads to this table need go through the database, since cache can't know if
       
  1794 // it has up-to-date information.
       
  1795 // ---------------------------------------------------------------------------
       
  1796 //
       
  1797 void CCmmCache::DbChangeError( const TUint32 aTableId )
       
  1798     {
       
  1799     OstTraceFunctionEntry0( CCMMCACHE_DBCHANGEERROR_ENTRY );
       
  1800 
       
  1801     (void)aTableId; //TODO
       
  1802     // Flag the table as: permanently not up-to-date
       
  1803 
       
  1804     //TODO, How to do this?
       
  1805     // Implement some 'status locked' flags that are always checked before changing status back to 'loaded' after reading database?
       
  1806     // Or move record status info to CCmmCache-class?
       
  1807     // What about plugins?
       
  1808 	// Or just ignore errors with notifiers?
       
  1809 
       
  1810     // For now, just ignore errors.
       
  1811 
       
  1812     OstTraceFunctionExit0( CCMMCACHE_DBCHANGEERROR_EXIT );
       
  1813     }
       
  1814 
       
  1815 // ---------------------------------------------------------------------------
       
  1816 // Tells the cache that a hadle to a destination was closed. The cache will
       
  1817 // decrement the related reference counter and perform any cleanup if necessary.
       
  1818 // This should be called automatically from the destructor of
       
  1819 // CCmmDestinationInstance-class.
       
  1820 // ---------------------------------------------------------------------------
       
  1821 //
       
  1822 void CCmmCache::CloseDestination( CCmmDestinationInstance& aDestinationInstance )
       
  1823     {
       
  1824     OstTraceFunctionEntry0( CCMMCACHE_CLOSEDESTINATION_ENTRY );
       
  1825 
       
  1826     TInt index = FindDestinationFromCache( aDestinationInstance.GetId() );
       
  1827 
       
  1828     if ( index >= 0 )
       
  1829         {
       
  1830         TInt remainingSessionInstances = iDestinationArray[index]->DestinationInstanceClosed();
       
  1831         if ( remainingSessionInstances <= 0)
       
  1832             {
       
  1833             // If status is 'to be deleted', then the last handle keeping this
       
  1834             // destination 'alive' was closed and it can now be deleted from
       
  1835             // database.
       
  1836             if ( iDestinationArray[index]->GetStatus() == ECmmDestinationStatusToBeDeleted )
       
  1837                 {
       
  1838                 // Delete the destination unless an active connection is using
       
  1839                 // one of it's connection methods.
       
  1840                 TRAP_IGNORE( DeleteDestinationForcedL( aDestinationInstance ) );
       
  1841                 // Destination is now removed from database. Tell instance
       
  1842                 // mapping to stop ignoring the related ID.
       
  1843                 iInstanceMapping->RemoveDestinationFromDeletedList( aDestinationInstance.GetId() );
       
  1844                 }
       
  1845 
       
  1846             // No more references, no client has an open handle to this, delete it.
       
  1847             delete iDestinationArray[index];
       
  1848             iDestinationArray.Remove( index );
       
  1849             }
       
  1850         }
       
  1851 
       
  1852     OstTraceFunctionExit0( CCMMCACHE_CLOSEDESTINATION_EXIT );
       
  1853     }
       
  1854 
       
  1855 // ---------------------------------------------------------------------------
       
  1856 // Tells the cache that a hadle to a connection method was closed. The cache
       
  1857 // will decrement the related reference counter and perform any cleanup if
       
  1858 // necessary.
       
  1859 // This should be called automatically from the destructor of
       
  1860 // CCmmConnMethodInstance-class.
       
  1861 // ---------------------------------------------------------------------------
       
  1862 //
       
  1863 void CCmmCache::CloseConnMethod( CCmmConnMethodInstance& aConnMethodInstance )
       
  1864     {
       
  1865     OstTraceFunctionEntry0( CCMMCACHE_CLOSECONNMETHOD_ENTRY );
       
  1866 
       
  1867     TInt index = FindConnMethodFromCache( aConnMethodInstance.GetId() );
       
  1868 
       
  1869     if ( index >= 0 )
       
  1870         {
       
  1871         TInt remainingSessionInstances = iConnMethodArray[index]->ConnMethodInstanceClosed();
       
  1872         if ( remainingSessionInstances <= 0 )
       
  1873             {
       
  1874             // If status is 'to be deleted', then the last handle keeping this
       
  1875             // connection method 'alive' was closed and it can now be deleted
       
  1876             // from database.
       
  1877             if ( iConnMethodArray[index]->GetStatus() == ECmmConnMethodStatusToBeDeleted )
       
  1878                 {
       
  1879                 // Can't remove a connection method that is in use.
       
  1880                 if ( !CheckIfCmConnected( aConnMethodInstance.GetId() ) )
       
  1881                     {
       
  1882                     // Can't leave here.
       
  1883                     TRAP_IGNORE( DeletePluginL( *( iConnMethodArray[index] ) ) );
       
  1884                     }
       
  1885 
       
  1886                 // Connection method is now removed from database. Tell
       
  1887                 // instance mapping to stop ignoring the related ID.
       
  1888                 iInstanceMapping->RemoveConnMethodFromDeletedList( aConnMethodInstance.GetId() );
       
  1889                 }
       
  1890 
       
  1891             // No more references, no client has an open handle to this, delete it.
       
  1892             delete iConnMethodArray[index];
       
  1893             iConnMethodArray.Remove( index );
       
  1894             }
       
  1895         }
       
  1896 
       
  1897     OstTraceFunctionExit0( CCMMCACHE_CLOSECONNMETHOD_EXIT );
       
  1898     }
       
  1899 
       
  1900 //-----------------------------------------------------------------------------
       
  1901 // Returns a reference to the CommsDat session.
       
  1902 //-----------------------------------------------------------------------------
       
  1903 //
       
  1904 CommsDat::CMDBSession& CCmmCache::Session() const
       
  1905     {
       
  1906     // No traces.
       
  1907     return iTrans->Session();
       
  1908     }
       
  1909 
       
  1910 //-----------------------------------------------------------------------------
       
  1911 // Finds out the bearer type and priority of the service type from given IAP
       
  1912 // record. performs LoadL()-call on the provided IAP record.
       
  1913 //-----------------------------------------------------------------------------
       
  1914 //
       
  1915 void CCmmCache::BearerInfoFromIapRecordL(
       
  1916         CommsDat::CCDIAPRecord* aIapRecord,
       
  1917         TUint32& aBearerType,
       
  1918         TUint& aBearerPriority ) const
       
  1919     {
       
  1920     OstTraceFunctionEntry0( CCMMCACHE_BEARERINFOFROMIAPRECORDL_ENTRY );
       
  1921 
       
  1922     // Load the IAP record from IAP table. This is an optimization so that
       
  1923     // plugins don't have to do it every time the CanHandleIapIdL() is called.
       
  1924     aIapRecord->LoadL( Session() );
       
  1925     BearerPriorityFromIapRecordL( aIapRecord, aBearerPriority );
       
  1926     BearerTypeFromIapRecordL( aIapRecord, aBearerType );
       
  1927 
       
  1928     OstTraceFunctionExit0( CCMMCACHE_BEARERINFOFROMIAPRECORDL_EXIT );
       
  1929     }
       
  1930 
       
  1931 //-----------------------------------------------------------------------------
       
  1932 // Finds out the priority of the service type in given IAP record.
       
  1933 //-----------------------------------------------------------------------------
       
  1934 //
       
  1935 void CCmmCache::BearerPriorityFromIapRecordL(
       
  1936         CommsDat::CCDIAPRecord* aIapRecord,
       
  1937         TUint& aBearerPriority ) const
       
  1938     {
       
  1939     OstTraceFunctionEntry0( CCMMCACHE_BEARERPRIORITYFROMIAPRECORDL_ENTRY );
       
  1940 
       
  1941     aBearerPriority = CMManager::KDataMobilitySelectionPolicyPriorityWildCard;
       
  1942     if ( !aIapRecord->iServiceType.IsNull() )
       
  1943         {
       
  1944         aBearerPriority = iBearerPriorityCache->GetPriority( aIapRecord->iServiceType.GetL() );
       
  1945         }
       
  1946 
       
  1947     OstTraceFunctionExit0( CCMMCACHE_BEARERPRIORITYFROMIAPRECORDL_EXIT );
       
  1948     }
       
  1949 
       
  1950 //-----------------------------------------------------------------------------
       
  1951 // Finds out the bearer type of a connection method from given IAP record.
       
  1952 //-----------------------------------------------------------------------------
       
  1953 //
       
  1954 void CCmmCache::BearerTypeFromIapRecordL(
       
  1955         CommsDat::CCDIAPRecord* aIapRecord,
       
  1956         TUint32& aBearerType ) const
       
  1957     {
       
  1958     OstTraceFunctionEntry0( CCMMCACHE_BEARERTYPEFROMIAPRECORDL_ENTRY );
       
  1959 
       
  1960     TInt err( KErrNone );
       
  1961     TUint32 extLevel( 0 );
       
  1962     TBool canHandle( EFalse );
       
  1963 
       
  1964     TInt foundIndex( KErrNotFound );
       
  1965 
       
  1966     // Check which bearer handles the given IAP ID.
       
  1967     for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
  1968         {
       
  1969         TRAP( err, canHandle = (*iPlugins)[i]->CanHandleIapIdL( aIapRecord ) );
       
  1970         if ( !err && canHandle )
       
  1971             {
       
  1972             TUint32 thisExtLevel = (*iPlugins)[i]->GetBearerInfoIntL( ECmExtensionLevel );
       
  1973             if ( extLevel < thisExtLevel )
       
  1974                 {
       
  1975                 extLevel = thisExtLevel;
       
  1976                 foundIndex = i;
       
  1977                 }
       
  1978             }
       
  1979         }
       
  1980     if ( foundIndex == KErrNotFound )
       
  1981         {
       
  1982         // No supporting plugin found.
       
  1983         User::Leave( KErrNotSupported );
       
  1984         }
       
  1985     aBearerType = (*iPlugins)[foundIndex]->GetBearerInfoIntL( CMManager::ECmBearerType );
       
  1986 
       
  1987     OstTraceFunctionExit0( CCMMCACHE_BEARERTYPEFROMIAPRECORDL_EXIT );
       
  1988     }
       
  1989 
       
  1990 // ---------------------------------------------------------------------------
       
  1991 // Find and return a copy of a connection method item matching the given ID.
       
  1992 // Returns KErrNotFound, if the connection method is not found.
       
  1993 // ---------------------------------------------------------------------------
       
  1994 //
       
  1995 TInt CCmmCache::GetConnMethodItem(
       
  1996         const TUint32 aConnMethodId,
       
  1997         TCmmConnMethodItem& aConnMethodItem ) const
       
  1998     {
       
  1999     OstTraceFunctionEntry0( CCMMCACHE_GETCONNMETHODITEM_ENTRY );
       
  2000 
       
  2001     TInt result = iInstanceMapping->GetConnMethodItem( aConnMethodId, aConnMethodItem );
       
  2002 
       
  2003     OstTraceFunctionExit0( CCMMCACHE_GETCONNMETHODITEM_EXIT );
       
  2004     return result;
       
  2005     }
       
  2006 
       
  2007 //-----------------------------------------------------------------------------
       
  2008 // Returns all conenction method IDs. Unsupported connection methods are
       
  2009 // included if aCheckBearerType is set to EFalse.
       
  2010 //-----------------------------------------------------------------------------
       
  2011 //
       
  2012 void CCmmCache::GetAllConnMethodsL(
       
  2013         RArray<TUint32>& aConnMethodArray,
       
  2014         TBool aCheckBearerType ) const
       
  2015     {
       
  2016     OstTraceFunctionEntry0( CCMMCACHE_GETALLCONNMETHODSL_ENTRY );
       
  2017 
       
  2018     iInstanceMapping->GetAllConnMethodsL( aConnMethodArray, aCheckBearerType );
       
  2019 
       
  2020     OstTraceFunctionExit0( CCMMCACHE_GETALLCONNMETHODSL_EXIT );
       
  2021     }
       
  2022 
       
  2023 //-----------------------------------------------------------------------------
       
  2024 // Returns the number of destinations the provided connection method belongs to.
       
  2025 //-----------------------------------------------------------------------------
       
  2026 //
       
  2027 TInt CCmmCache::DestinationsContainingConnMethod( const TUint32 aConnMethodId ) const
       
  2028     {
       
  2029     OstTraceFunctionEntry0( CCMMCACHE_CONNMETHODREFERENCECOUNT_ENTRY );
       
  2030 
       
  2031     TInt count = iInstanceMapping->DestinationsContainingConnMethod( aConnMethodId );
       
  2032 
       
  2033     OstTraceFunctionExit0( CCMMCACHE_CONNMETHODREFERENCECOUNT_EXIT );
       
  2034     return count;
       
  2035     }
       
  2036 
       
  2037 //-----------------------------------------------------------------------------
       
  2038 // Return the EasyWLAN IAP ID, zero if not found or WLAN not supported.
       
  2039 //-----------------------------------------------------------------------------
       
  2040 //
       
  2041 TUint32 CCmmCache::EasyWlanIdL() const
       
  2042     {
       
  2043     OstTraceFunctionEntry0( CCMMCACHE_EASYWLANIDL_ENTRY );
       
  2044 
       
  2045     TUint32 easyWlanId = iInstanceMapping->EasyWlanIdL();
       
  2046 
       
  2047     OstTraceFunctionExit0( CCMMCACHE_EASYWLANIDL_EXIT );
       
  2048     return easyWlanId;
       
  2049     }
       
  2050 
       
  2051 //-----------------------------------------------------------------------------
       
  2052 // Check if WLAN is supported on phone.
       
  2053 //-----------------------------------------------------------------------------
       
  2054 //
       
  2055 TBool CCmmCache::WlanSupported() const
       
  2056     {
       
  2057     OstTraceFunctionEntry0( CCMMCACHE_WLANSUPPORTED_ENTRY );
       
  2058 
       
  2059     TBool supported = iCmManagerImpl->WlanSupported();
       
  2060 
       
  2061     OstTraceFunctionExit0( CCMMCACHE_WLANSUPPORTED_EXIT );
       
  2062     return supported;
       
  2063     }
       
  2064 
       
  2065 //-----------------------------------------------------------------------------
       
  2066 // Find out the internet destination ID. Set to 0 if not found.
       
  2067 //-----------------------------------------------------------------------------
       
  2068 //
       
  2069 void CCmmCache::InternetDestinationIdL( TUint& aInternetDestinationId ) const
       
  2070     {
       
  2071     OstTraceFunctionEntry0( CCMMCACHE_INTERNETDESTINATIONIDL_ENTRY );
       
  2072 
       
  2073     iInstanceMapping->InternetDestinationIdL( aInternetDestinationId );
       
  2074 
       
  2075     OstTraceFunctionExit0( CCMMCACHE_INTERNETDESTINATIONIDL_EXIT );
       
  2076     }
       
  2077 
       
  2078 //-----------------------------------------------------------------------------
       
  2079 // Return the number of destinations in database.
       
  2080 //-----------------------------------------------------------------------------
       
  2081 //
       
  2082 TInt CCmmCache::GetDestinationCount() const
       
  2083     {
       
  2084     OstTraceFunctionEntry0( CCMMCACHE_GETDESTINATIONCOUNT_ENTRY );
       
  2085 
       
  2086     TInt count = iInstanceMapping->GetDestinationCount();
       
  2087 
       
  2088     OstTraceFunctionExit0( CCMMCACHE_GETDESTINATIONCOUNT_EXIT );
       
  2089     return count;
       
  2090     }
       
  2091 
       
  2092 //-----------------------------------------------------------------------------
       
  2093 // Return an array containing all destination IDs.
       
  2094 //-----------------------------------------------------------------------------
       
  2095 //
       
  2096 void CCmmCache::GetDestinationsL( RArray<TUint32>& aDestinationArray ) const
       
  2097     {
       
  2098     OstTraceFunctionEntry0( CCMMCACHE_GETDESTINATIONSL_ENTRY );
       
  2099 
       
  2100     iInstanceMapping->GetDestinationsL( aDestinationArray );
       
  2101 
       
  2102     OstTraceFunctionExit0( CCMMCACHE_GETDESTINATIONSL_EXIT );
       
  2103     }
       
  2104 
       
  2105 //-----------------------------------------------------------------------------
       
  2106 // Returns all the valid connection methods under given destination.
       
  2107 //-----------------------------------------------------------------------------
       
  2108 //
       
  2109 void CCmmCache::GetConnMethodsFromDestinationL(
       
  2110         const TUint32 aDestinationId,
       
  2111         RArray<TCmmConnMethodItem>& aConnMethodArray ) const
       
  2112     {
       
  2113     OstTraceFunctionEntry0( CCMMCACHE_GETCONNMETHODSFROMDESTINATIONL_ENTRY );
       
  2114 
       
  2115     iInstanceMapping->GetConnMethodsFromDestinationL(
       
  2116             aDestinationId, aConnMethodArray );
       
  2117 
       
  2118     OstTraceFunctionExit0( CCMMCACHE_GETCONNMETHODSFROMDESTINATIONL_EXIT );
       
  2119     }
       
  2120 
       
  2121 //-----------------------------------------------------------------------------
       
  2122 // Copies the bearer priority array's contents to aArray.
       
  2123 //-----------------------------------------------------------------------------
       
  2124 //
       
  2125 void CCmmCache::CopyBearerPriorityArrayL( RPointerArray<CCmmBearerPriority>& aArray ) const
       
  2126     {
       
  2127     OstTraceFunctionEntry0( CCMMCACHE_COPYBEARERPRIORITYARRAYL_ENTRY );
       
  2128 
       
  2129     iBearerPriorityCache->CopyL( aArray );
       
  2130 
       
  2131     OstTraceFunctionExit0( CCMMCACHE_COPYBEARERPRIORITYARRAYL_EXIT );
       
  2132     }
       
  2133 
       
  2134 //-----------------------------------------------------------------------------
       
  2135 // Updates the bearer priority array with the contents of aArray.
       
  2136 //-----------------------------------------------------------------------------
       
  2137 //
       
  2138 void CCmmCache::UpdateBearerPriorityArrayL( const RPointerArray<CCmmBearerPriority>& aArray )
       
  2139     {
       
  2140     OstTraceFunctionEntry0( CCMMCACHE_UPDATEBEARERPRIORITYARRAYL_ENTRY );
       
  2141 
       
  2142     iBearerPriorityCache->UpdateL( aArray );
       
  2143 
       
  2144     OstTraceFunctionExit0( CCMMCACHE_UPDATEBEARERPRIORITYARRAYL_EXIT );
       
  2145     }
       
  2146 
       
  2147 //-----------------------------------------------------------------------------
       
  2148 // Check from database if the given connection method belongs to any other
       
  2149 // destination than the one provided.
       
  2150 //-----------------------------------------------------------------------------
       
  2151 //
       
  2152 TBool CCmmCache::ConnMethodInOtherDestination(
       
  2153         const TUint32 aConnMethodId,
       
  2154         const TUint32 aDestinationId )
       
  2155     {
       
  2156     OstTraceFunctionEntry0( CCMMCACHE_CONNMETHODINOTHERDESTINATION_ENTRY );
       
  2157 
       
  2158     TBool cmInOtherDestination = iInstanceMapping->
       
  2159             ConnMethodInOtherDestination( aConnMethodId, aDestinationId );
       
  2160 
       
  2161     OstTraceFunctionExit0( CCMMCACHE_CONNMETHODINOTHERDESTINATION_EXIT );
       
  2162     return cmInOtherDestination;
       
  2163     }
       
  2164 
       
  2165 //-----------------------------------------------------------------------------
       
  2166 // Get the next free temporary ID.
       
  2167 //-----------------------------------------------------------------------------
       
  2168 //
       
  2169 TUint32 CCmmCache::NextFreeTemporaryId()
       
  2170     {
       
  2171     OstTraceFunctionEntry0( CCMMCACHE_NEXTFREETEMPORARYID_ENTRY );
       
  2172 
       
  2173     // Zero is not a valid ID.
       
  2174     if ( iCurrentTemporaryId == KMaxTUint32 )
       
  2175         {
       
  2176         //TODO, add flag to indicate a rollover has occured. after that need to check if temp ID is free before giving it out.
       
  2177 
       
  2178         iCurrentTemporaryId = KTemporaryIdCounterStart;
       
  2179         }
       
  2180 
       
  2181     iCurrentTemporaryId++;
       
  2182 
       
  2183     OstTraceFunctionExit0( CCMMCACHE_NEXTFREETEMPORARYID_EXIT );
       
  2184     return iCurrentTemporaryId;
       
  2185     }
       
  2186 
       
  2187 //-----------------------------------------------------------------------------
       
  2188 // Find an open destination matching the give ID from cache.
       
  2189 // Returns either a valid array index or KErrNotFound.
       
  2190 //-----------------------------------------------------------------------------
       
  2191 //
       
  2192 TInt CCmmCache::FindDestinationFromCache( const TUint32 aId )
       
  2193     {
       
  2194     OstTraceFunctionEntry0( CCMMCACHE_FINDDESTINATIONFROMCACHE_ENTRY );
       
  2195 
       
  2196     TInt result( KErrNotFound );
       
  2197 
       
  2198     // Skip if ID is 0.
       
  2199     if ( aId )
       
  2200         {
       
  2201         for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
       
  2202             {
       
  2203             if ( aId == iDestinationArray[i]->GetId() )
       
  2204                 {
       
  2205                 result = i;
       
  2206                 break;
       
  2207                 }
       
  2208             }
       
  2209         }
       
  2210 
       
  2211     OstTraceFunctionExit0( CCMMCACHE_FINDDESTINATIONFROMCACHE_EXIT );
       
  2212     return result;
       
  2213     }
       
  2214 
       
  2215 //-----------------------------------------------------------------------------
       
  2216 // Find an open destination matching the given name from cache. If a destination
       
  2217 // ID is provided, the search will exclude the relevant destination.
       
  2218 // Returns either a valid array index or KErrNotFound.
       
  2219 //-----------------------------------------------------------------------------
       
  2220 //
       
  2221 TInt CCmmCache::FindNotSavedDestinationFromCacheL(
       
  2222         const TDesC& aName,
       
  2223         const TUint32 aDestinationId )
       
  2224     {
       
  2225     OstTraceFunctionEntry0( CCMMCACHE_FINDNOTSAVEDDESTINATIONFROMCACHEL_ENTRY );
       
  2226 
       
  2227     TInt result( KErrNotFound );
       
  2228 
       
  2229     // Go through destination array.
       
  2230     for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
       
  2231         {
       
  2232         // Only check new destinations that are not yet in database.
       
  2233         if ( iDestinationArray[i]->GetStatus() == ECmmDestinationStatusNotSaved )
       
  2234             {
       
  2235             if ( aDestinationId )
       
  2236                 {
       
  2237                 if ( aDestinationId != iDestinationArray[i]->GetId() )
       
  2238                     {
       
  2239                     if ( !aName.Compare( iDestinationArray[i]->GetDestinationNameL() ) )
       
  2240                         {
       
  2241                         result = i;
       
  2242                         break;
       
  2243                         }
       
  2244                     }
       
  2245                 }
       
  2246             else
       
  2247                 {
       
  2248                 if ( !aName.Compare( iDestinationArray[i]->GetDestinationNameL() ) )
       
  2249                     {
       
  2250                     result = i;
       
  2251                     break;
       
  2252                     }
       
  2253                 }
       
  2254             }
       
  2255         }
       
  2256 
       
  2257     OstTraceFunctionExit0( CCMMCACHE_FINDNOTSAVEDDESTINATIONFROMCACHEL_EXIT );
       
  2258     return result;
       
  2259     }
       
  2260 
       
  2261 //-----------------------------------------------------------------------------
       
  2262 // Find an open connection method matching the given ID from cache.
       
  2263 // Returns either a valid array index or KErrNotFound.
       
  2264 //-----------------------------------------------------------------------------
       
  2265 //
       
  2266 TInt CCmmCache::FindConnMethodFromCache( const TUint32 aConnMethodId )
       
  2267     {
       
  2268     OstTraceFunctionEntry0( CCMMCACHE_FINDCONNMETHODFROMCACHE_ENTRY );
       
  2269 
       
  2270     TInt result( KErrNotFound );
       
  2271 
       
  2272     // Skip if ID is 0.
       
  2273     if ( aConnMethodId )
       
  2274         {
       
  2275         for ( TInt i = 0; i < iConnMethodArray.Count(); i++ )
       
  2276             {
       
  2277             if ( aConnMethodId == iConnMethodArray[i]->GetId() )
       
  2278                 {
       
  2279                 result = i;
       
  2280                 break;
       
  2281                 }
       
  2282             }
       
  2283         }
       
  2284 
       
  2285     OstTraceFunctionExit0( CCMMCACHE_FINDCONNMETHODFROMCACHE_EXIT );
       
  2286     return result;
       
  2287     }
       
  2288 
       
  2289 //-----------------------------------------------------------------------------
       
  2290 // Loads and initializes a connection method instance.
       
  2291 //-----------------------------------------------------------------------------
       
  2292 //
       
  2293 void CCmmCache::OpenConnectionMethodInstanceL(
       
  2294         CCmmConnMethodInstance& aConnMethodInstance,
       
  2295         const TUint32 aConnMethodId )
       
  2296     {
       
  2297     OstTraceFunctionEntry0( CCMMCACHE_OPENCONNECTIONMETHODINSTANCEL_ENTRY );
       
  2298 
       
  2299     // Find out the connection method bearer type.
       
  2300     TUint32 bearerType( 0 );
       
  2301     User::LeaveIfError( iInstanceMapping->
       
  2302             GetConnMethodBearerType( aConnMethodId, bearerType ) );
       
  2303 
       
  2304     // Check bearer type support and create plugin instance.
       
  2305     CCmPluginBaseEng* plugin = NULL;
       
  2306     for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
  2307         {
       
  2308         if ( ( *iPlugins )[i]->GetBearerInfoIntL(
       
  2309                 CMManager::ECmBearerType ) == bearerType )
       
  2310             {
       
  2311             TCmPluginInitParam pluginParams( Session() );
       
  2312             plugin = ( *iPlugins )[i]->CreateInstanceL( pluginParams );
       
  2313             CleanupStack::PushL( plugin );
       
  2314             plugin->LoadL( aConnMethodId );
       
  2315             break;
       
  2316             }
       
  2317         }
       
  2318     if ( !plugin )
       
  2319         {
       
  2320         User::Leave( KErrNotSupported );
       
  2321         }
       
  2322 
       
  2323     // Store the connection method into cache.
       
  2324     CCmmConnMethodStruct* connMethodStruct = CCmmConnMethodStruct::NewL( aConnMethodId );
       
  2325     connMethodStruct->SetPlugin( plugin, bearerType, ECmmConnMethodStatusValid );
       
  2326     CleanupStack::Pop( plugin );
       
  2327     CleanupStack::PushL( connMethodStruct );
       
  2328     iConnMethodArray.AppendL( connMethodStruct );
       
  2329     CleanupStack::Pop( connMethodStruct );
       
  2330 
       
  2331     // Copy the connection method data to session instance.
       
  2332     aConnMethodInstance.CopyDataL( connMethodStruct ); // Will increase reference counter.
       
  2333 
       
  2334     OstTraceFunctionExit0( CCMMCACHE_OPENCONNECTIONMETHODINSTANCEL_EXIT );
       
  2335     }
       
  2336 
       
  2337 //-----------------------------------------------------------------------------
       
  2338 // CCmmCache::GetConnectionMethodInfoIntL
       
  2339 //-----------------------------------------------------------------------------
       
  2340 //
       
  2341 TUint32 CCmmCache::GetConnectionMethodInfoIntL(
       
  2342         const TUint32 aCmId,
       
  2343         const TUint32 aAttribute )
       
  2344     {
       
  2345     OstTraceFunctionEntry0( CCMMCACHE_GETCONNECTIONMETHODINFOINTL_ENTRY );
       
  2346 
       
  2347     TUint32 retVal( 0 );
       
  2348 
       
  2349     CCmmConnMethodInstance* cmInstance = CCmmConnMethodInstance::NewLC( NULL, this );
       
  2350 
       
  2351     // Check if connection method is already opened in cache.
       
  2352     TInt index = FindConnMethodFromCache( aCmId );
       
  2353     if ( index != KErrNotFound )
       
  2354         {
       
  2355         // Already open in cache. Copy the connection method to session instance.
       
  2356         // Will increase reference counter.
       
  2357         cmInstance->CopyDataL( iConnMethodArray[index] );
       
  2358         }
       
  2359     else
       
  2360         {
       
  2361         OpenConnectionMethodInstanceL( *cmInstance, aCmId );
       
  2362         }
       
  2363 
       
  2364     retVal = cmInstance->GetIntAttributeL( aAttribute );
       
  2365 
       
  2366     CleanupStack::PopAndDestroy( cmInstance );
       
  2367 
       
  2368     OstTraceFunctionExit0( CCMMCACHE_GETCONNECTIONMETHODINFOINTL_EXIT );
       
  2369     return retVal;
       
  2370     }
       
  2371 
       
  2372 //-----------------------------------------------------------------------------
       
  2373 // CCmmCache::GetConnectionMethodInfoBoolL
       
  2374 //-----------------------------------------------------------------------------
       
  2375 //
       
  2376 TBool CCmmCache::GetConnectionMethodInfoBoolL(
       
  2377         const TUint32 aCmId,
       
  2378         const TUint32 aAttribute )
       
  2379     {
       
  2380     OstTraceFunctionEntry0( CCMMCACHE_GETCONNECTIONMETHODINFOBOOLL_ENTRY );
       
  2381 
       
  2382     TBool retVal( EFalse );
       
  2383 
       
  2384     CCmmConnMethodInstance* cmInstance = CCmmConnMethodInstance::NewLC( NULL, this );
       
  2385 
       
  2386     // Check if connection method is already opened in cache.
       
  2387     TInt index = FindConnMethodFromCache( aCmId );
       
  2388     if ( index != KErrNotFound )
       
  2389         {
       
  2390         // Already open in cache. Copy the connection method to session instance.
       
  2391         // Will increase reference counter.
       
  2392         cmInstance->CopyDataL( iConnMethodArray[index] );
       
  2393         }
       
  2394     else
       
  2395         {
       
  2396         OpenConnectionMethodInstanceL( *cmInstance, aCmId );
       
  2397         }
       
  2398 
       
  2399     retVal = cmInstance->GetBoolAttributeL( aAttribute );
       
  2400 
       
  2401     CleanupStack::PopAndDestroy( cmInstance );
       
  2402 
       
  2403     OstTraceFunctionExit0( CCMMCACHE_GETCONNECTIONMETHODINFOBOOLL_EXIT );
       
  2404     return retVal;
       
  2405     }
       
  2406 
       
  2407 //-----------------------------------------------------------------------------
       
  2408 // CCmmCache::GetConnectionMethodInfoStringL
       
  2409 //-----------------------------------------------------------------------------
       
  2410 //
       
  2411 HBufC* CCmmCache::GetConnectionMethodInfoStringL(
       
  2412         const TUint32 aCmId,
       
  2413         const TUint32 aAttribute )
       
  2414     {
       
  2415     OstTraceFunctionEntry0( CCMMCACHE_GETCONNECTIONMETHODINFOSTRINGL_ENTRY );
       
  2416 
       
  2417     HBufC* retVal( NULL );
       
  2418 
       
  2419     CCmmConnMethodInstance* cmInstance = CCmmConnMethodInstance::NewLC( NULL, this );
       
  2420 
       
  2421     // Check if connection method is already opened in cache.
       
  2422     TInt index = FindConnMethodFromCache( aCmId );
       
  2423     if ( index != KErrNotFound )
       
  2424         {
       
  2425         // Already open in cache. Copy the connection method to session instance.
       
  2426         // Will increase reference counter.
       
  2427         cmInstance->CopyDataL( iConnMethodArray[index] );
       
  2428         }
       
  2429     else
       
  2430         {
       
  2431         OpenConnectionMethodInstanceL( *cmInstance, aCmId );
       
  2432         }
       
  2433 
       
  2434     retVal = cmInstance->GetStringAttributeL( aAttribute );
       
  2435 
       
  2436     CleanupStack::PopAndDestroy( cmInstance );
       
  2437 
       
  2438     OstTraceFunctionExit0( CCMMCACHE_GETCONNECTIONMETHODINFOSTRINGL_EXIT );
       
  2439     return retVal;
       
  2440     }
       
  2441 
       
  2442 //-----------------------------------------------------------------------------
       
  2443 // CCmmCache::GetConnectionMethodInfoString8L
       
  2444 //-----------------------------------------------------------------------------
       
  2445 //
       
  2446 HBufC8* CCmmCache::GetConnectionMethodInfoString8L(
       
  2447         const TUint32 aCmId,
       
  2448         const TUint32 aAttribute )
       
  2449     {
       
  2450     OstTraceFunctionEntry0( CCMMCACHE_GETCONNECTIONMETHODINFOSTRING8L_ENTRY );
       
  2451 
       
  2452     HBufC8* retVal( NULL );
       
  2453 
       
  2454     CCmmConnMethodInstance* cmInstance = CCmmConnMethodInstance::NewLC( NULL, this );
       
  2455 
       
  2456     // Check if connection method is already opened in cache.
       
  2457     TInt index = FindConnMethodFromCache( aCmId );
       
  2458     if ( index != KErrNotFound )
       
  2459         {
       
  2460         // Already open in cache. Copy the connection method to session instance.
       
  2461         cmInstance->CopyDataL( iConnMethodArray[index] ); // Will increase reference counter.
       
  2462         }
       
  2463     else
       
  2464         {
       
  2465         OpenConnectionMethodInstanceL( *cmInstance, aCmId );
       
  2466         }
       
  2467 
       
  2468     retVal = cmInstance->GetString8AttributeL( aAttribute );
       
  2469 
       
  2470     CleanupStack::PopAndDestroy( cmInstance );
       
  2471 
       
  2472     OstTraceFunctionExit0( CCMMCACHE_GETCONNECTIONMETHODINFOSTRING8L_EXIT );
       
  2473     return retVal;
       
  2474     }
       
  2475 
       
  2476 
       
  2477 //-----------------------------------------------------------------------------
       
  2478 // CCmmCache::GetBearerInfoIntL
       
  2479 //-----------------------------------------------------------------------------
       
  2480 //
       
  2481 TUint32 CCmmCache::GetBearerInfoIntL(
       
  2482         const TUint32 aBearerType,
       
  2483         const TUint32 aAttribute )
       
  2484     {
       
  2485     OstTraceFunctionEntry0( CCMMCACHE_GETBEARERINFOINTL_ENTRY );
       
  2486 
       
  2487     TUint32 retVal( 0 );
       
  2488     TBool found( EFalse );
       
  2489 
       
  2490     for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
  2491         {
       
  2492         if ( ( *iPlugins )[i]->GetBearerInfoIntL( CMManager::ECmBearerType ) == aBearerType )
       
  2493             {
       
  2494             found = ETrue;
       
  2495             retVal = ( *iPlugins )[i]->GetBearerInfoIntL( aAttribute );
       
  2496             break;
       
  2497             }
       
  2498         }
       
  2499     if ( !found )
       
  2500         {
       
  2501         User::Leave( KErrArgument );
       
  2502         }
       
  2503 
       
  2504     OstTraceFunctionExit0( CCMMCACHE_GETBEARERINFOINTL_EXIT );
       
  2505     return retVal;
       
  2506     }
       
  2507 
       
  2508 //-----------------------------------------------------------------------------
       
  2509 // CCmmCache::GetBearerInfoBoolL
       
  2510 //-----------------------------------------------------------------------------
       
  2511 //
       
  2512 TBool CCmmCache::GetBearerInfoBoolL(
       
  2513         const TUint32 aBearerType,
       
  2514         const TUint32 aAttribute )
       
  2515     {
       
  2516     OstTraceFunctionEntry0( CCMMCACHE_GETBEARERINFOBOOLL_ENTRY );
       
  2517 
       
  2518     TBool retVal( EFalse );
       
  2519     TBool found( EFalse );
       
  2520 
       
  2521     for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
  2522         {
       
  2523         if ( ( *iPlugins )[i]->GetBearerInfoIntL( CMManager::ECmBearerType ) == aBearerType )
       
  2524             {
       
  2525             found = ETrue;
       
  2526             retVal = ( *iPlugins )[i]->GetBearerInfoBoolL( aAttribute );
       
  2527             break;
       
  2528             }
       
  2529         }
       
  2530     if ( !found )
       
  2531         {
       
  2532         User::Leave( KErrArgument );
       
  2533         }
       
  2534 
       
  2535     OstTraceFunctionExit0( CCMMCACHE_GETBEARERINFOBOOLL_EXIT );
       
  2536     return retVal;
       
  2537     }
       
  2538 
       
  2539 //-----------------------------------------------------------------------------
       
  2540 // CCmmCache::GetBearerInfoStringL
       
  2541 //-----------------------------------------------------------------------------
       
  2542 //
       
  2543 HBufC* CCmmCache::GetBearerInfoStringL(
       
  2544         const TUint32 aBearerType,
       
  2545         const TUint32 aAttribute )
       
  2546     {
       
  2547     OstTraceFunctionEntry0( CCMMCACHE_GETBEARERINFOSTRINGL_ENTRY );
       
  2548 
       
  2549     HBufC* retVal( NULL );
       
  2550     TBool found( EFalse );
       
  2551 
       
  2552     for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
  2553         {
       
  2554         if ( ( *iPlugins )[i]->GetBearerInfoIntL( CMManager::ECmBearerType ) == aBearerType )
       
  2555             {
       
  2556             found = ETrue;
       
  2557             retVal = ( *iPlugins )[i]->GetBearerInfoStringL( aAttribute );
       
  2558             break;
       
  2559             }
       
  2560         }
       
  2561     if ( !found )
       
  2562         {
       
  2563         User::Leave( KErrArgument );
       
  2564         }
       
  2565 
       
  2566     OstTraceFunctionExit0( CCMMCACHE_GETBEARERINFOSTRINGL_EXIT );
       
  2567     return retVal;
       
  2568     }
       
  2569 
       
  2570 //-----------------------------------------------------------------------------
       
  2571 // CCmmCache::GetBearerInfoString8L
       
  2572 //-----------------------------------------------------------------------------
       
  2573 //
       
  2574 HBufC8* CCmmCache::GetBearerInfoString8L(
       
  2575         const TUint32 aBearerType,
       
  2576         const TUint32 aAttribute )
       
  2577     {
       
  2578     OstTraceFunctionEntry0( CCMMCACHE_GETBEARERINFOSTRING8L_ENTRY );
       
  2579 
       
  2580     HBufC8* retVal( NULL );
       
  2581     TBool found( EFalse );
       
  2582 
       
  2583     for ( TInt i = 0; i < iPlugins->Count(); i++ )
       
  2584         {
       
  2585         if ( ( *iPlugins )[i]->GetBearerInfoIntL( CMManager::ECmBearerType ) == aBearerType )
       
  2586             {
       
  2587             found = ETrue;
       
  2588             retVal = ( *iPlugins )[i]->GetBearerInfoString8L( aAttribute );
       
  2589             break;
       
  2590             }
       
  2591         }
       
  2592     if ( !found )
       
  2593         {
       
  2594         User::Leave( KErrArgument );
       
  2595         }
       
  2596 
       
  2597     OstTraceFunctionExit0( CCMMCACHE_GETBEARERINFOSTRING8L_EXIT );
       
  2598     return retVal;
       
  2599     }
       
  2600 
       
  2601 //-----------------------------------------------------------------------------
       
  2602 // Read general connection settings from database.
       
  2603 //-----------------------------------------------------------------------------
       
  2604 //
       
  2605 void CCmmCache::ReadGenConnSettingsL( TCmGenConnSettings& aGenConnSettings ) const
       
  2606     {
       
  2607     OstTraceFunctionEntry0( CCMMCACHE_READGENCONNSETTINGSL_ENTRY );
       
  2608 
       
  2609     CommsDat::CMDBRecordSet<CCDDefConnRecord>* defConnRecordSet =
       
  2610             new( ELeave ) CommsDat::CMDBRecordSet<CCDDefConnRecord>(
       
  2611                     iCmManagerImpl->TableId( ECmmDbDefConnRecord ) );
       
  2612     CleanupStack::PushL( defConnRecordSet );
       
  2613 
       
  2614     CCDDefConnRecord* defConnRecord =
       
  2615             new( ELeave ) CCDDefConnRecord(
       
  2616                     iCmManagerImpl->TableId( ECmmDbDefConnRecord ) );
       
  2617     CleanupStack::PushL( defConnRecord );
       
  2618 
       
  2619     TRAP_IGNORE( defConnRecordSet->LoadL( Session() ) );
       
  2620     if ( defConnRecordSet->iRecords.Count() > 0 )
       
  2621         {
       
  2622         defConnRecord->SetElementId( defConnRecordSet->iRecords[0]->ElementId() );
       
  2623         defConnRecord->LoadL( Session() );
       
  2624 
       
  2625         aGenConnSettings.iUsageOfWlan =
       
  2626                 TCmUsageOfWlan( ( TInt )defConnRecord->iUsageOfWlan );
       
  2627         aGenConnSettings.iCellularDataUsageHome =
       
  2628                 TCmCellularDataUsage( ( TInt )defConnRecord->iCellularDataUsageHome );
       
  2629         aGenConnSettings.iCellularDataUsageVisitor =
       
  2630                 TCmCellularDataUsage( ( TInt )defConnRecord->iCellularDataUsageVisitor );
       
  2631         }
       
  2632     else
       
  2633         {
       
  2634         iTrans->OpenTransactionLC();
       
  2635 
       
  2636         aGenConnSettings.iUsageOfWlan = ECmUsageOfWlanKnown;
       
  2637         aGenConnSettings.iCellularDataUsageHome = ECmCellularDataUsageAutomatic;
       
  2638         aGenConnSettings.iCellularDataUsageVisitor = ECmCellularDataUsageConfirm;
       
  2639 
       
  2640         defConnRecord->SetRecordId( KCDNewRecordRequest );
       
  2641         defConnRecord->iUsageOfWlan = ( TUint )aGenConnSettings.iUsageOfWlan;
       
  2642         defConnRecord->iCellularDataUsageHome =
       
  2643                 ( TUint )aGenConnSettings.iCellularDataUsageHome;
       
  2644         defConnRecord->iCellularDataUsageVisitor =
       
  2645                 ( TUint )aGenConnSettings.iCellularDataUsageVisitor;
       
  2646         defConnRecord->StoreL( Session() );
       
  2647 
       
  2648         iTrans->CommitTransactionL();
       
  2649         }
       
  2650 
       
  2651     CleanupStack::PopAndDestroy( defConnRecord );
       
  2652     CleanupStack::PopAndDestroy( defConnRecordSet );
       
  2653 
       
  2654     OstTraceFunctionExit0( CCMMCACHE_READGENCONNSETTINGSL_EXIT );
       
  2655     }
       
  2656 
       
  2657 //-----------------------------------------------------------------------------
       
  2658 // Write general connection settings to database.
       
  2659 //-----------------------------------------------------------------------------
       
  2660 //
       
  2661 void CCmmCache::WriteGenConnSettingsL( const TCmGenConnSettings& aGenConnSettings )
       
  2662     {
       
  2663     OstTraceFunctionEntry0( CCMMCACHE_WRITEGENCONNSETTINGSL_ENTRY );
       
  2664 
       
  2665     iTrans->OpenTransactionLC();
       
  2666 
       
  2667     ReplaceGenConnSettingsL( aGenConnSettings );
       
  2668 
       
  2669     iTrans->CommitTransactionL();
       
  2670 
       
  2671     OstTraceFunctionExit0( CCMMCACHE_WRITEGENCONNSETTINGSL_EXIT );
       
  2672     }
       
  2673 
       
  2674 //-----------------------------------------------------------------------------
       
  2675 //  CCmmCache::ReplaceGenConnSettingsL()
       
  2676 //-----------------------------------------------------------------------------
       
  2677 //
       
  2678 void CCmmCache::ReplaceGenConnSettingsL( const TCmGenConnSettings& aGenConnSettings )
       
  2679     {
       
  2680     OstTraceFunctionEntry0( CCMMCACHE_REPLACEGENCONNSETTINGSL_ENTRY );
       
  2681     TBool oldRecordExists( EFalse );
       
  2682 
       
  2683     CommsDat::CMDBRecordSet<CCDDefConnRecord>* defConnRecordSet =
       
  2684             new( ELeave ) CommsDat::CMDBRecordSet<CCDDefConnRecord>(
       
  2685                     iCmManagerImpl->TableId( ECmmDbDefConnRecord ) );
       
  2686     CleanupStack::PushL( defConnRecordSet );
       
  2687 
       
  2688     CCDDefConnRecord* defConnRecord =
       
  2689             new( ELeave ) CCDDefConnRecord(
       
  2690                     iCmManagerImpl->TableId( ECmmDbDefConnRecord ) );
       
  2691     CleanupStack::PushL( defConnRecord );
       
  2692 
       
  2693     TRAPD( err, defConnRecordSet->LoadL( Session() ) );
       
  2694     if ( err == KErrNone )
       
  2695         {
       
  2696         defConnRecord->SetElementId( defConnRecordSet->iRecords[0]->ElementId() );
       
  2697         defConnRecord->LoadL( Session() );
       
  2698         oldRecordExists = ETrue;
       
  2699         }
       
  2700     else if ( err == KErrNotFound )
       
  2701         {
       
  2702         defConnRecord->SetRecordId( KCDNewRecordRequest );
       
  2703         }
       
  2704     else
       
  2705         {
       
  2706         User::Leave( err );
       
  2707         }
       
  2708 
       
  2709     defConnRecord->iUsageOfWlan = ( TUint )aGenConnSettings.iUsageOfWlan;
       
  2710     defConnRecord->iCellularDataUsageHome = ( TUint )aGenConnSettings.iCellularDataUsageHome;
       
  2711     defConnRecord->iCellularDataUsageVisitor = ( TUint )aGenConnSettings.iCellularDataUsageVisitor;
       
  2712 
       
  2713     if ( oldRecordExists )
       
  2714         {
       
  2715         defConnRecord->ModifyL( Session() );
       
  2716         }
       
  2717     else
       
  2718         {
       
  2719         defConnRecord->StoreL( Session() );
       
  2720         }
       
  2721 
       
  2722     CleanupStack::PopAndDestroy( defConnRecord );
       
  2723     CleanupStack::PopAndDestroy( defConnRecordSet );
       
  2724 
       
  2725     OstTraceFunctionExit0( CCMMCACHE_REPLACEGENCONNSETTINGSL_EXIT );
       
  2726     }
       
  2727 
       
  2728 // ---------------------------------------------------------------------------
       
  2729 // Opens a transaction and deletes the given connection method.
       
  2730 // ---------------------------------------------------------------------------
       
  2731 //
       
  2732 void CCmmCache::DeletePluginL( CCmmConnMethodStruct& aConnMethodStruct )
       
  2733     {
       
  2734     iTrans->OpenTransactionLC();
       
  2735     aConnMethodStruct.GetPlugin()->DeleteL();
       
  2736     iTrans->CommitTransactionL();
       
  2737     }
       
  2738 
       
  2739 // ---------------------------------------------------------------------------
       
  2740 // Enumerates connections and checks if the given connection method is
       
  2741 // connected.
       
  2742 // ---------------------------------------------------------------------------
       
  2743 //
       
  2744 TBool CCmmCache::CheckIfCmConnected( const TUint32 aCmId ) const
       
  2745     {
       
  2746     OstTraceFunctionEntry0( CCMMCACHE_CHECKIFCMCONNECTED_ENTRY );
       
  2747 
       
  2748     TBool result( EFalse );
       
  2749     RSocketServ ss;
       
  2750     RConnection connection;
       
  2751     TUint connectionCount( 0 );
       
  2752 
       
  2753     if ( ss.Connect() == KErrNone )
       
  2754         {
       
  2755         if ( connection.Open( ss, KAfInet ) == KErrNone )
       
  2756             {
       
  2757             if ( connection.EnumerateConnections( connectionCount ) == KErrNone )
       
  2758                 {
       
  2759                 TPckgBuf<TConnectionInfo> connInfo;
       
  2760 
       
  2761                 for ( TInt i = 1; i <= connectionCount; i++ )
       
  2762                     {
       
  2763                     connection.GetConnectionInfo( i, connInfo );
       
  2764 
       
  2765                     if ( connInfo().iIapId == aCmId )
       
  2766                         {
       
  2767                         result = ETrue;
       
  2768                         break;
       
  2769                         }
       
  2770                     }
       
  2771 
       
  2772                 }
       
  2773             connection.Close();
       
  2774             }
       
  2775         ss.Close();
       
  2776         }
       
  2777 
       
  2778     OstTraceFunctionExit0( CCMMCACHE_CHECKIFCMCONNECTED_EXIT );
       
  2779     return result;
       
  2780     }
       
  2781 
       
  2782 // ---------------------------------------------------------------------------
       
  2783 // Enumerates connections and checks if any of the connection methods in the
       
  2784 // given destination is connected.
       
  2785 // If pointer to destination instance is given, then information about
       
  2786 // relevant connection methods is retrieved from that. Otherwise the
       
  2787 // information is retrieved from instance mapping using the given ID.
       
  2788 // ---------------------------------------------------------------------------
       
  2789 //
       
  2790 TBool CCmmCache::DestinationConnectedL(
       
  2791         const TUint32 aDestinationId,
       
  2792         CCmmDestinationInstance* aDestinationInstance ) const
       
  2793     {
       
  2794     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONCONNECTEDL_ENTRY );
       
  2795 
       
  2796     TBool result( EFalse );
       
  2797     RSocketServ ss;
       
  2798     RConnection connection;
       
  2799     TUint connectionCount( 0 );
       
  2800 
       
  2801     if ( ss.Connect() == KErrNone )
       
  2802         {
       
  2803         if ( connection.Open( ss, KAfInet ) == KErrNone )
       
  2804             {
       
  2805             if ( connection.EnumerateConnections( connectionCount ) == KErrNone )
       
  2806                 {
       
  2807                 RArray<TCmmConnMethodItem> connMethodArray;
       
  2808                 CleanupClosePushL( connMethodArray );
       
  2809 
       
  2810                 // If destination instance provided, take the destination's
       
  2811                 // connection methods from there. Otherwise get the connection
       
  2812                 // methods from instance mapping. (If the destination is marked
       
  2813                 // to be deleted, instance mapping won't have information about
       
  2814                 // it.)
       
  2815                 if ( aDestinationInstance )
       
  2816                     {
       
  2817                     for ( TInt i = 0; i < aDestinationInstance->iConnMethodItemArray.Count(); i++ )
       
  2818                         {
       
  2819                         connMethodArray.AppendL( aDestinationInstance->iConnMethodItemArray[i] );
       
  2820                         }
       
  2821                     }
       
  2822                 else
       
  2823                     {
       
  2824                     iInstanceMapping->GetConnMethodsFromDestinationL(
       
  2825                             aDestinationId,
       
  2826                             connMethodArray );
       
  2827                     }
       
  2828 
       
  2829                 // Iterate through all connections.
       
  2830                 TPckgBuf<TConnectionInfo> connInfo;
       
  2831                 for ( TUint i = 1; i <= connectionCount; i++ )
       
  2832                     {
       
  2833                     connection.GetConnectionInfo( i, connInfo );
       
  2834 
       
  2835                     // Iterate through all connection methods in destinations.
       
  2836                     for ( TInt j = 0; j < connMethodArray.Count(); j++ )
       
  2837                         {
       
  2838                         if ( connInfo().iIapId == connMethodArray[j].iId )
       
  2839                             {
       
  2840                             result = ETrue;
       
  2841                             break;
       
  2842                             }
       
  2843                         }
       
  2844                     if ( result )
       
  2845                         {
       
  2846                         break;
       
  2847                         }
       
  2848                     }
       
  2849 
       
  2850                 CleanupStack::PopAndDestroy( &connMethodArray );
       
  2851                 }
       
  2852             connection.Close();
       
  2853             }
       
  2854         ss.Close();
       
  2855         }
       
  2856 
       
  2857     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONCONNECTEDL_EXIT );
       
  2858     return result;
       
  2859     }
       
  2860 
       
  2861 // ---------------------------------------------------------------------------
       
  2862 // Check from database if the given destination is an embedded destination in
       
  2863 // any other destination.
       
  2864 // ---------------------------------------------------------------------------
       
  2865 //
       
  2866 TBool CCmmCache::DestinationIsEmbedded( const TUint32 aDestinationId ) const
       
  2867     {
       
  2868     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONISEMBEDDED_ENTRY );
       
  2869 
       
  2870     TBool isEmbedded = iInstanceMapping->DestinationIsEmbedded( aDestinationId );
       
  2871 
       
  2872     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONISEMBEDDED_EXIT );
       
  2873     return isEmbedded;
       
  2874     }
       
  2875 
       
  2876 // ---------------------------------------------------------------------------
       
  2877 // Check from database if the given destination has an embedded destination.
       
  2878 // ---------------------------------------------------------------------------
       
  2879 //
       
  2880 TBool CCmmCache::DestinationHasEmbedded( const TUint32 aDestinationId ) const
       
  2881     {
       
  2882     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONHASEMBEDDED_ENTRY );
       
  2883 
       
  2884     TBool hasEmbedded = iInstanceMapping->DestinationHasEmbedded( aDestinationId );
       
  2885 
       
  2886     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONHASEMBEDDED_EXIT );
       
  2887     return hasEmbedded;
       
  2888     }
       
  2889 
       
  2890 // ---------------------------------------------------------------------------
       
  2891 // Check from database if the given destination is pointed to by any virtual
       
  2892 // IAP.
       
  2893 // ---------------------------------------------------------------------------
       
  2894 //
       
  2895 TBool CCmmCache::DestinationPointedToByVirtualIap( const TUint32 aDestinationId ) const
       
  2896     {
       
  2897     OstTraceFunctionEntry0( CCMMCACHE_DESTINATIONPOINTEDTOBYVIRTUALIAP_ENTRY );
       
  2898 
       
  2899     TBool pointedByVirtual =
       
  2900             iInstanceMapping->DestinationPointedToByVirtualIap( aDestinationId );
       
  2901 
       
  2902     OstTraceFunctionExit0( CCMMCACHE_DESTINATIONPOINTEDTOBYVIRTUALIAP_EXIT );
       
  2903     return pointedByVirtual;
       
  2904     }
       
  2905 
       
  2906 // ---------------------------------------------------------------------------
       
  2907 // Check from database if the given connection method is pointed to by any
       
  2908 // virtual IAP.
       
  2909 // ---------------------------------------------------------------------------
       
  2910 //
       
  2911 TBool CCmmCache::ConnMethodPointedToByVirtualIap( const TUint32 aConnMethodId ) const
       
  2912     {
       
  2913     OstTraceFunctionEntry0( CCMMCACHE_CONNMETHODPOINTEDTOBYVIRTUALIAP_ENTRY );
       
  2914 
       
  2915     TBool pointedToByVirtual =
       
  2916             iInstanceMapping->ConnMethodPointedToByVirtualIap( aConnMethodId );
       
  2917 
       
  2918     OstTraceFunctionExit0( CCMMCACHE_CONNMETHODPOINTEDTOBYVIRTUALIAP_EXIT );
       
  2919     return pointedToByVirtual;
       
  2920     }
       
  2921 
       
  2922 // ---------------------------------------------------------------------------
       
  2923 // Check if the given connection method is the only connection method in the
       
  2924 // given destination and if a virtual IAP points to that destination.
       
  2925 // ---------------------------------------------------------------------------
       
  2926 //
       
  2927 TBool CCmmCache::ConnMethodInDestinationButLocked(
       
  2928         const TUint32 aConnMethodId,
       
  2929         const TUint32 aDestinationId ) const
       
  2930     {
       
  2931     OstTraceFunctionEntry0( CCMMCACHE_CONNMETHODINDESTINATIONBUTLOCKED_ENTRY );
       
  2932 
       
  2933     TBool inAndlocked = iInstanceMapping->
       
  2934             ConnMethodInDestinationButLocked( aConnMethodId, aDestinationId );
       
  2935 
       
  2936     OstTraceFunctionExit0( CCMMCACHE_CONNMETHODINDESTINATIONBUTLOCKED_EXIT );
       
  2937     return inAndlocked;
       
  2938     }
       
  2939 
       
  2940 // ---------------------------------------------------------------------------
       
  2941 // Remove all references to the given connection method from the datamobility
       
  2942 // selection policy records. Then update instance mapping to reflect the
       
  2943 // current database state, and notify any possible client handles for the
       
  2944 // changed destinations. Also removes the connection method from any
       
  2945 // destination handles the client has open.
       
  2946 // ---------------------------------------------------------------------------
       
  2947 //
       
  2948 void CCmmCache::RemoveAllReferencesToConnMethodL(
       
  2949         CCmmConnMethodInstance& aConnMethodInstance )
       
  2950     {
       
  2951     OstTraceFunctionEntry0( CCMMCACHE_REMOVEALLREFERENCESTOCONNMETHODL_ENTRY );
       
  2952 
       
  2953     TUint32 connMethodId( aConnMethodInstance.GetId() );
       
  2954 
       
  2955     iTrans->OpenTransactionLC();
       
  2956 
       
  2957     // Create DataMobilitySelectionPolicy-record set.
       
  2958     CommsDat::CMDBRecordSet<CCDDataMobilitySelectionPolicyRecord>* snapRecordSet =
       
  2959             new( ELeave ) CommsDat::CMDBRecordSet<CCDDataMobilitySelectionPolicyRecord>(
       
  2960                     iCmManagerImpl->TableId( ECmmDbSnapRecord ) );
       
  2961     CleanupStack::PushL( snapRecordSet );
       
  2962 
       
  2963     // Create a DataMobilitySelectionPolicy-record.
       
  2964     CCDDataMobilitySelectionPolicyRecord* snapRecord =
       
  2965             new( ELeave ) CCDDataMobilitySelectionPolicyRecord(
       
  2966                     iCmManagerImpl->TableId( ECmmDbSnapRecord ) );
       
  2967     CleanupStack::PushL( snapRecord );
       
  2968 
       
  2969     TRAP_IGNORE( snapRecordSet->LoadL( iTrans->Session() ) );
       
  2970 
       
  2971     // Read IAP ID from each record and delete any that match the connection
       
  2972     // method we are removing all references for.
       
  2973     TUint32 connMethodIdInRecord( 0 );
       
  2974     TInt snapRecordCount( snapRecordSet->iRecords.Count() );
       
  2975     for ( TInt i = 0; i < snapRecordCount; i++ )
       
  2976         {
       
  2977         snapRecord->SetElementId( snapRecordSet->iRecords[i]->ElementId() );
       
  2978         snapRecord->LoadL( iTrans->Session() );
       
  2979 
       
  2980         connMethodIdInRecord = ( snapRecord->iIAP & KCDMaskShowRecordId ) >> 8;
       
  2981         if ( connMethodIdInRecord == connMethodId )
       
  2982             {
       
  2983             snapRecord->DeleteL( iTrans->Session() );
       
  2984             }
       
  2985         }
       
  2986     CleanupStack::PopAndDestroy( snapRecord );
       
  2987     CleanupStack::PopAndDestroy( snapRecordSet );
       
  2988 
       
  2989     iTrans->CommitTransactionL();
       
  2990 
       
  2991     // Reference count will be zero if this method call is not part of some
       
  2992     // bigger operation (e.g. connection method delete).
       
  2993     if ( iTrans->GetReferenceCount() == 0 )
       
  2994         {
       
  2995         // Update instance mapping to reflect the current database state, and
       
  2996         // notify any possible client handles for the changed destinations.
       
  2997         RArray<TUint32> changedDestinations;
       
  2998         iInstanceMapping->RemoveConnMethodFromDestinations( connMethodId, changedDestinations );
       
  2999         for ( TInt i = 0; i < changedDestinations.Count(); i++ )
       
  3000             {
       
  3001             TCmmIdStruct idStruct( changedDestinations[i], 0 );
       
  3002             aConnMethodInstance.RefreshHandlesForAllSessions( idStruct );
       
  3003             }
       
  3004         changedDestinations.Close();
       
  3005 
       
  3006         // Remove the connection method from any destination handles the client
       
  3007         // has open.
       
  3008         aConnMethodInstance.RemoveConnMethodFromSessionDestinationHandles( connMethodId );
       
  3009         }
       
  3010 
       
  3011     OstTraceFunctionExit0( CCMMCACHE_REMOVEALLREFERENCESTOCONNMETHODL_EXIT );
       
  3012     }
       
  3013 
       
  3014 // ---------------------------------------------------------------------------
       
  3015 // Update the ID of a new destination from temporary ID to real ID after a
       
  3016 // successful update to database.
       
  3017 // ---------------------------------------------------------------------------
       
  3018 //
       
  3019 void CCmmCache::RefreshDestinationId( const TCmmIdStruct& aIdStruct )
       
  3020     {
       
  3021     OstTraceFunctionEntry0( CCMMCACHE_REFRESHDESTINATIONID_ENTRY );
       
  3022 
       
  3023     // Iterate destinations in cache and update the ID if match found.
       
  3024     for ( TInt i = 0; i < iDestinationArray.Count(); i++ )
       
  3025         {
       
  3026         if ( iDestinationArray[i]->GetId() == aIdStruct.iTemporaryId )
       
  3027             {
       
  3028             iDestinationArray[i]->SetId( aIdStruct.iRealId );
       
  3029             break;
       
  3030             }
       
  3031         }
       
  3032 
       
  3033     OstTraceFunctionExit0( CCMMCACHE_REFRESHDESTINATIONID_EXIT );
       
  3034     }
       
  3035 
       
  3036 // ---------------------------------------------------------------------------
       
  3037 // Update the ID of a new connection method from temporary ID to real ID after
       
  3038 // a successful update to database.
       
  3039 // ---------------------------------------------------------------------------
       
  3040 //
       
  3041 void CCmmCache::RefreshConnMethodId( const TCmmIdStruct& aIdStruct )
       
  3042     {
       
  3043     OstTraceFunctionEntry0( CCMMCACHE_REFRESHCONNMETHODID_ENTRY );
       
  3044 
       
  3045     // Iterate connection methods in cache and update the ID if match found.
       
  3046     for ( TInt i = 0; i < iConnMethodArray.Count(); i++ )
       
  3047         {
       
  3048         if ( iConnMethodArray[i]->GetId() == aIdStruct.iTemporaryId )
       
  3049             {
       
  3050             iConnMethodArray[i]->SetId( aIdStruct.iRealId );
       
  3051             break; // Can only be 1 match.
       
  3052             }
       
  3053         }
       
  3054 
       
  3055     OstTraceFunctionExit0( CCMMCACHE_REFRESHCONNMETHODID_EXIT );
       
  3056     }
       
  3057 
       
  3058 // ---------------------------------------------------------------------------
       
  3059 // During destination update, after updating connection methods inside the
       
  3060 // destination, the database records containing the information of what
       
  3061 // connection methods are inside the destination need to be updated with real
       
  3062 // IDs for any newly created connection methods. These real IDs are held in the
       
  3063 // temporary array iUpdatedConnMethods until successful commit to database.
       
  3064 // This method is used to find out those real IDs before that.
       
  3065 // ---------------------------------------------------------------------------
       
  3066 //
       
  3067 void CCmmCache::TranslateTemporaryId( const TUint32 aTemporaryId, TUint32& aRealId ) const
       
  3068     {
       
  3069     OstTraceFunctionEntry0( CCMMCACHE_TRANSLATETEMPORARYID_ENTRY );
       
  3070 
       
  3071     aRealId = 0;
       
  3072 
       
  3073     for ( TInt i = 0; i < iUpdatedConnMethods.Count(); i++ )
       
  3074         {
       
  3075         if ( iUpdatedConnMethods[i].iTemporaryId == aTemporaryId )
       
  3076             {
       
  3077             aRealId = iUpdatedConnMethods[i].iRealId;
       
  3078             break;
       
  3079             }
       
  3080         }
       
  3081     if ( !aRealId )
       
  3082         {
       
  3083         ASSERT( 0 );
       
  3084         }
       
  3085 
       
  3086     OstTraceFunctionExit0( CCMMCACHE_TRANSLATETEMPORARYID_EXIT );
       
  3087     }
       
  3088 
       
  3089 // ---------------------------------------------------------------------------
       
  3090 // Check if the given connection method can have all references removed and
       
  3091 // made into an uncategorized connection method.
       
  3092 // ---------------------------------------------------------------------------
       
  3093 //
       
  3094 void CCmmCache::CheckIfConnMethodReferencesCanBeRemovedL(
       
  3095         const CCmmConnMethodInstance& aConnMethodInstance )
       
  3096     {
       
  3097     OstTraceFunctionEntry0( CCMMCACHE_CHECKIFCONNMETHODREFERENCESCANBEREMOVEDL_ENTRY );
       
  3098 
       
  3099     TUint32 connMethodId( aConnMethodInstance.GetId() );
       
  3100 
       
  3101     // Check that connection method exists in database.
       
  3102     if ( !iInstanceMapping->ValidConnMethodId( connMethodId ) )
       
  3103         {
       
  3104         User::Leave( KErrNotFound );
       
  3105         }
       
  3106 
       
  3107     // Can't remove an embedded destination this way.
       
  3108     if ( aConnMethodInstance.IsEmbeddedDestination() )
       
  3109         {
       
  3110         User::Leave( KErrArgument );
       
  3111         }
       
  3112 
       
  3113     // Iterate all destinations in database and check if possible reference can
       
  3114     // be removed.
       
  3115     RArray<TUint32> dbDestinations;
       
  3116     CleanupClosePushL( dbDestinations );
       
  3117     iInstanceMapping->GetDestinationsL( dbDestinations );
       
  3118     for ( TInt i = 0; i < dbDestinations.Count(); i++ )
       
  3119         {
       
  3120         if ( iInstanceMapping->ConnMethodInDestinationButLocked(
       
  3121                 connMethodId,
       
  3122                 dbDestinations[i] ) )
       
  3123             {
       
  3124             User::Leave( KErrLocked );
       
  3125             }
       
  3126         }
       
  3127     CleanupStack::PopAndDestroy( &dbDestinations );
       
  3128 
       
  3129     // Can't remove a connection method that is in use.
       
  3130     if ( CheckIfCmConnected( connMethodId ) )
       
  3131         {
       
  3132         User::Leave( KErrInUse );
       
  3133         }
       
  3134 
       
  3135     OstTraceFunctionExit0( CCMMCACHE_CHECKIFCONNMETHODREFERENCESCANBEREMOVEDL_EXIT );
       
  3136     }
       
  3137 
       
  3138 // ---------------------------------------------------------------------------
       
  3139 // Check if given connection method is referenced from any protected destination.
       
  3140 // ---------------------------------------------------------------------------
       
  3141 //
       
  3142 void CCmmCache::CheckIfConnMethodBelongsToProtectedDestinationL(
       
  3143         const CCmmConnMethodInstance& aConnMethodInstance,
       
  3144         TBool& aBelongsToProtectedDestination )
       
  3145     {
       
  3146     OstTraceFunctionEntry0( CCMMCACHE_CHECKIFCONNMETHODBELONGSTOPROTECTEDDESTINATIONL_ENTRY );
       
  3147 
       
  3148     TUint32 connMethodId( aConnMethodInstance.GetId() );
       
  3149 
       
  3150     // Check that connection method exists in database.
       
  3151     if ( !iInstanceMapping->ValidConnMethodId( connMethodId ) )
       
  3152         {
       
  3153         User::Leave( KErrNotFound );
       
  3154         }
       
  3155 
       
  3156     aBelongsToProtectedDestination = EFalse;
       
  3157     // Get destinations which have references to connection method passed as parameter.
       
  3158     RArray<TUint32> dbDestinations;
       
  3159     CleanupClosePushL( dbDestinations );
       
  3160     iInstanceMapping->DestinationsContainingConnMethodL( connMethodId, dbDestinations );
       
  3161     TUint32 metadata( 0 );
       
  3162     for ( TInt i = 0; i < dbDestinations.Count(); i++ )
       
  3163         {
       
  3164         // Check if any of destinations is protected.
       
  3165         metadata = iInstanceMapping->DestinationMetadata( dbDestinations[i] );
       
  3166         TUint32 protlevel =
       
  3167                 ( metadata & KDestProtectionLevelMask ) >> KBitsToShiftDestProtectionLevel;
       
  3168         if ( protlevel == CMManager::EProtLevel1 || protlevel == CMManager::EProtLevel3 )
       
  3169             {
       
  3170             aBelongsToProtectedDestination = ETrue;
       
  3171             break;
       
  3172             }
       
  3173         }
       
  3174     CleanupStack::PopAndDestroy( &dbDestinations );
       
  3175 
       
  3176     OstTraceFunctionExit0( CCMMCACHE_CHECKIFCONNMETHODBELONGSTOPROTECTEDDESTINATIONL_EXIT );
       
  3177     }
       
  3178 
       
  3179 // ---------------------------------------------------------------------------
       
  3180 // Check if the given connection method can be deleted.
       
  3181 // ---------------------------------------------------------------------------
       
  3182 //
       
  3183 void CCmmCache::CheckIfConnMethodCanBeDeletedL(
       
  3184         const CCmmConnMethodInstance& aConnMethodInstance )
       
  3185     {
       
  3186     OstTraceFunctionEntry0( CCMMCACHE_CHECKIFCONNMETHODCANBEDELETEDL_ENTRY );
       
  3187 
       
  3188     TUint32 connMethodId( aConnMethodInstance.GetId() );
       
  3189 
       
  3190     // Find connection method from cache.
       
  3191     TInt index = FindConnMethodFromCache( connMethodId );
       
  3192     if ( index == KErrNotFound )
       
  3193         {
       
  3194         User::Leave( KErrBadHandle );
       
  3195         }
       
  3196 
       
  3197     // Check connection method status at cache side.
       
  3198     switch ( iConnMethodArray[index]->GetStatus() )
       
  3199         {
       
  3200         case ECmmConnMethodStatusNotSaved:
       
  3201             {
       
  3202             // Connection method is not in database, nothing to delete.
       
  3203             User::Leave( KErrNotFound );
       
  3204             }
       
  3205             break;
       
  3206         case ECmmConnMethodStatusValid:
       
  3207             // Proceed.
       
  3208             break;
       
  3209         case ECmmConnMethodStatusToBeDeleted:
       
  3210             // Connection method has already been deleted.
       
  3211             return;
       
  3212         case ECmmConnMethodStatusChanged:
       
  3213         default:
       
  3214             {
       
  3215             ASSERT( 0 ); // Error, illegal status.
       
  3216             User::Leave( KErrCorrupt );
       
  3217             }
       
  3218             break;
       
  3219         }
       
  3220 
       
  3221     // Removing all references is part of deleting a connection method. Check
       
  3222     // if can do that.
       
  3223     CheckIfConnMethodReferencesCanBeRemovedL( aConnMethodInstance );
       
  3224 
       
  3225     // Check that no virtual IAP points to this connection method.
       
  3226     if ( iInstanceMapping->ConnMethodPointedToByVirtualIap( connMethodId ) )
       
  3227         {
       
  3228         User::Leave( KErrLocked );
       
  3229         }
       
  3230 
       
  3231     OstTraceFunctionExit0( CCMMCACHE_CHECKIFCONNMETHODCANBEDELETEDL_EXIT );
       
  3232     }
       
  3233 
       
  3234 // ---------------------------------------------------------------------------
       
  3235 // Check if the given destination can be deleted.
       
  3236 // ---------------------------------------------------------------------------
       
  3237 //
       
  3238 void CCmmCache::CheckIfDestinationCanBeDeletedL(
       
  3239         const CCmmDestinationInstance& aDestinationInstance )
       
  3240     {
       
  3241     OstTraceFunctionEntry0( CCMMCACHE_CHECKIFDESTINATIONCANBEDELETEDL_ENTRY );
       
  3242 
       
  3243     TUint32 destinationId( aDestinationInstance.GetId() );
       
  3244 
       
  3245     // Find destination from cache.
       
  3246     TInt index = FindDestinationFromCache( destinationId );
       
  3247     if ( index == KErrNotFound )
       
  3248         {
       
  3249         User::Leave( KErrBadHandle );
       
  3250         }
       
  3251 
       
  3252     // Check destination status in cache.
       
  3253     switch ( iDestinationArray[index]->GetStatus() )
       
  3254         {
       
  3255         case ECmmDestinationStatusNotSaved:
       
  3256             {
       
  3257             User::Leave( KErrNotFound );
       
  3258             }
       
  3259             break;
       
  3260         case ECmmDestinationStatusValid:
       
  3261             // Proceed.
       
  3262             break;
       
  3263         case ECmmDestinationStatusToBeDeleted:
       
  3264             // Destination has already been deleted.
       
  3265             return;
       
  3266         case ECmmDestinationStatusChanged:
       
  3267         default:
       
  3268             {
       
  3269             ASSERT( 0 ); // Error, illegal status.
       
  3270             User::Leave( KErrCorrupt );
       
  3271             }
       
  3272             break;
       
  3273         }
       
  3274 
       
  3275     // Check destination exists in database.
       
  3276     if ( !iInstanceMapping->ValidDestinationId( destinationId ) )
       
  3277         {
       
  3278         User::Leave( KErrNotFound );
       
  3279         }
       
  3280 
       
  3281     // Check if any virtual IAP points to this destination. Don't check session side.
       
  3282     if ( iInstanceMapping->DestinationPointedToByVirtualIap( destinationId ) )
       
  3283         {
       
  3284         User::Leave( KErrLocked );
       
  3285         }
       
  3286 
       
  3287     // Check if any of the connection methods in this destination are currently in use.
       
  3288     if ( DestinationConnectedL( destinationId ) )
       
  3289         {
       
  3290         User::Leave( KErrInUse );
       
  3291         }
       
  3292 
       
  3293     OstTraceFunctionExit0( CCMMCACHE_CHECKIFDESTINATIONCANBEDELETEDL_EXIT );
       
  3294     }
       
  3295 
       
  3296 // ---------------------------------------------------------------------------
       
  3297 // Return the requested table ID.
       
  3298 // ---------------------------------------------------------------------------
       
  3299 //
       
  3300 CommsDat::TMDBElementId CCmmCache::TableId( TCmmDbRecords aRecord )
       
  3301     {
       
  3302     return iCmManagerImpl->TableId( aRecord );
       
  3303     }
       
  3304 
       
  3305 // ---------------------------------------------------------------------------
       
  3306 // Initiate the deletion of given destination if none of the connection
       
  3307 // methods inside it are connected.
       
  3308 // ---------------------------------------------------------------------------
       
  3309 //
       
  3310 void CCmmCache::DeleteDestinationForcedL( CCmmDestinationInstance& aDestinationInstance )
       
  3311     {
       
  3312     OstTraceFunctionEntry0( CCMMCACHE_DELETEDESTINATIONFORCEDL_ENTRY );
       
  3313 
       
  3314     if ( !DestinationConnectedL( 0, &aDestinationInstance ) )
       
  3315         {
       
  3316         DeleteDestinationL( aDestinationInstance, ETrue );
       
  3317         }
       
  3318 
       
  3319     OstTraceFunctionExit0( CCMMCACHE_DELETEDESTINATIONFORCEDL_EXIT );
       
  3320     }
       
  3321 
       
  3322 // End of file