telephonyserverplugins/simtsy/src/CSimCallWaiting.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 42 3adadc800673
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implements the functionality required to provide clients with
       
    15 // CallWaiting status and registration information.
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file
       
    21 */
       
    22 
       
    23 #include <testconfigfileparser.h>
       
    24 #include "CSimCallWaiting.h"
       
    25 #include "CSimPhone.h"
       
    26 #include "Simlog.h"
       
    27 
       
    28 const TInt KMobServiceIndxStart = 1;
       
    29 const TInt KMobServiceIndxEnd   = 5;
       
    30 
       
    31 
       
    32 CSimCallWaiting* CSimCallWaiting::NewL(CSimPhone* aPhone)
       
    33 /**
       
    34  * Standard two-phase constructor.
       
    35  * @param aPhone				The parent phone object.
       
    36  * @return CSimCallWaiting		The new call waiting class.
       
    37  */
       
    38 	{
       
    39 	CSimCallWaiting* self=new(ELeave) CSimCallWaiting(aPhone);
       
    40 	CleanupStack::PushL(self);
       
    41 	self->ConstructL();
       
    42 	CleanupStack::Pop();
       
    43 	return self;
       
    44 	}
       
    45 
       
    46 CSimCallWaiting::CSimCallWaiting(CSimPhone* aPhone)
       
    47 		: iPhone(aPhone)
       
    48 /**
       
    49  * Trivial first phase construction.
       
    50  * @param aPhone				The parent phone object.
       
    51  */
       
    52 	{
       
    53 	}
       
    54 
       
    55 void CSimCallWaiting::ConstructL()
       
    56 /**
       
    57 	Second phase of 2-Phase Constructor
       
    58   	Retrieves all the Call waiting related tags from the config file
       
    59 */
       
    60 	{
       
    61 	LOGCALL1("Starting to parse Call waiting config parameters...");
       
    62 
       
    63 	iGetCWStatus = new(ELeave) CArrayPtrFlat<CListReadAllAttempt>(1);
       
    64 	FindAndCreateCWListL();
       
    65 	LOGCALL1("...Finished parsing Call waiting config parameters...");
       
    66 	}
       
    67 	
       
    68 void CSimCallWaiting::FindAndCreateCWListL()
       
    69 {
       
    70 /**
       
    71   	Retrieves all the Call waiting tags that define the 
       
    72   	original status of Call waiting from the config file
       
    73 */
       
    74 	LOGCALL1("CSimPhone::FindAndCreateCWListL");
       
    75 	RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
       
    76 
       
    77 	iCWList = CMobilePhoneCWList::NewL();
       
    78 	TInt count=CfgFile()->ItemCount(KCWList);
       
    79 	const CTestConfigItem* item=NULL;
       
    80 	TInt ret=KErrNone;
       
    81 
       
    82 	LOGCALL1("Starting to Load and Parse CWList Config parameters");
       
    83 	TInt i;
       
    84 	for(i=0;i<count;i++)
       
    85 		{
       
    86 		item=CfgFile()->Item(KCWList,i);
       
    87 		if(!item)
       
    88 			break;
       
    89 		
       
    90 		TInt serviceGroup, status;
       
    91 		
       
    92 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,serviceGroup);
       
    93 		if(ret!=KErrNone)
       
    94 			{
       
    95 			LOGPARSERR("serviceGroup",ret,0,&KCWList);
       
    96 			continue;
       
    97 			}
       
    98 
       
    99 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,status);
       
   100 		if(ret!=KErrNone)
       
   101 			{
       
   102 			LOGPARSERR("status",ret,1,&KCWList);
       
   103 			continue;
       
   104 			}
       
   105 		
       
   106 		entry.iServiceGroup=(RMobilePhone::TMobileService)serviceGroup;
       
   107 		entry.iStatus=(RMobilePhone::TMobilePhoneCWStatus)status;
       
   108 
       
   109 		iCWList->AddEntryL(entry);
       
   110 		}
       
   111 	}
       
   112 
       
   113 CSimCallWaiting::~CSimCallWaiting()
       
   114 	{
       
   115 	delete iCWList;
       
   116 	if (iGetCWStatus)
       
   117 		iGetCWStatus->ResetAndDestroy();
       
   118 	delete iGetCWStatus;
       
   119 	}
       
   120 
       
   121 TInt CSimCallWaiting::ExtFuncL(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
       
   122 	{
       
   123 	/**
       
   124   	Handles the phone based requests that apply to call waiting
       
   125   	@param aReqHandle Handle to the request
       
   126   	@param aIpc request identifier
       
   127   	@param aPckg contains additional information for the requests
       
   128 	*/
       
   129 
       
   130 	TAny* dataPtr = aPckg.Ptr1();
       
   131 	TAny* dataPtr2 = aPckg.Ptr2();
       
   132 	// The following requests can be completed even if the completion of another request is pending.
       
   133 	switch(aIpc)
       
   134 		{
       
   135 	case EMobilePhoneSetCallWaitingStatus:
       
   136 		return SetCallWaitingStatusL(aReqHandle,
       
   137 			REINTERPRET_CAST(RMobilePhone::TMobileService*, dataPtr),
       
   138 			REINTERPRET_CAST(RMobilePhone::TMobilePhoneServiceAction*,dataPtr2));
       
   139 	case EMobilePhoneNotifyCallWaitingStatusChange:
       
   140 		return NotifyCallWaitingStatusChange(aReqHandle, REINTERPRET_CAST(RMobilePhone::TMobilePhoneCWInfoEntryV1*, dataPtr));
       
   141 	case EMobilePhoneGetWaitingStatusPhase1:
       
   142 		return GetCallWaitingStatusPhase1(aReqHandle, 
       
   143 			REINTERPRET_CAST(CRetrieveMobilePhoneCWList::TGetCallWaitingRequest*, dataPtr), 
       
   144 			REINTERPRET_CAST(TInt*, dataPtr2));
       
   145 	case EMobilePhoneGetWaitingStatusPhase2:
       
   146 		return GetCallWaitingStatusPhase2(aReqHandle, 
       
   147 			REINTERPRET_CAST(RMobilePhone::TClientId*, dataPtr), aPckg.Des2n());		
       
   148 	default:
       
   149 		break;
       
   150 		}
       
   151 	return KErrNotSupported;
       
   152 	}
       
   153 	
       
   154 TInt CSimCallWaiting::CancelService(const TInt aIpc, const TTsyReqHandle aReqHandle)
       
   155 	{
       
   156 	/**
       
   157   	Cancels any phone based request regarding call waiting
       
   158   	@param aIpc the IPC to cancel
       
   159   	@param aReqHandle handle to the request
       
   160 	*/
       
   161 	switch(aIpc)
       
   162 		{
       
   163 	case EMobilePhoneSetCallWaitingStatus:
       
   164 		return SetCallWaitingStatusCancel(aReqHandle);
       
   165 	case EMobilePhoneNotifyCallWaitingStatusChange:
       
   166 		return NotifyCallWaitingStatusChangeCancel(aReqHandle);
       
   167 	default:
       
   168 		break;
       
   169 		}
       
   170 	return KErrNone;
       
   171 	}
       
   172 
       
   173 TInt CSimCallWaiting::NotifyCallWaitingStatusChange(const TTsyReqHandle aReqHandle, RMobilePhone::TMobilePhoneCWInfoEntryV1* aCW)
       
   174 	{	
       
   175 	/**
       
   176 	Requests to be notified of change in the Call Waiting status
       
   177 	@param aReqHandle Handle to the request
       
   178 	@param aCW contains the service group and new status that has changed
       
   179   	*/
       
   180 	__ASSERT_ALWAYS(!iCWNotification.iCWChangeInfoNotificationPending,SimPanic(ENotificationReqAlreadyOutstanding));
       
   181 	iCWNotification.iCWChangeInfoNotificationPending=ETrue;
       
   182 	iCWNotification.iCWChangeInfoReqHandle=aReqHandle;
       
   183 	iCWNotification.iCWInfo=aCW;
       
   184 	LOGCALL1("Finished CSimCallWaiting::NotifyCallWaitingStatusChange");
       
   185 	return KErrNone;
       
   186 	}
       
   187 
       
   188 TInt CSimCallWaiting::NotifyCallWaitingStatusChangeCancel(const TTsyReqHandle aReqHandle)
       
   189 	{
       
   190 	/**
       
   191 	Cancels request to be notified of call Waiting status change
       
   192 	@param aReqHandle Handle to the request
       
   193 	*/
       
   194 	if(iCWNotification.iCWChangeInfoNotificationPending)
       
   195 		{
       
   196 		iCWNotification.iCWChangeInfoNotificationPending=EFalse;
       
   197 		iPhone->ReqCompleted(aReqHandle,KErrCancel);
       
   198 		}
       
   199 	return KErrNone;
       
   200 	}
       
   201 	
       
   202 TInt CSimCallWaiting::SetCallWaitingStatusL(const TTsyReqHandle aReqHandle, RMobilePhone::TMobileService* aService,  RMobilePhone::TMobilePhoneServiceAction* aAction)
       
   203 	{
       
   204 	/**
       
   205 	Sets the status for call Waiting
       
   206 	@param aReqHandle Handle to the request
       
   207 	@param aCB condition for which the client whishes to set the call Waiting status
       
   208 	@param aInfo additional parameters to set the call Waiting status
       
   209   	*/
       
   210 	
       
   211 	// make sure we know that the operation concluded sucessfully
       
   212 	TRAPD(ret,UpdateCWListL(aService,aAction)); 	
       
   213 	if ( ret != KErrNone )
       
   214 		{ 
       
   215 		iPhone->ReqCompleted(aReqHandle,ret);
       
   216 		}
       
   217 		
       
   218 	// otherwise proceed and notify all went well
       
   219 	// Notify change
       
   220 	if (iCWNotification.iCWChangeInfoNotificationPending)
       
   221 		{
       
   222 		
       
   223 		(iCWNotification.iCWInfo->iServiceGroup)=*aService;
       
   224 				
       
   225 		switch (*aAction)
       
   226 			{
       
   227 			case RMobilePhone::EServiceActionRegister:
       
   228 			case RMobilePhone::EServiceActionActivate:
       
   229 				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusActive;
       
   230 				break;
       
   231 			case RMobilePhone::EServiceActionDeactivate:
       
   232 			case RMobilePhone::EServiceActionErase:
       
   233 				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusNotActive;
       
   234 				break;
       
   235 			case RMobilePhone::EServiceActionUnspecified:
       
   236 			default:
       
   237 				iCWNotification.iCWInfo->iStatus= RMobilePhone::ECallWaitingStatusUnknown;
       
   238 				// no sense doing any further operation - leave
       
   239 				User::Leave( KErrArgument );
       
   240 				break;
       
   241 			}
       
   242 		
       
   243 		iCWNotification.iCWChangeInfoNotificationPending=EFalse;
       
   244 		iPhone->ReqCompleted(iCWNotification.iCWChangeInfoReqHandle,KErrNone);
       
   245 		}
       
   246 		
       
   247 	iPhone->ReqCompleted(aReqHandle,KErrNone);
       
   248 		
       
   249 	return KErrNone;
       
   250 	}
       
   251 
       
   252 TInt CSimCallWaiting::SetCallWaitingStatusCancel(const TTsyReqHandle aReqHandle)
       
   253 	{
       
   254 	/**
       
   255 	Cancels the request to sets the status for call waiting
       
   256 	@param aReqHandle Handle to the request
       
   257   	*/
       
   258 	 
       
   259 	iPhone->ReqCompleted(aReqHandle,KErrCancel);
       
   260 	return KErrNone;
       
   261 	}
       
   262 	
       
   263 	
       
   264 	
       
   265 const CTestConfigSection* CSimCallWaiting::CfgFile()
       
   266 /**
       
   267  * Returns a pointer to the current configuration file section.
       
   268  *
       
   269  * @return CTestConfigSection	A pointer to the current configuration file data section.
       
   270  */
       
   271 	{
       
   272 	return iPhone->CfgFile();
       
   273 	}
       
   274 
       
   275 TInt CSimCallWaiting::GetCallWaitingStatusPhase1(const TTsyReqHandle aTsyReqHandle, 
       
   276 												 CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData, 
       
   277 												 TInt* aBufSize)
       
   278 	{
       
   279 	/**
       
   280 	1st phase retrieval of the the call waiting status list
       
   281 	@param aReqHandle Handle to the request
       
   282 	@param aReqData information about the request
       
   283 	@param aBufSize Size of the buffer the client has to allocate for the 2nd pahase
       
   284   	*/
       
   285 	LOGCALL1("CSimCallWaiting::GetCalWaitingStatusPhase1");
       
   286 	
       
   287 	TInt ret=KErrNone;
       
   288 	TInt leaveCode=KErrNone;
       
   289 	TRAP(leaveCode, ret=ProcessGetCallWaitingStatusPhase1L(aTsyReqHandle, aReqData, aBufSize););
       
   290 	if (leaveCode != KErrNone)
       
   291 			iPhone->ReqCompleted(aTsyReqHandle,leaveCode);
       
   292 
       
   293 	LOGCALL1("CSimCallWaiting::GetCalWaitingStatusPhase1");
       
   294 	return ret;
       
   295 	}
       
   296 	
       
   297 TInt CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L(const TTsyReqHandle aTsyReqHandle, 
       
   298 														 CRetrieveMobilePhoneCWList::TGetCallWaitingRequest* aReqData, 
       
   299 														 TInt* aBufSize)
       
   300 	{
       
   301 	/** Retrieve call waiting status of each line from phone, 
       
   302 	store each CB status response as a list entry,
       
   303 	stream the list and then return size of this buffer to client
       
   304 	@param aReqHandle Handle to the request
       
   305 	@param aReqData information about the request
       
   306 	@param aBufSize Size of the buffer the client has to allocate for the 2nd pahase
       
   307 	*/
       
   308 	LOGCALL1("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
       
   309 
       
   310 	CMobilePhoneCWList* list=CMobilePhoneCWList::NewL();
       
   311 	CleanupStack::PushL(list);
       
   312 		
       
   313 	TInt maxNum=iCWList->Enumerate();
       
   314 	//if testing all CB are non-active
       
   315 	// then we have to return a single entry EAllServices
       
   316 	if ( maxNum )
       
   317 		{
       
   318 		for(TInt i=0;i<maxNum;i++)
       
   319 			{
       
   320 			list->AddEntryL(iCWList->GetEntryL(i));
       
   321 			}
       
   322 		}
       
   323 	else
       
   324 		{
       
   325 		// if the list is empty and the querry general then we have to return general info
       
   326 		RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
       
   327 		
       
   328 		// Check that the data structure is supported by the simulated TSY version
       
   329 		TInt err = iPhone->CheckSimTsyVersion(entry);
       
   330 		if(err != KErrNone)
       
   331 			{
       
   332 			iPhone->ReqCompleted(aTsyReqHandle, err);
       
   333 			return KErrNone;
       
   334 			}
       
   335 
       
   336 		entry.iServiceGroup	= RMobilePhone::EAllServices;
       
   337 		entry.iStatus		= RMobilePhone::ECallWaitingStatusNotActive;
       
   338 		list->AddEntryL( entry );
       
   339 		}
       
   340 
       
   341 	// Store the streamed list and the client ID
       
   342 	CListReadAllAttempt* read=CListReadAllAttempt::NewL(aReqData->iClient,aTsyReqHandle);
       
   343 	CleanupStack::PushL(read);
       
   344 	
       
   345 	read->iListBuf = list->StoreLC();
       
   346 	CleanupStack::Pop(); // pop the CBufBase allocated by StoreLC
       
   347 	
       
   348 	iGetCWStatus->AppendL(read);
       
   349 	CleanupStack::Pop(read); // pop the CListReadAllAttempt
       
   350 	
       
   351 	// return the CBufBase’s size to client
       
   352 	*aBufSize=(read->iListBuf)->Size();
       
   353 	
       
   354 	CleanupStack::PopAndDestroy(list); // pop&destroy list
       
   355 	
       
   356 	// Complete first phase of list retrieval
       
   357 	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
       
   358 	
       
   359 	LOGCALL1("CSimCallWaiting::ProcessGetCallWaitingStatusPhase1L");
       
   360 	return KErrNone;
       
   361 	}
       
   362 
       
   363 TInt CSimCallWaiting::GetCallWaitingStatusPhase2(const TTsyReqHandle aTsyReqHandle, 
       
   364 												 RMobilePhone::TClientId* aClient, TDes8* aBuf)
       
   365 	{
       
   366 	/**
       
   367 	2nd phase retrieval of the the call waiting status list
       
   368 	@param aReqHandle Handle to the request
       
   369 	@param aClient Ponter to the client
       
   370 	@param aBuf Buffer containiong the call waiting status list
       
   371 	*/
       
   372 	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
       
   373 	CListReadAllAttempt* read=NULL;
       
   374 	// Find the get detected network attempt from this client
       
   375 	for (TInt i=0; i<iGetCWStatus->Count(); ++i)
       
   376 		{
       
   377 		read = iGetCWStatus->At(i);
       
   378 		if ((read->iClient.iSessionHandle==aClient->iSessionHandle) &&
       
   379 		    (read->iClient.iSubSessionHandle==aClient->iSubSessionHandle))
       
   380 			{
       
   381 			TPtr8 bufPtr((read->iListBuf)->Ptr(0));
       
   382 			// Copy the streamed list to the client
       
   383 			aBuf->Copy(bufPtr);
       
   384 			delete read;
       
   385 			iGetCWStatus->Delete(i);
       
   386 			iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
       
   387 			return KErrNone;
       
   388 			}
       
   389 		}
       
   390 	// Should handle error case of not finding the matching client from read all phase 1
       
   391 	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusPhase2");
       
   392 	return KErrNotFound;
       
   393 	}
       
   394 
       
   395 TInt CSimCallWaiting::GetCallWaitingStatusCancel(const TTsyReqHandle aTsyReqHandle)
       
   396 	{
       
   397 	/*
       
   398 	Cancels a Request to retrieve the call waiting status list
       
   399 	@param aReqHandle Handle to the request
       
   400 	*/
       
   401 	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
       
   402 	iPhone->ReqCompleted(aTsyReqHandle,KErrNone);
       
   403 	// Remove the read all attempt from iGetCBStatus
       
   404 	CListReadAllAttempt* read=NULL;
       
   405 	for (TInt i=0; i<iGetCWStatus->Count(); ++i)
       
   406 		{
       
   407 		read = iGetCWStatus->At(i);
       
   408 		if (read->iReqHandle == aTsyReqHandle)
       
   409 			{
       
   410 			delete read;
       
   411 			iGetCWStatus->Delete(i);
       
   412 			break;
       
   413 			}
       
   414 		}
       
   415 	iPhone->ReqCompleted(aTsyReqHandle,KErrCancel);
       
   416 	LOGCALL1("CSimCallWaiting::GetCallWaitingStatusCancel");
       
   417 	return KErrNone;
       
   418 	}
       
   419 	
       
   420 inline void SplitOneEntryIntoSeparateGroupsL( 
       
   421 								CMobilePhoneCWList* aCWList,
       
   422 								RMobilePhone::TMobilePhoneCWInfoEntryV1 aOrigEntry,
       
   423 								RMobilePhone::TMobileService aExceptServiceGroup
       
   424 									)
       
   425 	{
       
   426 	/*
       
   427 	Splits one entry valid for all basic service groups into individual entries 
       
   428 	and places them into a CMobilePhoneCBList. This excludes one service group.	 
       
   429 	@param aCBList The list to which to store the entries
       
   430 	@param aOrigEntry The original entry; details of which should be passed to individual group entries
       
   431 	@param aExceptServiceGroup The group which has to be avoided
       
   432 	*/
       
   433 	// we have to split the entry into entries 
       
   434 	// per group with the same condition; excluding the specified service group 
       
   435 	RMobilePhone::TMobilePhoneCWInfoEntryV1 anotherEntry = aOrigEntry;
       
   436 
       
   437 	//anotherEntry.iCondition = aOrigEntry.iCondition;
       
   438 	//anotherEntry.iStatus = RMobilePhone::ECallBarringStatusActive;
       
   439 	RMobilePhone::TMobileService service;
       
   440 	
       
   441 	for (TInt i=KMobServiceIndxStart; i<=KMobServiceIndxEnd;i++)
       
   442 		{
       
   443 		service=static_cast<RMobilePhone::TMobileService>(i);
       
   444 		if( service != aExceptServiceGroup )
       
   445 			{
       
   446 			anotherEntry.iServiceGroup=service;
       
   447 			aCWList->AddEntryL(anotherEntry);
       
   448 			}
       
   449 		}//end for (another)
       
   450 	}
       
   451 	
       
   452 void CSimCallWaiting::UpdateCWListL(RMobilePhone::TMobileService* aServiceGroup, RMobilePhone::TMobilePhoneServiceAction* aAction )
       
   453 	{
       
   454 	/*
       
   455 	Updates the status of call waiting.
       
   456 	@param aServiceGroup service group to set
       
   457 	@param aAction ation to be performed 
       
   458 	*/
       
   459 	
       
   460 	// no sense processing if either condition or change info are NULLS 
       
   461 	User::LeaveIfNull(aServiceGroup);
       
   462 	User::LeaveIfNull(aAction);
       
   463     
       
   464 	
       
   465 	//Lets do some work then
       
   466 	RMobilePhone::TMobilePhoneCWInfoEntryV1 theNewEntry;
       
   467 
       
   468 	theNewEntry.iServiceGroup = *aServiceGroup;
       
   469 	
       
   470 	switch (*aAction)
       
   471 		{
       
   472 		case RMobilePhone::EServiceActionRegister:
       
   473 		case RMobilePhone::EServiceActionActivate:
       
   474 			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusActive;
       
   475 			break;
       
   476 		case RMobilePhone::EServiceActionDeactivate:
       
   477 		case RMobilePhone::EServiceActionErase:
       
   478 			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusNotActive;
       
   479 			break;
       
   480 		case RMobilePhone::EServiceActionUnspecified:
       
   481 		default:
       
   482 			theNewEntry.iStatus= RMobilePhone::ECallWaitingStatusUnknown;
       
   483 			// no sense doing any further operation - leave
       
   484 			User::Leave( KErrArgument );
       
   485 			break;
       
   486 		}
       
   487 		
       
   488 	// retain prev version of the list in local variable and in Cleanup stack
       
   489 	CMobilePhoneCWList* thePrevCWList = CMobilePhoneCWList::NewL();
       
   490 	CleanupStack::PushL(thePrevCWList);
       
   491 	// copy existing data into the temp storage
       
   492 	for (TInt indx=0; indx<iCWList->Enumerate(); indx++)
       
   493 		{ 
       
   494 		thePrevCWList->AddEntryL(iCWList->GetEntryL(indx));
       
   495 		}
       
   496 	delete iCWList;
       
   497 	iCWList = NULL;
       
   498 	
       
   499 	// create a new version and hold it in the class member
       
   500 	iCWList = CMobilePhoneCWList::NewL();
       
   501 	// get a hold of it in a local variable       
       
   502 	CMobilePhoneCWList* theNewCWList = iCWList;
       
   503 	RMobilePhone::TMobilePhoneCWInfoEntryV1 entry;
       
   504 
       
   505 	TInt count = thePrevCWList->Enumerate();
       
   506 	
       
   507 	if (theNewEntry.iStatus == RMobilePhone::ECallWaitingStatusActive)
       
   508 		{
       
   509 		if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
       
   510 			{
       
   511 			theNewCWList->AddEntryL(theNewEntry);
       
   512 			}
       
   513 		else
       
   514 			{
       
   515 			for (TInt i = 0; i<count; i++)
       
   516 				{
       
   517 				entry = thePrevCWList->GetEntryL(i);
       
   518 				if(entry.iServiceGroup!=theNewEntry.iServiceGroup
       
   519 					&& entry.iServiceGroup!=RMobilePhone::EAllServices)
       
   520 					theNewCWList->AddEntryL(entry);
       
   521 				}
       
   522 			theNewCWList->AddEntryL(theNewEntry);
       
   523 			}
       
   524 		}
       
   525 	else //deactivate
       
   526 		{
       
   527 		if (theNewEntry.iServiceGroup==RMobilePhone::EAllServices)
       
   528 			{
       
   529 			theNewCWList->AddEntryL(theNewEntry);
       
   530 			}
       
   531 		else
       
   532 			{
       
   533 			for (TInt i = 0; i<count; i++)
       
   534 				{
       
   535 				entry = thePrevCWList->GetEntryL(i);
       
   536 				if(entry.iServiceGroup==RMobilePhone::EAllServices)
       
   537 					{
       
   538 					//add to the list active entries for all servive groups but the one to be deactivated
       
   539 					SplitOneEntryIntoSeparateGroupsL(theNewCWList,entry, theNewEntry.iServiceGroup);
       
   540 					continue;
       
   541 					}
       
   542 				if(entry.iServiceGroup!=theNewEntry.iServiceGroup)
       
   543 					{
       
   544 					theNewCWList->AddEntryL(entry);
       
   545 					}
       
   546 				}				
       
   547 			}
       
   548 			
       
   549 		}
       
   550 	// now delete the old memory	
       
   551 	CleanupStack::PopAndDestroy(thePrevCWList);	
       
   552 	}
       
   553