/*
* 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 <");
// 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;
}
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();
}
}
// -----------------------------------------------------------------------------
// CPEMessageHandler::HandleDialCall
// Handles dial message from dial service
//
// -----------------------------------------------------------------------------
//
TInt CPEMessageHandler::HandleDialServiceCall(
const TBool /*aClientCall*/ )
{
TEFLOGSTRING( KTAINT, "PE CPEMessageHandler::HandleDialCall" );
TInt errorCode( ECCPErrorNone );
//TODO
iModel.HandleInternalMessage( MPEPhoneModel::EPEMessageDialServiceCall );
return errorCode;
}
// End of File