--- /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