telephonyserverplugins/simtsy/src/CSimCallForwarding.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 20 244d7c5f118e
--- a/telephonyserverplugins/simtsy/src/CSimCallForwarding.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/CSimCallForwarding.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,1089 +1,1089 @@
-// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// Implements the functionality required to provide clients with
-// callforwarding status and registration information.
-// 
-//
-
-/**
- @file
-*/
-
-#include <testconfigfileparser.h>
-#include "CSimCallForwarding.h"
-#include "CSimPhone.h"
-#include "Simlog.h"
-
-const TInt KSettingListGranularity=5;	// < The granularity used for parameter list arrays.
-const TInt KInvalidTimeout = -1;        // Value used when timeout period does not matter
-const TInt KMobServiceIndxStart = 1;
-const TInt KMobServiceIndxEnd   = 6;
-
-CSimCallForwarding* CSimCallForwarding::NewL(CSimPhone* aPhone)
-/**
- * Standard two-phase constructor.
- * @param aPhone				The parent phone object.
- * @return CSimNetworkStatus	The new network status class.
- */
-	{
-	CSimCallForwarding* self=new(ELeave) CSimCallForwarding(aPhone);
-	CleanupStack::PushL(self);
-	self->ConstructL();
-	CleanupStack::Pop();
-	return self;
-	}
-
-CSimCallForwarding::CSimCallForwarding(CSimPhone* aPhone)
-		: iPhone(aPhone)
-/**
- * Trivial first phase construction.
- * @param aPhone				The parent phone object.
- */
-	{
-	}
-
-void CSimCallForwarding::ConstructL()
-	/** 
-	Second phase of 2-Phase Constructor
- 	Retrieves all the Call forwarding and Identity services tags from the config file
-	*/
-	{
-	LOGCALL1("Starting to parse Call Forwarding config parameters...");
-
-	iIdentityServiceStatus=new(ELeave) CArrayFixFlat<TIdentityServiceStatus>(KSettingListGranularity);
-	
-	iGetCFStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
-	FindAndCreateCFListL();
-	
-	// Read in the Identity services information
-	TInt count=CfgFile()->ItemCount(KIdentityServiceStatus);
-	const CTestConfigItem* item=NULL;
-	TInt ret=KErrNone;
-	for(TInt i=0;i<count;i++)
-		{
-		item=CfgFile()->Item(KIdentityServiceStatus,i);
-		if(!item)
-			break;
-
-		TInt status, service;
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,service);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("service",ret,0,&KIdentityServiceStatus);
-			continue;
-			}
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,status);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("status",ret,1,&KIdentityServiceStatus);
-			continue;
-			}
-			
-		TIdentityServiceStatus identityServiceStatus;
-		identityServiceStatus.iService = static_cast<RMobilePhone::TMobilePhoneIdService>(service);
-		identityServiceStatus.iStatus = static_cast<RMobilePhone::TMobilePhoneIdServiceStatus>(status);
-		iIdentityServiceStatus->AppendL(identityServiceStatus);
-		}
-		
-	LOGCALL1("...Finished parsing Call Forwarding config parameters...");
-	}
-
-CSimCallForwarding::~CSimCallForwarding()
-	/** 
-	Destroy all the objects constructed.
-	*/
-	{
-	if (iIdentityServiceStatus != NULL)
-		{
-		iIdentityServiceStatus->Delete(0,iIdentityServiceStatus->Count());
-		delete iIdentityServiceStatus;
-		}
-	delete iCFList;
-	if (iGetCFStatus)
-		iGetCFStatus->ResetAndDestroy();
-	delete iGetCFStatus;
-	}
-
-
-TInt CSimCallForwarding::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
-	{
-	/**
-	Handles all the Call forwarding APIs
-	@param aReqHandle to the request
-	@param Ipc unique identifier of the method to call
-	@param aPckg contains arguments of the method to call
-	*/
-	TAny* dataPtr = aPckg.Ptr1();
-	TAny* dataPtr2 = aPckg.Ptr2();
-
-	// The following requests can be completed even if the completion of another request is pending.
-	switch(aIpc)
-		{
-	case EMobilePhoneSetCallForwardingStatus:
-		return SetCallForwardingStatus(aReqHandle,
-			reinterpret_cast<RMobilePhone::TMobilePhoneCFCondition*>(dataPtr),
-			reinterpret_cast<RMobilePhone::TMobilePhoneCFChangeV1*>(dataPtr2));
-	case EMobilePhoneNotifyCallForwardingStatusChange:
-		return NotifyCallForwardingStatusChange(aReqHandle, reinterpret_cast<RMobilePhone::TMobilePhoneCFCondition*>(dataPtr));
-	case EMobilePhoneGetIdentityServiceStatus:
-		return GetIdentityServiceStatus(aReqHandle, 
-			reinterpret_cast<RMobilePhone::TMobilePhoneIdService*>(dataPtr),
-			reinterpret_cast<RMobilePhone::TMobilePhoneIdServiceStatus*>(dataPtr2));
-	case EMobilePhoneGetCallForwardingStatusPhase1:
-		return GetCallForwardingStatusPhase1(aReqHandle, 
-			REINTERPRET_CAST(CRetrieveMobilePhoneCFList::TGetCallForwardingRequest*, dataPtr), 
-			REINTERPRET_CAST(TInt*, dataPtr2));
-	case EMobilePhoneGetCallForwardingStatusPhase2:
-		return GetCallForwardingStatusPhase2(aReqHandle, 
-			REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());			
-	default:
-		break;
-		}
-	return KErrNotSupported;
-	}
-	
-TInt CSimCallForwarding::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
-	/**
-	Cancels Call forwarding requests
-	@param ipc request to cancel
-	@param aReqHandle Handle to the request
-	*/
-	{
-	switch(aIpc)
-		{
-	case EMobilePhoneSetCallForwardingStatus:
-		return SetCallForwardingStatusCancel(aReqHandle);
-	case EMobilePhoneNotifyCallForwardingStatusChange:
-		return NotifyCallForwardingStatusChangeCancel(aReqHandle);
-	case EMobilePhoneGetIdentityServiceStatus:
-		return GetIdentityServiceStatusCancel(aReqHandle);
-	default:
-		break;
-		}
-	return KErrNone;
-	}
-	
-void CSimCallForwarding::FindAndCreateCFListL()
-	{
-	/**
-	Creates the Call forwarding list from the config file
-	*/
-	LOGCALL1("CSimPhone::FindAndCreateCFListL");
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 entry;
-
-	if(iCFList)
-		delete iCFList;
-	iCFList=NULL;
-
-	iCFList = CMobilePhoneCFList::NewL();
-	TInt count=CfgFile()->ItemCount(KCFList);
-	const CTestConfigItem* item=NULL;
-	TInt ret=KErrNone;
-
-	LOGCALL1("Starting to Load and Parse CFList Config parameters");
-	
-	TInt i;
-	for(i=0;i<count;i++)
-		{
-		item=CfgFile()->Item(KCFList,i);
-		if(!item)
-			break;
-		
-		TPtrC8 number;
-		TInt condition, serviceGroup, status, timeout; // valid for CFRNy only
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,condition);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("condition",ret,0,&KCFList);
-			continue;
-			}
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,serviceGroup);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("serviceGroup",ret,1,&KCFList);
-			continue;
-			}
-
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,status);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("status",ret,2,&KCFList);
-			continue;
-			}
-
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,timeout);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("timeout",ret,3,&KCFList);
-			continue;
-			}
-		
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,number);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("number",ret,4,&KCFList);
-			continue;
-			}
-		
-		entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
-		entry.iNumber.iTelNumber.Copy(number);
-		entry.iTimeout=timeout;
-		entry.iCondition=(RMobilePhone::TMobilePhoneCFCondition)condition;
-		entry.iStatus=(RMobilePhone::TMobilePhoneCFStatus)status;
-		iCFList->AddEntryL(entry);
-		}//end for
-	
-	//CFlist must define entries for each condition even if unknown
-	//fill up table if it misses conditions:
-	
-	RArray<TBool> serviceArray;
-	//voice, auxVoice, data, packet, fax, sms, all;
-
-	CleanupClosePushL(serviceArray);
-
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 extraEntry;
-
-	for (TInt j=1;j<5;j++)//loop conditions
-		{
-		TInt serviceFound=EFalse;
-		TInt index;
-		extraEntry.iCondition=static_cast<RMobilePhone::TMobilePhoneCFCondition>(j);
-		serviceArray.Reset();
-		for(TInt h=0;h<8;h++)
-			{
-			serviceArray.Append(EFalse);
-			}
-		
-		for (TInt k=0;k<count;k++)//loop entries
-			{
-			entry=iCFList->GetEntryL(k);
-			if(entry.iCondition==static_cast<RMobilePhone::TMobilePhoneCFCondition>(j))
-				{
-				index = (TInt)entry.iServiceGroup;
-				serviceArray[index]=ETrue;
-				}
-			}
-		
-		if (!serviceArray[7])//(all services)
-			{
-			for (TInt l=1;l<7;l++)
-				{
-				if (serviceArray[l])
-					serviceFound=ETrue;										
-				}
-			//no service defined for this condition
-			if(!serviceFound)
-				{
-				extraEntry.iServiceGroup=RMobilePhone::EAllServices;
-				extraEntry.iStatus=RMobilePhone::ECallForwardingStatusNotRegistered;
-				iCFList->AddEntryL(extraEntry);
-				}
-			//some services defined in table
-			else
-				{
-				for (TInt m=1;m<7;m++)
-					{
-					if (!serviceArray[m])
-						{
-						extraEntry.iServiceGroup=static_cast<RMobilePhone::TMobileService>(m);
-						extraEntry.iStatus=RMobilePhone::ECallForwardingStatusNotRegistered;
-						iCFList->AddEntryL(extraEntry);
-						}
-					}//end for
-				}//end else
-			}//end if
-		}//end for
-		
-	CleanupStack::PopAndDestroy(&serviceArray);	//Destroying serviceArray to free the memory
-	}
-
-TInt CSimCallForwarding::GetIdentityServiceStatus(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneIdService* aService, RMobilePhone::TMobilePhoneIdServiceStatus* aStatus)
-	/**
-	Gets the status of the identity services
-	@param aReqHandle handle to the request
-	@param aService service that the client is interested in
-	@param aStatus of the identity service
-	*/
-	{
-	RMobilePhone::TMobilePhoneIdServiceStatus status;
-	status = RMobilePhone::EIdServiceUnknown;
-	TInt count = iIdentityServiceStatus->Count();
-	for(TInt i=0; i<count; i++)
-		{
-		if(iIdentityServiceStatus->At(i).iService == *aService)
-			{
-			status = iIdentityServiceStatus->At(i).iStatus;
-			break;
-			}
-		}
-	*aStatus = status;
-	iPhone->ReqCompleted(aReqHandle, KErrNone);
-	return KErrNone;
-	}
-	
-TInt CSimCallForwarding::GetIdentityServiceStatusCancel(const TTsyReqHandle aReqHandle)
-	/**
-	Cancels the request to get the status of the identity services
-	@param aReqHandle hadle to the request
-	*/
-	{
-	iPhone->ReqCompleted(aReqHandle,KErrCancel);
-	return KErrNone;
-	}
-	
-TInt CSimCallForwarding::NotifyCallForwardingStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCFCondition* aCF)
-	/**
-	Requests to be notified of call forwarding status change
-	@param aReqHandle handle to the request
-	@param aCF condition for which the client wants to be notified
-	 */
-	{
-	__ASSERT_ALWAYS(!iCFNotification.iCFChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
-
-	iCFNotification.iCFChangeInfoNotificationPending=ETrue;
-	iCFNotification.iCFChangeInfoReqHandle=aReqHandle;
-	iCFNotification.iCurrentCFCondition=aCF;
-	LOGCALL1("Finished CSimCallForwarding::NotifyCallForwardingStatusChange");
-	return KErrNone;
-	}
-	
-TInt CSimCallForwarding::NotifyCallForwardingStatusChangeCancel(const TTsyReqHandle aReqHandle)
-	/**
-	Cancels the request to be notified of call forwarding status change
-	@param aReqHandle handle to the request
-	*/
-	{
-	if(iCFNotification.iCFChangeInfoNotificationPending)
-		{
-		iCFNotification.iCFChangeInfoNotificationPending=EFalse;
-		iPhone->ReqCompleted(aReqHandle,KErrCancel);
-		}
-	return KErrNone;
-	}
-	
-TInt CSimCallForwarding::SetCallForwardingStatus(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCFCondition* aCF,  RMobilePhone::TMobilePhoneCFChangeV1* aInfo)
-	/**
-	Sets the status of call forwarding
-	@param aReqHandle handle to the request
-	@param aCF condition for which the client wants to set the status
-	@param aInfo value of Call forwarding to set
-	*/
-	{
-	TRAPD(err, UpdateCFListL(aCF,aInfo));
-	if ( err != KErrNone )
-		{ 
-		iPhone->ReqCompleted(aReqHandle,err);
-		return KErrNone;
-		}
-		
-	if(iCFNotification.iCFChangeInfoNotificationPending)
-		{
-		*(iCFNotification.iCurrentCFCondition)=*aCF;
-		iCFNotification.iCFChangeInfoNotificationPending=EFalse;
-		iPhone->ReqCompleted(iCFNotification.iCFChangeInfoReqHandle,KErrNone);
-		}
-	
-	iPhone->ReqCompleted(aReqHandle,err);
-	LOGCALL1("Finished CSimCallForwarding::SetCallForwardingStatus");
-	return KErrNone;
-	}
-	
-TInt CSimCallForwarding::SetCallForwardingStatusCancel(const TTsyReqHandle aReqHandle)
-	/**
-	Cancels the request to set the status of call forwarding
-	@param aReqHandle handle to the request
-	*/
-	{
-	iPhone->ReqCompleted(aReqHandle,KErrCancel);
-	return KErrNone;
-	}
-	
-
-TInt CSimCallForwarding::GetCallForwardingStatusPhase1(const TTsyReqHandle aTsyReqHandle, 
-												 CRetrieveMobilePhoneCFList::TGetCallForwardingRequest* aReqData, 
-												 TInt* aBufSize)
-	{
-	/**
-	1st phase retrieval of the status of call forwarding
-	@param aTsyReqHandle handle to the request
-	@param aReqData contains details of the request
-	@param aBufSize size of the buffer the client needs to allocate for phase 2
-	*/
-	LOGCALL1("CSimPhone::GetCallForwardingStatusPhase1");
-	TInt ret=KErrNone;
-
-    // for forwarding we cannot querry for all conditions;
-    // conditions - specific
-    // services  - individual and all
-	if ((aReqData->iCondition==RMobilePhone::ECallForwardingUnspecified)
-	   || (aReqData->iCondition==RMobilePhone::ECallForwardingAllCases)
-	   || (aReqData->iCondition==RMobilePhone::ECallForwardingAllConditionalCases))
-	   {
-			iPhone->ReqCompleted(aTsyReqHandle,KErrArgument);
-		}
-	else
-		{
-		TInt leaveCode=KErrNone;
-		TRAP(leaveCode, ret=ProcessGetCallForwardingStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
-		if (leaveCode != KErrNone)
-			iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
-		}
-	LOGCALL1("CSimPhone::GetCallForwardingStatusPhase1");
-	return ret;
-	}
-	
-TInt CSimCallForwarding::ProcessGetCallForwardingStatusPhase1L(const TTsyReqHandle aTsyReqHandle, 
-														 CRetrieveMobilePhoneCFList::TGetCallForwardingRequest* aReqData, 
-														 TInt* aBufSize)
-	{
-	/** Retrieve call forwarding status of each line from phone, 
-	store each CF status response as a list entry,
-	stream the list and then return size of this buffer to client
-	@param aReqHandle Handle to the request
-	@param aReqData information about the request
-	@param aBufSize Size of the buffer the client has to allocate for the 2nd pahase
-	*/
-
-	LOGCALL1("CSimPhone::ProcessGetCallForwardingStatusPhase1L");
-
-	CMobilePhoneCFList* list=CMobilePhoneCFList::NewL();
-	CleanupStack::PushL(list);
-	
-	TInt cnt=0;//Only interested by entries with a particular condition
-	TInt maxNum=iCFList->Enumerate();
-	TBool isAllGroups = (aReqData->iServiceGroup == RMobilePhone::EAllServices);
-	for(TInt i=0;i<maxNum;i++)
-		{
-		RMobilePhone::TMobilePhoneCFInfoEntryV1 entry = iCFList->GetEntryL(i);
-		
-		// Check that the data structure is supported by the simulated TSY version
-		TInt err = iPhone->CheckSimTsyVersion(entry);
-		if(err != KErrNone)
-			{
-			iPhone->ReqCompleted(aTsyReqHandle, err);
-			return KErrNone;
-			}
-
-		if((entry.iCondition == aReqData->iCondition) 
-		   &&(entry.iStatus != RMobilePhone::ECallForwardingStatusNotRegistered))
-			{
-			if ( !isAllGroups && (entry.iServiceGroup != aReqData->iServiceGroup))
-				{
-				continue;
-				}
-			list->AddEntryL(entry);
-			cnt++;
-			}	
-		}
-	// Store the streamed list and the client ID
-	CListReadAllAttempt* read=CListReadAllAttempt::NewL(aReqData->iClient,aTsyReqHandle);
-	CleanupStack::PushL(read);
-	
-	read->iListBuf = list->StoreLC();
-	CleanupStack::Pop(); // pop the CBufBase allocated by StoreLC
-	
-	iGetCFStatus->AppendL(read);
-	CleanupStack::Pop(read); // pop the CListReadAllAttempt
-	
-	// return the CBufBase’s size to client
-	*aBufSize=(read->iListBuf)->Size();
-	
-	CleanupStack::PopAndDestroy(list); // pop&destroy list
-	
-	// Complete first phase of list retrieval
-	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
-	LOGCALL1("CSimPhone::ProcessGetCallForwardingStatusPhase1L");
-	return KErrNone;	
-	}
-
-TInt CSimCallForwarding::GetCallForwardingStatusPhase2(const TTsyReqHandle aTsyReqHandle, 
-												 RMobilePhone::TClientId* aClient, TDes8* aBuf)
-	/**
-	2nd phase retrieval of the status of call forwarding
-	@param aTsyRqHandle handle to the request
-	@param aClient pointer to the client
-	@param aBuf buffer that contains the call forwarding list
-	*/
-	{
-	LOGCALL1("CSimPhone::GetCallForwardingStatusPhase2");
-	CListReadAllAttempt* read=NULL;
-	// Find the get detected network attempt from this client
-	for (TInt i=0; i<iGetCFStatus->Count(); ++i)
-		{
-		read = iGetCFStatus->At(i);
-		if ((read->iClient.iSessionHandle==aClient->iSessionHandle) &&
-		    (read->iClient.iSubSessionHandle==aClient->iSubSessionHandle))
-			{
-			TPtr8 bufPtr((read->iListBuf)->Ptr(0));
-			// Copy the streamed list to the client
-			aBuf->Copy(bufPtr);
-			delete read;
-			iGetCFStatus->Delete(i);
-			iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
-			return KErrNone;
-			}
-		}
-	// Should handle error case of not finding the matching client from read all phase 1
-	LOGCALL1("CSimPhone::GetCallForwardingStatusPhase2");
-	return KErrNotFound;
-	}
-
-
-TInt CSimCallForwarding::GetCallForwardingStatusCancel(const TTsyReqHandle aTsyReqHandle)
-	{
-	/**
-	Cancel the request to retrieve the status of call forwarding
-	@param aTsyReqHandle handle to the request
-	*/
-	LOGCALL1("CSimPhone::GetCallForwardingStatusCancel");
-	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
-	// Remove the read all attempt from iGetCFStatus
-	CListReadAllAttempt* read=NULL;
-	for (TInt i=0; i<iGetCFStatus->Count(); ++i)
-		{
-		read = iGetCFStatus->At(i);
-		if (read->iReqHandle == aTsyReqHandle)
-			{
-			delete read;
-			iGetCFStatus->Delete(i);
-			break;
-			}
-		}
-	iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
-	LOGCALL1("CSimPhone::GetCallForwardingStatusCancel");
-	return KErrNone;
-	}
-
-void CSimCallForwarding::UpdateCFListL(RMobilePhone::TMobilePhoneCFCondition* aCF, 
-									   RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo )
-	{		
-	/**
-	Modifies the status of call forwarding
-	@param aCF condition
-	@param aCFInfo details of the request
-	*/
-	User::LeaveIfNull(aCF);
-	User::LeaveIfNull(aCFInfo);
-
-	if (*aCF == RMobilePhone::ECallForwardingUnspecified)
-	    {
-	    // not supported - tell user it is a wrong argument 
-		User::Leave(KErrArgument);
-	    }
-	     
-	if ((*aCF == RMobilePhone::ECallForwardingAllCases)
-		||(*aCF == RMobilePhone::ECallForwardingAllConditionalCases)) 
-	    {
-	    // not supported - tell user it is a wrong argument 
-		User::Leave(KErrNotSupported);
-	    }  
-	       
-	switch (aCFInfo->iAction)
-		{
-		case RMobilePhone::EServiceActionRegister:
-			RegisterL(aCF, aCFInfo);
-			break;
-			
-		case RMobilePhone::EServiceActionActivate:
-			ActivateL(aCF, aCFInfo);
-			break;
-			
-		case RMobilePhone::EServiceActionInvoke:
-		    // currently not supported
-		    // tell user it is a wrong argument 
-			User::Leave(KErrArgument);
-			break;
-			
-		case RMobilePhone::EServiceActionDeactivate:
-			DeactivateL(aCF, aCFInfo);
-			break;
-			
-		case RMobilePhone::EServiceActionErase:
-			EraseL(aCF, aCFInfo);
-			break;
-			
-		case RMobilePhone::EServiceActionUnspecified:
-		default:
-		    // not supported - tell user it is a wrong argument 
-			User::Leave(KErrArgument);
-			break;
-		}
-	}
-	
-
-inline void SplitOneCFEntryIntoSeparateGroupsL(CMobilePhoneCFList* aCFList,
-											   RMobilePhone::TMobilePhoneCFInfoEntryV1& aOrigEntry,
-											   RMobilePhone::TMobileService aExceptServiceGroup)
-	{
-	/*
-	Splits one entry valid for all basic service groups into individual entries 
-	and places them into a CMobilePhoneCFList. This excludes one service group.	 
-	@param aCBList The list to which to store the entries
-	@param aOrigEntry The original entry; details of which should be passed to individual group entries
-	@param aExceptServiceGroup The group which has to be avoided
-	*/
-	// we have to split the entry into entries 
-	// per group with the same condition; excluding the specified service group 
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 anotherEntry(aOrigEntry);
-
-	RMobilePhone::TMobileService service;
-	
-	for (TInt i = KMobServiceIndxStart;i <= KMobServiceIndxEnd;i++)
-		{
-		service=static_cast<RMobilePhone::TMobileService>(i);
-		
-		if( service != aExceptServiceGroup )
-			{
-			anotherEntry.iServiceGroup=service;
-			aCFList->AddEntryL(anotherEntry);
-			}
-		}//end for (another)
-	}
-	
-	
-void CSimCallForwarding::UpdateCFQuiescentConditionL(TBool aActivate, 
-													RMobilePhone::TMobilePhoneCFCondition aCF)
-	{
-	// only the Call Forward Unconditional can alter any other CF condition
-	if(aCF == RMobilePhone::ECallForwardingUnconditional)
-		{		
-		TBool cFBChangeRequired = EFalse;
-		
-		RMobilePhone::TMobilePhoneCFInfoEntryV1 theEntry;
-		
-		const TInt count = iCFList->Enumerate();
-
-		// look for any instances of the ECallForwardingBusy
-		for (TInt indx=0; indx < count; indx++)
-			{ 
-			theEntry = iCFList->GetEntryL(indx);
-			
-			if(theEntry.iCondition == RMobilePhone::ECallForwardingBusy &&
-			  (theEntry.iStatus == RMobilePhone::ECallForwardingStatusActive || 
-			   theEntry.iStatus == RMobilePhone::ECallForwardingStatusQuiescent)) 
-				{
-				cFBChangeRequired = ETrue;
-				}												
-			}
-		
-		if(cFBChangeRequired)
-			{
-			// retain prev version of the list in local variable and in Cleanup stack
-			CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
-			CleanupStack::PushL(thePrevCFList);
-	
-			// copy existing data into the temp storage
-			for (TInt indx=0; indx < count; indx++)
-				{ 
-				thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
-				}
-
-			delete iCFList;
-			iCFList = NULL;
-	
-			// create a new version and hold it in the class member
-			iCFList = CMobilePhoneCFList::NewL();
-	
-			// get a hold of it in a local variable       
-			CMobilePhoneCFList* theNewCFList = iCFList;
-			
-			for(TInt indx=0; indx < count; indx++)
-				{
-				theEntry = thePrevCFList->GetEntryL(indx);
-			
-				if(theEntry.iCondition == RMobilePhone::ECallForwardingBusy)
-					{
-					if(aActivate)
-						{
-						if(theEntry.iStatus == RMobilePhone::ECallForwardingStatusActive)
-							{
-							theEntry.iStatus = RMobilePhone::ECallForwardingStatusQuiescent;
-							}
-						}
-					else
-						{
-						if(theEntry.iStatus == RMobilePhone::ECallForwardingStatusQuiescent)
-							{
-							theEntry.iStatus = RMobilePhone::ECallForwardingStatusActive;
-							}
-						}					
-					}			
-				theNewCFList->AddEntryL(theEntry);
-				}					
-			
-			// now delete the old memory
-			CleanupStack::PopAndDestroy(thePrevCFList);
-			}						
-		}
-	}	
-
-void CSimCallForwarding::ActivateL(RMobilePhone::TMobilePhoneCFCondition* aCF, 
-								   RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo )
-	{
-	// NOTE: An assumption is made that the calling method has checked the parameters
-	// are not NULL.
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 theNewEntry;
-
-	theNewEntry.iCondition = *aCF;
-	theNewEntry.iServiceGroup = aCFInfo->iServiceGroup;
-	theNewEntry.iStatus= RMobilePhone::ECallForwardingStatusNotActive;
-	theNewEntry.iNumber = aCFInfo->iNumber;
-	
-	if (*aCF ==  RMobilePhone::ECallForwardingNoReply)
-		{	
-		theNewEntry.iTimeout = aCFInfo->iTimeout;
-		}
-	else
-		{
-		theNewEntry.iTimeout = KInvalidTimeout;
-		} 
-
-
-	// retain prev version of the list in local variable and in Cleanup stack
-	CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
-	CleanupStack::PushL(thePrevCFList);
-	
-	const TInt count = iCFList->Enumerate();
-	
-	TBool CFUActive = EFalse;
-	
-	// copy existing data into the temp storage
-	for (TInt indx = 0; indx < count; indx++)
-		{ 	
-		thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
-		
-		RMobilePhone::TMobilePhoneCFInfoEntryV1 copyEntry = iCFList->GetEntryL(indx);
-
-		if(copyEntry.iCondition == RMobilePhone::ECallForwardingUnconditional &&
-		   copyEntry.iStatus == RMobilePhone::ECallForwardingStatusActive)
-			{
-			CFUActive = ETrue;
-			}
-		}
-	
-	delete iCFList;
-	iCFList = NULL;
-	
-	// create a new version and hold it in the class member
-	iCFList = CMobilePhoneCFList::NewL();
-	
-	// get a hold of it in a local variable 
-	CMobilePhoneCFList* theNewCFList = iCFList;
-	
-	TBool callForwardActivated = EFalse;
-		
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 entry;
-	
-	for (TInt i = 0; i < count; i++)
-		{
-		entry = thePrevCFList->GetEntryL(i);
-					
-		if(theNewEntry.iCondition == entry.iCondition)
-			{			
-			if(theNewEntry.iServiceGroup == entry.iServiceGroup)
-				{
-				// only activate service if previously in a not active state
-				if(entry.iStatus == RMobilePhone::ECallForwardingStatusNotActive)
-					{
-					if(entry.iCondition == RMobilePhone::ECallForwardingBusy && CFUActive != EFalse)
-						{
-						// do nothing, condition's service will not be activated as callforwarding
-						// unconditional is active	
-						}
-					else
-						{
-						entry.iStatus = RMobilePhone::ECallForwardingStatusActive;
-						callForwardActivated = ETrue;									
-						}
-					}					
-				}
-			else if(entry.iServiceGroup == RMobilePhone::EAllServices)
-				{
-				if(entry.iStatus == RMobilePhone::ECallForwardingStatusNotActive)
-					{
-					SplitOneCFEntryIntoSeparateGroupsL(theNewCFList,
-													   entry,
-													   theNewEntry.iServiceGroup);
-					
-					callForwardActivated = ETrue;
-					entry = theNewEntry;
-					}				
-				}					
-			}		
-
-		theNewCFList->AddEntryL(entry);				
-		}
-	
-	if(callForwardActivated)
-		{
-		// only need to check quiescent status if an activation has occurred
-		UpdateCFQuiescentConditionL(ETrue, theNewEntry.iCondition);	
-		}
-
-	CleanupStack::PopAndDestroy(thePrevCFList);
-	}
-
-void CSimCallForwarding::RegisterL(RMobilePhone::TMobilePhoneCFCondition* aCF, RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo)
-	{
-	TInt count = iCFList->Enumerate();
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 theNewEntry;
-
-	theNewEntry.iCondition = *aCF;
-	theNewEntry.iServiceGroup = aCFInfo->iServiceGroup;
-	theNewEntry.iStatus= RMobilePhone::ECallForwardingStatusNotActive;
-
-	theNewEntry.iNumber = aCFInfo->iNumber;
-	if (*aCF ==  RMobilePhone::ECallForwardingNoReply)
-		{	
-		theNewEntry.iTimeout = aCFInfo->iTimeout;
-		}
-	else
-		{
-		 theNewEntry.iTimeout = KInvalidTimeout;
-		} 
-
-	// retain prev version of the list in local variable and in Cleanup stack
-	CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
-	CleanupStack::PushL(thePrevCFList);
-	// copy existing data into the temp storage
-	for (TInt indx=0; indx<count; indx++)
-		{ 
-		thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
-		}
-	delete iCFList;
-	iCFList = NULL;
-	// create a new version and hold it in the class member
-	iCFList = CMobilePhoneCFList::NewL();
-	// get a hold of it in a local variable       
-	CMobilePhoneCFList* theNewCFList = iCFList;
-		
-	if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
-		{
-		//nothing for all conds
-		
-		//action is to Regiser (and activate)AllServices with a particular condition;
-		//Only copy entries with a different condition
-		//entries with same condition should not be copied as they will
-		//be represented by 1 with allservices
-		for (TInt i = 0; i<count; i++)
-			{
-			RMobilePhone::TMobilePhoneCFInfoEntryV1 entry = thePrevCFList->GetEntryL(i);
-
-			if (entry.iCondition != theNewEntry.iCondition)
-				// check if the existing entry is encompassed by the new one
-				theNewCFList->AddEntryL(entry);
-			}
-		theNewCFList->AddEntryL(theNewEntry);			
-		}
-	else
-		{
-		//ActivateOne;
-		for (TInt i = 0; i<count; i++)
-			{
-			RMobilePhone::TMobilePhoneCFInfoEntryV1 entry = thePrevCFList->GetEntryL(i);
-
-			if (theNewEntry.iCondition==entry.iCondition
-				&&  entry.iServiceGroup==theNewEntry.iServiceGroup)
-				{
-				theNewCFList->AddEntryL(theNewEntry);
-				continue;
-				}
-			if (entry.iCondition != theNewEntry.iCondition
-				|| (entry.iCondition == theNewEntry.iCondition
-				&& entry.iServiceGroup != theNewEntry.iServiceGroup
-				&& entry.iServiceGroup != RMobilePhone::EAllServices))
-				{
-				theNewCFList->AddEntryL(entry);	
-				continue;
-				}
-				
-			if(theNewEntry.iCondition==entry.iCondition
-				&&  entry.iServiceGroup==RMobilePhone::EAllServices)
-				{
-					
-				SplitOneCFEntryIntoSeparateGroupsL( 
-											theNewCFList,
-											entry,
-											theNewEntry.iServiceGroup
-											);
-					
-				theNewCFList->AddEntryL(theNewEntry);
-				}//end if
-			}//end for
-		}//end else
-	// now delete the old memory
-	CleanupStack::PopAndDestroy(thePrevCFList);
-	}
-
-void CSimCallForwarding::DeactivateL(RMobilePhone::TMobilePhoneCFCondition* aCF, 
-									 RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo )
-	{
-	// NOTE: An assumption is made that the calling method has checked the parameters
-	// are not NULL.
-		
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 theNewEntry;
-
-	theNewEntry.iCondition = *aCF;
-	theNewEntry.iServiceGroup = aCFInfo->iServiceGroup;
-	theNewEntry.iStatus= RMobilePhone::ECallForwardingStatusNotActive;
-		
-	// retain prev version of the list in local variable and in Cleanup stack
-	CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
-	CleanupStack::PushL(thePrevCFList);
-		
-	const TInt count = iCFList->Enumerate();
-
-	// copy existing data into the temp storage
-	for (TInt indx = 0; indx < count; indx++)
-		{ 
-		thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
-		}
-	
-	delete iCFList;
-	iCFList = NULL;
-	
-	// create a new version and hold it in the class member
-	iCFList = CMobilePhoneCFList::NewL();
-	
-	// get a hold of it in a local variable       
-	CMobilePhoneCFList* theNewCFList = iCFList;
-		
-	TBool callForwardDeactivated = EFalse;
-			
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 entry;
-
-	//Deactivate will deactivate active entries 
-	for (TInt indx = 0; indx < count; indx++)
-		{
-		entry = thePrevCFList->GetEntryL(indx);
-				
-		if(entry.iCondition == theNewEntry.iCondition)
-			{
-			if(entry.iServiceGroup == theNewEntry.iServiceGroup)
-				{
-				if(entry.iStatus == RMobilePhone::ECallForwardingStatusActive)
-					{
-				   	entry.iStatus = RMobilePhone::ECallForwardingStatusNotActive;
-					callForwardDeactivated = ETrue;
-					}								
-				}
-			else if(entry.iServiceGroup == RMobilePhone::EAllServices)
-				{
-				if(entry.iStatus == RMobilePhone::ECallForwardingStatusActive)
-					{
-					SplitOneCFEntryIntoSeparateGroupsL(theNewCFList,
-													   entry,
-													   theNewEntry.iServiceGroup);
-										
-					entry = theNewEntry;
-					callForwardDeactivated = ETrue;					
-					}			
-				}			
-			}	
-		
-		theNewCFList->AddEntryL(entry);
-		}//end for
-		
-	// this method will check if any de-activation has caused another Condition to become 
-	// cleared of the quiescent state
-	if(callForwardDeactivated)
-		{		
-		// pass a FALSE to the function to notify of a service de-activation
-		UpdateCFQuiescentConditionL(EFalse, theNewEntry.iCondition);
-		}
-
-	// now delete the old memory	
-	CleanupStack::PopAndDestroy(thePrevCFList);
-	}
-
-void CSimCallForwarding::EraseL(RMobilePhone::TMobilePhoneCFCondition* aCF, 
-								RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo )
-	{
-	// NOTE: An assumption is made that the calling method has checked the parameters
-	// are not NULL.
-	
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 theNewEntry;
-
-	theNewEntry.iCondition = *aCF;
-	theNewEntry.iServiceGroup = aCFInfo->iServiceGroup;
-	theNewEntry.iNumber.iTelNumber.Copy(KEmptyString);
-	theNewEntry.iTimeout = KErrNotFound;
-	theNewEntry.iStatus = RMobilePhone::ECallForwardingStatusNotRegistered;
-	
-	// retain prev version of the list in local variable and in Cleanup stack
-	CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
-	CleanupStack::PushL(thePrevCFList);
-	
-	const TInt count = iCFList->Enumerate();
-
-	// copy existing data into the temp storage
-	for (TInt indx = 0; indx < count; indx++)
-		{ 
-		thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
-		}
-	
-	delete iCFList;
-	iCFList = NULL;
-	
-	// create a new version and hold it in the class member
-	iCFList = CMobilePhoneCFList::NewL();
-	
-	// get a hold of it in a local variable       
-	CMobilePhoneCFList* theNewCFList = iCFList;
-	
-	RMobilePhone::TMobilePhoneCFInfoEntryV1 entry;	
-	
-	for(TInt i = 0; i < count; i++)
-		{
-		entry = thePrevCFList->GetEntryL(i);
-		
-		if(entry.iCondition == theNewEntry.iCondition)
-			{
-			if(entry.iServiceGroup == theNewEntry.iServiceGroup)
-				{
-				if(entry.iStatus == RMobilePhone::ECallForwardingStatusNotActive)
-					{
-				   	entry = theNewEntry;
-					}								
-				}
-			else if(entry.iServiceGroup == RMobilePhone::EAllServices)
-				{
-				if(entry.iStatus == RMobilePhone::ECallForwardingStatusActive)
-					{
-					SplitOneCFEntryIntoSeparateGroupsL(theNewCFList,
-													   entry,
-													   theNewEntry.iServiceGroup);
-										
-					entry = theNewEntry;
-					}			
-				}
-			}
-		theNewCFList->AddEntryL(entry);		
-		}
-
-	// now delete the old memory
-	CleanupStack::PopAndDestroy(thePrevCFList);	
-	}
-	
-const CTestConfigSection* CSimCallForwarding::CfgFile()
-/**
- * Returns a pointer to the current configuration file section.
- *
- * @return CTestConfigSection	A pointer to the current configuration file data section.
- */
-	{
-	return iPhone->CfgFile();
-	}
-
-
+// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implements the functionality required to provide clients with
+// callforwarding status and registration information.
+// 
+//
+
+/**
+ @file
+*/
+
+#include <testconfigfileparser.h>
+#include "CSimCallForwarding.h"
+#include "CSimPhone.h"
+#include "Simlog.h"
+
+const TInt KSettingListGranularity=5;	// < The granularity used for parameter list arrays.
+const TInt KInvalidTimeout = -1;        // Value used when timeout period does not matter
+const TInt KMobServiceIndxStart = 1;
+const TInt KMobServiceIndxEnd   = 6;
+
+CSimCallForwarding* CSimCallForwarding::NewL(CSimPhone* aPhone)
+/**
+ * Standard two-phase constructor.
+ * @param aPhone				The parent phone object.
+ * @return CSimNetworkStatus	The new network status class.
+ */
+	{
+	CSimCallForwarding* self=new(ELeave) CSimCallForwarding(aPhone);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CSimCallForwarding::CSimCallForwarding(CSimPhone* aPhone)
+		: iPhone(aPhone)
+/**
+ * Trivial first phase construction.
+ * @param aPhone				The parent phone object.
+ */
+	{
+	}
+
+void CSimCallForwarding::ConstructL()
+	/** 
+	Second phase of 2-Phase Constructor
+ 	Retrieves all the Call forwarding and Identity services tags from the config file
+	*/
+	{
+	LOGCALL1("Starting to parse Call Forwarding config parameters...");
+
+	iIdentityServiceStatus=new(ELeave) CArrayFixFlat<TIdentityServiceStatus>(KSettingListGranularity);
+	
+	iGetCFStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
+	FindAndCreateCFListL();
+	
+	// Read in the Identity services information
+	TInt count=CfgFile()->ItemCount(KIdentityServiceStatus);
+	const CTestConfigItem* item=NULL;
+	TInt ret=KErrNone;
+	for(TInt i=0;i<count;i++)
+		{
+		item=CfgFile()->Item(KIdentityServiceStatus,i);
+		if(!item)
+			break;
+
+		TInt status, service;
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,service);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("service",ret,0,&KIdentityServiceStatus);
+			continue;
+			}
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,status);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("status",ret,1,&KIdentityServiceStatus);
+			continue;
+			}
+			
+		TIdentityServiceStatus identityServiceStatus;
+		identityServiceStatus.iService = static_cast<RMobilePhone::TMobilePhoneIdService>(service);
+		identityServiceStatus.iStatus = static_cast<RMobilePhone::TMobilePhoneIdServiceStatus>(status);
+		iIdentityServiceStatus->AppendL(identityServiceStatus);
+		}
+		
+	LOGCALL1("...Finished parsing Call Forwarding config parameters...");
+	}
+
+CSimCallForwarding::~CSimCallForwarding()
+	/** 
+	Destroy all the objects constructed.
+	*/
+	{
+	if (iIdentityServiceStatus != NULL)
+		{
+		iIdentityServiceStatus->Delete(0,iIdentityServiceStatus->Count());
+		delete iIdentityServiceStatus;
+		}
+	delete iCFList;
+	if (iGetCFStatus)
+		iGetCFStatus->ResetAndDestroy();
+	delete iGetCFStatus;
+	}
+
+
+TInt CSimCallForwarding::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
+	{
+	/**
+	Handles all the Call forwarding APIs
+	@param aReqHandle to the request
+	@param Ipc unique identifier of the method to call
+	@param aPckg contains arguments of the method to call
+	*/
+	TAny* dataPtr = aPckg.Ptr1();
+	TAny* dataPtr2 = aPckg.Ptr2();
+
+	// The following requests can be completed even if the completion of another request is pending.
+	switch(aIpc)
+		{
+	case EMobilePhoneSetCallForwardingStatus:
+		return SetCallForwardingStatus(aReqHandle,
+			reinterpret_cast<RMobilePhone::TMobilePhoneCFCondition*>(dataPtr),
+			reinterpret_cast<RMobilePhone::TMobilePhoneCFChangeV1*>(dataPtr2));
+	case EMobilePhoneNotifyCallForwardingStatusChange:
+		return NotifyCallForwardingStatusChange(aReqHandle, reinterpret_cast<RMobilePhone::TMobilePhoneCFCondition*>(dataPtr));
+	case EMobilePhoneGetIdentityServiceStatus:
+		return GetIdentityServiceStatus(aReqHandle, 
+			reinterpret_cast<RMobilePhone::TMobilePhoneIdService*>(dataPtr),
+			reinterpret_cast<RMobilePhone::TMobilePhoneIdServiceStatus*>(dataPtr2));
+	case EMobilePhoneGetCallForwardingStatusPhase1:
+		return GetCallForwardingStatusPhase1(aReqHandle, 
+			REINTERPRET_CAST(CRetrieveMobilePhoneCFList::TGetCallForwardingRequest*, dataPtr), 
+			REINTERPRET_CAST(TInt*, dataPtr2));
+	case EMobilePhoneGetCallForwardingStatusPhase2:
+		return GetCallForwardingStatusPhase2(aReqHandle, 
+			REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());			
+	default:
+		break;
+		}
+	return KErrNotSupported;
+	}
+	
+TInt CSimCallForwarding::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
+	/**
+	Cancels Call forwarding requests
+	@param ipc request to cancel
+	@param aReqHandle Handle to the request
+	*/
+	{
+	switch(aIpc)
+		{
+	case EMobilePhoneSetCallForwardingStatus:
+		return SetCallForwardingStatusCancel(aReqHandle);
+	case EMobilePhoneNotifyCallForwardingStatusChange:
+		return NotifyCallForwardingStatusChangeCancel(aReqHandle);
+	case EMobilePhoneGetIdentityServiceStatus:
+		return GetIdentityServiceStatusCancel(aReqHandle);
+	default:
+		break;
+		}
+	return KErrNone;
+	}
+	
+void CSimCallForwarding::FindAndCreateCFListL()
+	{
+	/**
+	Creates the Call forwarding list from the config file
+	*/
+	LOGCALL1("CSimPhone::FindAndCreateCFListL");
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 entry;
+
+	if(iCFList)
+		delete iCFList;
+	iCFList=NULL;
+
+	iCFList = CMobilePhoneCFList::NewL();
+	TInt count=CfgFile()->ItemCount(KCFList);
+	const CTestConfigItem* item=NULL;
+	TInt ret=KErrNone;
+
+	LOGCALL1("Starting to Load and Parse CFList Config parameters");
+	
+	TInt i;
+	for(i=0;i<count;i++)
+		{
+		item=CfgFile()->Item(KCFList,i);
+		if(!item)
+			break;
+		
+		TPtrC8 number;
+		TInt condition, serviceGroup, status, timeout; // valid for CFRNy only
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,condition);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("condition",ret,0,&KCFList);
+			continue;
+			}
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,serviceGroup);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("serviceGroup",ret,1,&KCFList);
+			continue;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,status);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("status",ret,2,&KCFList);
+			continue;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,timeout);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("timeout",ret,3,&KCFList);
+			continue;
+			}
+		
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,number);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("number",ret,4,&KCFList);
+			continue;
+			}
+		
+		entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
+		entry.iNumber.iTelNumber.Copy(number);
+		entry.iTimeout=timeout;
+		entry.iCondition=(RMobilePhone::TMobilePhoneCFCondition)condition;
+		entry.iStatus=(RMobilePhone::TMobilePhoneCFStatus)status;
+		iCFList->AddEntryL(entry);
+		}//end for
+	
+	//CFlist must define entries for each condition even if unknown
+	//fill up table if it misses conditions:
+	
+	RArray<TBool> serviceArray;
+	//voice, auxVoice, data, packet, fax, sms, all;
+
+	CleanupClosePushL(serviceArray);
+
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 extraEntry;
+
+	for (TInt j=1;j<5;j++)//loop conditions
+		{
+		TInt serviceFound=EFalse;
+		TInt index;
+		extraEntry.iCondition=static_cast<RMobilePhone::TMobilePhoneCFCondition>(j);
+		serviceArray.Reset();
+		for(TInt h=0;h<8;h++)
+			{
+			serviceArray.Append(EFalse);
+			}
+		
+		for (TInt k=0;k<count;k++)//loop entries
+			{
+			entry=iCFList->GetEntryL(k);
+			if(entry.iCondition==static_cast<RMobilePhone::TMobilePhoneCFCondition>(j))
+				{
+				index = (TInt)entry.iServiceGroup;
+				serviceArray[index]=ETrue;
+				}
+			}
+		
+		if (!serviceArray[7])//(all services)
+			{
+			for (TInt l=1;l<7;l++)
+				{
+				if (serviceArray[l])
+					serviceFound=ETrue;										
+				}
+			//no service defined for this condition
+			if(!serviceFound)
+				{
+				extraEntry.iServiceGroup=RMobilePhone::EAllServices;
+				extraEntry.iStatus=RMobilePhone::ECallForwardingStatusNotRegistered;
+				iCFList->AddEntryL(extraEntry);
+				}
+			//some services defined in table
+			else
+				{
+				for (TInt m=1;m<7;m++)
+					{
+					if (!serviceArray[m])
+						{
+						extraEntry.iServiceGroup=static_cast<RMobilePhone::TMobileService>(m);
+						extraEntry.iStatus=RMobilePhone::ECallForwardingStatusNotRegistered;
+						iCFList->AddEntryL(extraEntry);
+						}
+					}//end for
+				}//end else
+			}//end if
+		}//end for
+		
+	CleanupStack::PopAndDestroy(&serviceArray);	//Destroying serviceArray to free the memory
+	}
+
+TInt CSimCallForwarding::GetIdentityServiceStatus(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneIdService* aService, RMobilePhone::TMobilePhoneIdServiceStatus* aStatus)
+	/**
+	Gets the status of the identity services
+	@param aReqHandle handle to the request
+	@param aService service that the client is interested in
+	@param aStatus of the identity service
+	*/
+	{
+	RMobilePhone::TMobilePhoneIdServiceStatus status;
+	status = RMobilePhone::EIdServiceUnknown;
+	TInt count = iIdentityServiceStatus->Count();
+	for(TInt i=0; i<count; i++)
+		{
+		if(iIdentityServiceStatus->At(i).iService == *aService)
+			{
+			status = iIdentityServiceStatus->At(i).iStatus;
+			break;
+			}
+		}
+	*aStatus = status;
+	iPhone->ReqCompleted(aReqHandle, KErrNone);
+	return KErrNone;
+	}
+	
+TInt CSimCallForwarding::GetIdentityServiceStatusCancel(const TTsyReqHandle aReqHandle)
+	/**
+	Cancels the request to get the status of the identity services
+	@param aReqHandle hadle to the request
+	*/
+	{
+	iPhone->ReqCompleted(aReqHandle,KErrCancel);
+	return KErrNone;
+	}
+	
+TInt CSimCallForwarding::NotifyCallForwardingStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCFCondition* aCF)
+	/**
+	Requests to be notified of call forwarding status change
+	@param aReqHandle handle to the request
+	@param aCF condition for which the client wants to be notified
+	 */
+	{
+	__ASSERT_ALWAYS(!iCFNotification.iCFChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
+
+	iCFNotification.iCFChangeInfoNotificationPending=ETrue;
+	iCFNotification.iCFChangeInfoReqHandle=aReqHandle;
+	iCFNotification.iCurrentCFCondition=aCF;
+	LOGCALL1("Finished CSimCallForwarding::NotifyCallForwardingStatusChange");
+	return KErrNone;
+	}
+	
+TInt CSimCallForwarding::NotifyCallForwardingStatusChangeCancel(const TTsyReqHandle aReqHandle)
+	/**
+	Cancels the request to be notified of call forwarding status change
+	@param aReqHandle handle to the request
+	*/
+	{
+	if(iCFNotification.iCFChangeInfoNotificationPending)
+		{
+		iCFNotification.iCFChangeInfoNotificationPending=EFalse;
+		iPhone->ReqCompleted(aReqHandle,KErrCancel);
+		}
+	return KErrNone;
+	}
+	
+TInt CSimCallForwarding::SetCallForwardingStatus(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCFCondition* aCF,  RMobilePhone::TMobilePhoneCFChangeV1* aInfo)
+	/**
+	Sets the status of call forwarding
+	@param aReqHandle handle to the request
+	@param aCF condition for which the client wants to set the status
+	@param aInfo value of Call forwarding to set
+	*/
+	{
+	TRAPD(err, UpdateCFListL(aCF,aInfo));
+	if ( err != KErrNone )
+		{ 
+		iPhone->ReqCompleted(aReqHandle,err);
+		return KErrNone;
+		}
+		
+	if(iCFNotification.iCFChangeInfoNotificationPending)
+		{
+		*(iCFNotification.iCurrentCFCondition)=*aCF;
+		iCFNotification.iCFChangeInfoNotificationPending=EFalse;
+		iPhone->ReqCompleted(iCFNotification.iCFChangeInfoReqHandle,KErrNone);
+		}
+	
+	iPhone->ReqCompleted(aReqHandle,err);
+	LOGCALL1("Finished CSimCallForwarding::SetCallForwardingStatus");
+	return KErrNone;
+	}
+	
+TInt CSimCallForwarding::SetCallForwardingStatusCancel(const TTsyReqHandle aReqHandle)
+	/**
+	Cancels the request to set the status of call forwarding
+	@param aReqHandle handle to the request
+	*/
+	{
+	iPhone->ReqCompleted(aReqHandle,KErrCancel);
+	return KErrNone;
+	}
+	
+
+TInt CSimCallForwarding::GetCallForwardingStatusPhase1(const TTsyReqHandle aTsyReqHandle, 
+												 CRetrieveMobilePhoneCFList::TGetCallForwardingRequest* aReqData, 
+												 TInt* aBufSize)
+	{
+	/**
+	1st phase retrieval of the status of call forwarding
+	@param aTsyReqHandle handle to the request
+	@param aReqData contains details of the request
+	@param aBufSize size of the buffer the client needs to allocate for phase 2
+	*/
+	LOGCALL1("CSimPhone::GetCallForwardingStatusPhase1");
+	TInt ret=KErrNone;
+
+    // for forwarding we cannot querry for all conditions;
+    // conditions - specific
+    // services  - individual and all
+	if ((aReqData->iCondition==RMobilePhone::ECallForwardingUnspecified)
+	   || (aReqData->iCondition==RMobilePhone::ECallForwardingAllCases)
+	   || (aReqData->iCondition==RMobilePhone::ECallForwardingAllConditionalCases))
+	   {
+			iPhone->ReqCompleted(aTsyReqHandle,KErrArgument);
+		}
+	else
+		{
+		TInt leaveCode=KErrNone;
+		TRAP(leaveCode, ret=ProcessGetCallForwardingStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
+		if (leaveCode != KErrNone)
+			iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
+		}
+	LOGCALL1("CSimPhone::GetCallForwardingStatusPhase1");
+	return ret;
+	}
+	
+TInt CSimCallForwarding::ProcessGetCallForwardingStatusPhase1L(const TTsyReqHandle aTsyReqHandle, 
+														 CRetrieveMobilePhoneCFList::TGetCallForwardingRequest* aReqData, 
+														 TInt* aBufSize)
+	{
+	/** Retrieve call forwarding status of each line from phone, 
+	store each CF status response as a list entry,
+	stream the list and then return size of this buffer to client
+	@param aReqHandle Handle to the request
+	@param aReqData information about the request
+	@param aBufSize Size of the buffer the client has to allocate for the 2nd pahase
+	*/
+
+	LOGCALL1("CSimPhone::ProcessGetCallForwardingStatusPhase1L");
+
+	CMobilePhoneCFList* list=CMobilePhoneCFList::NewL();
+	CleanupStack::PushL(list);
+	
+	TInt cnt=0;//Only interested by entries with a particular condition
+	TInt maxNum=iCFList->Enumerate();
+	TBool isAllGroups = (aReqData->iServiceGroup == RMobilePhone::EAllServices);
+	for(TInt i=0;i<maxNum;i++)
+		{
+		RMobilePhone::TMobilePhoneCFInfoEntryV1 entry = iCFList->GetEntryL(i);
+		
+		// Check that the data structure is supported by the simulated TSY version
+		TInt err = iPhone->CheckSimTsyVersion(entry);
+		if(err != KErrNone)
+			{
+			iPhone->ReqCompleted(aTsyReqHandle, err);
+			return KErrNone;
+			}
+
+		if((entry.iCondition == aReqData->iCondition) 
+		   &&(entry.iStatus != RMobilePhone::ECallForwardingStatusNotRegistered))
+			{
+			if ( !isAllGroups && (entry.iServiceGroup != aReqData->iServiceGroup))
+				{
+				continue;
+				}
+			list->AddEntryL(entry);
+			cnt++;
+			}	
+		}
+	// Store the streamed list and the client ID
+	CListReadAllAttempt* read=CListReadAllAttempt::NewL(aReqData->iClient,aTsyReqHandle);
+	CleanupStack::PushL(read);
+	
+	read->iListBuf = list->StoreLC();
+	CleanupStack::Pop(); // pop the CBufBase allocated by StoreLC
+	
+	iGetCFStatus->AppendL(read);
+	CleanupStack::Pop(read); // pop the CListReadAllAttempt
+	
+	// return the CBufBase’s size to client
+	*aBufSize=(read->iListBuf)->Size();
+	
+	CleanupStack::PopAndDestroy(list); // pop&destroy list
+	
+	// Complete first phase of list retrieval
+	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+	LOGCALL1("CSimPhone::ProcessGetCallForwardingStatusPhase1L");
+	return KErrNone;	
+	}
+
+TInt CSimCallForwarding::GetCallForwardingStatusPhase2(const TTsyReqHandle aTsyReqHandle, 
+												 RMobilePhone::TClientId* aClient, TDes8* aBuf)
+	/**
+	2nd phase retrieval of the status of call forwarding
+	@param aTsyRqHandle handle to the request
+	@param aClient pointer to the client
+	@param aBuf buffer that contains the call forwarding list
+	*/
+	{
+	LOGCALL1("CSimPhone::GetCallForwardingStatusPhase2");
+	CListReadAllAttempt* read=NULL;
+	// Find the get detected network attempt from this client
+	for (TInt i=0; i<iGetCFStatus->Count(); ++i)
+		{
+		read = iGetCFStatus->At(i);
+		if ((read->iClient.iSessionHandle==aClient->iSessionHandle) &&
+		    (read->iClient.iSubSessionHandle==aClient->iSubSessionHandle))
+			{
+			TPtr8 bufPtr((read->iListBuf)->Ptr(0));
+			// Copy the streamed list to the client
+			aBuf->Copy(bufPtr);
+			delete read;
+			iGetCFStatus->Delete(i);
+			iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+			return KErrNone;
+			}
+		}
+	// Should handle error case of not finding the matching client from read all phase 1
+	LOGCALL1("CSimPhone::GetCallForwardingStatusPhase2");
+	return KErrNotFound;
+	}
+
+
+TInt CSimCallForwarding::GetCallForwardingStatusCancel(const TTsyReqHandle aTsyReqHandle)
+	{
+	/**
+	Cancel the request to retrieve the status of call forwarding
+	@param aTsyReqHandle handle to the request
+	*/
+	LOGCALL1("CSimPhone::GetCallForwardingStatusCancel");
+	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+	// Remove the read all attempt from iGetCFStatus
+	CListReadAllAttempt* read=NULL;
+	for (TInt i=0; i<iGetCFStatus->Count(); ++i)
+		{
+		read = iGetCFStatus->At(i);
+		if (read->iReqHandle == aTsyReqHandle)
+			{
+			delete read;
+			iGetCFStatus->Delete(i);
+			break;
+			}
+		}
+	iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
+	LOGCALL1("CSimPhone::GetCallForwardingStatusCancel");
+	return KErrNone;
+	}
+
+void CSimCallForwarding::UpdateCFListL(RMobilePhone::TMobilePhoneCFCondition* aCF, 
+									   RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo )
+	{		
+	/**
+	Modifies the status of call forwarding
+	@param aCF condition
+	@param aCFInfo details of the request
+	*/
+	User::LeaveIfNull(aCF);
+	User::LeaveIfNull(aCFInfo);
+
+	if (*aCF == RMobilePhone::ECallForwardingUnspecified)
+	    {
+	    // not supported - tell user it is a wrong argument 
+		User::Leave(KErrArgument);
+	    }
+	     
+	if ((*aCF == RMobilePhone::ECallForwardingAllCases)
+		||(*aCF == RMobilePhone::ECallForwardingAllConditionalCases)) 
+	    {
+	    // not supported - tell user it is a wrong argument 
+		User::Leave(KErrNotSupported);
+	    }  
+	       
+	switch (aCFInfo->iAction)
+		{
+		case RMobilePhone::EServiceActionRegister:
+			RegisterL(aCF, aCFInfo);
+			break;
+			
+		case RMobilePhone::EServiceActionActivate:
+			ActivateL(aCF, aCFInfo);
+			break;
+			
+		case RMobilePhone::EServiceActionInvoke:
+		    // currently not supported
+		    // tell user it is a wrong argument 
+			User::Leave(KErrArgument);
+			break;
+			
+		case RMobilePhone::EServiceActionDeactivate:
+			DeactivateL(aCF, aCFInfo);
+			break;
+			
+		case RMobilePhone::EServiceActionErase:
+			EraseL(aCF, aCFInfo);
+			break;
+			
+		case RMobilePhone::EServiceActionUnspecified:
+		default:
+		    // not supported - tell user it is a wrong argument 
+			User::Leave(KErrArgument);
+			break;
+		}
+	}
+	
+
+inline void SplitOneCFEntryIntoSeparateGroupsL(CMobilePhoneCFList* aCFList,
+											   RMobilePhone::TMobilePhoneCFInfoEntryV1& aOrigEntry,
+											   RMobilePhone::TMobileService aExceptServiceGroup)
+	{
+	/*
+	Splits one entry valid for all basic service groups into individual entries 
+	and places them into a CMobilePhoneCFList. This excludes one service group.	 
+	@param aCBList The list to which to store the entries
+	@param aOrigEntry The original entry; details of which should be passed to individual group entries
+	@param aExceptServiceGroup The group which has to be avoided
+	*/
+	// we have to split the entry into entries 
+	// per group with the same condition; excluding the specified service group 
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 anotherEntry(aOrigEntry);
+
+	RMobilePhone::TMobileService service;
+	
+	for (TInt i = KMobServiceIndxStart;i <= KMobServiceIndxEnd;i++)
+		{
+		service=static_cast<RMobilePhone::TMobileService>(i);
+		
+		if( service != aExceptServiceGroup )
+			{
+			anotherEntry.iServiceGroup=service;
+			aCFList->AddEntryL(anotherEntry);
+			}
+		}//end for (another)
+	}
+	
+	
+void CSimCallForwarding::UpdateCFQuiescentConditionL(TBool aActivate, 
+													RMobilePhone::TMobilePhoneCFCondition aCF)
+	{
+	// only the Call Forward Unconditional can alter any other CF condition
+	if(aCF == RMobilePhone::ECallForwardingUnconditional)
+		{		
+		TBool cFBChangeRequired = EFalse;
+		
+		RMobilePhone::TMobilePhoneCFInfoEntryV1 theEntry;
+		
+		const TInt count = iCFList->Enumerate();
+
+		// look for any instances of the ECallForwardingBusy
+		for (TInt indx=0; indx < count; indx++)
+			{ 
+			theEntry = iCFList->GetEntryL(indx);
+			
+			if(theEntry.iCondition == RMobilePhone::ECallForwardingBusy &&
+			  (theEntry.iStatus == RMobilePhone::ECallForwardingStatusActive || 
+			   theEntry.iStatus == RMobilePhone::ECallForwardingStatusQuiescent)) 
+				{
+				cFBChangeRequired = ETrue;
+				}												
+			}
+		
+		if(cFBChangeRequired)
+			{
+			// retain prev version of the list in local variable and in Cleanup stack
+			CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
+			CleanupStack::PushL(thePrevCFList);
+	
+			// copy existing data into the temp storage
+			for (TInt indx=0; indx < count; indx++)
+				{ 
+				thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
+				}
+
+			delete iCFList;
+			iCFList = NULL;
+	
+			// create a new version and hold it in the class member
+			iCFList = CMobilePhoneCFList::NewL();
+	
+			// get a hold of it in a local variable       
+			CMobilePhoneCFList* theNewCFList = iCFList;
+			
+			for(TInt indx=0; indx < count; indx++)
+				{
+				theEntry = thePrevCFList->GetEntryL(indx);
+			
+				if(theEntry.iCondition == RMobilePhone::ECallForwardingBusy)
+					{
+					if(aActivate)
+						{
+						if(theEntry.iStatus == RMobilePhone::ECallForwardingStatusActive)
+							{
+							theEntry.iStatus = RMobilePhone::ECallForwardingStatusQuiescent;
+							}
+						}
+					else
+						{
+						if(theEntry.iStatus == RMobilePhone::ECallForwardingStatusQuiescent)
+							{
+							theEntry.iStatus = RMobilePhone::ECallForwardingStatusActive;
+							}
+						}					
+					}			
+				theNewCFList->AddEntryL(theEntry);
+				}					
+			
+			// now delete the old memory
+			CleanupStack::PopAndDestroy(thePrevCFList);
+			}						
+		}
+	}	
+
+void CSimCallForwarding::ActivateL(RMobilePhone::TMobilePhoneCFCondition* aCF, 
+								   RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo )
+	{
+	// NOTE: An assumption is made that the calling method has checked the parameters
+	// are not NULL.
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 theNewEntry;
+
+	theNewEntry.iCondition = *aCF;
+	theNewEntry.iServiceGroup = aCFInfo->iServiceGroup;
+	theNewEntry.iStatus= RMobilePhone::ECallForwardingStatusNotActive;
+	theNewEntry.iNumber = aCFInfo->iNumber;
+	
+	if (*aCF ==  RMobilePhone::ECallForwardingNoReply)
+		{	
+		theNewEntry.iTimeout = aCFInfo->iTimeout;
+		}
+	else
+		{
+		theNewEntry.iTimeout = KInvalidTimeout;
+		} 
+
+
+	// retain prev version of the list in local variable and in Cleanup stack
+	CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
+	CleanupStack::PushL(thePrevCFList);
+	
+	const TInt count = iCFList->Enumerate();
+	
+	TBool CFUActive = EFalse;
+	
+	// copy existing data into the temp storage
+	for (TInt indx = 0; indx < count; indx++)
+		{ 	
+		thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
+		
+		RMobilePhone::TMobilePhoneCFInfoEntryV1 copyEntry = iCFList->GetEntryL(indx);
+
+		if(copyEntry.iCondition == RMobilePhone::ECallForwardingUnconditional &&
+		   copyEntry.iStatus == RMobilePhone::ECallForwardingStatusActive)
+			{
+			CFUActive = ETrue;
+			}
+		}
+	
+	delete iCFList;
+	iCFList = NULL;
+	
+	// create a new version and hold it in the class member
+	iCFList = CMobilePhoneCFList::NewL();
+	
+	// get a hold of it in a local variable 
+	CMobilePhoneCFList* theNewCFList = iCFList;
+	
+	TBool callForwardActivated = EFalse;
+		
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 entry;
+	
+	for (TInt i = 0; i < count; i++)
+		{
+		entry = thePrevCFList->GetEntryL(i);
+					
+		if(theNewEntry.iCondition == entry.iCondition)
+			{			
+			if(theNewEntry.iServiceGroup == entry.iServiceGroup)
+				{
+				// only activate service if previously in a not active state
+				if(entry.iStatus == RMobilePhone::ECallForwardingStatusNotActive)
+					{
+					if(entry.iCondition == RMobilePhone::ECallForwardingBusy && CFUActive != EFalse)
+						{
+						// do nothing, condition's service will not be activated as callforwarding
+						// unconditional is active	
+						}
+					else
+						{
+						entry.iStatus = RMobilePhone::ECallForwardingStatusActive;
+						callForwardActivated = ETrue;									
+						}
+					}					
+				}
+			else if(entry.iServiceGroup == RMobilePhone::EAllServices)
+				{
+				if(entry.iStatus == RMobilePhone::ECallForwardingStatusNotActive)
+					{
+					SplitOneCFEntryIntoSeparateGroupsL(theNewCFList,
+													   entry,
+													   theNewEntry.iServiceGroup);
+					
+					callForwardActivated = ETrue;
+					entry = theNewEntry;
+					}				
+				}					
+			}		
+
+		theNewCFList->AddEntryL(entry);				
+		}
+	
+	if(callForwardActivated)
+		{
+		// only need to check quiescent status if an activation has occurred
+		UpdateCFQuiescentConditionL(ETrue, theNewEntry.iCondition);	
+		}
+
+	CleanupStack::PopAndDestroy(thePrevCFList);
+	}
+
+void CSimCallForwarding::RegisterL(RMobilePhone::TMobilePhoneCFCondition* aCF, RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo)
+	{
+	TInt count = iCFList->Enumerate();
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 theNewEntry;
+
+	theNewEntry.iCondition = *aCF;
+	theNewEntry.iServiceGroup = aCFInfo->iServiceGroup;
+	theNewEntry.iStatus= RMobilePhone::ECallForwardingStatusNotActive;
+
+	theNewEntry.iNumber = aCFInfo->iNumber;
+	if (*aCF ==  RMobilePhone::ECallForwardingNoReply)
+		{	
+		theNewEntry.iTimeout = aCFInfo->iTimeout;
+		}
+	else
+		{
+		 theNewEntry.iTimeout = KInvalidTimeout;
+		} 
+
+	// retain prev version of the list in local variable and in Cleanup stack
+	CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
+	CleanupStack::PushL(thePrevCFList);
+	// copy existing data into the temp storage
+	for (TInt indx=0; indx<count; indx++)
+		{ 
+		thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
+		}
+	delete iCFList;
+	iCFList = NULL;
+	// create a new version and hold it in the class member
+	iCFList = CMobilePhoneCFList::NewL();
+	// get a hold of it in a local variable       
+	CMobilePhoneCFList* theNewCFList = iCFList;
+		
+	if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
+		{
+		//nothing for all conds
+		
+		//action is to Regiser (and activate)AllServices with a particular condition;
+		//Only copy entries with a different condition
+		//entries with same condition should not be copied as they will
+		//be represented by 1 with allservices
+		for (TInt i = 0; i<count; i++)
+			{
+			RMobilePhone::TMobilePhoneCFInfoEntryV1 entry = thePrevCFList->GetEntryL(i);
+
+			if (entry.iCondition != theNewEntry.iCondition)
+				// check if the existing entry is encompassed by the new one
+				theNewCFList->AddEntryL(entry);
+			}
+		theNewCFList->AddEntryL(theNewEntry);			
+		}
+	else
+		{
+		//ActivateOne;
+		for (TInt i = 0; i<count; i++)
+			{
+			RMobilePhone::TMobilePhoneCFInfoEntryV1 entry = thePrevCFList->GetEntryL(i);
+
+			if (theNewEntry.iCondition==entry.iCondition
+				&&  entry.iServiceGroup==theNewEntry.iServiceGroup)
+				{
+				theNewCFList->AddEntryL(theNewEntry);
+				continue;
+				}
+			if (entry.iCondition != theNewEntry.iCondition
+				|| (entry.iCondition == theNewEntry.iCondition
+				&& entry.iServiceGroup != theNewEntry.iServiceGroup
+				&& entry.iServiceGroup != RMobilePhone::EAllServices))
+				{
+				theNewCFList->AddEntryL(entry);	
+				continue;
+				}
+				
+			if(theNewEntry.iCondition==entry.iCondition
+				&&  entry.iServiceGroup==RMobilePhone::EAllServices)
+				{
+					
+				SplitOneCFEntryIntoSeparateGroupsL( 
+											theNewCFList,
+											entry,
+											theNewEntry.iServiceGroup
+											);
+					
+				theNewCFList->AddEntryL(theNewEntry);
+				}//end if
+			}//end for
+		}//end else
+	// now delete the old memory
+	CleanupStack::PopAndDestroy(thePrevCFList);
+	}
+
+void CSimCallForwarding::DeactivateL(RMobilePhone::TMobilePhoneCFCondition* aCF, 
+									 RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo )
+	{
+	// NOTE: An assumption is made that the calling method has checked the parameters
+	// are not NULL.
+		
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 theNewEntry;
+
+	theNewEntry.iCondition = *aCF;
+	theNewEntry.iServiceGroup = aCFInfo->iServiceGroup;
+	theNewEntry.iStatus= RMobilePhone::ECallForwardingStatusNotActive;
+		
+	// retain prev version of the list in local variable and in Cleanup stack
+	CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
+	CleanupStack::PushL(thePrevCFList);
+		
+	const TInt count = iCFList->Enumerate();
+
+	// copy existing data into the temp storage
+	for (TInt indx = 0; indx < count; indx++)
+		{ 
+		thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
+		}
+	
+	delete iCFList;
+	iCFList = NULL;
+	
+	// create a new version and hold it in the class member
+	iCFList = CMobilePhoneCFList::NewL();
+	
+	// get a hold of it in a local variable       
+	CMobilePhoneCFList* theNewCFList = iCFList;
+		
+	TBool callForwardDeactivated = EFalse;
+			
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 entry;
+
+	//Deactivate will deactivate active entries 
+	for (TInt indx = 0; indx < count; indx++)
+		{
+		entry = thePrevCFList->GetEntryL(indx);
+				
+		if(entry.iCondition == theNewEntry.iCondition)
+			{
+			if(entry.iServiceGroup == theNewEntry.iServiceGroup)
+				{
+				if(entry.iStatus == RMobilePhone::ECallForwardingStatusActive)
+					{
+				   	entry.iStatus = RMobilePhone::ECallForwardingStatusNotActive;
+					callForwardDeactivated = ETrue;
+					}								
+				}
+			else if(entry.iServiceGroup == RMobilePhone::EAllServices)
+				{
+				if(entry.iStatus == RMobilePhone::ECallForwardingStatusActive)
+					{
+					SplitOneCFEntryIntoSeparateGroupsL(theNewCFList,
+													   entry,
+													   theNewEntry.iServiceGroup);
+										
+					entry = theNewEntry;
+					callForwardDeactivated = ETrue;					
+					}			
+				}			
+			}	
+		
+		theNewCFList->AddEntryL(entry);
+		}//end for
+		
+	// this method will check if any de-activation has caused another Condition to become 
+	// cleared of the quiescent state
+	if(callForwardDeactivated)
+		{		
+		// pass a FALSE to the function to notify of a service de-activation
+		UpdateCFQuiescentConditionL(EFalse, theNewEntry.iCondition);
+		}
+
+	// now delete the old memory	
+	CleanupStack::PopAndDestroy(thePrevCFList);
+	}
+
+void CSimCallForwarding::EraseL(RMobilePhone::TMobilePhoneCFCondition* aCF, 
+								RMobilePhone::TMobilePhoneCFChangeV1* aCFInfo )
+	{
+	// NOTE: An assumption is made that the calling method has checked the parameters
+	// are not NULL.
+	
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 theNewEntry;
+
+	theNewEntry.iCondition = *aCF;
+	theNewEntry.iServiceGroup = aCFInfo->iServiceGroup;
+	theNewEntry.iNumber.iTelNumber.Copy(KEmptyString);
+	theNewEntry.iTimeout = KErrNotFound;
+	theNewEntry.iStatus = RMobilePhone::ECallForwardingStatusNotRegistered;
+	
+	// retain prev version of the list in local variable and in Cleanup stack
+	CMobilePhoneCFList* thePrevCFList = CMobilePhoneCFList::NewL();
+	CleanupStack::PushL(thePrevCFList);
+	
+	const TInt count = iCFList->Enumerate();
+
+	// copy existing data into the temp storage
+	for (TInt indx = 0; indx < count; indx++)
+		{ 
+		thePrevCFList->AddEntryL(iCFList->GetEntryL(indx));
+		}
+	
+	delete iCFList;
+	iCFList = NULL;
+	
+	// create a new version and hold it in the class member
+	iCFList = CMobilePhoneCFList::NewL();
+	
+	// get a hold of it in a local variable       
+	CMobilePhoneCFList* theNewCFList = iCFList;
+	
+	RMobilePhone::TMobilePhoneCFInfoEntryV1 entry;	
+	
+	for(TInt i = 0; i < count; i++)
+		{
+		entry = thePrevCFList->GetEntryL(i);
+		
+		if(entry.iCondition == theNewEntry.iCondition)
+			{
+			if(entry.iServiceGroup == theNewEntry.iServiceGroup)
+				{
+				if(entry.iStatus == RMobilePhone::ECallForwardingStatusNotActive)
+					{
+				   	entry = theNewEntry;
+					}								
+				}
+			else if(entry.iServiceGroup == RMobilePhone::EAllServices)
+				{
+				if(entry.iStatus == RMobilePhone::ECallForwardingStatusActive)
+					{
+					SplitOneCFEntryIntoSeparateGroupsL(theNewCFList,
+													   entry,
+													   theNewEntry.iServiceGroup);
+										
+					entry = theNewEntry;
+					}			
+				}
+			}
+		theNewCFList->AddEntryL(entry);		
+		}
+
+	// now delete the old memory
+	CleanupStack::PopAndDestroy(thePrevCFList);	
+	}
+	
+const CTestConfigSection* CSimCallForwarding::CfgFile()
+/**
+ * Returns a pointer to the current configuration file section.
+ *
+ * @return CTestConfigSection	A pointer to the current configuration file data section.
+ */
+	{
+	return iPhone->CfgFile();
+	}
+
+