telephonyserverplugins/simtsy/src/CSimCall.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 42 3adadc800673
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This file contains the implementation of the Simulator TSY call classes.  The call classes
       
    15 // process the call-based requests made by ETel clients and passed down to the TSY by the
       
    16 // ETel Server.
       
    17 // 
       
    18 //
       
    19 
       
    20 /**
       
    21  @file
       
    22 */
       
    23 
       
    24 #include "CSimCall.h"
       
    25 #include "CSimPhone.h"
       
    26 #include "Simlog.h"
       
    27 
       
    28 void CSimCall::CloseCall(TAny* aObj)
       
    29 /**
       
    30 * Utility func for cleanup stack
       
    31 *
       
    32 * @param aObj a pointer to the CObject to close
       
    33 */
       
    34 	{
       
    35 	((CObject*)aObj)->Close();
       
    36 	}
       
    37 
       
    38 CSimCall::CSimCall(CSimLine* aLine,const TName& aName, CSimPhone* aPhone)
       
    39 			: iState(RMobileCall::EStatusIdle),iLine(aLine), 
       
    40 			  iHookState(ConvertStateToHook(iState)), iPhone(aPhone)
       
    41 	{
       
    42 	iNotifyStatusChange.iNotifyPending = EFalse;
       
    43 	iMobileNotifyStatusChange.iNotifyPending = EFalse;
       
    44 	iAnswerIncomingCall.iNotifyPending = EFalse;
       
    45 	iName.Copy(aName);
       
    46 	}
       
    47 
       
    48 void CSimCall::ConstructL()
       
    49 /**
       
    50 * Standard constructor
       
    51 */
       
    52 	{
       
    53 	iCallDurationHandler = CSimCallDuration::NewL(this);
       
    54 	iNotifyRemotePartyInfoTimer = CSimCallRemotePartyInfoChange::NewL(this);
       
    55 	}
       
    56 
       
    57 
       
    58 CSimCall::~CSimCall()
       
    59 /**
       
    60 * Standard destructor
       
    61 */
       
    62 	{
       
    63 	iLine->CallDestructor(this);
       
    64 	delete iCallDurationHandler;
       
    65 	delete iNotifyRemotePartyInfoTimer;
       
    66 	}
       
    67 
       
    68 CTelObject::TReqMode CSimCall::ReqModeL(const TInt aIpc)
       
    69 /**
       
    70 * This function returns the Request Mode for the request with the passed IPC value.
       
    71 * The ETel Server provides a function for returning the standard request modes for
       
    72 * the Core API requests.
       
    73 * Multimode API requests mode are handled here.
       
    74 *
       
    75 * @param aIpc the IPc number representing the client request
       
    76 * @return CTelObject::TReqMode the request mode to be used for this IPc number
       
    77 * @leave Leaves if the IPc number is not found
       
    78 */
       
    79 	{
       
    80 	// ReqModeL is called from the server's CTelObject::ReqAnalyserL
       
    81 	// in order to check the type of request it has
       
    82 
       
    83 	CTelObject::TReqMode reqMode=0;
       
    84 	LOGCALL2("CSimCall::ReqModeL called with IPC number %d",aIpc);
       
    85 	switch (aIpc)
       
    86 		{
       
    87 	//
       
    88 	// No Flow Control NOR Multiple Completion
       
    89 	//
       
    90 	case EMobileCallGetMobileDataCallCaps:
       
    91 	case EMobileCallGetMobileCallCaps:
       
    92 	case EMobileCallGetMobileCallStatus:
       
    93 	case EMobileCallGetMobileCallInfo:
       
    94 	case EMobileCallDialEmergencyCall:
       
    95 	case EMobileCallGetMobileDataCallRLPRange:
       
    96 	case EMobileCallSetDynamicHscsdParams:
       
    97 	case EMobileCallGetCurrentHscsdInfo:
       
    98 	case EMobileCallHold:
       
    99 	case EMobileCallResume:
       
   100 	case EMobileCallSwap:
       
   101 	case EMobileCallAnswerISV:
       
   102 		break;
       
   103 
       
   104 	//
       
   105 	// Flow Control Obeyed
       
   106 	//
       
   107 	case EMobileCallDialISV:
       
   108 		reqMode=KReqModeFlowControlObeyed;
       
   109 		break;
       
   110 
       
   111 	//
       
   112 	// Multiple Completion Services with Immediate Server Repost
       
   113 	// (Usually Notifications)
       
   114 	//
       
   115 
       
   116 	case EMobileCallNotifyHscsdInfoChange:
       
   117 	case EMobileCallNotifyMobileCallStatusChange:
       
   118 	case EMobileCallNotifyMobileCallCapsChange:
       
   119 	case EMobileCallNotifyRemotePartyInfoChange:
       
   120 		reqMode=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
       
   121 		break;
       
   122 		
       
   123 	default:
       
   124 		reqMode=CCallBase::ReqModeL(aIpc);
       
   125 		break;
       
   126 	}
       
   127 	return reqMode;
       
   128 	}
       
   129 
       
   130 TInt CSimCall::NumberOfSlotsL(const TInt aIpc)
       
   131 /**
       
   132 * NumberOfSlotsL is called by the server when it is registering a new notification
       
   133 * It enables the TSY to tell the server how many buffer slots to allocate for
       
   134 * "repost immediately" notifications that may trigger before clients collect them
       
   135 *
       
   136 * @param aIpc the IPc number representing the client request
       
   137 * @return TInt the number of slots required
       
   138 * @leave Leaves if the IPc number is not found
       
   139 */
       
   140 	{
       
   141 	switch (aIpc)
       
   142 		{
       
   143 	case EMobileCallNotifyHscsdInfoChange:
       
   144 	case EMobileCallNotifyMobileDataCallCapsChange:
       
   145 	case EMobileCallNotifyMobileCallStatusChange:
       
   146 	case EMobileCallNotifyMobileCallCapsChange:
       
   147 	case EMobileCallNotifyRemotePartyInfoChange:
       
   148 		LOGCALL1("CSimCall: Registered with default number of slots");
       
   149 		return KDefaultNumberOfSlots;
       
   150 	default:
       
   151 		LOGCALL1("CSimCall::NumberOfSlotsL: No match for IPC, defering to base function");
       
   152 		break;
       
   153 		}
       
   154 	return CCallBase::NumberOfSlotsL(aIpc);
       
   155 	}
       
   156 
       
   157 
       
   158 TInt CSimCall::RegisterNotification(const TInt /*aIpc*/)
       
   159 /**
       
   160 * The ETel Server calls this function when the first client makes a notification
       
   161 * request.  If supported by the underlying protocol controlling the
       
   162 * signalling stack, this can be used to start requesting updates for the relevant service.
       
   163 */
       
   164 	{
       
   165 	return KErrNone;
       
   166 	}
       
   167 
       
   168 TInt CSimCall::DeregisterNotification(const TInt /*aIpc*/)
       
   169 /**
       
   170 * The ETel Server calls this function when the last client that had previously
       
   171 * made a notification request closes its ETel Server handle.  If supported by
       
   172 * the underlying protocol controlling the	signalling stack, this can be used
       
   173 * to stop requesting updates for the relevant service.
       
   174 */
       
   175 	{
       
   176 	return KErrNone;
       
   177 	}
       
   178 
       
   179 
       
   180 void CSimCall::Init()
       
   181 /**
       
   182 * This function can be used to perform any necessary synchronous initialisation.
       
   183 */
       
   184 	{}
       
   185 
       
   186 TInt CSimCall::GetCaps(const TTsyReqHandle aTsyReqHandle,RCall::TCaps* aCallCaps)
       
   187 /**
       
   188 * Retrieve the Call capabilities
       
   189 *
       
   190 * @param aTsyReqHandle	TSY handle associated with this request.s
       
   191 * @param aCallCaps		Pointer to the call capability
       
   192 * @return KErrNone
       
   193 */
       
   194 	{
       
   195 	aCallCaps->iFlags=iCaps;
       
   196 	ReqCompleted(aTsyReqHandle,KErrNone);
       
   197 	return KErrNone;
       
   198 	}
       
   199 
       
   200 TInt CSimCall::NotifyCapsChange(const TTsyReqHandle aTsyReqHandle, RCall::TCaps* aCaps)
       
   201 /**
       
   202 * Register a client's interest in being notified when the call caps change.
       
   203 * @param aTsyReqHandle	The TSY handle associated with this request.
       
   204 * @param aCaps			The capability structure that will be populated with the new capability
       
   205 *						information.
       
   206 * @return TInt			Standard error code.
       
   207 */
       
   208 	{
       
   209 	__ASSERT_ALWAYS(!iNotifyCapsChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
       
   210 	iNotifyCapsChange.iNotifyPending=ETrue;
       
   211 	iNotifyCapsChange.iNotifyHandle=aTsyReqHandle;
       
   212 	iNotifyCapsChange.iNotifyData=aCaps;
       
   213 	return KErrNone;
       
   214 	}
       
   215 
       
   216 TInt CSimCall::NotifyCapsChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
       
   217 /**
       
   218 * Cancel a client's interest in being notified when the call capabilities change.
       
   219 */
       
   220 	{
       
   221 	if(iNotifyCapsChange.iNotifyPending)
       
   222 		{
       
   223 		iNotifyCapsChange.iNotifyPending=EFalse;
       
   224 		ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrCancel);
       
   225 		}
       
   226 	return KErrNone;
       
   227 	}
       
   228 
       
   229 TInt CSimCall::GetMobileCallCaps(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
       
   230 /**
       
   231 * Retrieve the Mobile Call capabilities
       
   232 *
       
   233 * @param aTsyReqHandle	TSY handle associated with this request.
       
   234 * @param aCaps			Pointer to the call capability
       
   235 * @return KErrNone
       
   236 */
       
   237 	{
       
   238 	TPckg<RMobileCall::TMobileCallCapsV1>* capsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)aCaps;
       
   239 	RMobileCall::TMobileCallCapsV1& caps=(*capsPckg)();
       
   240 
       
   241 	// Check that the data structure is supported by the simulated TSY version
       
   242 	TInt err = iPhone->CheckSimTsyVersion(caps);
       
   243 	if(err != KErrNone)
       
   244 		{
       
   245 		ReqCompleted(aTsyReqHandle, err);
       
   246 		return KErrNone;
       
   247 		}
       
   248 
       
   249 	caps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
       
   250 	caps.iCallEventCaps=0;
       
   251 	ReqCompleted(aTsyReqHandle,KErrNone);
       
   252 	return KErrNone;
       
   253 	}
       
   254 
       
   255 TInt CSimCall::NotifyMobileCallCapsChange(const TTsyReqHandle aTsyReqHandle, TDes8* aCaps)
       
   256 /**
       
   257 * Register a client's interest in being notified when the RMobileCall capabilities change.
       
   258 * @param aTsyReqHandle	The TSY handle associated with this request.
       
   259 * @param aCaps			The capability structure that will be populated with the new capability
       
   260 *						information.
       
   261 * @return TInt			Standard error code.
       
   262 */
       
   263 	{
       
   264 	__ASSERT_ALWAYS(!iNotifyMobileCapsChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
       
   265 	iNotifyMobileCapsChange.iNotifyPending=ETrue;
       
   266 	iNotifyMobileCapsChange.iNotifyHandle=aTsyReqHandle;
       
   267 	iNotifyMobileCapsChange.iNotifyData=aCaps;
       
   268 	return KErrNone;
       
   269 	}
       
   270 
       
   271 TInt CSimCall::NotifyMobileCallCapsChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
       
   272 /**
       
   273 * Cancel a client's interest in being notified when the RMobileCall capabilities change.
       
   274 */
       
   275 	{
       
   276 	if(iNotifyMobileCapsChange.iNotifyPending)
       
   277 		{
       
   278 		iNotifyMobileCapsChange.iNotifyPending=EFalse;
       
   279 		ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrCancel);
       
   280 		}
       
   281 	return KErrNone;
       
   282 	}
       
   283 
       
   284 TInt CSimCall::NotifyHookChange(const TTsyReqHandle aTsyReqHandle, RCall::THookStatus* aHookStatus)
       
   285 /**
       
   286 * Record a client's interst in being notified when the hook changes state.
       
   287 *
       
   288 * @param aTsyReqHandle Tsy Request handle for the client request
       
   289 * @param aHookStatus pointer to the hook status
       
   290 * @return KErrNone
       
   291 */
       
   292 	{
       
   293 	LOGCALL1(">>CSimCall::NotifyHookChange");
       
   294 	iNotifyHookChange.iNotifyPending = ETrue;
       
   295 	iNotifyHookChange.iNotifyHandle = aTsyReqHandle;
       
   296 	iNotifyHookChange.iNotifyData = aHookStatus;
       
   297 	LOGCALL1("<<CSimCall::NotifyHookChange");
       
   298 	return KErrNone;
       
   299 	}
       
   300 
       
   301 TInt CSimCall::NotifyHookChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
       
   302 /**
       
   303 * Cancel a client's interest in being notified when the hook state changes.
       
   304 *
       
   305 * @param aTsyReqHandle Tsy Request handle for the client cancel request
       
   306 * @return KErrNone
       
   307 */
       
   308 	{
       
   309 	LOGCALL1(">>CSimCall::NotifyHookChangeCancel");
       
   310 	if(iNotifyHookChange.iNotifyPending)
       
   311 		{
       
   312 		iNotifyHookChange.iNotifyPending=EFalse;
       
   313 		ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrCancel);
       
   314 		}
       
   315 	LOGCALL1("<<CSimCall::NotifyHookChangeCancel");
       
   316 	return KErrNone;
       
   317 	}
       
   318 
       
   319 TInt CSimCall::NotifyMobileCallStatusChange(const TTsyReqHandle aTsyReqHandle,RMobileCall::TMobileCallStatus* aStatus)
       
   320 /**
       
   321 * Record a client's interest in being notified when the call status changes.
       
   322 * First check that there isn't already a notification pending (the ETel Server should protect
       
   323 * against this) and then record the information necessary to complete the request later, when
       
   324 * the status does actually change.
       
   325 *
       
   326 * @param aTsyReqHandle Tsy Request handle for the client request
       
   327 * @param aStatus pointer to the call status
       
   328 * @return KErrNone
       
   329 */
       
   330 	{
       
   331 	LOGCALL1(">>CSimCall::NotifyMobileCallStatusChange");
       
   332 	__ASSERT_ALWAYS(!iMobileNotifyStatusChange.iNotifyPending,SimPanic(ENotificationAlreadyPending));
       
   333 
       
   334 	iMobileNotifyStatusChange.iNotifyPending = ETrue;
       
   335 	iMobileNotifyStatusChange.iNotifyHandle = aTsyReqHandle;
       
   336 	iMobileNotifyStatusChange.iNotifyData = aStatus;
       
   337 	LOGCALL1("<<CSimCall::NotifyMobileCallStatusChange");
       
   338 	return KErrNone;
       
   339 	}
       
   340 
       
   341 TInt CSimCall::NotifyMobileCallStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
       
   342 /**
       
   343 * Cancel a client's interest in being notified when the call status changes.
       
   344 * This is acheived simply by resetting the flag that indicates a notification is pending.
       
   345 * 
       
   346 * @param aTsyReqHandle Tsy Request handle for the client cancel request
       
   347 * @return KErrNone
       
   348 */
       
   349 	{
       
   350 	LOGCALL1(">>CSimCall::NotifyMobileCallStatusChangeCancel");
       
   351 	if(iMobileNotifyStatusChange.iNotifyPending)
       
   352 		{
       
   353 		iMobileNotifyStatusChange.iNotifyPending=EFalse;
       
   354 		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrCancel);
       
   355 		}
       
   356 	LOGCALL1("<<CSimCall::NotifyMobileCallStatusChangeCancel");
       
   357 	return KErrNone;
       
   358 	}
       
   359 
       
   360 
       
   361 TInt CSimCall::NotifyStatusChange(const TTsyReqHandle aTsyReqHandle,RCall::TStatus* aStatus)
       
   362 /**
       
   363 * Record a client's interest in being notified when the call status changes.
       
   364 * First check that there isn't already a notification pending (the ETel Server should protect
       
   365 * against this) and then record the information necessary to complete the request later, when
       
   366 * the status does actually change.
       
   367 *
       
   368 * @param aTsyReqHandle Tsy Request handle for the client request
       
   369 * @param aStatus pointer to the call status
       
   370 * @return KErrNone
       
   371 */
       
   372 	{
       
   373 	LOGCALL1(">>CSimCall::NotifyStatusChange");
       
   374 	__ASSERT_ALWAYS(!iNotifyStatusChange.iNotifyPending,SimPanic(ENotificationAlreadyPending));
       
   375 
       
   376 	iNotifyStatusChange.iNotifyPending = ETrue;
       
   377 	iNotifyStatusChange.iNotifyHandle = aTsyReqHandle;
       
   378 	iNotifyStatusChange.iNotifyData = aStatus;
       
   379 	LOGCALL1("<<CSimCall::NotifyStatusChange");
       
   380 	return KErrNone;
       
   381 	}
       
   382 
       
   383 TInt CSimCall::NotifyStatusChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
       
   384 /**
       
   385 *	Cancel a client's interest in being notified when the call status changes.
       
   386 *	This is acheived simply by resetting the flag that indicates a notification is pending.
       
   387 * 
       
   388 * @param aTsyReqHandle Tsy Request handle for the client cancel request
       
   389 * @return KErrNone
       
   390 */
       
   391 	{
       
   392 	LOGCALL1(">>CSimCall::NotifyStatusChangeCancel");
       
   393 	if(iNotifyStatusChange.iNotifyPending)
       
   394 		{
       
   395 		iNotifyStatusChange.iNotifyPending=EFalse;
       
   396 		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrCancel);
       
   397 		}
       
   398 	LOGCALL1("<<CSimCall::NotifyStatusChangeCancel");
       
   399 	return KErrNone;
       
   400 	}
       
   401 
       
   402 
       
   403 
       
   404 TInt CSimCall::NotifyDurationChange(const TTsyReqHandle aTsyReqHandle,TTimeIntervalSeconds* aTime)
       
   405 /**
       
   406 * Record a client's interest in being notified when the call duration changes.
       
   407 * 
       
   408 * @param aTsyReqHandle
       
   409 * @param aTime
       
   410 * @return KErrNone or symbian wide error code
       
   411 */
       
   412 	{
       
   413 	iCallDurationHandler->StartNotification(aTsyReqHandle, aTime);
       
   414 	return KErrNone;
       
   415 	}
       
   416 
       
   417 TInt CSimCall::NotifyDurationChangeCancel(const TTsyReqHandle /*aTsyReqHandle*/)
       
   418 /**
       
   419 * Not Supported in this TSY
       
   420 */
       
   421 	{
       
   422 	iCallDurationHandler->StopNotification();
       
   423 	return KErrNone;
       
   424 	}
       
   425 
       
   426 TInt CSimCall::GetInfo(const TTsyReqHandle aTsyReqHandle, RCall::TCallInfo* aCallInfo)
       
   427 /**
       
   428 * Retrieve the Call Information.
       
   429 *
       
   430 * @param aTsyReqHandle
       
   431 * @param aCallInfo pointer to the call information to be returned to client
       
   432 * @return KErrNone
       
   433 */
       
   434 	{
       
   435 	aCallInfo->iCallName.Copy(iName);
       
   436 	aCallInfo->iLineName.Copy(iLine->iLineName);
       
   437 	aCallInfo->iHookStatus=ConvertStateToHook(iState);
       
   438 	aCallInfo->iStatus=GetCoreCallStatus();
       
   439 	aCallInfo->iDuration=0;
       
   440 	ReqCompleted(aTsyReqHandle,KErrNone);
       
   441 	return KErrNone;
       
   442 	}
       
   443 
       
   444 TInt CSimCall::GetMobileCallInfo(const TTsyReqHandle aTsyReqHandle, TDes8* aMobileCallInfo)
       
   445 /**
       
   446 * Retrieve the Mobile Call Information
       
   447 *
       
   448 * @param aTsyReqHandle
       
   449 * @param aCallInfo pointer to the call information to be returned to client
       
   450 * @return KErrNone
       
   451 */
       
   452 	{
       
   453 	RMobileCall::TMobileCallInfoV1Pckg* mobileCallInfoV1=(RMobileCall::TMobileCallInfoV1Pckg*)aMobileCallInfo;
       
   454 	RMobileCall::TMobileCallInfoV1& mobileCallInfo=(*mobileCallInfoV1)();
       
   455 
       
   456 	// Check that the data structure is supported by the simulated TSY version
       
   457 	TInt err = iPhone->CheckSimTsyVersion(mobileCallInfo);
       
   458 	if(err != KErrNone)
       
   459 		{
       
   460 		ReqCompleted(aTsyReqHandle, err);
       
   461 		return KErrNone;
       
   462 		}
       
   463 
       
   464 	TUint caps=Caps();
       
   465 	if(caps&RCall::KCapsVoice)
       
   466 		mobileCallInfo.iService=RMobilePhone::EVoiceService;
       
   467 	else if(caps&RCall::KCapsData)
       
   468 		mobileCallInfo.iService=RMobilePhone::ECircuitDataService;
       
   469 	else if(caps&RCall::KCapsFax)
       
   470 		mobileCallInfo.iService=RMobilePhone::EFaxService;
       
   471 	else
       
   472 		mobileCallInfo.iService=RMobilePhone::EServiceUnspecified;
       
   473 
       
   474 	mobileCallInfo.iValid=0x0;
       
   475 	mobileCallInfo.iStatus=iState;
       
   476 	mobileCallInfo.iCallName.Copy(iName);
       
   477 	mobileCallInfo.iLineName.Copy(iLine->iLineName);
       
   478 	LOGCALL2("CSimCall::GetMobileCallInfo request completed with %d",iState);
       
   479 	ReqCompleted(aTsyReqHandle,KErrNone);
       
   480 	return KErrNone;
       
   481 	}
       
   482 
       
   483 RCall::TStatus CSimCall::GetCoreCallStatus()
       
   484 /**
       
   485 * Converts Multimode call status (RMobileCall::TMobileCallStatus) to 
       
   486 *          Core call Status (RCall::TStatus)
       
   487 *
       
   488 * @return RCall::TStatus The core call status
       
   489 */
       
   490 	{
       
   491 // All status enums with values of Disconnecting and below are identical in
       
   492 // ETelMM and Core, so the mapping function is simple.
       
   493 	RCall::TStatus coreStatus;
       
   494 	if (iState <= RMobileCall::EStatusDisconnecting)
       
   495 		coreStatus = (RCall::TStatus)iState;
       
   496 	else
       
   497 		switch (iState)
       
   498 		{
       
   499 		case RMobileCall::EStatusReconnectPending:
       
   500 		case RMobileCall::EStatusHold:
       
   501 			coreStatus = RCall::EStatusConnected;
       
   502 			break;
       
   503 		case RMobileCall::EStatusWaitingAlternatingCallSwitch:
       
   504 			coreStatus = RCall::EStatusIdle;
       
   505 			break;
       
   506 		default:
       
   507 			coreStatus = RCall::EStatusUnknown;
       
   508 			break;
       
   509 		}
       
   510 	return coreStatus;
       
   511 	}
       
   512 
       
   513 TInt CSimCall::GetStatus(const TTsyReqHandle aTsyReqHandle, RCall::TStatus* aCallStatus)
       
   514 /**
       
   515 * Return the current call state. (Core API request)
       
   516 *
       
   517 * @param aTsyReqHandle
       
   518 * @param aCallStatus pointer to the call status
       
   519 * @return KErrNone
       
   520 */
       
   521     {
       
   522 	LOGCALL1(">>CSimCall::GetStatus");
       
   523 	*aCallStatus=GetCoreCallStatus();
       
   524 	ReqCompleted(aTsyReqHandle,KErrNone);
       
   525 	LOGCALL1("<<CSimCall::GetStatus");
       
   526 	return KErrNone;
       
   527     }
       
   528 
       
   529 TInt CSimCall::GetMobileCallStatus(const TTsyReqHandle aTsyReqHandle, RMobileCall::TMobileCallStatus* aCallStatus)
       
   530 /**
       
   531 * Return the current call state. (Multimode API request)
       
   532 *
       
   533 * @param aTsyReqHandle
       
   534 * @param aCallStatus pointer to the call status
       
   535 * @return KErrNone
       
   536 */
       
   537     {
       
   538 	LOGCALL1(">>CSimCall::GetMobileCallStatus");
       
   539 	*aCallStatus=iState;
       
   540 	ReqCompleted(aTsyReqHandle,KErrNone);
       
   541 	LOGCALL1("<<CSimCall::GetMobileCallStatus");
       
   542 	return KErrNone;
       
   543     }
       
   544 
       
   545 TInt CSimCall::TransferOwnership(const TTsyReqHandle aTsyReqHandle)
       
   546 /**
       
   547 * Transfer call ownership
       
   548 * Not supported in this version of the Simulator TSY
       
   549 */
       
   550 	{
       
   551 	ReqCompleted(aTsyReqHandle,KErrNotSupported);
       
   552 	return KErrNone;
       
   553 	}
       
   554 
       
   555 TInt CSimCall::AcquireOwnership(const TTsyReqHandle aTsyReqHandle)
       
   556 /**
       
   557 * Acquires call ownership
       
   558 * Not supported in this version of the Simulator TSY
       
   559 */
       
   560 	{
       
   561 	ReqCompleted(aTsyReqHandle,KErrNotSupported);
       
   562 	return KErrNone;
       
   563 	}
       
   564 
       
   565 TInt CSimCall::AcquireOwnershipCancel(const TTsyReqHandle /*aTsyReqHandle*/)
       
   566 /**
       
   567 * cancel AcquireOwnership request
       
   568 * Not supported in this version of the Simulator TSY
       
   569 */
       
   570 	{
       
   571 	return KErrNone;
       
   572 	}
       
   573 
       
   574 TInt CSimCall::GetCallDuration(const TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime)
       
   575 /**
       
   576 * Retrieves the last call duration
       
   577 * Not supported in this version of the Simulator TSY
       
   578 */
       
   579 	{
       
   580 	LOGCALL1(">>CSimCall::GetCallDuration");
       
   581 	
       
   582 	iCallDurationHandler->GetDuration(aTime);
       
   583 	
       
   584 	ReqCompleted(aTsyReqHandle,KErrNone);
       
   585 	LOGCALL1("<<CSimCall::GetCallDuration");
       
   586 	return KErrNone;
       
   587 	}
       
   588 
       
   589 TInt CSimCall::RecoverDataPortAndRelinquishOwnership()
       
   590 /**
       
   591 * Recovers the comm port.
       
   592 * This is a data call specific request so not supported here.
       
   593 */
       
   594 	{
       
   595 	return KErrNotSupported;
       
   596 	}
       
   597 
       
   598 TInt CSimCall::GetFaxSettings(const TTsyReqHandle,RCall::TFaxSessionSettings*)
       
   599 /**
       
   600 * Retrieves the last fax settings
       
   601 * Not supported in this version of the Simulator TSY
       
   602 */
       
   603 	{	
       
   604 	return KErrNotSupported;
       
   605 	}
       
   606 
       
   607 TInt CSimCall::SetFaxSettings(const TTsyReqHandle,const RCall::TFaxSessionSettings*)
       
   608 /**
       
   609 * Sets the fax settings
       
   610 * Not supported in this version of the Simulator TSY
       
   611 */
       
   612 	{	
       
   613 	return KErrNotSupported;
       
   614 	}
       
   615 
       
   616 CTelObject* CSimCall::OpenNewObjectByNameL(const TDesC& /*aName*/)
       
   617 /**
       
   618 * Only Fax Calls can be opened from the Call object, KErrNotSupported is returned.
       
   619 */
       
   620 
       
   621 	{
       
   622 	User::Leave(KErrNotSupported);
       
   623 	return NULL;
       
   624 	}
       
   625 
       
   626 CTelObject* CSimCall::OpenNewObjectL(TDes& /*aNewName*/)
       
   627 /**
       
   628 * Only Fax objects can be opened from the Call object, and we are not supporting fax calls 
       
   629 * in this TSY. KErrNotSupported is returned.
       
   630 */
       
   631 	{
       
   632 	User::Leave(KErrNotSupported);
       
   633 	return NULL;
       
   634 	}
       
   635 
       
   636 TBool CSimCall::Used()
       
   637 	{
       
   638 	return (AccessCount()>1);
       
   639 	}
       
   640 
       
   641 void CSimCall::SetUsed()
       
   642 	{
       
   643 	(void)Open();
       
   644 	}
       
   645 
       
   646 void CSimCall::SetUnused()
       
   647 	{
       
   648 	Close();
       
   649 	}
       
   650 
       
   651 TInt CSimCall::ChangeStateL(RMobileCall::TMobileCallStatus aNewState,TBool aSwap, TBool aNoPropagation)
       
   652 /**
       
   653 * Attempt to change state.
       
   654 * First validate that the requested state change is ok.  If it is then proceed to change
       
   655 * the state and complete any pending state change notification.
       
   656 *
       
   657 * @param aState the new state to change to
       
   658 * @param aSwap indicates that state change takes place as a consequence of swap operation on the call
       
   659 * @param aNoPropagation  indicates whether change propagate to the holder line object
       
   660 * @return Error indication if change of state is successful or not
       
   661 */
       
   662 	{
       
   663 	LOGCALL3(">>CSimCall::ChangeState 0x%08x [newState=%d] entry", this,aNewState);
       
   664 	
       
   665 	if(!aNoPropagation)
       
   666 		{
       
   667 		TInt ret=iLine->ChangeStateL(aNewState,aSwap,this);
       
   668 		if(ret!=KErrNone)
       
   669 			return ret;
       
   670 		}
       
   671 	
       
   672 // Check for call duration change
       
   673 	if (!iCallDurationHandler)
       
   674 		iCallDurationHandler=CSimCallDuration::NewL(this);
       
   675 	if ((iState != RMobileCall::EStatusConnected) && (iState != RMobileCall::EStatusHold) &&  (aNewState == RMobileCall::EStatusConnected))
       
   676 		iCallDurationHandler->StartDuration();
       
   677 	else if ((aNewState != RMobileCall::EStatusConnected) && (aNewState != RMobileCall::EStatusHold) && ((iState == RMobileCall::EStatusConnected) || (iState == RMobileCall::EStatusHold)))
       
   678 		iCallDurationHandler->StopDuration();
       
   679 		
       
   680 // Actually change the state.
       
   681 	iState=aNewState;
       
   682 	
       
   683 // Check for a pending state change notification (core)
       
   684 	if(iNotifyStatusChange.iNotifyPending)
       
   685 		{
       
   686 		iNotifyStatusChange.iNotifyPending=EFalse;
       
   687 		*(RCall::TStatus*)iNotifyStatusChange.iNotifyData=GetCoreCallStatus();
       
   688 		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
       
   689 		}
       
   690 
       
   691 // Check for a pending state change notification (multimode)
       
   692 	if(iMobileNotifyStatusChange.iNotifyPending)
       
   693 		{
       
   694 		iMobileNotifyStatusChange.iNotifyPending=EFalse;
       
   695 		*(RMobileCall::TMobileCallStatus*)iMobileNotifyStatusChange.iNotifyData=iState;
       
   696 		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrNone);
       
   697 		}
       
   698 
       
   699 // Check for a pending hook change notification.
       
   700 	RCall::THookStatus hookStatus=ConvertStateToHook(iState);
       
   701 	if(iHookState!=hookStatus)
       
   702 		{
       
   703 		iHookState=hookStatus;
       
   704 		if(iNotifyHookChange.iNotifyPending)
       
   705 			{
       
   706 			iNotifyHookChange.iNotifyPending=EFalse;
       
   707 			*(RCall::THookStatus*)iNotifyHookChange.iNotifyData=iHookState;
       
   708 			ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrNone);
       
   709 			}
       
   710 		}
       
   711 
       
   712 // Check for a possible change in capabilities.
       
   713 	TUint caps=Caps();
       
   714 	if(iCaps!=caps)
       
   715 		{
       
   716 		iCaps=caps;
       
   717 		if(iNotifyCapsChange.iNotifyPending)
       
   718 			{
       
   719 			iNotifyCapsChange.iNotifyPending=EFalse;
       
   720 			((RCall::TCaps*)iNotifyCapsChange.iNotifyData)->iFlags=iCaps;
       
   721 			ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrNone);
       
   722 			}
       
   723 		if(iNotifyMobileCapsChange.iNotifyPending)
       
   724 			{
       
   725 			iNotifyMobileCapsChange.iNotifyPending=EFalse;
       
   726 			TPckg<RMobileCall::TMobileCallCapsV1>* mobileCallCapsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)iNotifyMobileCapsChange.iNotifyData;
       
   727 			RMobileCall::TMobileCallCapsV1& mobileCallCaps=(*mobileCallCapsPckg)();
       
   728 	
       
   729 			mobileCallCaps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
       
   730 			mobileCallCaps.iCallEventCaps=0;
       
   731 			ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrNone);
       
   732 			}
       
   733 		}
       
   734 	if((aNewState == RMobileCall::EStatusConnected && !aSwap)|| aNewState == RMobileCall::EStatusDisconnecting)
       
   735 		iLine->UpdatePhoneNotifiers(this,aNewState);		
       
   736 
       
   737 	LOGCALL2("<<CSimCall::ChangeState exit %d",iState);
       
   738 	return KErrNone;
       
   739 	}
       
   740 
       
   741 
       
   742 void CSimCall::UpdateNotifiers()
       
   743 /**
       
   744 	Update notifiers of other voice call when it gets swapped
       
   745 */
       
   746 	{
       
   747 	LOGCALL2(">>CSimCall::UpdateNotifiers 0x%08x entry", this);
       
   748 	
       
   749 // Check for call duration change
       
   750 	if (!iCallDurationHandler)
       
   751 		{
       
   752 		TRAP_IGNORE(iCallDurationHandler=CSimCallDuration::NewL(this));
       
   753 		}
       
   754 	
       
   755 			
       
   756 // Check for a pending state change notification (core)
       
   757 	if(iNotifyStatusChange.iNotifyPending)
       
   758 		{
       
   759 		iNotifyStatusChange.iNotifyPending=EFalse;
       
   760 		*(RCall::TStatus*)iNotifyStatusChange.iNotifyData=GetCoreCallStatus();
       
   761 		ReqCompleted(iNotifyStatusChange.iNotifyHandle,KErrNone);
       
   762 		}
       
   763 
       
   764 // Check for a pending state change notification (multimode)
       
   765 	if(iMobileNotifyStatusChange.iNotifyPending)
       
   766 		{
       
   767 		iMobileNotifyStatusChange.iNotifyPending=EFalse;
       
   768 		*(RMobileCall::TMobileCallStatus*)iMobileNotifyStatusChange.iNotifyData=iState;
       
   769 		ReqCompleted(iMobileNotifyStatusChange.iNotifyHandle,KErrNone);
       
   770 		}
       
   771 
       
   772 // Check for a pending hook change notification.
       
   773 	RCall::THookStatus hookStatus=ConvertStateToHook(iState);
       
   774 	if(iHookState!=hookStatus)
       
   775 		{
       
   776 		iHookState=hookStatus;
       
   777 		if(iNotifyHookChange.iNotifyPending)
       
   778 			{
       
   779 			iNotifyHookChange.iNotifyPending=EFalse;
       
   780 			*(RCall::THookStatus*)iNotifyHookChange.iNotifyData=iHookState;
       
   781 			ReqCompleted(iNotifyHookChange.iNotifyHandle,KErrNone);
       
   782 			}
       
   783 		}
       
   784 
       
   785 // Check for a possible change in capabilities.
       
   786 	TUint caps=Caps();
       
   787 	if(iCaps!=caps)
       
   788 		{
       
   789 		iCaps=caps;
       
   790 		if(iNotifyCapsChange.iNotifyPending)
       
   791 			{
       
   792 			iNotifyCapsChange.iNotifyPending=EFalse;
       
   793 			((RCall::TCaps*)iNotifyCapsChange.iNotifyData)->iFlags=iCaps;
       
   794 			ReqCompleted(iNotifyCapsChange.iNotifyHandle,KErrNone);
       
   795 			}
       
   796 		if(iNotifyMobileCapsChange.iNotifyPending)
       
   797 			{
       
   798 			iNotifyMobileCapsChange.iNotifyPending=EFalse;
       
   799 			TPckg<RMobileCall::TMobileCallCapsV1>* mobileCallCapsPckg=(TPckg<RMobileCall::TMobileCallCapsV1>*)iNotifyMobileCapsChange.iNotifyData;
       
   800 			RMobileCall::TMobileCallCapsV1& mobileCallCaps=(*mobileCallCapsPckg)();
       
   801 
       
   802 			mobileCallCaps.iCallControlCaps=iCaps;		// None of the extended caps are supported.
       
   803 			mobileCallCaps.iCallEventCaps=0;
       
   804 			ReqCompleted(iNotifyMobileCapsChange.iNotifyHandle,KErrNone);
       
   805 			}
       
   806 		}
       
   807 
       
   808 	LOGCALL2("<<CSimCall::UpdateNotifiers exit %d",iState);
       
   809 	}
       
   810 
       
   811 TInt CSimCall::ActionEvent(TCallEvent /*aEvent*/, TInt /*aStatus*/)
       
   812 /**
       
   813 * This is an empty shell function. Each line should implement its own
       
   814 * state machine.
       
   815 */
       
   816 	{
       
   817 	return KErrNotSupported;
       
   818 	}
       
   819 
       
   820 void CSimCall::GenerateCoreCallCaps(TUint& aCaps)
       
   821 /**
       
   822  * Populate the variable capabilities that are dependant upon the call state.
       
   823  * @param TUint		The capability variable that will be populated with the core capabilities.
       
   824  */
       
   825 	{
       
   826 	if(iState==RMobileCall::EStatusIdle)
       
   827 		aCaps |= RCall::KCapsDial;
       
   828 
       
   829 	if(iState==RMobileCall::EStatusConnected)
       
   830 		aCaps |= RCall::KCapsHangUp;
       
   831 
       
   832 	if((iLine->IsAnswerCallObjectSpare())&&(iState==RMobileCall::EStatusIdle))
       
   833 		aCaps |= RCall::KCapsAnswer;
       
   834 	}
       
   835 
       
   836 void CSimCall::ResetIfRingingL()
       
   837 	{
       
   838 	if(iState==RMobileCall::EStatusRinging)
       
   839 		__ASSERT_ALWAYS(ChangeStateL(RMobileCall::EStatusIdle,EFalse,ETrue) == KErrNone, SimPanic(EGeneral));
       
   840 	}
       
   841 
       
   842 void CSimCallDuration::TimerCallBack(TInt /*aId*/)
       
   843   	{
       
   844   	//increase duration by 1 sec
       
   845   	iCallDuration=static_cast<TTimeIntervalSeconds>(iCallDuration.Int()+1);
       
   846   	
       
   847   	if(iNotifyDurationChange.iNotifyPending)
       
   848   		{
       
   849   		*(TTimeIntervalSeconds*)iNotifyDurationChange.iNotifyData=iCallDuration;
       
   850   		iNotifyDurationChange.iNotifyPending=EFalse;
       
   851   		iCall->ReqCompleted(iNotifyDurationChange.iNotifyHandle,KErrNone);		
       
   852   		}
       
   853   	iDurationTimer->Start(1 , this);
       
   854   	}
       
   855 
       
   856 CSimCallDuration* CSimCallDuration::NewL(CSimCall* aCall)
       
   857 /**
       
   858  * Standard two-phase constructor.
       
   859  * @param aPhone				The parent phone object.
       
   860  * @return CSimCallDuration		The new CallDuration class 
       
   861  */
       
   862 	{
       
   863 	CSimCallDuration* self=new(ELeave) CSimCallDuration(aCall);
       
   864 	CleanupStack::PushL(self);
       
   865 	self->ConstructL();
       
   866 	CleanupStack::Pop();
       
   867 	return self;
       
   868 	}
       
   869 
       
   870 CSimCallDuration::CSimCallDuration(CSimCall* aCall)
       
   871 		:iCallDuration(0),iCall(aCall)
       
   872 /**
       
   873  * Trivial first phase construction.
       
   874  * @param aPhone				The parent phone object.
       
   875  */
       
   876 	{
       
   877 	iNotifyDurationChange.iNotifyPending=EFalse;
       
   878 	iNotifyDurationChange.iNotifyData=0;
       
   879 	}
       
   880 
       
   881 
       
   882 void CSimCallDuration::ConstructL()
       
   883 	{
       
   884 	iDurationTimer = CSimTimer::NewL(iCall->iLine->iPhone);
       
   885 	}
       
   886 
       
   887 
       
   888 CSimCallDuration::~CSimCallDuration()
       
   889 /**
       
   890  * Standard destructor.  Destroy the heap-based object owned by this object.
       
   891  */
       
   892 	{
       
   893 	if (iDurationTimer)
       
   894 		{
       
   895 		if (iDurationTimer->IsActive())
       
   896 			iDurationTimer->Cancel();
       
   897 		delete iDurationTimer;
       
   898 		}
       
   899 	}
       
   900 
       
   901 void CSimCallDuration::StartDuration()
       
   902 	{
       
   903 	iCallDuration = 0;
       
   904 	iDurationTimer->Start(1 , this);
       
   905 	}
       
   906 
       
   907 void CSimCallDuration::StopDuration()
       
   908 	{	
       
   909 	if (iDurationTimer)
       
   910 		{
       
   911 		if (iDurationTimer->IsActive())
       
   912 			iDurationTimer->Cancel();
       
   913 		}
       
   914 	}
       
   915 
       
   916 void CSimCallDuration::StartNotification(TTsyReqHandle aTsyReqHandle, TTimeIntervalSeconds* aTime)
       
   917 	{
       
   918 	__ASSERT_ALWAYS(!iNotifyDurationChange.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding));
       
   919 	iNotifyDurationChange.iNotifyData=aTime;
       
   920 	iNotifyDurationChange.iNotifyPending=ETrue;
       
   921 	iNotifyDurationChange.iNotifyHandle=aTsyReqHandle;
       
   922 	}
       
   923 
       
   924 void CSimCallDuration::StopNotification()
       
   925 	{
       
   926 	if(iNotifyDurationChange.iNotifyPending)
       
   927 		{
       
   928 		iNotifyDurationChange.iNotifyPending=EFalse;
       
   929 		iCall->ReqCompleted(iNotifyDurationChange.iNotifyHandle,KErrCancel);
       
   930 		}
       
   931 	}
       
   932 
       
   933 void CSimCallDuration::GetDuration(TTimeIntervalSeconds* aTime)
       
   934 	{
       
   935 	*aTime = iCallDuration;
       
   936 	}
       
   937 	
       
   938 CSimCallRemotePartyInfoChange* CSimCallRemotePartyInfoChange::NewL(CSimCall* aCall)
       
   939 /**
       
   940  * Standard two-phase constructor.
       
   941  * @param aCall on upon remote party info is needed
       
   942  * @return CSimCallRemotePartyInfoChange		
       
   943  */
       
   944 	{
       
   945 	CSimCallRemotePartyInfoChange* self=new(ELeave) CSimCallRemotePartyInfoChange(aCall);
       
   946 	CleanupStack::PushL(self);
       
   947 	self->ConstructL();
       
   948 	CleanupStack::Pop();
       
   949 	return self;
       
   950 	}
       
   951 
       
   952 CSimCallRemotePartyInfoChange::CSimCallRemotePartyInfoChange(CSimCall* aCall)
       
   953 		:iCall(aCall)
       
   954 /**
       
   955  * Trivial first phase construction.
       
   956  * @param aCall is call object upon remote party info is needed.
       
   957  */
       
   958 	{
       
   959 	iNotifyRemotePartyInfo.iNotifyPending=EFalse;
       
   960 	iNotifyRemotePartyInfo.iNotifyData=0;
       
   961 	}
       
   962 
       
   963 
       
   964 void CSimCallRemotePartyInfoChange::ConstructL()
       
   965 	{
       
   966 	iRemoteInfoTimer = CSimTimer::NewL(iCall->iLine->iPhone);
       
   967 	}
       
   968 
       
   969 void CSimCallRemotePartyInfoChange::Start()
       
   970 	{
       
   971 	iRemoteInfoTimer->Start(iDelay, this);
       
   972 	}
       
   973 
       
   974 CSimCallRemotePartyInfoChange::~CSimCallRemotePartyInfoChange()
       
   975 /**
       
   976  * Standard destructor.  Destroy the heap-based object owned by this object.
       
   977  */
       
   978 	{
       
   979 	if (iRemoteInfoTimer)
       
   980 		{
       
   981 		if (iRemoteInfoTimer->IsActive())
       
   982 			iRemoteInfoTimer->Cancel();
       
   983 		delete iRemoteInfoTimer;
       
   984 		}
       
   985 	}
       
   986 	
       
   987 void CSimCallRemotePartyInfoChange::TimerCallBack(TInt /*aId*/)
       
   988 	{
       
   989 	if(iRemotePartyInfoV1.iRemoteIdStatus != RMobileCall::ERemoteIdentityUnknown && iNotifyRemotePartyInfo.iNotifyPending)	
       
   990 		{
       
   991 		iNotifyRemotePartyInfo.iNotifyPending=EFalse;
       
   992 		*(RMobileCall::TMobileCallRemotePartyInfoV1*)iNotifyRemotePartyInfo.iNotifyData=iRemotePartyInfoV1;
       
   993 		iCall->ReqCompleted(iNotifyRemotePartyInfo.iNotifyHandle,KErrNone);
       
   994 		}	
       
   995 	}
       
   996 	
       
   997 TInt CSimCall::NotifyRemotePartyInfoChange(const TTsyReqHandle aTsyReqHandle, TDes8* aRemoteParty)
       
   998 /**
       
   999 * Record a client's interest in being notified when the remote party info changes.
       
  1000 * First check that there isn't already a notification pending (the ETel Server should protect
       
  1001 * against this) and then record the information necessary to complete the request later, when
       
  1002 * the status does actually change.
       
  1003 *
       
  1004 * @param aTsyReqHandle Tsy Request handle for the client request
       
  1005 * @param aStatus pointer to the call status
       
  1006 * @return KErrNone
       
  1007 */
       
  1008 	{
       
  1009 	LOGCALL1(">>CSimCall::NotifyRemotePartyInfoChange");
       
  1010 	__ASSERT_ALWAYS(iNotifyRemotePartyInfoTimer, SimPanic(EOjectNotConstructed));
       
  1011 	__ASSERT_ALWAYS(!iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending,SimPanic(ENotificationAlreadyPending));
       
  1012 	
       
  1013 	RMobileCall::TMobileCallRemotePartyInfoV1Pckg* remotepartyPckg = (RMobileCall::TMobileCallRemotePartyInfoV1Pckg*) aRemoteParty;
       
  1014 	RMobileCall::TMobileCallRemotePartyInfoV1& remoteparty = (*remotepartyPckg)();
       
  1015 
       
  1016 	// Check that the data structure is supported by the simulated TSY version
       
  1017 	TInt err = iPhone->CheckSimTsyVersion(remoteparty);
       
  1018 	if(err != KErrNone)
       
  1019 		{
       
  1020 		ReqCompleted(aTsyReqHandle, err);
       
  1021 		return KErrNone;
       
  1022 		}
       
  1023 
       
  1024 	//start timer
       
  1025 	iNotifyRemotePartyInfoTimer->Start();	
       
  1026 	
       
  1027 	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending = ETrue;
       
  1028 	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyHandle = aTsyReqHandle;
       
  1029 	iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyData = &remoteparty;
       
  1030 	LOGCALL1("<<CSimCall::NotifyRemotePartyInfoChange");
       
  1031 	return KErrNone;
       
  1032 	}
       
  1033 	
       
  1034 TInt CSimCall::NotifyRemotePartyInfoChangeCancel()
       
  1035 /**
       
  1036 * Cancel a client's interest in being notified when the remote party info changes.
       
  1037 * This is acheived simply by resetting the flag that indicates a notification is pending.
       
  1038 * 
       
  1039 * @return KErrNone
       
  1040 */
       
  1041 	{
       
  1042 	LOGCALL1(">>CSimCall::NotifyRemotePartyInfoChangeCancel");
       
  1043 	if(iNotifyRemotePartyInfoTimer && iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending)
       
  1044 		{
       
  1045 		iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyPending=EFalse;
       
  1046 		ReqCompleted(iNotifyRemotePartyInfoTimer->iNotifyRemotePartyInfo.iNotifyHandle,KErrCancel);
       
  1047 		}
       
  1048 	LOGCALL1("<<CSimCall::NotifyRemotePartyInfoChangeCancel");
       
  1049 	return KErrNone;
       
  1050 	}