phoneengine/phonemodel/src/cpemessagehandler.cpp
changeset 0 5f000ab63145
child 1 838b0a10d15b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneengine/phonemodel/src/cpemessagehandler.cpp	Mon Jan 18 20:18:27 2010 +0200
@@ -0,0 +1,2999 @@
+/*
+* 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:  Message handler
+*
+*/
+
+// INCLUDE FILES
+#include "cpecenrepmonitor.h"
+#include "cpeclientcallrequestmonitor.h"
+#include "cpeclientcallrequestmonitor.h"
+#include "cpeclientcommandhandlermonitor.h"
+#include "cpeclientservices.h"
+#include "cpeexternaldatahandler.h"
+#include "cpemanualcallcontrolhandler.h"
+#include "cpemessagehandler.h"
+#include "cpeparseremergencynumberhandler.h"
+#include "cpeparsermanufacturerhandler.h"
+#include "cpeparsermischandler.h"
+#include "cpeparserphonenumberhandler.h"
+#include "cpeparsersimcontrolhandler.h"
+#include "cpeparsersscallhandler.h"
+#include "cpeparsersshandler.h"
+#include "cpeparservoipnumberhandler.h"
+#include "cpepcnparserprocedurehandler.h"
+#include "cpesimstatemonitor.h"
+#include "cpetimer.h"
+#include "mpephonemodelinternal.h"
+#include "mpeservicehandling.h"
+#include "cperemotepartyinfomediator.h"
+
+#include <apacmdln.h>
+#include <apgcli.h>
+#include <apgtask.h>
+#include <AudioPreference.h>
+#include <barsc.h> 
+#include <barsread.h>
+#include <bldvariant.hrh>
+#include <ccpdefs.h>
+#include <coreapplicationuisdomainpskeys.h>
+#include <cpeclientinformation.h>
+#include <cpegsmaudiodata.h>
+#include <CPhoneGsmHandlerContainer.h>
+#include <CPhoneGsmOptionContainerBase.h>
+#include <CPhoneGsmParserBase.h>
+#include <CPhoneGsmParserResult.h>
+#include <featmgr.h>
+#include <mccecall.h>
+#include <mpeaudiodata.h>
+#include <mpecallhandling.h>
+#include <mpecontacthandling.h>
+#include <mpedatastore.h>
+#include <mpeloghandling.h>
+#include <pathinfo.h>
+#include <pepanic.pan>
+#include <PhCltTypes.h>
+#include <PhoneGsmParser.h>
+#include <ProfileEngineDomainConstants.h>
+#include <talogger.h>
+#include <w32std.h>
+
+// EXTERNAL DATA STRUCTURES
+// None.
+
+// EXTERNAL FUNCTION PROTOTYPES  
+// None.
+
+// CONSTANTS
+// Prefix change off. See SettingsInternalCRKeys.h
+const TInt KPEPrefixChangeOff = 0;
+// Prefix change on. See SettingsInternalCRKeys.h
+const TInt KPEPrefixChangeOn = 1;
+// International prefix
+_LIT( KPEIntPrefix, "+" );
+// Japan prefix
+_LIT( KPEJapanPrefix, "+81" );
+// Zero prefix
+_LIT( KPEZeroPrefix, "0" );
+// Valid dtmf sting
+_LIT( KValidDtmfChars, "0123456789pw*+#" );
+
+// Timeout for automatic answer. 
+const TInt KPEAutomaticAnswerTimeOut = 5000000;
+
+_LIT( KPEClirSuppress, "*31#" );
+_LIT( KPEClirInvoke, "#31#" );
+
+const TInt KPENumberPlus = '+';
+const TInt KPENumberHash = '#'; 
+const TInt KPENumberAsterisk = '*'; 
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CPEMessageHandler* CPEMessageHandler::NewL
+        ( 
+        MPEPhoneModelInternal& aModel,
+        MPECallHandling& aCallHandling,
+        MEngineMonitor& aEngineMonitor,
+        CPEGsmAudioData& aAudioData,
+        MPELogHandling& aLogHandling,
+        MPEContactHandling& aContactHandling,
+        CPESimStateMonitor& aSimStateMonitor,
+        CPEExternalDataHandler& aGsmExternalDataHandler,
+        MPEServiceHandling& aServiceHandling,
+        RFs& aFsSession )
+    {
+    CPEMessageHandler* self = new ( ELeave ) CPEMessageHandler( 
+        aModel, 
+        aCallHandling, 
+        aEngineMonitor, 
+        aAudioData, 
+        aLogHandling, 
+        aContactHandling, 
+        aSimStateMonitor,
+        aGsmExternalDataHandler,
+        aServiceHandling,
+        aFsSession );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::CPEMessageHandler
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPEMessageHandler::CPEMessageHandler( 
+        MPEPhoneModelInternal& aModel,                 // The model of the phone object which owns this object
+        MPECallHandling& aCallHandling,              // The reference parameter of the phone data object which is used to create call handling request
+        MEngineMonitor& aEngineMonitor,        // The reference parameter of the engine monitor object which is used to communication with phone application
+        CPEGsmAudioData& aAudioData,              // The reference parameter of the audio data object which is used to handle audio requests
+        MPELogHandling& aLogHandling,                // The reference parameter of the logs data object which is used to handle log requests   
+        MPEContactHandling& aContactHandling,          // The reference parameter of the contact data object which is used to handle contact requests
+        CPESimStateMonitor& aSimStateMonitor,
+        CPEExternalDataHandler& aExternalDataHandler, // The reference parameter of external data handler object
+        MPEServiceHandling& aServiceHandling,
+        RFs& aFsSession )                // The reference parameter of CustomAPI
+        : iModel( aModel ), 
+            iCallHandling( aCallHandling ),
+            iEngineMonitor( aEngineMonitor ),
+            iGsmAudioData( aAudioData ),
+            iLogHandling( aLogHandling ),
+            iContactHandling( aContactHandling ),
+            iExternalDataHandler( aExternalDataHandler ),
+            iSimStateMonitor( aSimStateMonitor ),
+            iFsSession( aFsSession ),
+            iServiceHandling( aServiceHandling ),
+            iDataStore( *aModel.DataStore() )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::BaseConstructL
+// Performs base construction of the object.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::ConstructL()
+    {
+    iClientInformation = CPEClientInformation::NewL();
+
+    iParser = PhoneGsmParser::CreateParserL();
+    iOptions = PhoneGsmParser::CreateOptionContainerL();
+    iManualCallControlHandler = CPEManualCallControlHandler::NewL( iCallHandling, *this, iDataStore );
+    iClientServices = CPEClientServices::NewL( iModel, *this, iCallHandling, *iManualCallControlHandler );
+    iParserHandlerContainer = CPhoneGsmHandlerContainer::NewL();
+
+    // NOTE: The handler objects will break some CleanUpStack usage rules:
+    // CPEMessageHandler class construct handler objects but ownership will be 
+    // transfered to Handler Container. And therefore CleanUpStack will be 
+    // used to member object because if iParserHandlerContainer->AddHandlerL 
+    // leaves CPEMessageHandler don't delete handler object hence CleanUpStack
+    // must delete handler object. 
+
+    // Handles manufacturer specific codes from the parser.
+    CPEParserManufacturerHandler* manufacturerHandler = 
+        new ( ELeave ) CPEParserManufacturerHandler( iModel, iCallHandling, iFsSession );
+    CleanupStack::PushL( manufacturerHandler );
+    iParserHandlerContainer->AddHandlerL( *manufacturerHandler ); // ownership will be transfered to Handler Container.
+    CleanupStack::Pop( manufacturerHandler );
+
+    // Handles misc codes from the parser.
+    CPEParserMiscHandler* miscHandler = new ( ELeave ) CPEParserMiscHandler( 
+        *this, 
+        iCallHandling );
+    CleanupStack::PushL( miscHandler );
+    iParserHandlerContainer->AddHandlerL( *miscHandler );// ownership will be transfered to Handler Container.
+    CleanupStack::Pop( miscHandler );
+
+    CPEParserPhoneNumberHandler* tempPhoneNumberHandler = 
+        new ( ELeave ) CPEParserPhoneNumberHandler( *this, 
+                                                       iCallHandling, 
+                                                       iDataStore );
+    CleanupStack::PushL( tempPhoneNumberHandler );
+    iParserHandlerContainer->AddHandlerL( *tempPhoneNumberHandler ); // ownership will be transfered to Handler Container.
+    CleanupStack::Pop( tempPhoneNumberHandler );
+    iPhoneNumberHandler = tempPhoneNumberHandler;
+
+    // Handles sim control procedures from the parser.
+    CPEParserSimControlHandler* simControlHandler = CPEParserSimControlHandler::NewL( 
+        iModel, 
+        iContactHandling );
+    CleanupStack::PushL( simControlHandler );
+    iParserHandlerContainer->AddHandlerL( *simControlHandler );// ownership will be transfered to Handler Container.
+    CleanupStack::Pop( simControlHandler );
+
+    // Handles supplementary services during calls from the parser.
+    CPEParserSSCallHandler* sSCallHandler = new ( ELeave ) CPEParserSSCallHandler( 
+        *this, 
+        iModel, 
+        *iManualCallControlHandler );
+    CleanupStack::PushL( sSCallHandler );
+    iParserHandlerContainer->AddHandlerL( *sSCallHandler );// ownership will be transfered to Handler Container.
+    CleanupStack::Pop( sSCallHandler );
+
+    iSSHandler = CPEParserSSHandler::NewL( *this, iModel ); 
+    iParserHandlerContainer->AddHandlerL( *iSSHandler );// ownership will be transfered to Handler Container.
+
+    // Handles pcn service requests from the parser.
+    CPEPcnParserProcedureHandler* pcnProcedureHandler = CPEPcnParserProcedureHandler::NewL( 
+        *this, 
+        iModel ); 
+    CleanupStack::PushL( pcnProcedureHandler );
+    iParserHandlerContainer->AddHandlerL( *pcnProcedureHandler );// ownership will be transfered to Handler Container.
+    CleanupStack::Pop( pcnProcedureHandler );
+    
+    // Handles emergency phone number
+    CPEParserEmergencyNumberHandler* tempEmergencyNumberHandler 
+        = new ( ELeave ) CPEParserEmergencyNumberHandler( *this, 
+                                                          iCallHandling, 
+                                                          iDataStore );
+    CleanupStack::PushL( tempEmergencyNumberHandler );
+    iParserHandlerContainer->AddHandlerL( *tempEmergencyNumberHandler ); // ownership will be transfered to Handler Container.
+    CleanupStack::Pop( tempEmergencyNumberHandler );
+    iEmergencyNumberHandler = tempEmergencyNumberHandler;
+
+    CPEParserVoipNumberHandler* tempVoipNumberHandler
+        = CPEParserVoipNumberHandler::NewLC( *this, 
+                                               iCallHandling, 
+                                               iServiceHandling,
+                                               iDataStore );
+
+    iParserHandlerContainer->AddHandlerL( *tempVoipNumberHandler ); // ownership will be transfered to Handler Container.
+    CleanupStack::Pop( tempVoipNumberHandler );
+    iVoipNumberHandler = tempVoipNumberHandler;
+    
+    iAutomaticAnswerTimer = CPETimer::NewL( iModel );
+ 
+    // Reserve needed callinfo and remoteinfo from heap.
+    iCallInfo = new ( ELeave ) RMobileCall::TMobileCallInfoV3;
+    
+    iResult = PhoneGsmParser::CreateResultL();
+    }
+        
+// Destructor
+CPEMessageHandler::~CPEMessageHandler()
+    {
+    delete iClientInformation;
+    delete iAsyncCallBack;
+    delete iCallInfo;
+    delete iAutomaticAnswerTimer;
+    delete iParserHandlerContainer;
+    delete iClientServices;
+    delete iManualCallControlHandler;
+    delete iOptions;
+    delete iParser;
+    delete iResult;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleAnswerCall
+// Handles answer message from phone application. Method calls AnswerCall 
+// method from the CallHandling subsystem.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleAnswerCall(
+        const TBool aAutomaticAnswer ) // Informs is this automatic answer or not
+    {
+    // Stop DTMF sending and empty buffers if answer was requested in the
+    // middle of DTMF sequence.
+    StopDtmfSending();
+    
+    //Check if this is automatic answer and play redialCompletedTone (confusing naming)
+    if( !aAutomaticAnswer )
+        {
+        iAutomaticAnswerTimer->Cancel();
+        }
+
+    return iCallHandling.AnswerCall();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleAudioRouting
+// Handles accessory mode changed message from AudioHandling subsystem. Method 
+// fecths accessory mode from AudioHandling subsystem and method sets new accessory
+// mode value to the CPEEngineInfo class. Method finds previously used volume
+// values for accessory and changes volume accordingly.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleAudioRouting( TBool aVideoCall, TInt aCallId )
+    {
+    TInt error( ECCPErrorNone );
+    
+    if ( aCallId == KPEEmergencyCallId )     
+         {
+         error = iGsmAudioData.HandleEnergencyCallStarting();
+         }
+     else
+         {
+         error = iGsmAudioData.HandleCallStarting( aVideoCall );
+         }
+    
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleRoutePreferenceChanged
+// Handles route preference changed message from AudioHandling subsystem. 
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleRoutePreferenceChanged()
+    {
+    TInt error( ECCPErrorNone );
+    
+    TEFLOGSTRING( KTAMESINT, "PE CPEMessageHandler::HandleRoutePreferenceChanged()" );
+    
+    error = iGsmAudioData.CallAudioRoutePreferenceChanged();
+     
+    return error;
+    }    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleContinueDtmfSending
+// Handles continue dtmf sending after 'w' character in the dtmf string
+// Method calls ContinueDtmfSending or StopDtmfSending method from the 
+// CallHandling subsystem.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleContinueDtmfSending( 
+        const TBool aContinue )
+    {
+    if ( aContinue )
+        {
+        HandleSendDtmf();
+        }
+    else
+        {
+        StopDtmfSending();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleReleaseAll
+// Handles release all message from phone application
+// Method calls ReleaseAll method from the CallHandling subsystem object..
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleReleaseAll()
+    {
+    return iCallHandling.ReleaseAll();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleReleaseCall
+// Handles release message from phone application
+// Method fecths call id number from the CPEEngineInfo structure and then
+// Method calls HangUp method from the CallHandling subsystem.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleReleaseCall( TPEHangUpOptions aAutoResumeOption )
+    {
+    TInt callId;
+    TInt errorCode( ECCPErrorNone );
+    callId = iDataStore.CallId();
+    
+    if ( CallIdCheck::IsVideo( callId ) )
+        {
+        //Video call
+        iGsmAudioData.StopInbandTonePlay();
+        errorCode = iCallHandling.HangUp( callId, ETPEHangUpNotResumeHeldCall );
+        }
+    else
+        {
+        errorCode = iCallHandling.HangUp( callId, aAutoResumeOption );
+        }
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleSendDtmf
+// Handles send dtmf message from phone application
+// Method fetches dtmf string from the CPEEngineInfo class and then
+// Method parses the DTMF string and then take action properly: 
+// hard pause: triggers sending MEngineMonitor::EPEMessageStoppedDTMF 
+//      to phone model
+// '+': triggers substitution speed dial digit with speed dial number. 
+//
+// Method calls SendDtmf method from the CallHandling subsystem.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleSendDtmf()
+    {
+    TInt errorCode( ECCPErrorNone );
+    TPEDtmfString dtmfString = iDataStore.DtmfStringCommand();
+
+    RemoveInvalidChars( dtmfString, KPEClientValidChars, EFalse );
+
+    if ( dtmfString.Length() == 0 )
+        {
+        iDataStore.SetDtmfString( KNullDesC() ); 
+        errorCode = KErrArgument;
+        }
+    // Parse the first character of the string
+    else if ( dtmfString[ 0 ] == KPEDtmfStopCharLowercase || 
+              dtmfString[ 0 ] == KPEDtmfStopCharUppercase ) // hard pause
+        {
+        TEFLOGSTRING( KTAMESINT, "PE CPEMessageHandler::HandleSendDtmf(), Processing W" );
+        // remove the hard pause char from the string
+        iDataStore.SetDtmfString( dtmfString.Mid( 1 ) );
+        iDataStore.SetDtmfStringCommand( dtmfString.Mid( 1 ) );
+        
+        // Send EPEMessageStoppedDTMF message asynchronic.
+
+        TCallBack callBack( CallbackSendMessageStoppedDTMF, this );
+        delete iAsyncCallBack;
+        iAsyncCallBack = NULL;
+        // Function does not allow to leave.
+        iAsyncCallBack = new CAsyncCallBack( callBack, CActive::EPriorityHigh );
+        if ( iAsyncCallBack )
+            {
+            iAsyncCallBack->CallBack();
+            }
+        else
+            {
+            iModel.SendMessage( MEngineMonitor::EPEMessageStoppedDTMF );
+            }
+        
+        dtmfString = KNullDesC;
+        }    
+    else if ( dtmfString[ 0 ] == KPEDtmfPlusChar ) // speed-dial substitution
+        {
+        TEFLOGSTRING( KTAMESINT, "PE CPEMessageHandler::HandleSendDtmf(), Processing +" );
+        HandlePlusSignInDtmf( dtmfString );
+        dtmfString = KNullDesC;
+        }
+    else if ( dtmfString[ 0 ] == KPEDtmfPauseCharLowercase || 
+              dtmfString[ 0 ] == KPEDtmfPauseCharUppercase ) // soft pause
+        {
+        TEFLOGSTRING( KTAMESINT, "PE CPEMessageHandler::HandleSendDtmf(), Processing P" );
+        
+        // store the full string for UI to display 
+        iDataStore.SetDtmfString( dtmfString );
+
+        if ( dtmfString.Length() > 1 )
+            {
+            // store the remainder of the string to be processed later
+            iDataStore.SetDtmfStringCommand( dtmfString.Mid( 1 ) ); 
+            }
+        else
+            {
+            // nothing left to process
+            iDataStore.SetDtmfStringCommand( KNullDesC() );
+            }
+        // set the dtmf string to send 
+        dtmfString = dtmfString.Left( 1 );
+        }
+    else 
+        {
+        // store the full string for UI to display 
+        iDataStore.SetDtmfString( dtmfString );
+        
+        // Find the next stop point
+        TInt stopPoint = ECCPErrorNotFound;
+        TPtrC validDtmfStringStopChars( KPEValidDTMFStringStopChars );
+        for ( TInt index = 0 ; index < dtmfString.Length(); index++ )
+            {
+            if ( validDtmfStringStopChars.Locate( dtmfString[index] ) != ECCPErrorNotFound )
+                {
+                stopPoint = index;
+                break; 
+                }
+            }
+
+        if ( stopPoint != ECCPErrorNotFound ) 
+            {
+            // store the remainder of the string to be processed later
+            iDataStore.SetDtmfStringCommand( dtmfString.Mid( stopPoint ) ); 
+            // set the dtmf string to send 
+            dtmfString = dtmfString.Left( stopPoint );            
+            }
+        else
+            {
+            // nothing left to process
+            iDataStore.SetDtmfStringCommand( KNullDesC() );
+            }
+        }
+
+    if ( dtmfString.Length() )  
+        {
+        TEFLOGSTRING2( KTAMESINT, "PE CPEMessageHandler::HandleSendDtmf(), Starting to play %S", &dtmfString );
+        // send the dtmf string to call handling subsystem
+        errorCode = iCallHandling.SendDtmf( dtmfString );
+        }
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::CallBackHandleSendDtmf
+// Asyncronous callback for HandleSendDtmf() function.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::CallBackHandleSendDtmf( TAny* aAny )
+    {
+    __ASSERT_ALWAYS( aAny , Panic( EPEPanicNullPointer ) );
+    CPEMessageHandler* self = static_cast<CPEMessageHandler*>(aAny);
+
+    delete self->iAsyncCallBack;
+    self->iAsyncCallBack = NULL;
+    return self->HandleSendDtmf();  
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandlePlusSignInDtmf
+// Handles plus (+) sign in a DTMF string.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandlePlusSignInDtmf(const TPEDtmfString& aDtmfString )
+    {
+    TEFLOGSTRING2( KTAMESINT, "PE CPEMessageHandler::HandlePlusSignInDtmf(), aDtmfString: %S", &aDtmfString ); 
+          
+    // Find the SD index after the plus sign
+    TPtrC validManualDTMFChars( KPEValidSpeedDialChars );
+    TInt index = ECCPErrorNotFound;
+    for ( index = 1 ; index < aDtmfString.Length() ; index++ )
+        {
+        if ( validManualDTMFChars.Locate( aDtmfString[index] ) == ECCPErrorNotFound )
+            {
+            TEFLOGSTRING( KTAMESINT, "PE CPEMessageHandler::HandlePlusSignInDtmf(), Not Found" ); 
+            break; 
+            }
+        }
+    TPESpeedDialSubstituionStatus sdStatus = EPEDtmfSpeedDialOk;
+    
+    // Empty string after the plus sign
+    if ( index == 1 )
+        {
+        if ( aDtmfString.Length() > 1 )
+            {
+            // pw+ after the plus sign.
+            sdStatus = EPEDtmfSpeedDialInvalidSpeedDial;
+            }
+        else
+            {
+            // string ended with the plus sign.
+            sdStatus = EPEDtmfSpeedDialPromptUser;
+            }
+        // Clear DTMF string.
+        iDataStore.SetDtmfString( KNullDesC() );
+        }
+    // Else if the SD location ends the DTMF string, move the index to the
+    // last character instead of one over.
+    else if ( index == aDtmfString.Length() )
+        {
+        index--;
+        }
+    
+    // Check that the index is valid
+    TInt sdIndex = ECCPErrorNotFound; 
+    if ( sdStatus == EPEDtmfSpeedDialOk )
+        {
+        TLex lexer( aDtmfString.Mid( 1, index ) );
+        // convert it to a number
+        if ( lexer.Val(sdIndex) == ECCPErrorNone )
+            {
+            // Is it out of range
+            if ( sdIndex < KPESpeedDialIndexMin  ||
+                sdIndex > KPESpeedDialIndexMax )
+                {
+                sdStatus = EPEDtmfSpeedDialInvalidSpeedDial;
+                }
+            }
+        else
+            {
+            sdStatus = EPEDtmfSpeedDialInvalidSpeedDial;
+            }
+        }
+    
+    // Fetch the SD location
+    TPEPhoneNumber speedDialLocationString;
+    if ( sdStatus == EPEDtmfSpeedDialOk )
+        {
+        TEFLOGSTRING2( KTAMESINT, "PE CPEMessageHandler::HandlePlusSignInDtmf(), SD location %i", sdIndex ); 
+        if ( iContactHandling.GetSpeedDialLocation( 
+            sdIndex, speedDialLocationString ) == ECCPErrorNone )
+            {
+            // Is content found
+            if ( speedDialLocationString.Length() == 0)
+                {
+                sdStatus = EPEDtmfSpeedDialNotAssigned;
+                }
+            else if ( speedDialLocationString[0] == KPEDtmfPlusChar)  
+                {
+                // plus char must be removed from dtmf string before sending
+                RemovePlusPrefix( speedDialLocationString );
+                }
+            }
+        else
+            {
+            sdStatus = EPEDtmfSpeedDialInvalidSpeedDial;
+            }
+        }
+    
+    // Now interpret the sdStatus to the next action
+    switch ( sdStatus )
+        {
+        case EPEDtmfSpeedDialOk:
+            {
+            TEFLOGSTRING2( KTAMESINT, "PE CPEMessageHandler::HandlePlusSignInDtmf(), SD result: %S", &speedDialLocationString ); 
+            // Take the SD location string and use that as new DTMF string
+            iDataStore.SetDtmfStringCommand( speedDialLocationString );
+            
+            // Do recursion asyncronously                        
+            TCallBack callBack( CallBackHandleSendDtmf, this );
+            delete iAsyncCallBack;
+            iAsyncCallBack = NULL;
+            // Function does not allow to leave.
+            iAsyncCallBack = new CAsyncCallBack( callBack, CActive::EPriorityStandard );
+            if ( iAsyncCallBack )
+                {
+                iAsyncCallBack->CallBack();
+                }
+            else
+                {
+                iModel.SendMessage( MEngineMonitor::EPEMessageDTMFSendingAborted );
+                }
+            }
+            break;
+        case EPEDtmfSpeedDialPromptUser:
+            // Speed dial location not given.
+            iDataStore.SetDtmfString( KNullDesC() );
+            iModel.SendMessage( MEngineMonitor::EPEMessagePromptSpeedDial );
+            break;
+        case EPEDtmfSpeedDialNotAssigned:
+            // Speed dial location valid but not assigned
+            iDataStore.SetDtmfString( KNullDesC() );
+            iDataStore.SetDtmfStringCommand( KNullDesC() );
+            iModel.SendMessage( MEngineMonitor::EPEMessageDTMFSendingAborted);
+            iModel.SendMessage( MEngineMonitor::EPEMessageSpeedDialNotAssigned );
+            break;
+        case EPEDtmfSpeedDialInvalidSpeedDial:
+            // Speed dial location invalid
+            iDataStore.SetDtmfString( KNullDesC() );
+            iDataStore.SetDtmfStringCommand( KNullDesC() );
+            iModel.SendMessage( MEngineMonitor::EPEMessageDTMFSendingAborted);
+            iModel.SendMessage( MEngineMonitor::EPEMessageInvalidSpeedDial );
+            break;
+        default:
+            Panic( EPEPanicInvalidState );
+            break;
+        } // end switch
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::CheckPrefix
+// Checks the status of phone number prefix change setting
+// and calls CPEMessageHandler::ChangePrefix for execution.
+// If error occurs the phone number is left untouched
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::CheckPrefix()
+    {
+    TInt err = ECCPErrorNone;
+    TBool checkPrefix = 
+        FeatureManager::FeatureSupported( KFeatureIdJapanPrefixChange );
+
+    if ( checkPrefix )
+        {
+        TInt prefixMode = KPEPrefixChangeOff; // Default is "off"
+
+        err = iExternalDataHandler.Get(
+            EPEDialPrefixChangeSetting,
+            prefixMode );
+
+        if ( !err )
+            {
+            if ( prefixMode == KPEPrefixChangeOn )
+                {
+                TPEPrefixText prefixText;
+                
+                err = iExternalDataHandler.GetText(
+                    EPEDialPrefixTextSetting,
+                    prefixText );
+
+                if ( !err )
+                    {
+                    err = ChangePrefix( prefixText );
+                    }
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::ChangePrefix
+// Executes phone number prefix change.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::ChangePrefix(
+    const TPEPrefixText& aPrefixText )
+    {
+    TInt err = ECCPErrorNone;
+
+    const TInt beginning = 0; // The beginning for replacement.
+    TInt replaceLength = 0; // The string length to be replaced.
+    TInt location = ECCPErrorNotFound; // The location of searched string.
+    TPEPhoneNumber phoneNumber = iDataStore.PhoneNumber();
+
+    // Try to find Japan prefix.
+    location = phoneNumber.Find( KPEJapanPrefix );
+    if ( location == beginning )
+        {
+        // The string was found, so make replacement. 
+        // Safe because KPEZeroPrefix < KPEJapanPrefix.
+        replaceLength = KPEJapanPrefix().Length();
+        phoneNumber.Replace( beginning, replaceLength, KPEZeroPrefix );
+        }
+    else
+        {
+        // Try to find international prefix.
+        location = phoneNumber.Find( KPEIntPrefix );
+        if ( location == beginning )
+            {
+            replaceLength = KPEIntPrefix().Length();
+            // The string was found, so try to make replacement. 
+            const TInt phoneNumLength = phoneNumber.Length();
+            const TInt prefixLength = aPrefixText.Length();
+
+            TInt stringLength = 
+                ( phoneNumLength + prefixLength - replaceLength );
+
+            if ( phoneNumber.MaxLength() >= stringLength )
+                {
+                // There is enough space to make this replace.
+                phoneNumber.Replace( beginning, replaceLength, aPrefixText );
+                }
+            else
+                {
+                // There is no space to combine the strings, so inform it.
+                err = KErrOverflow;
+                }
+            }
+        }
+
+    if ( err == ECCPErrorNone )
+        {
+        iDataStore.SetPhoneNumber( phoneNumber );
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDtmfSent
+// Handles DTMF sent message from the CallHandling subsystem.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleDtmfSent()
+    {
+    TInt errorCode( ECCPErrorNone );
+
+    // check if there are still parts of the string left to process
+    if ( iDataStore.DtmfStringCommand().Length() ) 
+        {
+        HandleSendDtmf();
+        errorCode = KPEDontSendMessage;
+        }
+    else 
+        {
+        // dtmf sending complete
+        iDataStore.SetDtmfString( KNullDesC() );
+        }
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::StopPlayingDtmf
+// Stops/Cancels playing dtmf tones and string (audio feedback and network)
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::StopDtmfSending()
+    {
+    // cancel subtitution callback:
+    if ( iAsyncCallBack )
+        {
+        iAsyncCallBack->Cancel();
+        delete iAsyncCallBack;
+        iAsyncCallBack = NULL;
+        }
+
+    iCallHandling.StopDtmfSending();
+    
+    iDataStore.SetDtmfString( KNullDesC() ); 
+    iDataStore.SetDtmfStringCommand( KNullDesC() );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleSetAudioMute
+// Handles audio mute message from the phone application.
+// Method fecths mute value from the CPEEngineInfo and then
+// Method sets mute value to the AudioHandling subsystem.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleSetAudioMute()
+    {
+    TEFLOGSTRING( KTAGENERAL, "PE: CPEMessageHandler::HandleSetAudioMute" );
+    TBool mute = iDataStore.AudioMuteCommand();
+    iGsmAudioData.SetAudioMuteSync( mute );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleSetAudioOutput
+// Handles audio output from the phone application.
+// Method fecths output and note values from the CPEEngineInfo and then
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleSetAudioOutput()
+    {
+    TEFLOGSTRING( KTAGENERAL, "PE: CPEMessageHandler::HandleSetAudioOutput" );
+    return iGsmAudioData.SetAudioOutput( iDataStore.AudioOutputCommand(),
+                                      iDataStore.ShowNoteCommand() );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleSetAudioVolume
+// Handles change volume message from the phone application.
+// Method fecths volume value from the CPEEngineInfo and then
+// Method sets volume value to the AudioHandling subsystem.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleSetAudioVolume()
+    {    
+    TInt volume = iDataStore.AudioVolumeCommand();
+    TEFLOGSTRING2( KTAGENERAL, "PE: CPEMessageHandler::HandleSetAudioVolume %d", volume );
+    iGsmAudioData.SetAudioVolumeSync( volume );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandlePlayDTMFL
+// Handles key down event.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandlePlayDTMFL()
+    {
+    ProcessPlayDTMFL();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleEndDTMF
+// Handles key up event.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleEndDTMF()
+    {
+    return ProcessEndDTMF();
+    }
+    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::SetClientInformation
+// Sets client information.
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::SetClientInformation(
+        const TInt aCallId,  
+        const TDesC& aMainPartOfPhoneNumber ) 
+    {
+    // Other ClientInformation it was already set before, in SetClientData
+    // method. Methods is called from HandleClientCallDataL before CallId is known.
+    iClientInformation->SetNumber( aMainPartOfPhoneNumber );
+    
+    iDataStore.SetCallClientInformation( *iClientInformation, aCallId );
+    
+    const TPECallOrigin& origin = iDataStore.CallOriginCommand();    
+    iDataStore.SetCallOrigin( origin, aCallId );    
+    }
+ 
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::SetClientData
+// Sets client dial data to member variable.
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::SetClientData(
+        const CPhCltDialData& aClientDialData ) 
+    {
+    CCCECallParameters& params = iDataStore.CallParameters();
+    
+    iClientDialData = &const_cast<CPhCltDialData&>( aClientDialData );
+
+    iClientInformation->SetName( iClientDialData->Name() );
+    
+    if ( iClientDialData->CallType() == EPhCltVideo || 
+        iClientDialData->CallType() == EPhCltForcedVideo )
+        {
+        iClientInformation->SetCallType( EPECallTypeVideo );
+        iDataStore.SetCallTypeCommand( EPECallTypeVideo );
+        params.SetCallType( CCPCall::ECallTypeVideo );
+        }
+    else if ( iClientDialData->CallType() == EPhCltCallVoIP )
+        {
+        iClientInformation->SetCallType( EPECallTypeVoIP );
+        iDataStore.SetCallTypeCommand( EPECallTypeVoIP );        
+        params.SetCallType( CCPCall::ECallTypePS );
+        }
+    else
+        {
+        iClientInformation->SetCallType( EPECallTypeCSVoice );
+        iDataStore.SetCallTypeCommand( EPECallTypeCSVoice );
+        params.SetCallType( CCPCall::ECallTypeCSVoice );
+        }
+      
+    iClientInformation->SetEndOtherCalls( iClientDialData->EndOtherCalls() );
+    
+    iClientInformation->SetAllowMatch( iClientDialData->AllowMatch() );
+    
+    iClientInformation->SetContactLink( iClientDialData->ContactLink() );
+   
+    iClientInformation->SetShowNumber( iClientDialData->ShowNumber() );
+
+    // Not accept 0, TODO Requirement clarification needed, 
+    // does service id 0 need special handling!
+    if ( iClientDialData->ServiceId() != 0 )
+        {
+        iDataStore.SetServiceIdCommand( iClientDialData->ServiceId() );
+        params.SetServiceId( iClientDialData->ServiceId() );
+        }
+        
+    iDataStore.SetUserToUserInformation( iClientDialData->UUI() );
+    
+    params.SetBearer( iClientDialData->Bearer() );
+    params.SetSubAddress( iClientDialData->SubAddress() );
+    
+    if ( iClientDialData->SATCall() )
+        {
+        params.SetOrigin( CCCECallParameters::ECCECallOriginSAT );
+        }
+    else
+        {
+        params.SetOrigin( CCCECallParameters::ECCECallOriginPhone );
+        }
+    }
+     
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleTerminateAllConnections
+// Method resets redial timer if active and calls TerminateAllConnection 
+// method from the CallHandling subsytem object.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleTerminateAllConnections()
+    {
+    TInt errorCode( ECCPErrorNone );
+    errorCode = iCallHandling.TerminateAllConnections();
+    TEFLOGSTRING2( 
+        KTAGENERAL, 
+        "PE: CPEMessageHandler::HandleTerminateAllConnections: Callhandling::TerminateAllConnections() called, Error code: %d", 
+        errorCode );
+
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::IsItCharThatCanDelete
+// Checks if character can be delete. If given charter can be located from 
+// KPECharsThatCanBeDelete, method returns ETrue else EFalse.
+// -----------------------------------------------------------------------------
+//
+TBool CPEMessageHandler::IsItCharThatCanDelete( 
+        const TChar& aChar ) const
+    {
+    TPtrC Invalid( KPECharsThatCanBeDelete );
+
+    return Invalid.Locate( aChar ) != ECCPErrorNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::IsValidChar
+// Checks if character is acceptable. If given charter can be located from 
+// KPEClientValidChars, method returns ETrue else EFalse.
+// -----------------------------------------------------------------------------
+//
+TBool CPEMessageHandler::IsValidChar( 
+        const TChar& aChar, //character to be checked
+        const TDesC& aValidChars ) const
+    {
+    return aValidChars.Locate( aChar ) != ECCPErrorNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::RemoveInvalidChars
+// Check all characters validity from descriptor one by one. 
+//    (1) If chater is valid then OK and next charter... 
+//    (2) If invalid check if that can be delete from string.
+//    (3) If it can be delete then DELETE and next charter... 
+//    (4) But if charter can NOT be delete then return value is EFalse.
+// -----------------------------------------------------------------------------
+//
+TBool CPEMessageHandler::RemoveInvalidChars( 
+        TDes& aString, //string to be processed
+        const TDesC& aValidChars,
+        const TBool aCheckForDelete ) const
+    {
+    TBool returnValue = ETrue;
+    TInt index = aString.Length() - 1;
+
+    TEFLOGSTRING2( KTAGENERAL, 
+        "PE: CPEMessageHandler::RemoveInvalidChars, String to parse = %S", &aString );
+
+    for ( ; index >= 0; index-- )
+        {
+        if ( !IsValidChar( aString[ index ], aValidChars ) )//(1)
+            {
+            if ( !aCheckForDelete 
+                || ( aCheckForDelete && IsItCharThatCanDelete( aString[index] ) ) )//(2)
+                {
+                aString.Delete( index, 1 ); // one character  //(3)
+                }
+            else
+                {
+                returnValue = EFalse;//(4) //if String includes alphabets or other forbidden characters return TFalse
+                }
+            }
+        }
+    if ( aCheckForDelete )
+        {
+        TLex input( aString );
+
+        TLexMark start;
+        input.Mark( start );
+
+        while ( input.Peek().IsDigit() ) 
+            {
+            input.Inc();
+            }
+
+        TPtrC mainpart( input.MarkedToken( start ) );
+        if ( mainpart.Length() )
+            {
+            aString = mainpart;
+            }
+    
+        if ( input.Remainder().Length() > 0 )
+            {
+            TPEDtmfString dtmfString = input.Remainder();
+            iDataStore.SetDtmfStringCommand( dtmfString );
+            }
+        else
+            {
+            TPEDtmfString dtmfString( KNullDesC );
+            iDataStore.SetDtmfStringCommand( dtmfString );
+            } 
+        
+        }
+    TEFLOGSTRING2( 
+        KTAGENERAL, 
+        "PE: CPEMessageHandler::RemoveInvalidChars, Parsed string = %S", 
+        &aString);
+    return returnValue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleGetLifeTimerData
+// Reads lifetimerdata from custom api and stores it to engine info
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleGetLifeTimerData() const
+    {
+    TCCPLifeTimeData lifeTimeData; 
+    TCCPLifeTimeDataPckg pckg( lifeTimeData );
+
+    if ( iCallHandling.GetLifeTime( pckg ) )
+        {
+        TEFLOGSTRING2( 
+            KTAGENERAL, 
+            "PE: CPEMessageHandler::HandleGetLifeTimerData, iHours = %d", 
+            lifeTimeData.iHours);
+        TEFLOGSTRING2( 
+            KTAGENERAL, 
+            "PE: CPEMessageHandler::HandleGetLifeTimerData, iMinutes = %d", 
+            lifeTimeData.iMinutes);
+            
+        iDataStore.SetLifeTimerData( pckg );
+        }
+    
+    return ECCPErrorNone;
+    }
+    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::CallbackSendMessageStoppedDTMF
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::CallbackSendMessageStoppedDTMF( TAny* aAny )
+    {
+    __ASSERT_ALWAYS( aAny , Panic( EPEPanicNullPointer ) );
+    CPEMessageHandler* self = static_cast<CPEMessageHandler*>(aAny);
+
+    delete self->iAsyncCallBack;
+    self->iAsyncCallBack = NULL;
+    self->iModel.SendMessage( MEngineMonitor::EPEMessageStoppedDTMF ); 
+
+    return ECCPErrorNone;
+    }
+    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::RemovePlusPrefix
+// Remove '+' from begin of the string
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::RemovePlusPrefix(
+    TPEPhoneNumber& aPhoneNumber )
+    {
+    TLex input( aPhoneNumber);
+
+    if ( input.Peek() == KPEDtmfPlusChar )
+        {
+        // remove plus char 
+        input.Inc();
+        aPhoneNumber = input.Remainder();
+        TEFLOGSTRING2( KTAMESINT, 
+            "PE CPEMessageHandler::RemovePlusPrefix(), aPhoneNumber: %S"
+            , &aPhoneNumber ); 
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleBuildConferenceCall
+// Handles Create conference message from phone application.
+// Method calls BuildConference method from MPECallHandling object.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleBuildConferenceCall()
+    {
+    return iCallHandling.BuildConference();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleGoOneToOne
+// Handles GoOneToOne message from PhoneApplication. Calls GoOneToOne
+// method from CallHandling object.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleGoOneToOne()
+    {
+    TInt callId = iDataStore.CallId();
+    __ASSERT_DEBUG( CallIdCheck::IsVoice( callId ), 
+        Panic( EPEPanicCallIndexOutOfRange ) );
+    return iCallHandling.GoOneToOne( callId );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleAddConferenceMember
+// Handles Add conference member message from phone application.
+// Method creates AddMember request to the CallHandling object.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleAddConferenceMember()
+    {
+    TEFLOGSTRING( KTAINT, 
+       "PE CPEMessageHandler::HandleAddConferenceMember ");
+    return iCallHandling.AddConferenceMember();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleAddConferenceMember
+// Handles dropped conference member message from callhandling subsystem.
+// In case a long dtmf string is being sent, cancels the sending process.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleDroppedConferenceMember()
+    {
+    TEFLOGSTRING( KTAINT, 
+       "PE CPEMessageHandler::HandleDroppedConferenceMember");
+    
+    StopDtmfSending();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleCallHandlingError
+// Handles error message from CallHandling subsystem
+// Method fetches error code from CallHandling subsystem and
+// Method sends error code to SAT
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::HandleCallHandlingError(
+        const TInt aCallId,
+        const TBool /*aBusyCall*/ )
+    {
+    // Call data not valid for call id -1, i.e. non-call error situations
+    if ( aCallId != KPECallIdNotUsed )
+        {
+        //Update local call info
+        const TInt errorCode = iCallHandling.GetCallInfo( *iCallInfo, aCallId );
+        
+        // Take the error from call handling.
+        TInt errorForClient = iDataStore.ErrorCode(); 
+        if (  errorCode == ECCPErrorNone )
+            {
+            const TInt diagnosticInfo = 
+                iCallHandling.CallTerminatedError( aCallId );
+            if ( diagnosticInfo != ECCPErrorNone )
+                {
+                errorForClient = diagnosticInfo;
+                }
+            }
+        
+        TEFLOGSTRING2( KTAINT,
+                "PE CPEMessageHandler::HandleCallHandlingError, SendRespond errorForClient: %d", errorForClient );
+        iClientServices->CallRequestMonitor()->SendRespond( errorForClient );            
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleEngineInfo
+// Handles call logging. Method add and update the call info.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleEngineInfo(
+    const TInt aCallId )       
+    {
+    TEFLOGSTRING2( KTAINT,
+        "PE CPEMessageHandler::HandleEngineInfo, call id: %d", aCallId );
+    TInt errorCode(  ECCPErrorNone );
+    TPEState callState;
+    
+    errorCode = FindCallInfo( aCallId );
+
+    if ( !errorCode )
+        {
+        callState = iCallHandling.GetCallState( aCallId );
+        TEFLOGSTRING2( KTAINT, 
+            "PE CPEMessageHandler::HandleEngineInfo, call state: %d", 
+            callState );
+
+        SetPhoneNumberForCallLogging( aCallId );
+
+        if ( callState == EPEStateDialing || callState == EPEStateRinging )
+            {
+            errorCode = UpdateClientInfo( aCallId );
+
+            iDataStore.SetRemoteIdentity( 
+                static_cast< RMobileCall::TMobileCallRemoteIdentityStatus > ( 
+                    iCallInfo->iRemoteParty.iRemoteIdStatus ), 
+                aCallId );
+            iTime.UniversalTime();
+            iDataStore.SetCallStartTime( iTime, aCallId );
+            iDataStore.SetCallDuration( 0, aCallId );
+            }
+
+        // Calls have to log also without a contact (ECCPErrorNotFound).
+        if ( errorCode == ECCPErrorNone || errorCode == ECCPErrorNotFound)
+            {
+            errorCode = ECCPErrorNone;
+            
+            // If call is emergency call, phonenumber must be fetched from engine info
+            // Log type must be recognized from call id also, because in idle state
+            // TSY has cleaned call info information
+            CheckAndHideIdentity( aCallId );
+
+            // Save the rest of information to EngineInfo.
+            SetLoggingInfo( aCallId, callState );
+            // Set missed call to EngineInfo.
+            IsMissedCall( aCallId, callState );
+            errorCode = iLogHandling.SaveCallEntry( aCallId );
+            }
+        } //if ( !errorCode )
+        
+    return errorCode;
+    }   
+ 
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::UpdateClientInfo
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::UpdateClientInfo( 
+    const TInt aCallId )
+    {
+    TInt errorCode( ECCPErrorNone );
+    const MPEClientInformation& clientInformation = iDataStore.CallClientInformation( aCallId );
+    
+    TEFLOGSTRING2( 
+        KTAINT, 
+        "PE CPEMessageHandler::UpdateClientInfo, remote name: '%S'", 
+        &iDataStore.RemoteName( aCallId ) );
+
+    TEFLOGSTRING2( 
+        KTAINT, 
+        "PE CPEMessageHandler::UpdateClientInfo, name: '%S'", 
+        &clientInformation.Name() );
+
+    TEFLOGSTRING2( 
+        KTAINT, 
+        "PE CPEMessageHandler::UpdateClientInfo, allowmatch: %d", 
+        clientInformation.AllowMatch() );
+    
+    if ( clientInformation.AllowMatch() && ( aCallId != KPEEmergencyCallId ) )
+        {
+        TEFLOGSTRING2( 
+            KTAINT, 
+            "PE CPEMessageHandler::UpdateClientInfo, match phone number: '%S'", 
+            &iDataStore.RemotePhoneNumber( aCallId ) );
+        if ( clientInformation.ContactLink().Length() > 0 )
+            {
+            errorCode = iContactHandling.FindContactInfoSync( 
+            aCallId, 
+            EPEFindWithContactId );
+            }    
+        else
+            {
+            errorCode = iContactHandling.FindContactInfoSync( 
+            aCallId, 
+            EPEFindWithPhoneNumber );            
+            }
+            
+        TEFLOGSTRING2( 
+            KTAINT, 
+            "PE CPEMessageHandler::UpdateClientInfo > MPEContactHandling::FindContactInfoSync( EPEFindWithPhoneNumber ), error code: %d", 
+            errorCode );
+        }
+    else if ( clientInformation.Name().Length() )
+        {
+        iDataStore.SetRemoteName( clientInformation.Name(), aCallId );
+        }
+    
+    // Calls have to log also without a contact (ECCPErrorNotFound).
+    if ( errorCode == ECCPErrorNone || errorCode == ECCPErrorNotFound)
+        {
+        // Set name to EngineInfo
+        SetName( aCallId );
+        }
+     return errorCode;   
+     }   
+    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::CheckAndHideIdentity
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::CheckAndHideIdentity(
+    const TInt aCallId )   
+    {
+    // If call is emergency call, phonenumber must be fetched from engine info
+    // Log type must be recognized from call id also, because in idle state
+    // TSY has cleaned call info information
+    RMobileCall::TMobileCallRemoteIdentityStatus tempIdentity;
+    tempIdentity = iDataStore.RemoteIdentity( aCallId );
+    
+    TEFLOGSTRING2( KTAINT,
+        "PE CPEMessageHandler::CheckAndHideIdentity, Identity: %d", tempIdentity );
+    if ( iCallInfo->iEmergency || aCallId == KPEEmergencyCallId ) 
+        {
+        iDataStore.SetRemotePhoneNumberType( EPEEmergencyNumber, aCallId );
+        }
+    else if( iDataStore.CallDirection( aCallId ) != RMobileCall::EMobileOriginated )
+		{
+		switch( tempIdentity )
+			{
+			case RMobileCall::ERemoteIdentitySuppressed:
+				{
+				// It is neccessary to perform an additional check for available
+				// remote party phone number to comply with Italian operator
+				// requirement: "If CLIR is active but network still provides
+				// the device with a phone number, it should not be blocked
+				// but passed to a client when requested."
+				if( iDataStore.RemotePhoneNumber( aCallId ).Length() == 0 )
+					{
+					HideIdentification( EPEPrivateNumber, aCallId );
+					}
+				else
+				    {
+				    // Align remote identity with remote phone number availability.
+				    iDataStore.SetRemoteIdentity( RMobileCall::ERemoteIdentityAvailable, aCallId );
+				    }
+				break;
+				}
+			case RMobileCall::ERemoteIdentityAvailableNoCliRejectedByUser:
+				{
+				HideIdentification( EPEPrivateNumber, aCallId );
+				break;
+				}
+			case RMobileCall::ERemoteIdentityUnknown:
+			case RMobileCall::ERemoteIdentityAvailableNoCliInteractionWithOtherService:
+			case RMobileCall::ERemoteIdentityUnavailableNoCliInteractionWithOtherService:
+			case RMobileCall::ERemoteIdentityAvailableNoCliCoinOrPayphone:
+			case RMobileCall::ERemoteIdentityUnavailableNoCliCoinOrPayphone:
+			case RMobileCall::ERemoteIdentityAvailableNoCliUnavailable:
+				{
+				HideIdentification( EPEUnknownNumber, aCallId );
+				break;
+				}
+			case RMobileCall::ERemoteIdentityAvailable:
+			default:
+				{
+				TEFLOGSTRING( KTAINT,
+					"PE CPEMessageHandler::CheckAndHideIdentity, CLI available" );
+				break;
+				}
+			}
+		}
+	}
+    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::FindCallInfo
+// Return callInfo from Etel/TSY.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::FindCallInfo(
+        const TInt aCallId )
+    {
+    TInt errorCode( ECCPErrorNone );
+    if ( CallIdCheck::IsVoice( aCallId ) || CallIdCheck::IsVideo( aCallId ) )
+        {
+        // Single call
+        errorCode = iCallHandling.GetCallInfo( *iCallInfo, aCallId );
+        TEFLOGSTRING3( 
+            KTAREQOUT, 
+            "CNT CPEMessageHandler::FindCallInfo > MPECallHandling::GetCallInfo, call id: %d, error code: %d", 
+            aCallId, 
+            errorCode );
+        TEFLOGSTRING2( 
+            KTAINT, 
+            "CNT CPEMessageHandler::FindCallInfo, remote number: '%S'", 
+            &iCallInfo->iRemoteParty.iRemoteNumber );
+        TEFLOGSTRING2( 
+            KTAINT, 
+            "CNT CPEMessageHandler::FindCallInfo, direction: %d", 
+            iDataStore.CallDirection( aCallId ) );
+        TEFLOGSTRING2( 
+            KTAINT, 
+            "CNT CPEMessageHandler::FindCallInfo, id status: %d", 
+            iCallInfo->iRemoteParty.iRemoteIdStatus );
+        }
+    else
+        {
+        // We don't log the master conference call and other unknown calls.
+        errorCode = KErrUnknown;
+        }
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::SetPhoneNumberForCallLogging
+// Set phonenumber for call logging
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::SetPhoneNumberForCallLogging(
+        const TInt aCallId )
+    {
+    // if call is MO then the phonenumber must be stored from dialled party.
+    if ( iDataStore.CallDirection( aCallId ) == RMobileCall::EMobileOriginated )
+        {
+
+        TPEPhoneNumber number;        
+        const TPECallOrigin origin = iDataStore.CallOrigin( aCallId );
+        
+        if ( origin == EPECallOriginSAT )
+            {
+            // Dont set for SAT calls >> number not logged
+            }
+        else if( iDataStore.PhoneNumber().Length() )
+            {
+            // Phonenumber given by user, includes pfe- and postfix.
+            number = iDataStore.PhoneNumber();
+            }   
+        else
+            {
+            // If call is made using ETel api, then phonenumber must take from callinfo.
+            number = iCallInfo->iDialledParty.iTelNumber;
+            }
+        
+        
+        // WholeOutgoingPhoneNumber should set only one time because in connected state 
+        // PhoneNumber is cleaned from datastore.
+        if( !iDataStore.WholeOutgoingPhoneNumber( aCallId ).Length() )
+            {
+        
+            TEFLOGSTRING2( KTAINT,
+                    "PE CPEMessageHandler::SetPhoneNumberAndDataCallLogging, number: '%S'"
+                    ,&number );
+            iDataStore.SetWholeOutgoingPhoneNumber( number, aCallId ); 
+            }
+        
+        // RemotePhoneNumber should set only one time because user can edit DataStore::PhoneNumber after dialing was started.
+        if( !iDataStore.RemotePhoneNumber( aCallId ).Length() )
+            {
+            TEFLOGSTRING3( 
+                KTAMESINT, 
+                "PE CPEMessageHandler::SetPhoneNumberForCallLogging, remote phone number: '%S', call id: %d", 
+                &number, aCallId );
+                                         
+            RemovePreAndPostFix( number );
+  
+            iDataStore.SetRemotePhoneNumber( number, aCallId );
+            }
+        
+        // The Colp number is stored to remoteparty in connected state.
+        TPEPhoneNumber colpNumber = iCallInfo->iRemoteParty.iRemoteNumber.iTelNumber;
+        RemovePreAndPostFix( colpNumber );
+        iDataStore.SetRemoteColpNumber( colpNumber, aCallId ); 
+        TEFLOGSTRING3( 
+            KTAMESINT, 
+            "PE CPEMessageHandler::SetPhoneNumberForCallLogging, colp number: '%S', call id: %d", 
+            &colpNumber, aCallId );
+        }
+    else if ( iDataStore.CallDirection( aCallId ) == RMobileCall::EMobileTerminated )
+        {
+        iDataStore.SetRemotePhoneNumber( iCallInfo->iRemoteParty.iRemoteNumber.iTelNumber, aCallId );
+        TEFLOGSTRING2( 
+            KTAMESINT, 
+            "PE CPEMessageHandler::SetPhoneNumberForCallLogging: remote phone number: '%S'", 
+            &iCallInfo->iRemoteParty.iRemoteNumber.iTelNumber );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::SetLoggingInfo
+// Store call information for logging
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::SetLoggingInfo(
+        const TInt aCallId,
+        TPEState aCallState )
+    {
+    if ( aCallState == EPEStateConnected )
+        {
+        iDataStore.SetCallStartTime( iCallInfo->iStartTime, aCallId );   
+        }
+    iDataStore.SetCallForwarded( iCallInfo->iForwarded, aCallId );
+    iDataStore.SetCallService( iCallInfo->iService, aCallId );
+    iDataStore.SetCallState( aCallState, aCallId );
+    iDataStore.SetCallDuration( iCallInfo->iDuration.Int() );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::SetName
+// Set calling name or client name to RemoteInfo.
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::SetName( const TInt aCallId )
+    {
+    if ( iDataStore.RemoteName( aCallId ).Length() <= 0 &&
+         iDataStore.RemoteCompanyName( aCallId ).Length() <= 0 &&
+         iCallInfo->iRemoteParty.iCallingName.Length() >0 ) 
+        { 
+        iDataStore.SetRemoteName( iCallInfo->iRemoteParty.iCallingName, aCallId );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HideIdentification
+// Hide identification to RemoteInfo.
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::HideIdentification(
+        TPEPhoneNumberIdType aPhoneNumberId,
+        const TInt aCallId )
+    {
+    TEFLOGSTRING2( KTAINT,
+        "PE CPEMessageHandler::HideIdentification: aPhoneNumberId = %d", aPhoneNumberId );
+    iDataStore.SetRemotePhoneNumberType( aPhoneNumberId, aCallId );
+    iDataStore.SetRemotePhoneNumber( KNullDesC(), aCallId );
+    iDataStore.SetRemoteName( KNullDesC(), aCallId );
+    iDataStore.SetRemotePartyName( KNullDesC(), aCallId );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::IsMissedCall
+// Check missed call in the idle state.
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::IsMissedCall(
+        const TInt aCallId,
+        TPEState aCallState )
+    {
+    if ( iDataStore.CallDirection( aCallId ) == RMobileCall::EMobileTerminated )
+        {
+        // If remote party has hanged up the current call on Ringing state, 
+        // this call is the missed call in the idle state.
+        if ( aCallState == EPEStateIdle )
+            {
+            TBool missedCall = EFalse;
+
+            if ( CallIdCheck::IsVoice( aCallId ) || CallIdCheck::IsVideo( aCallId ) )
+                {
+                iCallHandling.GetMissedCall( missedCall, aCallId );
+                }
+
+            iDataStore.SetMissedCall( missedCall, aCallId );
+            } 
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleCancelSSstringCommand
+// Handles cancel SS string command.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleCancelSSstringCommand()
+    {
+    TInt returnValue( ECCPErrorNone );
+
+    returnValue = iSSHandler->Cancel();
+
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleConferenceIdleState
+// Handles EPEMessageConferenceIdle message.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleConferenceIdleState( 
+        const TInt aCallId )
+    {
+    TInt counter;
+    TInt conferenceValue;
+
+    TTimeIntervalSeconds duration;
+    TInt errorCode = iCallHandling.GetCallDuration( duration, aCallId );
+    
+    // Duration offset is stored previously to data store using conference members
+    // duration. If we do not check for null here then the stored offset is ignored..
+    if ( ECCPErrorNone == errorCode && duration.Int() > 0 ) 
+        {
+        // Set last conference duration
+        iDataStore.SetCallDuration( duration.Int() );
+        }
+    else if ( ECCPErrorNone == errorCode && duration.Int() == 0 )
+        {
+        // copy conference call duration to last call duration
+        // all call specific data is erased a few lines down
+        iDataStore.SetCallDuration( iDataStore.CallDuration( aCallId ).Int() );
+        }   
+
+    //Reset values to the TPECallInfo structure
+    iDataStore.ResetCallInfo( aCallId );
+
+    // Reset Conference Master info from all ex-members
+    for ( counter = 0; counter < KPEMaximumNumberOfVoiceCalls; counter++ )
+        {
+        conferenceValue = iDataStore.CallConference( counter );
+        if ( conferenceValue == aCallId )
+            {
+            iDataStore.SetCallConference( KPENormalVoiceCall, counter );
+            }
+        }
+    
+    //Stops possible ringing tone playing
+    //APS Stops possible remote alerting tone playing
+    TEFLOGSTRING( KTAMESINT, 
+        "PE  CPEMessageHandler::HandleConferenceIdleState > iGsmAudioData.StopInbandTonePlay()");
+    iGsmAudioData.StopInbandTonePlay(); 
+    
+    ClearCallAudio();    
+        
+    return ECCPErrorNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleConnectedState
+// Handles connected message from the CallHandling subsystem 
+// 
+//  Method fetches call state and ALS line values from the Callhandling subsystem and then
+//  Method fetches remote information from the CPEEngineInfo class and then
+//  Method sets new values to the logInfo parameters and then
+//  Method updates call values to the LogHandling subsystem and then
+//  Method sets new values to the CPEEngineInfo class and then
+//  Method fecths possible dtmf string from the CPEParserPhoneNumberHandler class and then
+//  Method calls HandleSendDtmf method if dtmf string lenght was more than zero.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleConnectedState( 
+        const TInt aCallId )
+    {
+    TInt errorCode( ECCPErrorNone );
+    TPEState callState;
+    TPEDtmfString dtmfString;
+
+    RMobileCall::TMobileCallDirection callDirection;
+    callDirection = iDataStore.CallDirection( aCallId );
+
+    //Stops possible local playing of remote alerting tone
+    TEFLOGSTRING( 
+        KTAMESINT, 
+        "PE  CPEMessageHandler::HandleConnectedState: Calling iGsmAudioData.StopInbandTonePlay()");
+    iGsmAudioData.StopInbandTonePlay();
+
+    //If call was held then no logging is done.
+    callState = iDataStore.CallState( aCallId );
+    if ( callState != EPEStateHeld )
+        {
+        errorCode = HandleEngineInfo( aCallId );
+
+        // If phone number has contained dtmf string, phone engine sends dtmf string now.
+        // Only in MO - call.
+
+        if ( callDirection == RMobileCall::EMobileOriginated )
+            {
+            if ( aCallId == KPEEmergencyCallId )
+                {
+                dtmfString = iDataStore.DtmfStringCommand();
+                if ( dtmfString.Length() > 0 )
+                    {
+                    errorCode = HandleSendDtmf();
+                    }
+                }
+             else 
+                {
+
+                dtmfString = iDataStore.DtmfPostFix( aCallId );
+				
+                if ( dtmfString.Length() > 0 )
+                    {
+                    iDataStore.SetDtmfStringCommand( dtmfString );
+                    errorCode = HandleSendDtmf();
+                    }
+                }
+
+            iDataStore.SetErrorCode( errorCode );
+            }
+        }
+    // For Sat call ( normal or emergency )    
+    iClientServices->CallRequestMonitor()->SendRespond( ECCPErrorNone );
+    
+    // Reset Phonenumber from engine info, this is necessary so that call number
+    // logging works OK (see CPEMessageHandler::SetPhoneNumberForCallLogging).  
+    iDataStore.SetPhoneNumber( KNullDesC() );
+    
+    // COLP number is updated in connected state 
+    UpdateRemotePartyInfo();
+   
+    return ECCPErrorNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDialCall
+// Handles dial message from phone application
+// 
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleDialCall(
+    const TBool aClientCall )
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleDialCall" );
+    TInt errorCode( ECCPErrorNone );
+
+    TRAPD( trapError, errorCode = HandleDialCallL( aClientCall ));
+
+    if ( trapError )    
+        {
+        if ( aClientCall )    
+            {
+            iClientServices->CallRequestMonitor()->SendRespond( trapError );                    
+            }
+        TEFLOGSTRING2( KTAINT, "PE CPEMessageHandler::HandleDialCall: trapError = %d", trapError );
+        return trapError;
+        }
+    return errorCode;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDialEmergencyCall
+// Handles dial message from phone application
+// 
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleDialEmergencyCall(
+    const TBool aClientCall )
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleDialEmergencyCall" );
+    TInt errorCode( ECCPErrorNone );
+
+    if( iEmergencyCallActive && aClientCall )
+        {
+        // Client tried to make an emergency call even though we already
+        // have an active emergency call.
+        iClientServices->CallRequestMonitor()->SendRespond( ECCPErrorAlreadyInUse );
+        // Notify PhoneApp which is responsible for showing the error note
+        return ECCPErrorAlreadyInUse;
+        }
+    
+    iDataStore.SetCallTypeCommand( EPECallTypeCSVoice );
+        
+    // Check the phone number and change the prefix if needed
+    CheckPrefix();
+    
+    if ( aClientCall )
+        {
+        TPEPhoneNumber phoneNumber = iDataStore.PhoneNumber();
+        __ASSERT_DEBUG( !( phoneNumber == KNullDesC ), Panic( EPEPanicInvalidParameter));
+
+        TBuf<KPEPhoneNumberMaxLength> tempPhoneNumber = phoneNumber;
+        RemoveInvalidChars( tempPhoneNumber, KPEClientValidChars, ETrue );
+        RemovePreAndPostFix( tempPhoneNumber );
+        
+        SetClientInformation( KPEEmergencyCallId, tempPhoneNumber );
+        iClientServices->CallRequestMonitor()->SendRespond( ECCPErrorNone );
+        }
+
+    if ( IsActiveVideo() )
+        {
+        // PhoneApp needs to request releasing of data port from video telephony engine
+        // Emergency call initialization will continue after receiving MPEPhoneModel::
+        // EPEMessageContinueEmergencyCallInitialization
+        iModel.SendMessage( MEngineMonitor::EPEMessageInitiatedEmergencyWhileActiveVideo );
+        }
+    else
+        {
+        ContinueDialEmergency();
+        }
+
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDialCallL
+// Handles dial message from phone application
+// 
+//  Method fecths phone number from the CPEEngineInfo class and then
+//  Method sets process type to the CPEParserPhoneNumberHandler and then
+//  Method fecths clir settings from the Settings utility subsystem and tehn
+//  Method fecths call parameters from the CallHandling subsystem and then
+//  Method sets updated call parameter to the CallHandling subsystem and then
+//  Method parsers phonenumber and then
+//  Method process parsing result with PhoneParser
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleDialCallL(
+    const TBool aClientCall )
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleDialCallL" );
+    TBool parsingResult;
+    TPEPhoneNumber phoneNumber;
+    TInt errorCode( ECCPErrorNone );
+    TInt numberOfCalls;
+    
+    if ( aClientCall )
+        {
+        HandleClientCallData();
+        }
+        
+    //Get number of calls
+    numberOfCalls = iCallHandling.GetNumberOfCalls();
+
+    // Check the phone number for prefix change and change the prefix if needed
+    CheckPrefix();
+
+    phoneNumber = iDataStore.PhoneNumber();
+  
+    __ASSERT_ALWAYS( !( phoneNumber == KNullDesC ), User::Leave( ECCPErrorInvalidPhoneNumber ));
+    
+    // Number parser operations
+    iOptions->SetOptionStatus( KPhoneOptionSend, ETrue );
+    iOptions->SetOptionStatus( KPhoneOptionInCall, numberOfCalls > 0 );
+    // If voip call request
+    if( iDataStore.CallTypeCommand() == EPECallTypeVoIP )
+        {
+        iOptions->SetOptionStatus( KPhoneOptionVoipCall, ETrue );
+        }
+    else
+        {
+        iOptions->SetOptionStatus( KPhoneOptionVoipCall, EFalse );
+        }
+
+    parsingResult = iParser->ParseL( phoneNumber, *iResult, *iOptions );
+    if ( parsingResult )
+        {
+        iGsmParserErrorCode = ECCPErrorNone;
+        iParserHandlerContainer->ProcessL( *iResult );
+        errorCode = iGsmParserErrorCode;
+        }
+    else
+        {
+        // string was not recognised by any of the parser objects
+        TEFLOGSTRING( KTAERROR, 
+            "PE CPEMessageHandler::HANDLEDIALCALLL: PHONEPARSER DID NOT RECOGNIZE THE STRING!" );
+        errorCode = KErrArgument;
+        }
+
+    if ( aClientCall )
+        {
+        // Do not sent the response to SAT, unless there is error.
+        const TPECallOrigin& origin = iDataStore.CallOriginCommand();            
+        if ( origin != EPECallOriginSAT || errorCode )    
+            {
+            iClientServices->CallRequestMonitor()->SendRespond( errorCode );                    
+            }
+        }
+
+    TEFLOGSTRING2( KTAINT, "PE CPEMessageHandler::HandleDialCallL: errorCode = %d", errorCode );
+        
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleSatCallRequestCompleted
+// Sends respond to SAT after dial request completion
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::HandleSatCallRequestCompleted()
+    {
+    // Monitor with active request completes
+    iClientServices->CallRequestMonitor()->
+        SendRespond( iCallHandling.CallTerminatedError( iDataStore.CallId() ));                    
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDialEmergency
+// Handles emergency call message from phone application
+//
+//  Method calls DialEmergencyCall method from the CallHandling subsystem.
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::ContinueDialEmergency()
+    {
+    iDataStore.SetCallId( KPEEmergencyCallId );
+    if ( !iEmergencyCallActive )
+        {
+        iExternalDataHandler.Set( EPEEmergencyCallInfo, ETrue );  
+        iEmergencyCallActive = ETrue;        
+        }
+        // unmute mic
+        iDataStore.SetAudioMuteCommand( EFalse );
+        HandleSetAudioMute();
+
+    iCallHandling.DialEmergencyCall( iDataStore.PhoneNumber() );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDialingStateL
+// Handles dialing state transition for voice and video calls
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::HandleDialingStateL( 
+        const TInt aCallId )
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleDialingStateL <");
+    
+    if( iCallHandling.GetNumberOfCalls() == 1 )
+        {
+        // Check volume levels - zero level needs to be reset to default value
+        iGsmAudioData.SetDefaultVolume();
+        }
+    // Save call direction to engine info.
+    iDataStore.SetCallDirection( RMobileCall::EMobileOriginated, aCallId );
+    
+    // Log the call information.
+    User::LeaveIfError( HandleEngineInfo( aCallId ) );
+    
+    // publish remote party info to Mediator after contact matching is done
+    // as remote party info contains information from contact matching. 
+    UpdateRemotePartyInfo();
+    
+    TBool videoCall =
+        ( iDataStore.CallType( aCallId ) == EPECallTypeVideo ) ? ETrue : EFalse;
+
+    TEFLOGSTRING2(
+            KTAINT,
+            "CPEMessageHandler::HandleDialingStateL, callType: %d",
+            iDataStore.CallType( aCallId ) );
+        
+    // Determine the preferred output for call audio and route accordingly.
+    // Routing for incoming voice call is done in answering state.
+    HandleAudioRouting( videoCall, aCallId );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleIncomingCallL
+// Handles incoming voice and video call
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleIncomingCallL( 
+        const TInt aCallId )
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleIncomingCallL <");
+    
+    // Save call direction to engine info.
+    iDataStore.SetCallDirection( RMobileCall::EMobileTerminated, aCallId );
+
+    // Log the call information.
+    User::LeaveIfError( HandleEngineInfo( aCallId ) );
+    
+    // publish remote party info to Mediator after contact matching is done
+    // as remote party info contains information from contact matching. 
+    UpdateRemotePartyInfo();    
+    
+    TInt numberOfCalls = iCallHandling.GetNumberOfCalls();
+    
+    if( numberOfCalls > 1 )
+        {
+        TEFLOGSTRING( 
+            KTAMESINT, 
+            "PE  CPEMessageHandler::HandleIncomingCallL: Calling iGsmAudioData->PlayInbandTone() for call waiting tone");
+        iDataStore.SetInbandTone( ECCPCallWaiting );
+        iGsmAudioData.PlayInbandTone();
+        iWaitingCallId = aCallId;
+        }
+    else if( numberOfCalls == 1 )
+        {
+        // Check volume levels - zero level needs to be reset to default value
+        iGsmAudioData.SetDefaultVolume();
+        }
+    if( AutomaticAnswer( aCallId ) )
+        {
+        TEFLOGSTRING( KTAINT, 
+        "PE  CPEMessageHandler::HandleIncomingCallL: iAutomaticAnswerTimer->StartTimer");
+        iAutomaticAnswerTimer->StartTimer( KPEAutomaticAnswerTimeOut, MEngineMonitor::EPEMessageAnswer, aCallId );
+        }
+
+    // Cancel EnableService, if in progress
+    iServiceHandling.CancelServiceEnabling();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDisconnecting
+// Handles disconnecting. This means network doesn't play inband tones, but PE must play those.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleDisconnecting
+        (
+        const TInt /*aCallId*/  //The identification number of the call.
+        )
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleDisconnecting" );
+
+    iAutomaticAnswerTimer->Cancel();
+
+    TEFLOGSTRING( KTAMESOUT, 
+        "PE CPEMessageHandler::HandleDisconnecting > iGsmAudioData.PlayInbandTone()");
+    iGsmAudioData.PlayInbandTone();
+    
+    return ECCPErrorNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDisconnectingWithInband
+// Handles disconnecting with inband. This means network plays the inband tones
+// and PhoneEngine does not.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleDisconnectingWithInband(
+        const TInt /*aCallId*/ )
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleDisconnectingWithInband" );
+    return ECCPErrorNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDropConferenceMember
+// Handles drop message from phone application
+// Method calls DropMember method from CallHandling object.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleDropConferenceMember()
+    {
+    TInt callId = iDataStore.CallId();
+    __ASSERT_DEBUG( CallIdCheck::IsVoice( callId ), 
+        Panic( EPEPanicCallIndexOutOfRange ) );
+    return iCallHandling.DropMember( callId );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleHoldCall
+// Handles hold message from phone application
+// Method fecths call id number from the CPEEngineInfo class and then
+// Method calls HoldCall method from the CallHandling subsystem.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleHoldCall()
+    {
+    return iCallHandling.HoldCall();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleVoiceCallIdleState
+// Handles idle message from the CallHandling subsystem.
+//
+//  Method stops playing possible ringing tone and the
+//  Method gets call and ALS line information from the CallHandling subsystem and then
+//  Method fecth remote party information from the CPEEngineInfo class and then
+//  Method sets new values to the logInfo parameter and then
+//  Method updates log values to the LogHandling subsystem and then
+//  Method updates Engine Info's call terminated diagnostics value and then
+//  Method resets call information.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleVoiceCallIdleState( 
+    const TInt aCallId )
+    {
+    TInt errorCode( ECCPErrorGeneral );
+    TInt returnValue( ECCPErrorNone );
+    TInt numberOfCalls;
+
+    //Stops possible ringing tone playing
+    //APS Stops possible remote alerting tone playing
+    TEFLOGSTRING( KTAMESINT, 
+        "PE  CPEMessageHandler::HandleVoiceCallIdleState > iGsmAudioData.StopInbandTonePlay()");
+    iGsmAudioData.StopInbandTonePlay(); 
+    
+    ClearCallAudio();
+    
+    errorCode = iCallHandling.GetCallInfo( *iCallInfo, aCallId );
+    
+    if (  errorCode == ECCPErrorNone )
+        {
+        TInt diagnosticInfo = iCallHandling.GetCallTerminatedDiagnostics( 
+            iCallInfo->iCallName );
+        // if diagnosticInfo available set diagnostic error code to DataStore    
+        if ( diagnosticInfo != ECCPErrorNone )
+            {
+            iDataStore.SetErrorCode( diagnosticInfo );
+            }
+        }
+
+    errorCode = HandleEngineInfo( aCallId );  
+    iDataStore.SetErrorCode( ECCPErrorNone );
+
+    numberOfCalls = iCallHandling.GetNumberOfCalls();
+
+    if ( numberOfCalls == 0 )
+        {
+        // unmute mic
+        iDataStore.SetAudioMuteCommand( EFalse );
+        HandleSetAudioMute();
+        
+        if ( iEmergencyCallActive )
+            {
+            iExternalDataHandler.Set( EPEEmergencyCallInfo, EFalse );
+            iEmergencyCallActive = EFalse;
+            }
+        }
+
+    // If there is a waiting call (voice or data) on 
+    // the line, and no other calls, play ringing tones for it.
+    else if ( numberOfCalls == 1 )
+        {
+        TPEState callState;
+        callState = iCallHandling.GetCallState( iWaitingCallId );
+        // EPEStateRinging equals MT call
+        if( callState == EPEStateRinging )
+            {
+            // unmute mic
+            iDataStore.SetAudioMuteCommand( EFalse );
+            HandleSetAudioMute();
+            TEFLOGSTRING2( KTAMESINT, 
+                "CPEMessageHandler::HandleVoiceCallIdleState: aCallId = %d", 
+                aCallId );
+            }
+        else 
+            {
+            TEFLOGSTRING2( KTAMESINT, 
+                "CPEMessageHandler::HandleVoiceCallIdleState: callState = %d", 
+                callState );
+            }
+        }
+    else
+        {
+        TEFLOGSTRING2( KTAMESINT, 
+            "CPEMessageHandler::HandleVoiceCallIdleState: numberOfCalls = %d", 
+            numberOfCalls );
+        }
+    
+    iDataStore.ResetCallInfo( aCallId );    
+    
+    //publish remote party info to Mediator after call info has been cleared.
+    UpdateRemotePartyInfo();    
+
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::ProcessPlayDTMFL
+// Handles key down message from phone application
+//
+//  Method fecths key code value from the CallHandling subsystem and then
+//  Method calls StartDtmfTone method from the CallHandling subsystem.
+
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::ProcessPlayDTMFL()
+    {
+    const TChar keyCode = iDataStore.KeyCode();
+    
+    TBuf<1> keyCodeBuf;
+    keyCodeBuf.Append( keyCode );
+    
+    if ( KPEValidDTMFChars().Find( keyCodeBuf ) >= 0 )
+        {
+        if ( iCallHandling.GetNumberOfCalls() > 0 )
+            {   //There is ongoing call(s)
+            iCallHandling.StartDtmfTone( keyCode );
+            }
+        else
+            {
+            iGsmAudioData.PlayDtmfTone( keyCode );            
+            }
+        }
+        
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::ProcessEndDTMF
+// Handles end playing DTMF message from phone application
+// Method calls StopDtmfTone method from the CallHandling subsystem.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::ProcessEndDTMF()
+    {
+    TInt returnValue( ECCPErrorNone ); 
+    // Number parser operations
+    if ( iCallHandling.GetNumberOfCalls() > 0 )
+        {   //There is ongoing call(s)
+        returnValue =  iCallHandling.StopDtmfTone();
+        }
+    iGsmAudioData.StopDtmfTonePlay();
+    return returnValue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleRejectCall
+// Handles reject message from phone application
+//  Method stops playing possible ringing tone and then
+//  Method calls RejectCall method from the CallHandling subsystem.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleRejectCall
+        (
+        // None.
+        )
+    {
+    //Stops playing ringing tone
+    //Data call
+    iGsmAudioData.StopInbandTonePlay(); 
+    iAutomaticAnswerTimer->Cancel();
+    return iCallHandling.RejectCall( );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleResumeCall
+// Handles resume message from phone application
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleResumeCall()
+    {
+    return iCallHandling.ResumeCall();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleSendUssd
+// Handles request from CPEParserMiscHandler
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleSendUssd(
+        const TDesC& aString )   // USSD string to be sent.
+
+    {
+    return iClientServices->SendUssd( aString );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleSimStateChanged
+// Handles EPEMessageSIMStateChanged message from DosServer.
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::HandleSimStateChanged()  
+    {
+    iDataStore.SetSimState( iSimStateMonitor.SimState() );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleStartUpL
+// Handles startup message from the phone application.
+// Method calls StartUp method from the CallHandling subsystem and then
+// Method calls StartUp method from the AudioHandling subsystem and then
+// Method starts monitoring client originated calls.
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::HandleStartUp()
+    {
+    iCallHandling.StartUp( );
+    iGsmAudioData.StartUp( );
+    
+    iClientServices->StartMonitoring( );
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleVideoCallConnected
+// Handles data call logging in connected and idle state.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleVideoCallConnected(
+        const TInt aCallId )
+    {
+    //Stops possible remote alerting tone playing
+    TEFLOGSTRING( 
+        KTAINT, 
+        "PE  CPEMessageHandler::HandleVideoCallConnected > CPEGsmAudioData::StopInbandTonePlay()");
+    iGsmAudioData.StopInbandTonePlay(); 
+    // EFalse updates log information.
+    TInt errorCode = HandleEngineInfo( aCallId );
+    iDataStore.SetErrorCode( errorCode );
+    return ECCPErrorNone; 
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleVideoCallIdle
+// Handles data call logging and a possible waiting voice call in Idle state.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleVideoCallIdle(
+        const TInt aCallId )
+    {
+    TInt numberOfCalls;
+    //Stops possible remote alerting tone playing
+    TEFLOGSTRING( KTAINT,
+        "PE CPEMessageHandler::HandleVideoCallIdle > CPEGsmAudioData::StopInbandTonePlay()");
+    iGsmAudioData.StopInbandTonePlay(); 
+    HandleEngineInfo( aCallId );
+    iDataStore.SetErrorCode( ECCPErrorNone );
+    TInt returnValue( ECCPErrorNone );
+
+    numberOfCalls = iCallHandling.GetNumberOfCalls();
+    if ( numberOfCalls == 0 )
+        {
+        iGsmAudioData.HandleCallEnding();
+
+        // unmute mic
+        iDataStore.SetAudioMuteCommand( EFalse );
+        HandleSetAudioMute();
+        }
+    else if ( numberOfCalls == 1 )
+        {
+        TPEState callState;
+        callState = iCallHandling.GetCallState( iWaitingCallId );
+        // EPEStateRinging equals MT call
+        if ( callState == EPEStateRinging )
+            {
+            TEFLOGSTRING2( KTAMESINT, 
+                "CPEMessageHandler::HandleVideoCallIdle: aCallId = %d", 
+                aCallId );
+            iGsmAudioData.HandleCallEnding();
+            
+            // unmute mic
+            iDataStore.SetAudioMuteCommand( EFalse );
+            HandleSetAudioMute();
+            }
+        else 
+            {
+            TEFLOGSTRING2( KTAMESINT, 
+                "CPEMessageHandler::HandleVideoCallIdle: callState = %d", 
+                callState );
+            }
+        }
+    else
+        {
+        TEFLOGSTRING2( KTAMESINT, 
+            "CPEMessageHandler::HandleVideoCallIdle: numberOfCalls = %d", 
+            numberOfCalls );
+        }
+    iDataStore.ResetCallInfo( aCallId );
+    
+    //publish remote party info to Mediator after call info has been cleared.
+    UpdateRemotePartyInfo();    
+    
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleEmergencyCheck
+// Check is given number emergency number.
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleEmergencyCheck( )
+    {
+    TInt errorCode( ECCPErrorNone );
+    TPEPhoneNumber emergencyNumber;
+    TBool isEmergency;
+    emergencyNumber = iDataStore.PhoneNumber();
+
+    errorCode = iClientServices->IsEmergencyPhoneNumber( emergencyNumber, isEmergency );
+    if ( isEmergency  && errorCode == ECCPErrorNone )
+        {
+        iModel.SendMessage( MEngineMonitor::EPEMessageValidEmergencyNumber );
+        }
+    else
+        {
+        iModel.SendMessage( MEngineMonitor::EPEMessageInValidEmergencyNumber );
+        }
+
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandlePhoneNumberEditedL
+// Handles Phone Number Edited message from phone application, 
+// called when user is used paste or delete command.
+// Method check if there is ongoing call(s) if there is return ECCPErrorNone else
+// method fecths phone number from the CPEEngineInfo class and 
+// then method parsers phonenumber and then method process parsing result
+// with PhoneParser and Phoneengine.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+// 
+void CPEMessageHandler::HandlePhoneNumberEditedL()
+    {
+    TBool isServiceCode( EFalse );
+
+    iOptions->SetOptionStatus( KPhoneOptionInCall, 
+        ( iCallHandling.GetNumberOfCalls() > 0 ) );
+
+    iOptions->SetOptionStatus( KPhoneOptionSend, EFalse );
+    iOptions->SetOptionStatus( KPhoneOptionVoipCall, EFalse );
+
+    if( iParser->ParseL( iDataStore.PhoneNumber(), *iResult, *iOptions ) )
+        {
+        isServiceCode = ETrue;
+        iGsmParserErrorCode = ECCPErrorNone;
+        iParserHandlerContainer->ProcessL( *iResult );
+        }
+    else // check for service codes that require SEND
+        {
+        iOptions->SetOptionStatus( KPhoneOptionSend, ETrue );
+        if ( iParser->ParseL( iDataStore.PhoneNumber(), *iResult, *iOptions ) )
+            {
+            // if there is an incoming call only certain codes are allowed       
+            if ( iCallHandling.IsCallInState( EPEStateRinging ) &&
+                 !iCallHandling.IsCallInState( EPEStateConnected ) )
+                {
+                isServiceCode = PhoneGsmParser::IsAllowedForArriving( *iResult );
+                }
+            else
+                {
+                const PhoneGsmParser::TContentType type = 
+                    PhoneGsmParser::DetermineContentType( *iResult );
+                    
+                if ( type == PhoneGsmParser::EContentSupplementaryService ||
+                     type == PhoneGsmParser::EContentUnstructuredService )
+                    {
+                    isServiceCode = ETrue;
+                    }
+                }
+            }
+        }
+        
+    iDataStore.SetPhoneNumberIsServiceCode( isServiceCode );    
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::AutomaticAnswer
+// Checks if automatic answer is defined for connected accessory.
+// -----------------------------------------------------------------------------
+// 
+TBool CPEMessageHandler::AutomaticAnswer( const TInt aCallId ) const
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::AutomaticAnswer <" );
+    
+    TInt automaticAnswer( EFalse );
+    TInt accessory( 0 );
+         
+    if ( iCallHandling.GetNumberOfCalls() > 1 ) // The new call need to be the first in the array
+        {
+        return EFalse;
+        }
+        
+    iExternalDataHandler.Get( EPEAccessoryMode, accessory );
+    
+    switch ( accessory )
+        {
+        case EAccModeWiredHeadset:    //Wired headset
+        case EAccModeWirelessHeadset: //Wireless headset
+            {
+            // Safe to ignore error code here, 
+            // automatic answer setting just equals zero == EFalse if it fails
+            iExternalDataHandler.Get( EPEAutomaticAnswerHeadsetSetting, automaticAnswer );
+            break;
+            }
+        case EAccModeWiredCarKit:     //Wired carkit
+            {
+            iExternalDataHandler.Get( EPEAutomaticAnswerCarkitSetting, automaticAnswer );
+            break;
+            }           
+        case EAccModeWirelessCarKit:  //Wireless carkit
+            {
+            iExternalDataHandler.Get( EPEAutomaticAnswerWirelessCarkitSetting, automaticAnswer );                
+            break;
+            }           
+        case EAccModeLoopset:         //Loopset
+            {
+            iExternalDataHandler.Get( EPEAutomaticAnswerLoopsetSetting, automaticAnswer );                
+            break;
+            }           
+        case EAccModeMusicStand:      //Musicstand
+            {
+            iExternalDataHandler.Get( EPEAutomaticAnswerMusicStandSetting, automaticAnswer );                
+            break;
+            }
+         default:
+            break;
+         }
+
+    if ( automaticAnswer )
+        {
+        TFileName noneFilepath;
+        noneFilepath.Append( TParsePtrC( PathInfo::RomRootPath() ).Drive() );
+        noneFilepath.Append( KProfileNoSoundPath() );
+        
+        TProfileRingingType ringingType = iDataStore.RingingType(); 
+        TPEContactFileName ringingTone = iDataStore.RingingTone( aCallId );
+         
+        if ( ringingType == EProfileRingingTypeBeepOnce ||
+             ringingType == EProfileRingingTypeSilent ||
+             ringingTone == noneFilepath )
+            {
+            automaticAnswer = EFalse;
+            }
+        } 
+    TEFLOGSTRING2( KTAINT, 
+        "PE CPEMessageHandler::AutomaticAnswer > ret: %d", automaticAnswer );
+    return automaticAnswer;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleStopInbandTonePlay
+// Stop playing a InBand tone
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleStopInbandTonePlay()
+    {
+    iGsmAudioData.StopInbandTonePlay();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleAutomaticAnswerOff
+// Gets EPEMessageAutomaticAnswerOff from UI and makes soft cancelation of the
+// automatic answer when needed
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleAutomaticAnswerOff() const
+    {
+    iAutomaticAnswerTimer->Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleATDialingStarted()
+// Handles AT dialing completed message from Phone UI
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleATDialingStarted( const TBool aSucceed ) const
+    {
+    iClientServices->CommandHandlerMonitor()->DoCompleteCmdAtd( aSucceed ); 
+    }    
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::IsEmergencyAllowed()
+// Checks if emergency call is allowed. 
+// -----------------------------------------------------------------------------
+//
+TBool CPEMessageHandler::IsEmergencyAllowed() const
+    {
+    TBool networkConnectionAllowed( EFalse );
+    //It is safe to ignore error code here: a default value of EFalse is used if the get fails
+    iExternalDataHandler.Get( EPENetworkConnectionAllowedSetting, networkConnectionAllowed );
+    return networkConnectionAllowed;
+    }
+    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleClientCallData()
+// Handle Client Call Data.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleClientCallData() 
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleClientCallData" );
+    
+    CPhCltDialData* dialData = iClientServices->CallRequestMonitor()->ClientDialData();
+    
+    // Set already known Client information
+    SetClientData( *dialData );
+    
+    if ( dialData->CallType() == EPhCltVideo || dialData->CallType() == EPhCltForcedVideo )
+        {
+        iDataStore.SetCallTypeCommand( EPECallTypeVideo );
+        }
+    else if( dialData->CallType() == EPhCltCallVoIP )
+        {
+        iDataStore.SetCallTypeCommand( EPECallTypeVoIP );
+        }
+    else
+        {
+        iDataStore.SetCallTypeCommand( EPECallTypeCSVoice );
+        }
+        
+    // End other calls before dial SAT call
+    if ( dialData->EndOtherCalls() )
+        {
+        HandleReleaseAll();
+        TEFLOGSTRING( KTAINT,
+            "PE CPEMessageHandler::HandleClientCallData > HandleReleaseAll()" );
+         }       
+    }    
+    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::ClearCallAudio
+// Notifies audio handling that there is no active call and audio should be routed
+// accordingly.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::ClearCallAudio()
+    {
+    TEFLOGSTRING( KTAMESINT, "PE CPEMGsmessageHandler::ClearCallAudio()" );
+    TBool restrictingCalls( EFalse );
+
+    if ( iCallHandling.GetNumberOfCalls() > 0 )
+        {
+        restrictingCalls = 
+            // Single call states restricting the devsound notification
+            iCallHandling.IsCallInState( EPEStateConnected ) ||
+            iCallHandling.IsCallInState( EPEStateConnecting ) ||
+            iCallHandling.IsCallInState( EPEStateDialing ) ||
+            iCallHandling.IsCallInState( EPEStateHeld ) ||
+            // Conference call states restricting the devsound notification
+            ( iDataStore.CallState( KPEConferenceCallID )== EPEStateConnectedConference ) ||
+            ( iDataStore.CallState( KPEConferenceCallID ) == EPEStateCreatingConference ) ||
+            ( iDataStore.CallState( KPEConferenceCallID ) == EPEStateGoingOneToOne ) ||
+            ( iDataStore.CallState( KPEConferenceCallID ) == EPEStateAddingConferenceMember ) ||
+            ( iDataStore.CallState( KPEConferenceCallID ) == EPEStateAddedConferenceMember ) ||
+            ( iDataStore.CallState( KPEConferenceCallID ) == EPEStateDroppingConferenceMember ) ||
+            ( iDataStore.CallState( KPEConferenceCallID ) == EPEStateDroppedConferenceMember );
+        }
+    
+    if ( restrictingCalls == EFalse )
+        {
+        // deactivate audio
+        TEFLOGSTRING( KTAMESINT, "PE CPEMGsmessageHandler::ClearCallAudio() Deactivating" );
+        iGsmAudioData.HandleCallEnding();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleSwitchToVideoOrVoice 
+// This method handle EPEMessageSwitchToVideoOrVoice message. If current call id
+// is Data then call will be switched to Voice call and the other way around. 
+// Method set current phonenumber to dataStore and get call parameter and call 
+// hangUp to current call. 
+// When hangUp is completed (EPEMessageIdle was sent) sequence will be continue 
+// from ContinueSwitchToCall method.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleSwitchToVideoOrVoice( const TInt aCallId )
+    {
+    // First get the current phone number and then end voice call
+    // or video call.
+    TInt err( ECCPErrorNone );
+    
+    TEFLOGSTRING2( KTAINT, 
+        "PE CPEMessageHandler::HandleSwitchToVideoOrVoice, aCallId : %d", aCallId );
+    // if out of memory case then phonenumber is already datastore.
+    if( aCallId != KPECallIdNotUsed )
+        {
+        if ( iDataStore.CallDirection( aCallId ) == RMobileCall::EMobileOriginated )
+            {
+            iDataStore.SetSwitchToNumberCommand( iDataStore.WholeOutgoingPhoneNumber( aCallId ) );  
+            // Clear phonenumber to prevent using the wrong number in MO video call.
+            iDataStore.SetPhoneNumber( KNullDesC() );
+            }
+        else
+            {
+            iDataStore.SetSwitchToNumberCommand( iDataStore.RemotePhoneNumber( aCallId ) );
+            // Remote phone number must be stored as the phone number in case of low-memory situation where 
+            // an MO voice call can be initiated after failing to answer an MT video call.
+            iDataStore.SetPhoneNumber( iDataStore.RemotePhoneNumber( aCallId ) );
+            }
+
+        err = HandleReleaseCall();
+        }
+
+    return err;
+    }
+    
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::ContinueSwitchToCall
+// Metdod calls dial to multimedia call or voice call.
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::ContinueSwitchToCall( const TInt aCallId )  
+    {
+    TEFLOGSTRING2( KTAINT, 
+        "PE CPEMessageHandler::ContinueSwitchToCall, aCallId : %d", aCallId );
+    TInt callId;
+    TInt errorCode( ECCPErrorNone );
+  
+    TPEPhoneNumber phoneNumber = iDataStore.SwitchToNumberCommand();
+    TEFLOGSTRING2( KTAINT, 
+        "PE CPEMessageHandler::ContinueSwitchToCall, phoneNumber : %S", 
+        &phoneNumber );
+
+    // Check is current call voice or video
+    if ( CallIdCheck::IsVoice( aCallId ) )
+        {
+        // Create new video call to same phonenumber
+        iDataStore.SetCallTypeCommand( EPECallTypeVideo );
+        errorCode = iCallHandling.DialMultimedia( phoneNumber, callId );
+        }
+    else if ( CallIdCheck::IsVideo( aCallId ) )
+        {
+        // Create new voice call to same phonenumber
+        iDataStore.SetCallTypeCommand( EPECallTypeCSVoice );
+        errorCode = iCallHandling.DialCall( phoneNumber, callId );
+        }
+    TEFLOGSTRING2( KTAINT, 
+        "PE CPEMessageHandler::ContinueSwitchToCall(), error : %d", errorCode );    
+    return errorCode;    
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::RemovePreAndPostFix
+// Remmove supplementary service prefix and dtmf postfix.
+// Phone number can contain following parts: supplementary
+// service prefix, main part and dtmf postfix.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::RemovePreAndPostFix( 
+        TDes& aString )
+    {
+    // Check that string contains only valid dtmf characters.
+    if ( IsValidDtmfString( aString ))
+        {
+        TLex input( aString ); 
+        
+        RemovePrefix( input );
+        // Take number part.
+        HandleNumberPart( input, aString );        
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::RemovePrefix
+// Removes clir suppress/invoke prefix in the string.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::RemovePrefix( 
+        TLex& aLex )
+    {
+    TPtrC remainder( aLex.Remainder() );
+
+    if ( EqualsLeft( remainder, KPEClirSuppress ) )
+        {
+        aLex.Inc( KPEClirSuppress().Length() );
+        }
+    else if ( EqualsLeft( remainder, KPEClirInvoke ) )
+        {
+        aLex.Inc( KPEClirSuppress().Length() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleNumberPart
+// Search the main part of the phone number.
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleNumberPart(
+        TLex& aLex,
+        TDes& aNumberPart )
+    {   
+    TLexMark start;
+    aLex.Mark( start );
+  
+    // Optional forced call prefixes. 
+    if ( aLex.Peek() == KPENumberAsterisk || 
+         aLex.Peek() == KPENumberHash ) 
+         {
+         aLex.Inc(); 
+         }
+         
+    // Optional international prefix. 
+    if ( aLex.Peek() == KPENumberPlus ) 
+        { 
+        aLex.Inc(); 
+        } 
+
+    // And the rest of number. 
+    while ( ( aLex.Peek().IsDigit() ) ||  
+            ( aLex.Peek() == KPENumberAsterisk ) || 
+            ( aLex.Peek() == KPENumberHash ) ) 
+        {
+        aLex.Inc(); 
+        }
+
+    TPtrC mainpart( aLex.MarkedToken( start ) );
+    const TInt length = mainpart.Length();
+    if ( length <= KPEPhoneNumberMaxLength )
+        {
+        aNumberPart.Copy( mainpart );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::EqualsLeft
+// -----------------------------------------------------------------------------
+//
+TBool CPEMessageHandler::EqualsLeft( 
+        const TDesC& aString, 
+        const TDesC& aPrefix )
+    {
+    TBool result = EFalse;
+
+    if ( aPrefix.Length() <= aString.Length() )
+        {
+        TPtrC part( aString.Left( aPrefix.Length() ) );
+
+        result = ( part == aPrefix );
+        }
+
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleReplaceActive
+// -----------------------------------------------------------------------------
+// 
+TInt CPEMessageHandler::HandleReplaceActive()
+    {
+    return iCallHandling.ReplaceActive();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::CheckIfPhoneIsLockedL
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::CheckIfPhoneIsLockedL()
+    {
+    // Check if phone is locked
+    TInt  keyLockStatus( EAutolockStatusUninitialized );
+    TInt err = RProperty::Get( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus, keyLockStatus );
+    const TBool phoneIsLocked = ( keyLockStatus > EAutolockOff );
+
+    if ( phoneIsLocked && err == KErrNone )
+        {
+        // New call is not possible if device lock is on 
+        TEFLOGSTRING2( KTAERROR,
+            "PE CPEMessageHandler::CheckIfPhoneIsLockedL, keyLockStatus : %d", keyLockStatus );
+        User::Leave( ECCPErrorAuthenticationFailed );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::IsActiveVideo
+// Checks if there are any connected video calls
+// -----------------------------------------------------------------------------
+// 
+TBool CPEMessageHandler::IsActiveVideo()
+    {
+    TBool activeVideoCall( EFalse );
+    
+    TInt callId = iCallHandling.GetCallIdByState( EPEStateConnected );
+    if ( callId > ECCPErrorNotFound && iDataStore.CallType( callId ) == EPECallTypeVideo )
+        {
+        activeVideoCall = ETrue;
+        }
+    return activeVideoCall;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleServiceEnabled
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleServiceEnabled()
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleServiceEnabled ");
+
+    
+    return iVoipNumberHandler->ContinueVoipDial();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleRemotePartyInfoChanged
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleRemotePartyInfoChanged()
+    {
+    UpdateRemotePartyInfo();      
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleUnattendedTransferRequestResponse
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleUnattendedTransferRequestResponse( 
+        TBool aAcceptRequest )
+    {
+    TEFLOGSTRING( KTAINT, 
+        "PE CPEMessageHandler::HandleUnattendedTransferRequestResponse" );
+    
+    if ( aAcceptRequest )
+        {
+        return iCallHandling.AcceptUnattendedTransfer();
+        }
+    else
+        {
+        return iCallHandling.RejectUnattendedTransfer();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleUnattendedTransfer
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::HandleUnattendedTransfer()
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleUnattendedTransfer ");
+    TInt errorCode = iCallHandling.DoUnattendedTransfer( 
+            iDataStore.TransferTargetCommand() );
+     
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::ForwardCallToAddress
+// -----------------------------------------------------------------------------
+//
+TInt CPEMessageHandler::ForwardCallToAddress()
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::ForwardCallToAddress ");
+    TInt errorCode = iCallHandling.ForwardCallToAddress( 
+            iDataStore.ForwardAddressIndex() );
+     
+    return errorCode;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::HandleDisableService
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::HandleDisableService()
+    {
+    TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleDisableService ");
+    iServiceHandling.DisableService();
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::IsValidDtmfString
+// -----------------------------------------------------------------------------
+//
+TBool CPEMessageHandler::IsValidDtmfString( TDes& aString )
+    { 
+    TBool validDtmf = ETrue;
+
+    for( TInt i = 0; i < aString.Length(); i++ )
+        {
+        if ( KErrNotFound == KValidDtmfChars().Locate( aString[i] ) )
+            {
+            validDtmf = EFalse;
+            break;
+            }      
+        }
+    return validDtmf;
+    }
+
+// -----------------------------------------------------------------------------
+// CPEMessageHandler::UpdateRemotePartyInfo
+// -----------------------------------------------------------------------------
+//
+void CPEMessageHandler::UpdateRemotePartyInfo( )
+    { 
+    CPERemotePartyInfoMediator* mediatorUpdater = iModel.MediatorCommunicationHandler();
+    if ( mediatorUpdater ) 
+        {
+        mediatorUpdater->UpdateRemotePartyInfo();
+        }
+    }
+	
+//  End of File