telephonyserverplugins/simtsy/src/CSimCallWaiting.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
--- a/telephonyserverplugins/simtsy/src/CSimCallWaiting.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/CSimCallWaiting.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,553 +1,553 @@
-// 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
-// CallWaiting status and registration information.
-// 
-//
-
-/**
- @file
-*/
-
-#include <testconfigfileparser.h>
-#include "CSimCallWaiting.h"
-#include "CSimPhone.h"
-#include "Simlog.h"
-
-const TInt KMobServiceIndxStart = 1;
-const TInt KMobServiceIndxEnd   = 5;
-
-
-CSimCallWaiting* CSimCallWaiting::NewL(CSimPhone* aPhone)
-/**
- * Standard two-phase constructor.
- * @param aPhone				The parent phone object.
- * @return CSimCallWaiting		The new call waiting class.
- */
-	{
-	CSimCallWaiting* self=new(ELeave) CSimCallWaiting(aPhone);
-	CleanupStack::PushL(self);
-	self->ConstructL();
-	CleanupStack::Pop();
-	return self;
-	}
-
-CSimCallWaiting::CSimCallWaiting(CSimPhone* aPhone)
-		: iPhone(aPhone)
-/**
- * Trivial first phase construction.
- * @param aPhone				The parent phone object.
- */
-	{
-	}
-
-void CSimCallWaiting::ConstructL()
-/**
-	Second phase of 2-Phase Constructor
-  	Retrieves all the Call waiting related tags from the config file
-*/
-	{
-	LOGCALL1("Starting to parse Call waiting config parameters...");
-
-	iGetCWStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
-	FindAndCreateCWListL();
-	LOGCALL1("...Finished parsing Call waiting config parameters...");
-	}
-	
-void CSimCallWaiting::FindAndCreateCWListL()
-{
-/**
-  	Retrieves all the Call waiting tags that define the 
-  	original status of Call waiting from the config file
-*/
-	LOGCALL1("CSimPhone::FindAndCreateCWListL");
-	RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
-
-	iCWList = CMobilePhoneCWList::NewL();
-	TInt count=CfgFile()->ItemCount(KCWList);
-	const CTestConfigItem* item=NULL;
-	TInt ret=KErrNone;
-
-	LOGCALL1("Starting to Load and Parse CWList Config parameters");
-	TInt i;
-	for(i=0;i<count;i++)
-		{
-		item=CfgFile()->Item(KCWList,i);
-		if(!item)
-			break;
-		
-		TInt serviceGroup, status;
-		
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,serviceGroup);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("serviceGroup",ret,0,&KCWList);
-			continue;
-			}
-
-		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,status);
-		if(ret!=KErrNone)
-			{
-			LOGPARSERR("status",ret,1,&KCWList);
-			continue;
-			}
-		
-		entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
-		entry.iStatus=(RMobilePhone::TMobilePhoneCWStatus)status;
-
-		iCWList->AddEntryL(entry);
-		}
-	}
-
-CSimCallWaiting::~CSimCallWaiting()
-	{
-	delete iCWList;
-	if (iGetCWStatus)
-		iGetCWStatus->ResetAndDestroy();
-	delete iGetCWStatus;
-	}
-
-TInt CSimCallWaiting::ExtFuncL(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
-	{
-	/**
-  	Handles the phone based requests that apply to call waiting
-  	@param aReqHandle Handle to the request
-  	@param aIpc request identifier
-  	@param aPckg contains additional information for the requests
-	*/
-
-	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 EMobilePhoneSetCallWaitingStatus:
-		return SetCallWaitingStatusL(aReqHandle,
-			REINTERPRET_CAST(RMobilePhone::TMobileService*, dataPtr),
-			REINTERPRET_CAST(RMobilePhone::TMobilePhoneServiceAction*,dataPtr2));
-	case EMobilePhoneNotifyCallWaitingStatusChange:
-		return NotifyCallWaitingStatusChange(aReqHandle, REINTERPRET_CAST(RMobilePhone::TMobilePhoneCWInfoEntryV1*, dataPtr));
-	case EMobilePhoneGetWaitingStatusPhase1:
-		return GetCallWaitingStatusPhase1(aReqHandle, 
-			REINTERPRET_CAST(CRetrieveMobilePhoneCWList::TGetCallWaitingRequest*, dataPtr), 
-			REINTERPRET_CAST(TInt*, dataPtr2));
-	case EMobilePhoneGetWaitingStatusPhase2:
-		return GetCallWaitingStatusPhase2(aReqHandle, 
-			REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());		
-	default:
-		break;
-		}
-	return KErrNotSupported;
-	}
-	
-TInt CSimCallWaiting::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
-	{
-	/**
-  	Cancels any phone based request regarding call waiting
-  	@param aIpc the IPC to cancel
-  	@param aReqHandle handle to the request
-	*/
-	switch(aIpc)
-		{
-	case EMobilePhoneSetCallWaitingStatus:
-		return SetCallWaitingStatusCancel(aReqHandle);
-	case EMobilePhoneNotifyCallWaitingStatusChange:
-		return NotifyCallWaitingStatusChangeCancel(aReqHandle);
-	default:
-		break;
-		}
-	return KErrNone;
-	}
-
-TInt CSimCallWaiting::NotifyCallWaitingStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCWInfoEntryV1* aCW)
-	{	
-	/**
-	Requests to be notified of change in the Call Waiting status
-	@param aReqHandle Handle to the request
-	@param aCW contains the service group and new status that has changed
-  	*/
-	__ASSERT_ALWAYS(!iCWNotification.iCWChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
-	iCWNotification.iCWChangeInfoNotificationPending=ETrue;
-	iCWNotification.iCWChangeInfoReqHandle=aReqHandle;
-	iCWNotification.iCWInfo=aCW;
-	LOGCALL1("Finished CSimCallWaiting::NotifyCallWaitingStatusChange");
-	return KErrNone;
-	}
-
-TInt CSimCallWaiting::NotifyCallWaitingStatusChangeCancel(const TTsyReqHandle aReqHandle)
-	{
-	/**
-	Cancels request to be notified of call Waiting status change
-	@param aReqHandle Handle to the request
-	*/
-	if(iCWNotification.iCWChangeInfoNotificationPending)
-		{
-		iCWNotification.iCWChangeInfoNotificationPending=EFalse;
-		iPhone->ReqCompleted(aReqHandle,KErrCancel);
-		}
-	return KErrNone;
-	}
-	
-TInt CSimCallWaiting::SetCallWaitingStatusL(const TTsyReqHandle aReqHandle, RMobilePhone::TMobileService* aService,  RMobilePhone::TMobilePhoneServiceAction* aAction)
-	{
-	/**
-	Sets the status for call Waiting
-	@param aReqHandle Handle to the request
-	@param aCB condition for which the client whishes to set the call Waiting status
-	@param aInfo additional parameters to set the call Waiting status
-  	*/
-	
-	// make sure we know that the operation concluded sucessfully
-	TRAPD(ret,UpdateCWListL(aService,aAction)); 	
-	if ( ret != KErrNone )
-		{ 
-		iPhone->ReqCompleted(aReqHandle,ret);
-		}
-		
-	// otherwise proceed and notify all went well
-	// Notify change
-	if (iCWNotification.iCWChangeInfoNotificationPending)
-		{
-		
-		(iCWNotification.iCWInfo->iServiceGroup)=*aService;
-				
-		switch (*aAction)
-			{
-			case RMobilePhone::EServiceActionRegister:
-			case RMobilePhone::EServiceActionActivate:
-				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusActive;
-				break;
-			case RMobilePhone::EServiceActionDeactivate:
-			case RMobilePhone::EServiceActionErase:
-				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusNotActive;
-				break;
-			case RMobilePhone::EServiceActionUnspecified:
-			default:
-				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusUnknown;
-				// no sense doing any further operation - leave
-				User::Leave( KErrArgument );
-				break;
-			}
-		
-		iCWNotification.iCWChangeInfoNotificationPending=EFalse;
-		iPhone->ReqCompleted(iCWNotification.iCWChangeInfoReqHandle,KErrNone);
-		}
-		
-	iPhone->ReqCompleted(aReqHandle,KErrNone);
-		
-	return KErrNone;
-	}
-
-TInt CSimCallWaiting::SetCallWaitingStatusCancel(const TTsyReqHandle aReqHandle)
-	{
-	/**
-	Cancels the request to sets the status for call waiting
-	@param aReqHandle Handle to the request
-  	*/
-	 
-	iPhone->ReqCompleted(aReqHandle,KErrCancel);
-	return KErrNone;
-	}
-	
-	
-	
-const CTestConfigSection* CSimCallWaiting::CfgFile()
-/**
- * Returns a pointer to the current configuration file section.
- *
- * @return CTestConfigSection	A pointer to the current configuration file data section.
- */
-	{
-	return iPhone->CfgFile();
-	}
-
-TInt CSimCallWaiting::GetCallWaitingStatusPhase1(const TTsyReqHandle aTsyReqHandle, 
-												 CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData, 
-												 TInt* aBufSize)
-	{
-	/**
-	1st phase retrieval of the the call waiting status list
-	@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("CSimCallWaiting::GetCalWaitingStatusPhase1");
-	
-	TInt ret=KErrNone;
-	TInt leaveCode=KErrNone;
-	TRAP(leaveCode, ret=ProcessGetCallWaitingStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
-	if (leaveCode != KErrNone)
-			iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
-
-	LOGCALL1("CSimCallWaiting::GetCalWaitingStatusPhase1");
-	return ret;
-	}
-	
-TInt CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L(const TTsyReqHandle aTsyReqHandle, 
-														 CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData, 
-														 TInt* aBufSize)
-	{
-	/** Retrieve call waiting status of each line from phone, 
-	store each CB 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("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
-
-	CMobilePhoneCWList* list=CMobilePhoneCWList::NewL();
-	CleanupStack::PushL(list);
-		
-	TInt maxNum=iCWList->Enumerate();
-	//if testing all CB are non-active
-	// then we have to return a single entry EAllServices
-	if ( maxNum )
-		{
-		for(TInt i=0;i<maxNum;i++)
-			{
-			list->AddEntryL(iCWList->GetEntryL(i));
-			}
-		}
-	else
-		{
-		// if the list is empty and the querry general then we have to return general info
-		RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
-		
-		// 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;
-			}
-
-		entry.iServiceGroup	= RMobilePhone::EAllServices;
-		entry.iStatus		= RMobilePhone::ECallWaitingStatusNotActive;
-		list->AddEntryL( entry );
-		}
-
-	// 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
-	
-	iGetCWStatus->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("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
-	return KErrNone;
-	}
-
-TInt CSimCallWaiting::GetCallWaitingStatusPhase2(const TTsyReqHandle aTsyReqHandle, 
-												 RMobilePhone::TClientId* aClient, TDes8* aBuf)
-	{
-	/**
-	2nd phase retrieval of the the call waiting status list
-	@param aReqHandle Handle to the request
-	@param aClient Ponter to the client
-	@param aBuf Buffer containiong the call waiting status list
-	*/
-	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
-	CListReadAllAttempt* read=NULL;
-	// Find the get detected network attempt from this client
-	for (TInt i=0; i<iGetCWStatus->Count(); ++i)
-		{
-		read = iGetCWStatus->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;
-			iGetCWStatus->Delete(i);
-			iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
-			return KErrNone;
-			}
-		}
-	// Should handle error case of not finding the matching client from read all phase 1
-	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
-	return KErrNotFound;
-	}
-
-TInt CSimCallWaiting::GetCallWaitingStatusCancel(const TTsyReqHandle aTsyReqHandle)
-	{
-	/*
-	Cancels a Request to retrieve the call waiting status list
-	@param aReqHandle Handle to the request
-	*/
-	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
-	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
-	// Remove the read all attempt from iGetCBStatus
-	CListReadAllAttempt* read=NULL;
-	for (TInt i=0; i<iGetCWStatus->Count(); ++i)
-		{
-		read = iGetCWStatus->At(i);
-		if (read->iReqHandle == aTsyReqHandle)
-			{
-			delete read;
-			iGetCWStatus->Delete(i);
-			break;
-			}
-		}
-	iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
-	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
-	return KErrNone;
-	}
-	
-inline void SplitOneEntryIntoSeparateGroupsL( 
-								CMobilePhoneCWList* aCWList,
-								RMobilePhone::TMobilePhoneCWInfoEntryV1 aOrigEntry,
-								RMobilePhone::TMobileService aExceptServiceGroup
-									)
-	{
-	/*
-	Splits one entry valid for all basic service groups into individual entries 
-	and places them into a CMobilePhoneCBList. 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::TMobilePhoneCWInfoEntryV1 anotherEntry = aOrigEntry;
-
-	//anotherEntry.iCondition = aOrigEntry.iCondition;
-	//anotherEntry.iStatus = RMobilePhone::ECallBarringStatusActive;
-	RMobilePhone::TMobileService service;
-	
-	for (TInt i=KMobServiceIndxStart; i<=KMobServiceIndxEnd;i++)
-		{
-		service=static_cast<RMobilePhone::TMobileService>(i);
-		if( service != aExceptServiceGroup )
-			{
-			anotherEntry.iServiceGroup=service;
-			aCWList->AddEntryL(anotherEntry);
-			}
-		}//end for (another)
-	}
-	
-void CSimCallWaiting::UpdateCWListL(RMobilePhone::TMobileService* aServiceGroup, RMobilePhone::TMobilePhoneServiceAction* aAction )
-	{
-	/*
-	Updates the status of call waiting.
-	@param aServiceGroup service group to set
-	@param aAction ation to be performed 
-	*/
-	
-	// no sense processing if either condition or change info are NULLS 
-	User::LeaveIfNull(aServiceGroup);
-	User::LeaveIfNull(aAction);
-    
-	
-	//Lets do some work then
-	RMobilePhone::TMobilePhoneCWInfoEntryV1 theNewEntry;
-
-	theNewEntry.iServiceGroup = *aServiceGroup;
-	
-	switch (*aAction)
-		{
-		case RMobilePhone::EServiceActionRegister:
-		case RMobilePhone::EServiceActionActivate:
-			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusActive;
-			break;
-		case RMobilePhone::EServiceActionDeactivate:
-		case RMobilePhone::EServiceActionErase:
-			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusNotActive;
-			break;
-		case RMobilePhone::EServiceActionUnspecified:
-		default:
-			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusUnknown;
-			// no sense doing any further operation - leave
-			User::Leave( KErrArgument );
-			break;
-		}
-		
-	// retain prev version of the list in local variable and in Cleanup stack
-	CMobilePhoneCWList* thePrevCWList = CMobilePhoneCWList::NewL();
-	CleanupStack::PushL(thePrevCWList);
-	// copy existing data into the temp storage
-	for (TInt indx=0; indx<iCWList->Enumerate(); indx++)
-		{ 
-		thePrevCWList->AddEntryL(iCWList->GetEntryL(indx));
-		}
-	delete iCWList;
-	iCWList = NULL;
-	
-	// create a new version and hold it in the class member
-	iCWList = CMobilePhoneCWList::NewL();
-	// get a hold of it in a local variable       
-	CMobilePhoneCWList* theNewCWList = iCWList;
-	RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
-
-	TInt count = thePrevCWList->Enumerate();
-	
-	if (theNewEntry.iStatus == RMobilePhone::ECallWaitingStatusActive)
-		{
-		if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
-			{
-			theNewCWList->AddEntryL(theNewEntry);
-			}
-		else
-			{
-			for (TInt i = 0; i<count; i++)
-				{
-				entry = thePrevCWList->GetEntryL(i);
-				if(entry.iServiceGroup!=theNewEntry.iServiceGroup
-					&& entry.iServiceGroup!=RMobilePhone::EAllServices)
-					theNewCWList->AddEntryL(entry);
-				}
-			theNewCWList->AddEntryL(theNewEntry);
-			}
-		}
-	else //deactivate
-		{
-		if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
-			{
-			theNewCWList->AddEntryL(theNewEntry);
-			}
-		else
-			{
-			for (TInt i = 0; i<count; i++)
-				{
-				entry = thePrevCWList->GetEntryL(i);
-				if(entry.iServiceGroup==RMobilePhone::EAllServices)
-					{
-					//add to the list active entries for all servive groups but the one to be deactivated
-					SplitOneEntryIntoSeparateGroupsL(theNewCWList,entry, theNewEntry.iServiceGroup);
-					continue;
-					}
-				if(entry.iServiceGroup!=theNewEntry.iServiceGroup)
-					{
-					theNewCWList->AddEntryL(entry);
-					}
-				}				
-			}
-			
-		}
-	// now delete the old memory	
-	CleanupStack::PopAndDestroy(thePrevCWList);	
-	}
-
+// 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
+// CallWaiting status and registration information.
+// 
+//
+
+/**
+ @file
+*/
+
+#include <testconfigfileparser.h>
+#include "CSimCallWaiting.h"
+#include "CSimPhone.h"
+#include "Simlog.h"
+
+const TInt KMobServiceIndxStart = 1;
+const TInt KMobServiceIndxEnd   = 5;
+
+
+CSimCallWaiting* CSimCallWaiting::NewL(CSimPhone* aPhone)
+/**
+ * Standard two-phase constructor.
+ * @param aPhone				The parent phone object.
+ * @return CSimCallWaiting		The new call waiting class.
+ */
+	{
+	CSimCallWaiting* self=new(ELeave) CSimCallWaiting(aPhone);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CSimCallWaiting::CSimCallWaiting(CSimPhone* aPhone)
+		: iPhone(aPhone)
+/**
+ * Trivial first phase construction.
+ * @param aPhone				The parent phone object.
+ */
+	{
+	}
+
+void CSimCallWaiting::ConstructL()
+/**
+	Second phase of 2-Phase Constructor
+  	Retrieves all the Call waiting related tags from the config file
+*/
+	{
+	LOGCALL1("Starting to parse Call waiting config parameters...");
+
+	iGetCWStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
+	FindAndCreateCWListL();
+	LOGCALL1("...Finished parsing Call waiting config parameters...");
+	}
+	
+void CSimCallWaiting::FindAndCreateCWListL()
+{
+/**
+  	Retrieves all the Call waiting tags that define the 
+  	original status of Call waiting from the config file
+*/
+	LOGCALL1("CSimPhone::FindAndCreateCWListL");
+	RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
+
+	iCWList = CMobilePhoneCWList::NewL();
+	TInt count=CfgFile()->ItemCount(KCWList);
+	const CTestConfigItem* item=NULL;
+	TInt ret=KErrNone;
+
+	LOGCALL1("Starting to Load and Parse CWList Config parameters");
+	TInt i;
+	for(i=0;i<count;i++)
+		{
+		item=CfgFile()->Item(KCWList,i);
+		if(!item)
+			break;
+		
+		TInt serviceGroup, status;
+		
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,serviceGroup);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("serviceGroup",ret,0,&KCWList);
+			continue;
+			}
+
+		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,status);
+		if(ret!=KErrNone)
+			{
+			LOGPARSERR("status",ret,1,&KCWList);
+			continue;
+			}
+		
+		entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
+		entry.iStatus=(RMobilePhone::TMobilePhoneCWStatus)status;
+
+		iCWList->AddEntryL(entry);
+		}
+	}
+
+CSimCallWaiting::~CSimCallWaiting()
+	{
+	delete iCWList;
+	if (iGetCWStatus)
+		iGetCWStatus->ResetAndDestroy();
+	delete iGetCWStatus;
+	}
+
+TInt CSimCallWaiting::ExtFuncL(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
+	{
+	/**
+  	Handles the phone based requests that apply to call waiting
+  	@param aReqHandle Handle to the request
+  	@param aIpc request identifier
+  	@param aPckg contains additional information for the requests
+	*/
+
+	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 EMobilePhoneSetCallWaitingStatus:
+		return SetCallWaitingStatusL(aReqHandle,
+			REINTERPRET_CAST(RMobilePhone::TMobileService*, dataPtr),
+			REINTERPRET_CAST(RMobilePhone::TMobilePhoneServiceAction*,dataPtr2));
+	case EMobilePhoneNotifyCallWaitingStatusChange:
+		return NotifyCallWaitingStatusChange(aReqHandle, REINTERPRET_CAST(RMobilePhone::TMobilePhoneCWInfoEntryV1*, dataPtr));
+	case EMobilePhoneGetWaitingStatusPhase1:
+		return GetCallWaitingStatusPhase1(aReqHandle, 
+			REINTERPRET_CAST(CRetrieveMobilePhoneCWList::TGetCallWaitingRequest*, dataPtr), 
+			REINTERPRET_CAST(TInt*, dataPtr2));
+	case EMobilePhoneGetWaitingStatusPhase2:
+		return GetCallWaitingStatusPhase2(aReqHandle, 
+			REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());		
+	default:
+		break;
+		}
+	return KErrNotSupported;
+	}
+	
+TInt CSimCallWaiting::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
+	{
+	/**
+  	Cancels any phone based request regarding call waiting
+  	@param aIpc the IPC to cancel
+  	@param aReqHandle handle to the request
+	*/
+	switch(aIpc)
+		{
+	case EMobilePhoneSetCallWaitingStatus:
+		return SetCallWaitingStatusCancel(aReqHandle);
+	case EMobilePhoneNotifyCallWaitingStatusChange:
+		return NotifyCallWaitingStatusChangeCancel(aReqHandle);
+	default:
+		break;
+		}
+	return KErrNone;
+	}
+
+TInt CSimCallWaiting::NotifyCallWaitingStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCWInfoEntryV1* aCW)
+	{	
+	/**
+	Requests to be notified of change in the Call Waiting status
+	@param aReqHandle Handle to the request
+	@param aCW contains the service group and new status that has changed
+  	*/
+	__ASSERT_ALWAYS(!iCWNotification.iCWChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
+	iCWNotification.iCWChangeInfoNotificationPending=ETrue;
+	iCWNotification.iCWChangeInfoReqHandle=aReqHandle;
+	iCWNotification.iCWInfo=aCW;
+	LOGCALL1("Finished CSimCallWaiting::NotifyCallWaitingStatusChange");
+	return KErrNone;
+	}
+
+TInt CSimCallWaiting::NotifyCallWaitingStatusChangeCancel(const TTsyReqHandle aReqHandle)
+	{
+	/**
+	Cancels request to be notified of call Waiting status change
+	@param aReqHandle Handle to the request
+	*/
+	if(iCWNotification.iCWChangeInfoNotificationPending)
+		{
+		iCWNotification.iCWChangeInfoNotificationPending=EFalse;
+		iPhone->ReqCompleted(aReqHandle,KErrCancel);
+		}
+	return KErrNone;
+	}
+	
+TInt CSimCallWaiting::SetCallWaitingStatusL(const TTsyReqHandle aReqHandle, RMobilePhone::TMobileService* aService,  RMobilePhone::TMobilePhoneServiceAction* aAction)
+	{
+	/**
+	Sets the status for call Waiting
+	@param aReqHandle Handle to the request
+	@param aCB condition for which the client whishes to set the call Waiting status
+	@param aInfo additional parameters to set the call Waiting status
+  	*/
+	
+	// make sure we know that the operation concluded sucessfully
+	TRAPD(ret,UpdateCWListL(aService,aAction)); 	
+	if ( ret != KErrNone )
+		{ 
+		iPhone->ReqCompleted(aReqHandle,ret);
+		}
+		
+	// otherwise proceed and notify all went well
+	// Notify change
+	if (iCWNotification.iCWChangeInfoNotificationPending)
+		{
+		
+		(iCWNotification.iCWInfo->iServiceGroup)=*aService;
+				
+		switch (*aAction)
+			{
+			case RMobilePhone::EServiceActionRegister:
+			case RMobilePhone::EServiceActionActivate:
+				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusActive;
+				break;
+			case RMobilePhone::EServiceActionDeactivate:
+			case RMobilePhone::EServiceActionErase:
+				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusNotActive;
+				break;
+			case RMobilePhone::EServiceActionUnspecified:
+			default:
+				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusUnknown;
+				// no sense doing any further operation - leave
+				User::Leave( KErrArgument );
+				break;
+			}
+		
+		iCWNotification.iCWChangeInfoNotificationPending=EFalse;
+		iPhone->ReqCompleted(iCWNotification.iCWChangeInfoReqHandle,KErrNone);
+		}
+		
+	iPhone->ReqCompleted(aReqHandle,KErrNone);
+		
+	return KErrNone;
+	}
+
+TInt CSimCallWaiting::SetCallWaitingStatusCancel(const TTsyReqHandle aReqHandle)
+	{
+	/**
+	Cancels the request to sets the status for call waiting
+	@param aReqHandle Handle to the request
+  	*/
+	 
+	iPhone->ReqCompleted(aReqHandle,KErrCancel);
+	return KErrNone;
+	}
+	
+	
+	
+const CTestConfigSection* CSimCallWaiting::CfgFile()
+/**
+ * Returns a pointer to the current configuration file section.
+ *
+ * @return CTestConfigSection	A pointer to the current configuration file data section.
+ */
+	{
+	return iPhone->CfgFile();
+	}
+
+TInt CSimCallWaiting::GetCallWaitingStatusPhase1(const TTsyReqHandle aTsyReqHandle, 
+												 CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData, 
+												 TInt* aBufSize)
+	{
+	/**
+	1st phase retrieval of the the call waiting status list
+	@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("CSimCallWaiting::GetCalWaitingStatusPhase1");
+	
+	TInt ret=KErrNone;
+	TInt leaveCode=KErrNone;
+	TRAP(leaveCode, ret=ProcessGetCallWaitingStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
+	if (leaveCode != KErrNone)
+			iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
+
+	LOGCALL1("CSimCallWaiting::GetCalWaitingStatusPhase1");
+	return ret;
+	}
+	
+TInt CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L(const TTsyReqHandle aTsyReqHandle, 
+														 CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData, 
+														 TInt* aBufSize)
+	{
+	/** Retrieve call waiting status of each line from phone, 
+	store each CB 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("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
+
+	CMobilePhoneCWList* list=CMobilePhoneCWList::NewL();
+	CleanupStack::PushL(list);
+		
+	TInt maxNum=iCWList->Enumerate();
+	//if testing all CB are non-active
+	// then we have to return a single entry EAllServices
+	if ( maxNum )
+		{
+		for(TInt i=0;i<maxNum;i++)
+			{
+			list->AddEntryL(iCWList->GetEntryL(i));
+			}
+		}
+	else
+		{
+		// if the list is empty and the querry general then we have to return general info
+		RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
+		
+		// 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;
+			}
+
+		entry.iServiceGroup	= RMobilePhone::EAllServices;
+		entry.iStatus		= RMobilePhone::ECallWaitingStatusNotActive;
+		list->AddEntryL( entry );
+		}
+
+	// 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
+	
+	iGetCWStatus->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("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
+	return KErrNone;
+	}
+
+TInt CSimCallWaiting::GetCallWaitingStatusPhase2(const TTsyReqHandle aTsyReqHandle, 
+												 RMobilePhone::TClientId* aClient, TDes8* aBuf)
+	{
+	/**
+	2nd phase retrieval of the the call waiting status list
+	@param aReqHandle Handle to the request
+	@param aClient Ponter to the client
+	@param aBuf Buffer containiong the call waiting status list
+	*/
+	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
+	CListReadAllAttempt* read=NULL;
+	// Find the get detected network attempt from this client
+	for (TInt i=0; i<iGetCWStatus->Count(); ++i)
+		{
+		read = iGetCWStatus->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;
+			iGetCWStatus->Delete(i);
+			iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+			return KErrNone;
+			}
+		}
+	// Should handle error case of not finding the matching client from read all phase 1
+	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
+	return KErrNotFound;
+	}
+
+TInt CSimCallWaiting::GetCallWaitingStatusCancel(const TTsyReqHandle aTsyReqHandle)
+	{
+	/*
+	Cancels a Request to retrieve the call waiting status list
+	@param aReqHandle Handle to the request
+	*/
+	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
+	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
+	// Remove the read all attempt from iGetCBStatus
+	CListReadAllAttempt* read=NULL;
+	for (TInt i=0; i<iGetCWStatus->Count(); ++i)
+		{
+		read = iGetCWStatus->At(i);
+		if (read->iReqHandle == aTsyReqHandle)
+			{
+			delete read;
+			iGetCWStatus->Delete(i);
+			break;
+			}
+		}
+	iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
+	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
+	return KErrNone;
+	}
+	
+inline void SplitOneEntryIntoSeparateGroupsL( 
+								CMobilePhoneCWList* aCWList,
+								RMobilePhone::TMobilePhoneCWInfoEntryV1 aOrigEntry,
+								RMobilePhone::TMobileService aExceptServiceGroup
+									)
+	{
+	/*
+	Splits one entry valid for all basic service groups into individual entries 
+	and places them into a CMobilePhoneCBList. 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::TMobilePhoneCWInfoEntryV1 anotherEntry = aOrigEntry;
+
+	//anotherEntry.iCondition = aOrigEntry.iCondition;
+	//anotherEntry.iStatus = RMobilePhone::ECallBarringStatusActive;
+	RMobilePhone::TMobileService service;
+	
+	for (TInt i=KMobServiceIndxStart; i<=KMobServiceIndxEnd;i++)
+		{
+		service=static_cast<RMobilePhone::TMobileService>(i);
+		if( service != aExceptServiceGroup )
+			{
+			anotherEntry.iServiceGroup=service;
+			aCWList->AddEntryL(anotherEntry);
+			}
+		}//end for (another)
+	}
+	
+void CSimCallWaiting::UpdateCWListL(RMobilePhone::TMobileService* aServiceGroup, RMobilePhone::TMobilePhoneServiceAction* aAction )
+	{
+	/*
+	Updates the status of call waiting.
+	@param aServiceGroup service group to set
+	@param aAction ation to be performed 
+	*/
+	
+	// no sense processing if either condition or change info are NULLS 
+	User::LeaveIfNull(aServiceGroup);
+	User::LeaveIfNull(aAction);
+    
+	
+	//Lets do some work then
+	RMobilePhone::TMobilePhoneCWInfoEntryV1 theNewEntry;
+
+	theNewEntry.iServiceGroup = *aServiceGroup;
+	
+	switch (*aAction)
+		{
+		case RMobilePhone::EServiceActionRegister:
+		case RMobilePhone::EServiceActionActivate:
+			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusActive;
+			break;
+		case RMobilePhone::EServiceActionDeactivate:
+		case RMobilePhone::EServiceActionErase:
+			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusNotActive;
+			break;
+		case RMobilePhone::EServiceActionUnspecified:
+		default:
+			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusUnknown;
+			// no sense doing any further operation - leave
+			User::Leave( KErrArgument );
+			break;
+		}
+		
+	// retain prev version of the list in local variable and in Cleanup stack
+	CMobilePhoneCWList* thePrevCWList = CMobilePhoneCWList::NewL();
+	CleanupStack::PushL(thePrevCWList);
+	// copy existing data into the temp storage
+	for (TInt indx=0; indx<iCWList->Enumerate(); indx++)
+		{ 
+		thePrevCWList->AddEntryL(iCWList->GetEntryL(indx));
+		}
+	delete iCWList;
+	iCWList = NULL;
+	
+	// create a new version and hold it in the class member
+	iCWList = CMobilePhoneCWList::NewL();
+	// get a hold of it in a local variable       
+	CMobilePhoneCWList* theNewCWList = iCWList;
+	RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
+
+	TInt count = thePrevCWList->Enumerate();
+	
+	if (theNewEntry.iStatus == RMobilePhone::ECallWaitingStatusActive)
+		{
+		if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
+			{
+			theNewCWList->AddEntryL(theNewEntry);
+			}
+		else
+			{
+			for (TInt i = 0; i<count; i++)
+				{
+				entry = thePrevCWList->GetEntryL(i);
+				if(entry.iServiceGroup!=theNewEntry.iServiceGroup
+					&& entry.iServiceGroup!=RMobilePhone::EAllServices)
+					theNewCWList->AddEntryL(entry);
+				}
+			theNewCWList->AddEntryL(theNewEntry);
+			}
+		}
+	else //deactivate
+		{
+		if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
+			{
+			theNewCWList->AddEntryL(theNewEntry);
+			}
+		else
+			{
+			for (TInt i = 0; i<count; i++)
+				{
+				entry = thePrevCWList->GetEntryL(i);
+				if(entry.iServiceGroup==RMobilePhone::EAllServices)
+					{
+					//add to the list active entries for all servive groups but the one to be deactivated
+					SplitOneEntryIntoSeparateGroupsL(theNewCWList,entry, theNewEntry.iServiceGroup);
+					continue;
+					}
+				if(entry.iServiceGroup!=theNewEntry.iServiceGroup)
+					{
+					theNewCWList->AddEntryL(entry);
+					}
+				}				
+			}
+			
+		}
+	// now delete the old memory	
+	CleanupStack::PopAndDestroy(thePrevCWList);	
+	}
+