/*
* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: This file contains the implementation of CPECallHandling class
* member functions.
*
*/
// INCLUDE FILES
#include "cpecallhandling.h"
#include "cpevideocallhandling.h"
#include "cpesinglecall.h"
#include "cpedtmfhandling.h"
#include "cpesupplementaryservicesmonitor.h"
#include "mpephonemodelinternal.h"
#include "cpeconferencecall.h"
#include "cpecallarrayowner.h"
#include "mpecallhandling.h"
#include "cpecceobserver.h"
#include "cpesystemcallstate.h"
#include <gsmerror.h>
#include <mpedatastore.h>
#include <pepanic.pan>
#include <talogger.h>
#include <PSVariables.h>
#include <ctsydomainpskeys.h>
#include <mccecall.h>
#include <psetsaobserver.h>
#include <cccecallparameters.h>
// EXTERNAL DATA STRUCTURES
// None
// EXTERNAL FUNCTION PROTOTYPES
// None
// CONSTANTS
// None
// MACROS
// None
// LOCAL CONSTANTS AND MACROS
// MODULE DATA STRUCTURES
// None
// LOCAL FUNCTION PROTOTYPES
// None
// FORWARD DECLARATIONS
// None
// ============================= LOCAL FUNCTIONS ===============================
// None
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CPECallHandling::CPECallHandling
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CPECallHandling::CPECallHandling(
MPEPhoneModelInternal& aModel,
CCCE& aConvergedCallEngine,
MCCEDtmfInterface& aDtmfInterface
) : iModel( aModel ),
iConvergedCallEngine( aConvergedCallEngine ),
iDtmfInterface( aDtmfInterface ),
iReplaceActive( EFalse ),
iDialRequest( EFalse )
{
TEFLOGSTRING( KTAOBJECT, "CALL CPECallHandling::CPECallHandling()");
}
// Destructor
EXPORT_C CPECallHandling::~CPECallHandling()
{
TEFLOGSTRING( KTAOBJECT, "CALL CPECallHandling::~CPECallHandling() start");
delete iSystemCallState;
delete iDtmfHandling;
// No need to uninitialize feature manager - this is done in MPEPhoneModelInternal .cpp
delete iSupplementaryServicesMonitor;
delete iCCEObserver;
delete iVideoCallHandling;
delete iConferenceCall;
delete iCallArrayOwner;
delete iPsetSAObserver;
delete iCallOpenParams;
TEFLOGSTRING( KTAOBJECT, "CALL CPECallHandling::~CPECallHandling() complete");
}
// -----------------------------------------------------------------------------
// CPECallHandling::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
EXPORT_C CPECallHandling* CPECallHandling::NewL(
MPEPhoneModelInternal& aModel,
CCCE& aConvergedCallEngine,
MCCEDtmfInterface& aDtmfInterface )
{
TEFLOGSTRING( KTAOBJECT, "CALL CPECallHandling::NewL start." );
CPECallHandling* self = new (ELeave) CPECallHandling( aModel,
aConvergedCallEngine, aDtmfInterface );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
TEFLOGSTRING( KTAOBJECT, "CALL CPECallHandling::NewL complete." );
return self;
}
// -----------------------------------------------------------------------------
// CPECallHandling::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CPECallHandling::ConstructL()
{
TEFLOGSTRING( KTAOBJECT, "CALL CPECallHandling::BaseConstructL() start");
// Creates a supplementary services monitor
iSupplementaryServicesMonitor = new (ELeave) CPESupplementaryServicesMonitor(
*this, *iModel.DataStore() );
iCCEObserver = CPECCEObserver::NewL( *this, iModel );
iConvergedCallEngine.SetObserver( *iCCEObserver, *iSupplementaryServicesMonitor );
// Creates CPEDtmfSender object
iDtmfHandling = CPEDtmfHandling::NewL( *this, iDtmfInterface );
// Creates a call array owner object
iCallArrayOwner = CPECallArrayOwner::NewL(
iConvergedCallEngine,
*this );
iVideoCallHandling = CPEVideoCallHandling::NewL(
*this,
iModel,
iConvergedCallEngine,
*iCallArrayOwner );
iCallOpenParams = CCCECallParameters::NewL();
iSystemCallState = CPESystemCallState::NewL( *iCallArrayOwner, *iModel.DataStore() );
TEFLOGSTRING( KTAOBJECT, "CALL CPECallHandling::BaseConstructL() complete");
}
// -----------------------------------------------------------------------------
// CPECallHandling::SendErrorMessage
// Reroutes error messages to the Phone Engine, usable by other than call objects
// -----------------------------------------------------------------------------
//
void CPECallHandling::SendErrorMessage(
const TInt aErrorCode )
{
TEFLOGSTRING2( KTAINT,
"CALL CPECallHandling::SendErrorMessage, error code: %d",
aErrorCode );
iModel.DataStore()->SetErrorCode( aErrorCode );
iModel.SendMessage( MEngineMonitor::EPEMessageCallHandlingError );
}
// -----------------------------------------------------------------------------
// CPECallHandling::SendErrorMessage
// Reroutes error messages to the Phone Engine, usable by call objects
// -----------------------------------------------------------------------------
//
void CPECallHandling::SendErrorMessage(
const TInt aCallId,
const TInt aErrorCode )
{
TEFLOGSTRING3( KTAINT,
"CALL CPECallHandling::SendErrorMessage, error code: %d, call id: %d",
aErrorCode,
aCallId );
// Dial request failed - resume held call
if( aErrorCode == ECCPErrorInvalidFDN )
{
HandleAutoResume();
}
if ( aCallId == KPECallIdNotUsed )
{
SendErrorMessage( aErrorCode );
}
else
{
iModel.DataStore()->SetErrorCode( aErrorCode );
iModel.SendMessage( MEngineMonitor::EPEMessageCallHandlingError, aCallId );
//Handle call objet deleting if dialing fail.
if( ECCPErrorNone != aErrorCode )
{
CPESingleCall* callData = iCallArrayOwner->GetCallObject( aCallId );
if( callData )
{
TEFLOGSTRING2( KTAINT,
"CALL CPECallHandling::SendErrorMessage, call state %d", callData->GetCallState() );
if( callData->GetCallState() == EPEStateIdle )
{
ReleaseCallObject( aCallId );
iDialRequest = EFalse;
}
}
}
if( ( KPEConferenceCallID == aCallId ) && ( ECCPConferenceErrorAddCall == aErrorCode ) &&
iConferenceCall && ( iConferenceCall->EnumerateCalls() == 0 ) )
{
delete iConferenceCall;
iConferenceCall = NULL;
iModel.DataStore()->ResetCallInfo( aCallId );
}
}
}
// -----------------------------------------------------------------------------
// CPECallHandling::SendMessage
// Reroutes messages to the Phone Engine, usable by other than call objects
// -----------------------------------------------------------------------------
//
void CPECallHandling::SendMessage(
MEngineMonitor::TPEMessagesFromPhoneEngine aMessage )
{
TEFLOGSTRING2( KTAINT,
"CALL CPECallHandling::SendMessage, message id: %d", aMessage );
iModel.SendMessage( aMessage );
}
// -----------------------------------------------------------------------------
// CPECallHandling::SendMessage
// Reroutes messages to the Phone Engine, usable by call objects
// -----------------------------------------------------------------------------
//
void CPECallHandling::SendMessage(
MEngineMonitor::TPEMessagesFromPhoneEngine aMessage,
TInt aCallId )
{
TEFLOGSTRING3( KTAINT,
"CALL CPECallHandling::SendMessage, message id: %d, call id: %d",
aMessage,
aCallId );
TInt errorCode( KErrNone );
switch ( aMessage )
{
case MEngineMonitor::EPEMessageDialing:
{
iDialRequest = EFalse;
CPESingleCall* callData = iCallArrayOwner->GetCallObject( aCallId );
if( callData )
{
MCCECall& call = callData->Call();
iModel.DataStore()->SetCallIndex(call.CallIndex(), aCallId );
SetCallOrigin( aCallId, call );
}
break;
}
case MEngineMonitor::EPEMessageChangedCallDuration:
{
TTimeIntervalSeconds duration;
errorCode = GetCallDuration( duration, aCallId );
if ( errorCode == KErrNone )
{
iModel.DataStore()->SetCallDuration( duration, aCallId );
}
break;
}
case MEngineMonitor::EPEMessageIdle:
{
HandleAutoResume();
break;
}
case MEngineMonitor::EPEMessageAddedConferenceMember:
{
TName memberName;
TInt count;
errorCode = GetNumberOfParticipants( count );
TEFLOGSTRING2(
KTAMESIN,
"CALL CPECallHandling::SendMessage EPEMessageAddedConferenceMember errorCode %d",
errorCode );
if ( errorCode == KErrNone )
{
iModel.DataStore()->SetNumberOfConferenceMembers( count, KPEConferenceCallID );
iConferenceCall->GetConferenceMemberName( memberName );
if ( errorCode == KErrNone )
{
iModel.DataStore()->SetConferenceMemberInfo(
memberName,
KPEConferenceCallID,
aCallId );
iModel.DataStore()->SetCallConference( aCallId,
KPEConferenceCallID );
}
}
break;
}
case MEngineMonitor::EPEMessageDroppedConferenceMember:
{
TName memberName;
TInt memberCallId;
TInt count;
errorCode = GetNumberOfParticipants( count );
TEFLOGSTRING2(
KTAMESIN,
"CALL CPECallHandling::SendMessage EPEMessageAddedConferenceMember EPEMessageDroppedConferenceMember %d",
errorCode );
if ( errorCode == KErrNone )
{
iModel.DataStore()->SetNumberOfConferenceMembers( count, KPEConferenceCallID );
errorCode = GetConferenceMemberNameAndId( memberName,
memberCallId );
// Member has been taken to OneToOne conversation and is still alive
if ( errorCode == KErrNone )
{
iModel.DataStore()->SetConferenceMemberInfo(
memberName,
KPECallIdNotUsed,
aCallId );
iModel.DataStore()->SetCallConference(
KPENormalVoiceCall,
memberCallId );
}
else
{
// Member has been dropped and its state is idle, so no
// information can be found...
// So actually not an error situation memberName is empty
// (set in GetConferenceMemberNameAndId method)
iModel.DataStore()->SetConferenceMemberInfo(
memberName,
KPECallIdNotUsed,
aCallId );
errorCode = KErrNone;
}
}
break;
}
case MEngineMonitor::EPEMessageCallControlCapsChanged:
{
TPECallControlCaps callControlCaps;
errorCode = GetCallControlCaps( callControlCaps, aCallId );
if ( errorCode == KErrNone )
{
iModel.DataStore()->SetCallControlCaps(
callControlCaps,
aCallId );
}
break;
}
case MEngineMonitor::EPEMessageConferenceCapsChange:
{
TUint32 caps;
errorCode = GetConferenceCallCaps( caps );
if ( errorCode == KErrNone )
{
iModel.DataStore()->SetConferenceCallCaps( caps, aCallId );
}
break;
}
case MEngineMonitor::EPEMessageDisconnecting:
{
CPESingleCall* callData = iCallArrayOwner->GetCallObject( aCallId );
if ( callData )
{
TCCPTone inbandTone = callData->Tone();
iModel.DataStore()->SetInbandTone( inbandTone );
}
break;
}
case MEngineMonitor::EPEMessageConferenceErrorAddCall:
case MEngineMonitor::EPEMessageConferenceErrorRemoveCall:
case MEngineMonitor::EPEMessageConferenceErrorSwap:
case MEngineMonitor::EPEMessageConferenceErrorHold:
case MEngineMonitor::EPEMessageConferenceErrorResume:
case MEngineMonitor::EPEMessageConferenceErrorGoOneToOne:
case MEngineMonitor::EPEMessageConferenceErrorCurrentCallsToConference:
{
errorCode = KErrGeneral;
if( iConferenceCall && ( iConferenceCall->EnumerateCalls() == 0 ) )
{
delete iConferenceCall;
iConferenceCall = NULL;
}
break;
}
case MEngineMonitor::EPEMessageCallSecureStatusChanged:
{
iModel.DataStore()->SetCallSecureStatus(
IsSecureCall( aCallId ),
aCallId );
// Secure is specified
iModel.DataStore()->SetSecureSpecified( ETrue );
break;
}
case MEngineMonitor::EPEMessageSecureNotSpecified:
{
iModel.DataStore()->SetSecureSpecified( EFalse );
break;
}
case MEngineMonitor::EPEMessageRemotePartyInfoChanged:
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::SendMessage -> EPEMessageRemotePartyInfoChanged");
// HO cases call type can changes
CPESingleCall* connectedCall;
connectedCall = iCallArrayOwner->CallPointerByState( EPEStateConnected );
if( connectedCall )
{
CCPCall::TCallType callType = connectedCall->Call().Parameters().CallType();
if ( callType == CCPCall::ECallTypePS )
{
TEFLOGSTRING( KTAMESINT,
"CALL CPECallHandling::SendMessage -> EPEMessageRemotePartyInfoChanged->update call type to PS");
iModel.DataStore()->SetCallType( EPECallTypeVoIP, aCallId );
iModel.DataStore()->SetServiceIdCommand( connectedCall->Call().Parameters().ServiceId() );
iCallOpenParams->SetCallType( CCPCall::ECallTypePS);
}
else if ( callType == CCPCall::ECallTypeCSVoice )
{
TEFLOGSTRING( KTAMESINT,
"CALL CPECallHandling::SendMessage -> EPEMessageRemotePartyInfoChanged->update call type to CS");
iCallOpenParams->SetCallType( CCPCall::ECallTypeCSVoice );
iModel.DataStore()->SetServiceIdCommand( 1 );
iModel.DataStore()->SetCallType( EPECallTypeCSVoice, aCallId );
}
}
}
// Flow throught
case MEngineMonitor::EPEMessageIncoming:
{
CPESingleCall* callData = iCallArrayOwner->GetCallObject( aCallId );
if( callData )
{
MCCECall& call = callData->Call();
iModel.DataStore()->SetRemotePartyName( call.RemotePartyName(), aCallId );
iModel.DataStore()->SetRemotePhoneNumber( call.RemoteParty().Left( KPEPhoneNumberMaxLength ), aCallId );
iModel.DataStore()->SetCallIndex(call.CallIndex(), aCallId );
}
break;
}
case MEngineMonitor::EPEMessageForwardUnconditionalModeActive:
{
UpdateSaSetting();
break;
}
case MEngineMonitor::EPEMessageUnattendedTransferRequest:
{
CPESingleCall* call = iCallArrayOwner->GetCallObject( aCallId );
__ASSERT_DEBUG( NULL != call, Panic( EPEPanicIllegalCommand ) );
if ( call )
{
iModel.DataStore()->SetUnattendedTransferTarget(
call->UnattendedTransferTarget(), aCallId );
}
break;
}
case MEngineMonitor::EPEMessageALSLineChanged:
{
SetActiveLine();
break;
}
case MEngineMonitor::EPEMessageMovedPermanently:
case MEngineMonitor::EPEMessageMultipleChoices:
{
/* Incoming moved permanently request from server,
* store target addresses for later use
*/
CPESingleCall* call = iCallArrayOwner->GetCallObject( aCallId );
__ASSERT_DEBUG( NULL != call, Panic( EPEPanicIllegalCommand ) );
if ( call )
{
iModel.DataStore()->SetForwardAddressChoices(
call->ForwardAddressChoices(), aCallId );
}
break;
}
default:
// Other messages cause no action.
break;
}
if( aCallId != KPECallIdNotUsed )
{
// Preferred to be before sendmessage
// f.e active idle update before display to screen
iSystemCallState->NotifySystemCallStateChanged( aMessage, aCallId );
}
if ( errorCode )
{
SendErrorMessage( aCallId, errorCode );
}
else
{
iModel.SendMessage( aMessage, aCallId );
}
// Call obect deleting in idle state is handled here because phoneengine
// uses call object during idle state handling
if( aMessage == MEngineMonitor::EPEMessageIdle )
{
TEFLOGSTRING2( KTAINT,
"CALL CPECallHandling::SendMessage DeleteCallObject %d", aCallId );
iCallArrayOwner->DeleteCallObject( aCallId );
}
else if( aMessage == MEngineMonitor::EPEMessageConferenceIdle )
{
delete iConferenceCall;
iConferenceCall = NULL;
if ( iReplaceActive )
{
AnswerCall();
iReplaceActive = EFalse;
}
}
}
// -----------------------------------------------------------------------------
// CPECallHandling::AnswerCall
// Answers an incoming call
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::AnswerCall()
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::AnswerCall");
TInt callIndex;
CPESingleCall* callData;
CPESingleCall* connectedCall;
TInt errorCode( ECCPErrorNotFound );
callData = VoiceCallDataByState( EPEStateRinging, callIndex );
connectedCall = iCallArrayOwner->CallPointerByState( EPEStateConnected );
if( connectedCall && !iReplaceActive )
{
CCPCall::TCallType callType = connectedCall->Call().Parameters().CallType();
TEFLOGSTRING2( KTAINT,
"CALL CPECallHandling::AnswerCall EPEStateConnected type %d", callType );
if( callType == CCPCall::ECallTypeVideo )
{
TEFLOGSTRING( KTAINT,
"CALL CPECallHandling::AnswerCall ECCPErrorNotAllowed" );
return ECCPErrorNotAllowed;
}
}
if ( callData )
{
TEFLOGSTRING2( KTAINT,
"CALL CPECallHandling::AnswerCall > CPESingleCall::Answer %d",
callData->GetCallId() );
errorCode = callData->Answer();
}
else
{
TEFLOGSTRING( KTAINT,
"CALL CPECallHandling::AnswerCall > iVideoCallHandling->AnswerCall");
errorCode = iVideoCallHandling->AnswerCall();
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::DialCall
// creates dial request to the CPESingleCall object
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::DialCall(
const TPEPhoneNumber& aNumber,
TInt& aCallId )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DialCall" );
CPESingleCall* callData( NULL );
TInt errorCode( KErrNone );
// If there is allready video call, one dial in connecting, dialing or disconnecting state,
// we just ignore new dial request and send KErrInUse back to UI
if( iDialRequest )
{
// Dial request already send, waiting for dialing state.
errorCode = KErrGeneral;
TEFLOGSTRING( KTAERROR,
"CALL CPECALLHANDLING::DIALCALL ! DIAL FAILED: DIAL REQUEST ALREADY ACTIVE" );
}
else if ( IsDialAllowed ( EFalse ) )
{
// Set user to user info call params.
// Set user to user info call params.
const CCCECallParameters& params = iModel.DataStore()->CallParameters();
iCallOpenParams->SetBearer( params.Bearer() );
iCallOpenParams->SetSubAddress( params.SubAddress() );
iCallOpenParams->SetOrigin( params.Origin() );
iCallOpenParams->SetUUSId( iModel.DataStore()->UserToUserInformation() );
TRAP( errorCode, callData = OpenNewCallL( aNumber ) );
if( errorCode == KErrNone )
{
if( iModel.DataStore()->CallOriginCommand() == EPECallOriginSAT )
{
// disable number matching for SAT calls
callData->DisableFDNCheck();
}
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DialCall > Dial" );
iDialRequest = ETrue;
errorCode = callData->Dial( aNumber );
if ( errorCode != KErrNone )
{
iDialRequest = EFalse;
// Dial failed: clean up
ReleaseCallObject( callData->GetCallId() );
TEFLOGSTRING2( KTAERROR,
"CALL CPECALLHANDLING::DIALCALL ! DIAL FAILED: MAY NOT PROCEED! %d", errorCode );
}
else
{
// Dial request passed on successfully: forward new call id
aCallId = callData->GetCallId();
}
}
}
else
{
errorCode = KErrInUse;
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::DialMultimedia
// creates dial request to the CPESingleCall object
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::DialMultimedia(
const TPEPhoneNumber& aNumber,
TInt& aCallId
)
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::DialMultimedia");
TInt errorCode( ECCPErrorNone );
// If there is allready call, one dial in connecting, dialing or disconnecting state,
// we just ignore new dial request and send KErrInUse back to UI
if ( IsDialAllowed ( ETrue ) )
{
errorCode = iVideoCallHandling->DialCall( aNumber, aCallId );
}
else
{
errorCode = ECCPErrorAlreadyInUse;
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::IsDialAllowed
//
// -----------------------------------------------------------------------------
//
TBool CPECallHandling::IsDialAllowed( TBool aMultimediaDial )
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::IsDialAllowed");
CPESingleCall* call = iCallArrayOwner->CallPointerByState( EPEStateConnected );
CPESingleCall* heldCall = iCallArrayOwner->CallPointerByState( EPEStateHeld );
TBool status = EFalse;
if( ( call || heldCall ) && aMultimediaDial )
{
// A call was found when tried video call
TEFLOGSTRING( KTAERROR,
"CALL CPECALLHANDLING::IsDialAllowed() CANNOT CREATE A VIDEO CALL IN CALL STATE!");
}
else if( call && iVideoCallHandling->IsMultimedia( call->GetCallId() ) )
{
// A video call was found when tried voice or video call
TEFLOGSTRING( KTAERROR,
"CALL CPECALLHANDLING::IsDialAllowed() CANNOT CREATE A CALL IN VIDEO CALL STATE!");
}
else if( iCallArrayOwner->CallPointerByState( EPEStateDialing ) )
{
// A dialing call was found
TEFLOGSTRING( KTAERROR,
"CALL CPECALLHANDLING::IsDialAllowed() CANNOT CREATE A CALL IN DIALING STATE!");
}
else if( iCallArrayOwner->CallPointerByState( EPEStateConnecting ) )
{
// A connecting call was found
TEFLOGSTRING( KTAERROR,
"CALL CPECALLHANDLING::IsDialAllowed() CANNOT CREATE A CALL IN CONNECTING STATE!");
}
else if( iCallArrayOwner->CallPointerByState( EPEStateDisconnecting ) )
{
// A disconnecting call was found
TEFLOGSTRING( KTAERROR,
"CALL CPECALLHANDLING::IsDialAllowed() CANNOT CREATE A CALL IN DISCONNECTING STATE!");
}
else if( ( iConferenceCall && iConferenceCall->GetCallState() == EPEStateConnectedConference && ( heldCall ) ) ||
( iConferenceCall && iConferenceCall->GetCallState() == EPEStateHeldConference && ( call ) ) )
{
// coference and single call found
TEFLOGSTRING( KTAERROR,
"CALL CPECALLHANDLING::IsDialAllowed() CANNOT CREATE A CALL IN CONFERENCE AND SINGLE STATE!");
}
else
{
status = ETrue; // Dial allowed
}
return status;
}
// -----------------------------------------------------------------------------
// CPECallHandling::HangUp
// Terminates an ongoing call
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::HangUp(
TInt aCallId,
TPEHangUpOptions aAutoResumeOption )
{
TEFLOGSTRING3( KTAMESINT, "CALL CPECallHandling::HangUp aCallId= %d aAutoResumeOption= %d ", aCallId, aAutoResumeOption );
TInt errorCode( ECCPErrorNotFound );
CPESingleCall* heldcall = iCallArrayOwner->CallPointerByState( EPEStateHeld );
if( aAutoResumeOption == ETPEHangUpResumeHeldCall )
{
if( heldcall )
{
iModel.DataStore()->SetResumeHeldCall( ETrue, heldcall->GetCallId() );
}
else if( iConferenceCall && ( iConferenceCall->GetCallState() == EPEStateHeldConference ) )
{
iModel.DataStore()->SetResumeHeldCall( ETrue, KPEConferenceCallID );
}
}
else if( aAutoResumeOption == ETPEHangUpNotResumeHeldCall )
{
if( heldcall )
{
iModel.DataStore()->SetResumeHeldCall( EFalse, heldcall->GetCallId() );
}
else if( iConferenceCall && ( iConferenceCall->GetCallState() == EPEStateHeldConference ) )
{
iModel.DataStore()->SetResumeHeldCall( EFalse, KPEConferenceCallID );
}
}
if ( CallIdCheck::IsVoice( aCallId ))
{
CPESingleCall* callData = iCallArrayOwner->GetCallObject( aCallId );
if( callData )
{
// conference call that is not yet created, must be cancelled.
if( iConferenceCall && iConferenceCall->GetCallState() == EPEStateCreatingConference )
{
TEFLOGSTRING( KTAERROR,
"CPECallHandling::HangUp Delete conference call.");
delete iConferenceCall;
iConferenceCall = NULL;
}
errorCode = callData->HangUp();
}
else
{
TEFLOGSTRING( KTAERROR,
"CALL CPECALLHANDLING::HANGUP ! CALL OBJECT IN IDLE STATE OR ALREADY HANGING UP" );
}
}
else if ( CallIdCheck::IsVideo( aCallId ) )
{
errorCode = iVideoCallHandling->HangUp( aCallId );
}
else if ( CallIdCheck::IsConference( aCallId ) )
{
if( iConferenceCall )
{
errorCode = iConferenceCall->HangUp();
}
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::TerminateAllConnections
// Terminates all ringing voice and data calls
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::TerminateAllConnections()
{
CPESingleCall* callData;
TPEState callState;
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::TerminateAllConnections");
RejectCall(); // Rejects ringing call if one exists.
if ( iConferenceCall )
{
TEFLOGSTRING( KTAMESOUT,
"CALL CPECallHandling::TerminateAllConnections: Hanging Up conference call" );
iConferenceCall->HangUp();
}
// Hangup normal Voice Calls
for( TInt callId = 0; callId < KPEMaximumNumberOfVoiceCalls; callId++ )
{
callData = iCallArrayOwner->GetCallObject( callId );
if( callData )
{
callState = callData->GetCallState();
if ( callState != EPEStateIdle )
{
TEFLOGSTRING2( KTAREQOUT,
"CALL CPECallHandling::TerminateAllConnections: Hanging Up call id %d...",
callId );
callData->HangUp();
}
}
}
//Terminate all ringing data calls, connected data calls and packet data connections
return iVideoCallHandling->TerminateAllConnections();
}
// -----------------------------------------------------------------------------
// CPECallHandling::UpdatePhoneIdentity
// Method updates phone identity
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::UpdatePhoneIdentity(
MEngineMonitor::TPEMessagesFromPhoneEngine /*aMessage*/ )
{
TInt retValue( KErrNone );
CSInfo csinfo;
retValue = iConvergedCallEngine.GetCSInfo( csinfo );
TPEPhoneIdentityParameters phoneIdentityParameters;
phoneIdentityParameters.iSerialNumber = csinfo.iSerialNumber;
iModel.DataStore()->SetPhoneIdentityParameters( phoneIdentityParameters );
SendMessage( MEngineMonitor::EPEMessageShowIMEI );
return retValue;
}
// -----------------------------------------------------------------------------
// CPECallHandling::IsCallInState
// returns ETrue if there is a call in given state; otherwise EFalse
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CPECallHandling::IsCallInState( TPEState aState ) const
{
TBool isCallInState( EFalse );
iCallArrayOwner->CallPointerByState( aState ) ? isCallInState = ETrue : isCallInState = EFalse;
return isCallInState;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetCallIdByState
// returns return callid is there is a call; otherwise KPECallIdNotUsed( -1 ).
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::GetCallIdByState( TPEState aState ) const
{
TInt callId( KPECallIdNotUsed );
CPESingleCall* call = iCallArrayOwner->CallPointerByState( aState );
if( call )
{
callId = call->GetCallId();
}
TEFLOGSTRING2( KTAREQOUT,
"CALL CPECallHandling::GetCallIdByState: callid %d",
callId );
return callId;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetMissedCall
// Returns the missed voice call indicator.
// Method checks that call id is valid number
// Method gets CPECallData object from the CArrayPtrFlat and
// Method gets the missed voice call indicator from CPECallData object
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::GetMissedCall(
TBool& aMissedCall,
TInt aCallId )
{
TInt errorCode( ECCPErrorNotFound );
CPESingleCall* voiceCall = iCallArrayOwner->GetCallObject( aCallId );
if( voiceCall )
{
errorCode = voiceCall->GetMissedCall( aMissedCall );
}
else
{
__ASSERT_DEBUG( EFalse, Panic( EPEPanicIllegalCommand) );
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetCallInfo
// Returns call info
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::GetCallInfo(
RMobileCall::TMobileCallInfoV3& aCallInfo,
TInt aCallId )
{
CPESingleCall* callData;
TInt errorCode( ECCPErrorNotFound );
if ( CallIdCheck::IsVoice( aCallId ))
{
callData = iCallArrayOwner->GetCallObject( aCallId );
if( callData )
{
errorCode = callData->GetCallInfo( aCallInfo );
}
else
{
__ASSERT_DEBUG( EFalse, Panic( EPEPanicIllegalCommand) );
}
}
else if ( CallIdCheck::IsVideo( aCallId ) )
{
errorCode = iVideoCallHandling->GetCallInfo( aCallInfo, aCallId );
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetCallState
// Returns call state
// -----------------------------------------------------------------------------
//
EXPORT_C TPEState CPECallHandling::GetCallState(
TInt aCallId )
{
TPEState callState( EPEStateUnknown );
if ( CallIdCheck::IsConference( aCallId ) )
{
if( iConferenceCall )
{
callState = iConferenceCall->GetCallState();
}
else
{
callState = EPEStateConferenceIdle;
}
}
else
{
CPESingleCall* callData = iCallArrayOwner->GetCallObject( aCallId );
if( callData )
{
callState = callData->GetCallState();
}
else
{
callState = EPEStateIdle;
}
}
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::GetCallState, callState: %d", callState );
return callState;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetNumberOfCalls
// Returns number of non-idle calls
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::GetNumberOfCalls()
{
// Count ongoing calls
return iCallArrayOwner->ActiveCallCount();
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetCallDuration
// Returns voice call duration.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::GetCallDuration(
TTimeIntervalSeconds& aDuration,
TInt aCallId )
{
TInt errorCode( KErrNone );
if ( CallIdCheck::IsVoice( aCallId ))
{
CPESingleCall* callData = iCallArrayOwner->GetCallObject( aCallId );
if( callData )
{
callData->GetCallDuration( aDuration );
}
else
{
__ASSERT_DEBUG( EFalse, Panic( EPEPanicIllegalCommand) );
}
}
else if ( CallIdCheck::IsVideo( aCallId ) )
{
iVideoCallHandling->GetCallDuration( aDuration, aCallId );
}
else if ( CallIdCheck::IsConference( aCallId ) )
{
if( iConferenceCall )
{
iConferenceCall->GetCallDuration( aDuration );
errorCode = KErrNone;
}
else
{
errorCode = ECCPErrorNotFound;
}
}
else
{
errorCode = ECCPErrorNotFound;
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::RejectCall
// rejects the incoming call
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::RejectCall()
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::RejectCall");
TInt callIndex;
TInt errorCode( ECCPErrorNotFound );
CPESingleCall* callData = VoiceCallDataByState( EPEStateRinging, callIndex );
if( callIndex >= 0 )
{
callData->HangUp();
errorCode = KErrNone;
}
else
{
// Data call reject
errorCode = iVideoCallHandling->RejectCall();
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::ReleaseAll
// Release ongoing calls
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::ReleaseAll()
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::ReleaseAll");
CPESingleCall* callData;
TInt errorCode( ECCPErrorNotFound );
// Normal Voice Calls
for ( TInt callId=0; callId < KPEMaximumNumberOfVoiceCalls; callId++ )
{
callData = iCallArrayOwner->GetCallObject( callId );
if( callData &&
callData->GetCallState() != EPEStateIdle &&
callData->GetCallState() != EPEStateRinging )
{
callData->HangUp();
errorCode = KErrNone;
}
}
// Release ongoing data calls
errorCode ? errorCode = iVideoCallHandling->ReleaseAll() : iVideoCallHandling->ReleaseAll();
TEFLOGSTRING2( KTAINT, "PE CPECallHandling::ReleaseAll, error id: %d",
errorCode );
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::SendDtmf
// sends dtmf string
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::SendDtmf(
const TPEDtmfString& aDtmfString )
{
return iDtmfHandling->SendDtmfString( aDtmfString );
}
// -----------------------------------------------------------------------------
// CPECallHandling::ContinueDtmfSending
// Continues dtmf sending after 'w'-character
// -----------------------------------------------------------------------------
//
EXPORT_C void CPECallHandling::ContinueDtmfSending()
{
iDtmfHandling->ContinueDtmfSending();
}
// -----------------------------------------------------------------------------
// CPECallHandling::StartDtmfTone
// sends dtmf tone to the remote party
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::StartDtmfTone(
const TChar& aTone )
{
iDtmfHandling->StartDtmfTone(aTone);
return KErrNone;
}
// -----------------------------------------------------------------------------
// CPECallHandling::StopDtmfSending
// Stops dtmf sending after 'w'-character
// -----------------------------------------------------------------------------
//
EXPORT_C void CPECallHandling::StopDtmfSending()
{
iDtmfHandling->StopDtmfSending();
}
// -----------------------------------------------------------------------------
// CPECallHandling::StopDtmfTone
// stops sending dtmf tone to the remote party
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::StopDtmfTone()
{
iDtmfHandling->StopDtmfTone();
return KErrNone;
}
// -----------------------------------------------------------------------------
// CPECallHandling::CancelDtmfPlay
// Cancels Dtmf string sending
// -----------------------------------------------------------------------------
//
EXPORT_C void CPECallHandling::CancelDtmfPlay()
{
iDtmfHandling->CancelDtmfString();
}
// -----------------------------------------------------------------------------
// CPECallHandling::VoiceCallDataByState
// returns CPESingleCall voice call object by State
// -----------------------------------------------------------------------------
//
EXPORT_C CPESingleCall* CPECallHandling::VoiceCallDataByState(
TPEState aState,
TInt& aIndex ) const
{
aIndex = KPECallIdNotUsed;
CPESingleCall* returnValue = NULL;
if ( aState != EPEStateIdle )
{
for ( TInt callId=0; callId < KPEMaximumNumberOfVoiceCalls; callId++ )
{
CPESingleCall* callData = iCallArrayOwner->GetCallObject( callId );
if( callData )
{
if ( callData->GetCallState() == aState )
{
TEFLOGSTRING2(
KTAREQEND,
"CALL CPECallHandling::VoiceCallDataByState: , aState: %d",
aState );
TEFLOGSTRING2(
KTAREQEND,
"CALL CPECallHandling::VoiceCallDataByState: , callId: %d",
aState );
aIndex = callId;
returnValue = callData;
break;
}
}
}
}
return returnValue;
}
// -----------------------------------------------------------------------------
// From base class MPECallInitiator
// Initialises (incoming,external) voice call.
// -----------------------------------------------------------------------------
//
void CPECallHandling::InitVoiceCall( MCCECall& aNewCall )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::InitVoiceCall" );
CPESingleCall* callData( NULL );
TRAP_IGNORE( ( callData = iCallArrayOwner->CreateCallL( *this ) ) );
if ( callData )
{
iModel.DataStore()->SetPhoneNumber( KNullDesC() );
iModel.DataStore()->SetServiceId( callData->GetCallId(), aNewCall.ServiceId() );
const CCCPCallParameters& callParameters = aNewCall.Parameters();
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::InitVoiceCall call type: %d", callParameters.CallType() );
switch ( callParameters.CallType() )
{
case CCPCall::ECallTypeCSVoice:
{
iModel.DataStore()->SetCallType( EPECallTypeCSVoice, callData->GetCallId() );
// Set incoming Call's Als line
const CCCECallParameters& cceparams =
static_cast<const CCCECallParameters&> (callParameters);
iModel.DataStore()->SetCallALSLine( cceparams.LineType(), callData->GetCallId() );
}
break;
case CCPCall::ECallTypePS:
{
iModel.DataStore()->SetCallType( EPECallTypeVoIP, callData->GetCallId() );
}
break;
default:
__ASSERT_DEBUG( EFalse, Panic( EPEPanicIndexOutOfRange ));
break;
}
callData->SetCall( aNewCall );
TPECallControlCaps callControlCaps;
TInt err = GetCallControlCaps( callControlCaps, callData->GetCallId() );
if ( err == KErrNone )
{
iModel.DataStore()->SetCallControlCaps( callControlCaps, callData->GetCallId() );
}
iModel.DataStore()->SetCallSecureStatus( IsSecureCall( callData->GetCallId() ), callData->GetCallId() );
iModel.DataStore()->SetSecureSpecified( callData->SecureSpecified() );
}
else
{
Panic( EPEPanicNoFreeCalls );
}
}
// -----------------------------------------------------------------------------
// From base class MPECallInitiator
// Initialises (incoming,external) video call.
// -----------------------------------------------------------------------------
//
void CPECallHandling::InitVideoCall( MCCECall& aNewCall )
{
iVideoCallHandling->InitCall( aNewCall );
}
// -----------------------------------------------------------------------------
// CPECallHandling::ConnectedCalls
// Indicates if there is any connected calls
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CPECallHandling::ConnectedCalls()
{
TInt index;
return ( VoiceCallDataByState( EPEStateConnected, index ) ||
VoiceCallDataByState( EPEStateHeld, index ) ||
iVideoCallHandling->ConnectedCalls() );
}
// -----------------------------------------------------------------------------
// CPECallHandling::StartUp
// Starts monitoring incoming data calls
// -----------------------------------------------------------------------------
//
EXPORT_C void CPECallHandling::StartUp()
{
}
// -----------------------------------------------------------------------------
// CPECallHandling::SetCallParams
//
// -----------------------------------------------------------------------------
//
void CPECallHandling::SetCallParams( TInt aCallId )
{
iCallOpenParams->SetLineType( iActiveLine );
iModel.DataStore()->SetCallALSLine( iActiveLine, aCallId );
switch ( iModel.DataStore()->CallTypeCommand() )
{
case EPECallTypeCSVoice:
{
iCallOpenParams->SetCallType( CCPCall::ECallTypeCSVoice );
iModel.DataStore()->SetServiceIdCommand( 1 );
iModel.DataStore()->SetCallType( EPECallTypeCSVoice, aCallId );
}
break;
case EPECallTypeVideo:
{
iCallOpenParams->SetCallType( CCPCall::ECallTypeVideo);
iModel.DataStore()->SetServiceIdCommand( 1 );
iModel.DataStore()->SetCallType( EPECallTypeVideo, aCallId );
}
break;
case EPECallTypeVoIP:
{
iCallOpenParams->SetCallType( CCPCall::ECallTypePS);
iModel.DataStore()->SetCallType( EPECallTypeVoIP, aCallId );
//PhoneApp set service id in voip call case
}
break;
case EPECallTypeUninitialized:
default:
iCallOpenParams->SetCallType( CCPCall::ECallTypeCSVoice);
iModel.DataStore()->SetServiceIdCommand( 1 );
iModel.DataStore()->SetCallType( EPECallTypeCSVoice, aCallId );
break;
}
iCallOpenParams->SetServiceId( iModel.DataStore()->ServiceIdCommand() );
}
// -----------------------------------------------------------------------------
// CPECallHandling::SendMessage
// Reroutes messages to the Phone Engine
// -----------------------------------------------------------------------------
//
void CPECallHandling::SendMessage(
const MEngineMonitor::TPEMessagesFromPhoneEngine aMessage,
const TName& aName )
{
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::SendMessage, message id: %d", aMessage );
TInt callId( KPECallIdNotUsed );
MPECall* call = iCallArrayOwner->CallByName( aName );
if( call )
{
callId = call->GetCallId();
}
SendMessage( aMessage, callId );
}
// -----------------------------------------------------------------------------
// CPECallHandling::HandleInternalMessage
// Reroutes messages to the Phone Engine
// -----------------------------------------------------------------------------
//
void CPECallHandling::HandleInternalMessage(
TInt aMessage )
{
iModel.HandleInternalMessage( aMessage );
}
// -----------------------------------------------------------------------------
// CPECallHandling::OpenNewCallL
// returns ETrue if hangup active
// -----------------------------------------------------------------------------
//
CPESingleCall* CPECallHandling::OpenNewCallL( const TPEPhoneNumber& aNumber )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::OpenNewCallL");
TInt errorCode( KErrNone );
CPESingleCall* callData( NULL );
MCCECall* cceCall( NULL );
callData = iCallArrayOwner->CreateCallL( *this );
SetCallParams( callData->GetCallId() );
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::OpenNewCallL > CCCE::OpenNewCallL");
TRAP( errorCode,
cceCall = &( iConvergedCallEngine.OpenNewCallL( aNumber,
*iCallOpenParams,
*callData ) ) );
if ( errorCode == KErrNone )
{
callData->SetCall( *cceCall );
iModel.DataStore()->SetServiceId( callData->GetCallId(), cceCall->ServiceId() );
iModel.DataStore()->SetCallSecureStatus( callData->IsSecureCall(), callData->GetCallId() );
iModel.DataStore()->SetSecureSpecified( callData->SecureSpecified() );
TPECallControlCaps callControlCaps;
TInt err = GetCallControlCaps( callControlCaps, callData->GetCallId() );
if ( err == KErrNone )
{
iModel.DataStore()->SetCallControlCaps( callControlCaps, callData->GetCallId() );
}
}
else
{
// Open new call failed
ReleaseCallObject( callData->GetCallId() );
TEFLOGSTRING2( KTAERROR,
"CALL CPECALLHANDLING::OPENNEWCALLL ! OPENNEWCALL FAILED: MAY NOT PROCEED! %d", errorCode );
User::Leave( errorCode );
}
return callData;
}
// -----------------------------------------------------------------------------
// CPECallHandling::SetActiveLine
// Sets active line
// -----------------------------------------------------------------------------
//
EXPORT_C void CPECallHandling::SetActiveLine()
{
TEFLOGSTRING( KTAINT, "PE CPECallHandling::SetActiveLine" );
iActiveLine = iModel.DataStore()->ALSLine();
}
// -----------------------------------------------------------------------------
// CPECallHandling::IsSecureCall
// Returns the call secure status
// -----------------------------------------------------------------------------
//
TBool CPECallHandling::IsSecureCall( const TInt aCallId ) const
{
TEFLOGSTRING2(
KTAINT,
"PE CPECallHandling::IsSecureCall: aCallId = %d",
aCallId );
CPESingleCall* call = iCallArrayOwner->GetCallObject( aCallId );
__ASSERT_DEBUG( call, Panic( EPEPanicIndexOutOfRange ) );
TBool secured( EFalse );
if( call )
{
secured = call->IsSecureCall();
}
return secured;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetNumberOfParticipants
// returns number of conference members
// -----------------------------------------------------------------------------
//
TInt CPECallHandling::GetNumberOfParticipants(
TInt& aCount ) // The Number of participants
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::GetNumberOfParticipants" );
TInt errorCode( ECCPErrorNotFound );
if ( iConferenceCall )
{
aCount = iConferenceCall->EnumerateCalls();
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::GetNumberOfParticipants count %d", aCount );
errorCode = KErrNone;
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetConferenceMemberNameAndId
// Returns added or removeds members TName information and CallId.
// -----------------------------------------------------------------------------
//
TInt CPECallHandling::GetConferenceMemberNameAndId(
TName& aCallName, // Added or removed members TName information is returned here
TInt& aMemberCallId ) // Added or removed members callid is returned here
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::GetConferenceMemberNameAndId" );
TInt errorCode( ECCPErrorNotFound );
if ( iConferenceCall )
{
iConferenceCall->GetConferenceMemberName( aCallName );
MPECall* call = iCallArrayOwner->CallByName( aCallName );
if( call )
{
aMemberCallId = call->GetCallId();
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::GetConferenceMemberNameAndId CallId %d", aMemberCallId );
errorCode = KErrNone;
}
else
{
aMemberCallId = -1;
aCallName = KNullDesC;
}
}
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::GetConferenceMemberNameAndId errorCode %d", errorCode );
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetCallControlCaps
// returns call info
// Method checks that call id is valid number
// Method gets CPESingleCall object from the CArrayPtrFlat and
// Method gets call info from CPESingleCall object
// -----------------------------------------------------------------------------
//
TInt CPECallHandling::GetCallControlCaps(
TPECallControlCaps& aCallControlCaps,
TInt aCallId )
{
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::GetCallControlCaps %d", aCallId );
CPESingleCall* callData;
TInt errorCode( ECCPErrorNotFound );
MCCECallObserver::TCCECallControlCaps callControlCaps;
callData = iCallArrayOwner->GetCallObject( aCallId );
if ( callData )
{
callData->GetCallControlCaps( callControlCaps );
aCallControlCaps = static_cast<TPECallControlCaps>( callControlCaps );
errorCode = KErrNone;
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetConferenceCallCaps
// returns conference call capabilities
// Checks that call id is valid and gets CPEConferenceCall object and calls its method
// to get capabilities
// -----------------------------------------------------------------------------
//
TInt CPECallHandling::GetConferenceCallCaps(
TUint32& aCaps ) // capabilities are returned in this parameter
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::GetConferenceCallCaps" );
TInt errorCode( ECCPErrorNotFound );
if ( iConferenceCall )
{
aCaps = iConferenceCall->CallCaps();
errorCode = KErrNone;
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::AddMember
// Adds member to the conference call
// -----------------------------------------------------------------------------
//
TInt CPECallHandling::AddMember(
TInt aCallId )
{
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::AddMember %d", aCallId );
TInt errorCode( KErrNone );
TRAP( errorCode, AddMemberL( aCallId ));
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::AddMemberL
// Adds member to the conference call
// -----------------------------------------------------------------------------
//
void CPECallHandling::AddMemberL(
TInt aCallId )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::AddMemberL" );
CPESingleCall* callData;
callData = iCallArrayOwner->GetCallObject( aCallId );
if ( callData && iConferenceCall && CallIdCheck::IsVoice( aCallId ))
{
iConferenceCall->AddCallL( callData->Call() );
}
else
{
User::Leave( ECCPErrorNotFound );
}
}
// -----------------------------------------------------------------------------
// CPECallHandling::CallTerminatedError
// Handles RemoteTerminated.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::CallTerminatedError(
const TInt aCallId )
{
TInt errorCode( KErrNone );
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::CallTerminatedError" );
CPESingleCall* callObject = iCallArrayOwner->GetCallObject( aCallId );
if ( callObject )
{
callObject->GetErrorCode( errorCode );
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::BuildConference
// creates conference call
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::BuildConference()
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::BuildConference" );
TInt heldcallid;
CPESingleCall* heldcall( NULL );
TInt connectedcallid;
CPESingleCall* connectedcall( NULL );
TInt errorCode( ECCPErrorNotAllowed );
heldcall = VoiceCallDataByState( EPEStateHeld, heldcallid );
if ( heldcall )
{
connectedcall = VoiceCallDataByState( EPEStateConnected, connectedcallid );
if ( connectedcall )
{
TRAP( errorCode, CreateConferenceCallL( *heldcall, *connectedcall ) );
}
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::SwapCalls
// resumes a held call
// Method search active and held call
// Method gets CPESingleCall object from the CArrayPtrFlat and
// Method checks that call is in held state
// Method makes swap request to CPESingleCall object.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::SwapCalls()
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::SwapCalls" );
TInt callIndex;
CPESingleCall* callData;
TInt errorCode( ECCPErrorNotFound );
if ( ( iConferenceCall ) &&
( iConferenceCall->GetCallState() == EPEStateConnectedConference ) )
{
errorCode = iConferenceCall->Swap();
}
else
{
callData = VoiceCallDataByState( EPEStateConnected, callIndex );
if( callData )
{
errorCode = callData->Swap();
}
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::AddConferenceMember
// Handles add conference member
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::AddConferenceMember()
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::AddConferenceMember" );
CPESingleCall* callData;
TInt errorCode( ECCPErrorNotFound );
TPEState callState;
// Checks that call is single call and state of call is connected or held
for( TInt callId = 0; callId < KPEMaximumNumberOfVoiceCalls; callId++ )
{
callData = iCallArrayOwner->GetCallObject( callId );
if( callData )
{
// Check that call is not already join to Conference
if ( iModel.DataStore()->IsConferenceMemberId( callId ) == KPECallIdNotUsed )
{
callState = callData->GetCallState();
if ( callState == EPEStateConnected || callState == EPEStateHeld )
{
TEFLOGSTRING2( KTAINT,
"CALL CPECallHandling::AddConferenceMember > AddMember, CallId = %d"
, callId );
errorCode = AddMember( callId );
break;
}
}
}
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::DropMember
// drops member from the conference call
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::DropMember(
TInt aCallId )
{
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::DropMember %d", aCallId );
CPESingleCall* callData;
TInt errorCode( ECCPErrorNotFound );
if ( CallIdCheck::IsVoice( aCallId ))
{
callData = iCallArrayOwner->GetCallObject( aCallId );
if ( callData )
{
callData->HangUp();
errorCode = KErrNone;
}
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::GoOneToOne
// Splits one call to private conversation.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::GoOneToOne(
TInt aCallId )
{
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::GoOneToOne %d", aCallId );
TInt errorCode( ECCPErrorNotFound );
CPESingleCall* callData;
callData = iCallArrayOwner->GetCallObject( aCallId );
if ( iConferenceCall && callData )
{
TRAP( errorCode, iConferenceCall->GoOneToOneL( callData->Call() ) );
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::HoldCall
// holds an active call
// Method checks that call id is valid number and
// Method gets CPESingleCall object from the CArrayPtrFlat and
// Method checks that call is in connected state
// Method makes hold request to CPESingleCall object.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::HoldCall()
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::HoldCall" );
CPESingleCall* callData;
TInt callIndex;
TInt errorCode( ECCPErrorNotAllowed );
if ( iConferenceCall && ( iConferenceCall->GetCallState() == EPEStateConnectedConference ) )
{
// hold was explicitly requested by the user,
// update information to engine info
iModel.DataStore()->SetResumeHeldCall( EFalse, KPEConferenceCallID );
errorCode = iConferenceCall->Swap();
}
else
{
callData = VoiceCallDataByState( EPEStateConnected, callIndex );
if( callData )
{
// hold was explicitly requested by the user,
// update information to engine info
iModel.DataStore()->SetResumeHeldCall( EFalse, callIndex );
errorCode = callData->Hold();
}
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::ResumeCall
// resumes a held call
// Method checks that call id is valid number and
// Method gets CPESingleCall object from the CArrayPtrFlat and
// Method checks that call is in held state
// Method makes resume request to CPESingleCall object.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::ResumeCall()
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::ResumeCall" );
CPESingleCall* callData;
TInt callIndex;
TInt errorCode( ECCPErrorNotAllowed );
if ( iConferenceCall && ( iConferenceCall->GetCallState() == EPEStateHeldConference ) )
{
// resume was explicitly requested by the user, update information to engine info
iModel.DataStore()->SetResumeHeldCall( ETrue, KPEConferenceCallID );
errorCode = iConferenceCall->Swap();
}
else
{
callData = VoiceCallDataByState( EPEStateHeld, callIndex );
if( callData )
{
// resume was explicitly requested by the user, update information to engine info
iModel.DataStore()->SetResumeHeldCall( ETrue, callIndex );
errorCode = callData->Resume();
}
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::TransferCalls
// transfers the held party to the active party
// Method search active and held call
// Method gets CPESingleCall object from the CArrayPtrFlat and
// Method checks that call is in held state
// Method makes transfer request to CPESingleCall object.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::TransferCalls()
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::TransferCalls" );
TInt callIndex;
CPESingleCall* callData;
CPESingleCall* callDataHeld;
TInt errorCode( ECCPErrorNotAllowed );
callDataHeld = VoiceCallDataByState( EPEStateHeld, callIndex );
if( callDataHeld && !iConferenceCall )
{ // found one held call
callData = VoiceCallDataByState( EPEStateConnected, callIndex );
if ( callData ) // found the connected call
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::TransferCalls > Transfer" );
callDataHeld->Transfer( callData->Call().DialledParty() );
errorCode = KErrNone;
}
else
{
callData = VoiceCallDataByState( EPEStateConnecting, callIndex );
if ( callData ) // The connecting call found
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::TransferCalls > Transfer" );
callDataHeld->Transfer( callData->Call().DialledParty() );
errorCode = KErrNone;
}
}
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::DialEmergencyCall
// creates emergency dial request to the CPESingleCall object
// Method gets CPESingleCall object from the CArrayPtrFlat
// Method makes emergency dial request
// -----------------------------------------------------------------------------
//
EXPORT_C void CPECallHandling::DialEmergencyCall( const TPEPhoneNumber& aEmergencyNumber )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DialEmergencyCall" );
SendMessage( MEngineMonitor::EPEMessageInitiatedEmergencyCall );
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DialEmergencyCall start emergency dialing" );
CPESingleCall* callData = iCallArrayOwner->GetCallObject( KPEEmergencyCallId );
callData->DialEmergency( aEmergencyNumber );
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetCallTerminatedDiagnostics
// Returns call terminated diagnostics of a call
// Method returns valid info only after call state has changed to Idle.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::GetCallTerminatedDiagnostics(
TName& /*aCallName*/ ) const
{
TInt diagnosticsInfo = 0/*iCustomAPI.GetDiagnosticInfo( aCallName )*/;
TEFLOGSTRING2( KTAMESIN,
"CALL CPECallHandling::GetCallTerminatedDiagnostics: RMmCustomAPI::GetDiagnosticInfo, diagnosticInfo: %d",
diagnosticsInfo );
return diagnosticsInfo;
}
// -----------------------------------------------------------------------------
// CPECallHandling::CreateConferenceCallL
// -----------------------------------------------------------------------------
//
void CPECallHandling::CreateConferenceCallL(
CPESingleCall& aCall1,
CPESingleCall& aCall2 )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::CreateConferenceCallL start" );
if( !iConferenceCall )
{
iConferenceCall = CPEConferenceCall::NewL( *this, iConvergedCallEngine );
iConferenceCall->SetCallId( KPEConferenceCallID );
iConferenceCall->AddCallL( aCall1.Call() );
iConferenceCall->AddCallL( aCall2.Call() );
InitialiseConferenceCallInfo( aCall1.Call(), aCall2.Call() );
}
else
{
TEFLOGSTRING( KTAERROR, "CALL CPECallHandling::CreateConferenceCallL already exist" );
User::Leave( KErrAlreadyExists );
}
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::CreateConferenceCallL end" );
}
// -----------------------------------------------------------------------------
// CPECallHandling::GetLifeTime
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CPECallHandling::GetLifeTime( TDes8& aLifeTimeInfo )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::GetLifeTime" );
return iConvergedCallEngine.GetLifeTime( aLifeTimeInfo );
}
// -----------------------------------------------------------------------------
// CPECallHandling::UpdateSaSetting
// -----------------------------------------------------------------------------
//
void CPECallHandling::UpdateSaSetting()
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::UpdateSaSetting start" );
TUnconditionalCFStatus status( KCFIndicatorUnknown );
TSelectedLine line( ENotSupportedLine );
CCCECallParameters::TCCELineType lineType( CCCECallParameters::ECCELineTypePrimary );
CPESingleCall* call( NULL );
TCallDivertNotifySetting notifySet;
notifySet.Initialize();
notifySet.iCfActivated = ETrue;
// Get dialing call object
call = iCallArrayOwner->CallPointerByState( EPEStateDialing );
// Determinate als support and used line
lineType = iModel.DataStore()->ALSLine();
if( iModel.DataStore()->ALSLineSupport() )
{
if( CCCECallParameters::ECCELineTypePrimary == lineType )
{
line = EPrimaryLine;
}
else
{
line = EAuxiliaryLine;
}
}
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::UpdateSaSetting line %d", line );
// Determinate basic service code
notifySet.iBasicServiceCode = DefineDivertBsc( lineType, call );
// Create phonesetting connection
if( !iPsetSAObserver )
{
TRAPD( errorCode, iPsetSAObserver = CPsetSAObserver::NewL() );
if( errorCode != KErrNone )
{
TEFLOGSTRING2(
KTAERROR,
"CALL CPECallHandling::UpdateSaSetting FAIL with error %d",
errorCode );
return;
}
}
// Get diver status
TInt error = iPsetSAObserver->GetCurrentDivertStatus( status );
if ( error != KErrNone )
{
status = KCFNoCallsForwarded;
}
notifySet.iPreviousCfStatus = status;
// Update dovert indicator.
iPsetSAObserver->NotifyDivertChange(
line,
notifySet,
0 );
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::UpdateSaSetting end" );
}
// -----------------------------------------------------------------------------
// CPECallHandling::DefineDivertBsc
// -----------------------------------------------------------------------------
//
TInt CPECallHandling::DefineDivertBsc( CCCECallParameters::TCCELineType aLineType,
CPESingleCall* call )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DefineDivertBsc start" );
TInt bsc( EAllTele );
if ( !call )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DefineDivertBsc EUnknown" );
bsc = EUnknown;
return bsc;
}
else if ( call->Call().Parameters().CallType() == CCPCall::ECallTypeVideo )
{
// If initiated call is video set bsc as ESyncData.
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DefineDivertBsc ESyncData" );
bsc = ESyncData;
return bsc;
}
switch ( aLineType )
{
case CCCECallParameters::ECCELineTypePrimary:
// Call is done using line 1.
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DefineDivertBsc EAllTele" );
bsc = EAllTele;
break;
case CCCECallParameters::ECCELineTypeAux:
// Call is done using line 2.
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DefineDivertBsc EAltTele" );
bsc = EAltTele;
break;
default:
// Defauld case no alternate line service.
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DefineDivertBsc EAllTele default" );
bsc = EAllTele;
break;
}
TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::DefineDivertBsc end, bsc = %d", bsc );
return bsc;
}
// -----------------------------------------------------------------------------
// CPECallHandling::ReplaceActive
// Terminates an active call and answer waiting call
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::ReplaceActive()
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::ReplaceActive");
TInt errorCode( ECCPErrorNotFound );
TInt callIdConnected = KPECallIdNotUsed;
CPESingleCall* replacingcall = iCallArrayOwner->CallPointerByState( EPEStateRinging );
if( iConferenceCall && iConferenceCall->GetCallState() == EPEStateConnectedConference )
{
callIdConnected = iConferenceCall->GetCallId();
}
else
{
CPESingleCall* connectedcall = iCallArrayOwner->CallPointerByState( EPEStateConnected );
if ( connectedcall )
{
callIdConnected = connectedcall->GetCallId();
}
}
if ( callIdConnected != KPECallIdNotUsed && replacingcall )
{
if( CallIdCheck::IsConference( callIdConnected ) || CallIdCheck::IsVoice( callIdConnected ) )
{
iReplaceActive = ETrue;
errorCode = HangUp( callIdConnected , ETPEHangUpNotResumeHeldCall );
TEFLOGSTRING2( KTAMESINT, "CALL CPECallHandling::ReplaceActive HangUp error %d", errorCode );
if ( !CallIdCheck::IsConference( callIdConnected ) && errorCode == KErrNone ) // Conference replace when idle
{
errorCode = AnswerCall();
iReplaceActive = EFalse;
TEFLOGSTRING2( KTAMESINT, "CALL CPECallHandling::ReplaceActive AnswerCall error %d", errorCode );
}
else if ( errorCode != KErrNone )
{
iReplaceActive = EFalse;
}
}
else
{
errorCode = iVideoCallHandling->ReplaceActive( callIdConnected );
TEFLOGSTRING2( KTAMESINT, "CALL CPECallHandling::ReplaceActive DataCallHandling::ReplaceActive error %d", errorCode );
}
}
else
{
TEFLOGSTRING( KTAERROR, "CALL CPECALLHANDLING::REPLACEACTIVE ! CALL OBJECT NOT FOUND" );
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::AcceptUnattendedTransfer
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::AcceptUnattendedTransfer()
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::AcceptUnattendedTransfer" );
TInt callId = iModel.DataStore()->CallId();
CPESingleCall* call = iCallArrayOwner->GetCallObject( callId );
__ASSERT_DEBUG( NULL != call, Panic( EPEPanicIllegalCommand ) );
if ( NULL != call )
{
return call->AcceptUnattendedTransfer();
}
else
{
return KErrNotFound;
}
}
// -----------------------------------------------------------------------------
// CPECallHandling::RejectUnattendedTransfer
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::RejectUnattendedTransfer()
{
TEFLOGSTRING( KTAMESINT, "CALL CPECallHandling::RejectUnattendedTransfer" );
TInt callId = iModel.DataStore()->CallId();
CPESingleCall* call = iCallArrayOwner->GetCallObject( callId );
__ASSERT_DEBUG( NULL != call, Panic( EPEPanicIllegalCommand ) );
if ( NULL != call )
{
return call->RejectUnattendedTransfer();
}
else
{
return KErrNotFound;
}
}
// -----------------------------------------------------------------------------
// CPECallHandling::DoUnattendedTransfer
// Does unattended transfer request for the connected VoIP call
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::DoUnattendedTransfer( const TDesC& aTransferTarget )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::DoUnattendedTransfer" );
CPESingleCall* callData;
TInt callIndex;
TInt errorCode( ECCPErrorNotAllowed );
callData = VoiceCallDataByState( EPEStateConnected, callIndex );
if( callData )
{
errorCode = callData->UnattendedTransfer( aTransferTarget );
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::ForwardCallToAddress
// Forwards call by user selected address
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CPECallHandling::ForwardCallToAddress( TInt aIndex )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::ForwardCallToAddress" );
CPESingleCall* callData;
TInt callIndex;
TInt errorCode( ECCPErrorNotAllowed );
callData = VoiceCallDataByState( EPEStateDialing, callIndex );
if ( NULL == callData )
{
callData = VoiceCallDataByState( EPEStateConnecting, callIndex );
}
if ( NULL == callData )
{
callData = VoiceCallDataByState( EPEStateConnected, callIndex );
}
if( callData )
{
errorCode = callData->ForwardCallToAddress( aIndex );
}
return errorCode;
}
// -----------------------------------------------------------------------------
// CPECallHandling::SecureSpecified
// Returns the call secure specified status
// -----------------------------------------------------------------------------
//
TBool CPECallHandling::SecureSpecified( const TInt aCallId ) const
{
CPESingleCall* call = iCallArrayOwner->GetCallObject( aCallId );
__ASSERT_DEBUG( call, Panic( EPEPanicIndexOutOfRange ) );
TBool secureSpecified( ETrue );
if( call )
{
secureSpecified = call->SecureSpecified();
}
TEFLOGSTRING3(
KTAINT,
"PE CPECallHandling::SecureSpecified securespecified:%d aCallId:%d",
secureSpecified, aCallId );
return secureSpecified;
}
// -----------------------------------------------------------------------------
// CPECallHandling::InitConferenceCall
// -----------------------------------------------------------------------------
//
void CPECallHandling::InitConferenceCall( MCCEConferenceCall& aConference )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::InitConferenceCall start" );
if( iConferenceCall )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::InitConferenceCall already exist" );
delete iConferenceCall;
iConferenceCall = NULL;
}
TRAPD( error, ( iConferenceCall = CPEConferenceCall::NewL( *this, aConference ) ) );
if( error != KErrNone )
{
SendMessage( MEngineMonitor::EPEMessageConferenceErrorCurrentCallsToConference );
RPointerArray<MCCECall> callArray;
TInt err = aConference.GetCallArray( callArray );
for( TInt index = 0 ; index < callArray.Count() ; index++ )
{
TRAP_IGNORE( aConference.RemoveCallL( *callArray[index] ) );
}
aConference.Release();
callArray.Close();
TEFLOGSTRING( KTAERROR, "CALL CPECallHandling::InitConferenceCall FAIL" );
}
else
{
iConferenceCall->SetCallId( KPEConferenceCallID );
RPointerArray<MCCECall> callArray;
TInt err = aConference.GetCallArray( callArray );
if( err == KErrNone && callArray.Count() >= 2 )
{
InitialiseConferenceCallInfo( *callArray[0], *callArray[1] );
iConferenceCall->CallStateChanged( MCCEConferenceCallObserver::ECCEConferenceActive );
}
callArray.Close();
}
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::InitConferenceCall end" );
}
// -----------------------------------------------------------------------------
// CPECallHandling::CallOwner
// -----------------------------------------------------------------------------
//
EXPORT_C MPECallOwner& CPECallHandling::CallOwner() const
{
return *iCallArrayOwner;
}
// -----------------------------------------------------------------------------
// CPECallHandling::InitialiseConferenceCallInfo
// -----------------------------------------------------------------------------
//
void CPECallHandling::InitialiseConferenceCallInfo(
MCCECall& aCall1,
MCCECall& aCall2 )
{
TTimeIntervalSeconds call1Duration, call2Duration;
call1Duration = aCall1.CallDuration();
call2Duration = aCall2.CallDuration();
// Set conference call duration to match the longest running call.
// If this is not done, zero call duration is shown in case the
// conference call fails or user rejects it instantly
// --- See CPEGsmMessageHandler::HandleConferenceIdleState how
// the duration is handled in these scenarios.
if ( call1Duration > call2Duration )
{
iModel.DataStore()->SetCallDuration( call1Duration.Int(), KPEConferenceCallID );
}
else
{
iModel.DataStore()->SetCallDuration( call2Duration.Int(), KPEConferenceCallID );
}
if ( aCall1.Parameters().CallType()
== CCPCall::ECallTypeCSVoice )
{
iModel.DataStore()->SetCallType( EPECallTypeCSVoice, KPEConferenceCallID );
}
else if ( aCall1.Parameters().CallType()
== CCPCall::ECallTypePS )
{
iModel.DataStore()->SetCallType( EPECallTypeVoIP, KPEConferenceCallID );
}
__ASSERT_DEBUG( aCall1.ServiceId() == aCall2.ServiceId(),
Panic( EPEPanicInvalidParameter ) );
iModel.DataStore()->SetServiceId( KPEConferenceCallID, aCall1.ServiceId() );
}
// -----------------------------------------------------------------------------
// CPECallHandling::HandleAutoResume
// -----------------------------------------------------------------------------
//
void CPECallHandling::HandleAutoResume()
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::HandleAutoResume" );
if ( iConferenceCall && ( iConferenceCall->GetCallState() == EPEStateHeldConference ) )
{
// Check that no conference + single case
CPESingleCall* callData = iCallArrayOwner->CallPointerByState( EPEStateConnected );
if( !callData && iModel.DataStore()->ResumeHeldCall( KPEConferenceCallID ))
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::HandleAutoResume conference" );
iConferenceCall->Swap();
}
}
else
{
CPESingleCall* callData = iCallArrayOwner->CallPointerByState( EPEStateHeld );
// Check that no actice and held call, if waiting call gets idle
CPESingleCall* connectedCallData = iCallArrayOwner->CallPointerByState( EPEStateConnected );
if( callData && ( iModel.DataStore()->ResumeHeldCall( callData->GetCallId() ) )
&& !connectedCallData )
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::HandleAutoResume single" );
callData->Resume();
}
}
}
// -----------------------------------------------------------------------------
// CPECallHandling::ReleaseCallObject
// -----------------------------------------------------------------------------
//
TInt CPECallHandling::ReleaseCallObject( const TInt aCallId )
{
TInt error(KErrNone);
TEFLOGSTRING2( KTAINT,
"CALL CPECallHandling::ReleaseCallObject ReleaseCallObject %d", aCallId );
error = iCallArrayOwner->DeleteCallObject( aCallId );
// Reset datastore to prevent invalid usage in next call
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::ReleaseCallObject, Reset CallInfo" );
iModel.DataStore()->ResetCallInfo( aCallId );
return error;
}
// -----------------------------------------------------------------------------
// CPECallHandling::SetCallOrigin
// -----------------------------------------------------------------------------
//
void CPECallHandling::SetCallOrigin( const TInt aCallId, const MCCECall& aCall ) const
{
TEFLOGSTRING( KTAINT, "CALL CPECallHandling::SetCallOrigin" );
//ToDo: casting not needed when CCE API is fixed.
const CCCPCallParameters& parameters = aCall.Parameters();
CCPCall::TCallType callType = parameters.CallType();
if ( callType == CCPCall::ECallTypeCSVoice || callType == CCPCall::ECallTypeVideo )
{
const CCCECallParameters& params = static_cast<const CCCECallParameters&>( parameters );
// do not overwrite if it's client call, which CCE is not aware of
if ( iModel.DataStore()->CallOrigin( aCallId ) == EPECallOriginPhone )
{
if ( params.Origin() == CCCECallParameters::ECCECallOriginSAT )
{
iModel.DataStore()->SetCallOrigin( EPECallOriginSAT, aCallId );
}
}
}
}
// End of File