phoneengine/callhandling/src/cpevideocallhandling.cpp
changeset 0 5f000ab63145
child 21 92ab7f8d0eab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneengine/callhandling/src/cpevideocallhandling.cpp	Mon Jan 18 20:18:27 2010 +0200
@@ -0,0 +1,995 @@
+/*
+* Copyright (c) 2002-2007 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 implementation of CPEVideoCallHandling class.
+*
+*/
+
+
+// INCLUDE FILES
+#include "cpevideocallhandling.h"
+#include "cpesinglecall.h"
+#include "pevirtualengine.h"
+#include "cpecallarrayowner.h"
+#include "cpecallarrayowner.h"
+#include "cpegprstermination.h"
+
+#include <mpephonemodelinternal.h>
+#include <e32property.h>
+#include <gsmerror.h>
+#include <mpedatastore.h>
+#include <NetworkHandlingDomainPSKeys.h>
+#include <pepanic.pan>
+#include <pevirtualengine.h>
+#include <talogger.h>
+#include <ctsydomainpskeys.h>
+#include <connect/sbdefs.h>
+#include <ccce.h>
+#include <mccecall.h>
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::CPEVideoCallHandling
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPEVideoCallHandling::CPEVideoCallHandling(
+        MPEMessageSender& aOwner,
+        MPEPhoneModelInternal& aModel,        
+        CCCE& aConvergedCallEngine,
+        CPECallArrayOwner& aCallArrayOwner
+        ) : iOwner( aOwner ),
+            iModel( aModel ),
+            iConvergedCallEngine( aConvergedCallEngine ),
+            iDataCallName( KNullDesC ),
+            iCallArrayOwner( aCallArrayOwner ),
+            iDataStore( *( aModel.DataStore( ) ) ),
+            iRestoreCauseVTCallReject( EFalse )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPEVideoCallHandling::ConstructL()
+    {
+    TEFLOGSTRING( KTAOBJECT, "VID CPEVideoCallHandling::ConstructL start." );
+
+    iCallOpenParams = CCCECallParameters::NewL();
+    TEFLOGSTRING( KTAOBJECT, "VID CPEVideoCallHandling::ConstructL complete." );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CPEVideoCallHandling* CPEVideoCallHandling::NewL(
+        MPEMessageSender& aOwner,
+        MPEPhoneModelInternal& aModel,         
+        CCCE& aConvergedCallEngine,
+        CPECallArrayOwner& aCallArrayOwner )
+    {
+    TEFLOGSTRING( KTAOBJECT, "VID CPEVideoCallHandling::NewL start." );
+    CPEVideoCallHandling* self = new ( ELeave ) CPEVideoCallHandling( aOwner, 
+                                                                      aModel, 
+                                                                      aConvergedCallEngine,
+                                                                      aCallArrayOwner );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    TEFLOGSTRING( KTAOBJECT, "VID CPEVideoCallHandling::NewL complete." );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::~CPEVideoCallHandling()
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CPEVideoCallHandling::~CPEVideoCallHandling()
+    {
+    TFLOGSTRING( "CallHandling: CPEVideoCallHandling::~CPEVideoCallHandling() Start");
+    delete iGprsInterface;
+    iGprsInterface = NULL;
+    delete iCallOpenParams;
+    TFLOGSTRING( "CallHandling: CPEVideoCallHandling::~CPEVideoCallHandling() complete");
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::AnswerCall
+// Answers the incoming call
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::AnswerCall()
+    {
+    TEFLOGSTRING( KTAINT, "VID CPEVideoCallHandling::AnswerCall");
+    TInt errorCode( KErrNotFound );
+    CPESingleCall* dataCallData = VideoCallByState( EPEStateRinging );
+    if ( dataCallData )
+        {
+        if ( GetNumberOfCalls() == 1 )
+            {
+            TEFLOGSTRING( KTAINT, "VID CPEVideoCallHandling::AnswerCall > CPEDataCall::Answer" );
+            dataCallData->Answer();
+            errorCode = KErrNone;
+            }
+        else
+            {
+            TEFLOGSTRING( KTAERROR, 
+                    "VID CPEVIDEOCALLHANDLING::ANSWERCALL: NOT ALLOWED WITH EXISTING CALLS!" );
+            errorCode = ECCPErrorNotAllowed;
+            }
+        }
+    else
+        {
+        TEFLOGSTRING( KTAERROR, 
+                "VID CPEVIDEOCALLHANDLING::ANSWERCALL: NO RINGING CALLS FOUND!" );
+        }
+
+    return errorCode;
+    }
+    
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::VideoCallByState
+// Finds a data call object that is in specified  state
+// -----------------------------------------------------------------------------
+//  
+CPESingleCall* CPEVideoCallHandling::VideoCallByState( 
+        const TPEState aState ) const
+    {
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::DataCallByState" );
+    CPESingleCall* returnValue( NULL );
+    CPESingleCall* callData;
+        
+    for ( TInt callId = KPEDataCallIdBase; 
+          callId < ( KPEDataCallIdBase + KPEMaximumNumberOfDataCalls ); 
+          callId++ )
+        {
+        callData = iCallArrayOwner.GetCallObject( callId );
+        if ( callData 
+             && ( callData->GetCallState() == aState ) )
+            {
+            returnValue = callData;
+            TEFLOGSTRING2( KTAINT, 
+                "CALL CPEVideoCallHandling::DataCallByState %d", callId );
+            break;
+            }
+        }
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::CallTerminatedError
+// Handles RemoteTerminated. 
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::CallTerminatedError( const TInt aCallId )
+    {
+    TEFLOGSTRING2( KTAINT, 
+            "VID CPEVideoCallHandling::CallTerminatedError, aCallId: %d",
+            aCallId );
+    
+    TInt errorCode( KErrNone );    
+	CPESingleCall* dataCall = iCallArrayOwner.GetCallObject( aCallId );
+	if ( dataCall )
+	    {
+	    dataCall->GetErrorCode( errorCode );
+	    }
+	
+	TEFLOGSTRING2( KTAINT, 
+	            "VID CPEVideoCallHandling::CallTerminatedError, errorCode: %d",
+	            errorCode );
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::DataPortInUse
+// Tells if the call has reserved serial communications data port for use
+// The default value is EFalse, i.e. the data port has not been reserved for
+// use. The data port is recovered when no longer needed.
+// -----------------------------------------------------------------------------
+// 
+TBool CPEVideoCallHandling::DataPortInUse(
+        TInt aCallId ) const
+    {
+    TBool dataPortInUse( EFalse );
+    TPEState state;
+    
+    if ( CallIdCheck::IsVideo( aCallId ) )
+        {
+        CPESingleCall* callData = iCallArrayOwner.GetCallObject( aCallId );
+        if( callData )
+            {
+            state = callData->GetCallState();
+            if( state == EPEStateConnected )
+                {
+                dataPortInUse = ETrue;
+                }
+            }
+        }
+    return dataPortInUse;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::DialCall
+// Creates dialing request to the Multimode ETel. 
+// This request is for creating a new multimedia (=data) call
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::DialCall(
+        const TPEPhoneNumber& aNumber,
+        TInt& aCallId )
+    {
+    TEFLOGSTRING( KTAINT, "VID CPEVideoCallHandling::DialCall" );
+    TInt errorCode( KErrNone );
+    TInt networkMode( ENWNetworkModeUnknown );
+    CPESingleCall* callData( NULL );
+    
+    RProperty::Get( KPSUidNetworkInfo, KNWTelephonyNetworkMode, networkMode );   
+
+    TInt restoreValue;
+    RProperty::Get( KUidSystemCategory, conn::KUidBackupRestoreKey, restoreValue );       
+    
+    if ( networkMode == ENWNetworkModeWcdma && 
+        !( restoreValue & ( conn::EBURRestoreFull | conn::EBURRestorePartial )) )
+        {
+        TRAP( errorCode, callData = OpenNewCallL( aNumber ) );
+        if( errorCode == KErrNone )
+            {
+            TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::DialCall > Dial" );
+            errorCode = callData->Dial( aNumber );
+            if ( errorCode != KErrNone )
+                {
+                // Dial failed: clean up
+                ReleaseCallObject( callData->GetCallId() );
+                TEFLOGSTRING2( KTAERROR, 
+                        "VID CALL CPEVideoCallHandling::DialCall ! DIAL FAILED: MAY NOT PROCEED! %d",
+                        errorCode );
+                }
+            else
+                {
+                // Dial request passed on successfully: forward new call id
+                aCallId = callData->GetCallId();
+                }
+            }
+        }
+    else
+        {
+        TEFLOGSTRING( KTAERROR, 
+            "VID CPEVideoCallHandling::DialCall: Attempting video call in 2G network!" );
+        errorCode = ( networkMode != ENWNetworkModeWcdma ) ? 
+                      ECCPErrorVideoCallNotSupportedByNetwork : 
+                      ECCPErrorVideoCallNotAllowedDuringRestore;
+        }    
+        
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::HangUp
+// terminates an ongoing call
+// Method checks that call id is valid number and
+// hangups conference or data call or reroutes call to base class.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::HangUp( TInt aCallId )
+    {
+    TEFLOGSTRING( KTAINT, "VID CPEVideoCallHandling::HangUp" );
+    TInt errorCode( KErrNotFound );
+    CPESingleCall* videoCall = iCallArrayOwner.GetCallObject( aCallId );
+    
+    if ( videoCall && CallIdCheck::IsVideo( aCallId ) ) 
+        {
+
+        errorCode = videoCall->HangUp();
+        }
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::InitCall
+// Handles the initializing of a single data/video call.
+// -----------------------------------------------------------------------------
+//
+void CPEVideoCallHandling::InitCall( MCCECall& aCall )
+    {
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::InitCall" );
+    CPESingleCall* callData( NULL );
+	  TRAP_IGNORE( callData = iCallArrayOwner.CreateDataCallL( *this ) );
+
+    if ( callData )
+        {
+        iModel.DataStore()->SetPhoneNumber( KNullDesC() );
+        iModel.DataStore()->SetServiceId( callData->GetCallId(), aCall.ServiceId() );
+        callData->SetCall( aCall );
+        iModel.DataStore()->SetCallSecureStatus( callData->IsSecureCall(), callData->GetCallId() );
+        iModel.DataStore()->SetSecureSpecified( callData->SecureSpecified() );
+        
+    	const CCCPCallParameters& callParameters = aCall.Parameters();
+        switch ( callParameters.CallType() )
+            {
+            case CCPCall::ECallTypeCSVoice:
+                {
+                iModel.DataStore()->SetCallType( EPECallTypeCSVoice, callData->GetCallId() );
+                }
+                break;
+            case CCPCall::ECallTypeVideo:
+                {
+                iModel.DataStore()->SetCallType( EPECallTypeVideo, callData->GetCallId() );
+                }
+                break;
+            case CCPCall::ECallTypePS:
+                {
+                iModel.DataStore()->SetCallType( EPECallTypeVoIP, callData->GetCallId() );
+                }
+                break;
+            default:
+                __ASSERT_DEBUG( EFalse, Panic( EPEPanicIndexOutOfRange ));
+                break;
+            }
+        }
+    else
+    	{
+    	Panic( EPEPanicNoFreeCalls );
+    	}
+    }
+ 
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::IsMultimedia
+// Checks if the data call is a multimedia call. Requires that the data call has
+// already been opened.
+// -----------------------------------------------------------------------------
+//
+TBool CPEVideoCallHandling::IsMultimedia( TInt aCallId ) const
+    {
+    TEFLOGSTRING2( KTAINT, "VID CPEVideoCallHandling::IsMultimedia %d", aCallId );
+    
+    TBool multimedia( EFalse );
+    CPESingleCall* videoCall = iCallArrayOwner.GetCallObject( aCallId );
+    
+    if ( videoCall && CallIdCheck::IsVideo( aCallId ) 
+         && videoCall->Call().Parameters().CallType()  
+                == CCPCall::ECallTypeVideo )
+        {
+        multimedia = ETrue;
+        }
+        
+    return multimedia;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::NotifySystemCallStateChanged
+// Notifies system for changes to the call state.
+// -----------------------------------------------------------------------------
+//
+void CPEVideoCallHandling::NotifySystemCallStateChanged( 
+        MEngineMonitor::TPEMessagesFromPhoneEngine aMessage,  // The enumeration number of the message
+        TInt aCallId )
+    {
+    TEFLOGSTRING2( KTAINT, "VID CPEVideoCallHandling::NotifySystemCallStateChanged %d", aCallId );
+	// this needs to be checked because this function is called for all data calls
+	if ( IsMultimedia( aCallId ) )
+        {
+	    if ( aMessage == MEngineMonitor::EPEMessageIncoming ||
+	       aMessage == MEngineMonitor::EPEMessageDialing )
+	        {
+            TInt updateError = RProperty::Set( KPSUidCtsyCallInformation, 
+                KCTsyCallType, EPSCTsyCallTypeH324Multimedia );
+            TEFLOGSTRING2( updateError?KTAERROR:KTAMESOUT, 
+                "VID CPEVideoCallHandling::NotifySystemCallStateChanged request RProperty::Set, EPSCTsyCallTypeH324Multimedia, updateError: ",
+                updateError );
+	        }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::SendMessage
+// Overrides CPECallHandling::SendMessage to provide internal handling for gsm events
+// and common events related to multimedia calls.
+// -----------------------------------------------------------------------------
+//
+void CPEVideoCallHandling::SendMessage(
+        MEngineMonitor::TPEMessagesFromPhoneEngine aMessage,
+        TInt aCallId )
+    {
+    TEFLOGSTRING3( KTAINT, 
+        "VID CPEVideoCallHandling::SendMessage, message id: %d, call id: %d", 
+        aMessage, 
+        aCallId );
+        
+    TInt error( KErrNone );
+    CPESingleCall* videoCall = iCallArrayOwner.GetCallObject( aCallId );
+    CPESingleCall* connectedVideoCall = VideoCallByState( EPEStateConnected );
+
+    if ( IsMultimedia( aCallId ) )
+        {
+        switch ( aMessage )
+            {
+            case MEngineMonitor::EPEMessageIncoming:
+            case MEngineMonitor::EPEMessageDialing:
+                {
+                TInt restoreValue;
+                RProperty::Get( KUidSystemCategory, conn::KUidBackupRestoreKey, restoreValue );
+                if( ( restoreValue & ( conn::EBURRestoreFull | conn::EBURRestorePartial ) ) )
+                    {
+                    // First phase VT and restore: Check if there is a arriving VT 
+            	    // call and Restore ongoing.
+            	    TEFLOGSTRING( KTAINT, 
+                        "VID CPEVideoCallHandling::SendMessage > HangUp restore active " );
+               	    iRestoreCauseVTCallReject = ETrue;
+               	    if( videoCall )
+               	        {
+               	        videoCall->HangUp();
+               	        }
+               	    aMessage = MEngineMonitor::EPEMessageDoNotSendMe;
+                    }
+                break;
+                }
+            case MEngineMonitor::EPEMessageDisconnecting:
+                {
+                if( iRestoreCauseVTCallReject )
+	                {
+	            	// Second phase VT and restore: Check if there is a rejected arriving VT call 
+	                // and Restore ongoing, then don't notify observers.
+	                iRestoreCauseVTCallReject = EFalse;
+	                TEFLOGSTRING( KTAINT, 
+				        "VID CPEVideoCallHandling::SendMessage Second phase Restore and VT call" );
+	                aMessage = MEngineMonitor::EPEMessageDoNotSendMe;
+	                }
+                break;
+                }
+            case MEngineMonitor::EPEMessageIdle:
+                {
+                iRestoreCauseVTCallReject = EFalse;
+                // Check reject video cace, if there is connect VT call don't disconnect
+                if( !connectedVideoCall )
+	                {
+	                if ( CallTerminatedError( aCallId ) == KErrGsmCCIncompatibleDestination )
+	                    {
+	                    error = KErrGsmCCIncompatibleDestination;
+	                    }
+	                }
+                break;
+                }
+            default:
+                {
+                TEFLOGSTRING2( 
+                    KTAINT, 
+                    "VID CPEVideoCallHandling::SendMessage: multimedia call, message: %d", 
+                    aMessage );
+                break;
+                }
+            } 
+        }
+    else
+        {
+        TEFLOGSTRING2( 
+            KTAINT, 
+            "VID CPEVideoCallHandling::SendMessage, isMultimedia: %d", 
+            IsMultimedia( aCallId ) );
+        }
+    if ( error == KErrNone )
+        {
+        iOwner.SendMessage( aMessage, aCallId );
+        }
+    else
+        {
+        SendErrorMessage( aCallId, error );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::VideoCallInState
+// Checks if there are any data calls in the specified state
+// -----------------------------------------------------------------------------
+//
+TBool CPEVideoCallHandling::VideoCallInState( const TPEState& aState ) const
+    {
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::DataCallInState" );
+    TBool returnValue( EFalse );
+    if( VideoCallByState( aState ) )
+        {
+        returnValue = ETrue;
+        }
+    return returnValue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::IsPhoneNumberAvailable
+// -----------------------------------------------------------------------------
+//
+TBool CPEVideoCallHandling::IsPhoneNumberAvailable( const TInt aCallId )
+    {
+    TEFLOGSTRING2( KTAINT, 
+        "VID CPEVideoCallHandling::IsPhoneNumberAvailable, aCallId: %d"
+        , aCallId );
+    TBool phoneNumberAvailable ( EFalse );
+        
+    if ( iDataStore.CallDirection( aCallId ) == RMobileCall::EMobileOriginated )
+	    {
+	    phoneNumberAvailable = ETrue;	
+	    }
+    else
+	    {
+	    RMobileCall::TMobileCallRemoteIdentityStatus remoteIdentity;
+	    remoteIdentity = iDataStore.RemoteIdentity( aCallId );
+	    TEFLOGSTRING2( KTAINT, 
+	        "VID CPEVideoCallHandling::IsPhoneNumberAvailable, remoteIdentity: %d", 
+	        remoteIdentity);
+	    phoneNumberAvailable = ( remoteIdentity == RMobileCall::ERemoteIdentityAvailable ); 	
+	    }
+    TEFLOGSTRING2( KTAINT, 
+        "VID CPEVideoCallHandling::IsPhoneNumberAvailable, isAvailable: %d", 
+        phoneNumberAvailable );
+    return phoneNumberAvailable;
+    }
+    
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::VideoCallByState
+// returns CPEVoiceCall video call object by State
+// -----------------------------------------------------------------------------
+//
+CPESingleCall* CPEVideoCallHandling::VideoCallByState( TPEState aState )
+    {
+    TEFLOGSTRING2( KTAINT, 
+            "CPEVideoCallHandling::VideoCallByState, aState: %d", aState );    
+    TPEState state;
+    CPESingleCall* returnValue( NULL );
+
+    for ( TInt callId = KPEDataCallIdBase; 
+          callId < ( KPEDataCallIdBase + KPEMaximumNumberOfDataCalls );
+          callId++ )
+        {        
+        CPESingleCall* callData = iCallArrayOwner.GetCallObject( callId );
+        if( callData )
+            {
+            state = callData->GetCallState();
+
+            if ( state == aState )
+                {
+                returnValue = callData;
+                break;
+                }
+            }
+        }
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// Replace active video call with a waiting video call
+// NOT SUPPORTED AS OF 5.1
+// -----------------------------------------------------------------------------
+//    
+TInt CPEVideoCallHandling::ReplaceActive( TInt /*aCallId*/  )
+    {
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::SetCallParams
+//
+// -----------------------------------------------------------------------------
+//
+void CPEVideoCallHandling::SetCallParams( TInt aCallId )
+    {
+    TEFLOGSTRING2( KTAINT, 
+            "VID CCPEVideoCallHandling::SetCallParams, aCallId: %d", aCallId );
+    iCallOpenParams->SetLineType( CCCECallParameters::ECCELineTypePrimary );
+
+    switch ( iModel.DataStore()->CallTypeCommand() )
+        {
+        case EPECallTypeVideo:
+            {
+            iCallOpenParams->SetCallType( CCPCall::ECallTypeVideo );
+            iModel.DataStore()->SetServiceIdCommand( 1 );
+            iModel.DataStore()->SetCallType( EPECallTypeVideo, aCallId );
+            }
+            break;
+        default:
+            __ASSERT_DEBUG( EFalse, Panic( EPEPanicIndexOutOfRange ));
+            iCallOpenParams->SetCallType( CCPCall::ECallTypeVideo );
+            iModel.DataStore()->SetServiceIdCommand( 1 );
+            iModel.DataStore()->SetCallType( EPECallTypeVideo, aCallId );
+            break;
+        } 
+    iCallOpenParams->SetServiceId( iModel.DataStore()->ServiceIdCommand() );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::OpenNewCallL
+// returns ETrue if hangup active
+// -----------------------------------------------------------------------------
+//
+CPESingleCall* CPEVideoCallHandling::OpenNewCallL( const TPEPhoneNumber& aNumber )
+    {
+    TEFLOGSTRING( KTAINT, "VID CPEVideoCallHandling::OpenNewCallL");
+    TInt errorCode( KErrNone );
+    CPESingleCall* callData( NULL );
+    MCCECall* cceCall( NULL );
+    
+    callData = iCallArrayOwner.CreateDataCallL( *this );
+    SetCallParams( callData->GetCallId() );
+    
+    TEFLOGSTRING( KTAINT, 
+        "VID CPEVideoCallHandling::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() );
+    	}
+    else
+    	{
+    	// Open new call failed
+    	ReleaseCallObject( callData->GetCallId() );
+		TEFLOGSTRING2( KTAERROR, 
+		        "VID CPEVideoCallHandling::DIALCALL ! OPENNEWCALL FAILED: MAY NOT PROCEED! %d", 
+		        errorCode );
+	    User::Leave( errorCode );
+    	}
+    return callData;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::GetCallState
+// Returns call state information.
+// -----------------------------------------------------------------------------
+//
+TPEState CPEVideoCallHandling::GetCallState( TInt aCallId  )
+    {
+    TEFLOGSTRING2( KTAINT, 
+            "CALL CPEVideoCallHandling::GetCallState %d", aCallId );
+    TPEState callState( EPEStateUnknown );
+    CPESingleCall* callData = iCallArrayOwner.GetCallObject( aCallId );
+    if( callData )
+        {
+        callState = callData->GetCallState();
+        }
+    else
+        {
+        callState = EPEStateIdle;
+        }
+    TEFLOGSTRING2( KTAINT, 
+            "CALL CPEVideoCallHandling::GetCallState, callState: %d", 
+            callState );
+    return callState;
+    }
+    
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::VideoCallById
+// returns CPESingleCall video call object by State
+// -----------------------------------------------------------------------------
+//
+CPESingleCall* CPEVideoCallHandling::VideoCallById( TInt aCallId )
+    {
+    TEFLOGSTRING2( KTAINT, "VID CPEVideoCallHandling::VideoCallById %d", aCallId );
+    return iCallArrayOwner.GetCallObject( aCallId );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::GetNumberOfCalls
+// Returns number of data calls.
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::GetNumberOfCalls()
+    {
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::GetNumberOfCalls" );
+    // Count ongoing calls
+    return iCallArrayOwner.ActiveCallCount();
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::SendMessage
+// Reroutes messages to the Phone Engine
+// -----------------------------------------------------------------------------
+//
+void CPEVideoCallHandling::SendMessage( 
+    MEngineMonitor::TPEMessagesFromPhoneEngine aMessage,
+    const TName& aName )
+    {
+    TEFLOGSTRING2( KTAINT, "CALL CPECallHandling::SendMessage, message id: %d", aMessage );
+    CPESingleCall* videoCall = VideoCallByName( aName );
+    if( videoCall )
+        {
+        SendMessage( aMessage, videoCall->GetCallId() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::VideoCallByName
+// returns data call object by name
+// -----------------------------------------------------------------------------
+//
+CPESingleCall* CPEVideoCallHandling::VideoCallByName( const TName& aName )
+    {       
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::DataCallByName" );
+    CPESingleCall* returnValue( NULL );
+    CPESingleCall* callData;
+    for ( TInt callId = KPEDataCallIdBase; 
+          callId < ( KPEDataCallIdBase + KPEMaximumNumberOfDataCalls ); 
+          callId++ )
+        {
+        callData = iCallArrayOwner.GetCallObject( callId );
+
+        if ( callData 
+             && ( VideoCallName( callId ) == aName ) )
+            {
+            returnValue = callData;
+            TEFLOGSTRING2( KTAINT, 
+                "CALL CPEVideoCallHandling::DataCallByName %d", callId );
+            break;
+            }
+        }
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::VideoCallName
+// Finds data call name given the call id.
+// -----------------------------------------------------------------------------
+//  
+TName& CPEVideoCallHandling::VideoCallName( const TInt aCallId )
+    {
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::DataCallName" );
+    
+    iDataCallName = KNullDesC;
+    TInt errorCode( KErrNone );
+
+    if ( CallIdCheck::IsVideo( aCallId ) )
+        {
+        RMobileCall::TMobileCallInfoV3* dataCallInfo = NULL;
+        dataCallInfo = new RMobileCall::TMobileCallInfoV3;
+        
+        if ( dataCallInfo )
+            {
+            errorCode = GetCallInfo( *dataCallInfo, aCallId );
+            TEFLOGSTRING2( KTAINT, 
+                "CALL CPEVideoCallHandling::DataCallName > GetCallInfo, error code: %d", 
+                errorCode );
+ 
+            if ( errorCode == KErrNone )
+                {
+                iDataCallName = dataCallInfo->iCallName;
+                }
+            }
+        else
+            {
+            errorCode = KErrNoMemory;
+            TEFLOGSTRING( KTAINT, 
+                "CALL CPEVideoCallHandling::DataCallName, error code = KErrNoMemory" );
+            }
+        delete dataCallInfo;
+        }
+    return iDataCallName;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::GetCallInfo
+// Returns data call information.
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::GetCallInfo( 
+        RMobileCall::TMobileCallInfoV3& aCallInfo,
+        TInt aCallId )
+    {
+    TEFLOGSTRING2( KTAINT, "CALL CPEVideoCallHandling::GetCallInfo %d", aCallId );
+    CPESingleCall* videoCall( NULL );
+    TInt errorCode( KErrNotFound );
+    videoCall = iCallArrayOwner.GetCallObject( aCallId );
+    if ( videoCall && CallIdCheck::IsVideo( aCallId ) )
+        {
+        errorCode = videoCall->GetCallInfo( aCallInfo );
+        errorCode = KErrNone;
+        }
+    else
+        {
+        __ASSERT_DEBUG( EFalse, Panic( EPEPanicIllegalCommand) );
+        }
+    return errorCode;
+    }
+ 
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::SendErrorMessage
+// Reroutes error code to Call Handling interface.
+// -----------------------------------------------------------------------------
+//
+void CPEVideoCallHandling::SendErrorMessage(
+    const TInt aCallId,
+    const TInt aErrorCode )
+    {
+    TEFLOGSTRING3( KTAINT, 
+        "CALL CPEVideoCallHandling::SendErrorMessage, error code: %d, error cause: %d, call id: %d", 
+        aErrorCode, 
+        aCallId );
+    iOwner.SendErrorMessage( aCallId, aErrorCode );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::HandleInternalMessage
+// Reroutes messages to the Phone Engine
+// -----------------------------------------------------------------------------
+//
+void CPEVideoCallHandling::HandleInternalMessage( TInt aMessage )
+    {
+    TEFLOGSTRING2( KTAINT, "CALL CPEVideoCallHandling::HandleInternalMessage, message: %d", aMessage );
+    iOwner.HandleInternalMessage( aMessage );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::ConnectedCalls
+// Indicates if there are any connected calls.
+// -----------------------------------------------------------------------------
+//
+TBool CPEVideoCallHandling::ConnectedCalls()
+    {
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::ConnectedCalls" );
+    TBool returnValue( EFalse );
+    if( VideoCallByState( EPEStateConnected ) )
+        {
+        returnValue = ETrue;
+        }
+    return returnValue ;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::RejectCall
+// Rejects the incoming call.
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::RejectCall()
+    {
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::RejectCall" );
+    TInt errorCode( KErrNotFound );
+    
+    CPESingleCall* videoCall = VideoCallByState( EPEStateRinging );
+    if( videoCall )
+        {
+        videoCall->HangUp();
+        errorCode = KErrNone;
+        }
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::ReleaseAll
+// Releases all ongoing calls.
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::ReleaseAll()
+    {
+    CPESingleCall* callData;
+    TInt errorCode( KErrNotFound );
+    TPEState callState;
+    
+    TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::ReleaseAll " );
+    
+    for ( TInt callId = KPEDataCallIdBase; 
+          callId < ( KPEDataCallIdBase + KPEMaximumNumberOfDataCalls ); 
+          callId++ )
+        {
+        callData = iCallArrayOwner.GetCallObject( callId );
+        if ( callData )
+            {
+            callState = callData->GetCallState();
+            if ( callState != EPEStateIdle && callState != EPEStateRinging )
+                {
+                TEFLOGSTRING2( KTAINT, 
+                    "CALL CPEVideoCallHandling::ReleaseAll, call id: %d", 
+                    callId );
+                HangUp( callId );
+                errorCode = KErrNone;
+                }
+            }
+        }
+        
+    TEFLOGSTRING2( KTAINT, 
+        "CALL CPEVideoCallHandling::ReleaseAll, error code: %d", 
+        errorCode );
+            
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::TerminateAllConnections
+// Terminates all ringing data calls, connected data calls and packet data
+// connections.
+// -----------------------------------------------------------------------------
+//
+TInt CPEVideoCallHandling::TerminateAllConnections()
+    {
+    TEFLOGSTRING( KTAMESINT, 
+        "CALL CPEVideoCallHandling::TerminateAllConnections");    
+    // Terminate GPRS connection.
+    // If GPRS connections are being terminated, 
+    // then we do not start again.
+    TBool canBeDeleted = ETrue;
+    if ( iGprsInterface )
+        {
+        canBeDeleted = !iGprsInterface->IsTerminating();
+        }
+
+    TInt error( KErrNone );
+    if ( canBeDeleted )
+        {
+        delete iGprsInterface;
+        iGprsInterface = NULL;
+        TRAP( error,
+            iGprsInterface = new (ELeave) CPEGprsTermination;
+            iGprsInterface->StartL() );
+        }
+    // Hangup Data calls
+    ReleaseAll();
+    
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEVideoCallHandling::GetCallDuration
+// Returns voice and conference (master call) call duration.
+// Method checks that call id is valid number and gets
+// call duration from conference or data call object or from
+// calls base class for voice call duration.
+// -----------------------------------------------------------------------------
+//
+ TInt CPEVideoCallHandling::GetCallDuration( 
+         TTimeIntervalSeconds& aDuration, 
+         TInt aCallId )
+    {
+    TEFLOGSTRING2( KTAINT, "CALL CPEVideoCallHandling::GetCallDuration %d", aCallId ); 
+    TInt errorCode( KErrNotFound );
+    CPESingleCall* callData( NULL );
+    callData = iCallArrayOwner.GetCallObject( aCallId );
+    
+    if ( callData && CallIdCheck::IsVideo( aCallId ) )
+        {
+        callData->GetCallDuration( aDuration );
+        errorCode = KErrNone;
+        }
+    else
+        {
+        __ASSERT_DEBUG( EFalse, Panic( EPEPanicIllegalCommand) );
+        }
+
+    return errorCode;
+    }
+ 
+ // -----------------------------------------------------------------------------
+ // CPEVideoCallHandling::ReleaseCallObject
+ // -----------------------------------------------------------------------------
+ //
+ TInt CPEVideoCallHandling::ReleaseCallObject( const TInt aCallId  )
+     {
+     TInt error(KErrNone);
+     TEFLOGSTRING2( KTAINT, 
+             "CALL CPEVideoCallHandling::ReleaseCallObject ReleaseCallObject %d", aCallId );
+     error = iCallArrayOwner.DeleteCallObject( aCallId );
+     // Reset datastore to prevent invalid usage in next call
+     TEFLOGSTRING( KTAINT, "CALL CPEVideoCallHandling::ReleaseCallObject, Reset CallInfo" );
+     iModel.DataStore()->ResetCallInfo( aCallId );
+     return error;
+     }
+ 
+//  End of File