// 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 "cmmcalltsy.h"
#include <featmgr/featurecontrol.h>
#include <featureuids.h>
#include "cmmphonetsy.h"
#include "cmmlinetsy.h"
#include "cmmtsyreqhandlestore.h"
#include "cmmcalllist.h"
#include "CMmCommonStaticUtility.h"
#include "cmmlinelist.h"
#include "cmmmessagemanagerbase.h"
#include <ctsy/pluginapi/cmmdatapackage.h>
#include <ctsy/serviceapi/gsmerror.h>
#include "cmmcallgsmwcdmaext.h"
#include <ctsy/pluginapi/mtelephonyaudiocontrol.h>
// ======== MEMBER FUNCTIONS ========
CMmCallTsy::CMmCallTsy() :
iCallParamsPckg(iCallParams),
iReqHandleType(EMultimodeCallReqHandleUnknown)
{
}
void CMmCallTsy::ConstructL(
RMobilePhone::TMobileService aMode )
{
#ifdef REQHANDLE_TIMER
//Create req handle store
iTsyReqHandleStore = CMmTsyReqHandleStore::NewL( this, iMmPhone,
EMultimodeCallMaxNumOfRequests, iCallReqHandles);
#else
//Create req handle store
iTsyReqHandleStore = CMmTsyReqHandleStore::NewL(
EMultimodeCallMaxNumOfRequests, iCallReqHandles);
#endif
iCallMode = aMode;
//Call ownership change request list
iList = CAcquireOwnerList::NewL();
//initialise call duration notifier
iCallTimer = CHeartbeatRunner::NewL( this );
//Initialise extension modules
InitExtensionModulesL( aMode );
//Initialise miscellaneous internal attributes
InitInternalAttributes();
}
CMmCallTsy::~CMmCallTsy()
{
TFLOGSTRING3("TSY: CMmCallTsy::~CMmCallTsy. Call deleted iCallId:%d iCallName:%S",iCallId, &iCallName);
TInt trapError( KErrNone );
//Hang up call if call is still connecting or active and hang up is not
//called
if( iTsyReqHandleStore )
{
if ( !( RMobileCall::EStatusIdle == iMobileCallStatus ||
RMobileCall::EStatusDisconnecting == iMobileCallStatus ||
RMobileCall::EStatusDisconnectingWithInband == iMobileCallStatus )
&& ( 0 == iTsyReqHandleStore->GetTsyReqHandle(
EMultimodeCallHangUp ) ) )
{
TBool timerStarted = EFalse;
if( iCallTimer )
{
timerStarted = iCallTimer->Stop();
}
//Check air time timer only if call was in active state(call timer
//was started)
if ( timerStarted )
{
if( iMmPhone )
{
iMmPhone->AirTimeTimerCheckStop();
//TODO: attention reviewers - please check if UpdateLifeTimer should/shouldn't be called here
UpdateLifeTimer();
}
}
//Send call release request before deleting this object
TInt symbianHangUpCause( KErrGsmReleaseByUser );
//Create package
CCallDataPackage package;
//Set call id and call mode
package.SetCallIdAndMode( iCallId, iCallMode );
TBool autoStChangeDisable = EFalse;
//Pack call parameters and mobile call info
package.PackData( &symbianHangUpCause, &autoStChangeDisable );
//Send request to the Domestic OS layer.
if( iMessageManager )
{
TRAP( trapError,
iMessageManager->HandleRequestL( EEtelCallHangUp, &package );
);
// inform telephony audio control that we're hanging up the call
if ( iTelephonyAudioControlSetup && iTelephonyAudioControl )
{
iTelephonyAudioControl->TeardownTelephonyAudio( iCallName,
KErrNone );
TFLOGSTRING2("TSY: CMmCallTsy::~CMmCallTsy Call routing tear down: Call name:%S", &iCallName );
}
}
// We can't do nothing if hanguprequest fails here,
// because call object is closed.
}
}
//delete req handle store
if ( iTsyReqHandleStore )
{
delete iTsyReqHandleStore;
}
iTsyReqHandleStore = NULL;
//delete req handle store
if ( iList )
{
delete iList;
}
iList = NULL;
//delete call ownership change request list
if ( iCallTimer )
{
delete iCallTimer;
}
iCallTimer = NULL;
//Decrement number of opened calls from line.
if( iMmLine )
{
iMmLine->DecrementNumberOfCalls();
}
// Remove the call from the list of calls
if( iMmPhone )
{
iMmPhone->CallList()->RemoveObject( this );
}
//delete call extension
if ( iMmCallExtInterface )
{
delete iMmCallExtInterface;
}
iMmCallExtInterface = NULL;
iMmPhone = NULL;
iMmLine = NULL;
iCallTimer = NULL;
iRetNotifyMobileCallCaps = NULL;
iRetCaps = NULL;
iRetStatus = NULL;
iRetMobileCallStatus = NULL;
iRetRemotePartyInfo = NULL;
iRetTimeIntervalSeconds = NULL;
iRetCallEvent = NULL;
iList = NULL;
iTsyReqHandleStore = NULL;
iRetPrivacyStatus = NULL;
iMessageManager = NULL;
iRetUUI = NULL;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::InitExtensionModulesL
// Initialises extension modules for CMmCallTsy
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::InitExtensionModulesL(
RMobilePhone::TMobileService aMode )
{
RMobilePhone::TMobilePhoneNetworkMode currentMode;
iMmPhone->GetStaticExtensionMode( ¤tMode );
iMmCallExtInterface = reinterpret_cast<CMmCallExtInterface*>
(CMmCallGsmWcdmaExt::NewL( this, aMode, iMessageManager ) );
}
// ---------------------------------------------------------------------------
// CMmCallTsy::InitInternalAttributes
// Initialises miscellaneous internal attributes.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::InitInternalAttributes()
{
//Set status parameters
iCallStatus = RCall::EStatusIdle;
iMobileCallStatus = RMobileCall::EStatusIdle;
//Initialise call params
iCallParams.iSpeakerControl = RCall::EMonitorSpeakerControlOnUntilCarrier;
iCallParams.iSpeakerVolume = RCall::EMonitorSpeakerVolumeLow;
iCallParams.iInterval = 4;
iCallParams.iWaitForDialTone = RCall::EDialToneWait;
iCallParams.iIdRestrict = RMobileCall::EIdRestrictDefault;
iCallParams.iCug.iExplicitInvoke = EFalse;
iCallParams.iCug.iCugIndex = 0;
iCallParams.iCug.iSuppressPrefCug = EFalse;
iCallParams.iCug.iSuppressOA = EFalse;
iCallParams.iAutoRedial = EFalse;
// CallParamsV2
iCallParams.iBearerMode = RMobileCall::EMulticallNotSupported;
// CallParamsV7
iCallParams.iCallParamOrigin = RMobileCall::EOriginatorUnknown;
iCallParams.iBCRepeatIndicator = RMobileCall::EBCAlternateMode;
iCallParams.iIconId.iQualifier = RMobileCall::EIconQualifierNotSet;
iCallParams.iIconId.iIdentifier = 0;
iCallParams.iAlphaId.Zero();
iCallParams.iSubAddress.Zero();
iCallParams.iBearerCap1.Zero();
iCallParams.iBearerCap2.Zero();
iCallParams.iBCRepeatIndicator = RMobileCall::EBCAlternateMode;
iDialCancelFlag = CMmCallTsy::EDialCancelNotCalled;
iAnswerCancelFlag = EFalse;
iHangUpFlag = EFalse;
//this is required for the Conference call.
iPreviousCallId = -1;
//Initialize last exit code
iLastExitCode = KErrNotFound;
//this is required for custom tsy
iDiagnosticOctet = NULL;
//by default a call object has been created through ETel
iGhostCall = EFalse;
iEtelOriginated = ETrue;
iPreviousCallControlCaps = 0;
iIsRemoteReleasedCall = EFalse;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::OpenNewObjectByNameL
// Creates new object and returns a pointer to it. Not supported.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CTelObject* CMmCallTsy::OpenNewObjectByNameL(
const TDesC& )
{
//Not supported
User::Leave( KErrNotSupported );
//lint -e{527} "unreachable code"
return NULL;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::OpenNewObjectL
// Creates new object and returns a pointer to it. Not supported.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CTelObject* CMmCallTsy::OpenNewObjectL(
TDes& )
{
// Not supported
User::Leave( KErrNotSupported );
//lint -e{527} "unreachable code"
return NULL;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::ExtFunc
// TRAP's all CMmCallTsy related MM API requests in case that they fail. This
// method functions only as a centralized TRAP for the DoExtFuncL method that
// does the actual mapping of IPC number to TSY method call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::ExtFunc(
const TTsyReqHandle aTsyReqHandle,
const TInt aIpc,
const TDataPackage& aPackage )
{
TInt ret( KErrNone );
TInt trapError( KErrNone );
// Ensure the ReqHandleType is unset.
// This will detect cases where this method indirectly calls itself
// (e.g. servicing a client call that causes a self-reposting notification to complete and thus repost).
// Such cases are not supported because iReqHandleType is in the context of this class instance,
// not this request, and we don't want the values set by the inner request and the outer request
// interfering with each other.
__ASSERT_DEBUG(iReqHandleType==EMultimodeCallReqHandleUnknown, User::Invariant());
//before processing further the request, check if offline mode status
//is enabled and if the given request can be perfomed in that case.
if ( ERfsStateInfoInactive == iMmPhone->GetRfStateInfo () &&
!IsRequestPossibleInOffline( aIpc ) )
{
TFLOGSTRING2("TSY: Offline mode ON, request is not allowed: %d", aIpc );
ret = CMmCommonStaticUtility::EpocErrorCode(
KErrGeneral, KErrGsmOfflineOpNotAllowed );
//Complete the request with appropiate error
ReqCompleted ( aTsyReqHandle, ret );
}
else
{
TRAP( trapError, ret = DoExtFuncL( aTsyReqHandle, aIpc, aPackage ); );
if ( trapError != KErrNone )
{
//error handling. Object cannot be created.
ReqCompleted( aTsyReqHandle, trapError );
}
else if ( ret != KErrNone )
{
ReqCompleted( aTsyReqHandle, ret );
}
//save request handle
if ( EMultimodeCallReqHandleUnknown != iReqHandleType )
{
#ifdef REQHANDLE_TIMER
SetTypeOfResponse( iReqHandleType, aTsyReqHandle );
#else
iTsyReqHandleStore->SetTsyReqHandle(
iReqHandleType, aTsyReqHandle );
#endif
// We've finished with this value now. Clear it so it doesn't leak
// up to any other instances of this method down the call stack
iReqHandleType = EMultimodeCallReqHandleUnknown;
}
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetInfo
// This CORE API method returns core Call information.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetInfo(
const TTsyReqHandle aTsyReqHandle,
RCall::TCallInfo* aCallInfo )
{
//Fill Core Call information
aCallInfo->iCallName = iCallName;
aCallInfo->iStatus = iCallStatus;
aCallInfo->iLineName = iMmLine->LineName();
aCallInfo->iHookStatus = RCall::EHookStatusUnknown;
aCallInfo->iDuration = GetCallDurationInSeconds();
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyCapsChange
// This CORE API method requests notifications when core caps change.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyCapsChange(
const TTsyReqHandle aTsyReqHandle,
RCall::TCaps* aCaps )
{
iRetCaps = aCaps;
//Store the current capabilities
iPreviousCaps = iCallCaps;
iTsyReqHandleStore->SetTsyReqHandle(
EMultimodeCallCapsChangeNotification, aTsyReqHandle );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyCapsChangeCancel
// This CORE API method cancels core caps change notifications.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyCapsChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetCaps = NULL;
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallCapsChangeNotification );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyCapsChange
// Complete notification when caps change.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteNotifyCapsChange()
{
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallCapsChangeNotification );
//if caps have changed and client has requested capability notifications
if ( EMultimodeCallReqHandleUnknown != reqHandle &&
iRetCaps != NULL &&
iCallCaps.iFlags != iPreviousCaps.iFlags )
{
iRetCaps->iFlags = iCallCaps.iFlags;
ReqCompleted( reqHandle, KErrNone );
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyHookChange
// This CORE API method requests notifications on hook change.
// Feature not supported.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyHookChange(
const TTsyReqHandle aTsyReqHandle,
RCall::THookStatus* )
{
ReqCompleted( aTsyReqHandle, KErrNotSupported );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyHookChange
// This CORE API method cancels hook change notifications.
// Feature not supported.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyHookChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
ReqCompleted( aTsyReqHandle, KErrNotSupported );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyStatusChange
// This CORE API method requests notifications when Core status changes.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyStatusChange(
const TTsyReqHandle aTsyReqHandle,
RCall::TStatus* aStatus )
{
// Save request handle and ptr to aStatus.
iRetStatus = aStatus;
iTsyReqHandleStore->SetTsyReqHandle(
EMultimodeCallNotifyStatusChange, aTsyReqHandle );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyStatusChangeCancel
// This CORE API method cancels core status change notifications.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyStatusChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetStatus = NULL;
iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallNotifyStatusChange );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::HandleGhostCallStatusChange
// Handles status change notifications of a call object that is not monitored
// by any client (handle to this call object has not been opened by any client).
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::HandleGhostCallStatusChange(
TInt aResult,
CMmDataPackage* aDataPackage )
{
RMobileCall::TMobileCallStatus callStatus( RMobileCall::EStatusIdle );
RMobileCall::TMobileCallStatus receivedCallStatus(
RMobileCall::EStatusIdle );
aDataPackage->UnPackData( receivedCallStatus );
TTsyReqHandle mobileStatusHandle = iTsyReqHandleStore->GetTsyReqHandle(
EMultimodeCallNotifyMobileCallStatusChange );
//client is ready for receiving status change indications
//or call has entered either idle or active status -> no
//more status changes are assumed soon.
if ( mobileStatusHandle ||
( receivedCallStatus == RMobileCall::EStatusConnected ) ||
( receivedCallStatus == RMobileCall::EStatusIdle ) )
{
//this call is not anymore a ghost call
iGhostCall = EFalse;
//idle state indicated -> no more indications waited.
if ( RMobileCall::EStatusIdle == receivedCallStatus )
{
//ghost call has terminated, inform client
CompleteNotifyStatusChange( aResult, aDataPackage );
}
//complete one or more simulated status change indications
else
{
if ( RMobileCall::EStatusDisconnecting == receivedCallStatus ||
RMobileCall::EStatusDisconnectingWithInband ==
receivedCallStatus )
{
CompleteNotifyStatusChange( aResult, aDataPackage );
}
else
{
//Send simulated status indications to the client
//since it has missed the real ones.
if ( receivedCallStatus >= RMobileCall::EStatusDialling )
{
callStatus = RMobileCall::EStatusDialling;
aDataPackage->PackData( &callStatus );
CompleteNotifyStatusChange( aResult, aDataPackage );
}
if ( receivedCallStatus >= RMobileCall::EStatusConnecting )
{
callStatus = RMobileCall::EStatusConnecting;
aDataPackage->PackData( &callStatus );
CompleteNotifyStatusChange( aResult, aDataPackage );
}
if ( receivedCallStatus >= RMobileCall::EStatusConnected )
{
callStatus = RMobileCall::EStatusConnected;
aDataPackage->PackData( &callStatus );
CompleteNotifyStatusChange( aResult, aDataPackage );
}
}
}
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyDurationChange
// This CORE API method requests notification when call duration changes.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyDurationChange(
const TTsyReqHandle aTsyReqHandle,
TTimeIntervalSeconds* aTime )
{
iRetTimeIntervalSeconds = aTime;
iTsyReqHandleStore->SetTsyReqHandle(
EMultimodeCallNotifyDurationChange, aTsyReqHandle );
if ( iCallStatus == RCall::EStatusConnected && iCallTimer != NULL)
{
//start duration notifications immediately
iCallTimer->Start();
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyDurationChangeCancel
// This CORE API method cancels call duration change notifications.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyDurationChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetTimeIntervalSeconds = NULL;
if ( iCallTimer != NULL )
{
//stop notifications
iCallTimer->Stop();
}
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyDurationChange );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyCallDurationChange
// Complete notification when duration changes. Timer causes calling of
// this completion every second. Type is not defined because this is
// called by iCallTimer.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteNotifyCallDurationChange()
{
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyDurationChange );
if ( EMultimodeCallReqHandleUnknown != reqHandle )
{
//get current duration.
*iRetTimeIntervalSeconds = GetCallDurationInSeconds();
ReqCompleted( reqHandle, KErrNone );
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetStatus
// This CORE API methods returns core call status through the aStatus param.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetStatus(
const TTsyReqHandle aTsyReqHandle,
RCall::TStatus* aStatus )
{
*aStatus = iCallStatus;
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetCaps
// This CORE API method returns Core call capabilities.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetCaps(
const TTsyReqHandle aTsyReqHandle,
RCall::TCaps* aCaps )
{
*aCaps = iCallCaps;
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::DialCancel
// This CORE API method cancels an outstanding dial request.Calls HangUp
// method to do this and set a flag so that we can know that DialCancel
// handling is going on.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::DialCancel(
const TTsyReqHandle aTsyReqHandle )
{
TFLOGSTRING3("TSY: CMmCallTsy::DialCancel. Req handle: %d, Call name: %S", aTsyReqHandle, &iCallName);
TInt ret( KErrGeneral );
//check if dial cancel has been called
if ( CMmCallTsy::EDialCancelNotCalled != iDialCancelFlag )
{
ret = KErrServerBusy;
}
else
{
ret = KErrNone;
iDialCancelFlag = CMmCallTsy::EDialCancelCallCalled;
if ( iCallId > 0 || (GetDialFlag()&& iCallStatus!=RMobileCall::EStatusIdle) )
{
if ( RMobileCall::EStatusDisconnecting != iMobileCallStatus )
{
TFLOGSTRING("TSY: CMmCallTsy::DialCancel Hangup called");
HangUp( aTsyReqHandle );
}
else
{
TFLOGSTRING("TSY: CMmCallTsy::DialCancel skipped Hangup call");
}
}
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteDial
// Completes a Dial request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteDial(
TInt aResult )
{
TFLOGSTRING2("TSY: CMmCallTsy::CompleteDial. Result:%d", aResult );
TFLOGSTRING3("TSY: CMmCallTsy::CompleteDial. Call Id:%d Call name:%S", iCallId, &iCallName);
//Set dial flag to false
SetDialFlag( EFalse );
TTsyReqHandle reqHandle ( EMultimodeCallReqHandleUnknown );
if ( KETelExt3rdPartyV1 == iExtensionId )
{
//3rd Party Client
//reset req handle. Returns the deleted req handle
TFLOGSTRING("TSY: CMmCallTsy::CompleteDial. EMultimodeCallDialISV");
reqHandle =
iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallDialISV );
}
else
{
//reset req handle. Returns the deleted req handle
TFLOGSTRING("TSY: CMmCallTsy::CompleteDial. EMultimodeCallDial");
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 );
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::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 CMmCallTsy::AnswerIncomingCallCancel(
const TTsyReqHandle aTsyReqHandle )
{
TFLOGSTRING3("TSY: CMmCallTsy::AnswerIncomingCallCancel. Req handle: %d, Call name: %S", aTsyReqHandle, &iCallName);
TInt ret( KErrNone );
if( iAnswerCancelFlag )
{
ret = KErrServerBusy;
}
else
{
iAnswerCancelFlag = ETrue;
if ( 0 < iCallId )
{
HangUp( aTsyReqHandle );
}
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteAnswerIncomingCall
// Completes answer request to client.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteAnswerIncomingCall(
TInt aResult )
{
TFLOGSTRING2("TSY: CMmCallTsy::CompleteAnswerIncomingCall. Result:%d", aResult );
TFLOGSTRING3("TSY: CMmCallTsy::CompleteAnswerIncomingCall. Call Id:%d Call name:%S", iCallId, &iCallName);
TTsyReqHandle reqHandle ( EMultimodeCallReqHandleUnknown );
TFLOGSTRING2("TSY: CMmCallTsy::CompleteAnswerIncomingCall. iExtensionId:%d", iExtensionId );
if ( KETelExt3rdPartyV1 == iExtensionId )
{
//3rd Party Client
//reset req handle. Returns the deleted req handle
reqHandle =
iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallAnswerISV );
}
else
{
//reset req handle. Returns the deleted req handle
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 );
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::HangUpCancel
// CORE API method. 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 HangUp() acknowledgemnt and when it receives it, the TSY will
// complete the original HangUp request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::HangUpCancel(
const TTsyReqHandle )
{
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::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 CMmCallTsy::CompleteHangUp(
TInt aResult )
{
TFLOGSTRING2("TSY: CMmCallTsy::CompleteHangUp.\n \t\t\t Result:%d", aResult );
TFLOGSTRING3("TSY: CMmCallTsy::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;
//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;
}
//If client refuses to answer, remove the answering capability
iCallCaps.iFlags &= ~( RCall::KCapsAnswer );
}
ReqCompleted( reqHandle, ret );
//complete caps change notification
CompleteNotifyCapsChange();
}
}
// Complete for DialCancel or AnswerIncomingCallCancel, success
else if ( KErrNone == aResult )
{
// Find out if this is cancelling of Dial
TTsyReqHandle cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallDial );
if ( cancelHandle == NULL )
{
// Find out if this is cancelling of AnswerIncomingCall
cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallAnswer );
if( NULL == cancelHandle )
{
// Find out if this is cancelling of AnswerIncomingCallISV
cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallAnswerISV );
if( NULL == cancelHandle )
{
// Find out if this is cancelling of DialISV
cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallDialISV );
if ( NULL == cancelHandle )
{
// Find out if this is cancelling of DialNoFdnCheck
cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallDialNoFdnCheck );
}
}
}
}
if ( 0 < cancelHandle )
{
// Complete with error value KErrCancel
ReqCompleted( cancelHandle, KErrCancel );
// Cancel has succeeded, update core status -
// dial possible again
iCallCaps.iFlags |= RCall::KCapsDial;
// If client refuses to answer, remove the answering capability
iCallCaps.iFlags &= ~( RCall::KCapsAnswer );
// Complete caps change notification
CompleteNotifyCapsChange();
}
}
// 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 ( cancelHandle == NULL )
{
// Find out if this is cancelling of AnswerIncomingCall
cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallAnswer );
if( NULL == cancelHandle )
{
// Find out if this is cancelling of AnswerIncomingCallISV
cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallAnswerISV );
if( NULL == cancelHandle )
{
// Find out if this is cancelling of DialISV
cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallDialISV );
if ( NULL == cancelHandle )
{
// Find out if this is cancelling of DialNoFdnCheck
cancelHandle = iTsyReqHandleStore->
ResetTsyReqHandle( EMultimodeCallDialNoFdnCheck );
}
}
}
}
// Cancel to Dial or AnswerIncomingCall
if ( 0 < cancelHandle )
{
// 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 HangUp flag
iHangUpFlag = EFalse;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetOwnershipStatus
// Get call ownership status.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetOwnershipStatus(
const TTsyReqHandle,
RCall::TOwnershipStatus* )
{
return KErrNotSupported;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::TransferOwnership
// Transfers the call ownership.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::TransferOwnership(
const TTsyReqHandle )
{
return KErrNotSupported;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::AcquireOwnership
// Acquire the call ownership.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::AcquireOwnership(
const TTsyReqHandle )
{
return KErrNotSupported;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::AcquireOwnershipCancel
// Cancel the call ownership acquire.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::AcquireOwnershipCancel(
const TTsyReqHandle )
{
return KErrNotSupported;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::RelinquishOwnership
// Relinquish the call ownership.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::RelinquishOwnership()
{
return KErrNotSupported;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetCallParams
// This CORE API method is used for getting Core call parameters.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetCallParams(
const TTsyReqHandle aTsyReqHandle,
TDes8* aParams )
{
if(sizeof(RMobileCall::TMobileCallParamsV1) > aParams->MaxLength())
{
TFLOGSTRING ("TSY: CMmCallTsy::GetCallParams bad size argument");
// Complete the request with appropiate error
return KErrArgument;
}
RMobileCall::TMobileCallParamsV1Pckg* paramsPckgV1 =
reinterpret_cast<RMobileCall::TMobileCallParamsV1Pckg*>( aParams );
RMobileCall::TMobileCallParamsV1& paramsV1 = ( *paramsPckgV1 )();
paramsV1.iSpeakerControl = iCallParams.iSpeakerControl;
paramsV1.iSpeakerVolume = iCallParams.iSpeakerVolume;
paramsV1.iInterval = iCallParams.iInterval;
paramsV1.iWaitForDialTone = iCallParams.iWaitForDialTone;
//let extension to update mode specific params as well
iMmCallExtInterface->GetCallParams( aParams );
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetCallDuration
// This CORE API method is used for getting call duration. Calls
// GetCallDurationInSeconds() method to return the current call duration.
// See details from there.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetCallDuration(
const TTsyReqHandle aTsyReqHandle,
TTimeIntervalSeconds* aTime )
{
//get duration
*aTime = GetCallDurationInSeconds();
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CallId
// Returns call ID.of this call
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::CallId() const
{
return iCallId;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetCallId
// Sets call ID.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::SetCallId(
TInt aCallId )
{
TInt ret( KErrGeneral );
if ( aCallId <= KMaxCallIdValue )
{
iCallId = aCallId;
ret = KErrNone;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetCallStatus
// Sets call Status.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetCallStatus(
RCall::TStatus aCallStatus,
RMobileCall::TMobileCallStatus aMobileCallStatus )
{
iCallStatus = aCallStatus;
iMobileCallStatus = aMobileCallStatus;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetPreviousCallId
// Sets previous active call ID. The Call ID is set when the call goes to idle
// state. Before the previous call ID is set, all other calls are checked and
// if they have the same previous call ID, their call id will be cleared. This
// is required by Conference call implementation.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetPreviousCallId(
TInt aCurrentId )
{
if ( aCurrentId > 0 )
{
CMmCallTsy* mmCall = NULL;
for ( TInt i = 0; i < iMmPhone->CallList()->
GetNumberOfObjects(); i++ )
{
mmCall = iMmPhone->CallList()->GetMmCallByIndex( i );
if ( mmCall->PreviousCallId() == aCurrentId )
{
mmCall->SetPreviousCallId( -1 );
}
}
}
iPreviousCallId = aCurrentId;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::PreviousCallId
// Returns previous active call ID. The Call ID is reset when the call goes to
// idle state. This is required by Conference call implementation.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::PreviousCallId() const
{
return iPreviousCallId;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::ResetPreviousCallId
// Resets previous active call ID. The Call ID is reset when the call goes to
// idle state. This is required by Conference call implementation.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::ResetPreviousCallId()
{
iPreviousCallId = -1;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CallMode
// Returns call mode.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
RMobilePhone::TMobileService CMmCallTsy::CallMode() const
{
return iCallMode;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CallDirection
// Returns call direction.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
RMobileCall::TMobileCallDirection CMmCallTsy::CallDirection() const
{
return iCallDirection;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetCallDirection
// Sets call direction.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::SetCallDirection(
RMobileCall::TMobileCallDirection aCallDirection )
{
iCallDirection = aCallDirection;
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CallName
// Returns call name.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
const TDesC& CMmCallTsy::CallName() const
{
return iCallName;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetCallName
// Sets call name.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetCallName(
const TName& aCallName )
{
iCallName = aCallName;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetCallCaps
// Sets call capabilities.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetCallCaps(
TUint32 aCallCaps )
{
iCallCaps.iFlags = aCallCaps;
CompleteNotifyCapsChange();
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CallCaps
// Returns call capabilities.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TUint32 CMmCallTsy::CallCaps() const
{
//get call caps
TUint32 aCallCaps = iCallCaps.iFlags;
//return them
return aCallCaps;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetMobileCallCaps
// This function returns the call control and call event dynamic capabilities.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetMobileCallCaps(
const TTsyReqHandle aTsyReqHandle,
TDes8* aCaps )
{
TInt ret( KErrArgument );
if ( sizeof ( RMobileCall::TMobileCallCapsV1 ) <= aCaps->MaxLength() )
{
RMobileCall::TMobileCallCapsV1Pckg* callCapsV1Pckg =
reinterpret_cast<RMobileCall::TMobileCallCapsV1Pckg*>( aCaps );
RMobileCall::TMobileCallCapsV1& callCapsV1 =
( *callCapsV1Pckg )();
if ( KETelExtMultimodeV1 == callCapsV1.ExtensionId() )
{
ret = KErrNone;
iMmCallExtInterface->GetMobileCallCapsV1( callCapsV1 );
}
}
ReqCompleted( aTsyReqHandle, ret );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyMobileCallCapsChange
// Notifies the change of Mobile Call Capabilities.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyMobileCallCapsChange(
TDes8* aCaps )
{
TInt ret( KErrArgument );
if ( sizeof ( RMobileCall::TMobileCallCapsV1 ) <= aCaps->MaxLength() )
{
RMobileCall::TMobileCallCapsV1Pckg* callCapsV1Pckg =
reinterpret_cast<RMobileCall::TMobileCallCapsV1Pckg*>( aCaps );
RMobileCall::TMobileCallCapsV1& callCapsV1 =
( *callCapsV1Pckg )();
if ( KETelExtMultimodeV1 == callCapsV1.ExtensionId() )
{
ret = KErrNone;
iRetNotifyMobileCallCaps = aCaps;
iReqHandleType = EMultimodeCallNotifyMobileCallCapsChange;
}
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyMobileCallCapsChangeCancel
// Cancels an outstanding asynchronous NotifyMobileCallCapsChange request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyMobileCallCapsChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
//reset pointer
iRetNotifyMobileCallCaps = NULL;
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyMobileCallCapsChange );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyMobileCallCapsChange
// Completes a NotifyMobileCallCapsChange method. The caps request is directed
// to the currently active protocol extension.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteNotifyMobileCallCapsChange(
TInt aErrorCode )
{
//get req handle.
TTsyReqHandle reqHandle = iTsyReqHandleStore->GetTsyReqHandle(
EMultimodeCallNotifyMobileCallCapsChange );
if ( EMultimodeCallReqHandleUnknown != reqHandle )
{
RMobileCall::TMobileCallCapsV1Pckg* callCapsV1Pckg =
reinterpret_cast<RMobileCall::TMobileCallCapsV1Pckg*>(
iRetNotifyMobileCallCaps );
RMobileCall::TMobileCallCapsV1& callCapsV1 =
( *callCapsV1Pckg )();
iMmCallExtInterface->GetMobileCallCapsV1( callCapsV1 );
if (callCapsV1.iCallControlCaps != iPreviousCallControlCaps )
{
//reset req handle.
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyMobileCallCapsChange );
iPreviousCallControlCaps = callCapsV1.iCallControlCaps;
iRetNotifyMobileCallCaps = NULL;
ReqCompleted( reqHandle, aErrorCode );
}
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyMobileCallCapsChange
// Returns a pointer to the active extension.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CMmCallExtInterface* CMmCallTsy::ActiveCallExtension()
{
return iMmCallExtInterface;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::ClearCallStatus
// Clears internal call status.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::ClearCallStatus()
{
iCallDirection = RMobileCall::EDirectionUnknown;
iEtelOriginated = ETrue;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::Status
// Returns the current core call status. Can be called from TSY classes.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
RCall::TStatus CMmCallTsy::Status() const
{
return iCallStatus;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::MobileCallStatus
// Returns the current mobile call status. Can be called from TSY classes.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
RMobileCall::TMobileCallStatus CMmCallTsy::MobileCallStatus() const
{
return iMobileCallStatus;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetMobileCallStatus
// Returns the current status of the call through the aStatus argument.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetMobileCallStatus(
const TTsyReqHandle aTsyReqHandle,
RMobileCall::TMobileCallStatus* aStatus )
{
*aStatus = iMobileCallStatus;
ReqCompleted( aTsyReqHandle, KErrNone );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyMobileCallStatusChange
// Allows a client to be notified when the call changes state. The request
// completes when the call changes state, the new state being passed in the
// aStatus parameter.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyMobileCallStatusChange(
RMobileCall::TMobileCallStatus* aStatus )
{
iRetMobileCallStatus = aStatus;
iReqHandleType = EMultimodeCallNotifyMobileCallStatusChange;
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyMobileCallStatusChangeCancel
// Cancels an outstanding asynchronous NotifyMobileCallStatusChange request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyMobileCallStatusChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetMobileCallStatus = NULL;
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyMobileCallStatusChange );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyCallEvent
// Allows clients to be notified when various call events occur. These events
// may be generated locally (i.e. from within the ME) or remotely (by the
// remote connected party). The request completes when an event occurs. Upon
// completion, the aEvent parameter will return the event type.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyCallEvent(
RMobileCall::TMobileCallEvent* aEvent )
{
iRetCallEvent = aEvent;
iReqHandleType = EMultimodeCallNotifyCallEvent;
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyCallEventCancel
// This method cancels an outstanding asynchronous NotifyCallEvent request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyCallEventCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetCallEvent = NULL;
iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallNotifyCallEvent );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyCallEvent
// Allows clients to be notified when various call events occur.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteNotifyCallEvent(
RMobileCall::TMobileCallEvent aEvent )
{
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyCallEvent );
if ( EMultimodeCallReqHandleUnknown != reqHandle &&
iRetCallEvent != NULL )
{
if( IsPartOfConference() && RMobileCall::ERemoteTerminated == aEvent )
{
TFLOGSTRING("TSY: iIsRemoteReleasedCall = ETrue");
iIsRemoteReleasedCall = ETrue;
}
*iRetCallEvent = aEvent;
ReqCompleted( reqHandle, KErrNone );
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyRemoteCallEvent
// Informs common TSY about a remote event (that cannot be understood from
// status indication.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteNotifyRemoteCallEvent(
const CMmDataPackage* aDataPackage )
{
RMobileCall::TMobileCallEvent callEvent( RMobileCall::ERemoteHold );
aDataPackage->UnPackData( callEvent );
switch ( callEvent )
{
case RMobileCall::ERemoteHold:
case RMobileCall::ERemoteResume:
case RMobileCall::ERemoteTerminated:
case RMobileCall::ERemoteConferenceCreate:
CompleteNotifyCallEvent( callEvent );
break;
//local events handled by CMmCallTsy::CompleteNotifyStatusChange
case RMobileCall::ELocalHold:
case RMobileCall::ELocalResume:
case RMobileCall::ELocalDeflectCall:
case RMobileCall::ELocalTransfer:
//not supported cases
case RMobileCall::ERemoteTransferring:
case RMobileCall::ERemoteTransferAlerting:
case RMobileCall::ERemoteBarred:
case RMobileCall::ERemoteForwarding:
case RMobileCall::ERemoteWaiting:
case RMobileCall::ELocalBarred:
default:
break;
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetMobileCallInfo
// The method returns a current snapshot of the call information
// described in the TMobileCallInfoVx class. The class is packaged into
// a TMobileCallInfoVxPckg before being passed to the GetMobileCallInfo method.
// This method actually calls FillMobileCallInfo method to get mobile call
// information.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetMobileCallInfo(
const TTsyReqHandle aTsyReqHandle,
TDes8* aInfo )
{
//get the mobile call information
TInt ret = FillMobileCallInfo( aInfo );
ReqCompleted( aTsyReqHandle, ret );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::FillMobileCallInfo
// The method fills a current snapshot of the call information described in
// the TMobileCallInfoVx class to the aInfo. The mode specific fields will
// be filled by the extension.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::FillMobileCallInfo(
TDes8* aInfo )
{
TFLOGSTRING("TSY: CMmCallTsy::FillMobileCallInfo");
TInt ret = KErrArgument;
TInt extensionId = 0;
if ( sizeof ( RMobilePhone::TMultimodeType ) <= aInfo->MaxLength() )
{
RMobilePhone::TMultimodeTypePckg* infoParamsPckg =
reinterpret_cast<RMobilePhone::TMultimodeTypePckg*>(
aInfo );
RMobilePhone::TMultimodeType& callInfo = ( *infoParamsPckg )();
// get extensionid from the recieved data
extensionId = callInfo.ExtensionId();
TFLOGSTRING2("TSY: CMmCallTsy::FillMobileCallInfo - extensionid=%d",callInfo.ExtensionId());
}
//TMobileCallInfoV1
if ( KETelExtMultimodeV1 == extensionId ||
KETelExtMultimodeV3 == extensionId ||
KEtelExtMultimodeV7 == extensionId ||
KEtelExtMultimodeV8 == extensionId )
{
TFLOGSTRING("TSY: CMmCallTsy::FillMobileCallInfo - V1");
// Set ret to KErrNone. We can fill this parameter class.
ret = KErrNone;
RMobileCall::TMobileCallInfoV1Pckg* paramsPckgV1 =
reinterpret_cast<RMobileCall::TMobileCallInfoV1Pckg*>( aInfo );
RMobileCall::TMobileCallInfoV1& info = ( *paramsPckgV1 )();
// set mobilecallinfo default values
FillMobileCallInfoDefaults( &info );
// fill specific data
iMmCallExtInterface->FillMobileCallInfo( &info );
}
// TMobileCallInfoV3
if ( KETelExtMultimodeV3 == extensionId ||
KEtelExtMultimodeV7 == extensionId ||
KEtelExtMultimodeV8 == extensionId )
{
TFLOGSTRING("TSY: CMmCallTsy::FillMobileCallInfo - V3");
RMobileCall::TMobileCallInfoV3Pckg* paramsPckgV3 =
reinterpret_cast<RMobileCall::TMobileCallInfoV3Pckg*>( aInfo );
RMobileCall::TMobileCallInfoV3& info = ( *paramsPckgV3 )();
// fill specific data
iMmCallExtInterface->FillMobileCallInfoV3( &info ) ;
}
// TMobileCallInfoV7
if ( KEtelExtMultimodeV7 == extensionId ||
KEtelExtMultimodeV8 == extensionId )
{
TFLOGSTRING("TSY: CMmCallTsy::FillMobileCallInfo - V7");
RMobileCall::TMobileCallInfoV7Pckg* paramsPckgV7 =
reinterpret_cast<RMobileCall::TMobileCallInfoV7Pckg*>( aInfo );
RMobileCall::TMobileCallInfoV7& info = ( *paramsPckgV7 )();
// fill specific data
iMmCallExtInterface->FillMobileCallInfoV7( &info );
}
// TMobileCallInfoV8
if ( KEtelExtMultimodeV8 == extensionId )
{
TFLOGSTRING("TSY: CMmCallTsy::FillMobileCallInfo - V8");
RMobileCall::TMobileCallInfoV8Pckg* paramsPckgV8 =
reinterpret_cast<RMobileCall::TMobileCallInfoV8Pckg*>( aInfo );
RMobileCall::TMobileCallInfoV8& info = ( *paramsPckgV8 )();
// fill specific data
iMmCallExtInterface->FillMobileCallInfoV8( &info );
}
TFLOGSTRING2("TSY: CMmCallTsy::FillMobileCallInfo end. ret=%d",ret);
return ret;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyRemotePartyInfoChange
// This method allows the client to be notified of any change in the remote
// party information.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyRemotePartyInfoChange(
TDes8* aRemotePartyInfo )
{
TInt ret = KErrNone;
if( sizeof( RMobileCall::TMobileCallRemotePartyInfoV1 ) > aRemotePartyInfo->MaxLength() )
{
TFLOGSTRING ("TSY: CMmCallTsy::NotifyRemotePartyInfoChange Bad size argument");
// Complete the request with appropiate error
ret = KErrArgument;
}
else
{
iRetRemotePartyInfo = aRemotePartyInfo;
iReqHandleType = EMultimodeCallNotifyRemotePartyInfoChange;
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyRemotePartyInfoChangeCancel
// This method cancels an outstanding asynchronous NotifyRemotePartyInfoChange
// request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyRemotePartyInfoChangeCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetRemotePartyInfo = NULL;
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyRemotePartyInfoChange );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyRemotePartyInfoChange
// Completes a NotifyRemotePartyInfoChange method.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteNotifyRemotePartyInfoChange()
{
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyRemotePartyInfoChange );
if ( EMultimodeCallReqHandleUnknown != reqHandle )
{
iMmCallExtInterface->GetRemotePartyInfo(
reinterpret_cast<RMobileCall::TMobileCallRemotePartyInfoV1Pckg*>
( iRetRemotePartyInfo ) );
ReqCompleted( reqHandle, KErrNone );
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyMobileCallInfoChange
// Notifies common TSY about mobile call information change.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteNotifyMobileCallInfoChange(
CMmDataPackage* aDataPackage )
{
//set data to gsm extension
//( direction added because not uppdated in messagehandler)
iMmCallExtInterface->SetMobileCallData(
aDataPackage, iCallDirection );
//call completenotify remotepartyinfochange
CompleteNotifyRemotePartyInfoChange();
}
// ---------------------------------------------------------------------------
// CMmCallTsy::TransferL
// This method allows a client to transfer a call so that the remote party of
// one call ends up connected to the remote party of another call while this
// user drops out of both calls.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::TransferL(
const TTsyReqHandle aTsyReqHandle )
{
TInt ret( KErrServerBusy );
TTsyReqHandle transferHandle =
iTsyReqHandleStore->GetTsyReqHandle( EMultimodeCallTransfer );
if ( !transferHandle )
{
ret = iMmCallExtInterface->TransferL();
if ( KErrNone != ret )
{
ReqCompleted( aTsyReqHandle, ret );
}
else
{
//save tsy req handle type
iReqHandleType = EMultimodeCallTransfer;
}
}
else
{
ReqCompleted( aTsyReqHandle, ret );
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteTransfer
// This method completes an outstanding asynchronous Transfer request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteTransfer(
TInt aErrorCode )
{
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle =
iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallTransfer );
if ( EMultimodeCallReqHandleUnknown != reqHandle )
{
ReqCompleted( reqHandle, aErrorCode );
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyPrivacyConfirmation
// This method allows the client to be notified when the network has confirmed
// the privacy setting.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyPrivacyConfirmation(
RMobilePhone::TMobilePhonePrivacy* aPrivacyStatus )
{
iRetPrivacyStatus = aPrivacyStatus;
iReqHandleType = EMultimodeCallNotifyPrivacyConfirmation;
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::NotifyPrivacyConfirmationCancel
// Cancels an outstanding asynchronous NotifyPrivacyConfirmation request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::NotifyPrivacyConfirmationCancel(
const TTsyReqHandle aTsyReqHandle )
{
iRetPrivacyStatus = NULL;
iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyPrivacyConfirmation );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteNotifyPrivacyConfirmation
// Completes a NotifyPrivacyConfirmation request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteNotifyPrivacyConfirmation(
RMobilePhone::TMobilePhonePrivacy aStatus )
{
//reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle = iTsyReqHandleStore->ResetTsyReqHandle(
EMultimodeCallNotifyPrivacyConfirmation );
if ( EMultimodeCallReqHandleUnknown != reqHandle )
{
*iRetPrivacyStatus = aStatus;
ReqCompleted( reqHandle, KErrNone );
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::Line
// Return the line from which this call object has been opened from.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CMmLineTsy* CMmCallTsy::Line()
{
//Return the line from which this call object has been opened from.
return iMmLine;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::Phone
// This method returns pointer to the Phone object.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CMmPhoneTsy* CMmCallTsy::Phone()
{
//This method returns pointer to the Phone object.
return iMmPhone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetCallDurationInSeconds
// Returns call duration in seconds. If call is not active, the duration of
// the last successful call will be returned.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TTimeIntervalSeconds CMmCallTsy::GetCallDurationInSeconds()
{
// If the call is active, NumberOfBeats will return the current duration
// If the call is not active, NumberOfBeats will return the last
// call duration
TTimeIntervalSeconds duration ( iCallTimer->NumberOfBeats() );
return duration;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::IsServiceLocallyRequested
// Return ETrue if this type of request is requested by any of TSY's client.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::IsServiceLocallyRequested(
CMmCallTsy::TCallRequestTypes aReqType )
{
//Return ETrue if this type of request is requested by any TSY's client.
//create parameter callCount and get number of objects from call list to
//it
TInt callCount = iMmPhone->CallList()->GetNumberOfObjects();
CMmCallTsy* mmCall = NULL;
TBool ret( EFalse);
for ( TInt i = 0; i < callCount; i++ )
{
mmCall = reinterpret_cast<CMmCallTsy*>(
iMmPhone->CallList()->GetObjectByIndex(i));
if( mmCall->ServiceRequested( aReqType ) )
{
ret = ETrue;
break;
}
}
return ret;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetGhostCall
// Return ETrue if this call is a Ghost Call
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::GetGhostCall() const
{
return iGhostCall;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetDiagnostics
// Returns value of iDiagnosticOctect internal attribute
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TUint8 CMmCallTsy::GetDiagnostics() const
{
return iDiagnosticOctet;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetDiagnostics
// Sets aDiagnosticOctet into internal variable iDiagnosticOctet
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetDiagnostics(
TUint8 aDiagnosticOctet )
{
iDiagnosticOctet = aDiagnosticOctet;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetCallReqHandleStore
// Returns pointer to iTsyReqHandleStore
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
CMmTsyReqHandleStore* CMmCallTsy::GetCallReqHandleStore()
{
return iTsyReqHandleStore;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetUnownedCallObjectFlag
// TSY creates automatically call object for incoming call or ghost call that
// is created using AT-commands. This method sets flag indicating if a client
// has't opened existing call object for this call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetUnownedCallObjectFlag(
TBool aIsUnownedCallObject )
{
iUnownedCallObject = aIsUnownedCallObject;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::IsUnownedCallObject
// TSY creates automatically call object for incoming call or ghost call that
// is created using AT-commands. This flag indicates that client haven't
// opened existing call object for this call.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::IsUnownedCallObject() const
{
return iUnownedCallObject;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetGhostCall
// Sets a flag that indicates that this call is not created through ETel
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetGhostCall(
TBool aValue )
{
//Sets a flag that indicates that this call is not created through ETel
iGhostCall = aValue;
if ( aValue )
{
iEtelOriginated = EFalse;
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::ETelOriginated
// Returns ETrue is this call has been originated through ETel API
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::ETelOriginated() const
{
return iEtelOriginated;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::ServiceRequested
// Returns ETrue if this service is pending on this call object
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::ServiceRequested(
CMmCallTsy::TCallRequestTypes aReqType )
{
TBool ret( EFalse );
if( CMmCallTsy::EMultimodeCallReqHandleUnknown !=
iTsyReqHandleStore->GetTsyReqHandle( aReqType ) )
{
//Returns ETrue if this service is pending on this call object
ret = ETrue;
}
return ret;
}
#ifdef REQHANDLE_TIMER
// ---------------------------------------------------------------------------
// CMmCallTsy::Complete
// Completes the request due timer expiration
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::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 EMultimodeCallDial:
case EMultimodeCallDialISV:
CompleteDial( aError );
break;
case EMultimodeCallDialNoFdnCheck:
CompleteDialNoFdn( aError );
break;
case EMultimodeCallAnswer:
case EMultimodeCallAnswerISV:
CompleteAnswerIncomingCall( aError );
break;
case EMultimodeCallHangUp:
CompleteHangUp( aError );
break;
case EMultimodeCallTransfer:
CompleteTransfer( 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 EMultimodeMobileCallHold:
case EMultimodeMobileCallResume:
case EMultimodeMobileCallSwap:
case EMultimodeMobileCallDeflectCall:
case EMultimodeMobileCallDialEmergencyCall:
case EMultimodeCallGoOneToOne:
case EMultimodeCallSetDynamicHscsdParams:
default:
ReqCompleted(
iTsyReqHandleStore->ResetTsyReqHandle( aReqHandleType ),
aError );
break;
}
}
#endif
#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 CMmCallTsy::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: CMmCallTsy::Request Completed. Handle:%d Error:%d", aTsyReqHandle, aError);
CTelObject::ReqCompleted(aTsyReqHandle,aError);
}
#endif
// ---------------------------------------------------------------------------
// CMmCallTsy::IsPartOfConference
// Returns ETrue if this call is part of a conference
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::IsPartOfConference() const
{
return iIsPartOfConference;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetPartOfConference
// Sets the flag indicating that this call is part of a MO conference
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetPartOfConference( TBool aPartOfConference )
{
iIsPartOfConference = aPartOfConference;
#ifdef TF_LOGGING_METHOD
if ( iIsPartOfConference )
{
TFLOGSTRING2( "TSY: CMmCallTsy::SetPartOfConference: Call %d has joined the conference", iCallId );
}
else
{
TFLOGSTRING( "TSY: CMmCallTsy::SetPartOfConference: Call has left the conference" );
}
#endif // TF_LOGGING_METHOD
}
// ---------------------------------------------------------------------------
// CMmCallTsy::IsRequestPossibleInOffLine
// Checks wether a ETel request can be performed or not while offline mode is
// enabled
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::IsRequestPossibleInOffline( TInt aIpc ) const
{
// we assume here that most of the requests are possible, thefore
// we switch for the not possible ones, optimizing a bit the checking.
TBool isRequestPossible ( ETrue );
switch ( aIpc )
{
case EMobileCallDialEmergencyCall://OK (when flag is enabled)
{
isRequestPossible = EFalse;
RFeatureControl featureControl;
TInt err = featureControl.Open();
if ( (err == KErrNone) && (featureControl.FeatureSupported(NFeature::KEmergencyCallsEnabledInOfflineMode) == KFeatureSupported) )
{
isRequestPossible = ETrue;
}
featureControl.Close();
}
break;
//case EMobileCallGetMobileCallStatus: //OK
//case EMobileCallNotifyMobileCallStatusChange://OK
case EMobileCallHold://NO
case EMobileCallResume://NO
case EMobileCallSwap://NO
case EMobileCallTransfer://NO
case EMobileCallGoOneToOne://NO
//case EMobileCallNotifyCallEvent://OK
//case EMobileCallGetMobileCallCaps: //OK
//case EMobileCallNotifyMobileCallCapsChange: //OK
//case EMobileCallGetMobileCallInfo://OK
//case EMobileCallNotifyRemotePartyInfoChange://OK
//case EMobileCallNotifyPrivacyConfirmation://OK
//case EMobileCallGetMobileDataCallCaps: //OK
//case EMobileCallNotifyMobileDataCallCapsChange: //OK
//case EMobileCallGetMobileDataCallRLPRange://OK
//case EMobileCallSetDynamicHscsdParams://OK
//case EMobileCallGetCurrentHscsdInfo://OK
//case EMobileCallNotifyHscsdInfoChange://OK
isRequestPossible = EFalse;
break;
default:
break;
}
return isRequestPossible;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetFaxSettings
// This CORE API method is used for getting fax settings
// (not supported by default).
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetFaxSettings(
const TTsyReqHandle,
RCall::TFaxSessionSettings* )
{
return KErrNotSupported;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetFaxSettings
// This CORE API method is used for set fax settings
// (not supported by default).
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::SetFaxSettings(
const TTsyReqHandle,
const RCall::TFaxSessionSettings*)
{
return KErrNotSupported;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetExtensionId
// Set iExtensionId attribute
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetExtensionId(
TInt aExtensionId )
{
iExtensionId = aExtensionId;
TFLOGSTRING2("TSY: CMmCallTsy::SetExtensionId.iExtensionId:%d",iExtensionId );
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetExtensionId
// Get iExtensionId attribute
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::GetExtensionId()
{
return iExtensionId;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetDialFlag
// Sets iDialFlag boolean value
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetDialFlag(
TBool aDialFlag )
{
iDialFlag= aDialFlag;
TFLOGSTRING2("TSY: CMmCallTsy::SetDialFlag. iDialFlag:%d",iDialFlag );
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetDialFlag
// Returns iDialFlag boolean value
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::GetDialFlag()
{
TFLOGSTRING2("TSY: CMmCallTsy::GetDialFlag. iDialFlag:%d",iDialFlag );
return iDialFlag;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::IsRemoteReleasedCall
// Returns iIsRemoteReleasedCall boolean value
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TBool CMmCallTsy::IsRemoteReleasedCall() const
{
TFLOGSTRING("TSY: CMmCallTsy::IsRemoteReleasedCall()");
return iIsRemoteReleasedCall;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::ActivateUUS
// Specifies which User-To-User Signalling service(s) should be activated.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::ActivateUUS( const TTsyReqHandle aTsyReqHandle,
RMobileCall::TMobileCallUUSRequestV1Pckg* aUUSRequest )
{
// Support only implicit-UUS1 service,
// save the UUS-Request and send it during the Dial so that
// UUS-Request can be mapped on LTSY side to correct phone call (with id).
// details of the message send, see CMmVoiceCallTsy::Dial
// To support UUS2 and UUS3 services in future the logic must be
// changed so that the UUS information can be sended to LTSY immediately.
// Unpack UUS parameters
RMobileCall::TMobileCallUUSRequestV1 requestUUS = ( *aUUSRequest )();
TFLOGSTRING3("TSY: CMmCallTsy::ActivateUUS() -ServiceReq:%u -UUI:%S", requestUUS.iServiceReq, &requestUUS.iUUI );
// handle implicit UUS1 request only
if ( requestUUS.iServiceReq & RMobileCall::KUUS1Implicit )
{
// take a copy of the UUS request
iUUSRequest = requestUUS;
// complete req, with KErrNone
ReqCompleted( aTsyReqHandle, KErrNone );
}
else
{
// other UUS services are not supported in this phase
ReqCompleted( aTsyReqHandle, KErrNotSupported );
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::ReceiveUUI
// Enables the client to receive the next incoming UUI message or in case
// already received, return the buffered UUI.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::ReceiveUUI( const TTsyReqHandle aTsyReqHandle,
RMobileCall::TMobileCallUUI* aUUI )
{
TFLOGSTRING("TSY: CMmCallTsy::ReceiveUUI()" );
// check are there any UUI information already in the buffer (UUS1)
if ( 0 < iReceivedUUI.Length() )
{
TFLOGSTRING2("TSY: CMmCallTsy::ReceiveUUI() - information in BUFFER:%S", &iReceivedUUI );
// copy and empty the buffered information
*aUUI = iReceivedUUI;
iReceivedUUI.Zero();
// complete the request
ReqCompleted( aTsyReqHandle, KErrNone );
}
else
{
TFLOGSTRING("TSY: CMmCallTsy::ReceiveUUI() - wait for next incoming UUI message" );
// Save request handle and pointer of the UUI message.
iRetUUI = aUUI;
iTsyReqHandleStore->SetTsyReqHandle(
EMultimodeCallReceiveUUI, aTsyReqHandle );
}
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::ReceiveUUICancel
// Use this method to cancel a previously placed asynchronous
// EMobileCallReceiveUUI request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::ReceiveUUICancel( const TTsyReqHandle aTsyReqHandle )
{
TFLOGSTRING("TSY: CMmCallTsy::ReceiveUUICancel()");
// reset the client side pointer, empty buffer and cancel the handle
iRetUUI = NULL;
iReceivedUUI.Zero();
iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallReceiveUUI );
ReqCompleted( aTsyReqHandle, KErrCancel );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteReceiveUUI
// This method completes an outstanding ReceiveUUI request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteReceiveUUI( CMmDataPackage* aDataPackage,
TInt aResult )
{
TFLOGSTRING("TSY: CMmCallTsy::CompleteReceiveUUI()" );
RMobileCall::TMobileCallUUI* receiveUUI = NULL;
aDataPackage->UnPackData( &receiveUUI );
TFLOGSTRING2("TSY: CMmCallTsy::CompleteReceiveUUI() - receiveUUI:%S", &receiveUUI );
// reset req handle. Returns the deleted req handle
TTsyReqHandle reqHandle =
iTsyReqHandleStore->ResetTsyReqHandle( EMultimodeCallReceiveUUI );
if ( EMultimodeCallReqHandleUnknown != reqHandle )
{
TFLOGSTRING("TSY: CMmCallTsy::CompleteReceiveUUI() - Handle found, complete" );
// Update the client side data through pointer
*iRetUUI = *receiveUUI;
// Null client side pointer, data copied
iRetUUI = NULL;
// complete req
ReqCompleted( reqHandle, aResult );
}
else if ( KErrNone == aResult )
{
TFLOGSTRING("TSY: CMmCallTsy::CompleteReceiveUUI() - Handle NOT found, buffer" );
// set initial information to the buffer
iReceivedUUI = *receiveUUI;
}
}
// ---------------------------------------------------------------------------
// CMmCallTsy::SetDialTypeId
// Set iDialTypeId attribute
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::SetDialTypeId(
TUint8 aDialType )
{
iDialTypeId = aDialType;
TFLOGSTRING2("TSY: CMmCallTsy::SetDialTypeId.iDialType:%d",aDialType );
}
// ---------------------------------------------------------------------------
// CMmCallTsy::GetDialTypeId
// Returns iDialTypeId value
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TUint8 CMmCallTsy::GetDialTypeId()
{
TFLOGSTRING2("TSY: CMmCallTsy::GetDialType. iDialType:%d",iDialTypeId );
return iDialTypeId;
}
// ---------------------------------------------------------------------------
// CMmCallTsy::CompleteDialNoFdn
// Completes a Dial request.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
void CMmCallTsy::CompleteDialNoFdn(
TInt aResult )
{
TFLOGSTRING2("TSY: CMmCallTsy::CompleteDialNoFdn. Result:%d", aResult );
TFLOGSTRING3("TSY: CMmCallTsy::CompleteDialNoFdn. Call Id:%d Call name:%S", iCallId, &iCallName);
//Set dial flag to false
SetDialFlag( EFalse );
TTsyReqHandle reqHandle ( EMultimodeCallReqHandleUnknown );
// Reset req handle. Returns the deleted req handle
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();
}
//Complete request
ReqCompleted( reqHandle, aResult );
}
//Set dial type to none
SetDialTypeId( KMultimodeCallTypeDialNone );
}
// ---------------------------------------------------------------------------
// CMmCallTsy::UpdateLifeTimer
// When the last call from conference call becomes idle, we are updating
// life time duration param with remaining call duration
// ---------------------------------------------------------------------------
//
void CMmCallTsy::UpdateLifeTimer()
{
if ( iMmPhone->NumberOfActiveCalls() == 0 )
{
TTimeIntervalSeconds tis;
iMmPhone->GetAirTimeDuration(tis);
TUint32 duration;
duration = tis.Int();
duration = duration % iMmPhone->KLifeTimeUpdateInterval;
TFLOGSTRING2("TSY: CMmCallTsy::UpdateLifeTimer - \
duration: %d", duration);
//errors: trap and ignore
CMmDataPackage dataPackage;
dataPackage.PackData( &duration );
#ifdef USING_CTSY_DISPATCHER
TRAP_IGNORE(iMessageManager->HandleRequestL(
ECtsyUpdateLifeTimeReq, &dataPackage );
);
#else
TRAP_IGNORE(iMessageManager->HandleRequestL(
EMmTsyUpdateLifeTimeIPC, &dataPackage );
);
#endif //USING_CTSY_DISPATCHER
}
}
// CMmCallTsy::FillMobileCallInfoDefaults
// The method fills a current snapshot of the call information described in
// the TMobileCallInfoV1 class to the aInfo. The mode specific fields will
// be filled by the extension.
// (other items were commented in a header).
// ---------------------------------------------------------------------------
//
TInt CMmCallTsy::FillMobileCallInfoDefaults(
RMobileCall::TMobileCallInfoV1* aInfo )
{
TFLOGSTRING("TSY: CMmCallTsy::FillMobileCallInfoDefaults");
//set validity fields to 0 in the beginning.
aInfo->iValid = 0;
//The name of the call
aInfo->iCallName.Copy( iCallName );
//The name of the line on which the call is open
aInfo->iLineName.Copy( iMmLine->LineName() );
//The current status of the call
aInfo->iStatus = iMobileCallStatus;
//The time & date the call started.
TDateTime temp( iCallTimer->GetTimerStartTime()->DateTime() );
aInfo->iStartTime.Set(
temp.Year(), temp.Month(), temp.Day(),
temp.Hour(), temp.Minute(), temp.Second(), temp.MicroSecond() );
//The current duration of the call
aInfo->iDuration = GetCallDurationInSeconds();
//Set validity indication
aInfo->iValid |= RMobileCall::KCallStartTime | RMobileCall::KCallDuration;
//Client call Id. Note! Call server uses different call Id.
aInfo->iCallId = iCallId;
aInfo->iValid |= RMobileCall::KCallId;
//The reason for termination of a finished call. Will equal KErrNone if
//the call ended normally and KErrNotFound if the call has not ended.
aInfo->iExitCode = iLastExitCode;
aInfo->iValid |= RMobileCall::KCallExitCode;
//ETrue if the call is an emergency call or EFalse if it is not.
aInfo->iEmergency = iEmergencyCall;
aInfo->iValid |= RMobileCall::KCallEmergency;
TFLOGSTRING("TSY: CMmCallTsy::FillMobileCallInfoDefaults end");
return KErrNone;
}
// End of File