realtimenetprots/sipfw/ProfileAgent/Server/Src/SipProfileServerCore.cpp
changeset 0 307788aac0a8
child 4 dd3853b8dc3f
child 15 8248b03a2669
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name        : sipprofileservercore.cpp
       
    15 // Part of     : SIP Profile Server
       
    16 // implementation
       
    17 // Version     : 1.0
       
    18 //
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include "SipProfileServerCore.h"
       
    24 #include "SipProfileCSServer.h"
       
    25 #include "sipextendedconcreteprofileobserver.h"
       
    26 #include "SIPProfileStorage.h"
       
    27 #include "SipProfileStorageSecureBackup.h"
       
    28 #include "SipProfileCacheItem.h"
       
    29 #include "SipProfileCacheCleanupItem.h"
       
    30 #include "sipconcreteprofile.h"
       
    31 #include "sipprofileplugins.h"
       
    32 #include "sipplugindirector.h"
       
    33 #include "SipProfileStateUnregistered.h"
       
    34 #include "SipProfileStateRegistered.h"
       
    35 #include "SipProfileStateRegInProg.h"
       
    36 #include "SipProfileStateUnregInProg.h"
       
    37 #include "sipprofilestatewaitforiap.h"
       
    38 #include "sipprofilestatewaitforpermission.h"
       
    39 #include "sipprofilestatemigratingtonewiap.h"
       
    40 #include "sipprofilestateunregisteringoldiap.h"
       
    41 #include "SipProfileLog.h"
       
    42 #include "sipalrhandler.h"
       
    43 #include "sipalrmigrationcontroller.h"
       
    44 #include "sipmanagedprofile.h"
       
    45 #include "sipprofile.h"
       
    46 #include "sipprofilecs.h"
       
    47 #include "SIPProfileStorageIndex.h"
       
    48 #include <siperr.h>
       
    49 #include <sipsystemstatemonitor.h>
       
    50 #include <random.h>
       
    51 
       
    52 
       
    53 // ============================ MEMBER FUNCTIONS ===============================
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // CSIPProfileServerCore::NewL
       
    57 // Two-phased constructor.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 CSIPProfileServerCore* CSIPProfileServerCore::NewL()
       
    61     {
       
    62     CSIPProfileServerCore* self = CSIPProfileServerCore::NewLC();
       
    63     CleanupStack::Pop(self);
       
    64     return self;
       
    65     }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // CSIPProfileServerCore::NewLC
       
    69 // Two-phased constructor.
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 CSIPProfileServerCore* CSIPProfileServerCore::NewLC()
       
    73     {
       
    74     CSIPProfileServerCore* self = new(ELeave)CSIPProfileServerCore();
       
    75     CleanupStack::PushL(self);
       
    76     self->ConstructL();
       
    77     return self;
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // CSIPProfileServerCore::CSIPProfileServerCore
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 CSIPProfileServerCore::CSIPProfileServerCore() :
       
    85 	iBackupInProgress(EFalse)
       
    86 #ifdef CPPUNIT_TEST
       
    87     // Set the array granularity to 1, so they allocate memory for every append    
       
    88     , iProfileCache(1),
       
    89     iObservers(1),
       
    90     iMigrationControllers(1)
       
    91 #endif
       
    92     {
       
    93     }
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // CSIPProfileServerCore::ConstructL
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 void CSIPProfileServerCore::ConstructL()
       
   100     {
       
   101     User::LeaveIfError(iFs.Connect());
       
   102 
       
   103     iFindEntry = CSIPProfileCacheItem::NewL(*this, iUnregistered);
       
   104 
       
   105     iPluginDirector = CSIPPluginDirector::NewL(*this);
       
   106 
       
   107     iUnregistered = CSIPProfileStateUnregistered::NewL(*iPluginDirector);
       
   108     iRegistered = CSIPProfileStateRegistered::NewL(*iPluginDirector);
       
   109     iUnregInProg = CSIPProfileStateUnregInProg::NewL(*iPluginDirector);
       
   110     iRegInProg = CSIPProfileStateRegInProg::NewL(*iPluginDirector);
       
   111     iWaitForIAP = CSIPProfileStateWaitForIAP::NewL(*iPluginDirector);
       
   112     iWaitForPermission =
       
   113     	CSIPProfileStateWaitForPermission::NewL(*iPluginDirector);
       
   114     iMigratingToNewIAP =
       
   115     	CSIPProfileStateMigratingToNewIAP::NewL(*iPluginDirector);
       
   116     iUnregisteringOldIAP =
       
   117     	CSIPProfileStateUnregisteringOldIAP::NewL(*iPluginDirector);
       
   118 
       
   119     iUnregistered->SetNeighbourStates(*iRegInProg, *iWaitForIAP);
       
   120     iRegistered->SetNeighbourStates(*iUnregInProg,
       
   121     								*iUnregistered,
       
   122     								*iRegInProg,
       
   123     								*iWaitForPermission);
       
   124     iUnregInProg->SetNeighbourStates(*iUnregistered, *iRegistered);
       
   125     iRegInProg->SetNeighbourStates(*iRegistered,
       
   126     							   *iUnregistered,
       
   127     							   *iUnregInProg,
       
   128     							   *iWaitForIAP,
       
   129     							   *iWaitForPermission);
       
   130     iWaitForIAP->SetNeighbourStates(*iWaitForPermission,
       
   131     								*iRegInProg,
       
   132     								*iUnregInProg,
       
   133     								*iUnregistered);
       
   134     iWaitForPermission->SetNeighbourStates(*iWaitForIAP,
       
   135     	*iMigratingToNewIAP,
       
   136     	*iRegInProg,
       
   137     	*iRegistered,
       
   138     	*iUnregInProg,
       
   139     	*iUnregistered);
       
   140     iMigratingToNewIAP->SetNeighbourStates(*iUnregisteringOldIAP,
       
   141     									   *iWaitForIAP,
       
   142     									   *iRegistered,
       
   143     									   *iUnregInProg,
       
   144     									   *iUnregistered);
       
   145 	iUnregisteringOldIAP->SetNeighbourStates(*iRegistered, *iUnregInProg);
       
   146 	
       
   147 	LoadSystemStateMonitorL();
       
   148 	
       
   149 	iAlrHandler = CSipAlrHandler::NewL(*this,iSystemStateMonitor);
       
   150 
       
   151     LoadProfilesL(EFalse);
       
   152 
       
   153     iNotify = CSIPProfileStorageSecureBackup::NewL(this);
       
   154     
       
   155     iServer = CSIPProfileCSServer::NewL(*this);
       
   156 	
       
   157 	iOfflineEventReceived = EFalse;
       
   158     
       
   159     PROFILE_DEBUG1("ProfileServer started")
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CSIPProfileServerCore::~CSIPProfileServerCore
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 CSIPProfileServerCore::~CSIPProfileServerCore()
       
   167     {
       
   168     // If the monitor plug-in is deleted later in destructor, leaks memory.
       
   169     if (iSystemStateMonitor)
       
   170     	{
       
   171     	iSystemStateMonitor->StopMonitoring( 
       
   172     	    CSipSystemStateMonitor::ESystemState, 0, *this);
       
   173     	delete iSystemStateMonitor;
       
   174     	}
       
   175     
       
   176     delete iServer;    
       
   177     
       
   178     iObservers.Reset();
       
   179 
       
   180 	// Profile cache entries use migration controllers, so delete entries first
       
   181     iProfileCache.ResetAndDestroy();
       
   182 
       
   183 	// Migration controllers use ALR handler, so delete controllers first
       
   184 	iMigrationControllers.ResetAndDestroy();
       
   185 	delete iAlrHandler;
       
   186 
       
   187     delete iProfileStorage;
       
   188     delete iPluginDirector;
       
   189     delete iProfilePlugins;
       
   190     delete iFindEntry;
       
   191 
       
   192     delete iUnregistered;
       
   193     delete iRegistered;
       
   194     delete iUnregInProg;
       
   195     delete iRegInProg;
       
   196     delete iWaitForIAP;
       
   197     delete iWaitForPermission;
       
   198     delete iMigratingToNewIAP;
       
   199     delete iUnregisteringOldIAP;
       
   200 
       
   201     delete iNotify;
       
   202 
       
   203     iFs.Close();
       
   204 
       
   205     PROFILE_DEBUG1("ProfileServer stopped")
       
   206     
       
   207 #ifdef _BullseyeCoverage
       
   208     // Store coverage measurement
       
   209     cov_write();
       
   210 #endif
       
   211     }
       
   212     
       
   213 // -----------------------------------------------------------------------------
       
   214 // CSIPProfileServerCore::SIPProfileStatusEvent
       
   215 // -----------------------------------------------------------------------------
       
   216 //
       
   217 void CSIPProfileServerCore::SIPProfileStatusEvent(CSIPConcreteProfile& aProfile,
       
   218 												  TUint32 aContextId)
       
   219     {
       
   220     CSIPProfileCacheItem* item = ProfileCacheItem(aProfile.Id());
       
   221     TRAPD(err, SIPProfileStatusEventL(aProfile.Id(), aContextId));
       
   222 
       
   223     if (err != KErrNone)
       
   224         {
       
   225 		if (item)
       
   226         	{
       
   227         	HandleAsyncError(*item,
       
   228         					 CSIPConcreteProfile::ERegistrationInProgress,
       
   229         					 err);
       
   230         	}
       
   231         }
       
   232     }
       
   233 
       
   234 // -----------------------------------------------------------------------------
       
   235 // CSIPProfileServerCore::SIPProfileStatusEventL
       
   236 // -----------------------------------------------------------------------------
       
   237 //
       
   238 void CSIPProfileServerCore::SIPProfileStatusEventL(TUint32 aProfileId,
       
   239     											   TUint32 aContextId)
       
   240     {
       
   241     PROFILE_DEBUG4("ProfileServerCore::SIPProfileStatusEventL id,ctxId",
       
   242     			   aProfileId, aContextId)
       
   243 
       
   244     CSIPProfileCacheItem* item = ProfileCacheItem(aProfileId);
       
   245     if (item)
       
   246     	{
       
   247 		// In MigratingToNewIAP state, only profile in use is new IAP's register
       
   248     	CSIPConcreteProfile::TStatus status;
       
   249         iPluginDirector->State(status, item->UsedProfile());
       
   250 
       
   251         item->RegistrationStatusEventL(status, aContextId);
       
   252 
       
   253         if (!item->IsActiveState() )
       
   254         	{
       
   255         	if (status == CSIPConcreteProfile::ERegistered)
       
   256         		item->RemoveL();
       
   257         	else
       
   258         	if (item->CanBePermanentlyRemoved())
       
   259         		{
       
   260         		RemoveProfileItem(aProfileId);
       
   261             	delete item;
       
   262 				item = NULL;
       
   263             	PROFILE_DEBUG3(
       
   264             	"ProfileServerCore::SIPProfileStatusEventL(removed) id",
       
   265                 	aProfileId)
       
   266             	}
       
   267         		
       
   268         	}
       
   269         if (item && item->IsRfsInprogress())
       
   270             {
       
   271             CSIPConcreteProfile::TStatus status;
       
   272             TInt count = iProfileCache.Count();
       
   273             for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   274                 {
       
   275                 iPluginDirector->State(status, iProfileCache[i]->UsedProfile());
       
   276                 if (status == CSIPConcreteProfile::EUnregistered)
       
   277                     count--;
       
   278                 }
       
   279             if (!count)
       
   280                 {
       
   281                 iSystemStateMonitor->EventProcessingCompleted(
       
   282 								CSipSystemStateMonitor::ERfsState, 0, *this);
       
   283                 }
       
   284             }
       
   285         }
       
   286 		
       
   287 		if (iOfflineEventReceived)
       
   288         {
       
   289         CSIPConcreteProfile::TStatus status;
       
   290         TInt count = iProfileCache.Count();
       
   291         for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   292             {
       
   293             iPluginDirector->State(status, iProfileCache[i]->UsedProfile());
       
   294             if (status == CSIPConcreteProfile::EUnregistered)
       
   295                 count--;
       
   296             }
       
   297         if (!count)
       
   298             {
       
   299             iSystemStateMonitor->EventProcessingCompleted(CSipSystemStateMonitor::ESystemState, 0, *this);
       
   300             }
       
   301         }
       
   302 		
       
   303     CheckServerStatus();
       
   304     }
       
   305 
       
   306 // -----------------------------------------------------------------------------
       
   307 // CSIPProfileServerCore::SIPProfileErrorEvent
       
   308 // -----------------------------------------------------------------------------
       
   309 //
       
   310 void CSIPProfileServerCore::SIPProfileErrorEvent(CSIPConcreteProfile& aProfile,
       
   311     											 TInt aError)
       
   312     {
       
   313     PROFILE_DEBUG4("ProfileServerCore::SIPProfileErrorEvent id,err", 
       
   314                    aProfile.Id(), aError)
       
   315 
       
   316     CSIPProfileCacheItem* item = ProfileCacheItem(aProfile.Id());
       
   317     if (item)
       
   318     	{
       
   319     	CSIPConcreteProfile::TStatus status = ValidateErrorStatus(*item);
       
   320         HandleAsyncError(*item, status, aError);
       
   321         iPluginDirector->StartTimerForCleanup();
       
   322     	}
       
   323 
       
   324     CheckServerStatus();
       
   325     }
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 // CSIPProfileServerCore::ProceedRegistration
       
   329 // -----------------------------------------------------------------------------
       
   330 //
       
   331 TBool CSIPProfileServerCore::ProceedRegistration
       
   332 		(CSIPConcreteProfile& aProfile, TInt aError)
       
   333     {
       
   334     PROFILE_DEBUG4("ProfileServerCore::ProceedRegistration id, err", aProfile.Id(), aError)
       
   335     CSIPProfileCacheItem* item = ProfileCacheItem(aProfile.Id());
       
   336     if (!item)
       
   337     	{
       
   338     	return EFalse;
       
   339     	}
       
   340 
       
   341     if ( ShouldChangeIap(item->UsedProfile(), aError) && 
       
   342     	 !item->SnapRetryCountReached() )
       
   343         {
       
   344         PROFILE_DEBUG1("CSIPProfileServerCore::ProceedRegistration, IAP should be changed")
       
   345         // If IAP should be changed, handle this like an error, so the profile
       
   346         // can ask for a new IAP.
       
   347         SIPProfileErrorEvent(item->UsedProfile(), aError);
       
   348         
       
   349         // Return false so that the profile agent does not retry registration
       
   350         // with old IAP.
       
   351         return EFalse;
       
   352         }
       
   353 	PROFILE_DEBUG1("CSIPProfileServerCore::ProceedRegistration, IAP should NOT be changed")        
       
   354         
       
   355     if (!item->IsActiveState())
       
   356         {
       
   357         PROFILE_DEBUG1("ProceedRegistration, profile removed")
       
   358         return EFalse;
       
   359         }
       
   360     if (item->ReferenceCount() == 0)
       
   361     	{
       
   362     	if (!item->LatestProfile().IsAutoRegistrationEnabled())
       
   363             {
       
   364             PROFILE_DEBUG1("ProceedRegistration, profile not used")
       
   365             return EFalse;
       
   366             }
       
   367     	if (item->HasProfileUpdate())
       
   368             {
       
   369             PROFILE_DEBUG1("ProceedRegistration, profile updated, not used")
       
   370             return EFalse;
       
   371             }
       
   372     	}
       
   373 
       
   374     PROFILE_DEBUG1("ProceedRegistration, profile untouched")
       
   375     return ETrue;    
       
   376     }    
       
   377 
       
   378 // -----------------------------------------------------------------------------
       
   379 // CSIPProfileServerCore::GetFailedProfilesL
       
   380 // -----------------------------------------------------------------------------
       
   381 //
       
   382 void CSIPProfileServerCore::GetFailedProfilesL(const TSIPProfileTypeInfo& aType,
       
   383     RPointerArray<CSIPConcreteProfile>& aFailedProfiles) const
       
   384     {
       
   385     for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   386         {
       
   387         const CSIPConcreteProfile& profile = iProfileCache[i]->Profile();
       
   388 
       
   389         if (profile.ProfileType().iSIPProfileClass == aType.iSIPProfileClass &&
       
   390         	profile.ProfileType().iSIPProfileName  == aType.iSIPProfileName &&
       
   391             (profile.IsEnabled() || profile.IsAutoRegistrationEnabled()) &&
       
   392              profile.Status() == CSIPConcreteProfile::EUnregistered &&
       
   393              profile.LastRegistrationError() != KErrNone)
       
   394         	{
       
   395         	aFailedProfiles.AppendL(&profile);
       
   396         	}
       
   397         }
       
   398     }
       
   399 
       
   400 // -----------------------------------------------------------------------------
       
   401 // CSIPProfileServerCore::HandleProfileError
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 TBool CSIPProfileServerCore::HandleProfileError(CSIPProfileCacheItem& aItem,
       
   405 											    TInt aOwnError)
       
   406 	{
       
   407     iPluginDirector->TerminateHandling(aItem.UsedProfile());
       
   408     return aItem.HandleError(aOwnError);
       
   409 	}
       
   410 
       
   411 // -----------------------------------------------------------------------------
       
   412 // CSIPProfileServerCore::SystemVariableUpdated
       
   413 // If a system shutdown event is received, initiate de-registering each profile
       
   414 // -----------------------------------------------------------------------------
       
   415 //
       
   416 void CSIPProfileServerCore::SystemVariableUpdated( 
       
   417     CSipSystemStateMonitor::TSystemVariable aVariable,
       
   418     TInt /*aObjectId*/,
       
   419     TInt aValue )
       
   420     {
       
   421     PROFILE_DEBUG3("CSIPProfileServerCore::SystemVariableUpdated System State changed to value", aValue)
       
   422     
       
   423     //If the SystemState is Offline, turn the boolean variable to true so that Profile-Server
       
   424     //can indicate System State monitor that event processing is completed, provided all the 
       
   425     //profiles have got deregistered
       
   426     if (CSipSystemStateMonitor::ESystemOffline == aValue)
       
   427         iOfflineEventReceived = ETrue;
       
   428     
       
   429 	if ( aVariable == CSipSystemStateMonitor::ESystemState &&
       
   430 	     (aValue == CSipSystemStateMonitor::ESystemShuttingDown || 
       
   431 	     aValue == CSipSystemStateMonitor::ESystemOffline
       
   432 			 ))
       
   433 	    {    
       
   434         for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   435             {
       
   436             iProfileCache[i]->ShutdownInitiated();
       
   437             }	    
       
   438 	    }
       
   439 	//If the System State is Online, register all the profiles in always on mode
       
   440 	else if(aVariable == CSipSystemStateMonitor::ESystemState && 
       
   441 		aValue == CSipSystemStateMonitor::ESystemOnline)
       
   442 		{
       
   443 		iOfflineEventReceived = EFalse;
       
   444 		for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   445 		    {
       
   446 		    iProfileCache[i]->ResetShutdownvariable();
       
   447 		    CSIPProfileCacheItem* item = iProfileCache[i];
       
   448 		    if (item->Profile().IsAutoRegistrationEnabled())
       
   449 		        {
       
   450                 TRAPD(err, item->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue));
       
   451 		        if (err != KErrNone)
       
   452 		            {
       
   453 		            HandleAsyncError(*item,CSIPConcreteProfile::ERegistrationInProgress,err);
       
   454 		            }
       
   455 				}
       
   456 			}
       
   457 		}
       
   458 	else if(aVariable == CSipSystemStateMonitor::ERfsState)
       
   459 	    {
       
   460 	    if(aValue == CSipSystemStateMonitor::ERfsStarted)
       
   461 	        {
       
   462 	        PROFILE_DEBUG1("RFS Started, de-registering the profiles")
       
   463 	        for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   464 	            {
       
   465 	            iProfileCache[i]->RfsInprogress(ETrue);
       
   466 	            }
       
   467 	        }
       
   468 	    else if(aValue == CSipSystemStateMonitor::ERfsFailed)
       
   469 	        {
       
   470 	        PROFILE_DEBUG1("RFS Failed, re-registering the profiles")
       
   471 	        for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   472 	            {
       
   473 	            iProfileCache[i]->RfsInprogress(EFalse);
       
   474 	            if (iProfileCache[i]->IsReferred())
       
   475 	                {
       
   476 	                TRAPD(err, iProfileCache[i]->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue));
       
   477 	                if (err != KErrNone)
       
   478 	                    {
       
   479 	                    HandleAsyncError(*iProfileCache[i],
       
   480 	                            CSIPConcreteProfile::ERegistrationInProgress,
       
   481 	                            err);	                            
       
   482 	                    }
       
   483 	                }
       
   484 	            }
       
   485 	        }
       
   486 	    else if(aValue == CSipSystemStateMonitor::ERfsCompleted)
       
   487 	        {
       
   488 	        PROFILE_DEBUG1("RFS Completed")
       
   489 	        for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   490 	            {
       
   491 	            iProfileCache[i]->RfsInprogress(EFalse);
       
   492 	            }
       
   493 	        }
       
   494 	    }
       
   495     }
       
   496 
       
   497 // -----------------------------------------------------------------------------
       
   498 // CSIPProfileServerCore::SessionRegisterL
       
   499 // -----------------------------------------------------------------------------
       
   500 //
       
   501 void CSIPProfileServerCore::SessionRegisterL(
       
   502 	const MSIPExtendedConcreteProfileObserver& aObserver)
       
   503     {
       
   504     iObservers.AppendL(&aObserver);
       
   505     }
       
   506 
       
   507 // -----------------------------------------------------------------------------
       
   508 // CSIPProfileServerCore::SessionCleanup
       
   509 // -----------------------------------------------------------------------------
       
   510 //
       
   511 void CSIPProfileServerCore::SessionCleanup(	
       
   512 	const MSIPExtendedConcreteProfileObserver& aObserver)
       
   513     {
       
   514     TRAP_IGNORE(SessionCleanupL(aObserver))
       
   515     }
       
   516 
       
   517 // -----------------------------------------------------------------------------
       
   518 // CSIPProfileServerCore::ProfilePluginsL
       
   519 // -----------------------------------------------------------------------------
       
   520 //
       
   521 const CSIPProfilePlugins& CSIPProfileServerCore::ProfilePluginsL()
       
   522     {
       
   523     delete iProfilePlugins;
       
   524     iProfilePlugins = NULL;
       
   525     iProfilePlugins = CSIPProfilePlugins::NewL();
       
   526     RArray<TSIPProfileTypeInfo> array;
       
   527     CleanupClosePushL(array);
       
   528 
       
   529     RImplInfoPtrArray infoArray;
       
   530     CleanupStack::PushL(TCleanupItem(ResetAndDestroyInfo, &infoArray));
       
   531 
       
   532     TRAPD(err, iPluginDirector->ListImplementationsL(infoArray));
       
   533     if (err == KErrNone) 
       
   534         {
       
   535         for (TInt i = 0; i < infoArray.Count(); i ++)
       
   536             {
       
   537             CImplementationInformation* ecomInfo = infoArray[i];
       
   538             TSIPProfileTypeInfo info;
       
   539             ConvertTypeInfoL(*ecomInfo, info);
       
   540             array.AppendL(info);
       
   541             }
       
   542         }
       
   543     CleanupStack::Pop(&infoArray);
       
   544     infoArray.ResetAndDestroy();
       
   545     infoArray.Close();
       
   546 
       
   547     iProfilePlugins->SetPluginsL(array);
       
   548     CleanupStack::Pop(&array);
       
   549     array.Close();
       
   550     return *iProfilePlugins;
       
   551     }
       
   552 
       
   553 // -----------------------------------------------------------------------------
       
   554 // CSIPProfileServerCore::AddProfileL
       
   555 // -----------------------------------------------------------------------------
       
   556 //
       
   557 void CSIPProfileServerCore::AddProfileL(CSIPConcreteProfile* aProfile,
       
   558     const MSIPExtendedConcreteProfileObserver& aObserver)
       
   559     {
       
   560     __ASSERT_ALWAYS(iProfileStorage != NULL, User::Leave(KErrLocked));
       
   561 
       
   562     CSIPProfileCacheCleanupItem* cleanup =
       
   563     	new (ELeave) CSIPProfileCacheCleanupItem;
       
   564 	CleanupStack::PushL(cleanup);
       
   565     CleanupStack::PushL(TCleanupItem(CrashRevert, cleanup));
       
   566 
       
   567     CSIPProfileCacheItem* item = CSIPProfileCacheItem::NewL(*this,
       
   568     														iUnregistered);
       
   569     cleanup->iCacheItem = item;
       
   570 
       
   571     item->AddObserverL(aObserver);
       
   572     iProfileCache.AppendL(item);
       
   573     cleanup->iCache = &iProfileCache;
       
   574 
       
   575 	// AddSIPProfileL sets stream id to aProfile's profile id
       
   576     iProfileStorage->AddSIPProfileL(*aProfile);
       
   577 
       
   578     CleanupStack::Pop(); // TCleanupItem
       
   579     CleanupStack::PopAndDestroy(cleanup);
       
   580 	
       
   581 	CSIPConcreteProfile* defaultProfile = FindDefaultProfile();
       
   582 
       
   583 	if ( !defaultProfile )
       
   584 		{
       
   585 		aProfile->SetDefault( ETrue );
       
   586 		}
       
   587 
       
   588 	if ( defaultProfile && aProfile->IsDefault() && defaultProfile != aProfile )
       
   589 		{
       
   590 		defaultProfile->SetDefault( EFalse );
       
   591 		}
       
   592 
       
   593     item->SetProfile(aProfile);
       
   594 
       
   595     SendProfileAddedEvent(*aProfile);
       
   596     }
       
   597 
       
   598 // -----------------------------------------------------------------------------
       
   599 // CSIPProfileServerCore::RemoveProfileL
       
   600 // -----------------------------------------------------------------------------
       
   601 //
       
   602 void CSIPProfileServerCore::RemoveProfileL(TUint32 aProfileId)
       
   603 
       
   604     {
       
   605     __ASSERT_ALWAYS(iProfileStorage != NULL, User::Leave(KErrLocked));
       
   606 
       
   607     CSIPProfileCacheItem* item = ProfileCacheItemL(aProfileId);
       
   608     __ASSERT_ALWAYS(item->ReferenceCount() == 0, User::Leave(KErrInUse));
       
   609 
       
   610     iProfileStorage->DeleteSIPProfileL(item->Profile().StorageId());
       
   611 
       
   612 	CSIPConcreteProfile* defaultProfile = FindDefaultProfile();
       
   613 	
       
   614 	if ( defaultProfile && defaultProfile->Id() == aProfileId )
       
   615         {
       
   616         TUint32 storageId = iProfileStorage->DefaultProfile();
       
   617 
       
   618         if ( storageId )
       
   619             {
       
   620             CSIPConcreteProfile* newDefault = &( ProfileCacheItemByStorageIdL( storageId ).Profile() );
       
   621             newDefault->SetDefault( ETrue );
       
   622             }
       
   623         }
       
   624 
       
   625     SendProfileRemovedEventL(*item);
       
   626 
       
   627     item->RemoveL();
       
   628 
       
   629     if (item->CanBePermanentlyRemoved())
       
   630         {
       
   631         RemoveProfileItem(aProfileId);
       
   632         delete item;
       
   633         }
       
   634     }
       
   635 
       
   636 // -----------------------------------------------------------------------------
       
   637 // CSIPProfileServerCore::UpdateProfileToStoreL
       
   638 // aProfile has the correct profile id.
       
   639 // -----------------------------------------------------------------------------
       
   640 //
       
   641 TBool CSIPProfileServerCore::UpdateProfileToStoreL(
       
   642     CSIPConcreteProfile *aProfile,
       
   643     const MSIPExtendedConcreteProfileObserver& aObserver)
       
   644     {
       
   645     __ASSERT_ALWAYS(iProfileStorage != NULL, User::Leave(KErrLocked));
       
   646 
       
   647     CSIPProfileCacheItem* item = ProfileCacheItemL(aProfile->Id());    
       
   648 
       
   649 	if (aProfile->ServerParameter(
       
   650 			KSIPOutboundProxy, KSIPDigestPassword) == KNullDesC8)
       
   651 		{
       
   652 		const TDesC8& oldPassword( 
       
   653 				item->Profile().ServerParameter(
       
   654 						KSIPOutboundProxy, KSIPDigestPassword) );
       
   655 
       
   656 		aProfile->SetServerParameterL( 
       
   657 			KSIPOutboundProxy, KSIPDigestPassword, oldPassword);	
       
   658 		}
       
   659 
       
   660 	if (aProfile->ServerParameter(
       
   661 			KSIPRegistrar, KSIPDigestPassword) == KNullDesC8)
       
   662 		{
       
   663 		const TDesC8& oldPassword( 
       
   664 				item->Profile().ServerParameter(
       
   665 						KSIPRegistrar, KSIPDigestPassword) );
       
   666 
       
   667 		aProfile->SetServerParameterL( 
       
   668 			KSIPRegistrar, KSIPDigestPassword, oldPassword);	
       
   669 		}
       
   670 
       
   671 	aProfile->SetStorageId(item->Profile().StorageId());
       
   672     iProfileStorage->UpdateSIPProfileL(*aProfile);
       
   673 
       
   674 	if ( aProfile->IsDefault() )
       
   675         {
       
   676         CSIPConcreteProfile* defaultProfile = FindDefaultProfile();
       
   677         
       
   678         if ( defaultProfile && defaultProfile != aProfile )
       
   679         	{
       
   680         	defaultProfile->SetDefault( EFalse );
       
   681         	}
       
   682         }
       
   683 	
       
   684     SendProfileUpdatedEventL(*item, *aProfile);
       
   685     
       
   686     return item->CacheOldProfile(aProfile, aObserver);
       
   687     }
       
   688 
       
   689 // -----------------------------------------------------------------------------
       
   690 // CSIPProfileServerCore::Profile
       
   691 // -----------------------------------------------------------------------------
       
   692 //
       
   693 const CSIPConcreteProfile*
       
   694 CSIPProfileServerCore::Profile(TUint32 aProfileId) const
       
   695     {
       
   696     CSIPProfileCacheItem* item = ProfileCacheItem(aProfileId);
       
   697     if (item)
       
   698         {
       
   699         return &item->Profile();
       
   700         }
       
   701     return NULL;
       
   702     }
       
   703 
       
   704 // -----------------------------------------------------------------------------
       
   705 // CSIPProfileServerCore::ProfileDefaultL
       
   706 // -----------------------------------------------------------------------------
       
   707 //
       
   708 const CSIPConcreteProfile* CSIPProfileServerCore::ProfileDefaultL()
       
   709     {
       
   710     __ASSERT_ALWAYS(iProfileStorage != NULL, User::Leave(KErrLocked));
       
   711 
       
   712 	CSIPProfileCacheItem* item =
       
   713 		ProfileCacheItemByStorageId(iProfileStorage->DefaultProfile());
       
   714 	if (item)
       
   715         {
       
   716         return &item->Profile();
       
   717         }
       
   718     return NULL;
       
   719     }
       
   720 
       
   721 // -----------------------------------------------------------------------------
       
   722 // CSIPProfileServerCore::ProfileL
       
   723 // -----------------------------------------------------------------------------
       
   724 //
       
   725 CSIPConcreteProfile& CSIPProfileServerCore::ProfileL(TUint32 aProfileId,
       
   726     const MSIPExtendedConcreteProfileObserver& aObserver) const
       
   727     {
       
   728     CSIPProfileCacheItem* item = ProfileCacheItem(aProfileId);
       
   729 	__ASSERT_ALWAYS(item != NULL && item->IsActiveState(),
       
   730 					User::Leave(KErrNotFound));
       
   731     __ASSERT_ALWAYS(!item->IsObserverOrUser(aObserver), User::Leave(KErrInUse));
       
   732 
       
   733     item->AddObserverL(aObserver);
       
   734 	return item->LatestProfile();
       
   735     }
       
   736 
       
   737 // -----------------------------------------------------------------------------
       
   738 // CSIPProfileServerCore::ProfileRefreshL
       
   739 // -----------------------------------------------------------------------------
       
   740 //
       
   741 CSIPConcreteProfile& CSIPProfileServerCore::ProfileRefreshL(TUint32 aProfileId,
       
   742     const MSIPExtendedConcreteProfileObserver& aObserver) const
       
   743     {
       
   744     CSIPProfileCacheItem* item = ProfileCacheItem(aProfileId);
       
   745 	__ASSERT_ALWAYS(item != NULL && item->IsActiveState(),
       
   746 					User::Leave(KErrNotFound));
       
   747     __ASSERT_ALWAYS(item->IsObserverOrUser(aObserver),
       
   748     				User::Leave(KErrArgument));
       
   749 	return item->LatestProfile();
       
   750     }
       
   751 
       
   752 // -----------------------------------------------------------------------------
       
   753 // CSIPProfileServerCore::CreateProfileL
       
   754 // -----------------------------------------------------------------------------
       
   755 //
       
   756 CSIPConcreteProfile*
       
   757 CSIPProfileServerCore::CreateProfileL(const TSIPProfileTypeInfo& aType)
       
   758     {
       
   759     PROFILE_DEBUG1("CreateProfileL")
       
   760 
       
   761     return iPluginDirector->CreateProfileL(aType);
       
   762     }
       
   763 
       
   764 // -----------------------------------------------------------------------------
       
   765 // CSIPProfileServerCore::ProfilesByAORL
       
   766 // -----------------------------------------------------------------------------
       
   767 //
       
   768 void CSIPProfileServerCore::ProfilesByAORL(const TDesC8& aAOR,
       
   769 	const MSIPExtendedConcreteProfileObserver* aObserver,
       
   770 	RPointerArray<CSIPConcreteProfile>& aArray) const
       
   771     {
       
   772     for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   773         {
       
   774         if (iProfileCache[i]->HasAorL(aAOR) &&
       
   775         	iProfileCache[i]->IsActiveState())
       
   776             {
       
   777             HandleMatchingProfileL(aObserver, aArray, *iProfileCache[i]);
       
   778             }
       
   779         }
       
   780     }
       
   781 
       
   782 // -----------------------------------------------------------------------------
       
   783 // CSIPProfileServerCore::DeleteProfileL
       
   784 // -----------------------------------------------------------------------------
       
   785 //
       
   786 void CSIPProfileServerCore::DeleteProfileL(
       
   787     TUint32 aProfileId,
       
   788     const MSIPExtendedConcreteProfileObserver& aObserver)
       
   789     {
       
   790     CSIPProfileCacheItem* item = ProfileCacheItem(aProfileId);
       
   791 	if (item)
       
   792 		{
       
   793 		if (item->IsUser(aObserver))
       
   794             {
       
   795             DisableProfileL(aProfileId, aObserver);
       
   796             }
       
   797         item->RemoveObserver(aObserver);
       
   798 		}
       
   799     }
       
   800 
       
   801 // -----------------------------------------------------------------------------
       
   802 // CSIPProfileServerCore::CanServerStop
       
   803 // -----------------------------------------------------------------------------
       
   804 //
       
   805 TBool CSIPProfileServerCore::CanServerStop() const
       
   806     {
       
   807     if (iBackupInProgress || iObservers.Count() > 0)
       
   808         {
       
   809         return EFalse;
       
   810         }
       
   811 
       
   812     for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   813         {
       
   814         const CSIPConcreteProfile& profile = iProfileCache[i]->Profile();
       
   815         if ((profile.IsAutoRegistrationEnabled() &&
       
   816              profile.LastRegistrationError() == KErrNone)
       
   817              ||
       
   818              profile.Status() != CSIPConcreteProfile::EUnregistered)
       
   819             {
       
   820             return EFalse;
       
   821             }
       
   822         }
       
   823     return ETrue;
       
   824     }
       
   825 
       
   826 // -----------------------------------------------------------------------------
       
   827 // CSIPProfileServerCore::BackupInProgress
       
   828 // -----------------------------------------------------------------------------
       
   829 //
       
   830 TBool CSIPProfileServerCore::BackupInProgress() const
       
   831     {
       
   832     return iBackupInProgress;
       
   833     }
       
   834 
       
   835 // -----------------------------------------------------------------------------
       
   836 // CSIPProfileServerCore::ProfilesL
       
   837 // -----------------------------------------------------------------------------
       
   838 //
       
   839 void CSIPProfileServerCore::ProfilesL(
       
   840 	const MSIPExtendedConcreteProfileObserver* aObserver,
       
   841 	RPointerArray<CSIPConcreteProfile>& aArray) const
       
   842     {
       
   843     for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   844         {
       
   845 		HandleMatchingProfileL(aObserver, aArray, *iProfileCache[i]);
       
   846         }
       
   847     }
       
   848 
       
   849 // -----------------------------------------------------------------------------
       
   850 // CSIPProfileServerCore::ProfilesByTypeL
       
   851 // -----------------------------------------------------------------------------
       
   852 //
       
   853 void CSIPProfileServerCore::ProfilesByTypeL(
       
   854 	const TSIPProfileTypeInfo& aType,                                   
       
   855 	const MSIPExtendedConcreteProfileObserver* aObserver,
       
   856 	RPointerArray<CSIPConcreteProfile>& aArray) const
       
   857     {
       
   858     for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   859         {
       
   860 		const TSIPProfileTypeInfo& type =
       
   861         	iProfileCache[i]->LatestProfile().ProfileType();
       
   862 
       
   863         if (aType.iSIPProfileName.Compare(type.iSIPProfileName) == 0 &&
       
   864             aType.iSIPProfileClass == type.iSIPProfileClass &&
       
   865             iProfileCache[i]->IsActiveState())
       
   866             {
       
   867 			HandleMatchingProfileL(aObserver, aArray, *iProfileCache[i]);
       
   868             }
       
   869         }
       
   870     }
       
   871 
       
   872 // -----------------------------------------------------------------------------
       
   873 // CSIPProfileServerCore::HandleMatchingProfileL
       
   874 // -----------------------------------------------------------------------------
       
   875 //
       
   876 void CSIPProfileServerCore::HandleMatchingProfileL(
       
   877 	const MSIPExtendedConcreteProfileObserver* aObserver,
       
   878 	RPointerArray<CSIPConcreteProfile>& aArray,
       
   879 	CSIPProfileCacheItem& aItem) const
       
   880 	{
       
   881     // Append only if the profile state is Active i.e if it not 
       
   882     // requested for the removal
       
   883     if (aItem.IsActiveState())
       
   884     	{
       
   885     	aArray.AppendL(&(aItem.LatestProfile()));        	
       
   886     	}    
       
   887 
       
   888     if (aObserver && !aItem.IsObserverOrUser(*aObserver))
       
   889         {
       
   890         aItem.AddObserverL(*aObserver);
       
   891         }
       
   892 	}
       
   893 
       
   894 // -----------------------------------------------------------------------------
       
   895 // CSIPProfileServerCore::UpdateRegistrationL
       
   896 // Second phase of profile update.
       
   897 // -----------------------------------------------------------------------------
       
   898 //
       
   899 void CSIPProfileServerCore::UpdateRegistrationL(TUint32 aProfileId,
       
   900     const MSIPExtendedConcreteProfileObserver& aObserver)
       
   901     {
       
   902     CSIPProfileCacheItem* item = ProfileCacheItemL(aProfileId);
       
   903     CSIPConcreteProfile::TStatus
       
   904     	status(CSIPConcreteProfile::ERegistrationInProgress);
       
   905     if (item->Profile().Status() == CSIPConcreteProfile::ERegistered)
       
   906         {
       
   907         status = CSIPConcreteProfile::EUnregistrationInProgress;
       
   908         }
       
   909 
       
   910     TRAPD(err, item->UpdateRegistrationL(aObserver));
       
   911     if (err != KErrNone)
       
   912         {
       
   913         HandleAsyncError(*item, status, err);
       
   914         }
       
   915     }
       
   916 
       
   917 // -----------------------------------------------------------------------------
       
   918 // CSIPProfileServerCore::EnableProfileL
       
   919 // -----------------------------------------------------------------------------
       
   920 //
       
   921 CSIPConcreteProfile::TStatus CSIPProfileServerCore::EnableProfileL(
       
   922     TUint32 aProfileId,
       
   923     const MSIPExtendedConcreteProfileObserver& aObserver)
       
   924     {
       
   925 	CSIPProfileCacheItem* item = ProfileCacheItemL(aProfileId);
       
   926     iAlrHandler->EnableProfileL(*item, aObserver);
       
   927     return item->Profile().Status();
       
   928     }
       
   929 
       
   930 // -----------------------------------------------------------------------------
       
   931 // CSIPProfileServerCore::DisableProfileL
       
   932 // -----------------------------------------------------------------------------
       
   933 //
       
   934 CSIPConcreteProfile::TStatus CSIPProfileServerCore::DisableProfileL(
       
   935     TUint32 aProfileId,
       
   936     const MSIPExtendedConcreteProfileObserver& aObserver)
       
   937     {
       
   938     CSIPProfileCacheItem* item = ProfileCacheItemL(aProfileId);
       
   939     iAlrHandler->DisableProfileL(*item, aObserver);
       
   940     return item->Profile().Status();
       
   941     }
       
   942 
       
   943 // -----------------------------------------------------------------------------
       
   944 // CSIPProfileServerCore::ForceDisableProfileL
       
   945 // -----------------------------------------------------------------------------
       
   946 //
       
   947 CSIPConcreteProfile::TStatus CSIPProfileServerCore::ForceDisableProfileL(
       
   948     TUint32 aProfileId,
       
   949     const MSIPExtendedConcreteProfileObserver& aObserver)
       
   950     {
       
   951     CSIPProfileCacheItem* item = ProfileCacheItemL(aProfileId);
       
   952     (void)aObserver;
       
   953     //When profile state is not unregistered, 
       
   954     //perform cleanup and send event notification
       
   955     
       
   956     if(CSIPConcreteProfile::EUnregistered != item->UsedProfile().Status())
       
   957     	{
       
   958     	PROFILE_DEBUG3("CSIPProfileServerCore::ForceDisableProfileL, Forcibly disabling profile", aProfileId);
       
   959     	item->SwitchToUnregisteredState();
       
   960     	iPluginDirector->TerminateHandling(item->UsedProfile());
       
   961     	item->ClearMigrationProfiles();
       
   962     	iPluginDirector->StartTimerForCleanup();
       
   963     	item->ClearOldProfile();
       
   964     	SendProfileForciblyDisabledEvent(*item);
       
   965     	}
       
   966     return item->Profile().Status();
       
   967     }
       
   968 
       
   969 // -----------------------------------------------------------------------------
       
   970 // CSIPProfileServerCore::ProfileUsageL
       
   971 // -----------------------------------------------------------------------------
       
   972 //
       
   973 TInt CSIPProfileServerCore::ProfileUsageL(TUint32 aProfileId) const
       
   974     {
       
   975     return ProfileCacheItemL(aProfileId)->ReferenceCount();
       
   976     }
       
   977 
       
   978 // -----------------------------------------------------------------------------
       
   979 // CSIPProfileServerCore::RegisterProfiles
       
   980 // If always-on profile has SNAP, it must obtain an IAP before it can register.
       
   981 // -----------------------------------------------------------------------------
       
   982 //
       
   983 void CSIPProfileServerCore::RegisterProfiles()
       
   984     {
       
   985     for (TInt i = 0; i < iProfileCache.Count(); i++)
       
   986         {
       
   987         CSIPProfileCacheItem* item = iProfileCache[i];
       
   988         if (item->Profile().IsAutoRegistrationEnabled())
       
   989             {
       
   990 			TRAPD(err, item->StartRegisterL(*iWaitForIAP, *iRegInProg, ETrue));
       
   991             if (err != KErrNone)
       
   992                 {
       
   993                 HandleAsyncError(*item,
       
   994                     			 CSIPConcreteProfile::ERegistrationInProgress,
       
   995                     			 err);
       
   996                 }
       
   997             }
       
   998         }
       
   999     }
       
  1000 
       
  1001 // -----------------------------------------------------------------------------
       
  1002 // CSIPProfileServerCore::LoadProfilesL
       
  1003 // -----------------------------------------------------------------------------
       
  1004 //
       
  1005 void CSIPProfileServerCore::LoadProfilesL(TBool aNotifyProfileCreation)
       
  1006     {
       
  1007     // Read profiles from cenrep
       
  1008     TRAPD(err, iProfileStorage = CSIPProfileStorage::NewL(iFs));
       
  1009     HandleProfileStorageErrorL(err);
       
  1010 
       
  1011     RPointerArray<CSIPConcreteProfile>* profiles(NULL);
       
  1012     TRAP(err, profiles = iProfileStorage->SIPProfilesL());
       
  1013     HandleProfileStorageErrorL(err);
       
  1014     if (err != KErrNone)
       
  1015         {
       
  1016         profiles = iProfileStorage->SIPProfilesL();
       
  1017         }
       
  1018 
       
  1019     CleanupStack::PushL(TCleanupItem(ResetAndDestroy, profiles));
       
  1020     AddProfilesInCacheL(*profiles, aNotifyProfileCreation);    
       
  1021     
       
  1022     CleanupStack::Pop(); // TCleanupItem
       
  1023     profiles->ResetAndDestroy();
       
  1024     delete profiles;
       
  1025     
       
  1026     // Read profiles from profiles.dat file
       
  1027     TRAP(err, profiles = iProfileStorage->SIPProfilesL(ETrue));
       
  1028     HandleProfileStorageErrorL(err, ETrue);
       
  1029     
       
  1030     if (err != KErrNone)
       
  1031         {
       
  1032         profiles = iProfileStorage->SIPProfilesL(ETrue);
       
  1033         }    
       
  1034 
       
  1035     CleanupStack::PushL(TCleanupItem(ResetAndDestroy, profiles));
       
  1036     AddProfilesInCacheL(*profiles, aNotifyProfileCreation);
       
  1037     
       
  1038     
       
  1039     CleanupStack::Pop(); // TCleanupItem
       
  1040     profiles->ResetAndDestroy();
       
  1041     delete profiles;
       
  1042     
       
  1043 
       
  1044     RegisterProfiles();    
       
  1045     iProfileStorage->GetProfileStorageIndexObject()->SetProfileServerCoreObject(this);
       
  1046     }
       
  1047     
       
  1048 // -----------------------------------------------------------------------------
       
  1049 // CSIPProfileServerCore::AddProfilesInCacheL
       
  1050 // -----------------------------------------------------------------------------
       
  1051 //
       
  1052 void CSIPProfileServerCore::AddProfilesInCacheL(RPointerArray<CSIPConcreteProfile>& profiles,TBool aNotifyProfileCreation)
       
  1053 	{
       
  1054 	TInt count = profiles.Count();
       
  1055     for (TInt i = 0; i < count; i++) 
       
  1056         {
       
  1057         CSIPConcreteProfile* profile =
       
  1058         	static_cast<CSIPConcreteProfile*>(profiles[0]);
       
  1059         CSIPProfileCacheItem* item =
       
  1060         	CSIPProfileCacheItem::NewLC(*this, iUnregistered);
       
  1061         profiles.Remove(0);
       
  1062         item->SetProfile(profile);
       
  1063         iProfileCache.AppendL(item);
       
  1064         CleanupStack::Pop(item);
       
  1065         if (aNotifyProfileCreation)
       
  1066             {
       
  1067             SendProfileAddedEvent(*profile);
       
  1068             }
       
  1069         }
       
  1070 	}
       
  1071 
       
  1072 // -----------------------------------------------------------------------------
       
  1073 // CSIPProfileServerCore::TerminateProfilesL
       
  1074 // -----------------------------------------------------------------------------
       
  1075 //
       
  1076 void CSIPProfileServerCore::TerminateProfilesL()
       
  1077     {
       
  1078     TInt count = iProfileCache.Count();
       
  1079     for (TInt i = 0; i < count; ++i)
       
  1080         {
       
  1081         iPluginDirector->TerminateHandling(iProfileCache[i]->UsedProfile());
       
  1082         SendProfileRemovedEventL(*iProfileCache[i]);
       
  1083         }
       
  1084     iProfileCache.ResetAndDestroy();
       
  1085     }
       
  1086 
       
  1087 // -----------------------------------------------------------------------------
       
  1088 // CSIPProfileServerCore::ProfileCacheItemL
       
  1089 // -----------------------------------------------------------------------------
       
  1090 //
       
  1091 CSIPProfileCacheItem*
       
  1092 CSIPProfileServerCore::ProfileCacheItemL(TUint32 aProfileId) const
       
  1093     {
       
  1094     CSIPProfileCacheItem* item = ProfileCacheItem(aProfileId);
       
  1095     __ASSERT_ALWAYS(item != NULL, User::Leave(KErrNotFound));
       
  1096     return item;
       
  1097     }
       
  1098 
       
  1099 // -----------------------------------------------------------------------------
       
  1100 // CSIPProfileServerCore::ProfileCacheItem
       
  1101 // -----------------------------------------------------------------------------
       
  1102 //
       
  1103 CSIPProfileCacheItem*
       
  1104 CSIPProfileServerCore::ProfileCacheItem(TUint32 aProfileId) const
       
  1105     {
       
  1106     return FindProfileCacheItem(ProfileCached(aProfileId));
       
  1107     }
       
  1108 
       
  1109 // -----------------------------------------------------------------------------
       
  1110 // CSIPProfileServerCore::ProfileCached
       
  1111 // -----------------------------------------------------------------------------
       
  1112 //
       
  1113 TInt CSIPProfileServerCore::ProfileCached(TUint32 aProfileId) const
       
  1114     {
       
  1115     TIdentityRelation<CSIPProfileCacheItem>
       
  1116     	compareId(CSIPProfileCacheItem::Compare);
       
  1117     iFindEntry->SetProfileId(aProfileId);
       
  1118     return iProfileCache.Find(iFindEntry, compareId);
       
  1119     }
       
  1120 
       
  1121 // -----------------------------------------------------------------------------
       
  1122 // CSIPProfileServerCore::FindProfileCacheItem
       
  1123 // -----------------------------------------------------------------------------
       
  1124 //
       
  1125 CSIPProfileCacheItem*
       
  1126 CSIPProfileServerCore::FindProfileCacheItem(TInt aIndex) const
       
  1127     {
       
  1128     if (aIndex != KErrNotFound)
       
  1129         {
       
  1130         return static_cast<CSIPProfileCacheItem*>(iProfileCache[aIndex]);
       
  1131         }
       
  1132     return NULL;
       
  1133     }
       
  1134 
       
  1135 // -----------------------------------------------------------------------------
       
  1136 // CSIPProfileServerCore::ProfileCacheItemByStorageIdL
       
  1137 // -----------------------------------------------------------------------------
       
  1138 //
       
  1139 CSIPProfileCacheItem&
       
  1140 CSIPProfileServerCore::ProfileCacheItemByStorageIdL(TUint32 aStorageId) const
       
  1141     {
       
  1142     CSIPProfileCacheItem* item = ProfileCacheItemByStorageId(aStorageId);
       
  1143     __ASSERT_ALWAYS(item != NULL, User::Leave(KErrNotFound));    
       
  1144     return *item;
       
  1145     }
       
  1146 
       
  1147 // -----------------------------------------------------------------------------
       
  1148 // CSIPProfileServerCore::ProfileCacheItemByStorageId
       
  1149 // -----------------------------------------------------------------------------
       
  1150 //
       
  1151 CSIPProfileCacheItem*
       
  1152 CSIPProfileServerCore::ProfileCacheItemByStorageId(TUint32 aStorageId) const
       
  1153     {
       
  1154     for (TInt i = 0; i < iProfileCache.Count(); ++i)
       
  1155         {
       
  1156         if (iProfileCache[i]->Profile().StorageId() == aStorageId)
       
  1157         	{
       
  1158         	return iProfileCache[i];
       
  1159         	}
       
  1160         }
       
  1161     return NULL;
       
  1162     }
       
  1163 
       
  1164 // -----------------------------------------------------------------------------
       
  1165 // CSIPProfileServerCore::SendRegistrationStatusEventL
       
  1166 // -----------------------------------------------------------------------------
       
  1167 //
       
  1168 void CSIPProfileServerCore::SendRegistrationStatusEventL(
       
  1169     CSIPProfileCacheItem& aItem) const
       
  1170     {        
       
  1171     SendStatusEventL(aItem, aItem.Profile().Status());
       
  1172     iPluginDirector->StartTimerForCleanup();
       
  1173     }
       
  1174 
       
  1175 // -----------------------------------------------------------------------------
       
  1176 // CSIPProfileServerCore::SendUnregisteredStatusEventL
       
  1177 // -----------------------------------------------------------------------------
       
  1178 //
       
  1179 void CSIPProfileServerCore::SendUnregisteredStatusEventL(
       
  1180     CSIPProfileCacheItem& aItem) const
       
  1181     {
       
  1182     SendStatusEventL(aItem, CSIPConcreteProfile::EUnregistered);
       
  1183     }
       
  1184 
       
  1185 // -----------------------------------------------------------------------------
       
  1186 // CSIPProfileServerCore::SendStatusEventL
       
  1187 // -----------------------------------------------------------------------------
       
  1188 //
       
  1189 void CSIPProfileServerCore::SendStatusEventL(CSIPProfileCacheItem& aItem, 
       
  1190 	CSIPConcreteProfile::TStatus aStatus) const
       
  1191     {
       
  1192     CSIPConcreteProfile &profile = aItem.Profile();
       
  1193     const RPointerArray<MSIPExtendedConcreteProfileObserver>& obs =
       
  1194     	aItem.Observers();
       
  1195 
       
  1196     for (TInt i = 0; i < obs.Count(); i++)
       
  1197         {
       
  1198 		if(aStatus == CSIPConcreteProfile::EUnregistered)	
       
  1199 	        obs[i]->RegistrationStatusChangedL(aItem.ProfileId(),
       
  1200         								   aStatus,
       
  1201                                      	   0);
       
  1202 		else
       
  1203 			obs[i]->RegistrationStatusChangedL(aItem.ProfileId(),
       
  1204         									   aStatus,
       
  1205                 	                    	   profile.ContextId());
       
  1206         }
       
  1207     }
       
  1208 
       
  1209 // -----------------------------------------------------------------------------
       
  1210 // CSIPProfileServerCore::SendErrorEvent
       
  1211 // -----------------------------------------------------------------------------
       
  1212 //
       
  1213 TInt CSIPProfileServerCore::SendErrorEvent(CSIPProfileCacheItem& item,
       
  1214                                            CSIPConcreteProfile::TStatus aStatus,
       
  1215                                            TInt aError) const
       
  1216     {
       
  1217     TInt err(KErrNone);
       
  1218     
       
  1219     const RPointerArray<MSIPExtendedConcreteProfileObserver>& obs =
       
  1220     	item.Observers();
       
  1221 
       
  1222     for (TInt i = 0; i < obs.Count() && !err; i++)
       
  1223         {
       
  1224         TRAP(err, obs[i]->ErrorOccurredL(item.ProfileId(), aStatus, aError));
       
  1225         }
       
  1226     return err;
       
  1227     }
       
  1228 
       
  1229 // -----------------------------------------------------------------------------
       
  1230 // CSIPProfileServerCore::SendProfileAddedEvent
       
  1231 // -----------------------------------------------------------------------------
       
  1232 //
       
  1233 void CSIPProfileServerCore::SendProfileAddedEvent(
       
  1234     const CSIPConcreteProfile& aProfile) const
       
  1235     {
       
  1236     for (TInt i = 0; i < iObservers.Count(); i++)
       
  1237         {
       
  1238         TRAP_IGNORE(iObservers[i]->AddedL(aProfile.Id()))
       
  1239         }
       
  1240     }
       
  1241 
       
  1242 // -----------------------------------------------------------------------------
       
  1243 // CSIPProfileServerCore::SendProfileUpdatedEventL
       
  1244 // -----------------------------------------------------------------------------
       
  1245 //
       
  1246 void CSIPProfileServerCore::SendProfileUpdatedEventL(
       
  1247     const CSIPProfileCacheItem& aItem,
       
  1248     const CSIPConcreteProfile& aProfile) const
       
  1249     {
       
  1250     const RPointerArray<MSIPExtendedConcreteProfileObserver>& obs =
       
  1251     	aItem.Observers();
       
  1252 
       
  1253     for (TInt i = 0; i < obs.Count(); i++)
       
  1254         {
       
  1255 		obs[i]->UpdatedL(aItem.ProfileId(), aProfile.ExternalizedSizeL());
       
  1256         }
       
  1257     }
       
  1258 
       
  1259 // -----------------------------------------------------------------------------
       
  1260 // CSIPProfileServerCore::SendProfileRemovedEventL
       
  1261 // -----------------------------------------------------------------------------
       
  1262 //
       
  1263 void CSIPProfileServerCore::SendProfileRemovedEventL(
       
  1264     CSIPProfileCacheItem& aItem) const
       
  1265     {
       
  1266     const RPointerArray<MSIPExtendedConcreteProfileObserver>& obs =
       
  1267     	aItem.Observers();
       
  1268 
       
  1269     for (TInt i = 0; i < obs.Count(); i++)
       
  1270         {
       
  1271         obs[i]->RemovedL(aItem.ProfileId());
       
  1272         }
       
  1273     }
       
  1274 
       
  1275 // -----------------------------------------------------------------------------
       
  1276 // CSIPProfileServerCore::SessionCleanupL
       
  1277 // -----------------------------------------------------------------------------
       
  1278 //
       
  1279 void CSIPProfileServerCore::SessionCleanupL(
       
  1280     const MSIPExtendedConcreteProfileObserver& aObserver)
       
  1281     {
       
  1282     TInt index = iObservers.Find(&aObserver);
       
  1283     if (index != KErrNotFound)
       
  1284         {
       
  1285         iObservers.Remove(index);
       
  1286         }
       
  1287 
       
  1288     for (TInt i = 0; i < iProfileCache.Count(); i ++)
       
  1289         {
       
  1290         CSIPProfileCacheItem* item = iProfileCache[i];
       
  1291         if (item->IsUser(aObserver))
       
  1292             {
       
  1293             DisableProfileL(item->ProfileId(), aObserver);
       
  1294             }        
       
  1295         item->RemoveObserver(aObserver);
       
  1296         }
       
  1297     iPluginDirector->Cleanup();
       
  1298     }
       
  1299 
       
  1300 // -----------------------------------------------------------------------------
       
  1301 // CSIPProfileServerCore::ConvertTypeInfoL
       
  1302 // -----------------------------------------------------------------------------
       
  1303 //
       
  1304 void CSIPProfileServerCore::ConvertTypeInfoL(
       
  1305     const CImplementationInformation& aEcomInfo,
       
  1306     TSIPProfileTypeInfo& aInfo) const
       
  1307     {
       
  1308     TLex8 lex(aEcomInfo.DataType());
       
  1309     if (!lex.Peek().IsDigit())
       
  1310         {
       
  1311         User::Leave(KErrArgument);
       
  1312         }
       
  1313     TInt id(0);
       
  1314     User::LeaveIfError(lex.Val(id));
       
  1315     lex.Inc();
       
  1316     aInfo.iSIPProfileName = lex.Remainder();
       
  1317     aInfo.iSIPProfileClass = (enum TSIPProfileTypeInfo::TSIPProfileClass) id;
       
  1318     }
       
  1319 
       
  1320 // -----------------------------------------------------------------------------
       
  1321 // CSIPProfileServerCore::CheckServerStatus
       
  1322 // -----------------------------------------------------------------------------
       
  1323 //
       
  1324 void CSIPProfileServerCore::CheckServerStatus() const
       
  1325     {
       
  1326     if (CanServerStop())
       
  1327         {
       
  1328         iServer->ServerCanStop();
       
  1329         }
       
  1330     }
       
  1331 
       
  1332 // -----------------------------------------------------------------------------
       
  1333 // CSIPProfileServerCore::HandleProfileStorageErrorL
       
  1334 // -----------------------------------------------------------------------------
       
  1335 //
       
  1336 void CSIPProfileServerCore::HandleProfileStorageErrorL(TInt aErr, TBool fileStore)
       
  1337     {
       
  1338     switch (aErr)
       
  1339     	{
       
  1340     	case KErrNone:
       
  1341     		break;
       
  1342 
       
  1343     	case KErrNoMemory:
       
  1344     	case KErrInUse: 
       
  1345     		User::Leave(aErr);
       
  1346     		break;
       
  1347 
       
  1348     	default: 	        	        
       
  1349 	        if (!fileStore)
       
  1350 	        	{
       
  1351 	        	delete iProfileStorage;
       
  1352 	        	iProfileStorage = NULL;
       
  1353 	        	CSIPProfileStorage::DeleteAllProfilesL();
       
  1354 	        	iProfileStorage = CSIPProfileStorage::NewL(iFs);
       
  1355 	        	}
       
  1356 	        	else
       
  1357 	        	{
       
  1358 	        	// Corrupted sipprofiles.dat file
       
  1359 	        	iProfileStorage->DeleteAllStreamProfilesL();	        		
       
  1360 	        	}	        
       
  1361     	}
       
  1362     }
       
  1363 
       
  1364 // -----------------------------------------------------------------------------
       
  1365 // CSIPProfileServerCore::ValidateErrorStatus
       
  1366 // -----------------------------------------------------------------------------
       
  1367 //
       
  1368 CSIPConcreteProfile::TStatus
       
  1369 CSIPProfileServerCore::ValidateErrorStatus(CSIPProfileCacheItem& aItem) const
       
  1370     {
       
  1371     CSIPConcreteProfile::TStatus status = aItem.Profile().Status();
       
  1372     if (status == CSIPConcreteProfile::EUnregistrationInProgress)
       
  1373         {
       
  1374         return status;
       
  1375         }
       
  1376     return CSIPConcreteProfile::ERegistrationInProgress;
       
  1377     }
       
  1378 
       
  1379 // -----------------------------------------------------------------------------
       
  1380 // CSIPProfileServerCore::HandleAsyncError
       
  1381 // -----------------------------------------------------------------------------
       
  1382 //
       
  1383 void CSIPProfileServerCore::HandleAsyncError(CSIPProfileCacheItem& aItem, 
       
  1384 	CSIPConcreteProfile::TStatus aStatus,
       
  1385     TInt aError)
       
  1386     {
       
  1387     TInt err(aError);
       
  1388     if (aStatus == CSIPConcreteProfile::EUnregistrationInProgress)
       
  1389         {
       
  1390         err = KErrNone;
       
  1391         }
       
  1392 
       
  1393     if (HandleProfileError(aItem, err))
       
  1394     	{
       
  1395 	    if (err == KErrTotalLossOfPrecision)
       
  1396 	        {
       
  1397 	        TRAP_IGNORE(SendUnregisteredStatusEventL(aItem))
       
  1398 	        }
       
  1399 	    else
       
  1400 	        {
       
  1401 	        SendErrorEvent(aItem, aStatus, aError);
       
  1402 	        }
       
  1403     	}
       
  1404     }
       
  1405 
       
  1406 // -----------------------------------------------------------------------------
       
  1407 // CSIPProfileServerCore::ReleaseStorage
       
  1408 // -----------------------------------------------------------------------------
       
  1409 //
       
  1410 void CSIPProfileServerCore::ReleaseStorage(TBool aRestoreOngoing)
       
  1411     {
       
  1412     PROFILE_DEBUG1("ProfileServerCore::ReleaseStorage")
       
  1413 
       
  1414     iBackupInProgress = ETrue;
       
  1415     TRAPD(err, ReleaseStorageL(aRestoreOngoing));
       
  1416 
       
  1417     if (err != KErrNone)
       
  1418         {
       
  1419         PROFILE_DEBUG1("ProfileServerCore::ReleaseStorage => failed")
       
  1420 #ifndef CPPUNIT_TEST
       
  1421         User::Panic(KSipProfileCSServerPanic, ERestoreFailure);
       
  1422 #endif
       
  1423         }
       
  1424     }
       
  1425 
       
  1426 // -----------------------------------------------------------------------------
       
  1427 // CSIPProfileServerCore::ReleaseStorageL
       
  1428 // -----------------------------------------------------------------------------
       
  1429 //
       
  1430 void CSIPProfileServerCore::ReleaseStorageL(TBool aRestoreOngoing)
       
  1431     {
       
  1432     __ASSERT_ALWAYS(iProfileStorage != NULL,
       
  1433     				User::Leave(KErrTotalLossOfPrecision));
       
  1434 
       
  1435 	if (aRestoreOngoing)
       
  1436 		{
       
  1437 		TerminateProfilesL();	
       
  1438 		}
       
  1439 
       
  1440     delete iProfileStorage;
       
  1441     iProfileStorage = NULL;
       
  1442     PROFILE_DEBUG1("ProfileServerCore::ReleaseStorageL, storage released")
       
  1443     }
       
  1444 
       
  1445 // -----------------------------------------------------------------------------
       
  1446 // CSIPProfileServerCore::ReserveStorage
       
  1447 // -----------------------------------------------------------------------------
       
  1448 //
       
  1449 void CSIPProfileServerCore::ReserveStorage(TBool aRestoreOngoing)
       
  1450     {
       
  1451     PROFILE_DEBUG1("ProfileServerCore::ReserveStorage")
       
  1452 
       
  1453     iBackupInProgress = EFalse;
       
  1454     TRAPD(err, ReserveStorageL(aRestoreOngoing));
       
  1455 
       
  1456     if (err != KErrNone)
       
  1457         {
       
  1458         PROFILE_DEBUG1("ProfileServerCore::ReserveStorage => failed")
       
  1459 #ifndef CPPUNIT_TEST
       
  1460         User::Panic(KSipProfileCSServerPanic, ERestoreFailure);
       
  1461 #endif
       
  1462         }
       
  1463     }
       
  1464 
       
  1465 // -----------------------------------------------------------------------------
       
  1466 // CSIPProfileServerCore::ReserveStorageL
       
  1467 // -----------------------------------------------------------------------------
       
  1468 //
       
  1469 void CSIPProfileServerCore::ReserveStorageL(TBool aRestoreOngoing)
       
  1470     {
       
  1471 	if (!iProfileStorage)
       
  1472 		{
       
  1473 		if (aRestoreOngoing)
       
  1474 			{
       
  1475 			LoadProfilesL(ETrue);
       
  1476     		CheckServerStatus();
       
  1477 			}
       
  1478 		else
       
  1479 			{
       
  1480 			// Backup ends. Do not read profiles, as they are already in cache.
       
  1481 			iProfileStorage = CSIPProfileStorage::NewL(iFs);
       
  1482 			}
       
  1483 		PROFILE_DEBUG1("ProfileServerCore::ReserveStorageL, storage reserved")
       
  1484 		}
       
  1485     }
       
  1486 
       
  1487 // -----------------------------------------------------------------------------
       
  1488 // CSIPProfileServerCore::ResetAndDestroy
       
  1489 // -----------------------------------------------------------------------------
       
  1490 //
       
  1491 void CSIPProfileServerCore::ResetAndDestroy(TAny* aArray)
       
  1492     {
       
  1493     RPointerArray<CSIPConcreteProfile>* array =
       
  1494     	static_cast<RPointerArray<CSIPConcreteProfile>*> (aArray);
       
  1495     array->ResetAndDestroy();
       
  1496     delete array;
       
  1497     }
       
  1498 
       
  1499 // -----------------------------------------------------------------------------
       
  1500 // CSIPProfileServerCore::ResetAndDestroyInfo
       
  1501 // -----------------------------------------------------------------------------
       
  1502 //
       
  1503 void CSIPProfileServerCore::ResetAndDestroyInfo(TAny* aArray)
       
  1504     {
       
  1505     RPointerArray<CImplementationInformation>* array =
       
  1506     	static_cast<RPointerArray<CImplementationInformation>*> (aArray);
       
  1507     array->ResetAndDestroy();
       
  1508     array->Close();
       
  1509     }
       
  1510 
       
  1511 // -----------------------------------------------------------------------------
       
  1512 // CSIPProfileServerCore::CrashRevert
       
  1513 // -----------------------------------------------------------------------------
       
  1514 //
       
  1515 void CSIPProfileServerCore::CrashRevert(TAny* aItem)
       
  1516     {
       
  1517     CSIPProfileCacheCleanupItem* item =
       
  1518     	static_cast<CSIPProfileCacheCleanupItem*> (aItem);
       
  1519     item->CrashRevert();
       
  1520     }
       
  1521 
       
  1522 // -----------------------------------------------------------------------------
       
  1523 // CSIPProfileServerCore::AllowMigrationL
       
  1524 // -----------------------------------------------------------------------------
       
  1525 //
       
  1526 void CSIPProfileServerCore::AllowMigrationL(TUint32 aProfileId,
       
  1527 	TUint32 aIapId,
       
  1528 	const MSIPExtendedConcreteProfileObserver& aObserver)
       
  1529     {
       
  1530     iAlrHandler->AllowMigrationL(*ProfileCacheItemL(aProfileId),
       
  1531     							 aIapId,
       
  1532     							 aObserver);
       
  1533     }
       
  1534 
       
  1535 // -----------------------------------------------------------------------------
       
  1536 // CSIPProfileServerCore::DisallowMigrationL
       
  1537 // -----------------------------------------------------------------------------
       
  1538 //
       
  1539 void CSIPProfileServerCore::DisallowMigrationL(TUint32 aProfileId,
       
  1540 	TUint32 aIapId,
       
  1541 	const MSIPExtendedConcreteProfileObserver& aObserver)
       
  1542     {
       
  1543     iAlrHandler->DisallowMigrationL(*ProfileCacheItemL(aProfileId),
       
  1544     								aIapId,
       
  1545     								aObserver);
       
  1546     }
       
  1547     
       
  1548 // -----------------------------------------------------------------------------
       
  1549 // CSIPProfileServerCore::RefreshIapAvailabilityL
       
  1550 // -----------------------------------------------------------------------------
       
  1551 //
       
  1552 void CSIPProfileServerCore::RefreshIapAvailabilityL(TUint32 aProfileId)
       
  1553     {
       
  1554     iAlrHandler->RefreshIapAvailabilityL(*ProfileCacheItemL(aProfileId));
       
  1555     }
       
  1556 
       
  1557 // -----------------------------------------------------------------------------
       
  1558 // CSIPProfileServerCore::MigrationStartedL
       
  1559 // -----------------------------------------------------------------------------
       
  1560 //
       
  1561 void CSIPProfileServerCore::MigrationStartedL(const CSIPProfileCacheItem& aItem,
       
  1562 											  TUint32 aSnapId,
       
  1563 											  TUint32 aIapId) const
       
  1564 	{
       
  1565 	const RPointerArray<MSIPExtendedConcreteProfileObserver>& obs =
       
  1566     	aItem.Observers();
       
  1567     for (TInt i = 0; i < obs.Count(); ++i)
       
  1568         {
       
  1569         obs[i]->MigrationStartedL(aItem.ProfileId(), aSnapId, aIapId);
       
  1570         }
       
  1571 	}
       
  1572 
       
  1573 // -----------------------------------------------------------------------------
       
  1574 // CSIPProfileServerCore::MigrationCompletedL
       
  1575 // -----------------------------------------------------------------------------
       
  1576 //
       
  1577 void
       
  1578 CSIPProfileServerCore::MigrationCompletedL(const CSIPProfileCacheItem& aItem,
       
  1579 										   TUint32 aSnapId,
       
  1580 										   TUint32 aIapId) const
       
  1581 	{
       
  1582 	const RPointerArray<MSIPExtendedConcreteProfileObserver>& obs =
       
  1583     	aItem.Observers();
       
  1584     for (TInt i = 0; i < obs.Count(); ++i)
       
  1585         {
       
  1586         obs[i]->MigrationCompletedL(aItem.ProfileId(), aSnapId, aIapId);
       
  1587         }
       
  1588 	}
       
  1589 
       
  1590 // -----------------------------------------------------------------------------
       
  1591 // CSIPProfileServerCore::PassAlrErrorToClientL
       
  1592 // -----------------------------------------------------------------------------
       
  1593 //
       
  1594 TInt
       
  1595 CSIPProfileServerCore::PassAlrErrorToClient(const CSIPProfileCacheItem& aItem,
       
  1596 											TInt aError,
       
  1597 											TUint32 aSnapId,
       
  1598 											TUint32 aIapId) const
       
  1599 	{
       
  1600 	TInt err(KErrNone);
       
  1601 	const RPointerArray<MSIPExtendedConcreteProfileObserver>& obs =
       
  1602     	aItem.Observers();
       
  1603     for (TInt i = 0; i < obs.Count() && !err; ++i)
       
  1604         {
       
  1605         err = obs[i]->AlrError(aError, aItem.ProfileId(), aSnapId, aIapId);
       
  1606         }
       
  1607     return err;
       
  1608 	}
       
  1609 
       
  1610 // -----------------------------------------------------------------------------
       
  1611 // CSIPProfileServerCore::MigrationControllerL
       
  1612 // -----------------------------------------------------------------------------
       
  1613 //
       
  1614 CSipAlrMigrationController&
       
  1615 CSIPProfileServerCore::MigrationControllerL(TUint32 aSnapId)
       
  1616 	{
       
  1617 	RemoveUnusedMigrationControllers(aSnapId);
       
  1618 
       
  1619 	for (TInt i = 0; i < iMigrationControllers.Count(); ++i)
       
  1620 		{
       
  1621 		if (iMigrationControllers[i]->SnapId() == aSnapId)
       
  1622 			{
       
  1623 			return *iMigrationControllers[i];
       
  1624 			}
       
  1625 		}
       
  1626 
       
  1627 	CSipAlrMigrationController* ctrl =
       
  1628 		CSipAlrMigrationController::NewLC(iAlrHandler->AlrMonitorL(), aSnapId);
       
  1629 	iMigrationControllers.AppendL(ctrl);
       
  1630 	CleanupStack::Pop(ctrl);
       
  1631 	return *ctrl;
       
  1632 	}
       
  1633 
       
  1634 // -----------------------------------------------------------------------------
       
  1635 // CSIPProfileServerCore::UnregisteredState
       
  1636 // -----------------------------------------------------------------------------
       
  1637 //
       
  1638 CSIPProfileState& CSIPProfileServerCore::UnregisteredState()
       
  1639 	{
       
  1640 	return *iUnregistered;
       
  1641 	}
       
  1642 
       
  1643 // -----------------------------------------------------------------------------
       
  1644 // CSIPProfileServerCore::RemoveProfileItem
       
  1645 // -----------------------------------------------------------------------------
       
  1646 //
       
  1647 void CSIPProfileServerCore::RemoveProfileItem(TUint32 aProfileId)
       
  1648 	{
       
  1649     TInt index = ProfileCached(aProfileId);
       
  1650     if (index >= 0)
       
  1651     	{
       
  1652     	iProfileCache.Remove(index);
       
  1653     	}
       
  1654 	}
       
  1655 
       
  1656 // -----------------------------------------------------------------------------
       
  1657 // CSIPProfileServerCore::RemoveUnusedMigrationControllers
       
  1658 // -----------------------------------------------------------------------------
       
  1659 //
       
  1660 void CSIPProfileServerCore::RemoveUnusedMigrationControllers(TUint32 aSnapId)
       
  1661 	{	
       
  1662 	for (TInt i = iMigrationControllers.Count() - 1; i >= 0; --i)
       
  1663 		{
       
  1664 		if (!iMigrationControllers[i]->IsUsed() &&
       
  1665 			iMigrationControllers[i]->SnapId() != aSnapId)
       
  1666 			{
       
  1667 			CSipAlrMigrationController* unused = iMigrationControllers[i];
       
  1668 			iMigrationControllers.Remove(i);
       
  1669 			delete unused;
       
  1670 			}
       
  1671 		}
       
  1672 	}
       
  1673 
       
  1674 // -----------------------------------------------------------------------------
       
  1675 // CSIPProfileServerCore::GenerateProfileIdL
       
  1676 // Generate a random profile id (don't use value 0) and check it is not in use.
       
  1677 // -----------------------------------------------------------------------------
       
  1678 //
       
  1679 TUint32 CSIPProfileServerCore::GenerateProfileIdL()
       
  1680 	{
       
  1681 	const TInt KProfileIdLength = sizeof(TUint32);
       
  1682 	HBufC8* buf = HBufC8::NewLC(KProfileIdLength);
       
  1683     TPtr8 dataPtr(buf->Des());
       
  1684     dataPtr.FillZ(dataPtr.MaxLength());
       
  1685 	CSystemRandom* random = CSystemRandom::NewLC();
       
  1686 
       
  1687 	const TUint32 KEmptyProfileId = 0;
       
  1688 	TUint32 id(KEmptyProfileId);
       
  1689 	TBool alreadyUsed(EFalse);
       
  1690 	do
       
  1691 		{
       
  1692 		random->GenerateBytesL(dataPtr);
       
  1693 
       
  1694 		const TInt KHighestBytePos 		 = 24;
       
  1695 		const TInt KSecondHighestBytePos = 16;
       
  1696 		const TInt KLowestBytePos 		 = 8;
       
  1697 		id = dataPtr[0] << KHighestBytePos |
       
  1698 			 dataPtr[1] << KSecondHighestBytePos |
       
  1699 			 dataPtr[2] << KLowestBytePos |
       
  1700 			 dataPtr[3];
       
  1701 		alreadyUsed = EFalse;
       
  1702 
       
  1703 		for (TInt i = 0; i < iProfileCache.Count() && !alreadyUsed; ++i)
       
  1704 	        {
       
  1705 	        alreadyUsed = (iProfileCache[i]->Profile().Id() == id);
       
  1706 	        }
       
  1707 		} while (alreadyUsed || id == KEmptyProfileId);
       
  1708 
       
  1709 	CleanupStack::PopAndDestroy(random);
       
  1710 	CleanupStack::PopAndDestroy(buf);
       
  1711 	return id;
       
  1712 	}
       
  1713 
       
  1714 // -----------------------------------------------------------------------------
       
  1715 // CSIPProfileServerCore::LoadSystemStateMonitorL
       
  1716 // Load first matching plugin. There should be just one.
       
  1717 // -----------------------------------------------------------------------------
       
  1718 //
       
  1719 void CSIPProfileServerCore::LoadSystemStateMonitorL()
       
  1720 	{
       
  1721 	__ASSERT_ALWAYS(!iSystemStateMonitor, User::Leave(KErrAlreadyExists));
       
  1722 
       
  1723 	RImplInfoPtrArray infoArray;
       
  1724 	CleanupStack::PushL(TCleanupItem(ResetAndDestroyInfo, &infoArray));
       
  1725 	REComSession::ListImplementationsL(KSipSystemStateMonitorIfUid, infoArray);    
       
  1726 
       
  1727 	if (infoArray.Count() > 0 && infoArray[0])
       
  1728 	    {
       
  1729 		// Create a specific plugin with its UID
       
  1730 		iSystemStateMonitor = reinterpret_cast<CSipSystemStateMonitor*>(
       
  1731 			REComSession::CreateImplementationL(
       
  1732 				infoArray[0]->ImplementationUid(),
       
  1733 				_FOFF(CSipSystemStateMonitor, iInstanceKey)));
       
  1734         PROFILE_DEBUG1("System state monitor loaded")
       
  1735   		iSystemStateMonitor->StartMonitoringL(
       
  1736   		    CSipSystemStateMonitor::ESystemState, 0, *this);
       
  1737 		iSystemStateMonitor->StartMonitoringL(
       
  1738 			CSipSystemStateMonitor::ERfsState, 0, *this);
       
  1739 	    }
       
  1740 	CleanupStack::Pop(); // TCleanupItem
       
  1741 	infoArray.ResetAndDestroy();
       
  1742 	}
       
  1743 
       
  1744 // -----------------------------------------------------------------------------
       
  1745 // CSIPProfileServerCore::FindDefaultProfile
       
  1746 // -----------------------------------------------------------------------------
       
  1747 //
       
  1748 CSIPConcreteProfile* CSIPProfileServerCore::FindDefaultProfile() const
       
  1749 	{
       
  1750 	const TInt count = iProfileCache.Count();
       
  1751 	
       
  1752 	for ( TInt i=0 ; i<count ; ++i )
       
  1753 		{
       
  1754 		if ( iProfileCache[i]->ProfileId() && iProfileCache[i]->IsActiveState() )
       
  1755 			{
       
  1756 			CSIPConcreteProfile* ptr = &( iProfileCache[i]->LatestProfile() );
       
  1757 			
       
  1758 			if ( ptr && ptr->IsDefault() )
       
  1759 				{
       
  1760 				return ptr;
       
  1761 				}
       
  1762 			}
       
  1763 		}
       
  1764 	return NULL;
       
  1765 	}
       
  1766 
       
  1767 // -----------------------------------------------------------------------------
       
  1768 // CSIPProfileServerCore::ShouldChangeIap
       
  1769 // -----------------------------------------------------------------------------
       
  1770 // 
       
  1771 TBool CSIPProfileServerCore::ShouldChangeIap(CSIPConcreteProfile& aProfile, TInt aError) const
       
  1772 	{
       
  1773 	PROFILE_DEBUG3("CSIPProfileServerCore::ShouldChangeIap, error", aError)
       
  1774 	TUint32 dummySnapId(0);	
       
  1775 	if ( aProfile.ExtensionParameter(KSIPSnapId, dummySnapId) == KErrNone &&
       
  1776 	     !AnyRegisteredProfileUsesIap(aProfile.IapId()) )
       
  1777 	    {
       
  1778 		PROFILE_DEBUG1("CSIPProfileServerCore::ShouldChangeIap, snap is in use")
       
  1779 
       
  1780 	    // This profile uses a SNAP.
       
  1781 	    // There are no registered profiles using the same IAP as this profile.
       
  1782 	    
       
  1783         if ( aError == KErrTimedOut ||
       
  1784 	         aError == KErrSIPResolvingFailure )
       
  1785 	        {
       
  1786 			PROFILE_DEBUG1("CSIPProfileServerCore::ShouldChangeIap returns True")
       
  1787 	        return ETrue;
       
  1788 	        }
       
  1789 	    }
       
  1790 	PROFILE_DEBUG1("CSIPProfileServerCore::ShouldChangeIap returns false")
       
  1791     return EFalse;
       
  1792 	}
       
  1793  
       
  1794 TBool CSIPProfileServerCore::AnyRegisteredProfileUsesIap(TUint aIap) const
       
  1795     {
       
  1796     
       
  1797     for ( TInt i = 0; i < iProfileCache.Count(); i++ )
       
  1798         {
       
  1799         PROFILE_DEBUG3("CSIPProfileServerCore::AnyRegisteredProfileUsesIap, i", i)
       
  1800         // Iterate all CSIPProfileCacheItems.
       
  1801         if ( iProfileCache[i]->IsActiveState() )
       
  1802             {
       
  1803             // Cache item is valid.
       
  1804             CSIPConcreteProfile& profile = iProfileCache[i]->Profile();
       
  1805 			PROFILE_DEBUG3("CSIPProfileServerCore::AnyRegisteredProfileUsesIap, profile status", profile.Status())
       
  1806 			PROFILE_DEBUG4("CSIPProfileServerCore::AnyRegisteredProfileUsesIap, aIap, profile.IapId", aIap, profile.IapId())
       
  1807 
       
  1808             if ( profile.Status() == CSIPConcreteProfile::ERegistered && 
       
  1809                  profile.IapId() == aIap )
       
  1810                 {
       
  1811                     // Profile is registered and is using the specified IAP.
       
  1812 					PROFILE_DEBUG1("CSIPProfileServerCore::AnyRegisteredProfileUsesIap returns True")
       
  1813 
       
  1814                     return ETrue;
       
  1815                 }
       
  1816             }
       
  1817         }
       
  1818 
       
  1819 	PROFILE_DEBUG1("CSIPProfileServerCore::AnyRegisteredProfileUsesIap returns false")
       
  1820     return EFalse;
       
  1821     }
       
  1822 
       
  1823 // ----------------------------------------------------------------------------
       
  1824 // Function is used to send ForciblyDisabled event on the profile to the
       
  1825 // Profile Agent Client.
       
  1826 // ----------------------------------------------------------------------------
       
  1827 void CSIPProfileServerCore::SendProfileForciblyDisabledEvent(
       
  1828 	const CSIPProfileCacheItem& aItem) const
       
  1829     {
       
  1830     	//Get the list of observers for a given Profile Item
       
  1831     	const RPointerArray<MSIPExtendedConcreteProfileObserver>& obs =
       
  1832         	aItem.Observers();
       
  1833 
       
  1834     	//Iterate through the list of observers for that profile item
       
  1835     	//and send event to each of them.
       
  1836         for (TInt i = 0; i < obs.Count(); i++)
       
  1837         	{
       
  1838 			TRAP_IGNORE(obs[i]->RegistrationStatusChangedL(aItem.ProfileId(),
       
  1839 						aItem.Profile().Status(), ESipProfileItcOpProfileForciblyDisabled));
       
  1840             }
       
  1841     }