--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneengine/callhandling/src/cpecallhandling.cpp Mon Jan 18 20:18:27 2010 +0200
@@ -0,0 +1,2423 @@
+/*
+* 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(), 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