telephonyserverplugins/simtsy/src/CSimCall.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
--- a/telephonyserverplugins/simtsy/src/CSimCall.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/CSimCall.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,1050 +1,1050 @@
-// 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 of the Simulator TSY call classes.  The call classes
-// process the call-based requests made by ETel clients and passed down to the TSY by the
-// ETel Server.
-// 
-//
-
-/**
- @file
-*/
-
-#include "CSimCall.h"
-#include "CSimPhone.h"
-#include "Simlog.h"
-
-void CSimCall::CloseCall(TAny* aObj)
-/**
-* Utility func for cleanup stack
-*
-* @param aObj a pointer to the CObject to close
-*/
-	{
-	((CObject*)aObj)->Close();
-	}
-
-CSimCall::CSimCall(CSimLine* aLine,const TName& aName, CSimPhone* aPhone)
-			: iState(RMobileCall::EStatusIdle),iLine(aLine), 
-			  iHookState(ConvertStateToHook(iState)), iPhone(aPhone)
-	{
-	iNotifyStatusChange.iNotifyPending = EFalse;
-	iMobileNotifyStatusChange.iNotifyPending = EFalse;
-	iAnswerIncomingCall.iNotifyPending = EFalse;
-	iName.Copy(aName);
-	}
-
-void CSimCall::ConstructL()
-/**
-* Standard constructor
-*/
-	{
-	iCallDurationHandler = CSimCallDuration::NewL(this);
-	iNotifyRemotePartyInfoTimer = CSimCallRemotePartyInfoChange::NewL(this);
-	}
-
-
-CSimCall::~CSimCall()
-/**
-* Standard destructor
-*/
-	{
-	iLine->CallDestructor(this);
-	delete iCallDurationHandler;
-	delete iNotifyRemotePartyInfoTimer;
-	}
-
-CTelObject::TReqMode CSimCall::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;
-	LOGCALL2("CSimCall::ReqModeL called with IPC number %d",aIpc);
-	switch (aIpc)
-		{
-	//
-	// No Flow Control NOR Multiple Completion
-	//
-	case EMobileCallGetMobileDataCallCaps:
-	case EMobileCallGetMobileCallCaps:
-	case EMobileCallGetMobileCallStatus:
-	case EMobileCallGetMobileCallInfo:
-	case EMobileCallDialEmergencyCall:
-	case EMobileCallGetMobileDataCallRLPRange:
-	case EMobileCallSetDynamicHscsdParams:
-	case EMobileCallGetCurrentHscsdInfo:
-	case EMobileCallHold:
-	case EMobileCallResume:
-	case EMobileCallSwap:
-	case EMobileCallAnswerISV:
-		break;
-
-	//
-	// Flow Control Obeyed
-	//
-	case EMobileCallDialISV:
-		reqMode=KReqModeFlowControlObeyed;
-		break;
-
-	//
-	// Multiple Completion Services with Immediate Server Repost
-	// (Usually Notifications)
-	//
-
-	case EMobileCallNotifyHscsdInfoChange:
-	case EMobileCallNotifyMobileCallStatusChange:
-	case EMobileCallNotifyMobileCallCapsChange:
-	case EMobileCallNotifyRemotePartyInfoChange:
-		reqMode=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
-		break;
-		
-	default:
-		reqMode=CCallBase::ReqModeL(aIpc);
-		break;
-	}
-	return reqMode;
-	}
-
-TInt CSimCall::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 EMobileCallNotifyHscsdInfoChange:
-	case EMobileCallNotifyMobileDataCallCapsChange:
-	case EMobileCallNotifyMobileCallStatusChange:
-	case EMobileCallNotifyMobileCallCapsChange:
-	case EMobileCallNotifyRemotePartyInfoChange:
-		LOGCALL1("CSimCall: Registered with default number of slots");
-		return KDefaultNumberOfSlots;
-	default:
-		LOGCALL1("CSimCall::NumberOfSlotsL: No match for IPC, defering to base function");
-		break;
-		}
-	return CCallBase::NumberOfSlotsL(aIpc);
-	}
-
-
-TInt CSimCall::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 CSimCall::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 CSimCall::Init()
-/**
-* This function can be used to perform any necessary synchronous initialisation.
-*/
-	{}
-
-TInt CSimCall::GetCaps(const TTsyReqHandle aTsyReqHandle,RCall::TCaps* aCallCaps)
-/**
-* Retrieve the Call capabilities
-*
-* @param aTsyReqHandle	TSY handle associated with this request.s
-* @param aCallCaps		Pointer to the call capability
-* @return KErrNone
-*/
-	{
-	aCallCaps->iFlags=iCaps;
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RCall::TCaps* aCaps)
-/**
-* Register a client's interest in being notified when the call caps change.
-* @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 CSimCall::NotifyCapsChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when the call capabilities change.
-*/
-	{
-	if(iNotifyCapsChange.iNotifyPending)
-		{
-		iNotifyCapsChange.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrCancel);
-		}
-	return KErrNone;
-	}
-
-TInt CSimCall::GetMobileCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
-/**
-* Retrieve the Mobile Call capabilities
-*
-* @param aTsyReqHandle	TSY handle associated with this request.
-* @param aCaps			Pointer to the call capability
-* @return KErrNone
-*/
-	{
-	TPckg<RMobileCall::TMobileCallCapsV1>* capsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)aCaps;
-	RMobileCall::TMobileCallCapsV1& caps=(*capsPckg)();
-
-	// Check that the data structure is supported by the simulated TSY version
-	TInt err = iPhone->CheckSimTsyVersion(caps);
-	if(err != KErrNone)
-		{
-		ReqCompleted(aTsyReqHandle, err);
-		return KErrNone;
-		}
-
-	caps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
-	caps.iCallEventCaps=0;
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyMobileCallCapsChange(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
-/**
-* Register a client's interest in being notified when the RMobileCall capabilities change.
-* @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(!iNotifyMobileCapsChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
-	iNotifyMobileCapsChange.iNotifyPending=ETrue;
-	iNotifyMobileCapsChange.iNotifyHandle=aTsyReqHandle;
-	iNotifyMobileCapsChange.iNotifyData=aCaps;
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyMobileCallCapsChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when the RMobileCall capabilities change.
-*/
-	{
-	if(iNotifyMobileCapsChange.iNotifyPending)
-		{
-		iNotifyMobileCapsChange.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrCancel);
-		}
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyHookChange(const TTsyReqHandle aTsyReqHandle, RCall::THookStatus* aHookStatus)
-/**
-* Record a client's interst in being notified when the hook changes state.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aHookStatus pointer to the hook status
-* @return KErrNone
-*/
-	{
-	LOGCALL1(">>CSimCall::NotifyHookChange");
-	iNotifyHookChange.iNotifyPending = ETrue;
-	iNotifyHookChange.iNotifyHandle = aTsyReqHandle;
-	iNotifyHookChange.iNotifyData = aHookStatus;
-	LOGCALL1("<<CSimCall::NotifyHookChange");
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyHookChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when the hook state changes.
-*
-* @param aTsyReqHandle Tsy Request handle for the client cancel request
-* @return KErrNone
-*/
-	{
-	LOGCALL1(">>CSimCall::NotifyHookChangeCancel");
-	if(iNotifyHookChange.iNotifyPending)
-		{
-		iNotifyHookChange.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrCancel);
-		}
-	LOGCALL1("<<CSimCall::NotifyHookChangeCancel");
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyMobileCallStatusChange(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus)
-/**
-* Record a client's interest in being notified when the call status changes.
-* First check that there isn't already a notification pending (the ETel Server should protect
-* against this) and then record the information necessary to complete the request later, when
-* the status does actually change.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aStatus pointer to the call status
-* @return KErrNone
-*/
-	{
-	LOGCALL1(">>CSimCall::NotifyMobileCallStatusChange");
-	__ASSERT_ALWAYS(!iMobileNotifyStatusChange.iNotifyPending,SimPanic(ENotificationAlreadyPending));
-
-	iMobileNotifyStatusChange.iNotifyPending = ETrue;
-	iMobileNotifyStatusChange.iNotifyHandle = aTsyReqHandle;
-	iMobileNotifyStatusChange.iNotifyData = aStatus;
-	LOGCALL1("<<CSimCall::NotifyMobileCallStatusChange");
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyMobileCallStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Cancel a client's interest in being notified when the call status changes.
-* This is acheived simply by resetting the flag that indicates a notification is pending.
-* 
-* @param aTsyReqHandle Tsy Request handle for the client cancel request
-* @return KErrNone
-*/
-	{
-	LOGCALL1(">>CSimCall::NotifyMobileCallStatusChangeCancel");
-	if(iMobileNotifyStatusChange.iNotifyPending)
-		{
-		iMobileNotifyStatusChange.iNotifyPending=EFalse;
-		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrCancel);
-		}
-	LOGCALL1("<<CSimCall::NotifyMobileCallStatusChangeCancel");
-	return KErrNone;
-	}
-
-
-TInt CSimCall::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle,RCall::TStatus* aStatus)
-/**
-* Record a client's interest in being notified when the call status changes.
-* First check that there isn't already a notification pending (the ETel Server should protect
-* against this) and then record the information necessary to complete the request later, when
-* the status does actually change.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aStatus pointer to the call status
-* @return KErrNone
-*/
-	{
-	LOGCALL1(">>CSimCall::NotifyStatusChange");
-	__ASSERT_ALWAYS(!iNotifyStatusChange.iNotifyPending,SimPanic(ENotificationAlreadyPending));
-
-	iNotifyStatusChange.iNotifyPending = ETrue;
-	iNotifyStatusChange.iNotifyHandle = aTsyReqHandle;
-	iNotifyStatusChange.iNotifyData = aStatus;
-	LOGCALL1("<<CSimCall::NotifyStatusChange");
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-*	Cancel a client's interest in being notified when the call status changes.
-*	This is acheived simply by resetting the flag that indicates a notification is pending.
-* 
-* @param aTsyReqHandle Tsy Request handle for the client cancel request
-* @return KErrNone
-*/
-	{
-	LOGCALL1(">>CSimCall::NotifyStatusChangeCancel");
-	if(iNotifyStatusChange.iNotifyPending)
-		{
-		iNotifyStatusChange.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrCancel);
-		}
-	LOGCALL1("<<CSimCall::NotifyStatusChangeCancel");
-	return KErrNone;
-	}
-
-
-
-TInt CSimCall::NotifyDurationChange(const TTsyReqHandle aTsyReqHandle,TTimeIntervalSeconds* aTime)
-/**
-* Record a client's interest in being notified when the call duration changes.
-* 
-* @param aTsyReqHandle
-* @param aTime
-* @return KErrNone or symbian wide error code
-*/
-	{
-	iCallDurationHandler->StartNotification(aTsyReqHandle, aTime);
-	return KErrNone;
-	}
-
-TInt CSimCall::NotifyDurationChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* Not Supported in this TSY
-*/
-	{
-	iCallDurationHandler->StopNotification();
-	return KErrNone;
-	}
-
-TInt CSimCall::GetInfo(const TTsyReqHandle aTsyReqHandle, RCall::TCallInfo* aCallInfo)
-/**
-* Retrieve the Call Information.
-*
-* @param aTsyReqHandle
-* @param aCallInfo pointer to the call information to be returned to client
-* @return KErrNone
-*/
-	{
-	aCallInfo->iCallName.Copy(iName);
-	aCallInfo->iLineName.Copy(iLine->iLineName);
-	aCallInfo->iHookStatus=ConvertStateToHook(iState);
-	aCallInfo->iStatus=GetCoreCallStatus();
-	aCallInfo->iDuration=0;
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	return KErrNone;
-	}
-
-TInt CSimCall::GetMobileCallInfo(const TTsyReqHandle aTsyReqHandle, TDes8* aMobileCallInfo)
-/**
-* Retrieve the Mobile Call Information
-*
-* @param aTsyReqHandle
-* @param aCallInfo pointer to the call information to be returned to client
-* @return KErrNone
-*/
-	{
-	RMobileCall::TMobileCallInfoV1Pckg* mobileCallInfoV1=(RMobileCall::TMobileCallInfoV1Pckg*)aMobileCallInfo;
-	RMobileCall::TMobileCallInfoV1& mobileCallInfo=(*mobileCallInfoV1)();
-
-	// Check that the data structure is supported by the simulated TSY version
-	TInt err = iPhone->CheckSimTsyVersion(mobileCallInfo);
-	if(err != KErrNone)
-		{
-		ReqCompleted(aTsyReqHandle, err);
-		return KErrNone;
-		}
-
-	TUint caps=Caps();
-	if(caps&RCall::KCapsVoice)
-		mobileCallInfo.iService=RMobilePhone::EVoiceService;
-	else if(caps&RCall::KCapsData)
-		mobileCallInfo.iService=RMobilePhone::ECircuitDataService;
-	else if(caps&RCall::KCapsFax)
-		mobileCallInfo.iService=RMobilePhone::EFaxService;
-	else
-		mobileCallInfo.iService=RMobilePhone::EServiceUnspecified;
-
-	mobileCallInfo.iValid=0x0;
-	mobileCallInfo.iStatus=iState;
-	mobileCallInfo.iCallName.Copy(iName);
-	mobileCallInfo.iLineName.Copy(iLine->iLineName);
-	LOGCALL2("CSimCall::GetMobileCallInfo request completed with %d",iState);
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	return KErrNone;
-	}
-
-RCall::TStatus CSimCall::GetCoreCallStatus()
-/**
-* 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 CSimCall::GetStatus(const TTsyReqHandle aTsyReqHandle, RCall::TStatus* aCallStatus)
-/**
-* Return the current call state. (Core API request)
-*
-* @param aTsyReqHandle
-* @param aCallStatus pointer to the call status
-* @return KErrNone
-*/
-    {
-	LOGCALL1(">>CSimCall::GetStatus");
-	*aCallStatus=GetCoreCallStatus();
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	LOGCALL1("<<CSimCall::GetStatus");
-	return KErrNone;
-    }
-
-TInt CSimCall::GetMobileCallStatus(const TTsyReqHandle aTsyReqHandle, RMobileCall::TMobileCallStatus* aCallStatus)
-/**
-* Return the current call state. (Multimode API request)
-*
-* @param aTsyReqHandle
-* @param aCallStatus pointer to the call status
-* @return KErrNone
-*/
-    {
-	LOGCALL1(">>CSimCall::GetMobileCallStatus");
-	*aCallStatus=iState;
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	LOGCALL1("<<CSimCall::GetMobileCallStatus");
-	return KErrNone;
-    }
-
-TInt CSimCall::TransferOwnership(const TTsyReqHandle aTsyReqHandle)
-/**
-* Transfer call ownership
-* Not supported in this version of the Simulator TSY
-*/
-	{
-	ReqCompleted(aTsyReqHandle,KErrNotSupported);
-	return KErrNone;
-	}
-
-TInt CSimCall::AcquireOwnership(const TTsyReqHandle aTsyReqHandle)
-/**
-* Acquires call ownership
-* Not supported in this version of the Simulator TSY
-*/
-	{
-	ReqCompleted(aTsyReqHandle,KErrNotSupported);
-	return KErrNone;
-	}
-
-TInt CSimCall::AcquireOwnershipCancel(const TTsyReqHandle /*aTsyReqHandle*/)
-/**
-* cancel AcquireOwnership request
-* Not supported in this version of the Simulator TSY
-*/
-	{
-	return KErrNone;
-	}
-
-TInt CSimCall::GetCallDuration(const TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime)
-/**
-* Retrieves the last call duration
-* Not supported in this version of the Simulator TSY
-*/
-	{
-	LOGCALL1(">>CSimCall::GetCallDuration");
-	
-	iCallDurationHandler->GetDuration(aTime);
-	
-	ReqCompleted(aTsyReqHandle,KErrNone);
-	LOGCALL1("<<CSimCall::GetCallDuration");
-	return KErrNone;
-	}
-
-TInt CSimCall::RecoverDataPortAndRelinquishOwnership()
-/**
-* Recovers the comm port.
-* This is a data call specific request so not supported here.
-*/
-	{
-	return KErrNotSupported;
-	}
-
-TInt CSimCall::GetFaxSettings(const TTsyReqHandle,RCall::TFaxSessionSettings*)
-/**
-* Retrieves the last fax settings
-* Not supported in this version of the Simulator TSY
-*/
-	{	
-	return KErrNotSupported;
-	}
-
-TInt CSimCall::SetFaxSettings(const TTsyReqHandle,const RCall::TFaxSessionSettings*)
-/**
-* Sets the fax settings
-* Not supported in this version of the Simulator TSY
-*/
-	{	
-	return KErrNotSupported;
-	}
-
-CTelObject* CSimCall::OpenNewObjectByNameL(const TDesC& /*aName*/)
-/**
-* Only Fax Calls can be opened from the Call object, KErrNotSupported is returned.
-*/
-
-	{
-	User::Leave(KErrNotSupported);
-	return NULL;
-	}
-
-CTelObject* CSimCall::OpenNewObjectL(TDes& /*aNewName*/)
-/**
-* Only Fax objects can be opened from the Call object, and we are not supporting fax calls 
-* in this TSY. KErrNotSupported is returned.
-*/
-	{
-	User::Leave(KErrNotSupported);
-	return NULL;
-	}
-
-TBool CSimCall::Used()
-	{
-	return (AccessCount()>1);
-	}
-
-void CSimCall::SetUsed()
-	{
-	(void)Open();
-	}
-
-void CSimCall::SetUnused()
-	{
-	Close();
-	}
-
-TInt CSimCall::ChangeStateL(RMobileCall::TMobileCallStatus aNewState,TBool aSwap, TBool aNoPropagation)
-/**
-* Attempt to change state.
-* First validate that the requested state change is ok.  If it is then proceed to change
-* the state and complete any pending state change notification.
-*
-* @param aState the new state to change to
-* @param aSwap indicates that state change takes place as a consequence of swap operation on the call
-* @param aNoPropagation  indicates whether change propagate to the holder line object
-* @return Error indication if change of state is successful or not
-*/
-	{
-	LOGCALL3(">>CSimCall::ChangeState 0x%08x [newState=%d] entry", this,aNewState);
-	
-	if(!aNoPropagation)
-		{
-		TInt ret=iLine->ChangeStateL(aNewState,aSwap,this);
-		if(ret!=KErrNone)
-			return ret;
-		}
-	
-// Check for call duration change
-	if (!iCallDurationHandler)
-		iCallDurationHandler=CSimCallDuration::NewL(this);
-	if ((iState != RMobileCall::EStatusConnected) && (iState != RMobileCall::EStatusHold) &&  (aNewState == RMobileCall::EStatusConnected))
-		iCallDurationHandler->StartDuration();
-	else if ((aNewState != RMobileCall::EStatusConnected) && (aNewState != RMobileCall::EStatusHold) && ((iState == RMobileCall::EStatusConnected) || (iState == RMobileCall::EStatusHold)))
-		iCallDurationHandler->StopDuration();
-		
-// Actually change the state.
-	iState=aNewState;
-	
-// Check for a pending state change notification (core)
-	if(iNotifyStatusChange.iNotifyPending)
-		{
-		iNotifyStatusChange.iNotifyPending=EFalse;
-		*(RCall::TStatus*)iNotifyStatusChange.iNotifyData=GetCoreCallStatus();
-		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
-		}
-
-// Check for a pending state change notification (multimode)
-	if(iMobileNotifyStatusChange.iNotifyPending)
-		{
-		iMobileNotifyStatusChange.iNotifyPending=EFalse;
-		*(RMobileCall::TMobileCallStatus*)iMobileNotifyStatusChange.iNotifyData=iState;
-		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrNone);
-		}
-
-// Check for a pending hook change notification.
-	RCall::THookStatus hookStatus=ConvertStateToHook(iState);
-	if(iHookState!=hookStatus)
-		{
-		iHookState=hookStatus;
-		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;
-			((RCall::TCaps*)iNotifyCapsChange.iNotifyData)->iFlags=iCaps;
-			ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrNone);
-			}
-		if(iNotifyMobileCapsChange.iNotifyPending)
-			{
-			iNotifyMobileCapsChange.iNotifyPending=EFalse;
-			TPckg<RMobileCall::TMobileCallCapsV1>* mobileCallCapsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)iNotifyMobileCapsChange.iNotifyData;
-			RMobileCall::TMobileCallCapsV1& mobileCallCaps=(*mobileCallCapsPckg)();
-	
-			mobileCallCaps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
-			mobileCallCaps.iCallEventCaps=0;
-			ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrNone);
-			}
-		}
-	if((aNewState == RMobileCall::EStatusConnected && !aSwap)|| aNewState == RMobileCall::EStatusDisconnecting)
-		iLine->UpdatePhoneNotifiers(this,aNewState);		
-
-	LOGCALL2("<<CSimCall::ChangeState exit %d",iState);
-	return KErrNone;
-	}
-
-
-void CSimCall::UpdateNotifiers()
-/**
-	Update notifiers of other voice call when it gets swapped
-*/
-	{
-	LOGCALL2(">>CSimCall::UpdateNotifiers 0x%08x entry", this);
-	
-// Check for call duration change
-	if (!iCallDurationHandler)
-		{
-		TRAP_IGNORE(iCallDurationHandler=CSimCallDuration::NewL(this));
-		}
-	
-			
-// Check for a pending state change notification (core)
-	if(iNotifyStatusChange.iNotifyPending)
-		{
-		iNotifyStatusChange.iNotifyPending=EFalse;
-		*(RCall::TStatus*)iNotifyStatusChange.iNotifyData=GetCoreCallStatus();
-		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
-		}
-
-// Check for a pending state change notification (multimode)
-	if(iMobileNotifyStatusChange.iNotifyPending)
-		{
-		iMobileNotifyStatusChange.iNotifyPending=EFalse;
-		*(RMobileCall::TMobileCallStatus*)iMobileNotifyStatusChange.iNotifyData=iState;
-		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrNone);
-		}
-
-// Check for a pending hook change notification.
-	RCall::THookStatus hookStatus=ConvertStateToHook(iState);
-	if(iHookState!=hookStatus)
-		{
-		iHookState=hookStatus;
-		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;
-			((RCall::TCaps*)iNotifyCapsChange.iNotifyData)->iFlags=iCaps;
-			ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrNone);
-			}
-		if(iNotifyMobileCapsChange.iNotifyPending)
-			{
-			iNotifyMobileCapsChange.iNotifyPending=EFalse;
-			TPckg<RMobileCall::TMobileCallCapsV1>* mobileCallCapsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)iNotifyMobileCapsChange.iNotifyData;
-			RMobileCall::TMobileCallCapsV1& mobileCallCaps=(*mobileCallCapsPckg)();
-
-			mobileCallCaps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
-			mobileCallCaps.iCallEventCaps=0;
-			ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrNone);
-			}
-		}
-
-	LOGCALL2("<<CSimCall::UpdateNotifiers exit %d",iState);
-	}
-
-TInt CSimCall::ActionEvent(TCallEvent /*aEvent*/, TInt /*aStatus*/)
-/**
-* This is an empty shell function. Each line should implement its own
-* state machine.
-*/
-	{
-	return KErrNotSupported;
-	}
-
-void CSimCall::GenerateCoreCallCaps(TUint& aCaps)
-/**
- * Populate the variable capabilities that are dependant upon the call state.
- * @param TUint		The capability variable that will be populated with the core capabilities.
- */
-	{
-	if(iState==RMobileCall::EStatusIdle)
-		aCaps |= RCall::KCapsDial;
-
-	if(iState==RMobileCall::EStatusConnected)
-		aCaps |= RCall::KCapsHangUp;
-
-	if((iLine->IsAnswerCallObjectSpare())&&(iState==RMobileCall::EStatusIdle))
-		aCaps |= RCall::KCapsAnswer;
-	}
-
-void CSimCall::ResetIfRingingL()
-	{
-	if(iState==RMobileCall::EStatusRinging)
-		__ASSERT_ALWAYS(ChangeStateL(RMobileCall::EStatusIdle,EFalse,ETrue) == KErrNone, SimPanic(EGeneral));
-	}
-
-void CSimCallDuration::TimerCallBack(TInt /*aId*/)
-  	{
-  	//increase duration by 1 sec
-  	iCallDuration=static_cast<TTimeIntervalSeconds>(iCallDuration.Int()+1);
-  	
-  	if(iNotifyDurationChange.iNotifyPending)
-  		{
-  		*(TTimeIntervalSeconds*)iNotifyDurationChange.iNotifyData=iCallDuration;
-  		iNotifyDurationChange.iNotifyPending=EFalse;
-  		iCall->ReqCompleted(iNotifyDurationChange.iNotifyHandle,KErrNone);		
-  		}
-  	iDurationTimer->Start(1 , this);
-  	}
-
-CSimCallDuration* CSimCallDuration::NewL(CSimCall* aCall)
-/**
- * Standard two-phase constructor.
- * @param aPhone				The parent phone object.
- * @return CSimCallDuration		The new CallDuration class 
- */
-	{
-	CSimCallDuration* self=new(ELeave) CSimCallDuration(aCall);
-	CleanupStack::PushL(self);
-	self->ConstructL();
-	CleanupStack::Pop();
-	return self;
-	}
-
-CSimCallDuration::CSimCallDuration(CSimCall* aCall)
-		:iCallDuration(0),iCall(aCall)
-/**
- * Trivial first phase construction.
- * @param aPhone				The parent phone object.
- */
-	{
-	iNotifyDurationChange.iNotifyPending=EFalse;
-	iNotifyDurationChange.iNotifyData=0;
-	}
-
-
-void CSimCallDuration::ConstructL()
-	{
-	iDurationTimer = CSimTimer::NewL(iCall->iLine->iPhone);
-	}
-
-
-CSimCallDuration::~CSimCallDuration()
-/**
- * Standard destructor.  Destroy the heap-based object owned by this object.
- */
-	{
-	if (iDurationTimer)
-		{
-		if (iDurationTimer->IsActive())
-			iDurationTimer->Cancel();
-		delete iDurationTimer;
-		}
-	}
-
-void CSimCallDuration::StartDuration()
-	{
-	iCallDuration = 0;
-	iDurationTimer->Start(1 , this);
-	}
-
-void CSimCallDuration::StopDuration()
-	{	
-	if (iDurationTimer)
-		{
-		if (iDurationTimer->IsActive())
-			iDurationTimer->Cancel();
-		}
-	}
-
-void CSimCallDuration::StartNotification(TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime)
-	{
-	__ASSERT_ALWAYS(!iNotifyDurationChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
-	iNotifyDurationChange.iNotifyData=aTime;
-	iNotifyDurationChange.iNotifyPending=ETrue;
-	iNotifyDurationChange.iNotifyHandle=aTsyReqHandle;
-	}
-
-void CSimCallDuration::StopNotification()
-	{
-	if(iNotifyDurationChange.iNotifyPending)
-		{
-		iNotifyDurationChange.iNotifyPending=EFalse;
-		iCall->ReqCompleted(iNotifyDurationChange.iNotifyHandle,KErrCancel);
-		}
-	}
-
-void CSimCallDuration::GetDuration(TTimeIntervalSeconds* aTime)
-	{
-	*aTime = iCallDuration;
-	}
-	
-CSimCallRemotePartyInfoChange* CSimCallRemotePartyInfoChange::NewL(CSimCall* aCall)
-/**
- * Standard two-phase constructor.
- * @param aCall on upon remote party info is needed
- * @return CSimCallRemotePartyInfoChange		
- */
-	{
-	CSimCallRemotePartyInfoChange* self=new(ELeave) CSimCallRemotePartyInfoChange(aCall);
-	CleanupStack::PushL(self);
-	self->ConstructL();
-	CleanupStack::Pop();
-	return self;
-	}
-
-CSimCallRemotePartyInfoChange::CSimCallRemotePartyInfoChange(CSimCall* aCall)
-		:iCall(aCall)
-/**
- * Trivial first phase construction.
- * @param aCall is call object upon remote party info is needed.
- */
-	{
-	iNotifyRemotePartyInfo.iNotifyPending=EFalse;
-	iNotifyRemotePartyInfo.iNotifyData=0;
-	}
-
-
-void CSimCallRemotePartyInfoChange::ConstructL()
-	{
-	iRemoteInfoTimer = CSimTimer::NewL(iCall->iLine->iPhone);
-	}
-
-void CSimCallRemotePartyInfoChange::Start()
-	{
-	iRemoteInfoTimer->Start(iDelay, this);
-	}
-
-CSimCallRemotePartyInfoChange::~CSimCallRemotePartyInfoChange()
-/**
- * Standard destructor.  Destroy the heap-based object owned by this object.
- */
-	{
-	if (iRemoteInfoTimer)
-		{
-		if (iRemoteInfoTimer->IsActive())
-			iRemoteInfoTimer->Cancel();
-		delete iRemoteInfoTimer;
-		}
-	}
-	
-void CSimCallRemotePartyInfoChange::TimerCallBack(TInt /*aId*/)
-	{
-	if(iRemotePartyInfoV1.iRemoteIdStatus != RMobileCall::ERemoteIdentityUnknown && iNotifyRemotePartyInfo.iNotifyPending)	
-		{
-		iNotifyRemotePartyInfo.iNotifyPending=EFalse;
-		*(RMobileCall::TMobileCallRemotePartyInfoV1*)iNotifyRemotePartyInfo.iNotifyData=iRemotePartyInfoV1;
-		iCall->ReqCompleted(iNotifyRemotePartyInfo.iNotifyHandle,KErrNone);
-		}	
-	}
-	
-TInt CSimCall::NotifyRemotePartyInfoChange(const TTsyReqHandle aTsyReqHandle, TDes8* aRemoteParty)
-/**
-* Record a client's interest in being notified when the remote party info changes.
-* First check that there isn't already a notification pending (the ETel Server should protect
-* against this) and then record the information necessary to complete the request later, when
-* the status does actually change.
-*
-* @param aTsyReqHandle Tsy Request handle for the client request
-* @param aStatus pointer to the call status
-* @return KErrNone
-*/
-	{
-	LOGCALL1(">>CSimCall::NotifyRemotePartyInfoChange");
-	__ASSERT_ALWAYS(iNotifyRemotePartyInfoTimer, SimPanic(EOjectNotConstructed));
-	__ASSERT_ALWAYS(!iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending,SimPanic(ENotificationAlreadyPending));
-	
-	RMobileCall::TMobileCallRemotePartyInfoV1Pckg* remotepartyPckg = (RMobileCall::TMobileCallRemotePartyInfoV1Pckg*) aRemoteParty;
-	RMobileCall::TMobileCallRemotePartyInfoV1& remoteparty = (*remotepartyPckg)();
-
-	// Check that the data structure is supported by the simulated TSY version
-	TInt err = iPhone->CheckSimTsyVersion(remoteparty);
-	if(err != KErrNone)
-		{
-		ReqCompleted(aTsyReqHandle, err);
-		return KErrNone;
-		}
-
-	//start timer
-	iNotifyRemotePartyInfoTimer->Start();	
-	
-	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending = ETrue;
-	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyHandle = aTsyReqHandle;
-	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyData = &remoteparty;
-	LOGCALL1("<<CSimCall::NotifyRemotePartyInfoChange");
-	return KErrNone;
-	}
-	
-TInt CSimCall::NotifyRemotePartyInfoChangeCancel()
-/**
-* Cancel a client's interest in being notified when the remote party info changes.
-* This is acheived simply by resetting the flag that indicates a notification is pending.
-* 
-* @return KErrNone
-*/
-	{
-	LOGCALL1(">>CSimCall::NotifyRemotePartyInfoChangeCancel");
-	if(iNotifyRemotePartyInfoTimer && iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending)
-		{
-		iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending=EFalse;
-		ReqCompleted(iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyHandle,KErrCancel);
-		}
-	LOGCALL1("<<CSimCall::NotifyRemotePartyInfoChangeCancel");
-	return KErrNone;
-	}
+// 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 of the Simulator TSY call classes.  The call classes
+// process the call-based requests made by ETel clients and passed down to the TSY by the
+// ETel Server.
+// 
+//
+
+/**
+ @file
+*/
+
+#include "CSimCall.h"
+#include "CSimPhone.h"
+#include "Simlog.h"
+
+void CSimCall::CloseCall(TAny* aObj)
+/**
+* Utility func for cleanup stack
+*
+* @param aObj a pointer to the CObject to close
+*/
+	{
+	((CObject*)aObj)->Close();
+	}
+
+CSimCall::CSimCall(CSimLine* aLine,const TName& aName, CSimPhone* aPhone)
+			: iState(RMobileCall::EStatusIdle),iLine(aLine), 
+			  iHookState(ConvertStateToHook(iState)), iPhone(aPhone)
+	{
+	iNotifyStatusChange.iNotifyPending = EFalse;
+	iMobileNotifyStatusChange.iNotifyPending = EFalse;
+	iAnswerIncomingCall.iNotifyPending = EFalse;
+	iName.Copy(aName);
+	}
+
+void CSimCall::ConstructL()
+/**
+* Standard constructor
+*/
+	{
+	iCallDurationHandler = CSimCallDuration::NewL(this);
+	iNotifyRemotePartyInfoTimer = CSimCallRemotePartyInfoChange::NewL(this);
+	}
+
+
+CSimCall::~CSimCall()
+/**
+* Standard destructor
+*/
+	{
+	iLine->CallDestructor(this);
+	delete iCallDurationHandler;
+	delete iNotifyRemotePartyInfoTimer;
+	}
+
+CTelObject::TReqMode CSimCall::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;
+	LOGCALL2("CSimCall::ReqModeL called with IPC number %d",aIpc);
+	switch (aIpc)
+		{
+	//
+	// No Flow Control NOR Multiple Completion
+	//
+	case EMobileCallGetMobileDataCallCaps:
+	case EMobileCallGetMobileCallCaps:
+	case EMobileCallGetMobileCallStatus:
+	case EMobileCallGetMobileCallInfo:
+	case EMobileCallDialEmergencyCall:
+	case EMobileCallGetMobileDataCallRLPRange:
+	case EMobileCallSetDynamicHscsdParams:
+	case EMobileCallGetCurrentHscsdInfo:
+	case EMobileCallHold:
+	case EMobileCallResume:
+	case EMobileCallSwap:
+	case EMobileCallAnswerISV:
+		break;
+
+	//
+	// Flow Control Obeyed
+	//
+	case EMobileCallDialISV:
+		reqMode=KReqModeFlowControlObeyed;
+		break;
+
+	//
+	// Multiple Completion Services with Immediate Server Repost
+	// (Usually Notifications)
+	//
+
+	case EMobileCallNotifyHscsdInfoChange:
+	case EMobileCallNotifyMobileCallStatusChange:
+	case EMobileCallNotifyMobileCallCapsChange:
+	case EMobileCallNotifyRemotePartyInfoChange:
+		reqMode=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
+		break;
+		
+	default:
+		reqMode=CCallBase::ReqModeL(aIpc);
+		break;
+	}
+	return reqMode;
+	}
+
+TInt CSimCall::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 EMobileCallNotifyHscsdInfoChange:
+	case EMobileCallNotifyMobileDataCallCapsChange:
+	case EMobileCallNotifyMobileCallStatusChange:
+	case EMobileCallNotifyMobileCallCapsChange:
+	case EMobileCallNotifyRemotePartyInfoChange:
+		LOGCALL1("CSimCall: Registered with default number of slots");
+		return KDefaultNumberOfSlots;
+	default:
+		LOGCALL1("CSimCall::NumberOfSlotsL: No match for IPC, defering to base function");
+		break;
+		}
+	return CCallBase::NumberOfSlotsL(aIpc);
+	}
+
+
+TInt CSimCall::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 CSimCall::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 CSimCall::Init()
+/**
+* This function can be used to perform any necessary synchronous initialisation.
+*/
+	{}
+
+TInt CSimCall::GetCaps(const TTsyReqHandle aTsyReqHandle,RCall::TCaps* aCallCaps)
+/**
+* Retrieve the Call capabilities
+*
+* @param aTsyReqHandle	TSY handle associated with this request.s
+* @param aCallCaps		Pointer to the call capability
+* @return KErrNone
+*/
+	{
+	aCallCaps->iFlags=iCaps;
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RCall::TCaps* aCaps)
+/**
+* Register a client's interest in being notified when the call caps change.
+* @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 CSimCall::NotifyCapsChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when the call capabilities change.
+*/
+	{
+	if(iNotifyCapsChange.iNotifyPending)
+		{
+		iNotifyCapsChange.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrCancel);
+		}
+	return KErrNone;
+	}
+
+TInt CSimCall::GetMobileCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
+/**
+* Retrieve the Mobile Call capabilities
+*
+* @param aTsyReqHandle	TSY handle associated with this request.
+* @param aCaps			Pointer to the call capability
+* @return KErrNone
+*/
+	{
+	TPckg<RMobileCall::TMobileCallCapsV1>* capsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)aCaps;
+	RMobileCall::TMobileCallCapsV1& caps=(*capsPckg)();
+
+	// Check that the data structure is supported by the simulated TSY version
+	TInt err = iPhone->CheckSimTsyVersion(caps);
+	if(err != KErrNone)
+		{
+		ReqCompleted(aTsyReqHandle, err);
+		return KErrNone;
+		}
+
+	caps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
+	caps.iCallEventCaps=0;
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyMobileCallCapsChange(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
+/**
+* Register a client's interest in being notified when the RMobileCall capabilities change.
+* @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(!iNotifyMobileCapsChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
+	iNotifyMobileCapsChange.iNotifyPending=ETrue;
+	iNotifyMobileCapsChange.iNotifyHandle=aTsyReqHandle;
+	iNotifyMobileCapsChange.iNotifyData=aCaps;
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyMobileCallCapsChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when the RMobileCall capabilities change.
+*/
+	{
+	if(iNotifyMobileCapsChange.iNotifyPending)
+		{
+		iNotifyMobileCapsChange.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrCancel);
+		}
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyHookChange(const TTsyReqHandle aTsyReqHandle, RCall::THookStatus* aHookStatus)
+/**
+* Record a client's interst in being notified when the hook changes state.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aHookStatus pointer to the hook status
+* @return KErrNone
+*/
+	{
+	LOGCALL1(">>CSimCall::NotifyHookChange");
+	iNotifyHookChange.iNotifyPending = ETrue;
+	iNotifyHookChange.iNotifyHandle = aTsyReqHandle;
+	iNotifyHookChange.iNotifyData = aHookStatus;
+	LOGCALL1("<<CSimCall::NotifyHookChange");
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyHookChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when the hook state changes.
+*
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGCALL1(">>CSimCall::NotifyHookChangeCancel");
+	if(iNotifyHookChange.iNotifyPending)
+		{
+		iNotifyHookChange.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrCancel);
+		}
+	LOGCALL1("<<CSimCall::NotifyHookChangeCancel");
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyMobileCallStatusChange(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus)
+/**
+* Record a client's interest in being notified when the call status changes.
+* First check that there isn't already a notification pending (the ETel Server should protect
+* against this) and then record the information necessary to complete the request later, when
+* the status does actually change.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aStatus pointer to the call status
+* @return KErrNone
+*/
+	{
+	LOGCALL1(">>CSimCall::NotifyMobileCallStatusChange");
+	__ASSERT_ALWAYS(!iMobileNotifyStatusChange.iNotifyPending,SimPanic(ENotificationAlreadyPending));
+
+	iMobileNotifyStatusChange.iNotifyPending = ETrue;
+	iMobileNotifyStatusChange.iNotifyHandle = aTsyReqHandle;
+	iMobileNotifyStatusChange.iNotifyData = aStatus;
+	LOGCALL1("<<CSimCall::NotifyMobileCallStatusChange");
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyMobileCallStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Cancel a client's interest in being notified when the call status changes.
+* This is acheived simply by resetting the flag that indicates a notification is pending.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGCALL1(">>CSimCall::NotifyMobileCallStatusChangeCancel");
+	if(iMobileNotifyStatusChange.iNotifyPending)
+		{
+		iMobileNotifyStatusChange.iNotifyPending=EFalse;
+		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrCancel);
+		}
+	LOGCALL1("<<CSimCall::NotifyMobileCallStatusChangeCancel");
+	return KErrNone;
+	}
+
+
+TInt CSimCall::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle,RCall::TStatus* aStatus)
+/**
+* Record a client's interest in being notified when the call status changes.
+* First check that there isn't already a notification pending (the ETel Server should protect
+* against this) and then record the information necessary to complete the request later, when
+* the status does actually change.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aStatus pointer to the call status
+* @return KErrNone
+*/
+	{
+	LOGCALL1(">>CSimCall::NotifyStatusChange");
+	__ASSERT_ALWAYS(!iNotifyStatusChange.iNotifyPending,SimPanic(ENotificationAlreadyPending));
+
+	iNotifyStatusChange.iNotifyPending = ETrue;
+	iNotifyStatusChange.iNotifyHandle = aTsyReqHandle;
+	iNotifyStatusChange.iNotifyData = aStatus;
+	LOGCALL1("<<CSimCall::NotifyStatusChange");
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+*	Cancel a client's interest in being notified when the call status changes.
+*	This is acheived simply by resetting the flag that indicates a notification is pending.
+* 
+* @param aTsyReqHandle Tsy Request handle for the client cancel request
+* @return KErrNone
+*/
+	{
+	LOGCALL1(">>CSimCall::NotifyStatusChangeCancel");
+	if(iNotifyStatusChange.iNotifyPending)
+		{
+		iNotifyStatusChange.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrCancel);
+		}
+	LOGCALL1("<<CSimCall::NotifyStatusChangeCancel");
+	return KErrNone;
+	}
+
+
+
+TInt CSimCall::NotifyDurationChange(const TTsyReqHandle aTsyReqHandle,TTimeIntervalSeconds* aTime)
+/**
+* Record a client's interest in being notified when the call duration changes.
+* 
+* @param aTsyReqHandle
+* @param aTime
+* @return KErrNone or symbian wide error code
+*/
+	{
+	iCallDurationHandler->StartNotification(aTsyReqHandle, aTime);
+	return KErrNone;
+	}
+
+TInt CSimCall::NotifyDurationChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* Not Supported in this TSY
+*/
+	{
+	iCallDurationHandler->StopNotification();
+	return KErrNone;
+	}
+
+TInt CSimCall::GetInfo(const TTsyReqHandle aTsyReqHandle, RCall::TCallInfo* aCallInfo)
+/**
+* Retrieve the Call Information.
+*
+* @param aTsyReqHandle
+* @param aCallInfo pointer to the call information to be returned to client
+* @return KErrNone
+*/
+	{
+	aCallInfo->iCallName.Copy(iName);
+	aCallInfo->iLineName.Copy(iLine->iLineName);
+	aCallInfo->iHookStatus=ConvertStateToHook(iState);
+	aCallInfo->iStatus=GetCoreCallStatus();
+	aCallInfo->iDuration=0;
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	return KErrNone;
+	}
+
+TInt CSimCall::GetMobileCallInfo(const TTsyReqHandle aTsyReqHandle, TDes8* aMobileCallInfo)
+/**
+* Retrieve the Mobile Call Information
+*
+* @param aTsyReqHandle
+* @param aCallInfo pointer to the call information to be returned to client
+* @return KErrNone
+*/
+	{
+	RMobileCall::TMobileCallInfoV1Pckg* mobileCallInfoV1=(RMobileCall::TMobileCallInfoV1Pckg*)aMobileCallInfo;
+	RMobileCall::TMobileCallInfoV1& mobileCallInfo=(*mobileCallInfoV1)();
+
+	// Check that the data structure is supported by the simulated TSY version
+	TInt err = iPhone->CheckSimTsyVersion(mobileCallInfo);
+	if(err != KErrNone)
+		{
+		ReqCompleted(aTsyReqHandle, err);
+		return KErrNone;
+		}
+
+	TUint caps=Caps();
+	if(caps&RCall::KCapsVoice)
+		mobileCallInfo.iService=RMobilePhone::EVoiceService;
+	else if(caps&RCall::KCapsData)
+		mobileCallInfo.iService=RMobilePhone::ECircuitDataService;
+	else if(caps&RCall::KCapsFax)
+		mobileCallInfo.iService=RMobilePhone::EFaxService;
+	else
+		mobileCallInfo.iService=RMobilePhone::EServiceUnspecified;
+
+	mobileCallInfo.iValid=0x0;
+	mobileCallInfo.iStatus=iState;
+	mobileCallInfo.iCallName.Copy(iName);
+	mobileCallInfo.iLineName.Copy(iLine->iLineName);
+	LOGCALL2("CSimCall::GetMobileCallInfo request completed with %d",iState);
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	return KErrNone;
+	}
+
+RCall::TStatus CSimCall::GetCoreCallStatus()
+/**
+* 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 CSimCall::GetStatus(const TTsyReqHandle aTsyReqHandle, RCall::TStatus* aCallStatus)
+/**
+* Return the current call state. (Core API request)
+*
+* @param aTsyReqHandle
+* @param aCallStatus pointer to the call status
+* @return KErrNone
+*/
+    {
+	LOGCALL1(">>CSimCall::GetStatus");
+	*aCallStatus=GetCoreCallStatus();
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	LOGCALL1("<<CSimCall::GetStatus");
+	return KErrNone;
+    }
+
+TInt CSimCall::GetMobileCallStatus(const TTsyReqHandle aTsyReqHandle, RMobileCall::TMobileCallStatus* aCallStatus)
+/**
+* Return the current call state. (Multimode API request)
+*
+* @param aTsyReqHandle
+* @param aCallStatus pointer to the call status
+* @return KErrNone
+*/
+    {
+	LOGCALL1(">>CSimCall::GetMobileCallStatus");
+	*aCallStatus=iState;
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	LOGCALL1("<<CSimCall::GetMobileCallStatus");
+	return KErrNone;
+    }
+
+TInt CSimCall::TransferOwnership(const TTsyReqHandle aTsyReqHandle)
+/**
+* Transfer call ownership
+* Not supported in this version of the Simulator TSY
+*/
+	{
+	ReqCompleted(aTsyReqHandle,KErrNotSupported);
+	return KErrNone;
+	}
+
+TInt CSimCall::AcquireOwnership(const TTsyReqHandle aTsyReqHandle)
+/**
+* Acquires call ownership
+* Not supported in this version of the Simulator TSY
+*/
+	{
+	ReqCompleted(aTsyReqHandle,KErrNotSupported);
+	return KErrNone;
+	}
+
+TInt CSimCall::AcquireOwnershipCancel(const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+* cancel AcquireOwnership request
+* Not supported in this version of the Simulator TSY
+*/
+	{
+	return KErrNone;
+	}
+
+TInt CSimCall::GetCallDuration(const TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime)
+/**
+* Retrieves the last call duration
+* Not supported in this version of the Simulator TSY
+*/
+	{
+	LOGCALL1(">>CSimCall::GetCallDuration");
+	
+	iCallDurationHandler->GetDuration(aTime);
+	
+	ReqCompleted(aTsyReqHandle,KErrNone);
+	LOGCALL1("<<CSimCall::GetCallDuration");
+	return KErrNone;
+	}
+
+TInt CSimCall::RecoverDataPortAndRelinquishOwnership()
+/**
+* Recovers the comm port.
+* This is a data call specific request so not supported here.
+*/
+	{
+	return KErrNotSupported;
+	}
+
+TInt CSimCall::GetFaxSettings(const TTsyReqHandle,RCall::TFaxSessionSettings*)
+/**
+* Retrieves the last fax settings
+* Not supported in this version of the Simulator TSY
+*/
+	{	
+	return KErrNotSupported;
+	}
+
+TInt CSimCall::SetFaxSettings(const TTsyReqHandle,const RCall::TFaxSessionSettings*)
+/**
+* Sets the fax settings
+* Not supported in this version of the Simulator TSY
+*/
+	{	
+	return KErrNotSupported;
+	}
+
+CTelObject* CSimCall::OpenNewObjectByNameL(const TDesC& /*aName*/)
+/**
+* Only Fax Calls can be opened from the Call object, KErrNotSupported is returned.
+*/
+
+	{
+	User::Leave(KErrNotSupported);
+	return NULL;
+	}
+
+CTelObject* CSimCall::OpenNewObjectL(TDes& /*aNewName*/)
+/**
+* Only Fax objects can be opened from the Call object, and we are not supporting fax calls 
+* in this TSY. KErrNotSupported is returned.
+*/
+	{
+	User::Leave(KErrNotSupported);
+	return NULL;
+	}
+
+TBool CSimCall::Used()
+	{
+	return (AccessCount()>1);
+	}
+
+void CSimCall::SetUsed()
+	{
+	(void)Open();
+	}
+
+void CSimCall::SetUnused()
+	{
+	Close();
+	}
+
+TInt CSimCall::ChangeStateL(RMobileCall::TMobileCallStatus aNewState,TBool aSwap, TBool aNoPropagation)
+/**
+* Attempt to change state.
+* First validate that the requested state change is ok.  If it is then proceed to change
+* the state and complete any pending state change notification.
+*
+* @param aState the new state to change to
+* @param aSwap indicates that state change takes place as a consequence of swap operation on the call
+* @param aNoPropagation  indicates whether change propagate to the holder line object
+* @return Error indication if change of state is successful or not
+*/
+	{
+	LOGCALL3(">>CSimCall::ChangeState 0x%08x [newState=%d] entry", this,aNewState);
+	
+	if(!aNoPropagation)
+		{
+		TInt ret=iLine->ChangeStateL(aNewState,aSwap,this);
+		if(ret!=KErrNone)
+			return ret;
+		}
+	
+// Check for call duration change
+	if (!iCallDurationHandler)
+		iCallDurationHandler=CSimCallDuration::NewL(this);
+	if ((iState != RMobileCall::EStatusConnected) && (iState != RMobileCall::EStatusHold) &&  (aNewState == RMobileCall::EStatusConnected))
+		iCallDurationHandler->StartDuration();
+	else if ((aNewState != RMobileCall::EStatusConnected) && (aNewState != RMobileCall::EStatusHold) && ((iState == RMobileCall::EStatusConnected) || (iState == RMobileCall::EStatusHold)))
+		iCallDurationHandler->StopDuration();
+		
+// Actually change the state.
+	iState=aNewState;
+	
+// Check for a pending state change notification (core)
+	if(iNotifyStatusChange.iNotifyPending)
+		{
+		iNotifyStatusChange.iNotifyPending=EFalse;
+		*(RCall::TStatus*)iNotifyStatusChange.iNotifyData=GetCoreCallStatus();
+		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
+		}
+
+// Check for a pending state change notification (multimode)
+	if(iMobileNotifyStatusChange.iNotifyPending)
+		{
+		iMobileNotifyStatusChange.iNotifyPending=EFalse;
+		*(RMobileCall::TMobileCallStatus*)iMobileNotifyStatusChange.iNotifyData=iState;
+		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrNone);
+		}
+
+// Check for a pending hook change notification.
+	RCall::THookStatus hookStatus=ConvertStateToHook(iState);
+	if(iHookState!=hookStatus)
+		{
+		iHookState=hookStatus;
+		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;
+			((RCall::TCaps*)iNotifyCapsChange.iNotifyData)->iFlags=iCaps;
+			ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrNone);
+			}
+		if(iNotifyMobileCapsChange.iNotifyPending)
+			{
+			iNotifyMobileCapsChange.iNotifyPending=EFalse;
+			TPckg<RMobileCall::TMobileCallCapsV1>* mobileCallCapsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)iNotifyMobileCapsChange.iNotifyData;
+			RMobileCall::TMobileCallCapsV1& mobileCallCaps=(*mobileCallCapsPckg)();
+	
+			mobileCallCaps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
+			mobileCallCaps.iCallEventCaps=0;
+			ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrNone);
+			}
+		}
+	if((aNewState == RMobileCall::EStatusConnected && !aSwap)|| aNewState == RMobileCall::EStatusDisconnecting)
+		iLine->UpdatePhoneNotifiers(this,aNewState);		
+
+	LOGCALL2("<<CSimCall::ChangeState exit %d",iState);
+	return KErrNone;
+	}
+
+
+void CSimCall::UpdateNotifiers()
+/**
+	Update notifiers of other voice call when it gets swapped
+*/
+	{
+	LOGCALL2(">>CSimCall::UpdateNotifiers 0x%08x entry", this);
+	
+// Check for call duration change
+	if (!iCallDurationHandler)
+		{
+		TRAP_IGNORE(iCallDurationHandler=CSimCallDuration::NewL(this));
+		}
+	
+			
+// Check for a pending state change notification (core)
+	if(iNotifyStatusChange.iNotifyPending)
+		{
+		iNotifyStatusChange.iNotifyPending=EFalse;
+		*(RCall::TStatus*)iNotifyStatusChange.iNotifyData=GetCoreCallStatus();
+		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
+		}
+
+// Check for a pending state change notification (multimode)
+	if(iMobileNotifyStatusChange.iNotifyPending)
+		{
+		iMobileNotifyStatusChange.iNotifyPending=EFalse;
+		*(RMobileCall::TMobileCallStatus*)iMobileNotifyStatusChange.iNotifyData=iState;
+		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrNone);
+		}
+
+// Check for a pending hook change notification.
+	RCall::THookStatus hookStatus=ConvertStateToHook(iState);
+	if(iHookState!=hookStatus)
+		{
+		iHookState=hookStatus;
+		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;
+			((RCall::TCaps*)iNotifyCapsChange.iNotifyData)->iFlags=iCaps;
+			ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrNone);
+			}
+		if(iNotifyMobileCapsChange.iNotifyPending)
+			{
+			iNotifyMobileCapsChange.iNotifyPending=EFalse;
+			TPckg<RMobileCall::TMobileCallCapsV1>* mobileCallCapsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)iNotifyMobileCapsChange.iNotifyData;
+			RMobileCall::TMobileCallCapsV1& mobileCallCaps=(*mobileCallCapsPckg)();
+
+			mobileCallCaps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
+			mobileCallCaps.iCallEventCaps=0;
+			ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrNone);
+			}
+		}
+
+	LOGCALL2("<<CSimCall::UpdateNotifiers exit %d",iState);
+	}
+
+TInt CSimCall::ActionEvent(TCallEvent /*aEvent*/, TInt /*aStatus*/)
+/**
+* This is an empty shell function. Each line should implement its own
+* state machine.
+*/
+	{
+	return KErrNotSupported;
+	}
+
+void CSimCall::GenerateCoreCallCaps(TUint& aCaps)
+/**
+ * Populate the variable capabilities that are dependant upon the call state.
+ * @param TUint		The capability variable that will be populated with the core capabilities.
+ */
+	{
+	if(iState==RMobileCall::EStatusIdle)
+		aCaps |= RCall::KCapsDial;
+
+	if(iState==RMobileCall::EStatusConnected)
+		aCaps |= RCall::KCapsHangUp;
+
+	if((iLine->IsAnswerCallObjectSpare())&&(iState==RMobileCall::EStatusIdle))
+		aCaps |= RCall::KCapsAnswer;
+	}
+
+void CSimCall::ResetIfRingingL()
+	{
+	if(iState==RMobileCall::EStatusRinging)
+		__ASSERT_ALWAYS(ChangeStateL(RMobileCall::EStatusIdle,EFalse,ETrue) == KErrNone, SimPanic(EGeneral));
+	}
+
+void CSimCallDuration::TimerCallBack(TInt /*aId*/)
+  	{
+  	//increase duration by 1 sec
+  	iCallDuration=static_cast<TTimeIntervalSeconds>(iCallDuration.Int()+1);
+  	
+  	if(iNotifyDurationChange.iNotifyPending)
+  		{
+  		*(TTimeIntervalSeconds*)iNotifyDurationChange.iNotifyData=iCallDuration;
+  		iNotifyDurationChange.iNotifyPending=EFalse;
+  		iCall->ReqCompleted(iNotifyDurationChange.iNotifyHandle,KErrNone);		
+  		}
+  	iDurationTimer->Start(1 , this);
+  	}
+
+CSimCallDuration* CSimCallDuration::NewL(CSimCall* aCall)
+/**
+ * Standard two-phase constructor.
+ * @param aPhone				The parent phone object.
+ * @return CSimCallDuration		The new CallDuration class 
+ */
+	{
+	CSimCallDuration* self=new(ELeave) CSimCallDuration(aCall);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CSimCallDuration::CSimCallDuration(CSimCall* aCall)
+		:iCallDuration(0),iCall(aCall)
+/**
+ * Trivial first phase construction.
+ * @param aPhone				The parent phone object.
+ */
+	{
+	iNotifyDurationChange.iNotifyPending=EFalse;
+	iNotifyDurationChange.iNotifyData=0;
+	}
+
+
+void CSimCallDuration::ConstructL()
+	{
+	iDurationTimer = CSimTimer::NewL(iCall->iLine->iPhone);
+	}
+
+
+CSimCallDuration::~CSimCallDuration()
+/**
+ * Standard destructor.  Destroy the heap-based object owned by this object.
+ */
+	{
+	if (iDurationTimer)
+		{
+		if (iDurationTimer->IsActive())
+			iDurationTimer->Cancel();
+		delete iDurationTimer;
+		}
+	}
+
+void CSimCallDuration::StartDuration()
+	{
+	iCallDuration = 0;
+	iDurationTimer->Start(1 , this);
+	}
+
+void CSimCallDuration::StopDuration()
+	{	
+	if (iDurationTimer)
+		{
+		if (iDurationTimer->IsActive())
+			iDurationTimer->Cancel();
+		}
+	}
+
+void CSimCallDuration::StartNotification(TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime)
+	{
+	__ASSERT_ALWAYS(!iNotifyDurationChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
+	iNotifyDurationChange.iNotifyData=aTime;
+	iNotifyDurationChange.iNotifyPending=ETrue;
+	iNotifyDurationChange.iNotifyHandle=aTsyReqHandle;
+	}
+
+void CSimCallDuration::StopNotification()
+	{
+	if(iNotifyDurationChange.iNotifyPending)
+		{
+		iNotifyDurationChange.iNotifyPending=EFalse;
+		iCall->ReqCompleted(iNotifyDurationChange.iNotifyHandle,KErrCancel);
+		}
+	}
+
+void CSimCallDuration::GetDuration(TTimeIntervalSeconds* aTime)
+	{
+	*aTime = iCallDuration;
+	}
+	
+CSimCallRemotePartyInfoChange* CSimCallRemotePartyInfoChange::NewL(CSimCall* aCall)
+/**
+ * Standard two-phase constructor.
+ * @param aCall on upon remote party info is needed
+ * @return CSimCallRemotePartyInfoChange		
+ */
+	{
+	CSimCallRemotePartyInfoChange* self=new(ELeave) CSimCallRemotePartyInfoChange(aCall);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CSimCallRemotePartyInfoChange::CSimCallRemotePartyInfoChange(CSimCall* aCall)
+		:iCall(aCall)
+/**
+ * Trivial first phase construction.
+ * @param aCall is call object upon remote party info is needed.
+ */
+	{
+	iNotifyRemotePartyInfo.iNotifyPending=EFalse;
+	iNotifyRemotePartyInfo.iNotifyData=0;
+	}
+
+
+void CSimCallRemotePartyInfoChange::ConstructL()
+	{
+	iRemoteInfoTimer = CSimTimer::NewL(iCall->iLine->iPhone);
+	}
+
+void CSimCallRemotePartyInfoChange::Start()
+	{
+	iRemoteInfoTimer->Start(iDelay, this);
+	}
+
+CSimCallRemotePartyInfoChange::~CSimCallRemotePartyInfoChange()
+/**
+ * Standard destructor.  Destroy the heap-based object owned by this object.
+ */
+	{
+	if (iRemoteInfoTimer)
+		{
+		if (iRemoteInfoTimer->IsActive())
+			iRemoteInfoTimer->Cancel();
+		delete iRemoteInfoTimer;
+		}
+	}
+	
+void CSimCallRemotePartyInfoChange::TimerCallBack(TInt /*aId*/)
+	{
+	if(iRemotePartyInfoV1.iRemoteIdStatus != RMobileCall::ERemoteIdentityUnknown && iNotifyRemotePartyInfo.iNotifyPending)	
+		{
+		iNotifyRemotePartyInfo.iNotifyPending=EFalse;
+		*(RMobileCall::TMobileCallRemotePartyInfoV1*)iNotifyRemotePartyInfo.iNotifyData=iRemotePartyInfoV1;
+		iCall->ReqCompleted(iNotifyRemotePartyInfo.iNotifyHandle,KErrNone);
+		}	
+	}
+	
+TInt CSimCall::NotifyRemotePartyInfoChange(const TTsyReqHandle aTsyReqHandle, TDes8* aRemoteParty)
+/**
+* Record a client's interest in being notified when the remote party info changes.
+* First check that there isn't already a notification pending (the ETel Server should protect
+* against this) and then record the information necessary to complete the request later, when
+* the status does actually change.
+*
+* @param aTsyReqHandle Tsy Request handle for the client request
+* @param aStatus pointer to the call status
+* @return KErrNone
+*/
+	{
+	LOGCALL1(">>CSimCall::NotifyRemotePartyInfoChange");
+	__ASSERT_ALWAYS(iNotifyRemotePartyInfoTimer, SimPanic(EOjectNotConstructed));
+	__ASSERT_ALWAYS(!iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending,SimPanic(ENotificationAlreadyPending));
+	
+	RMobileCall::TMobileCallRemotePartyInfoV1Pckg* remotepartyPckg = (RMobileCall::TMobileCallRemotePartyInfoV1Pckg*) aRemoteParty;
+	RMobileCall::TMobileCallRemotePartyInfoV1& remoteparty = (*remotepartyPckg)();
+
+	// Check that the data structure is supported by the simulated TSY version
+	TInt err = iPhone->CheckSimTsyVersion(remoteparty);
+	if(err != KErrNone)
+		{
+		ReqCompleted(aTsyReqHandle, err);
+		return KErrNone;
+		}
+
+	//start timer
+	iNotifyRemotePartyInfoTimer->Start();	
+	
+	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending = ETrue;
+	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyHandle = aTsyReqHandle;
+	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyData = &remoteparty;
+	LOGCALL1("<<CSimCall::NotifyRemotePartyInfoChange");
+	return KErrNone;
+	}
+	
+TInt CSimCall::NotifyRemotePartyInfoChangeCancel()
+/**
+* Cancel a client's interest in being notified when the remote party info changes.
+* This is acheived simply by resetting the flag that indicates a notification is pending.
+* 
+* @return KErrNone
+*/
+	{
+	LOGCALL1(">>CSimCall::NotifyRemotePartyInfoChangeCancel");
+	if(iNotifyRemotePartyInfoTimer && iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending)
+		{
+		iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending=EFalse;
+		ReqCompleted(iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyHandle,KErrCancel);
+		}
+	LOGCALL1("<<CSimCall::NotifyRemotePartyInfoChangeCancel");
+	return KErrNone;
+	}