telephonyserverplugins/simtsy/src/CSimLine.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
--- a/telephonyserverplugins/simtsy/src/CSimLine.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/CSimLine.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,927 +1,927 @@
-
-// 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:
-// This file contains the implementation for the functionality common to all 
-// the specific line classes, such as CSimVoiceLine and CSimDataline.
-// 
-//
-
-/**
- @file
-*/
-
-#include <testconfigfileparser.h>
-#include "CSimLine.h"
-#include "CSimPhone.h"
-#include "CSimCall.h"
-#include "Simlog.h"
-#include "CSimPubSub.h"
-
-void CSimLine::CloseLine(TAny* aObj)
-/**
-*	Utility func for cleanup stack
-*
-* @param aObj a pointer to the CObject to close
-*/
-	{
-	((CObject*)aObj)->Close();
-	}
-
-CSimLine::CSimLine(CSimPhone* aPhone)
-			:iPhone(aPhone), iState(RMobileCall::EStatusIdle), 
-			iHookState(ConvertStateToHook(iState))
-	{
-	iNameOfLastCallAdded.Zero();
-	iNotifyStatusChange.iNotifyPending = EFalse;
-	iNotifyMobileStatusChange.iNotifyPending = EFalse;
-	}
-
-void CSimLine::ConstructL(const TName& aName)
-/**
-* Second phase of two phase constructor.
-* Creates the System Agent object for incoming call notification and other notifications.
-*
-* @param aName name of the Line to be created.
-*/
-	{
-	LOGLINE2(">>CSimLine::ConstructL [aLineName=%S]", &aName);
-	iLineName = aName;
-	iSimPubSubIC = CSimPubSub::NewL(this,iICProperty);
-	iSimPubSubIC->Start();
-
-	iSimPubSubRH = CSimPubSub::NewL(this,iRHProperty);
-	iSimPubSubRH->Start();
-	
-	iNotifyIncomingCallPause=this->CfgFile()->ItemValue(KNotifyIncomingCallPauseDuration,KDefaultNotifyIncomingCallPauseDuration);
-	
-	iTimer = CSimTimer::NewL(iPhone);
-		LOGLINE1("<<CSimLine::ConstructL");
-}
-
-CSimLine::~CSimLine()
-/**
-*	Standard destructor.
-*/
-	{
-	delete iSimPubSubIC;
-	delete iSimPubSubRH;
-	iTimer->Cancel();
-	delete iTimer;
-	}
-
-
-void CSimLine::UpdatePhoneNotifiers(CSimCall* aCall,TUint /*aStatus*/)
-	{
-		TInt count=	iCalls->Count();
-		TInt i=0;
-		while(i<count)
-		{
- 		if(iCalls->At(i) != aCall && (iCalls->At(i)->iState == RMobileCall::EStatusHold || iCalls->At(i)->iState == RMobileCall::EStatusConnected))
-			iCalls->At(i)->UpdateNotifiers();
-		i++;
-		}	
-	}
-
-CTelObject::TReqMode CSimLine::ReqModeL(const TInt aIpc)
-/**
-* This function returns the Request Mode for the request with the passed IPC value.
-* The ETel Server provides a function for returning the standard request modes for 
-* the Core API requests.
-* Multimode API requests mode are handled here.
-*
-* @param aIpc the IPc number representing the client request
-* @return CTelObject::TReqMode the request mode to be used for this IPc number
-* @leave Leaves if the IPc number is not found
-*/
-	{
-	// ReqModeL is called from the server's CTelObject::ReqAnalyserL
-	// in order to check the type of request it has
-
-	CTelObject::TReqMode reqMode=0;
-	switch (aIpc)
-		{
-//
-// No Flow Control NOR Multiple Completion
-//
-	case EMobileLineGetMobileLineStatus:
-		break;
-
-//
-// Multiple Completion Services with Immediate Server Repost
-// (Usually Notifications)
-//
-	case EMobileLineNotifyMobileLineStatusChange:
-		reqMode=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
-		break;
-//
-// Must be a core API request so get request mode from Etel
-//
-	default:
-		reqMode=CLineBase::ReqModeL(aIpc);
-		break;
-		}
-
-	return reqMode;
-	}
-
-
-TInt CSimLine::NumberOfSlotsL(const TInt aIpc)
-/**
-* NumberOfSlotsL is called by the server when it is registering a new notification
-* It enables the TSY to tell the server how many buffer slots to allocate for
-* "repost immediately" notifications that may trigger before clients collect them
-*
-* @param aIpc the IPc number representing the client request
-* @return TInt the number of slots required
-* @leave Leaves if the IPc number is not found
-*/
-	{
-	switch (aIpc)
-		{
-	case EMobileLineNotifyMobileLineStatusChange:
-		LOGLINE1("CLineMobile: Registered with the default number of slots");
-		return KDefaultNumberOfSlots;
-
-	default:
-		LOGLINE1("CSimLine::NumberOfSlotsL: No match for IPC, defering to base function");
-		break;
-		}
-	return CLineBase::NumberOfSlotsL(aIpc);
-	}
-
-
-TInt CSimLine::RegisterNotification(const TInt /*aIpc*/)
-/**
-* The ETel Server calls this function when the first client makes a notification request.
-* If supported by the underlying protocol controlling the signalling stack, 
-* this can be used to start requesting updates for the relevant service.
-*/
-	{
-	return KErrNone;
-	}
-
-TInt CSimLine::DeregisterNotification(const TInt /*aIpc*/)
-/**
-* The ETel Server calls this function when the last client that had previously
-* made a notification request closes its ETel Server handle.  If supported by
-* the underlying protocol controlling the	signalling stack, this can be used
-* to stop requesting updates for the relevant service.
-*/
-	{
-	return KErrNone;
-	}
-
-void CSimLine::Init()
-/**
-*	This function can be used to perform any necessary synchronous initialisation.
-*/
-	{}
-
-TInt CSimLine::NotifyIncomingCall(const TTsyReqHandle aTsyReqHandle, TName* aName)
-/**
-* Register a client's interest in an incoming call notification.
-* Core ETel API Request.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aName pointer to the name of the call
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyIncomingCall");
-	iNotifyIncomingCall.iNotifyPending=ETrue;
-	iNotifyIncomingCall.iNotifyHandle=aTsyReqHandle;
-	iNotifyIncomingCall.iNotifyData=(TAny*)aName;
-	LOGLINE1("<<CSimLine::NotifyIncomingCall");
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyIncomingCallCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancels a client's interest in an incoming call.
-* Core ETel API Request.
-*
-* @param aTsyReqHandle Tsy Request handle for the client cancel request
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyIncomingCallCancel");
-	if(iNotifyIncomingCall.iNotifyPending)
-		{
-		iTimer->Cancel();
-		iNotifyIncomingCall.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyIncomingCall.iNotifyHandle, KErrCancel);
-		}
-	LOGLINE1("<<CSimLine::NotifyIncomingCallCancel");
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyHookChange(const TTsyReqHandle aTsyReqHandle, RCall::THookStatus* aHookStatus)
-/**
-* Record a client's interst in being notified when the line hook changes state.
-* Core ETel API Request.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aHookStatus pointer to the line hook
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyHookChange");
-	iNotifyHookChange.iNotifyPending=ETrue;
-	iNotifyHookChange.iNotifyHandle=aTsyReqHandle;
-	iNotifyHookChange.iNotifyData=(TAny*)aHookStatus;
-	LOGLINE1("<<CSimLine::NotifyHookChange");
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyHookChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when the line hook changes state.
-* Core ETel API Request.
-*
-* @param aTsyReqHandle Tsy Request handle for the client cancel request
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyHookChangeCancel");
-	if(iNotifyHookChange.iNotifyPending)
-		{
-		iNotifyHookChange.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrCancel);
-		}
-	LOGLINE1("<<CSimLine::NotifyHookChangeCancel");
-	return KErrNone;
-	}
-
-
-TInt CSimLine::NotifyMobileLineStatusChange(const TTsyReqHandle aTsyReqHandle, RMobileCall::TMobileCallStatus* aStatus)
-/**
-* Record a client's interst in being notified when the line changes state. (Multimode)
-* MM ETel API Request.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aStatus pointer to the line status
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyMobileLineStatusChange");
-	iNotifyMobileStatusChange.iNotifyPending=ETrue;
-	iNotifyMobileStatusChange.iNotifyHandle=aTsyReqHandle;
-	iNotifyMobileStatusChange.iNotifyData=aStatus;
-	LOGLINE1("<<CSimLine::NotifyMobileLineStatusChange");
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyMobileLineStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when the line changes state.(Multimode Request)
-* MM ETel API Request.
-* 
-* @param aTsyReqHandle Tsy Request handle for the client cancel request
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyMobileLineStatusChangeCancel");
-	if(iNotifyMobileStatusChange.iNotifyPending)
-		{
-		iNotifyMobileStatusChange.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyMobileStatusChange.iNotifyHandle,KErrCancel);
-		}
-	LOGLINE1("<<CSimLine::NotifyMobileLineStatusChangeCancel");
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle, RCall::TStatus* aStatus)
-/**
-* Record a client's interst in being notified when the line changes state. (Core)
-* Core ETel API Request.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aStatus pointer to the line status
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyStatusChange");
-	iNotifyStatusChange.iNotifyPending=ETrue;
-	iNotifyStatusChange.iNotifyHandle=aTsyReqHandle;
-	iNotifyStatusChange.iNotifyData=aStatus;
-	LOGLINE1("<<CSimLine::NotifyStatusChange");
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when the line changes state.(Multimode Request)
-* Core ETel API Request.
-* 
-* @param aTsyReqHandle Tsy Request handle for the client cancel request
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyStatusChangeCancel");
-	if(iNotifyStatusChange.iNotifyPending)
-		{
-		iNotifyStatusChange.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrCancel);
-		}
-	LOGLINE1("<<CSimLine::NotifyStatusChangeCancel");
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyCallAdded(const TTsyReqHandle aTsyReqHandle,TName* aName)
-/**
-* Record a client's interest in being notified when a new call is added.
-* Core ETel API Request.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aName pointer to the name of the call
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyCallAdded");
-	iNotifyCallAdded.iNotifyPending=ETrue;
-	iNotifyCallAdded.iNotifyHandle=aTsyReqHandle;
-	iNotifyCallAdded.iNotifyData=(TAny*)aName;
-	LOGLINE1("<<CSimLine::NotifyCallAdded");
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyCallAddedCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when a new call is added.
-* Core ETel API Request.
-*
-* @param aTsyReqHandle Tsy Request handle for the client cancel request
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::NotifyCallAddedCancel");
-	if(iNotifyCallAdded.iNotifyPending)
-		{
-		iNotifyCallAdded.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyCallAdded.iNotifyHandle,KErrCancel);
-		}
-	LOGLINE1("<<CSimLine::NotifyCallAddedCancel");
-	return KErrNone;
-	}
-
-
-void CSimLine::HandleNewCallAddedNotification(const TDesC& aNewName)
-/**
-* Process a potential "New Call Added Notification" completion.
-*/
-	{
-	LOGLINE1(">>CSimLine::HandleNewCallAddedNotification");
-	iNameOfLastCallAdded.Copy(aNewName);
-	if(iNotifyCallAdded.iNotifyPending)
-		{
-		iNotifyCallAdded.iNotifyPending=EFalse;
-		((TName*)iNotifyCallAdded.iNotifyData)->Copy(aNewName);
-		ReqCompleted(iNotifyCallAdded.iNotifyHandle,KErrNone);
-		}
-	LOGLINE1("<<CSimLine::HandleNewCallAddedNotification");
-	}
-
-TInt CSimLine::GetCaps(const TTsyReqHandle aTsyReqHandle, RLine::TCaps* aCaps)
-/**
- * Retrieve the current line capabilities.
- * Core ETel API Request.
- *
- * @param aTsyReqHandle		TSY request handle associated with this request.
- * @param aCaps				Point to capability structure that will be populated with the caps.
- * @return TInt				Standard return value.
- */
-	{
-	aCaps->iFlags=iCaps;
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RLine::TCaps* aCaps)
-/**
-* Register a client's interest in being notified when the line caps change.
-* Core ETel API Request.
-*
-* @param aTsyReqHandle	The TSY handle associated with this request.
-* @param aCaps			The capability structure that will be populated with the new capability
-*						information.
-* @return TInt			Standard error code.
-*/
-	{
-	__ASSERT_ALWAYS(!iNotifyCapsChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
-	iNotifyCapsChange.iNotifyPending=ETrue;
-	iNotifyCapsChange.iNotifyHandle=aTsyReqHandle;
-	iNotifyCapsChange.iNotifyData=aCaps;
-	return KErrNone;
-	}
-
-TInt CSimLine::NotifyCapsChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when the call capabilities change.
-* Core ETel API Request.
-*/
-	{
-	if(iNotifyCapsChange.iNotifyPending)
-		{
-		iNotifyCapsChange.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrCancel);
-		}
-	return KErrNone;
-	}
-
-TInt CSimLine::GetInfo(const TTsyReqHandle aTsyReqHandle, RMobileLine::TLineInfo* aLineInfo)
-/**
-* Retrieve the Line Information
-* Core ETel API Request.
-*
-* @param aTsyReqHandle
-* @param aLineInfo pointer to the line information to be returned to client
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::GetInfo");
-	aLineInfo->iHookStatus=iHookState;
-	aLineInfo->iStatus=(RCall::TStatus)iState;
-	aLineInfo->iNameOfLastCallAdded.Copy(iNameOfLastCallAdded);
-	if(iAnswerNextIncomingCall)
-		aLineInfo->iNameOfCallForAnswering.Copy(iAnswerNextIncomingCall->iName);
-	else
-		aLineInfo->iNameOfCallForAnswering.Zero();
-
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	LOGLINE1("<<CSimLine::GetInfo");
-	return KErrNone;
-	}
-
-
-RCall::TStatus CSimLine::GetCoreLineStatus()
-/**
-* Converts Multimode call status (RMobileCall::TMobileCallStatus) to 
-*          Core call Status (RCall::TStatus)
-*
-* @return RCall::TStatus The core call status
-*/
-	{
-// All status enums with values of Disconnecting and below are identical in
-// ETelMM and Core, so the mapping function is simple.
-	RCall::TStatus coreStatus;
-	if (iState <= RMobileCall::EStatusDisconnecting)
-		coreStatus = (RCall::TStatus)iState;
-	else
-		switch (iState)
-		{
-		case RMobileCall::EStatusReconnectPending:
-		case RMobileCall::EStatusHold:
-			coreStatus = RCall::EStatusConnected;
-			break;
-		case RMobileCall::EStatusWaitingAlternatingCallSwitch:
-			coreStatus = RCall::EStatusIdle;
-			break;
-		default:
-			coreStatus = RCall::EStatusUnknown;
-			break;
-		}
-	return coreStatus;
-	}
-
-TInt CSimLine::GetStatus(const TTsyReqHandle aTsyReqHandle,RCall::TStatus* aLineStatus)
-/**
-* Return the current line state. (Core API request)
-* Core ETel API Request.
-*
-* @param aTsyReqHandle
-* @param aLineStatus pointer to the line status
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::GetStatus");
-	*aLineStatus=GetCoreLineStatus();
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	LOGLINE1("<<CSimLine::GetStatus");
-	return KErrNone;
-	}
-
-TInt CSimLine::GetMobileLineStatus(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aLineStatus)
-/**
-* Return the current line state. (MultiMode API request)
-* MM ETel API Request.
-*
-* @param aTsyReqHandle
-* @param aLineStatus pointer to the line status
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::GetMobileLineStatus");
-	*aLineStatus=iState;
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	LOGLINE1("<<CSimLine::GetMobileLineStatus");
-	return KErrNone;
-	}
-
-TInt CSimLine::GetHookStatus(const TTsyReqHandle aTsyReqHandle,RCall::THookStatus* aHookStatus)
-/**
-* Return the current Hook state. 
-* Core ETel API Request.
-*
-* @param aTsyReqHandle
-* @param aHookStatus pointer to the hook status
-* @return KErrNone
-*/
-	{
-	LOGLINE1(">>CSimLine::GetHookStatus");
-	*aHookStatus=iHookState;
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	LOGLINE1("<<CSimLine::GetHookStatus");
-	return KErrNone;
-	}
-
-const CTestConfigSection* CSimLine::CfgFile()
-/**
-* Returns a pointer to the config file section
-*
-* @return CTestConfig a pointer to the configuration file data section
-*/
-	{
-	LOGLINE1(">>CSimLine::CfgFile");
-	return iPhone->CfgFile();
-	}
-
-TInt CSimLine::ChangeStateL(RMobileCall::TMobileCallStatus aNewState,TBool aSwap,CSimCall* aOriginatingCall)
-/**
-* Validate and change the Line State
-*
-* @param aNewState the new state to change to
-* @param aSwap indicates whether change comes from swap operation on the call
-* @param aOriginatingCall original call that change comes from
-* @return Error indication if change of state is successful or not
-*/
-	{
-	__ASSERT_ALWAYS(aNewState!=RMobileCall::EStatusUnknown,SimPanic(ECallStatusUnknownIllegal));
-	__ASSERT_ALWAYS(iState!=RMobileCall::EStatusUnknown,SimPanic(ECallStatusUnknownIllegal));
-	CSimCall* swappedCall=NULL;
-	TInt i=0;
-	TInt count=iCalls->Count();
-	for(i=0;i<count;i++)
-		{
-		LOGLINE3(">>CSimLine::ChangeState0 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
-		}
-	
-	TInt ret=KErrGeneral;
-	const TStateChangeValidity* stateChangePnt=KLineStateChangeValidity;
-	while(stateChangePnt->iOldState!=KStateTableTerminator)
-		{
-		if((stateChangePnt->iOldState==iState) && 
-			((stateChangePnt->iNewState==aNewState) || aNewState==RMobileCall::EStatusIdle))
-			{
-			ret=stateChangePnt->iError;
-			break;
-			}
-		stateChangePnt++;
-		}
-
-    //coverity[cannot_single]	
-	if(ret!=KErrNone && !(aSwap && iState==RMobileCall::EStatusConnected && aNewState==RMobileCall::EStatusConnected))
-		return ret;
- 
-	LOGLINE2(">>CSimLine::ChangeState 0x%08x",aOriginatingCall);
-	if(aNewState==RMobileCall::EStatusIdle)
-		{
-		if(iState==RMobileCall::EStatusIdle)
-			return KErrAlreadyExists;
-		else if(iState==RMobileCall::EStatusDisconnecting || iState==RMobileCall::EStatusDialling)
-			{
-			TInt i=0;
-			TInt count=iCalls->Count();
-			for(i=0;i<count;i++)
-				{
-				LOGLINE3(">>CSimLine::ChangeState1 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
-	
-				if(aOriginatingCall!=iCalls->At(i) && iCalls->At(i)->iState != RMobileCall::EStatusIdle)
-					{
-					aNewState=iCalls->At(i)->iState;
-					break;
-					}
-				}
-			}		
-		}
-	else if(aNewState==RMobileCall::EStatusHold)
-		{
-		if((iState == RMobileCall::EStatusRinging) && 
-			(aNewState == RMobileCall::EStatusHold))
-			{
-			if(aOriginatingCall->iState != RMobileCall::EStatusConnected)
-				return KErrGeneral;			
-			aNewState=RMobileCall::EStatusRinging;
-			}
-		TInt i=0;
-		TInt count=iCalls->Count();
-		for(i=0;i<count;i++)
-			{
-			LOGLINE3(">>CSimLine::ChangeState1 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
-			if(iCalls->At(i) != aOriginatingCall && iCalls->At(i)->iState == RMobileCall::EStatusHold)
-				{
-				if(aSwap)
-					{
-					swappedCall=iCalls->At(i);
-					swappedCall->iState=RMobileCall::EStatusConnected;
-					aNewState=RMobileCall::EStatusConnected;
-					}
-				else
-					return KErrAlreadyExists;
-				}
-			}	
-		}
-	else if(aNewState==RMobileCall::EStatusConnected)
-		{
-		TInt i=0;
-		TInt count=iCalls->Count();
-		for(i=0;i<count;i++)
-			{
-			LOGLINE3(">>CSimLine::ChangeState1 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
-			if(iCalls->At(i) != aOriginatingCall)
-				{
-				if(iCalls->At(i)->iState == RMobileCall::EStatusConnected)
-					{
-                    //coverity[dead_error_condition]					
-					if(aSwap)
-						{
-						swappedCall=iCalls->At(i);
-						swappedCall->iState=RMobileCall::EStatusHold;
-						aNewState=RMobileCall::EStatusConnected;
-						break;
-						}
-					else
-                        //coverity[dead_error_line]					    
-						return KErrAlreadyExists;
-					}			
-				}
-			}	
-		}
-
-	// Actually change the state.
-	LOGLINE3(">>CSimLine::ChangeState [oldState=%d]  [newState=%d]", iState, aNewState);
-	
-	if(iState != aNewState)
-		{
-		iState=aNewState;
-
-		// Check for a pending line state notification (core)
-		if(iNotifyStatusChange.iNotifyPending)
-			{
-			iNotifyStatusChange.iNotifyPending=EFalse;
-			*(RCall::TStatus*)iNotifyStatusChange.iNotifyData=GetCoreLineStatus();
-			ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
-			}
-
-		// Check for a pending line state notification (multimode)
-		if(iNotifyMobileStatusChange.iNotifyPending)
-			{
-			iNotifyMobileStatusChange.iNotifyPending=EFalse;
-			*(RMobileCall::TMobileCallStatus*)iNotifyMobileStatusChange.iNotifyData=iState;
-			ReqCompleted(iNotifyMobileStatusChange.iNotifyHandle,KErrNone);
-			}
-
-		// Check for a pending hook state notification.
-		if(iHookState!=ConvertStateToHook(iState))
-			{
-			iHookState=ConvertStateToHook(iState);
-			if(iNotifyHookChange.iNotifyPending)
-				{
-				iNotifyHookChange.iNotifyPending=EFalse;
-				*(RCall::THookStatus*)iNotifyHookChange.iNotifyData=iHookState;
-				ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrNone);
-				}
-			}
-		}
-	// Check for a possible change in capabilities.
-	TUint caps=Caps();
-	if(iCaps!=caps)
-		{
-		iCaps=caps;
-		if(iNotifyCapsChange.iNotifyPending)
-			{
-			iNotifyCapsChange.iNotifyPending=EFalse;
-			((RLine::TCaps*)iNotifyCapsChange.iNotifyData)->iFlags=iCaps;
-			ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrNone);
-			}
-		}
-
-	if(aSwap && swappedCall)
-		swappedCall->UpdateNotifiers();
-	// Request that the phone change its state, to ensure its in step.
-	if((ret = iPhone->ValidateChangeState(this,aNewState)) != KErrNone)
-		return ret;
-
-	for(i=0;i<iCalls->Count();i++)
-		{
-	LOGLINE3(">>CSimLine::ChangeState5 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
-		}
-	
-	LOGLINE1("<<CSimLine::ChangeState");
-	return KErrNone;
-	}
-
-void CSimLine::SimPSEvent(const CSimPubSub::TPubSubProperty aProperty, TInt /*aStatus*/)
-/**
-Handles the P&S notifications for the Line class
-
-@param aProperty The property key representing the notification. 
-*/
-	{
-	LOGLINE1(">>CSimLine::SimPSEvent");
-	if(aProperty==iICProperty) // check for this here still, start the timer for amount specified in config file.
-		ProcessIncomingCallEvent();
-	if(aProperty==iRHProperty)
-		ProcessRemoteHangupEvent();
-	LOGLINE1("<<CSimLine::SimPSEvent");
-	}
-
-TInt CSimLine::SetAutoAnswerCallObject(CSimCall* aCallObject)
-/**
-* Attempt to set the call object that will be used to answer the next incoming
-* call.  If there is already an AnswerIncomingCall registered, then
-* return with the relevant error.
-*
-* @param aCallObject pointer to the call object
-* @return KErrNone if successful
-*/
-	{
-	LOGLINE1(">>CSimLine::SetAnswerCallObject");
-	if(iAnswerIncomingCallReqPending)			// Is there a request already outstanding?
-		return KErrEtelAnswerAlreadyOutstanding;
-
-	iAnswerIncomingCallReqPending=ETrue;
-	if (iAnswerNextIncomingCall!=aCallObject)
-		{
-		if (iSpareCall != iAnswerNextIncomingCall)
-			{
-			iAnswerNextIncomingCall->Close();
-			}
-		iAnswerNextIncomingCall=aCallObject;		// Set the "answer next call" object
-		iAnswerNextIncomingCall->Open();
-		}
-	LOGLINE1("<<CSimLine::SetAnswerCallObject");
-	return KErrNone;
-	}
-
-void CSimLine::ResetAutoAnswerCallObject(CSimCall* aCallObject)
-/**
-* This function is used to reset, or effectively cancel, the call object that
-* was to be used to automatically answer the next incoming call.
-*
-* @param aCallObject pointer to the call object
-*/
-	{
-	LOGLINE1(">>CSimLine::ResetAnswerCallObject");
-	__ASSERT_ALWAYS(iAnswerNextIncomingCall==aCallObject,SimPanic(EIllegalAnswerNextIncomingCallInconsistancy));
-	iAnswerNextIncomingCall->Close();
-	iAnswerNextIncomingCall=iSpareCall;
-	iAnswerIncomingCallReqPending=EFalse;
-	}
-
-void CSimLine::ProcessIncomingCallEvent()
-/**
-* Process an incoming call event.
-*/
-	{
-	LOGLINE1(">>CSimLine::ProcessIncomingCallEvent ");
-
-	if (iSpareCall == iAnswerNextIncomingCall)
-		{
-		TName callName;
-		TRAPD(err,iAnswerNextIncomingCall=CreateNewCallL(callName,ECallTypeNormalCall));
-		if (err!=KErrNone)
-			{
-			SimPanic(EOjectNotConstructed);
-			}
-		}
-	
-	// Delay sending the notification of an incoming call if
-	// one has been set.
-	iTimer->Start(iNotifyIncomingCallPause, this);
-	
-	__ASSERT_ALWAYS(iAnswerNextIncomingCall->ActionEvent(CSimCall::ECallEventIncomingCall,KErrNone) == KErrNone, SimPanic(EGeneral));
-	LOGLINE1("<<CSimLine::ProcessIncomingCallEvent");
-	}
-
-TInt CSimLine::SetRemoteHangupCallObject(CSimCall* aCallObject)
-/**
-* Attempt to set the call object that will be hung up remotely
-* If there is already a RemoteHangup registered, then
-* return with the relevant error.
-*
-* @param aCallObject pointer to the call object
-* @return KErrNone if successful
-*/
-	{
-	LOGLINE1(">>CSimLine::SetRemoteHangupCallObject");
-	if(iRemoteHangupCallReqPending)			// Is there a request already outstanding?
-		return KErrEtelInitialisationFailure;
-
-	iRemoteHangupCallReqPending=ETrue;
-	if (iRemoteHangupCall!=aCallObject)
-		{
-		iRemoteHangupCall=aCallObject;		// Set the "remote hang up" object
-		}
-	LOGLINE1("<<CSimLine::SetRemoteHangupCallObject");
-	return KErrNone;
-	}
-
-void CSimLine::ResetRemoteHangupCallObject(CSimCall* aCallObject)
-/**
-* This function is used to reset, or effectively cancel, the call object that
-* was to be remotely hung up.
-*
-* @param aCallObject pointer to the call object
-*/
-	{
-	LOGLINE1(">>CSimLine::ResetRemoteHangupCallObject");
-	__ASSERT_ALWAYS(iRemoteHangupCall==aCallObject,SimPanic(EIllegalAnswerRemoteHangupCallInconsistency));
-	iRemoteHangupCallReqPending=EFalse;
-	}
-
-void CSimLine::ProcessRemoteHangupEvent()
-/**
-* Process a remote hangup event.
-*/
-	{
-	LOGLINE1(">>CSimLine::ProcessRemoteHangupEvent");
-
-	if (iRemoteHangupCall == NULL)
-		{
-		TInt err = FindActiveCall(iRemoteHangupCall);
-		if(err == KErrNone)
-			{
-			err = iRemoteHangupCall->ActionEvent(CSimCall::ECallEventRemoteHangup,KErrNone);
-			if(err != KErrNone)
-				{
-				LOGLINE2("ERROR: CSimLine::ProcessRemoteHangupEvent returned: %d", err);
-				}
-			}
-		else
-			{
-			LOGLINE1("No outstanding call to hang up remotely");
-			}
-		}
-	LOGLINE1("<<CSimLine::ProcessRemoteHangupEvent");
-	}
-
-void CSimLine::CallDestructor(CSimCall* aCall)
-/**
- * This function is called from a call's destructor.
- * It must delete the call from its list.  If the call cannot be found, an unacceptable
- * inconsistancy must have developed, and the TSY will panic.
- */
-	{
-	for(TInt i=0;i<iCalls->Count();i++)
-		{
-		if(iCalls->At(i)==aCall)
-			{
-			iCalls->Delete(i);
-			return;
-			}
-		}
-	SimPanic(EIllegalCallNotRegisteredWithLine);
-	}
-
-TBool CSimLine::IsAnswerCallObjectSpare()
-/**
- * Is the "answer" call object actually the spare object.
- */
-	{
-	return (iSpareCall==iAnswerNextIncomingCall);
-	}
-
-/**
-Called when iTimer has delayed the sending of the notification of the incoming call.
-*/
-void CSimLine::TimerCallBack(TInt /*aId*/)
-	{
-	ProcessNotifyIncomingCallEvent();
-	}
-
-/**
-Send notification of an incoming call.
-*/
-void CSimLine::ProcessNotifyIncomingCallEvent()
-	{
-	LOGLINE1(">>CSimLine::ProcessNotifyIncomingCallEvent");	
-	if(iNotifyIncomingCall.iNotifyPending)
-		{
-		iNotifyIncomingCall.iNotifyPending=EFalse;
-		((TName*)iNotifyIncomingCall.iNotifyData)->Copy(iAnswerNextIncomingCall->iName);
-		ReqCompleted(iNotifyIncomingCall.iNotifyHandle,KErrNone);
-		}
-	LOGLINE1("<<CSimLine::ProcessNotifyIncomingCallEvent");	
-	}
-
+
+// 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:
+// This file contains the implementation for the functionality common to all 
+// the specific line classes, such as CSimVoiceLine and CSimDataline.
+// 
+//
+
+/**
+ @file
+*/
+
+#include <testconfigfileparser.h>
+#include "CSimLine.h"
+#include "CSimPhone.h"
+#include "CSimCall.h"
+#include "Simlog.h"
+#include "CSimPubSub.h"
+
+void CSimLine::CloseLine(TAny* aObj)
+/**
+*	Utility func for cleanup stack
+*
+* @param aObj a pointer to the CObject to close
+*/
+	{
+	((CObject*)aObj)->Close();
+	}
+
+CSimLine::CSimLine(CSimPhone* aPhone)
+			:iPhone(aPhone), iState(RMobileCall::EStatusIdle), 
+			iHookState(ConvertStateToHook(iState))
+	{
+	iNameOfLastCallAdded.Zero();
+	iNotifyStatusChange.iNotifyPending = EFalse;
+	iNotifyMobileStatusChange.iNotifyPending = EFalse;
+	}
+
+void CSimLine::ConstructL(const TName& aName)
+/**
+* Second phase of two phase constructor.
+* Creates the System Agent object for incoming call notification and other notifications.
+*
+* @param aName name of the Line to be created.
+*/
+	{
+	LOGLINE2(">>CSimLine::ConstructL [aLineName=%S]", &aName);
+	iLineName = aName;
+	iSimPubSubIC = CSimPubSub::NewL(this,iICProperty);
+	iSimPubSubIC->Start();
+
+	iSimPubSubRH = CSimPubSub::NewL(this,iRHProperty);
+	iSimPubSubRH->Start();
+	
+	iNotifyIncomingCallPause=this->CfgFile()->ItemValue(KNotifyIncomingCallPauseDuration,KDefaultNotifyIncomingCallPauseDuration);
+	
+	iTimer = CSimTimer::NewL(iPhone);
+		LOGLINE1("<<CSimLine::ConstructL");
+}
+
+CSimLine::~CSimLine()
+/**
+*	Standard destructor.
+*/
+	{
+	delete iSimPubSubIC;
+	delete iSimPubSubRH;
+	iTimer->Cancel();
+	delete iTimer;
+	}
+
+
+void CSimLine::UpdatePhoneNotifiers(CSimCall* aCall,TUint /*aStatus*/)
+	{
+		TInt count=	iCalls->Count();
+		TInt i=0;
+		while(i<count)
+		{
+ 		if(iCalls->At(i) != aCall && (iCalls->At(i)->iState == RMobileCall::EStatusHold || iCalls->At(i)->iState == RMobileCall::EStatusConnected))
+			iCalls->At(i)->UpdateNotifiers();
+		i++;
+		}	
+	}
+
+CTelObject::TReqMode CSimLine::ReqModeL(const TInt aIpc)
+/**
+* This function returns the Request Mode for the request with the passed IPC value.
+* The ETel Server provides a function for returning the standard request modes for 
+* the Core API requests.
+* Multimode API requests mode are handled here.
+*
+* @param aIpc the IPc number representing the client request
+* @return CTelObject::TReqMode the request mode to be used for this IPc number
+* @leave Leaves if the IPc number is not found
+*/
+	{
+	// ReqModeL is called from the server's CTelObject::ReqAnalyserL
+	// in order to check the type of request it has
+
+	CTelObject::TReqMode reqMode=0;
+	switch (aIpc)
+		{
+//
+// No Flow Control NOR Multiple Completion
+//
+	case EMobileLineGetMobileLineStatus:
+		break;
+
+//
+// Multiple Completion Services with Immediate Server Repost
+// (Usually Notifications)
+//
+	case EMobileLineNotifyMobileLineStatusChange:
+		reqMode=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
+		break;
+//
+// Must be a core API request so get request mode from Etel
+//
+	default:
+		reqMode=CLineBase::ReqModeL(aIpc);
+		break;
+		}
+
+	return reqMode;
+	}
+
+
+TInt CSimLine::NumberOfSlotsL(const TInt aIpc)
+/**
+* NumberOfSlotsL is called by the server when it is registering a new notification
+* It enables the TSY to tell the server how many buffer slots to allocate for
+* "repost immediately" notifications that may trigger before clients collect them
+*
+* @param aIpc the IPc number representing the client request
+* @return TInt the number of slots required
+* @leave Leaves if the IPc number is not found
+*/
+	{
+	switch (aIpc)
+		{
+	case EMobileLineNotifyMobileLineStatusChange:
+		LOGLINE1("CLineMobile: Registered with the default number of slots");
+		return KDefaultNumberOfSlots;
+
+	default:
+		LOGLINE1("CSimLine::NumberOfSlotsL: No match for IPC, defering to base function");
+		break;
+		}
+	return CLineBase::NumberOfSlotsL(aIpc);
+	}
+
+
+TInt CSimLine::RegisterNotification(const TInt /*aIpc*/)
+/**
+* The ETel Server calls this function when the first client makes a notification request.
+* If supported by the underlying protocol controlling the signalling stack, 
+* this can be used to start requesting updates for the relevant service.
+*/
+	{
+	return KErrNone;
+	}
+
+TInt CSimLine::DeregisterNotification(const TInt /*aIpc*/)
+/**
+* The ETel Server calls this function when the last client that had previously
+* made a notification request closes its ETel Server handle.  If supported by
+* the underlying protocol controlling the	signalling stack, this can be used
+* to stop requesting updates for the relevant service.
+*/
+	{
+	return KErrNone;
+	}
+
+void CSimLine::Init()
+/**
+*	This function can be used to perform any necessary synchronous initialisation.
+*/
+	{}
+
+TInt CSimLine::NotifyIncomingCall(const TTsyReqHandle aTsyReqHandle, TName* aName)
+/**
+* Register a client's interest in an incoming call notification.
+* Core ETel API Request.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aName pointer to the name of the call
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyIncomingCall");
+	iNotifyIncomingCall.iNotifyPending=ETrue;
+	iNotifyIncomingCall.iNotifyHandle=aTsyReqHandle;
+	iNotifyIncomingCall.iNotifyData=(TAny*)aName;
+	LOGLINE1("<<CSimLine::NotifyIncomingCall");
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyIncomingCallCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancels a client's interest in an incoming call.
+* Core ETel API Request.
+*
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyIncomingCallCancel");
+	if(iNotifyIncomingCall.iNotifyPending)
+		{
+		iTimer->Cancel();
+		iNotifyIncomingCall.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyIncomingCall.iNotifyHandle, KErrCancel);
+		}
+	LOGLINE1("<<CSimLine::NotifyIncomingCallCancel");
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyHookChange(const TTsyReqHandle aTsyReqHandle, RCall::THookStatus* aHookStatus)
+/**
+* Record a client's interst in being notified when the line hook changes state.
+* Core ETel API Request.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aHookStatus pointer to the line hook
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyHookChange");
+	iNotifyHookChange.iNotifyPending=ETrue;
+	iNotifyHookChange.iNotifyHandle=aTsyReqHandle;
+	iNotifyHookChange.iNotifyData=(TAny*)aHookStatus;
+	LOGLINE1("<<CSimLine::NotifyHookChange");
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyHookChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when the line hook changes state.
+* Core ETel API Request.
+*
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyHookChangeCancel");
+	if(iNotifyHookChange.iNotifyPending)
+		{
+		iNotifyHookChange.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrCancel);
+		}
+	LOGLINE1("<<CSimLine::NotifyHookChangeCancel");
+	return KErrNone;
+	}
+
+
+TInt CSimLine::NotifyMobileLineStatusChange(const TTsyReqHandle aTsyReqHandle, RMobileCall::TMobileCallStatus* aStatus)
+/**
+* Record a client's interst in being notified when the line changes state. (Multimode)
+* MM ETel API Request.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aStatus pointer to the line status
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyMobileLineStatusChange");
+	iNotifyMobileStatusChange.iNotifyPending=ETrue;
+	iNotifyMobileStatusChange.iNotifyHandle=aTsyReqHandle;
+	iNotifyMobileStatusChange.iNotifyData=aStatus;
+	LOGLINE1("<<CSimLine::NotifyMobileLineStatusChange");
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyMobileLineStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when the line changes state.(Multimode Request)
+* MM ETel API Request.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyMobileLineStatusChangeCancel");
+	if(iNotifyMobileStatusChange.iNotifyPending)
+		{
+		iNotifyMobileStatusChange.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyMobileStatusChange.iNotifyHandle,KErrCancel);
+		}
+	LOGLINE1("<<CSimLine::NotifyMobileLineStatusChangeCancel");
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle, RCall::TStatus* aStatus)
+/**
+* Record a client's interst in being notified when the line changes state. (Core)
+* Core ETel API Request.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aStatus pointer to the line status
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyStatusChange");
+	iNotifyStatusChange.iNotifyPending=ETrue;
+	iNotifyStatusChange.iNotifyHandle=aTsyReqHandle;
+	iNotifyStatusChange.iNotifyData=aStatus;
+	LOGLINE1("<<CSimLine::NotifyStatusChange");
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when the line changes state.(Multimode Request)
+* Core ETel API Request.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyStatusChangeCancel");
+	if(iNotifyStatusChange.iNotifyPending)
+		{
+		iNotifyStatusChange.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrCancel);
+		}
+	LOGLINE1("<<CSimLine::NotifyStatusChangeCancel");
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyCallAdded(const TTsyReqHandle aTsyReqHandle,TName* aName)
+/**
+* Record a client's interest in being notified when a new call is added.
+* Core ETel API Request.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aName pointer to the name of the call
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyCallAdded");
+	iNotifyCallAdded.iNotifyPending=ETrue;
+	iNotifyCallAdded.iNotifyHandle=aTsyReqHandle;
+	iNotifyCallAdded.iNotifyData=(TAny*)aName;
+	LOGLINE1("<<CSimLine::NotifyCallAdded");
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyCallAddedCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when a new call is added.
+* Core ETel API Request.
+*
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::NotifyCallAddedCancel");
+	if(iNotifyCallAdded.iNotifyPending)
+		{
+		iNotifyCallAdded.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyCallAdded.iNotifyHandle,KErrCancel);
+		}
+	LOGLINE1("<<CSimLine::NotifyCallAddedCancel");
+	return KErrNone;
+	}
+
+
+void CSimLine::HandleNewCallAddedNotification(const TDesC& aNewName)
+/**
+* Process a potential "New Call Added Notification" completion.
+*/
+	{
+	LOGLINE1(">>CSimLine::HandleNewCallAddedNotification");
+	iNameOfLastCallAdded.Copy(aNewName);
+	if(iNotifyCallAdded.iNotifyPending)
+		{
+		iNotifyCallAdded.iNotifyPending=EFalse;
+		((TName*)iNotifyCallAdded.iNotifyData)->Copy(aNewName);
+		ReqCompleted(iNotifyCallAdded.iNotifyHandle,KErrNone);
+		}
+	LOGLINE1("<<CSimLine::HandleNewCallAddedNotification");
+	}
+
+TInt CSimLine::GetCaps(const TTsyReqHandle aTsyReqHandle, RLine::TCaps* aCaps)
+/**
+ * Retrieve the current line capabilities.
+ * Core ETel API Request.
+ *
+ * @param aTsyReqHandle		TSY request handle associated with this request.
+ * @param aCaps				Point to capability structure that will be populated with the caps.
+ * @return TInt				Standard return value.
+ */
+	{
+	aCaps->iFlags=iCaps;
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RLine::TCaps* aCaps)
+/**
+* Register a client's interest in being notified when the line caps change.
+* Core ETel API Request.
+*
+* @param aTsyReqHandle	The TSY handle associated with this request.
+* @param aCaps			The capability structure that will be populated with the new capability
+*						information.
+* @return TInt			Standard error code.
+*/
+	{
+	__ASSERT_ALWAYS(!iNotifyCapsChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
+	iNotifyCapsChange.iNotifyPending=ETrue;
+	iNotifyCapsChange.iNotifyHandle=aTsyReqHandle;
+	iNotifyCapsChange.iNotifyData=aCaps;
+	return KErrNone;
+	}
+
+TInt CSimLine::NotifyCapsChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when the call capabilities change.
+* Core ETel API Request.
+*/
+	{
+	if(iNotifyCapsChange.iNotifyPending)
+		{
+		iNotifyCapsChange.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrCancel);
+		}
+	return KErrNone;
+	}
+
+TInt CSimLine::GetInfo(const TTsyReqHandle aTsyReqHandle, RMobileLine::TLineInfo* aLineInfo)
+/**
+* Retrieve the Line Information
+* Core ETel API Request.
+*
+* @param aTsyReqHandle
+* @param aLineInfo pointer to the line information to be returned to client
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::GetInfo");
+	aLineInfo->iHookStatus=iHookState;
+	aLineInfo->iStatus=(RCall::TStatus)iState;
+	aLineInfo->iNameOfLastCallAdded.Copy(iNameOfLastCallAdded);
+	if(iAnswerNextIncomingCall)
+		aLineInfo->iNameOfCallForAnswering.Copy(iAnswerNextIncomingCall->iName);
+	else
+		aLineInfo->iNameOfCallForAnswering.Zero();
+
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	LOGLINE1("<<CSimLine::GetInfo");
+	return KErrNone;
+	}
+
+
+RCall::TStatus CSimLine::GetCoreLineStatus()
+/**
+* Converts Multimode call status (RMobileCall::TMobileCallStatus) to 
+*          Core call Status (RCall::TStatus)
+*
+* @return RCall::TStatus The core call status
+*/
+	{
+// All status enums with values of Disconnecting and below are identical in
+// ETelMM and Core, so the mapping function is simple.
+	RCall::TStatus coreStatus;
+	if (iState <= RMobileCall::EStatusDisconnecting)
+		coreStatus = (RCall::TStatus)iState;
+	else
+		switch (iState)
+		{
+		case RMobileCall::EStatusReconnectPending:
+		case RMobileCall::EStatusHold:
+			coreStatus = RCall::EStatusConnected;
+			break;
+		case RMobileCall::EStatusWaitingAlternatingCallSwitch:
+			coreStatus = RCall::EStatusIdle;
+			break;
+		default:
+			coreStatus = RCall::EStatusUnknown;
+			break;
+		}
+	return coreStatus;
+	}
+
+TInt CSimLine::GetStatus(const TTsyReqHandle aTsyReqHandle,RCall::TStatus* aLineStatus)
+/**
+* Return the current line state. (Core API request)
+* Core ETel API Request.
+*
+* @param aTsyReqHandle
+* @param aLineStatus pointer to the line status
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::GetStatus");
+	*aLineStatus=GetCoreLineStatus();
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	LOGLINE1("<<CSimLine::GetStatus");
+	return KErrNone;
+	}
+
+TInt CSimLine::GetMobileLineStatus(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aLineStatus)
+/**
+* Return the current line state. (MultiMode API request)
+* MM ETel API Request.
+*
+* @param aTsyReqHandle
+* @param aLineStatus pointer to the line status
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::GetMobileLineStatus");
+	*aLineStatus=iState;
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	LOGLINE1("<<CSimLine::GetMobileLineStatus");
+	return KErrNone;
+	}
+
+TInt CSimLine::GetHookStatus(const TTsyReqHandle aTsyReqHandle,RCall::THookStatus* aHookStatus)
+/**
+* Return the current Hook state. 
+* Core ETel API Request.
+*
+* @param aTsyReqHandle
+* @param aHookStatus pointer to the hook status
+* @return KErrNone
+*/
+	{
+	LOGLINE1(">>CSimLine::GetHookStatus");
+	*aHookStatus=iHookState;
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	LOGLINE1("<<CSimLine::GetHookStatus");
+	return KErrNone;
+	}
+
+const CTestConfigSection* CSimLine::CfgFile()
+/**
+* Returns a pointer to the config file section
+*
+* @return CTestConfig a pointer to the configuration file data section
+*/
+	{
+	LOGLINE1(">>CSimLine::CfgFile");
+	return iPhone->CfgFile();
+	}
+
+TInt CSimLine::ChangeStateL(RMobileCall::TMobileCallStatus aNewState,TBool aSwap,CSimCall* aOriginatingCall)
+/**
+* Validate and change the Line State
+*
+* @param aNewState the new state to change to
+* @param aSwap indicates whether change comes from swap operation on the call
+* @param aOriginatingCall original call that change comes from
+* @return Error indication if change of state is successful or not
+*/
+	{
+	__ASSERT_ALWAYS(aNewState!=RMobileCall::EStatusUnknown,SimPanic(ECallStatusUnknownIllegal));
+	__ASSERT_ALWAYS(iState!=RMobileCall::EStatusUnknown,SimPanic(ECallStatusUnknownIllegal));
+	CSimCall* swappedCall=NULL;
+	TInt i=0;
+	TInt count=iCalls->Count();
+	for(i=0;i<count;i++)
+		{
+		LOGLINE3(">>CSimLine::ChangeState0 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
+		}
+	
+	TInt ret=KErrGeneral;
+	const TStateChangeValidity* stateChangePnt=KLineStateChangeValidity;
+	while(stateChangePnt->iOldState!=KStateTableTerminator)
+		{
+		if((stateChangePnt->iOldState==iState) && 
+			((stateChangePnt->iNewState==aNewState) || aNewState==RMobileCall::EStatusIdle))
+			{
+			ret=stateChangePnt->iError;
+			break;
+			}
+		stateChangePnt++;
+		}
+
+    //coverity[cannot_single]	
+	if(ret!=KErrNone && !(aSwap && iState==RMobileCall::EStatusConnected && aNewState==RMobileCall::EStatusConnected))
+		return ret;
+ 
+	LOGLINE2(">>CSimLine::ChangeState 0x%08x",aOriginatingCall);
+	if(aNewState==RMobileCall::EStatusIdle)
+		{
+		if(iState==RMobileCall::EStatusIdle)
+			return KErrAlreadyExists;
+		else if(iState==RMobileCall::EStatusDisconnecting || iState==RMobileCall::EStatusDialling)
+			{
+			TInt i=0;
+			TInt count=iCalls->Count();
+			for(i=0;i<count;i++)
+				{
+				LOGLINE3(">>CSimLine::ChangeState1 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
+	
+				if(aOriginatingCall!=iCalls->At(i) && iCalls->At(i)->iState != RMobileCall::EStatusIdle)
+					{
+					aNewState=iCalls->At(i)->iState;
+					break;
+					}
+				}
+			}		
+		}
+	else if(aNewState==RMobileCall::EStatusHold)
+		{
+		if((iState == RMobileCall::EStatusRinging) && 
+			(aNewState == RMobileCall::EStatusHold))
+			{
+			if(aOriginatingCall->iState != RMobileCall::EStatusConnected)
+				return KErrGeneral;			
+			aNewState=RMobileCall::EStatusRinging;
+			}
+		TInt i=0;
+		TInt count=iCalls->Count();
+		for(i=0;i<count;i++)
+			{
+			LOGLINE3(">>CSimLine::ChangeState1 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
+			if(iCalls->At(i) != aOriginatingCall && iCalls->At(i)->iState == RMobileCall::EStatusHold)
+				{
+				if(aSwap)
+					{
+					swappedCall=iCalls->At(i);
+					swappedCall->iState=RMobileCall::EStatusConnected;
+					aNewState=RMobileCall::EStatusConnected;
+					}
+				else
+					return KErrAlreadyExists;
+				}
+			}	
+		}
+	else if(aNewState==RMobileCall::EStatusConnected)
+		{
+		TInt i=0;
+		TInt count=iCalls->Count();
+		for(i=0;i<count;i++)
+			{
+			LOGLINE3(">>CSimLine::ChangeState1 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
+			if(iCalls->At(i) != aOriginatingCall)
+				{
+				if(iCalls->At(i)->iState == RMobileCall::EStatusConnected)
+					{
+                    //coverity[dead_error_condition]					
+					if(aSwap)
+						{
+						swappedCall=iCalls->At(i);
+						swappedCall->iState=RMobileCall::EStatusHold;
+						aNewState=RMobileCall::EStatusConnected;
+						break;
+						}
+					else
+                        //coverity[dead_error_line]					    
+						return KErrAlreadyExists;
+					}			
+				}
+			}	
+		}
+
+	// Actually change the state.
+	LOGLINE3(">>CSimLine::ChangeState [oldState=%d]  [newState=%d]", iState, aNewState);
+	
+	if(iState != aNewState)
+		{
+		iState=aNewState;
+
+		// Check for a pending line state notification (core)
+		if(iNotifyStatusChange.iNotifyPending)
+			{
+			iNotifyStatusChange.iNotifyPending=EFalse;
+			*(RCall::TStatus*)iNotifyStatusChange.iNotifyData=GetCoreLineStatus();
+			ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
+			}
+
+		// Check for a pending line state notification (multimode)
+		if(iNotifyMobileStatusChange.iNotifyPending)
+			{
+			iNotifyMobileStatusChange.iNotifyPending=EFalse;
+			*(RMobileCall::TMobileCallStatus*)iNotifyMobileStatusChange.iNotifyData=iState;
+			ReqCompleted(iNotifyMobileStatusChange.iNotifyHandle,KErrNone);
+			}
+
+		// Check for a pending hook state notification.
+		if(iHookState!=ConvertStateToHook(iState))
+			{
+			iHookState=ConvertStateToHook(iState);
+			if(iNotifyHookChange.iNotifyPending)
+				{
+				iNotifyHookChange.iNotifyPending=EFalse;
+				*(RCall::THookStatus*)iNotifyHookChange.iNotifyData=iHookState;
+				ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrNone);
+				}
+			}
+		}
+	// Check for a possible change in capabilities.
+	TUint caps=Caps();
+	if(iCaps!=caps)
+		{
+		iCaps=caps;
+		if(iNotifyCapsChange.iNotifyPending)
+			{
+			iNotifyCapsChange.iNotifyPending=EFalse;
+			((RLine::TCaps*)iNotifyCapsChange.iNotifyData)->iFlags=iCaps;
+			ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrNone);
+			}
+		}
+
+	if(aSwap && swappedCall)
+		swappedCall->UpdateNotifiers();
+	// Request that the phone change its state, to ensure its in step.
+	if((ret = iPhone->ValidateChangeState(this,aNewState)) != KErrNone)
+		return ret;
+
+	for(i=0;i<iCalls->Count();i++)
+		{
+	LOGLINE3(">>CSimLine::ChangeState5 0x%08x %d",iCalls->At(i),iCalls->At(i)->iState);
+		}
+	
+	LOGLINE1("<<CSimLine::ChangeState");
+	return KErrNone;
+	}
+
+void CSimLine::SimPSEvent(const CSimPubSub::TPubSubProperty aProperty, TInt /*aStatus*/)
+/**
+Handles the P&S notifications for the Line class
+
+@param aProperty The property key representing the notification. 
+*/
+	{
+	LOGLINE1(">>CSimLine::SimPSEvent");
+	if(aProperty==iICProperty) // check for this here still, start the timer for amount specified in config file.
+		ProcessIncomingCallEvent();
+	if(aProperty==iRHProperty)
+		ProcessRemoteHangupEvent();
+	LOGLINE1("<<CSimLine::SimPSEvent");
+	}
+
+TInt CSimLine::SetAutoAnswerCallObject(CSimCall* aCallObject)
+/**
+* Attempt to set the call object that will be used to answer the next incoming
+* call.  If there is already an AnswerIncomingCall registered, then
+* return with the relevant error.
+*
+* @param aCallObject pointer to the call object
+* @return KErrNone if successful
+*/
+	{
+	LOGLINE1(">>CSimLine::SetAnswerCallObject");
+	if(iAnswerIncomingCallReqPending)			// Is there a request already outstanding?
+		return KErrEtelAnswerAlreadyOutstanding;
+
+	iAnswerIncomingCallReqPending=ETrue;
+	if (iAnswerNextIncomingCall!=aCallObject)
+		{
+		if (iSpareCall != iAnswerNextIncomingCall)
+			{
+			iAnswerNextIncomingCall->Close();
+			}
+		iAnswerNextIncomingCall=aCallObject;		// Set the "answer next call" object
+		iAnswerNextIncomingCall->Open();
+		}
+	LOGLINE1("<<CSimLine::SetAnswerCallObject");
+	return KErrNone;
+	}
+
+void CSimLine::ResetAutoAnswerCallObject(CSimCall* aCallObject)
+/**
+* This function is used to reset, or effectively cancel, the call object that
+* was to be used to automatically answer the next incoming call.
+*
+* @param aCallObject pointer to the call object
+*/
+	{
+	LOGLINE1(">>CSimLine::ResetAnswerCallObject");
+	__ASSERT_ALWAYS(iAnswerNextIncomingCall==aCallObject,SimPanic(EIllegalAnswerNextIncomingCallInconsistancy));
+	iAnswerNextIncomingCall->Close();
+	iAnswerNextIncomingCall=iSpareCall;
+	iAnswerIncomingCallReqPending=EFalse;
+	}
+
+void CSimLine::ProcessIncomingCallEvent()
+/**
+* Process an incoming call event.
+*/
+	{
+	LOGLINE1(">>CSimLine::ProcessIncomingCallEvent ");
+
+	if (iSpareCall == iAnswerNextIncomingCall)
+		{
+		TName callName;
+		TRAPD(err,iAnswerNextIncomingCall=CreateNewCallL(callName,ECallTypeNormalCall));
+		if (err!=KErrNone)
+			{
+			SimPanic(EOjectNotConstructed);
+			}
+		}
+	
+	// Delay sending the notification of an incoming call if
+	// one has been set.
+	iTimer->Start(iNotifyIncomingCallPause, this);
+	
+	__ASSERT_ALWAYS(iAnswerNextIncomingCall->ActionEvent(CSimCall::ECallEventIncomingCall,KErrNone) == KErrNone, SimPanic(EGeneral));
+	LOGLINE1("<<CSimLine::ProcessIncomingCallEvent");
+	}
+
+TInt CSimLine::SetRemoteHangupCallObject(CSimCall* aCallObject)
+/**
+* Attempt to set the call object that will be hung up remotely
+* If there is already a RemoteHangup registered, then
+* return with the relevant error.
+*
+* @param aCallObject pointer to the call object
+* @return KErrNone if successful
+*/
+	{
+	LOGLINE1(">>CSimLine::SetRemoteHangupCallObject");
+	if(iRemoteHangupCallReqPending)			// Is there a request already outstanding?
+		return KErrEtelInitialisationFailure;
+
+	iRemoteHangupCallReqPending=ETrue;
+	if (iRemoteHangupCall!=aCallObject)
+		{
+		iRemoteHangupCall=aCallObject;		// Set the "remote hang up" object
+		}
+	LOGLINE1("<<CSimLine::SetRemoteHangupCallObject");
+	return KErrNone;
+	}
+
+void CSimLine::ResetRemoteHangupCallObject(CSimCall* aCallObject)
+/**
+* This function is used to reset, or effectively cancel, the call object that
+* was to be remotely hung up.
+*
+* @param aCallObject pointer to the call object
+*/
+	{
+	LOGLINE1(">>CSimLine::ResetRemoteHangupCallObject");
+	__ASSERT_ALWAYS(iRemoteHangupCall==aCallObject,SimPanic(EIllegalAnswerRemoteHangupCallInconsistency));
+	iRemoteHangupCallReqPending=EFalse;
+	}
+
+void CSimLine::ProcessRemoteHangupEvent()
+/**
+* Process a remote hangup event.
+*/
+	{
+	LOGLINE1(">>CSimLine::ProcessRemoteHangupEvent");
+
+	if (iRemoteHangupCall == NULL)
+		{
+		TInt err = FindActiveCall(iRemoteHangupCall);
+		if(err == KErrNone)
+			{
+			err = iRemoteHangupCall->ActionEvent(CSimCall::ECallEventRemoteHangup,KErrNone);
+			if(err != KErrNone)
+				{
+				LOGLINE2("ERROR: CSimLine::ProcessRemoteHangupEvent returned: %d", err);
+				}
+			}
+		else
+			{
+			LOGLINE1("No outstanding call to hang up remotely");
+			}
+		}
+	LOGLINE1("<<CSimLine::ProcessRemoteHangupEvent");
+	}
+
+void CSimLine::CallDestructor(CSimCall* aCall)
+/**
+ * This function is called from a call's destructor.
+ * It must delete the call from its list.  If the call cannot be found, an unacceptable
+ * inconsistancy must have developed, and the TSY will panic.
+ */
+	{
+	for(TInt i=0;i<iCalls->Count();i++)
+		{
+		if(iCalls->At(i)==aCall)
+			{
+			iCalls->Delete(i);
+			return;
+			}
+		}
+	SimPanic(EIllegalCallNotRegisteredWithLine);
+	}
+
+TBool CSimLine::IsAnswerCallObjectSpare()
+/**
+ * Is the "answer" call object actually the spare object.
+ */
+	{
+	return (iSpareCall==iAnswerNextIncomingCall);
+	}
+
+/**
+Called when iTimer has delayed the sending of the notification of the incoming call.
+*/
+void CSimLine::TimerCallBack(TInt /*aId*/)
+	{
+	ProcessNotifyIncomingCallEvent();
+	}
+
+/**
+Send notification of an incoming call.
+*/
+void CSimLine::ProcessNotifyIncomingCallEvent()
+	{
+	LOGLINE1(">>CSimLine::ProcessNotifyIncomingCallEvent");	
+	if(iNotifyIncomingCall.iNotifyPending)
+		{
+		iNotifyIncomingCall.iNotifyPending=EFalse;
+		((TName*)iNotifyIncomingCall.iNotifyData)->Copy(iAnswerNextIncomingCall->iName);
+		ReqCompleted(iNotifyIncomingCall.iNotifyHandle,KErrNone);
+		}
+	LOGLINE1("<<CSimLine::ProcessNotifyIncomingCallEvent");	
+	}
+