--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/common_tsy/commontsy/src/mmtsy/cmmdatacalltsy.cpp Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,3236 @@
+// Copyright (c) 2006-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:
+//
+
+
+
+// INCLUDE FILES
+#include "cmmdatacalltsy.h"
+#include "cmmdatalinetsy.h"
+#include "cmmphonetsy.h"
+#include "cmmtsyreqhandlestore.h"
+#include "cmmcalllist.h"
+#include "CMmCommonStaticUtility.h"
+#include "MmTsy_numberOfSlots.h"
+#include "cmmlinelist.h"
+#include "cmmmessagemanagerbase.h"
+#include <ctsy/pluginapi/cmmdatapackage.h>
+#include <ctsy/serviceapi/gsmerror.h>
+#include "cmmcallgsmwcdmaext.h"
+#include <etelmmerr.h>
+
+
+// ======== MEMBER FUNCTIONS ========
+
+CMmDataCallTsy::CMmDataCallTsy()
+ {
+ }
+
+CMmDataCallTsy* CMmDataCallTsy::NewL(
+ CMmPhoneTsy* aMmPhone, CMmDataLineTsy* aMmLine,
+ RMobilePhone::TMobileService aMode,
+ TDes& aName,
+ CMmMessageManagerBase* aMessageManager )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::NewL. Call name: %S", &aName);
+
+ CMmDataCallTsy* mmCall = NULL;
+
+ //check input parameters
+ if ( NULL != aMmPhone && NULL != aMmLine &&
+ RMobilePhone::ECircuitDataService == aMode )
+ {
+ mmCall = new( ELeave ) CMmDataCallTsy;
+ CleanupClosePushL( *mmCall );
+ mmCall->iMmPhone = aMmPhone;
+ mmCall->iMmLine = aMmLine;
+ mmCall->iCallName = aName;
+ mmCall->iCallMode = aMode;
+ mmCall->iMessageManager = aMessageManager;
+ mmCall->ConstructL( aMode );
+ CleanupStack::Pop( mmCall );
+ }
+
+ return mmCall;
+ }
+
+CMmDataCallTsy::~CMmDataCallTsy()
+ {
+TFLOGSTRING3("TSY: CMmDataCallTsy::~CMmDataCallTsy - Call deleted iCallId: %d iCallName: %S",
+ iCallId, &iCallName);
+
+ // If Dial fails, Symbian CSD agent will close the call immediately.
+ // This means that TSY has not yet received call status indications,
+ // where call status changes to idle. Thus responses from modem are
+ // passed to call object.
+ // Here we need to recover dataport if it is used.
+ CCallBase::SetUnowned();
+
+ // Check if dataport is loaned!
+ if ( iLoanedCommPort.iPort.Compare( KNullDesC) != 0 )
+ {
+ //Create package
+ CCallDataPackage package;
+ //Set call id and call mode
+ package.SetCallIdAndMode( iCallId, iCallMode );
+ //Pack commport
+ package.PackData( &iLoanedCommPort );
+
+ //Send request to the Domestic OS layer.
+ if( iMessageManager )
+ {
+ TRAP_IGNORE(
+ iMessageManager->HandleRequestL(
+ EEtelCallRecoverDataPort, &package );
+ );
+ }
+
+ iLoanedCommPort.iCsy.Zero();
+ iLoanedCommPort.iPort.Zero();
+ }
+
+ iRetDataCallCaps = NULL;
+ iRetHscsdInfo = NULL;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::InitInternalAttributes
+// Initialises miscellaneous internal attributes.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::InitInternalAttributes()
+ {
+ CMmCallTsy::InitInternalAttributes();
+
+ //set call capabilities
+ iCallCaps.iFlags =
+ RCall::KCapsData | RCall::KCapsDial | RCall::KCapsConnect;
+
+ // Boolean that indicates if this call object is finished data call.
+ // Required as Symbian CSD agent in situation where first data call
+ // fails due wrong number and it then opens second data call, which
+ // dials correct number. Call status notifications go to wrong call
+ // object (the first one) and causes problems for clients.
+ iIsFinishedDataCall = EFalse;
+
+ //data call params
+ iRetDataCallCaps = NULL;
+ iLoanedCommPort.iCsy.Zero();
+ iLoanedCommPort.iPort.Zero();
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::DoExtFuncL
+// DoExtFuncL is called by the Etel server when it has an "extended", i.e.
+// non-core ETel request for the TSY. To process a request handle, request
+// type and request data are passed to the TSY.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::DoExtFuncL(
+ const TTsyReqHandle aTsyReqHandle,
+ const TInt aIpc,
+ const TDataPackage& aPackage )
+ {
+TFLOGSTRING3("TSY: CMmDataCallTsy::DoExtFuncL - IPC: %d Handle: %d",
+ aIpc, aTsyReqHandle);
+
+ TInt ret( KErrNone );
+
+ TAny* dataPtr = aPackage.Ptr1();
+ TAny* dataPtr2 = aPackage.Ptr2();
+
+ // The request data has to extracted from TDataPackage and the TAny*
+ // pointers have to be "cast" to the expected request data type
+
+ // NOTE! Do not put any Cancel methods here.
+ switch ( aIpc )
+ {
+ // Call Status
+ // Get Call Status
+ case EMobileCallGetMobileCallStatus:
+ ret = GetMobileCallStatus( aTsyReqHandle,
+ reinterpret_cast<RMobileCall::TMobileCallStatus*>(dataPtr) );
+ break;
+ // Notify Call Status Change
+ case EMobileCallNotifyMobileCallStatusChange:
+ ret = NotifyMobileCallStatusChange(
+ reinterpret_cast<RMobileCall::TMobileCallStatus*>(dataPtr) );
+ break;
+ // Transfer One Call to Remote Party of Another Call
+ case EMobileCallTransfer:
+ ret = TransferL( aTsyReqHandle );
+ break;
+ // Notify Call Event
+ case EMobileCallNotifyCallEvent:
+ ret = NotifyCallEvent(
+ reinterpret_cast<RMobileCall::TMobileCallEvent*>( dataPtr) );
+ break;
+ // Call Control
+ // Get Call Capabilities
+ case EMobileCallGetMobileCallCaps:
+ ret = GetMobileCallCaps( aTsyReqHandle, aPackage.Des1n() );
+ break;
+
+ //Notify Call Capabilities Change
+ case EMobileCallNotifyMobileCallCapsChange:
+ ret = NotifyMobileCallCapsChange(aPackage.Des1n());
+ break;
+
+ // Call Information
+ // Get Mobile Call Information
+ case EMobileCallGetMobileCallInfo:
+ ret = GetMobileCallInfo( aTsyReqHandle, aPackage.Des1n() );
+ break;
+ // Notify Change of Remote Party Information
+ case EMobileCallNotifyRemotePartyInfoChange:
+ ret = NotifyRemotePartyInfoChange(
+ reinterpret_cast<RMobileCall::TMobileCallRemotePartyInfoV1Pckg*>(
+ aPackage.Des1n()) );
+ break;
+ // Data Call Capabilities
+ // Get Data Call Capabilities
+ case EMobileCallGetMobileDataCallCaps:
+ ret = GetMobileDataCallCaps( aTsyReqHandle, aPackage.Des1n() );
+ break;
+ // Notify Change of Data Call Capabilities
+ case EMobileCallNotifyMobileDataCallCapsChange:
+ ret = NotifyMobileDataCallCapsChange( aTsyReqHandle,
+ aPackage.Des1n() );
+ break;
+ // Data Call RLP Parameters
+ // Get Data Call RLP Range
+ case EMobileCallGetMobileDataCallRLPRange:
+ ret = GetMobileDataCallRLPRange( aTsyReqHandle,
+ reinterpret_cast<TInt*>(dataPtr),
+ reinterpret_cast<RMobileCall::TMobileDataRLPRangesV1Pckg*>(
+ dataPtr2) );
+ break;
+ // High Speed Circuit Switched Data (HCSCD)
+ // Set Dynamic HSCSD Call Parameters
+ case EMobileCallSetDynamicHscsdParams:
+ ret = SetDynamicHscsdParams( aTsyReqHandle,
+ reinterpret_cast<RMobileCall::TMobileCallAiur*>(dataPtr),
+ reinterpret_cast<TInt*>(dataPtr2) );
+ break;
+ // Get Current HSCSD Call Information
+ case EMobileCallGetCurrentHscsdInfo:
+ ret = GetCurrentHscsdInfo( aTsyReqHandle, aPackage.Des1n() );
+ break;
+ // Notify Change of HSCSD Call Information
+ case EMobileCallNotifyHscsdInfoChange:
+ ret = NotifyHscsdInfoChange( aTsyReqHandle, aPackage.Des1n() );
+ break;
+ // Order to notify if privacy is confirmed
+ case EMobileCallNotifyPrivacyConfirmation:
+ ret = NotifyPrivacyConfirmation(
+ reinterpret_cast<RMobilePhone::TMobilePhonePrivacy*>(dataPtr) );
+ break;
+ // Dial a call ( DialNoFdnCheck )
+ case EMobileCallDialNoFdnCheck:
+ ret = DialNoFdnCheck( aTsyReqHandle, aPackage.Des1n(),
+ aPackage.Des2u() );
+ break;
+ // Unsupported features
+ case EMobileCallDialEmergencyCall:
+ case EMobileCallHold:
+ case EMobileCallResume:
+ case EMobileCallSwap:
+ case EMobileCallGoOneToOne:
+
+ case EMobileCallSwitchAlternatingCall:
+ case EMobileCallNotifyAlternatingCallSwitch:
+ case EMobileCallSetPrivacy:
+ case EMobileCallSetTrafficChannel:
+ case EMobileCallNotifyTrafficChannelConfirmation:
+ case EMobileCallGetUUSCaps:
+ case EMobileCallNotifyUUSCapsChange:
+ case EMobileCallActivateUUS:
+ case EMobileCallSendUUI:
+ case EMobileCallReceiveUUI:
+ case EMobileCallHangupWithUUI:
+ case EMobileCallAnswerWithUUI:
+ case EMobileCallNotifyVoiceFallback:
+ case EMobileCallDeflect:
+ case EMobileCallActivateCCBS:
+ case EMobileCallRejectCCBS:
+ default:
+ ret = KErrNotSupported;
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::ReqModeL
+// ReqModeL is called from the ETel server's CTelObject::ReqAnalyserL in order
+// to check the type of request it has.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+CTelObject::TReqMode CMmDataCallTsy::ReqModeL(
+ const TInt aIpc )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::ReqModeL - IPC: %d", aIpc);
+
+ CTelObject::TReqMode ret( 0 ); // default return value
+
+ switch ( aIpc )
+ {
+ // No Flow Control
+ // All disabled
+ // TSYs wishing to implement their own buffering algorithm will
+ // place all requests in this category.
+ // This category will also be used by the RecoverDataPort request
+ // that must be passed to the TSY to indicate that it may use
+ // the communications port after a loan.
+
+ // Get methods that do not use Licencee specific TSY and return
+ // immediately. Flow control not required.
+ case EEtelCallGetInfo:
+ case EEtelCallGetStatus:
+ case EEtelCallGetCaps:
+ case EEtelCallGetBearerServiceInfo:
+ case EEtelCallGetOwnershipStatus:
+ case EEtelCallGetCallParams:
+ case EEtelCallGetCallDuration:
+ case EEtelCallGetFaxSettings:
+ case EMobileCallGetMobileCallStatus:
+ case EMobileCallGetMobileCallInfo:
+ case EMobileCallGetMobileDataCallCaps:
+ case EMobileCallGetMobileCallCaps:
+ case EMobileCallGetCurrentHscsdInfo:
+ case EMobileCallGetMobileDataCallRLPRange:
+ case EMobileCallGetUUSCaps:
+ case EMobileCallActivateUUS:
+ case EMobileCallSendUUI:
+ case EMobileCallReceiveUUI:
+ case EMobileCallHangupWithUUI:
+ case EMobileCallAnswerWithUUI:
+ // Other methods that do not use Licencee specific TSY and return
+ // immediately.
+ // Flow control not required.
+ case EEtelCallAcquireOwnership:
+ case EEtelCallTransferOwnership:
+ case EEtelCallSetFaxSettings:
+ // Methods that can propably take a long time and cannot therefore be
+ // flow controlled. Solution: All these methods must check req handle
+ // table before handling the request. In case that the request table
+ // indicates that same method has been called and has not been
+ // completed, the method should return KErrServerBusy.
+ case EMobileCallTransfer:
+ // This is also included here due to the fact that Emergency call
+ // should never be blocked by flow control. KErrServerBusy returned
+ // when already already dialing.
+ case EMobileCallDialEmergencyCall:
+ // HangUp cannot be flow controlled. Client should for example be able
+ // to terminate a call while another call is e.g. in Dialling state.
+ case EEtelCallHangUp:
+ // Answer was mixed with Hangup. Therefore this is also No flow
+ // control type
+ case EEtelCallAnswer:
+ // dial is not flow controlled as compeltion may take a while and that
+ // blocks for example PS data activation in 3G while dialing.
+ case EEtelCallDial:
+ case EMobileCallDialNoFdnCheck:
+ break;
+ // Flow Controlled Services
+ // KReqModeFlowControlObeyed
+ // Commands that change the state of the phone, e.g. clearing the
+ // AoC counter; are commands that the TSY should only deal with
+ // one at a time.
+
+ //Voice call related methods that should be handled one at the time.
+ case EEtelCallConnect:
+ case EMobileCallHold:
+ case EMobileCallResume:
+ case EMobileCallSwap:
+ case EMobileCallDeflect:
+ case EMobileCallGoOneToOne:
+ //Data call related methods that should be handled one at the time.
+ case EEtelCallLoanDataPort:
+ case EEtelCallRecoverDataPort:
+ case EMobileCallSwitchAlternatingCall:
+ case EMobileCallSetDynamicHscsdParams:
+ case EMobileCallSetPrivacy:
+ case EMobileCallSetTrafficChannel:
+ ret = KReqModeFlowControlObeyed;
+ break;
+ // ReqModePostImmediately
+ // Requests that notify a client about a change of state, where
+ // the TSY needs to distinguish between different clients.
+ //ret=KReqModeRePostImmediately;
+
+ // KReqModeMultipleCompletionEnabled
+ // (a) commands that may take some time, but which the TSY can
+ // handle more than one of concurrently, or
+ // (b) notifications that the TSY does not wish to be re-posted
+ // immediately, so the server does no buffering.
+ //ret=KReqModeMultipleCompletionEnabled;
+
+ // KReqModeMultipleCompletionEnabled | KReqModeFlowControlObeyed
+ // A command that may take some time and which the TSY can only
+ // deal with one at a time.
+ //ret = KReqModeMultipleCompletionEnabled |
+ // KReqModeFlowControlObeyed;
+ //break;
+
+ // Notifications
+ // KReqModeMultipleCompletionEnabled | ReqModePostImmediately
+ // Requests that notify a client about a change of state.
+ // Since these requests do not require the issuing of any modem
+ // commands, they do not have to obey flow control.
+ // The TSY never gets more than one of these outstanding per
+ // CTelObject
+ case EEtelCallNotifyHookChange:
+ case EEtelCallNotifyStatusChange:
+ case EEtelCallNotifyDurationChange:
+ case EEtelCallCapsChangeNotification:
+ case EMobileCallNotifyCallEvent:
+ case EMobileCallNotifyMobileCallStatusChange:
+ case EMobileCallNotifyRemotePartyInfoChange:
+ case EMobileCallNotifyPrivacyConfirmation:
+ case EMobileCallNotifyTrafficChannelConfirmation:
+ case EMobileCallNotifyHscsdInfoChange:
+ case EMobileCallNotifyMobileDataCallCapsChange:
+ case EMobileCallNotifyAlternatingCallSwitch:
+ case EMobileCallNotifyMobileCallCapsChange:
+ case EMobileCallNotifyVoiceFallback:
+ case EMobileCallNotifyUUSCapsChange:
+ ret = KReqModeMultipleCompletionEnabled |
+ KReqModeRePostImmediately;
+ break;
+ // Cancel Requests
+ // It is not necessary to include the Cancel methods in ReqModeL.
+ // The ETel server never calls ReqModeL with a Cancel IPC.
+
+ // Other variations of return values are unusable
+
+ // Default: Call CCallBase's ReqModeL.
+ default:
+ //Direct the request to the CCallBase
+ ret = CCallBase::ReqModeL( aIpc );
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::NumberOfSlotsL
+// 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.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::NumberOfSlotsL(
+ const TInt aIpc )
+ {
+ // There is a buffer in the ETel server for each type of NOTIFICATION and
+ // the size of the buffer is determined by the TSY. When the ETel server
+ // discovers that a request is "repost immediately" it will ask the TSY
+ // how big a buffer it wants by calling CTelObject::NumberOfSlotsL( ).
+ //
+ // It is up to the TSY developer's judgement how many buffer slots this
+ // method returns for each notification. If there is a danger that
+ // a particular notification could trigger frequently and in rapid
+ // succession (e.g. call group change notification) then at least 10 or
+ // 20 slots may be required. For a notification that triggers rarely,
+ // perhaps 1 or 2 slots is enough.
+ //
+ // So if the ETel server has stored a few occurrences of a particular
+ // notification, when a client subsequently calls that notification
+ // request, the ETel server will complete the client's request with
+ // the saved data.
+
+ TInt numberOfSlots( 1 );
+
+ switch ( aIpc )
+ {
+ case EEtelCallNotifyHookChange:
+ numberOfSlots = KMmCallHookChangeSlots;
+ break;
+ case EEtelCallNotifyStatusChange:
+ numberOfSlots = KMmCallStatusChangeSlots;
+ break;
+ case EEtelCallNotifyDurationChange:
+ numberOfSlots = KMmCallDurationChangeSlots;
+ break;
+ case EEtelCallCapsChangeNotification:
+ numberOfSlots = KMmCallCapsChangeSlots;
+ break;
+ case EMobileCallNotifyCallEvent:
+ numberOfSlots = KMmCallCallEventSlots;
+ break;
+ case EMobileCallNotifyMobileCallStatusChange:
+ numberOfSlots = KMmCallMobileCallStatusChangeSlots;
+ break;
+ case EMobileCallNotifyRemotePartyInfoChange:
+ numberOfSlots = KMmCallRemotePartyInfoChangeSlots;
+ break;
+ case EMobileCallNotifyPrivacyConfirmation:
+ numberOfSlots = KMmCallPrivacyConfirmationSlots;
+ break;
+ case EMobileCallNotifyTrafficChannelConfirmation:
+ numberOfSlots = KMmCallTrafficChannelConfirmationSlots;
+ break;
+ case EMobileCallNotifyHscsdInfoChange:
+ numberOfSlots = KMmCallHscsdInfoChangeSlots;
+ break;
+ case EMobileCallNotifyMobileDataCallCapsChange:
+ numberOfSlots = KMmCallMobileDataCallCapsChangeSlots;
+ break;
+ case EMobileCallNotifyAlternatingCallSwitch:
+ numberOfSlots = KMmCallAlternatingCallSwitchSlots;
+ break;
+ case EMobileCallNotifyMobileCallCapsChange:
+ numberOfSlots = KMmCallMobileCallCapsChangeSlots;
+ break;
+ case EMobileCallNotifyVoiceFallback:
+ numberOfSlots = KMmCallVoiceFallbackSlots;
+ break;
+ case EMobileCallNotifyUUSCapsChange:
+ numberOfSlots = KMmCallUUSCapsChangeSlots;
+ break;
+ default:
+ // Unknown or invalid Call IPC
+ User::Leave( KErrNotSupported );
+ break;
+ }
+
+ return numberOfSlots;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CancelService
+// CancelService is called by the ETel server when it is "cleaning-up" any
+// still outstanding asynchronous requests before closing a client's
+// sub-session. This will happen if a client closes its R-class handle without
+// cancelling outstanding asynchronous requests. Only Mobile API requests are
+// handled here.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::CancelService(
+ const TInt aIpc,
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ TFLOGSTRING3("TSY: CMmDataCallTsy::CancelService - IPC: %d, Req handle: %d",
+ aIpc, aTsyReqHandle);
+
+ TInt ret( KErrNone );
+
+ //When the clients close their sub-sessions (eg. by calling RPhone::Close)
+ //they may not have cancelled all their outstanding asynchronous requests
+ //before closing. It is up to the ETel server to clean up in this
+ //situation, so the server will find the list of outstanding requests
+ //related to that sub-session object and pass these outstanding IPC req
+ //numbers, one at a time, to the CancelService function in the TSY.
+ switch ( aIpc )
+ {
+ //TSY has started a request and it is not possible to then cancel this
+ //request. The best thing for the TSY to do in this case is to proceed
+ //as though the Cancel never happened. The server's call to the TSY
+ //cancel function will return synchronously. The TSY then continues to
+ //wait for the original acknowledgement and when it receives it,
+ //the TSY will complete the original request.
+ case EMobileCallSetDynamicHscsdParams:
+ case EMobileCallHold:
+ case EMobileCallResume:
+ case EMobileCallSwap:
+ case EMobileCallGoOneToOne:
+ case EMobileCallDeflect:
+ case EMobileCallTransfer:
+ case EMobileCallNotifyTrafficChannelConfirmation:
+ break;
+ //Cancel methods that are not supported
+ case EMobileCallDialEmergencyCall:
+ case EMobileCallSwitchAlternatingCall:
+ case EMobileCallNotifyAlternatingCallSwitch:
+ case EMobileCallGetMobileDataCallRLPRange:
+ case EMobileCallNotifyVoiceFallback:
+ case EMobileCallNotifyUUSCapsChange:
+ case EMobileCallActivateUUS:
+ case EMobileCallSendUUI:
+ case EMobileCallReceiveUUI:
+ case EMobileCallHangupWithUUI:
+ case EMobileCallAnswerWithUUI:
+ ret = KErrNotSupported;
+ break;
+ //Notification Cancels, no special requirements.
+ case EMobileCallNotifyMobileDataCallCapsChange:
+ ret = NotifyMobileDataCallCapsChangeCancel( aTsyReqHandle );
+ break;
+ case EMobileCallNotifyHscsdInfoChange:
+ ret = NotifyHscsdInfoChangeCancel( aTsyReqHandle );
+ break;
+ case EMobileCallNotifyMobileCallCapsChange:
+ ret = NotifyMobileCallCapsChangeCancel( aTsyReqHandle );
+ break;
+ case EMobileCallNotifyMobileCallStatusChange:
+ ret = NotifyMobileCallStatusChangeCancel( aTsyReqHandle );
+ break;
+ case EMobileCallNotifyCallEvent:
+ ret = NotifyCallEventCancel( aTsyReqHandle );
+ break;
+ case EMobileCallNotifyRemotePartyInfoChange:
+ ret = NotifyRemotePartyInfoChangeCancel( aTsyReqHandle );
+ break;
+ case EMobileCallNotifyPrivacyConfirmation:
+ ret = NotifyPrivacyConfirmationCancel( aTsyReqHandle );
+ break;
+ //Default case
+ default:
+ //call CCallBase
+ ret = CCallBase::CancelService( aIpc, aTsyReqHandle );
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CompleteNotifyStatusChange
+// Complete notification when status changes. If the new status requires, this
+// method will ask call protocol extension to update it's status and
+// capabilities and line owning this call to update it's status.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CompleteNotifyStatusChange(
+ TInt aResult,
+ CMmDataPackage* aDataPackage )
+ {
+ if ( iGhostCall )
+ {
+ HandleGhostCallStatusChange( aResult, aDataPackage );
+ }
+ else
+ {
+ TInt callIndex( 0 );
+ TInt extendedError(
+ CMmCommonStaticUtility::ExtendedErrorCode( aResult ) );
+ TInt ret( KErrNone );
+ TBool timerStarted( EFalse );
+ TBool statusChanged ( EFalse );
+ TBool mobileStatusChanged ( EFalse );
+ CMmDataCallTsy* mmCall = NULL;
+ RMobileCall::TMobileCallStatus callStatus( RMobileCall::EStatusIdle );
+ CCallDataPackage* callDataPackage =
+ reinterpret_cast<CCallDataPackage*>( aDataPackage );
+
+ callDataPackage->UnPackData( callStatus );
+
+ TFLOGSTRING2("TSY: CMmDataCallTsy::CompleteNotifyStatusChange - \
+ aResult: %d", aResult );
+ TFLOGSTRING3("TSY: CMmDataCallTsy::CompleteNotifyStatusChange - \
+ Call status: %d, Call name: %S", callStatus, &iCallName);
+
+ switch( callStatus )
+ {
+ case RMobileCall::EStatusIdle:
+ // stop the call duration timer
+ timerStarted = iCallTimer->Stop();
+ // Check air time timer only if call was in active state
+ // (call timer was started)
+ if ( timerStarted )
+ {
+ iMmPhone->AirTimeTimerCheckStop();
+ UpdateLifeTimer();
+ }
+
+ iCallStatus = RCall::EStatusIdle;
+ iMobileCallStatus = RMobileCall::EStatusIdle;
+
+ SetUnowned();
+ ClearCallStatus();
+ statusChanged = ETrue;
+
+ if ( KErrNone != aResult )
+ {
+ if ( KErrGsmReleaseByUser == aResult ||
+ KErrGsmBusyUserRequest == aResult )
+ {
+ // aResult must be KErrNone to indicate the client
+ // that HangUp has successfully completed
+ CompleteHangUp( KErrNone );
+ if ( this != iMmPhone->WaitingCallForData() )
+ {
+ CompleteAnswerIncomingCall(
+ KErrGsmBusyUserRequest );
+ }
+ }
+ else
+ {
+ // Set last exit code
+ iLastExitCode = aResult;
+ CompleteHangUp( aResult );
+ if ( this != iMmPhone->WaitingCallForData() )
+ {
+ CompleteAnswerIncomingCall( aResult );
+ }
+ }
+ CompleteDial( aResult );
+ CompleteDialNoFdn( aResult );
+ }
+ // Try to complete Dial and HangUp; If completes happens from
+ // here, something has gone wrong. Done to prevent TSY from
+ // hanging.
+ else
+ {
+ iLastExitCode = KErrGeneral;
+ TInt errorValue = CMmCommonStaticUtility::EpocErrorCode(
+ KErrNotReady, KErrNotFound );
+ CompleteDial( errorValue );
+ CompleteDialNoFdn( errorValue );
+ CompleteHangUp( errorValue );
+ if ( this != iMmPhone->WaitingCallForData() )
+ {
+ CompleteAnswerIncomingCall( errorValue );
+ }
+ }
+ // save last id. Required by Conference call implementation
+ SetPreviousCallId( iCallId );
+ // reset call id
+ iCallId = -1;
+
+ // reset caps.
+ iCallCaps.iFlags |=
+ RCall::KCapsDial | RCall::KCapsConnect;
+ iCallCaps.iFlags &= ~( RCall::KCapsAnswer );
+
+ // Check if KCapsHangup or dataport caps still exists
+ // If it does, remove and complete notification.
+ if ( ( RCall::KCapsHangUp ==
+ ( iCallCaps.iFlags & RCall::KCapsHangUp ) ) ||
+ ( RCall::KCapsLoanDataPort ==
+ ( iCallCaps.iFlags & RCall::KCapsLoanDataPort ) ) ||
+ ( RCall::KCapsRecoverDataPort ==
+ ( iCallCaps.iFlags & RCall::KCapsRecoverDataPort) ) )
+ {
+ iCallCaps.iFlags &= ~(
+ RCall::KCapsHangUp |
+ RCall::KCapsLoanDataPort |
+ RCall::KCapsRecoverDataPort );
+ CompleteNotifyCapsChange();
+ }
+
+ // Call Transfer handling
+ if ( ServiceRequested( EMultimodeCallTransfer ) )
+ {
+ // Complete Transfer
+ CompleteTransfer( KErrNone );
+ }
+ break;
+ // End of case KCallStatusIdle
+ case RMobileCall::EStatusDialling:
+#ifdef REQHANDLE_TIMER
+ iTsyReqHandleStore->StopTimeout( EMultimodeCallDial );
+ iTsyReqHandleStore->StopTimeout(
+ EMultimodeCallDialNoFdnCheck );
+#endif
+ iCallStatus = RCall::EStatusDialling;
+ iMobileCallStatus = RMobileCall::EStatusDialling;
+ statusChanged = ETrue;
+ if ( iDialCancelFlag != CMmCallTsy::EDialCancelNotCalled )
+ {
+ TTsyReqHandle dialCancelHandle =
+ iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeCallDial );
+ TTsyReqHandle dialCancelHandleNoFdn =
+ iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeCallDialNoFdnCheck );
+
+ if ( 0 < dialCancelHandle )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteNotifyStatusChange. - HangUp - EMultimodeCallDial");
+ HangUp( dialCancelHandle );
+ }
+ else if ( 0 < dialCancelHandleNoFdn )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteNotifyStatusChange. - HangUp - EMultimodeCallDialNoFdnCheck");
+ HangUp( dialCancelHandleNoFdn );
+ }
+ else
+ {
+ iDialCancelFlag = CMmCallTsy::EDialCancelNotCalled;
+ }
+ }
+ break;
+ case RMobileCall::EStatusConnecting:
+ iCallStatus = RCall::EStatusConnecting;
+ iMobileCallStatus = RMobileCall::EStatusConnecting;
+ statusChanged = ETrue;
+ break;
+ case RMobileCall::EStatusRinging:
+ iCallStatus = RCall::EStatusRinging;
+ iMobileCallStatus = RMobileCall::EStatusRinging;
+ statusChanged = ETrue;
+
+ // Set caps.
+ iCallCaps.iFlags &= ~(
+ RCall::KCapsDial | RCall::KCapsConnect );
+
+ iCallCaps.iFlags |= RCall::KCapsHangUp;
+ if ( ( NULL == iMmPhone->CallList()->GetMmCallByStatus(
+ RMobileCall::EStatusConnected ) ) &&
+ ( NULL == iMmPhone->CallList()->GetMmCallByStatus(
+ RMobileCall::EStatusHold ) ) )
+ {
+ iCallCaps.iFlags |= RCall::KCapsAnswer;
+ }
+ //complete caps change notification
+ CompleteNotifyCapsChange();
+
+ // Check if the call is for Call Back functionality.
+ // E.g. client has dialled server, which calls back to
+ // save user the data call charging.
+ TFLOGSTRING("TSY: CMmDataCallTsy::Check for waiting call");
+ if ( this == iMmPhone->WaitingCallForData() )
+ {
+ // Client has already tried to answer the incoming
+ // call, so do it now
+ CallComingForWaitingCall();
+ }
+ break;
+ case RMobileCall::EStatusAnswering:
+ // Set caps
+ iCallCaps.iFlags |= RCall::KCapsHangUp;
+ iCallCaps.iFlags &= ~(
+ RCall::KCapsDial |
+ RCall::KCapsAnswer );
+
+
+ iCallStatus = RCall::EStatusAnswering;
+ iMobileCallStatus = RMobileCall::EStatusAnswering;
+ statusChanged = ETrue;
+ break;
+ case RMobileCall::EStatusConnected:
+ if ( KErrMMEtelCallForbidden == aResult )
+ {
+ CMmCallList* callList = iMmPhone->CallList();
+
+ for( TInt i=0; i< callList->GetNumberOfObjects();i++)
+ {
+ CMmDataCallTsy* call =
+ reinterpret_cast<CMmDataCallTsy*>(
+ iMmPhone->CallList()->GetMmCallByIndex( i ) );
+
+ // if there is call with status Answering, complete
+ // it with CALL_CAUSE_NOT_ALLOWED
+ if( RCall::EStatusAnswering == call->Status() )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteNotifyStatusChange Answering not allowed!");
+ TInt errorValue =
+ CMmCommonStaticUtility::EpocErrorCode(
+ KErrAccessDenied, KErrMMEtelCallForbidden );
+ call->CompleteAnswerIncomingCall( errorValue );
+ }
+ }
+ }
+ // check previous status. If status is answering
+ if ( RCall::EStatusAnswering == iCallStatus )
+ {
+ // don't start timers if error occurred
+ if ( KErrNone == aResult )
+ {
+ //Start call duration monitoring
+ iCallTimer->Start();
+ //Check if start the air time duration monitoring
+ iMmPhone->AirTimeTimerCheckStart();
+ }
+
+ }
+ // If it was connecting and dial cancel has not been activated
+ else if ( ( iCallStatus == RCall::EStatusConnecting ||
+ iCallStatus == RCall::EStatusDialling ) &&
+ CMmCallTsy::EDialCancelNotCalled == iDialCancelFlag )
+ {
+ // Start call duration monitoring
+ iCallTimer->Start();
+ // start air time duration monitoring
+ iMmPhone->AirTimeTimerCheckStart();
+ }
+
+ // Don't update status if it has not changed.
+ if ( RCall::EStatusConnected != iCallStatus ||
+ RMobileCall::EStatusConnected != iMobileCallStatus )
+ {
+ iCallStatus = RCall::EStatusConnected;
+ iMobileCallStatus = RMobileCall::EStatusConnected;
+ statusChanged = ETrue;
+ }
+ break;
+ case RMobileCall::EStatusDisconnecting:
+ // When call is released, this call object becomes "used".
+ // Thus set iIsFinishedDataCall to ETrue.
+ iIsFinishedDataCall = ETrue;
+
+ // Core status
+ iCallStatus = RCall::EStatusHangingUp;
+ statusChanged = ETrue;
+ // Mobile status
+ iMobileCallStatus = RMobileCall::EStatusDisconnecting;
+ mobileStatusChanged = ETrue;
+
+ if ( iCallDirection == RMobileCall::EMobileTerminated )
+ {
+ // CompleteDial in case remote user is busy
+ CompleteDial( aResult );
+ CompleteDialNoFdn( aResult );
+ }
+
+ // Set last exit code
+ if ( KErrGsmReleaseByUser == aResult ||
+ KErrGsmBusyUserRequest == aResult ||
+ KErrGsmCCNormalUnspecified == extendedError ||
+ KErrNone == aResult )
+ {
+ iLastExitCode = KErrNone;
+ }
+ else
+ {
+ // set last exit code
+ iLastExitCode = aResult;
+ }
+
+ // reset caps.
+ if ( RCall::KCapsLoanDataPort ==
+ ( iCallCaps.iFlags & RCall::KCapsLoanDataPort ) )
+ {
+ iCallCaps.iFlags &= ~( RCall::KCapsLoanDataPort );
+ CompleteNotifyCapsChange();
+ }
+ break;
+ case RMobileCall::EStatusDisconnectingWithInband:
+ // When call is released, this call object becomes "used".
+ // Thus set iIsFinishedDataCall to ETrue.
+ iIsFinishedDataCall = ETrue;
+ // Core status
+ iCallStatus = RCall::EStatusHangingUp;
+ statusChanged = ETrue;
+ // Mobile status
+ iMobileCallStatus =
+ RMobileCall::EStatusDisconnectingWithInband;
+ mobileStatusChanged = ETrue;
+ // CompleteDial in case remote user is busy
+ CompleteDial( aResult );
+ CompleteDialNoFdn( aResult );
+ // Set last exit code
+ if ( KErrGsmReleaseByUser == aResult ||
+ KErrGsmBusyUserRequest == aResult ||
+ KErrGsmCCNormalUnspecified == extendedError ||
+ KErrNone == aResult )
+ {
+ iLastExitCode = KErrNone;
+ }
+ else
+ {
+ // set last exit code
+ iLastExitCode = aResult;
+ }
+
+ //reset caps.
+ if ( RCall::KCapsLoanDataPort ==
+ ( iCallCaps.iFlags & RCall::KCapsLoanDataPort ) )
+ {
+ iCallCaps.iFlags &= ~( RCall::KCapsLoanDataPort );
+ CompleteNotifyCapsChange();
+ }
+ break;
+ case RMobileCall::EStatusHold:
+ case RMobileCall::EStatusUnknown:
+ case RMobileCall::EStatusReconnectPending:
+ case RMobileCall::EStatusWaitingAlternatingCallSwitch:
+ case RMobileCall::EStatusTransferring:
+ case RMobileCall::EStatusTransferAlerting:
+ default:
+ // nothing to do
+ break;
+ }
+
+ //reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeCallNotifyStatusChange );
+
+ if ( ( EMultimodeCallReqHandleUnknown != reqHandle )
+ && statusChanged )
+ {
+ *iRetStatus = iCallStatus;
+ //reset req handle.
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallNotifyStatusChange );
+
+ ReqCompleted( reqHandle, ret );
+ }
+
+ // reset req handle. Returns the deleted req handle
+ reqHandle = iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeCallNotifyMobileCallStatusChange );
+
+ if ( ( EMultimodeCallReqHandleUnknown != reqHandle )
+ && (statusChanged || mobileStatusChanged) )
+ {
+ *iRetMobileCallStatus = iMobileCallStatus;
+ // reset req handle.
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallNotifyMobileCallStatusChange );
+ ReqCompleted( reqHandle, ret );
+ }
+
+ // Update also line's status
+ if ( statusChanged || mobileStatusChanged )
+ {
+ iMmLine->CompleteNotifyStatusChange();
+ }
+
+ // Inform extension dll about the current status. Enables dynamic
+ // capability updates. Must be done before Notifying caps change
+ if ( KErrNone == iMmCallExtInterface->
+ CompleteNotifyStatusChange( iMobileCallStatus ) )
+ {
+ CompleteNotifyMobileCallCapsChange( KErrNone );
+ CompleteNotifyMobileDataCallCapsChange();
+ }
+
+ mmCall = reinterpret_cast<CMmDataCallTsy*>(
+ iMmPhone->CallList()->GetMmCallByIndex( callIndex ) );
+ while ( mmCall )
+ {
+ if ( RMobileCall::EStatusIdle != mmCall->MobileCallStatus() &&
+ this != mmCall )
+ {
+ if ( KErrNone ==
+ mmCall->ActiveCallExtension()->
+ CompleteNotifyStatusChange( mmCall->MobileCallStatus() ) )
+ {
+ mmCall->CompleteNotifyMobileCallCapsChange( KErrNone );
+ mmCall->CompleteNotifyMobileDataCallCapsChange();
+ }
+ }
+ callIndex++;
+ mmCall = reinterpret_cast<CMmDataCallTsy*>(
+ iMmPhone->CallList()->GetMmCallByIndex( callIndex ) );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::Dial
+// This CORE API method dials to the given number.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::Dial(
+ const TTsyReqHandle aTsyReqHandle,
+ const TDesC8* aCallParams,
+ TDesC* aTelNumber )
+ {
+TFLOGSTRING3("TSY: CMmDataCallTsy::Dial - Req handle: %d, Call name: %S",
+ aTsyReqHandle, &iCallName);
+
+ if( aCallParams->Length()!= 0)
+ {
+ if(sizeof(RCall::TCallParams) > aCallParams->Length())
+ {
+ TFLOGSTRING ("TSY: CMmDataCallTsy::Dial bad size argument");
+ // Complete the request with appropiate error
+ return KErrArgument;
+ }
+ }
+ CMmCallList* callList = iMmPhone->CallList();
+ TBool dialFlag( EFalse );
+
+ for(TInt i=0; i< callList->GetNumberOfObjects();i++)
+ {
+ CMmCallTsy* call = callList->GetMmCallByIndex( i );
+ if( call->GetDialFlag() )
+ {
+ dialFlag = ETrue;
+ i= callList->GetNumberOfObjects();
+ }
+ }
+
+ if(!dialFlag )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::Dial ONGOING" );
+ SetDialFlag( ETrue );
+ TTsyReqHandle dialHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallDial );
+
+ // reset exit code
+ iLastExitCode = KErrNone;
+
+ // reset finished data call flag
+ iIsFinishedDataCall = EFalse;
+
+ if ( ERfsStateInfoInactive == iMmPhone->GetRfStateInfo() )
+ {
+ TFLOGSTRING("TSY: Offline mode ON, Dial request is not allowed" );
+ TInt ret = CMmCommonStaticUtility::EpocErrorCode(
+ KErrGeneral, KErrGsmOfflineOpNotAllowed );
+
+ // Complete the request with appropiate error
+ ReqCompleted ( aTsyReqHandle, ret );
+ }
+
+ // check that status is Idle
+ else if ( RMobileCall::EStatusIdle != iMobileCallStatus )
+ {
+ // The request cannot be forwarded since this call object
+ // is still in use.
+ // Complete request with status value informing the client
+ // about the situation.
+ TFLOGSTRING("TSY: CMmDataCallTsy::Dial - KErrNotReady");
+ ReqCompleted( aTsyReqHandle, KErrNotReady );
+ }
+ else if ( 0 < dialHandle )
+ {
+ // The request is already in processing because of previous request
+ // Complete request with status value informing the client about
+ // the situation.
+ TFLOGSTRING("TSY: CMmDataCallTsy::Dial - KErrServerBusy");
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else
+ {
+
+ TInt ret( KErrNone );
+ TInt trapError( KErrNone );
+ TCallOwnership ownerShip = EOwnedFalse;
+
+ if(aCallParams->Length() >0)
+ {
+ RCall::TCallParamsPckg* paramsPckg = reinterpret_cast<RCall::TCallParamsPckg*>(
+ const_cast<TDesC8*>( aCallParams ) );
+ RCall::TCallParams& params = ( *paramsPckg )();
+
+ // save call params
+ iCallParams.iSpeakerControl = params.iSpeakerControl;
+ iCallParams.iSpeakerVolume = params.iSpeakerVolume;
+ iCallParams.iInterval = params.iInterval;
+ iCallParams.iWaitForDialTone = params.iWaitForDialTone;
+ }
+ else
+ {
+ iCallParams.iSpeakerControl = RCall::EMonitorSpeakerControlAlwaysOff;
+ iCallParams.iSpeakerVolume = RCall::EMonitorSpeakerVolumeOff;
+ iCallParams.iInterval = 0;
+ iCallParams.iWaitForDialTone = RCall::EDialToneWait;
+ }
+
+ // set call direction
+ iCallDirection = RMobileCall::EMobileOriginated;
+
+ // Check if there already is an active or connecting call
+ TInt numberOfObjects = iMmPhone->CallList()->
+ GetNumberOfObjects();
+ for ( TInt i = 0; i < numberOfObjects; i++ )
+ {
+ CMmDataCallTsy* mmCall = reinterpret_cast<CMmDataCallTsy*>(
+ iMmPhone->CallList()->GetMmCallByIndex( i ) );
+ if ( !( RMobileCall::EStatusUnknown ==
+ mmCall->MobileCallStatus() ||
+ RMobileCall::EStatusIdle ==
+ mmCall->MobileCallStatus() ||
+ RMobileCall::EStatusDisconnecting ==
+ mmCall->MobileCallStatus() ||
+ RMobileCall::EStatusDisconnectingWithInband ==
+ mmCall->MobileCallStatus() ) )
+ {
+ ret = KErrEtelCallAlreadyActive;
+ break;
+ }
+ }
+
+ // Return value can also be priorityclient!
+ ownerShip = CheckOwnership( aTsyReqHandle );
+
+ if ( KErrNone == ret && ( EOwnedUnowned == ownerShip ||
+ EOwnedPriorityClient == ownerShip ) )
+ {
+ SetOwnership( aTsyReqHandle );
+
+ if ( KErrNone == ret )
+ {
+ TFLOGSTRING("TSY: CMmDataCallTsy::Dial - DialDataCall");
+ TRAP( trapError,
+ ret = iMmCallExtInterface->DialDataCallL(
+ iCallMode, aCallParams, aTelNumber );
+ );
+ if ( KErrNone != trapError )
+ {
+ //error handling. DialDataCall() leaved.
+ ret = trapError;
+ }
+ // If dial succeeded, continue
+ if ( KErrNone == ret )
+ {
+ RPhone::TStatus modemStatus;
+ modemStatus.iModemDetected = RPhone::EDetectedPresent;
+ modemStatus.iMode = RPhone::EModeEstablishingLink;
+ iMmPhone->CompleteNotifyModemDetected( modemStatus );
+
+ //update core status
+ iCallCaps.iFlags &= ~(
+ RCall::KCapsDial | RCall::KCapsConnect );
+ iCallCaps.iFlags |= RCall::KCapsHangUp;
+ //complete core caps change
+ CompleteNotifyCapsChange();
+ }
+ }
+ }
+
+ if ( KErrNone != ret )
+ {
+ ReqCompleted( aTsyReqHandle, ret );
+ ClearCallStatus();
+ }
+ else
+ {
+#ifdef REQHANDLE_TIMER
+ // set timer for the request
+ SetTypeOfResponse( EMultimodeCallDial, aTsyReqHandle );
+#else
+ // set timer
+ iTsyReqHandleStore->SetTsyReqHandle(
+ EMultimodeCallDial, aTsyReqHandle );
+#endif
+ }
+ }
+
+ return KErrNone;
+ }
+ else
+ return KErrServerBusy;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CompleteDial
+// Completes a Dial request.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CompleteDial(
+ TInt aResult )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::CompleteDial - Result: %d", aResult );
+TFLOGSTRING3("TSY: CMmDataCallTsy::CompleteDial - Call Id: %d, Call name: %S",
+ iCallId, &iCallName);
+
+ // Set dial flag to false
+ SetDialFlag( EFalse );
+
+ // reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallDial );
+
+ if ( EMultimodeCallReqHandleUnknown != reqHandle )
+ {
+ if ( aResult != KErrNone )
+ {
+ // The creation has failed.
+ iLastExitCode = aResult;
+ ClearCallStatus();
+
+ //Dial has failed, update core status - dial possible again
+ iCallCaps.iFlags |= RCall::KCapsDial;
+ iCallCaps.iFlags &= ~( RCall::KCapsHangUp );
+
+ //complete caps change notification
+ CompleteNotifyCapsChange();
+ }
+
+ ReqCompleted( reqHandle, aResult );
+
+ }
+
+ // Set also new call caps to enable dataport loaning!
+ if ( RCall::EStatusConnected == iCallStatus &&
+ KErrNone == aResult )
+ {
+ iCallCaps.iFlags |= RCall::KCapsLoanDataPort;
+ iMmCallExtInterface->AddGSMCallCaps(
+ RCall::KCapsLoanDataPort );
+
+ //complete caps change notification
+ CompleteNotifyCapsChange();
+ CompleteNotifyMobileCallCapsChange( KErrNone );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::AnswerIncomingCall
+// This CORE API method is used for answering to an incoming call.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::AnswerIncomingCall(
+ const TTsyReqHandle aTsyReqHandle,
+ const TDesC8* )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::AnswerIncomingCall. \n\t\t\t Handle: %d",
+ aTsyReqHandle);
+
+ TTsyReqHandle answerCallHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallAnswer );
+
+ if ( 0 < answerCallHandle )
+ {
+ //The request is already in processing because of previous request
+ //Complete request with status value informing the client about
+ //the situation.
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else
+ {
+ TInt ret( KErrNone );
+ //call object is under use again
+ iIsFinishedDataCall = EFalse;
+ //reset exit code
+ iLastExitCode = KErrNone;
+
+ if ( EOwnedUnowned == CheckOwnership( aTsyReqHandle ) )
+ {
+ // If Answering is allowed (KCapsAnswer is set) or
+ // if automatic answer is to be enabled (call status idle)
+ if ( iCallCaps.iFlags & RCall::KCapsAnswer ||
+ RCall::EStatusIdle == iCallStatus )
+ {
+ SetOwnership( aTsyReqHandle );
+
+ if ( KErrNone == ret )
+ {
+ //Answer incoming call
+ TRAPD( trapError,
+ ret = iMmCallExtInterface->
+ AnswerIncomingDataCallL( iCallId );
+ );
+
+ if ( KErrNone != trapError )
+ {
+ //error handling. Object cannot be created.
+ ret = trapError;
+ }
+
+ if ( KErrNone == ret )
+ {
+ //Remove answering, dialing and connecting
+ //capabilities
+ iCallCaps.iFlags |= RCall::KCapsHangUp;
+ iCallCaps.iFlags &= ~( RCall::KCapsAnswer |
+ RCall::KCapsDial | RCall::KCapsConnect );
+ CompleteNotifyCapsChange();
+ }
+ }
+ }
+ else
+ {
+ ret = KErrNotReady;
+ }
+ }
+ else if ( EOwnedTrue == CheckOwnership( aTsyReqHandle ) ||
+ EOwnedPriorityClient == CheckOwnership( aTsyReqHandle ) )
+ {
+ // SOS architechture Call Back functionality tries to answer
+ // incoming call even before the current MO call is fully
+ // released. So, save pointer to this CMmDataCallTsy object
+ // into CMmPhoneTsy.
+ iMmPhone->SetWaitingCallForData( this );
+ //Remove answering, dialing and connecting capabilities.
+ iCallCaps.iFlags |= RCall::KCapsHangUp;
+ iCallCaps.iFlags &= ~(
+ RCall::KCapsAnswer | RCall::KCapsDial | RCall::KCapsConnect );
+ CompleteNotifyCapsChange();
+ }
+ // Else return error
+ else
+ {
+ ret = KErrEtelNotCallOwner;
+ }
+
+ //error handling
+ if ( KErrNone != ret )
+ {
+ ReqCompleted( aTsyReqHandle, ret );
+ ClearCallStatus();
+ }
+ else
+ {
+#ifdef REQHANDLE_TIMER
+ //set timer for the request
+ SetTypeOfResponse( EMultimodeCallAnswer, aTsyReqHandle );
+#else
+ //timer set
+ iTsyReqHandleStore->SetTsyReqHandle(
+ EMultimodeCallAnswer, aTsyReqHandle );
+#endif
+ }
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::AnswerIncomingCallCancel
+// TSY has started a request and it is not possible to then cancel this
+// request. The best thing for the TSY to do in this case is to call
+// HangUp method to do this and set a flag so that we can know that
+// AnswerIncomingCallCancel handling is going on.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::AnswerIncomingCallCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+TFLOGSTRING3("TSY: CMmDataCallTsy::AnswerIncomingCallCancel. Req handle: %d, Call name: %S",
+ aTsyReqHandle, &iCallName);
+
+ TInt ret( KErrNone );
+
+ if( iAnswerCancelFlag )
+ {
+ ret = KErrServerBusy;
+ }
+ else
+ {
+ iAnswerCancelFlag = ETrue;
+
+ if ( 0 < iCallId )
+ {
+ HangUp( aTsyReqHandle );
+ }
+ else
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::AnswerIncomingCallCancel -- iCallStatus = %d",
+ iCallStatus);
+ if ( RCall::EStatusUnknown == iCallStatus )
+ {
+ // Cancel automatic answering
+
+ //Create package
+ CCallDataPackage package;
+ //Set call id and call mode
+ package.SetCallIdAndMode( iCallId, iCallMode );
+ // This is needed, messhandler tries to get two pointers.
+ // Without this second pointer is NULL and crashes
+ TBool autoStChangeDisable( EFalse );
+ TInt hangUpCause( KErrGsmReleaseByUser );
+ //Pack call parameters and mobile call info
+ package.PackData( &hangUpCause, &autoStChangeDisable );
+
+ //Send request to the Domestic OS layer.
+ TRAPD( leaveError,
+ ret = iMessageManager->HandleRequestL(
+ EEtelCallHangUp, &package );
+ );
+
+ //send failure
+ if ( KErrNone != ret || KErrNone != leaveError )
+ {
+ ReqCompleted( aTsyReqHandle, ret );
+ }
+ }
+ CompleteAnswerIncomingCall( KErrCancel );
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CompleteAnswerIncomingCall
+// Completes answer request to client.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CompleteAnswerIncomingCall(
+ TInt aResult )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::CompleteAnswerIncomingCall - Result: %d",
+ aResult );
+TFLOGSTRING3("TSY: CMmDataCallTsy::CompleteAnswerIncomingCall - Call Id: %d, Call name: %S",
+ iCallId, &iCallName);
+
+ //reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle =
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallAnswer );
+
+ if ( EMultimodeCallReqHandleUnknown != reqHandle )
+ {
+ if ( KErrNone != aResult )
+ {
+ TInt extendedError(
+ CMmCommonStaticUtility::ExtendedErrorCode( aResult ) );
+
+ if ( KErrGsmCCNormalUnspecified == extendedError )
+ {
+ //Call MT released while answer request was ongoing
+ //Set Symbian error value to disconnected.
+ aResult = CMmCommonStaticUtility::EpocErrorCode(
+ KErrGeneral, KErrDisconnected );
+ }
+ else
+ {
+ iCallCaps.iFlags |= RCall::KCapsAnswer | RCall::KCapsDial;
+ iCallCaps.iFlags &= ~( RCall::KCapsHangUp );
+
+ CompleteNotifyCapsChange();
+ }
+
+ iLastExitCode = aResult;
+
+ ClearCallStatus();
+ }
+
+ ReqCompleted( reqHandle, aResult );
+
+ }
+
+ // Set also new call caps to enable dataport loaning!
+ if ( RCall::EStatusConnected == iCallStatus &&
+ KErrNone == aResult )
+ {
+ iCallCaps.iFlags |= RCall::KCapsLoanDataPort;
+ iMmCallExtInterface->AddGSMCallCaps(
+ RCall::KCapsLoanDataPort );
+
+ //complete caps change notification
+ CompleteNotifyCapsChange();
+ CompleteNotifyMobileCallCapsChange( KErrNone );
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::HangUp
+// This CORE API method disconnects the call. Used with normal voice calls,
+// emergency calls as well as data calls. DialCancel also uses this method.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::HangUp(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+TFLOGSTRING3("TSY: CMmDataCallTsy::HangUp - Req. handle: %d, Call name: %S",
+ aTsyReqHandle, &iCallName);
+
+ TInt hangUpCause( KErrNone );
+ TInt ret( KErrNone );
+
+ TTsyReqHandle hangUpHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallHangUp );
+ TTsyReqHandle dialHandle =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallDial );
+ TTsyReqHandle dialHandleNoFdnCheck =
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallDialNoFdnCheck );
+
+ if ( 0 < hangUpHandle || iHangUpFlag )
+ {
+ //The request is already in processing because of previous request
+ //Complete request with status value informing the client about
+ //the situation.
+TFLOGSTRING("TSY: CMmDataCallTsy::HangUp - KErrServerBusy");
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else if ( RCall::EStatusIdle == iCallStatus &&
+ EMultimodeCallReqHandleUnknown == dialHandle )
+ {
+ //Call object is already in idle state. Complete HangUp request with
+ //error.
+TFLOGSTRING("TSY: CMmDataCallTsy::HangUp - KErrNotReady");
+ ReqCompleted( aTsyReqHandle, KErrNotReady );
+ }
+ else
+ {
+ // If this was not called by DialCancel or AnswerIncomingCallCancel
+ if ( CMmCallTsy::EDialCancelNotCalled == iDialCancelFlag &&
+ !iAnswerCancelFlag )
+ {
+#ifdef REQHANDLE_TIMER
+ //set timer for the request
+ SetTypeOfResponse( EMultimodeCallHangUp, aTsyReqHandle );
+#else
+ //save HangUp request handle, set timer
+ iTsyReqHandleStore->SetTsyReqHandle(
+ EMultimodeCallHangUp, aTsyReqHandle );
+#endif
+ }
+
+ //decide the hangup cause
+ if ( RCall::EStatusRinging == iCallStatus )
+ {
+ iLastExitCode = KErrGsmCallRejected;
+ hangUpCause = KErrGsmBusyUserRequest;
+ }
+ else
+ {
+ hangUpCause = KErrGsmReleaseByUser;
+ }
+
+ // Call handling
+ //If the call is ringing e.g. MT call, we do not have ownership
+ //yet. So let the client reject the call without checking
+ //ownership.
+ if ( RCall::EStatusRinging == iCallStatus )
+ {
+ TFLOGSTRING("TSY: CMmDataCallTsy::HangUp - Reject incoming call");
+ }
+ //Phone Application is the first client that is started, it
+ //will always be the priority client and thus able to hangup calls
+ //Owner of the call is also able to hangup the call.
+ else if ( ( CCallBase::CheckPriorityClient( aTsyReqHandle ) ) ||
+ ( CheckOwnership( aTsyReqHandle ) != EOwnedFalse ) )
+ {
+ ret = KErrNone;
+ }
+ // If call is not owned, complete with error
+ else if ( CCallBase::EOwnedTrue !=
+ CheckOwnership( aTsyReqHandle ) )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallHangUp );
+ ret = KErrEtelNotCallOwner;
+ ReqCompleted( aTsyReqHandle, KErrEtelNotCallOwner );
+ }
+
+ if ( KErrNone == ret )
+ {
+ //Create package
+ CCallDataPackage package;
+ //Set call id and call mode
+ package.SetCallIdAndMode( iCallId, iCallMode );
+
+ // This is needed, messhandler tries to get two pointers. Without
+ // this second pointer is NULL and crashes
+ TBool autoStChangeDisable = EFalse;
+ //Pack call parameters and mobile call info
+ package.PackData( &hangUpCause, &autoStChangeDisable );
+ //Send request to the Domestic OS layer.
+ TRAPD( leaveError,
+ ret = iMessageManager->HandleRequestL(
+ EEtelCallHangUp, &package );
+ );
+
+ //send failure
+ if ( KErrNone != ret || KErrNone != leaveError )
+ {
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallHangUp );
+ ReqCompleted( aTsyReqHandle, ret );
+ }
+ else
+ {
+ //update core status - hangup not possible now.
+ //remove also dataport caps
+ iCallCaps.iFlags &= ~(
+ RCall::KCapsHangUp | RCall::KCapsLoanDataPort );
+
+ iMmCallExtInterface->RemoveGSMCallCaps(
+ RCall::KCapsHangUp | RCall::KCapsLoanDataPort );
+
+ //complete core caps change
+ CompleteNotifyCapsChange();
+ CompleteNotifyMobileCallCapsChange( KErrNone );
+ //set HangUp flag to ongoing
+ iHangUpFlag = ETrue;
+ }
+ }
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CompleteHangUp
+// Completes call hangup (both normal and emergency calls). If the cause value
+// is different than the sent one, the call release requset has failed. In
+// this case the causeValue describes the fail cause. Otherwise the call
+// releasing has succeeded.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CompleteHangUp(
+ TInt aResult )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::CompleteHangUp.\n \t\t\t Result: %d",
+ aResult );
+TFLOGSTRING3("TSY: CMmDataCallTsy::CompleteHangUp - Call Id: %d, Call name: %S",
+ iCallId, &iCallName);
+
+ TInt ret( KErrNone );
+
+ // Complete for HangUp request
+ // (not to DialCancel or AnswerIncomingCallCancel)
+ if ( CMmCallTsy::EDialCancelNotCalled == iDialCancelFlag &&
+ !iAnswerCancelFlag )
+ {
+ //reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle =
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallHangUp );
+
+ if ( EMultimodeCallReqHandleUnknown != reqHandle )
+ {
+ //if hangup request failed
+ if ( KErrNone != aResult )
+ {
+ //Hangup failed, it should be still possible to carry out
+ iCallCaps.iFlags |= RCall::KCapsHangUp;
+ iMmCallExtInterface->AddGSMCallCaps(
+ RCall::KCapsHangUp );
+
+ //Call status is not idle. HangUp request failed, complete
+ //HangUp request with error.
+ if ( RCall::EStatusIdle != iCallStatus )
+ {
+ // ignore KErrGsmReleaseByUser, which means that the call ended
+ // because the local user released the call, and must be treated
+ // as a normal return code from the LTSY
+ ret = ( (aResult == KErrGsmReleaseByUser) ? KErrNone : aResult );
+ }
+ }
+ else
+ {
+ //Dial hangup has succeeded, update core status -
+ //dial possible again
+ iCallCaps.iFlags |= RCall::KCapsDial;
+
+ if ( KErrGsmCallRejected != iLastExitCode )
+ {
+ iLastExitCode = KErrNone;
+ }
+
+ //Bring back also the connecting capability
+ iCallCaps.iFlags |= RCall::KCapsConnect;
+ //If client refuses to answer, remove the answering capability
+ iCallCaps.iFlags &= ~( RCall::KCapsAnswer );
+ }
+ ReqCompleted( reqHandle, ret );
+
+ //complete caps change notification
+ CompleteNotifyCapsChange();
+ CompleteNotifyMobileCallCapsChange( KErrNone );
+
+ //Change modem state to idle
+ RPhone::TStatus modemStatus;
+ modemStatus.iModemDetected = RPhone::EDetectedPresent;
+ modemStatus.iMode = RPhone::EModeIdle;
+ iMmPhone->CompleteNotifyModemDetected( modemStatus );
+ // Reset call extension attributes
+ iMmCallExtInterface->ResetInternalAttributes();
+ }
+ }
+ // Complete for DialCancel or AnswerIncomingCallCancel, success
+ else if ( KErrNone == aResult )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteHangUp - EMultimodeCallDial");
+ // Find out if this is cancelling of Dial
+ TTsyReqHandle cancelHandle =
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallDial );
+
+ if ( NULL == cancelHandle )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteHangUp - EMultimodeCallDialNoFdnCheck");
+ // Find out if this is cancelling of DialNoFdnCheck
+ cancelHandle = iTsyReqHandleStore->
+ ResetTsyReqHandle( EMultimodeCallDialNoFdnCheck );
+
+ if ( NULL == cancelHandle )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteHangUp - EMultimodeCallAnswer");
+ // Find out if this is cancelling of AnswerIncomingCall
+ cancelHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallAnswer );
+ }
+ }
+
+ if ( 0 < cancelHandle )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteHangUp with KErrCancel");
+
+ // Complete with error value KErrCancel
+ ReqCompleted( cancelHandle, KErrCancel );
+
+ // Cancel has succeeded, update core status -
+ // dial possible again
+ iCallCaps.iFlags |= RCall::KCapsDial;
+ // Bring back also the connecting capability
+ iCallCaps.iFlags |= RCall::KCapsConnect;
+ // If client refuses to answer, remove the answering capability
+ iCallCaps.iFlags &= ~( RCall::KCapsAnswer );
+ // Complete caps change notification
+ CompleteNotifyCapsChange();
+
+ // Change modem state to idle
+ RPhone::TStatus modemStatus;
+ modemStatus.iModemDetected = RPhone::EDetectedPresent;
+ modemStatus.iMode = RPhone::EModeIdle;
+ iMmPhone->CompleteNotifyModemDetected( modemStatus );
+ // Reset call extension attributes
+ iMmCallExtInterface->ResetInternalAttributes();
+ }
+ }
+ // Cancel failed and the request succeeded (connected)
+ else if ( RCall::EStatusConnected == iCallStatus )
+ {
+ // Find out if this is cancelling of Dial
+ TTsyReqHandle cancelHandle =
+ iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallDial );
+
+ if ( NULL == cancelHandle )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteHangUp - cancelling of EMultimodeCallDialNoFdnCheck");
+ // Find out if this is cancelling of DialNoFdnCheck
+ TTsyReqHandle cancelHandle =
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallDialNoFdnCheck );
+
+ if ( NULL == cancelHandle )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteHangUp - cancelling of AnswerIncomingCall");
+ // Find out if this is cancelling of AnswerIncomingCall
+ cancelHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallAnswer );
+ }
+ }
+
+
+ // Cancel to Dial or AnswerIncomingCall
+ if ( 0 < cancelHandle )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteHangUp - with KErrNone");
+ // Complete with success (KErrNone)
+ ReqCompleted( cancelHandle, KErrNone );
+
+ // Succeeded, update core status - hangup possible again
+ iCallCaps.iFlags |= RCall::KCapsHangUp;
+ // Complete caps change notification
+ CompleteNotifyCapsChange();
+ }
+ }
+
+ // Reset cancel flags
+ iDialCancelFlag = CMmCallTsy::EDialCancelNotCalled;
+ iAnswerCancelFlag = EFalse;
+ // reset the HangUp flag
+ iHangUpFlag = EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::GetOwnershipStatus
+// Get call ownership status.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::GetOwnershipStatus(
+ const TTsyReqHandle aTsyReqHandle,
+ RCall::TOwnershipStatus* aOwnershipStatus )
+ {
+ TCallOwnership ownerShip = CheckOwnership( aTsyReqHandle );
+
+ switch ( ownerShip )
+ {
+ case EOwnedUnowned:
+ *aOwnershipStatus = RCall::EOwnershipUnowned;
+ break;
+ case EOwnedTrue:
+ *aOwnershipStatus = RCall::EOwnershipOwnedByThisClient;
+ break;
+ case EOwnedFalse:
+ *aOwnershipStatus = RCall::EOwnershipOwnedByAnotherClient;
+ break;
+ case EOwnedPriorityClient:
+ if ( CCallBase::CheckPriorityClient( aTsyReqHandle ) )
+ {
+ *aOwnershipStatus = RCall::EOwnershipOwnedByThisClient;
+ }
+ else
+ {
+ *aOwnershipStatus = RCall::EOwnershipOwnedByAnotherClient;
+ }
+ break;
+ default:
+ //all possible values are switched, nothing to do here...
+ break;
+ }
+
+ ReqCompleted( aTsyReqHandle, KErrNone );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::TransferOwnership
+// Transfers the call ownership.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::TransferOwnership(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ // If call is not owned, complete with error
+ if ( CCallBase::EOwnedTrue != CheckOwnership( aTsyReqHandle ) )
+ {
+ ReqCompleted( aTsyReqHandle, KErrEtelNotCallOwner );
+ }
+ // If list is empty, complete with error
+ else if ( iList->iAcquireList.IsEmpty() )
+ {
+ ReqCompleted( aTsyReqHandle, KErrEtelNoClientInterestedInThisCall );
+ }
+ else
+ {
+ CAcquireEntry* entry = iList->iAcquireList.First();
+ if ( entry )
+ {
+ SetOwnership( entry->iTsyReqHandle );
+ ReqCompleted( entry->iTsyReqHandle, KErrNone );
+ iList->Remove( entry );
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ }
+ else
+ {
+ ReqCompleted( aTsyReqHandle, KErrGeneral );
+ }
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::AcquireOwnership
+// Acquire the call ownership.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::AcquireOwnership(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ TInt trapError;
+ // Check if the call is unowned?
+ if ( CheckOwnership( aTsyReqHandle ) == CCallBase::EOwnedUnowned )
+ {
+ // It is, return with error
+ ReqCompleted( aTsyReqHandle, KErrEtelCallNotActive );
+ }
+ else
+ {
+ CAcquireEntry* entry = NULL;
+ // Call is owned, add this req handle to acquire list
+// coverity [resource_leak]
+// TRAP macro releases memory while exception caught and trapError != KErrNone
+ TRAP( trapError, ( entry = CAcquireEntry::NewL( aTsyReqHandle ) ) );
+ if ( trapError != KErrNone )
+ {
+ //error handling. Object cannot be created.
+ ReqCompleted( aTsyReqHandle, trapError );
+ }
+ else if ( NULL != entry )
+ {
+ iList->iAcquireList.AddLast( *entry );
+ }
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::AcquireOwnershipCancel
+// Cancel the call ownership acquire.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::AcquireOwnershipCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ CAcquireEntry* entry = iList->FindByTsyReqHandle( aTsyReqHandle );
+ if ( NULL != entry )
+ {
+ iList->Remove( entry );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+ }
+ else
+ {
+ ReqCompleted( aTsyReqHandle, KErrNotFound );
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::RelinquishOwnership
+// Relinquish the call ownership.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::RelinquishOwnership()
+ {
+ if ( iList->iAcquireList.IsEmpty() )
+ {
+ SetUnowned();
+ if ( RCall::EStatusConnected != iCallStatus )
+ {
+ RelinquishOwnershipCompleted( KErrNone );
+ }
+ }
+ else
+ {
+ CAcquireEntry* entry = iList->iAcquireList.First();
+ if ( entry )
+ {
+ SetOwnership( entry->iTsyReqHandle );
+ ReqCompleted( entry->iTsyReqHandle, KErrNone );
+ iList->Remove( entry );
+ }
+ RelinquishOwnershipCompleted( KErrNone );
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::RegisterNotification
+// RegisterNotification is called when the server recognises that this
+// notification is being posted for the first time on this sub-session object.
+// It enables the TSY to "turn on" any regular notification messages that it
+// may receive from DOS. Currently does not really do anything but returns
+// KErrNone to ETel server in case of known notification request type.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::RegisterNotification(
+ const TInt aIpc )
+ {
+ TInt ret( KErrNone );
+
+ switch ( aIpc )
+ {
+ case EEtelCallNotifyHookChange:
+ case EEtelCallNotifyStatusChange:
+ case EEtelCallNotifyDurationChange:
+ case EEtelCallCapsChangeNotification:
+ case EMobileCallNotifyCallEvent:
+ case EMobileCallNotifyMobileCallStatusChange:
+ case EMobileCallNotifyRemotePartyInfoChange:
+ case EMobileCallNotifyPrivacyConfirmation:
+ case EMobileCallNotifyTrafficChannelConfirmation:
+ case EMobileCallNotifyHscsdInfoChange:
+ case EMobileCallNotifyMobileDataCallCapsChange:
+ case EMobileCallNotifyAlternatingCallSwitch:
+ case EMobileCallNotifyMobileCallCapsChange:
+ case EMobileCallNotifyVoiceFallback:
+ case EMobileCallNotifyUUSCapsChange:
+ ret = KErrNone;
+ break;
+ default:
+ // Unknown or invalid IPC
+ ret = KErrNotSupported;
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::DeregisterNotification
+// DeregisterNotification is called when the server recognises that this
+// notification will not be posted again because the last client to have a
+// handle on this sub-session object has just closed the handle. It enables
+// the TSY to "turn off" any regular notification messages that it may receive
+// from DOS. Currently does not really do anything but returns KErrNone to
+// ETel server in case of known notification request type.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::DeregisterNotification(
+ const TInt aIpc )
+ {
+ TInt ret ( KErrNone );
+
+ switch ( aIpc )
+ {
+ case EEtelCallNotifyHookChange:
+ case EEtelCallNotifyStatusChange:
+ case EEtelCallNotifyDurationChange:
+ case EEtelCallCapsChangeNotification:
+ case EMobileCallNotifyCallEvent:
+ case EMobileCallNotifyMobileCallStatusChange:
+ case EMobileCallNotifyRemotePartyInfoChange:
+ case EMobileCallNotifyPrivacyConfirmation:
+ case EMobileCallNotifyTrafficChannelConfirmation:
+ case EMobileCallNotifyHscsdInfoChange:
+ case EMobileCallNotifyMobileDataCallCapsChange:
+ case EMobileCallNotifyAlternatingCallSwitch:
+ case EMobileCallNotifyMobileCallCapsChange:
+ case EMobileCallNotifyVoiceFallback:
+ case EMobileCallNotifyUUSCapsChange:
+ ret = KErrNone;
+ break;
+ default:
+ // Unknown or invalid IPC
+ ret = KErrNotSupported;
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::ClearCallStatus
+// Clears internal call status.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::ClearCallStatus()
+ {
+ SetUnowned();
+ CMmCallTsy::ClearCallStatus();
+ }
+
+#ifdef REQHANDLE_TIMER
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::SetTypeOfResponse
+// Sets the type of response for a given Handle. Automatic mode includes an
+// automatic response in case of non response from the Domestic OS Layer in a
+// specified time.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::SetTypeOfResponse(
+ const TInt aReqHandleType,
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ //Sets the type of response for a given Handle. Automatic mode includes an
+ //automatic response in case of non response from the Licencee specific
+ //TSY in a specified time.
+ TInt timeOut( 0 );
+
+ //example switch
+ switch ( aReqHandleType )
+ {
+ case EMultimodeCallDial:
+ case EMultimodeCallDialNoFdnCheck:
+ timeOut = KMmCallDialTimeOut;
+ break;
+ case EMultimodeCallAnswer:
+ // If call mode is data and client is expecting call back from
+ // server, set timeout value to KMmCallAnswerCallBackTimeOut
+ if ( this == iMmPhone->WaitingCallForData() )
+ {
+ timeOut = KMmCallAnswerCallBackTimeOut;
+ }
+ else
+ {
+ timeOut = KMmCallAnswerTimeOut;
+ }
+ break;
+ case EMultimodeCallHangUp:
+ timeOut = KMmCallHangUpTimeOut;
+ break;
+ case EMultimodeCallTransfer:
+ timeOut = KMmCallTransferTimeOut;
+ break;
+ case EMultimodeCallSetDynamicHscsdParams:
+ timeOut = KMmCallSetDynamicHscsdParamsTimeOut;
+ break;
+ //Can't use timer:
+ // - all notifications
+ //case EMultimodeCallNotifyStatusChange:
+ //case EMultimodeCallNotifyDurationChange:
+ //case EMultimodeCallCapsChangeNotification:
+ //case EMultimodeCallNotifyMobileCallStatusChange:
+ //case EMultimodeCallNotifyCallEvent:
+ //case EMultimodeCallNotifyRemotePartyInfoChange:
+ //case EMultimodeCallNotifyMobileCallCapsChange:
+ //case EMultimodeCallNotifyDataCallCapsChange:
+ //case EMultimodeCallNotifyHscsdInfoChange:
+ //case EMultimodeCallNotifyPrivacyConfirmation:
+
+ case EMultimodeMobileCallHold:
+ case EMultimodeMobileCallResume:
+ case EMultimodeMobileCallSwap:
+ case EMultimodeMobileCallDeflectCall:
+ case EMultimodeMobileCallDialEmergencyCall:
+ case EMultimodeCallGoOneToOne:
+ default:
+ //does not use timer
+ iTsyReqHandleStore->SetTsyReqHandle(
+ aReqHandleType,
+ aTsyReqHandle );
+ break;
+ }
+
+ if ( timeOut > 0 )
+ {
+ //the timeout parameter is given in seconds.
+ iTsyReqHandleStore->SetTsyReqHandle(
+ aReqHandleType, aTsyReqHandle, timeOut );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::Complete
+// Completes the request due timer expiration.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::Complete(
+ TInt aReqHandleType,
+ TInt aError )
+ {
+ //All possible TSY req handle types are listed in the
+ //switch case below.
+ switch( aReqHandleType )
+ {
+ //cases handled with automatic completion
+ case EMultimodeCallSetDynamicHscsdParams:
+ CompleteSetDynamicHscsdParams( aError );
+ break;
+
+ //Can't use timer:
+ // - all notifications
+ //case EMultimodeCallNotifyStatusChange:
+ //case EMultimodeCallNotifyDurationChange:
+ //case EMultimodeCallCapsChangeNotification:
+ //case EMultimodeCallNotifyMobileCallStatusChange:
+ //case EMultimodeCallNotifyCallEvent:
+ //case EMultimodeCallNotifyRemotePartyInfoChange:
+ //case EMultimodeCallNotifyMobileCallCapsChange:
+ //case EMultimodeCallNotifyDataCallCapsChange:
+ //case EMultimodeCallNotifyHscsdInfoChange:
+ //case EMultimodeCallNotifyPrivacyConfirmation:
+
+ case EMultimodeCallDial:
+ case EMultimodeCallDialNoFdnCheck:
+ case EMultimodeCallAnswer:
+ case EMultimodeCallHangUp:
+ case EMultimodeMobileCallHold:
+ case EMultimodeMobileCallResume:
+ case EMultimodeMobileCallSwap:
+ case EMultimodeMobileCallDeflectCall:
+ case EMultimodeMobileCallDialEmergencyCall:
+ case EMultimodeCallTransfer:
+ case EMultimodeCallGoOneToOne:
+ default:
+ CMmCallTsy::Complete( aReqHandleType, aError );
+ break;
+ }
+ }
+#endif
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CallComingForWaitingCall
+// Starts to answer an incoming call.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CallComingForWaitingCall()
+ {
+ //Incoming call detected, which is directed to this call object
+ //which should be waiting for incoming call
+ TFLOGSTRING("TSY: CMmDataCallTsy::CallComingForWaitingCall");
+
+ TInt ret( KErrNone );
+
+ TFLOGSTRING("TSY: CMmDataCallTsy::AnswerIncomingCall - Data call");
+ //Answer incoming call
+ TRAPD( trapError,
+ ret = iMmCallExtInterface->AnswerIncomingDataCallL( iCallId );
+ );
+
+ if ( KErrNone != trapError )
+ {
+ //error handling. Object cannot be created.
+ ret = trapError;
+ }
+
+ if ( KErrNone == ret )
+ {
+ // SOS architechture Call Back functionality tries to answer
+ // incoming call even before the current MO call is fully
+ // released. This is done by dialup agent (CsdAgx/CsdAgt),
+ // which does not wait for the previous call to get
+ // disconnected. As the call is now answered, NULL the pointer
+ // to this CMmDataCallTsy object from CMmPhoneTsy.
+ iMmPhone->SetWaitingCallForData( NULL );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::IsFinishedData
+// Returns boolean that indicates if call object is already been used in
+// data calls. This means that call has been already released or disconnected.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TBool CMmDataCallTsy::IsFinishedData() const
+ {
+ return iIsFinishedDataCall;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::LoanDataPort
+// This CORE API method loans dataport to client.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::LoanDataPort(
+ const TTsyReqHandle aTsyReqHandle,
+ RCall::TCommPort* aCommPort )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::LoanDataPort - Client taking control: %S",
+ &iCallName );
+
+ TInt ret( KErrNone );
+
+ // Check if the port is loaned!
+ if ( iLoanedCommPort.iPort.Compare( KNullDesC) == 0 )
+ {
+ // Check ownership
+ TCallOwnership ownerShip = CheckOwnership( aTsyReqHandle );
+ // If not yet owned, take ownership.
+ if ( EOwnedUnowned == ownerShip || EOwnedPriorityClient == ownerShip )
+ {
+ SetOwnership( aTsyReqHandle );
+ }
+ // Else check if this req handle already owns the call.
+ else if ( CCallBase::EOwnedTrue != ownerShip )
+ {
+ ret = KErrEtelNotCallOwner;
+ }
+
+ // If port can be loaned, request access to dataport
+ if ( ret == KErrNone )
+ {
+ //Create package
+ CCallDataPackage package;
+ //Set call id and call mode
+ package.SetCallIdAndMode( iCallId, iCallMode );
+ //Pack commport
+ package.PackData( aCommPort );
+
+ //Send request to the Domestic OS layer.
+ TRAPD( trapError,
+ ret = iMessageManager->HandleRequestL(
+ EEtelCallLoanDataPort, &package );
+ );
+
+ if ( KErrNone != trapError )
+ {
+ //error handling, leaved.
+ ret = trapError;
+ }
+
+ if ( KErrNone == ret )
+ {
+ iLoanedCommPort.iCsy.Copy( aCommPort->iCsy );
+ iLoanedCommPort.iPort.Copy( aCommPort->iPort );
+
+ // If dataport was available, changed new call caps and
+ // complete notification!
+ iCallCaps.iFlags |=
+ RCall::KCapsData |
+ RCall::KCapsHangUp |
+ RCall::KCapsRecoverDataPort;
+ iCallCaps.iFlags &= ~( RCall::KCapsLoanDataPort );
+
+ iMmCallExtInterface->AddGSMCallCaps(
+ RCall::KCapsRecoverDataPort );
+ iMmCallExtInterface->RemoveGSMCallCaps(
+ RCall::KCapsLoanDataPort );
+
+ CompleteNotifyCapsChange();
+ CompleteNotifyMobileCallCapsChange( KErrNone );
+ }
+ else
+ {
+ SetUnowned();
+ }
+ }
+ }
+ else
+ {
+ ret = KErrEtelPortAlreadyLoaned;
+ }
+
+ // Complete request if result is KErrNone.
+ // Return possible error to CCallBase base class because it sets
+ // iLoanDataport to TRUE if KErrNone is returned. This may cause
+ // serious problems when the data call object is closed and data port
+ // is not really loaned. ETel completes request in case where error is
+ // returned.
+ if ( KErrNone == ret )
+ {
+ ReqCompleted( aTsyReqHandle, KErrNone );
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::LoanDataPortCancel
+// Cancels dataport loaning to client. LoanDataPort always
+// completes immediately, this is never used.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::LoanDataPortCancel(
+ const TTsyReqHandle )
+ {
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::RecoverDataPort
+// This CORE API method recovers dataport from client.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::RecoverDataPort(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::RecoverDataPort - Client returning control: %S",
+ &iCallName );
+
+ TInt ret( KErrNone );
+
+ // Check if the port is loaned!
+ if ( iLoanedCommPort.iPort.Compare( KNullDesC) != 0 )
+ {
+ //Create package
+ CCallDataPackage package;
+ //Set call id and call mode
+ package.SetCallIdAndMode( iCallId, iCallMode );
+ //Pack commport
+ package.PackData( &iLoanedCommPort );
+
+ //Send request to the Domestic OS layer.
+ TRAPD( trapError,
+ ret = iMessageManager->HandleRequestL(
+ EEtelCallRecoverDataPort, &package );
+ );
+
+ if ( KErrNone != trapError )
+ {
+ //error handling, leaved.
+ ret = trapError;
+ }
+
+ iLoanedCommPort.iCsy.Zero();
+ iLoanedCommPort.iPort.Zero();
+
+ // Set new call caps!
+ iCallCaps.iFlags |= RCall::KCapsLoanDataPort;
+ iCallCaps.iFlags &= ~( RCall::KCapsRecoverDataPort );
+
+ iMmCallExtInterface->AddGSMCallCaps(
+ RCall::KCapsLoanDataPort );
+ iMmCallExtInterface->RemoveGSMCallCaps(
+ RCall::KCapsRecoverDataPort );
+ }
+ else
+ {
+ ret = KErrEtelPortNotLoanedToClient;
+ }
+
+ ReqCompleted( aTsyReqHandle, ret );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::RecoverDataPortAndRelinquishOwnership
+// Recovers dataport from client and relinquishes ownership.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::RecoverDataPortAndRelinquishOwnership()
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::RecoverDataPortAndRelinquishOwnership - \
+ Client returning control: %S", &iCallName );
+
+ TInt ret( KErrNone );
+
+ // Check if the port is loaned!
+ if ( iLoanedCommPort.iPort.Compare( KNullDesC) != 0 )
+ {
+ //Create package
+ CCallDataPackage package;
+ //Set call id and call mode
+ package.SetCallIdAndMode( iCallId, iCallMode );
+ //Pack commport
+ package.PackData( &iLoanedCommPort );
+
+ //Send request to the Domestic OS layer.
+ TRAPD( trapError,
+ ret = iMessageManager->HandleRequestL(
+ EEtelCallRecoverDataPort, &package );
+ );
+
+ if ( KErrNone != trapError )
+ {
+ //error handling, leaved.
+ ret = trapError;
+ }
+
+ iLoanedCommPort.iCsy.Zero();
+ iLoanedCommPort.iPort.Zero();
+
+ if ( iList->iAcquireList.IsEmpty() )
+ {
+ SetUnowned();
+
+ if ( KErrNone == ret )
+ {
+ // Call owner is closing data call handle. Call
+ // RecoverDataPortAndRelinquishOwnershipCompleted method.
+ RecoverDataPortAndRelinquishOwnershipCompleted( KErrNone );
+ }
+ }
+ else
+ {
+ CAcquireEntry* entry = iList->iAcquireList.First();
+ if ( entry )
+ {
+ SetOwnership( entry->iTsyReqHandle );
+ ReqCompleted( entry->iTsyReqHandle, KErrNone );
+ iList->Remove( entry );
+ }
+ // Set new call caps!
+ iCallCaps.iFlags |= RCall::KCapsLoanDataPort;
+ iCallCaps.iFlags &= ~( RCall::KCapsRecoverDataPort );
+
+ iMmCallExtInterface->AddGSMCallCaps(
+ RCall::KCapsLoanDataPort );
+ iMmCallExtInterface->RemoveGSMCallCaps(
+ RCall::KCapsRecoverDataPort );
+ }
+ }
+ else
+ {
+ ret = KErrEtelPortNotLoanedToClient;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::Connect
+// Set correct data call attributes, depending on parameter extension.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::Connect(
+ const TTsyReqHandle aTsyReqHandle,
+ const TDesC8* aCallParams )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::Connect");
+ if ( CheckOwnership( aTsyReqHandle ) == CCallBase::EOwnedUnowned )
+ {
+ SetOwnership( aTsyReqHandle );
+ }
+ TDes8* callParams = reinterpret_cast<TDes8*>(const_cast<TDesC8*> (aCallParams));
+ if(callParams->MaxLength() == 0)
+ {
+ // default parameters...
+ iCallParams.iSpeakerControl = RCall::EMonitorSpeakerControlAlwaysOff;
+ iCallParams.iSpeakerVolume = RCall::EMonitorSpeakerVolumeOff;
+ iCallParams.iInterval = 0;
+ iCallParams.iWaitForDialTone = RCall::EDialToneWait;
+ ReqCompleted( aTsyReqHandle, KErrNone );
+
+ return KErrNone;
+ }
+ if(callParams->MaxLength() == sizeof(RCall::TCallParams))
+ {
+ // only RCall parameters
+ RCall::TCallParamsPckg* paramsPckg =
+ reinterpret_cast<RCall::TCallParamsPckg*>(callParams);
+ RCall::TCallParams& params = ( *paramsPckg )();
+
+ iCallParams.iSpeakerControl = params.iSpeakerControl;
+ iCallParams.iSpeakerVolume = params.iSpeakerVolume;
+ iCallParams.iInterval = params.iInterval;
+ iCallParams.iWaitForDialTone = params.iWaitForDialTone;
+ ReqCompleted( aTsyReqHandle, KErrNone );
+
+ return KErrNone;
+ }
+ if(sizeof(RMobileCall::TMobileCallParamsV1) > aCallParams->Length())
+ {
+ TFLOGSTRING ("TSY: CMmDataCallTsy::Connect bad size argument");
+ // Complete the request with appropiate error
+ return KErrArgument;
+ }
+ RMobileCall::TMobileCallParamsV1Pckg* paramsPckgV1 =
+ reinterpret_cast<RMobileCall::TMobileCallParamsV1Pckg*> ( callParams );
+ RMobileCall::TMobileCallParamsV1& paramsV1 = ( *paramsPckgV1 )();
+
+ if ( CheckOwnership( aTsyReqHandle ) == CCallBase::EOwnedUnowned )
+ {
+ SetOwnership( aTsyReqHandle );
+ }
+
+
+ iCallParams.iSpeakerControl = paramsV1.iSpeakerControl;
+ iCallParams.iSpeakerVolume = paramsV1.iSpeakerVolume;
+ iCallParams.iInterval = paramsV1.iInterval;
+ iCallParams.iWaitForDialTone = paramsV1.iWaitForDialTone;
+
+ if ( ( paramsV1.ExtensionId() == KETelExtMultimodeV1 ) ||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileDataCallParamsV1 ) ||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileDataCallParamsV2 ) ||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileDataCallParamsV8 ) ||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileHscsdCallParamsV1 )||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileHscsdCallParamsV2 )||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileHscsdCallParamsV7 )||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileHscsdCallParamsV8 ))
+ {
+ iCallParams.iIdRestrict = paramsV1.iIdRestrict;
+ iCallParams.iCug = paramsV1.iCug;
+ iCallParams.iAutoRedial = paramsV1.iAutoRedial;
+ }
+
+ if ( ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileDataCallParamsV1 ) ||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileDataCallParamsV2 ) ||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileDataCallParamsV8 ) ||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileHscsdCallParamsV1 )||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileHscsdCallParamsV2 )||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileHscsdCallParamsV7 )||
+ ( paramsV1.ExtensionId() ==
+ RMobileCall::KETelMobileHscsdCallParamsV8 ))
+ {
+ iMmCallExtInterface->Connect( aCallParams );
+ }
+
+ ReqCompleted( aTsyReqHandle, KErrNone );
+
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::ConnectChancel
+// Cancels connecting of a (data) call (Not Supported).
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::ConnectCancel(
+ const TTsyReqHandle )
+ {
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::GetMobileDataCallCaps
+// Get data call caps.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::GetMobileDataCallCaps(
+ const TTsyReqHandle aTsyReqHandle,
+ TDes8* aCaps )
+ {
+ TInt ret( KErrArgument );
+
+ if ( sizeof ( RMobileCall::TMobileCallDataCapsV1 ) <= aCaps->MaxLength() )
+ {
+ RMobileCall::TMobileCallDataCapsV1Pckg* callDataCapsV1Pckg =
+ reinterpret_cast<RMobileCall::TMobileCallDataCapsV1Pckg*>( aCaps );
+ RMobileCall::TMobileCallDataCapsV1& callDataCapsV1 =
+ ( *callDataCapsV1Pckg )();
+
+ if ( KETelExtMultimodeV1 == callDataCapsV1.ExtensionId() )
+ {
+ // The call will only have data capabilities if this call has been
+ // opened from the phone's data line.
+ ret = KErrNone;
+ iMmCallExtInterface->GetMobileDataCallCapsV1( callDataCapsV1 );
+ }
+ }
+
+ ReqCompleted( aTsyReqHandle, ret );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::NotifyMobileDataCallCapsChange
+// Notifies change of the data call capabilities.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::NotifyMobileDataCallCapsChange(
+ const TTsyReqHandle,
+ TDes8* aCaps )
+ {
+ TInt ret( KErrArgument );
+
+ if ( sizeof ( RMobileCall::TMobileCallDataCapsV1 ) <= aCaps->MaxLength() )
+ {
+ RMobileCall::TMobileCallDataCapsV1Pckg* callDataCapsV1Pckg =
+ reinterpret_cast<RMobileCall::TMobileCallDataCapsV1Pckg*>( aCaps );
+ RMobileCall::TMobileCallDataCapsV1& callDataCapsV1 =
+ ( *callDataCapsV1Pckg )();
+
+ if ( KETelExtMultimodeV1 == callDataCapsV1.ExtensionId() )
+ {
+ ret = KErrNone;
+ iRetDataCallCaps = aCaps;
+ iReqHandleType = EMultimodeCallNotifyDataCallCapsChange;
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::NotifyMobileDataCallCapsChangeCancel
+// Cancels MobileDataCallCaps change notifications.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::NotifyMobileDataCallCapsChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ iRetDataCallCaps = NULL;
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallNotifyDataCallCapsChange );
+ ReqCompleted( aTsyReqHandle, KErrCancel );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CompleteNotifyMobileDataCallCapsChange
+// Complete a NotifyMobileDataCallCapsChange request.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CompleteNotifyMobileDataCallCapsChange()
+ {
+ //reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallNotifyDataCallCapsChange );
+
+ if ( EMultimodeCallReqHandleUnknown != reqHandle )
+ {
+ RMobileCall::TMobileCallDataCapsV1Pckg* callDataCapsV1Pckg =
+ reinterpret_cast<RMobileCall::TMobileCallDataCapsV1Pckg*>(
+ iRetDataCallCaps );
+ RMobileCall::TMobileCallDataCapsV1& callDataCapsV1 =
+ ( *callDataCapsV1Pckg )();
+
+ iMmCallExtInterface->GetMobileDataCallCapsV1( callDataCapsV1 );
+
+ iRetDataCallCaps = NULL;
+
+ ReqCompleted( reqHandle, KErrNone );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::GetBearerServiceInfo
+// Get bearer service info.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::GetBearerServiceInfo(
+ const TTsyReqHandle aTsyReqHandle,
+ RCall::TBearerService* aBearerService )
+ {
+ // If the call is not connected, the request will return KErrNotFound.
+ TInt ret( KErrNotFound );
+ // Reset info variables. Info is also unknown for voice call.
+ aBearerService->iBearerCaps =
+ RCall::KBearerCapsCompressionNone | RCall::KBearerCapsProtocolUnknown;
+ aBearerService->iBearerSpeed = RCall::EBearerDataUnknown;
+
+ if ( RCall::EStatusConnected == iCallStatus )
+ {
+ ret = iMmCallExtInterface->GetBearerServiceInfo( aBearerService );
+ }
+
+ ReqCompleted( aTsyReqHandle, ret );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::SetDynamicHscsdParams
+// Set HSCSD dynamic data parameters.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::SetDynamicHscsdParams(
+ const TTsyReqHandle aTsyReqHandle,
+ RMobileCall::TMobileCallAiur* aAiur,
+ TInt* aRxTimeslots )
+ {
+ TInt ret( KErrNone );
+ // HSCSD parameters can be set only if this call has been opened
+ // from the phone's data line.
+TFLOGSTRING3("TSY: CMmDataCallTsy::SetDynamicHscsdParams.\n \t\t\t Air Intrf: %d\n \t\t\t RX slots: %d",
+ *aAiur, *aRxTimeslots);
+
+ iReqHandleType = EMultimodeCallSetDynamicHscsdParams;
+
+ TRAP_IGNORE(
+ ret = iMmCallExtInterface->SetDynamicHscsdParamsL(
+ aAiur, aRxTimeslots );
+ );
+
+ // If not a data call or extension returned error.
+ if ( KErrNone != ret )
+ {
+ ReqCompleted( aTsyReqHandle, KErrNotFound );
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::SetDynamicHscsdParamsCancel
+// Cancel SetDynamicHscsdParams request.
+// Not possible, as SetDynamicHscsdParams request is completed immediately.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::SetDynamicHscsdParamsCancel(
+ const TTsyReqHandle ) const
+ {
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CompleteSetDynamicHscsdParams
+// Complete a SetDynamicHscsdParams request.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CompleteSetDynamicHscsdParams(
+ TInt aErrorCode )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteSetDynamicHscsdParams");
+ //reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallSetDynamicHscsdParams );
+
+ if ( EMultimodeCallReqHandleUnknown != reqHandle )
+ {
+ ReqCompleted( reqHandle, aErrorCode );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::GetCurrentHscsdInfo
+// Get current HSCSD info.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::GetCurrentHscsdInfo(
+ const TTsyReqHandle aTsyReqHandle,
+ TDes8* aHSCSDInfo )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::GetCurrentHscsdInfo");
+ TInt ret( KErrNone );
+ // HSCSD info can be read only if this call has been opened from the
+ // phone's data line and call is connected.
+ // Connected here means that TSY gas has received CONNECT: XXXX from modem
+ // When CONNECT: XXXX has been received, TSY has completed clients request
+ // which can be dial or answer.
+ // Thus those req handles should be unknown, otherwise the call is not yet
+ // connected.
+ if ( ( EMultimodeCallReqHandleUnknown ==
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallDial ) ) &&
+ ( EMultimodeCallReqHandleUnknown ==
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallAnswer ) ) &&
+ ( EMultimodeCallReqHandleUnknown ==
+ iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallDialNoFdnCheck ) ) )
+ {
+ ret = iMmCallExtInterface->GetCurrentHscsdInfo( aHSCSDInfo );
+ }
+ else
+ {
+ RMobileCall::TMobileCallHscsdInfoV1Pckg* hscsdInfoPckg =
+ reinterpret_cast<RMobileCall::TMobileCallHscsdInfoV1Pckg*>(
+ aHSCSDInfo );
+ RMobileCall::TMobileCallHscsdInfoV1& hscsdInfo = (*hscsdInfoPckg)();
+
+ hscsdInfo.iAiur = RMobileCall::EAiurBpsUnspecified;
+ hscsdInfo.iRxTimeSlots = 0;
+ hscsdInfo.iTxTimeSlots = 0;
+ hscsdInfo.iCodings = RMobileCall::ETchCodingUnspecified;
+
+ ret = KErrEtelCallNotActive;
+ }
+
+ ReqCompleted( aTsyReqHandle, ret );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::NotifyHscsdInfoChange
+// Notifies change of the HSCSD info.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::NotifyHscsdInfoChange(
+ const TTsyReqHandle,
+ TDes8* aHSCSDInfo )
+ {
+ // HSCSD info can be read only if this call has been opened
+ // from the phone's data line.
+ // Save request handle and ptr to aHSCSDInfo.
+ iRetHscsdInfo = aHSCSDInfo;
+ iReqHandleType = EMultimodeCallNotifyHscsdInfoChange;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::NotifyHscsdInfoChangeCancel
+// Cancels HSCSD info change notifications.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::NotifyHscsdInfoChangeCancel(
+ const TTsyReqHandle aTsyReqHandle )
+ {
+ TInt ret( KErrNone );
+
+ iRetHscsdInfo = NULL;
+ iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallNotifyHscsdInfoChange );
+ ret = KErrCancel;
+
+ ReqCompleted( aTsyReqHandle, ret );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CompleteNotifyHscsdInfoChange
+// Complete a NotifyHscsdInfoChange request.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CompleteNotifyHscsdInfoChange()
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteNotifyHscsdInfoChange");
+ //reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallNotifyHscsdInfoChange );
+
+ if ( EMultimodeCallReqHandleUnknown != reqHandle )
+ {
+ TInt ret = iMmCallExtInterface->GetCurrentHscsdInfo( iRetHscsdInfo );
+ iRetHscsdInfo = NULL;
+ ReqCompleted( reqHandle, ret );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::GetMobileDataCallRLPRange
+// Get Data Call RLP Range.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::GetMobileDataCallRLPRange(
+ const TTsyReqHandle aTsyReqHandle,
+ TInt*,
+ TDes8* )
+ {
+ ReqCompleted( aTsyReqHandle, KErrNotSupported );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::DialNoFdnCheck
+// This CORE API method dials to the given number.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+TInt CMmDataCallTsy::DialNoFdnCheck(
+ const TTsyReqHandle aTsyReqHandle,
+ const TDesC8* aCallParams,
+ TDesC* aTelNumber )
+ {
+TFLOGSTRING3("TSY: CMmDataCallTsy::DialNoFdnCheck - Req handle: %d, Call name: %S",
+ aTsyReqHandle, &iCallName);
+
+ CMmCallList* callList = iMmPhone->CallList();
+ TBool dialFlag( EFalse );
+
+ for(TInt i=0; i< callList->GetNumberOfObjects();i++)
+ {
+ CMmCallTsy* call = callList->GetMmCallByIndex( i );
+ if( call->GetDialFlag() )
+ {
+ dialFlag = ETrue;
+ i= callList->GetNumberOfObjects();
+ }
+ }
+
+ if( !dialFlag )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy::DialNoFdnCheck ONGOING" );
+
+ SetDialFlag( ETrue );
+
+ TTsyReqHandle dialHandle = iTsyReqHandleStore->GetTsyReqHandle(
+ EMultimodeCallDialNoFdnCheck );
+
+ // reset exit code
+ iLastExitCode = KErrNone;
+
+ // reset finished data call flag
+ iIsFinishedDataCall = EFalse;
+
+ if ( ERfsStateInfoInactive == iMmPhone->GetRfStateInfo() )
+ {
+TFLOGSTRING("TSY: CMmDataCallTsy - DialNoFdnCheck - Offline mode ON, Dial request is not allowed" );
+ TInt ret = CMmCommonStaticUtility::EpocErrorCode(
+ KErrGeneral, KErrGsmOfflineOpNotAllowed );
+ SetDialFlag( EFalse );
+TFLOGSTRING("TSY: CMmDataCallTsy::DialNoFdnCheck - RF inactive -> dial-flag false" );
+ // Complete the request with appropiate error
+ ReqCompleted ( aTsyReqHandle, ret );
+ }
+
+ // check that status is Idle
+ else if ( RMobileCall::EStatusIdle != iMobileCallStatus )
+ {
+ // Request cannot be forwarded since this call object
+ // is still in use.
+ // Complete request with status value informing the client
+ // about the situation.
+TFLOGSTRING("TSY: CMmDataCallTsy::DialNoFdnCheck - KErrNotReady");
+ ReqCompleted( aTsyReqHandle, KErrNotReady );
+ }
+ else if ( 0 < dialHandle )
+ {
+ // Request is already in processing because of previous request
+ // Complete request with status value informing the client about
+ // the situation.
+TFLOGSTRING("TSY: CMmDataCallTsy::DialNoFdnCheck - KErrServerBusy");
+ ReqCompleted( aTsyReqHandle, KErrServerBusy );
+ }
+ else
+ {
+ TInt ret( KErrNone );
+ TInt trapError( KErrNone );
+ TCallOwnership ownerShip = EOwnedFalse;
+
+ RMobileCall::TMobileCallParamsV1Pckg* paramsPckgV1 =
+ reinterpret_cast<RMobileCall::TMobileCallParamsV1Pckg*>(
+ const_cast<TDesC8*>( aCallParams ) );
+ RMobileCall::TMobileCallParamsV1& paramsV1 = ( *paramsPckgV1 )();
+
+ // save call params
+ iCallParams.iSpeakerControl = paramsV1.iSpeakerControl;
+ iCallParams.iSpeakerVolume = paramsV1.iSpeakerVolume;
+ iCallParams.iInterval = paramsV1.iInterval;
+ iCallParams.iWaitForDialTone = paramsV1.iWaitForDialTone;
+
+ // set call direction
+ iCallDirection = RMobileCall::EMobileOriginated;
+
+ // Check if there already is an active or connecting call
+ TInt numberOfObjects = iMmPhone->CallList()->
+ GetNumberOfObjects();
+ for ( TInt i = 0; i < numberOfObjects; i++ )
+ {
+ CMmDataCallTsy* mmCall = reinterpret_cast<CMmDataCallTsy*>(
+ iMmPhone->CallList()->GetMmCallByIndex( i ) );
+ if ( !( RMobileCall::EStatusUnknown ==
+ mmCall->MobileCallStatus() ||
+ RMobileCall::EStatusIdle ==
+ mmCall->MobileCallStatus() ||
+ RMobileCall::EStatusDisconnecting ==
+ mmCall->MobileCallStatus() ||
+ RMobileCall::EStatusDisconnectingWithInband ==
+ mmCall->MobileCallStatus() ) )
+ {
+ ret = KErrEtelCallAlreadyActive;
+ break;
+ }
+ }
+
+ // Return value can also be priorityclient!
+ ownerShip = CheckOwnership( aTsyReqHandle );
+
+ if ( KErrNone == ret && ( EOwnedUnowned == ownerShip ||
+ EOwnedPriorityClient == ownerShip ) )
+ {
+ SetOwnership( aTsyReqHandle );
+
+ if ( KErrNone == ret )
+ {
+ SetDialTypeId( KMultimodeCallTypeIDNoFdnCheck );
+
+TFLOGSTRING("TSY: CMmDataCallTsy::DialNoFdnCheck - DialDataCall");
+ TRAP( trapError,
+ ret = iMmCallExtInterface->DialDataCallL(
+ iCallMode, aCallParams, aTelNumber );
+ );
+ if ( KErrNone != trapError )
+ {
+ //error handling. DialDataCall() leaved.
+ ret = trapError;
+ }
+ // If dial succeeded, continue
+ if ( KErrNone == ret )
+ {
+ RPhone::TStatus modemStatus;
+ modemStatus.iModemDetected = RPhone::EDetectedPresent;
+ modemStatus.iMode = RPhone::EModeEstablishingLink;
+ iMmPhone->CompleteNotifyModemDetected( modemStatus );
+
+ //update core status
+ iCallCaps.iFlags &= ~(
+ RCall::KCapsDial | RCall::KCapsConnect );
+ iCallCaps.iFlags |= RCall::KCapsHangUp;
+ //complete core caps change
+ CompleteNotifyCapsChange();
+ }
+ }
+ }
+
+ if ( KErrNone != ret )
+ {
+ ReqCompleted( aTsyReqHandle, ret );
+ ClearCallStatus();
+ }
+ else
+ {
+#ifdef REQHANDLE_TIMER
+ // set timer for the request
+ SetTypeOfResponse( EMultimodeCallDialNoFdnCheck,
+ aTsyReqHandle );
+#else
+ // set timer
+ iTsyReqHandleStore->SetTsyReqHandle(
+ EMultimodeCallDialNoFdnCheck, aTsyReqHandle );
+#endif
+ }
+ }
+
+ return KErrNone;
+ }
+ else
+ {
+ return KErrServerBusy;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMmDataCallTsy::CompleteDialNoFdn
+// Completes a Dial request.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::CompleteDialNoFdn(
+ TInt aResult )
+ {
+TFLOGSTRING2("TSY: CMmDataCallTsy::CompleteDialNoFdn - Result: %d", aResult );
+TFLOGSTRING3("TSY: CMmDataCallTsy::CompleteDialNoFdn - Call Id: %d, Call name: %S",
+ iCallId, &iCallName);
+
+ // Set dial flag to false
+ SetDialFlag( EFalse );
+
+ // reset req handle. Returns the deleted req handle
+ TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
+ EMultimodeCallDialNoFdnCheck );
+
+ if ( EMultimodeCallReqHandleUnknown != reqHandle )
+ {
+ if ( aResult != KErrNone )
+ {
+ // The creation has failed.
+ iLastExitCode = aResult;
+ ClearCallStatus();
+
+ //Dial has failed, update core status - dial possible again
+ iCallCaps.iFlags |= RCall::KCapsDial;
+ iCallCaps.iFlags &= ~( RCall::KCapsHangUp );
+
+ //complete caps change notification
+ CompleteNotifyCapsChange();
+ }
+TFLOGSTRING2("TSY: CMmDataCallTsy::CompleteDialNoFdn before ReqComplete %d", aResult );
+ ReqCompleted( reqHandle, aResult );
+
+TFLOGSTRING("TSY: CMmDataCallTsy::CompleteDialNoFdn - set dialtype to none ");
+ //Set dial type to none
+ SetDialTypeId( KMultimodeCallTypeDialNone );
+ }
+
+ // Set also new call caps to enable dataport loaning!
+ if ( RCall::EStatusConnected == iCallStatus &&
+ KErrNone == aResult )
+ {
+ iCallCaps.iFlags |= RCall::KCapsLoanDataPort;
+ iMmCallExtInterface->AddGSMCallCaps(
+ RCall::KCapsLoanDataPort );
+
+ //complete caps change notification
+ CompleteNotifyCapsChange();
+ CompleteNotifyMobileCallCapsChange( KErrNone );
+ }
+ }
+
+#ifdef TF_LOGGING_ENABLED
+// ---------------------------------------------------------------------------
+// CMmCallTsy::ReqCompleted
+// Overloads CTelObject::ReqCompleted for logging purposes. It prints the
+// aTsyReqHandle and aError variable in the log file and then calls
+// CTelObject::ReqCompleted.
+// (other items were commented in a header).
+// ---------------------------------------------------------------------------
+//
+void CMmDataCallTsy::ReqCompleted(
+ const TTsyReqHandle aTsyReqHandle,
+ const TInt aError )
+ {
+ //Overloads CTelObject::ReqCompleted for logging purposes. It
+ //prints the aTsyReqHandle and aError variable in the log file and then
+ //calls CTelObject::ReqCompleted.
+TFLOGSTRING3("TSY: CMmDataCallTsy::Request Completed. Handle:%d Error:%d", aTsyReqHandle, aError);
+
+ CTelObject::ReqCompleted(aTsyReqHandle,aError);
+ }
+#endif
+
+// End of File