diff -r 000000000000 -r dd21522fd290 browserutilities/browsertelservice/src/BrowserTelService.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browserutilities/browsertelservice/src/BrowserTelService.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,2899 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + + +// INCLUDE FILES +#include +#include +#include + +// For phonebook API +#include // Phonebook Contact +#include // Phonebook Engine +#include // Phonebook field types +#include +#include // Phonebook editor +// For searching a matching number from contact's db +#include +#include + +#include +// +#include +#include +#include +#include + +// For email API +#include +#include +#include +#include + +// For BaflUtils +#include + +// Stringloader +#include + +// TApaTask, TApaTaskList +#include + +// Connection management +#include +#include + +#include +#include +#include +#include + +#include +// Const file name for make call +#include + +#include +#include + +#include + +#include + +#include "BrowserTelService.h" +#include "BrowserTelServiceDlgs.h" +#include "TelServiceLogger.h" + +#include "BrowserUtilitiesVariant.hrh" // KBrowserUtilitiesMailtoSchemeToMmsEditor + +const TInt KParseArrayAllocation = 10; +const TInt KTimerDelay = 2500000; + +_LIT( KValidDTMFChars,"w/p*#0123456789ABCDabcd," ); +_LIT( KDTMFWaitChars, "/wp,*#" ); +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ +_LIT( KDTMFInvalidWaitChars, "/," ); +_LIT( KDTMFValidPause, "p" ); +#endif // __BROWSER_TEL_SERVICES_CALLUI__ +// load resource file +_LIT( KResourceFileName, "Z:browsertelservice.RSC" ); + +// Path of the temp file +_LIT(KTempDrive, "d:"); +_LIT( KTempPath, "\\system\\temp\\" ); + +// The library to be loaded. +_LIT( KDialUtilsLoadLib, "DialUtils.dll" ); + +const TInt KKimonoBase = 26000; + +/* + This is a conversion table from browsertelservice internal + error codes to global and localized error ids. + {local error code, global error id} + Exception is KErrArgument-NW_STAT_WTAI_INVALID_ARGUMENT pair, because + case of wrong dtmf sequence has no WTAI correspondent error code. +*/ +const TInt KErrorConvTable[][2] = + { + {KErrInvocationError, NW_STAT_WTAI_INVOCATIONERROR}, + {KErrNoCallActive, NW_STAT_WTAI_NOCALLACTIVE}, + {KErrUserNoAnswer, NW_STAT_WTAI_NOANSWER}, + {KErrNoService, NW_STAT_WTAI_NOSERVICE}, + {KErrUserBusy, NW_STAT_WTAI_USERBUSY}, + {KErrPBPhoneBookFull, NW_STAT_WTAI_PHONEBOOKFULL}, + {KErrPBWriteError, NW_STAT_WTAI_PBWRITEERROR}, + {KErrPBNumberTooLong, NW_STAT_WTAI_PBNUMBERTOOLONG}, + {KErrPBNameTooLong, NW_STAT_WTAI_PBNAMETOOLONG}, + {KErrUnspecified, NW_STAT_WTAI_UNSPECIFIED_ERROR}, + {KErrArgument,NW_STAT_WTAI_INVALID_ARGUMENT}, + {KErrEtelBusyDetected, NW_STAT_WTAI_USERBUSY}, + {KErrEtelNoAnswer, NW_STAT_WTAI_NOANSWER}, + {0,0} + }; + +// ================= MEMBER FUNCTIONS ======================= + +//----------------------------------------------------------------------------- +// CBrowserTelService::NewLC() +//----------------------------------------------------------------------------- +// +EXPORT_C CBrowserTelService* CBrowserTelService::NewLC( + MBrowserTelServiceObserver* aObserver ) + { + CBrowserTelService* self = new( ELeave ) CBrowserTelService; + CleanupStack::PushL( self ); + self->ConstructL( aObserver ); + return self; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::NewL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C CBrowserTelService* CBrowserTelService::NewL( + MBrowserTelServiceObserver* aObserver ) + { + CBrowserTelService* self = CBrowserTelService::NewLC( aObserver ); + CleanupStack::Pop(); + return self; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::ConstructL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::ConstructL( MBrowserTelServiceObserver* aObserver ) + { + TELSERVICE_CREATE; + + iServiceHandler = NULL; + + SetState( EIdle ); + + if( aObserver ) + { + iObserverList.Append( aObserver ); + } + + iSynch = EFalse; + iIdle = CIdle::NewL( CActive::EPriorityIdle ); + + // Prepare telservice logger. + TELSERVICE_CREATE; + + // Resouce file loading + TParse* fileParser = new (ELeave) TParse; + CleanupStack::PushL( fileParser ); + + fileParser->Set( KResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL ); + iResourceFileName = fileParser->FullName(); + iResourceLoader.OpenL( iResourceFileName ); + iResourceOpened = ETrue; + + CleanupStack::PopAndDestroy( fileParser ); // fileParser + + iErrorUi = CErrorUI::NewL(); + +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + iDialData = CAiwDialData::NewL(); +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + + CActiveScheduler::Add( this ); + } + +//--------------------------------------------------------------------------------------- +// Default C++ constructor +//--------------------------------------------------------------------------------------- +// +CBrowserTelService::CBrowserTelService() +: CActive( EPriorityNormal ), + iResourceFileName( KNullDesC ), + iResourceLoader( *CCoeEnv::Static() ), + iResourceOpened( EFalse ) + { + } + +//--------------------------------------------------------------------------------------- +// Destructor +//--------------------------------------------------------------------------------------- +// +EXPORT_C CBrowserTelService::~CBrowserTelService() + { + TELSERVICE_ENTERFN( "~CBrowserTelService()" ) + + delete iServiceHandler; + iServiceHandler = NULL; + + // Cancel all current activity + Cancel(); + + // Close all open sessions + CloseAllSessions(); + +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + if (iDialData) + { + delete iDialData; + } +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + + if( iSendableDTMFNumbers ) + { + iSendableDTMFNumbers->ResetAndDestroy(); + delete iSendableDTMFNumbers; + } + + if( iDlgDTMFNumbers ) + { + iDlgDTMFNumbers->ResetAndDestroy(); + delete iDlgDTMFNumbers; + } + + // Empty the observer list + iObserverList.Reset(); +/* + if ( iResourceFileOffset ) + { + CCoeEnv::Static()->DeleteResourceFile( iResourceFileOffset ); + } + */ + if ( iResourceOpened ) + { + iResourceLoader.Close(); + iResourceOpened = EFalse; + } + +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + + if( iDTMFNumber ) + { + delete iDTMFNumber; + iDTMFNumber = NULL; + } + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + + delete iIdle; + delete iErrorUi; + + TELSERVICE_LEAVEFN( "~CBrowserTelService()" ) + TELSERVICE_DELETE + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::InitializeL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C HBufC* CBrowserTelService::ParsePhoneNumberL( TDes* aNumber ) + { + TELSERVICE_WRITE( "ParsePhoneNumberL()" ) + return FindAndRipDTMFSequenceL( aNumber ); + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::MakeCall() +//--------------------------------------------------------------------------------------- +// +EXPORT_C TInt CBrowserTelService::MakeCall( TDesC& aNumber, + TBool aSendDTMFAlwaysConfirm ) + { + TELSERVICE_ENTERFN( "MakeCall() synchronous" ) + + TInt retVal( KErrNone ); + + iRetVal = KErrNone; + + // Flag to indicate that synchronous method was called + iSynch = ETrue; + TRAP( retVal, MakeCallL( aNumber, aSendDTMFAlwaysConfirm ) ); + + if( retVal != KErrNone ) + { + ErrorHandler( retVal ); + + retVal = KErrCancel; + } + iSynch = EFalse; + + TELSERVICE_LEAVEFN( "MakeCall() synchronous" ) + return retVal; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::MakeCall() +//--------------------------------------------------------------------------------------- +// +EXPORT_C void CBrowserTelService::MakeCall( TRequestStatus& aStatus, + TDesC& aNumber, + TBool aSendDTMFAlwaysConfirm ) + { + TELSERVICE_ENTERFN( "MakeCall() asynchronous" ) + + iRetVal = KErrNone; + + aStatus = KRequestPending; + iUserRequestStatus = &aStatus; + iSynch = EFalse; + + TRAPD( err, MakeCall( aNumber, aSendDTMFAlwaysConfirm ) ); + + TELSERVICE_WRITE_FORMAT( "Asynch makecall start: %d", err ) + + if( err ) + { + ErrorHandler( err ); + + User::RequestComplete( iUserRequestStatus, err ); + + CleanupBuffers(); + } + + TELSERVICE_LEAVEFN( "MakeCall() asynchronous" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::CancelMakeCall() +//--------------------------------------------------------------------------------------- +// +EXPORT_C void CBrowserTelService::CancelMakeCall() + { + TELSERVICE_ENTERFN( "CancelMakeCall()" ) + +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + + // There is no ongoing request + +#else // __BROWSER_TEL_SERVICES_CALLUI__ + + Cancel(); + SetStateIdleAndNotifyObservers(); + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + + TELSERVICE_LEAVEFN( "CancelMakeCall()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::MakeCallL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::MakeCallL( TDesC& aNumber, TBool aSendDTMFAlwaysConfirm, TBool voipCall ) + { + iDTMFAlwaysConfirm = aSendDTMFAlwaysConfirm; + iRetVal = KErrNone; + + if( State() != EIdle ) + { + return; + } + + if( aNumber.Length() == 0 ) + { + User::Leave( KErrInvocationError ); + } + + +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + if( aNumber.Length() > AIWDialDataExt::KMaximumPhoneNumberLength ) + { + User::Leave( KErrPBNumberTooLong ); + } + + HBufC* orgNumber = HBufC::NewLC( AIWDialDataExt::KMaximumPhoneNumberLength ); +#else // __BROWSER_TEL_SERVICES_CALLUI__ + + if( aNumber.Length() > RMobilePhone::KMaxMobileTelNumberSize ) + { + User::Leave( KErrPBNumberTooLong ); + } + + HBufC* orgNumber = HBufC::NewLC( RMobilePhone::KMaxMobileTelNumberSize ); + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + + orgNumber->Des().Copy( aNumber ); + + if( FeatureManager::FeatureSupported( KFeatureIdJapanPrefixChange ) ) + { + RLibrary dialUtils; + if( dialUtils.Load( KDialUtilsLoadLib ) == KErrNone ) + { + CleanupClosePushL( dialUtils ); + + // Call function CreateDialUtilsFactoryL() + TInt res = dialUtils.Lookup( 1 )(); + CDialUtilsFactory * dialUtilsFactory = + reinterpret_cast< CDialUtilsFactory * >( res ); + + // This way the library is not needed at the linking time. + // Create Dial Utils (see that the function deletes the factory + // instance): + CDialUtilsApi* dialUtilsApi = dialUtilsFactory->CDialUtilsApiLD(); + dialUtilsFactory = NULL; + + // Then use the Dial Utils API, for example: + if( dialUtilsApi->CheckNumber( *orgNumber ) == KErrOverflow ) + // no we have the converted number + { + User::Leave( KErrPBNumberTooLong ); + } + + delete dialUtilsApi; + CleanupStack::PopAndDestroy( &dialUtils ); + } + } + + // Handle postd format + TPtr orgNumberPtr( orgNumber->Des() ); + HBufC* postdParm = FindPostdParmL( orgNumberPtr ); + + if(voipCall) + { + FindAndRipVoipParametersL( orgNumberPtr ); + } + + + // Rip URI parameters from Tel URI, in order to that + // number validation and DTMF works as earlier + // Parameters will be added back in later phase + HBufC* params = FindAndRipURIParametersL( orgNumberPtr ); + CleanupStack::PushL( params ); + + HBufC* number = ValidateNumberL( *orgNumber ); + CleanupStack::PushL( number ); + + TPtr numberPtr = number->Des(); + iDTMFNumber= FindAndRipDTMFSequenceL( &numberPtr ); + + TBool isPostd(EFalse); + if ( ! iDTMFNumber ) + { + iDTMFNumber = postdParm; + if ( iDTMFNumber ) + { + isPostd = ETrue; + } + } + else + { + delete postdParm; + } +#ifndef __BROWSER_TEL_SERVICES_CALLUI__ + + iSendableDTMFNumbers = ParseDTMFSequencesL( iDTMFNumber ); + iDlgDTMFNumbers = ParseDTMFSequencesForDlgL( iDTMFNumber ); + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + + if( ShowDialogL( *number, EConfirmMakeCall ) ) + { + +#ifndef __WINS__ + DisconnectActiveCSDConnectionL(); +#endif + +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + + HBufC* temp = NULL; + if( iDTMFNumber ) + { + // Confirm the user (s)he wants to send the DTMF + if( SendDMFConfQueryL( iDTMFNumber->Des() ) ) + { + if ( !isPostd ) + { + // Add iDTMFNumber to number + temp = HBufC::NewLC( number->Length() + iDTMFNumber->Length() ); + temp->Des().Copy( number->Des() ); + temp->Des().Append( iDTMFNumber->Des() ); + } + else + { + // Add p+iDTMFNumber to number for postd + temp = HBufC::NewLC( number->Length() + iDTMFNumber->Length() + 1 /*for the 'p' character*/ ); + temp->Des().Copy( number->Des() ); + temp->Des().Append( 'p' ); + temp->Des().Append( iDTMFNumber->Des() ); + } + } + else + { + // Call number without dtmf + temp = number->AllocLC(); + } + } + else + { + temp = number->AllocLC(); + } + + temp = temp->ReAllocL( temp->Length() + params->Length() ); + CleanupStack::Pop( temp ); // location may have changed, update cleanupstack + CleanupStack::PushL( temp ); + temp->Des().Append( *params ); + + // ... and make the call + DoMakeCallL( *temp, voipCall ); + + CleanupStack::PopAndDestroy( temp ); // temp + +#else // __BROWSER_TEL_SERVICES_CALLUI__ + + // ... and make the call + DoMakeCallL( *number, voipCall ); + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + } + else + { + User::Leave( KErrCancel ); + } + + CleanupStack::PopAndDestroy( 3 ); // orgNumber, params, number + } + +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SendDMFConfQueryL() +//--------------------------------------------------------------------------------------- +// +TBool CBrowserTelService::SendDMFConfQueryL( const TDesC& aDTMF ) + { + TBool retVal( EFalse ); + + + TELSERVICE_ENTERFN( "SendDMFConfQueryL()" ) + + if( 0 == aDTMF.Length() ) + { + return retVal; + } + + CRepository* repository = CRepository::NewL( KCRUidBrowser ); + CleanupStack::PushL (repository ); + repository->Get( KBrowserConfirmedDTMFOnce, iConfirmedOnce ); + + TELSERVICE_WRITE( "display send dtmf dialog" ) + + if( iDTMFAlwaysConfirm ) + { + retVal = ShowDialogL( aDTMF, EConfirmSendDTMF ); + } + else if( iDTMFAlwaysConfirm == EFalse && + iConfirmedOnce == EFalse ) + { + retVal = ShowDialogL( aDTMF, + EConfirmSendDTMF ); + iConfirmedOnce = ETrue; + repository->Set( KBrowserConfirmedDTMFOnce, iConfirmedOnce ); + } + + CleanupStack::PopAndDestroy( repository ); + + return retVal; + } + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::CleanupBuffs() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::CleanupBuffers() + { + if( iSendableDTMFNumbers ) + { + iSendableDTMFNumbers->ResetAndDestroy(); + delete iSendableDTMFNumbers; + iSendableDTMFNumbers = NULL; + } + + if( iDlgDTMFNumbers ) + { + iDlgDTMFNumbers->ResetAndDestroy(); + delete iDlgDTMFNumbers; + iDlgDTMFNumbers = NULL; + } + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::DoMakeCallL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::DoMakeCallL( TDesC& aNumber, TBool voipCall ) + { + TELSERVICE_ENTERFN( "DoMakeCallL()" ) + +#ifndef __BROWSER_TEL_SERVICES_CALLUI__ + + RTelServer::TPhoneInfo info; + RPhone::TLineInfo lineInfo; + + // Connect to the telephony server and load the TSY. + User::LeaveIfError( iRTelServer.Connect() ); + User::LeaveIfError( iRTelServer.LoadPhoneModule( KMmTsyModuleName ) ); + // Get the details for the first (and only) phone. + User::LeaveIfError( iRTelServer.GetPhoneInfo( 0, info ) ); + // Open the phone. + User::LeaveIfError( iRPhone.Open( iRTelServer, info.iName ) ); + // Get the information for the voice line, line 0. + User::LeaveIfError( iRPhone.GetLineInfo( 0, lineInfo ) ); + // Open the line. iName will now be "VoiceLine1". + User::LeaveIfError( iRLine.Open( iRPhone, KMmTsyVoice1LineName ) ); + TInt count; + // Gets the number of calls opened from a line. + User::LeaveIfError( iRLine.EnumerateCall( count ) ); + if ( count > 2 ) + { + HBufC* text = StringLoader::LoadL( + R_TEXT_CALL_NOT_ALLOWED, + CEikonEnv::Static() ); + CleanupStack::PushL( text ); + TDialerDialogs::ErrorNoteL( *text ); + CleanupStack::PopAndDestroy();// text + User::Leave( KErrNone ); + } + + // Open a new phone call. + User::LeaveIfError( iRCall.OpenNewCall( iRLine ) ); + + // Initialize state + SetState( EDialing ); + + // Actually dial the specified number. + iRCall.Dial( iStatus, aNumber ); + SetActive(); + + NotifyObservers(); + + if( iSynch ) + { + TELSERVICE_WRITE( "starting DoMakeCallL wait loop" ) + iWait.Start(); // start the wait loop. DoMakeCallL() method won't + // return until iWait->AsyncStop() is called in RunL() + TELSERVICE_WRITE( "DoMakeCallL wait loop stopped" ) + + if( iRetVal == KErrNone ) + { + if( HandleInternalSendDTMFL() ) + { + TELSERVICE_WRITE( "starting HandleInternalSendDTMFL wait loop" ) + iInternalDTMFWaitStarted = ETrue; + iWait.Start(); + iRAdvGsmPhone.Close(); + TELSERVICE_WRITE( "HandleInternalSendDTMFL wait loop stopped" ) + + if( iWaitDlg ) + { + iWaitDlg->ProcessFinishedL(); + } + iInternalDTMFWaitStarted = EFalse; + } + } + else + { + User::Leave( iRetVal ); + } + } + +#else // __BROWSER_TEL_SERVICES_CALLUI__ + + if(!iServiceHandler) + { + iServiceHandler = CAiwServiceHandler::NewL(); + } + iServiceHandler->AttachL( R_BROWSERTELSERVICES_MENU_AIW_INTERESTS ); + + + CAiwGenericParamList& paramList = iServiceHandler->InParamListL(); + CAiwGenericParamList& output = iServiceHandler->OutParamListL(); + + TPtrC number = aNumber; + + iDialData->SetPhoneNumberL( number ); + if( !voipCall ) + { + iDialData->SetCallType( CAiwDialData::EAIWVideo ); + } + else + { + iDialData->SetCallType( CAiwDialData::EAIWVoiP ); + } + iDialData->FillInParamListL( paramList ); + + iServiceHandler->ExecuteServiceCmdL( + KAiwCmdCall, + paramList, + output, + 0, // No options used. + this ); // + + if( iSynch ) + { + iWait.Start(); + } + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + + TELSERVICE_LEAVEFN( "DoMakeCallL()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SendDTMFL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::SendDTMFL( TDesC& aNumber, TBool aSendDTMFAlwaysConfirm ) + { + iDTMFAlwaysConfirm = aSendDTMFAlwaysConfirm; + + iRetVal = KErrNone; + CheckIsThereActivateVoiceCallOnL(); + + if( State() == EConnected ) + { + CheckDTMFNumberL( aNumber ); + + // Set flag to indicate that synchronous method was called + iSynch = ETrue; + + delete iSendableDTMFNumbers; + iSendableDTMFNumbers = NULL; + + delete iDlgDTMFNumbers; + iDlgDTMFNumbers = NULL; + + iSendableDTMFNumbers = ParseDTMFSequencesL( &aNumber ); + iDlgDTMFNumbers = ParseDTMFSequencesForDlgL( &aNumber ); + + if( HandleInternalSendDTMFL() ) + { + TELSERVICE_WRITE( "starting HandleInternalSendDTMFL wait loop" ) + iInternalDTMFWaitStarted = ETrue; + iWait.Start(); + TELSERVICE_WRITE( "HandleInternalSendDTMFL wait loop stopped" ) + + if( iWaitDlg ) + { + iWaitDlg->ProcessFinishedL(); + } + iInternalDTMFWaitStarted = EFalse; + } + + // Unset flag + iSynch = EFalse; + } + else // no active voice connection + { + User::Leave( KErrNoCallActive ); + } + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SendDTMFL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::SendDTMFL( TRequestStatus& aStatus,TDesC& aNumber, + TBool aSendDTMFAlwaysConfirm ) + { + iDTMFAlwaysConfirm = aSendDTMFAlwaysConfirm; + + aStatus = KRequestPending; + iUserRequestStatus = &aStatus; + CheckIsThereActivateVoiceCallOnL(); + + if( State() == EConnected ) + { + CheckDTMFNumberL( aNumber ); + + if( iSendableDTMFNumbers ) + { + iSendableDTMFNumbers->ResetAndDestroy(); + } + delete iSendableDTMFNumbers; + iSendableDTMFNumbers = NULL; + + if( iDlgDTMFNumbers ) + { + iDlgDTMFNumbers->ResetAndDestroy(); + } + delete iDlgDTMFNumbers; + iDlgDTMFNumbers = NULL; + + iSendableDTMFNumbers = ParseDTMFSequencesL( &aNumber ); + iDlgDTMFNumbers = ParseDTMFSequencesForDlgL( &aNumber ); + + HandleInternalSendDTMFL(); + } + else // no active voice connection + { + User::Leave( KErrNoCallActive ); + } + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::DoSendDTMFL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::DoSendDTMFL( TDesC& aNumber ) + { + TELSERVICE_ENTERFN( "DoSendDTMFL()" ) + + CheckIsThereActivateVoiceCallOnL(); + + if( State() == EConnected ) + { + // Cancel any outstanding requests + Cancel(); + + RTelServer::TPhoneInfo info; + User::LeaveIfError( iRTelServer.GetPhoneInfo( 0, info ) ); + User::LeaveIfError( iRAdvGsmPhone.Open( iRTelServer, info.iName ) ); + + // Set state + SetState( EDialingDTMF ); + // Notify the observer + NotifyObservers(); + + // Send DTMF tones + if( aNumber.Length() ) + { + iRAdvGsmPhone.SendDTMFTones( iStatus, aNumber ); + } + else + { + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + + SetActive(); + + if( iSynch ) + { + iWait.Start(); // start the wait loop. DoSendDTMFL() + // method won't return + // until iWait->AsyncStop() is called in RunL() + } + } + else + { + User::Leave( KErrCancel ); + } + + TELSERVICE_LEAVEFN( "DoSendDTMFL()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::ValidateNumberL() +//--------------------------------------------------------------------------------------- +// +HBufC* CBrowserTelService::ValidateNumberL( TDesC& aNumber ) + { + TELSERVICE_ENTERFN( "ValidateNumberL()" ) + + HBufC* buf = HBufC::NewLC( aNumber.Length() ); + TPtr ptr = buf->Des(); + ptr.Copy( aNumber ); + + for( TInt i = 0; i < ptr.Length(); i++ ) + { + TChar currentChar = ptr[i]; + + if( currentChar.IsSpace() ) + { + ptr.Delete( i, 1 ); + i--; + } + else if( !currentChar.IsDigit() ) + { + if( currentChar == '+' ) + { + if( i != 0 ) + { + User::Leave( KErrInvocationError ); + } + } + else + { + currentChar.UpperCase(); + + switch( currentChar ) + { + case '*': + case '#': + case 'A': + case 'B': + case 'C': + case 'D': + case 'P': + case 'W': + case ',': + case '/': + if( i == 0 ) + { + User::Leave( KErrInvocationError ); + } + break; + + case '.': + case '-': + case '(': + case ')': + { + ptr.Delete( i, 1 ); + i--; + } + break; + + default: + // invalid character in the phone number + { + User::Leave( KErrInvocationError ); + } + break; + } + } + } + } + + CleanupStack::Pop( buf ); // buf + + TELSERVICE_LEAVEFN( "ValidateNumberL()" ) + return buf; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::FindAndHandlePostdL() +//--------------------------------------------------------------------------------------- +// +HBufC* CBrowserTelService::FindPostdParmL( TDes& aNumber ) + { + TELSERVICE_ENTERFN( "FindPostdParmL()" ) + + HBufC* buf = NULL; + _LIT( KPostd, ";postd=" ); + TInt ret = aNumber.Find( KPostd ); + if ( ret != KErrNotFound ) + { + buf = aNumber.Mid( ret + KPostd().Length() ).AllocL(); + aNumber.SetLength ( ret ); + } + TELSERVICE_LEAVEFN( "FindPostdParmL()" ) + return buf; + } + + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::FindAndRipDTMFSequenceL() +//--------------------------------------------------------------------------------------- +// +HBufC* CBrowserTelService::FindAndRipDTMFSequenceL( TDes* aNumber ) + { + TELSERVICE_ENTERFN( "FindAndRipDTMFSequnceL()" ) + + HBufC* buf = NULL; + + TPtrC waitChars; + waitChars.Set( KDTMFWaitChars ); + + // Look for the first DTMF-wait char and extract the + // dtmf string from the phonenumber + for( TInt i = 0; i < aNumber->Length(); i++ ) + { + if( ( waitChars.Locate( (*aNumber)[i] ) != KErrNotFound ) ) + { +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + + buf = aNumber->Mid(i).AllocL(); + aNumber->Delete( i, buf->Length() ); + + // Remove all the invalid wait chars from + // the sequence which is not accepted by CallUi + TPtrC invalidWaitChars; + invalidWaitChars.Set( KDTMFInvalidWaitChars ); + + for( TInt j = 0; j < buf->Length(); j++ ) + { + if( ( invalidWaitChars.Locate( (*buf)[j] ) != KErrNotFound ) ) + { + TPtr ptr = buf->Des(); + ptr.Replace( j, 1,KDTMFValidPause() ); + } + } + +#else // __BROWSER_TEL_SERVICES_CALLUI__ + + if( (*aNumber)[i] == '#' || + (*aNumber)[i] == '*' ) + // these chars are parts of the dtms sequence + { + buf = aNumber->Mid(i).AllocL(); + aNumber->Delete( i, buf->Length() ); + } + else + { + // +1 -> wait char is not part of the dtmf sequence + buf = aNumber->Mid(i+1).AllocL(); + aNumber->Delete( i, buf->Length() + 1); + } + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + break; + } + } + TELSERVICE_LEAVEFN( "FindAndRipDTMFSequenceL()" ) + return buf; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::FindAndRipURIParametersL() +//--------------------------------------------------------------------------------------- +// +HBufC* CBrowserTelService::FindAndRipURIParametersL( TDes& aNumber ) + { + TELSERVICE_ENTERFN( "FindAndRipURIParametersL()" ) + + HBufC* buf = NULL; + TInt offset = aNumber.Locate( TChar( ';' ) ); + if( offset > 0 ) // Separator is not allowed to be a first char + { + __ASSERT_DEBUG( offset <= aNumber.Length(), User::Leave( KErrGeneral ) ); + buf = aNumber.Mid( offset ).AllocL(); + aNumber.SetLength( offset ); + } + else + { + buf = HBufC::NewL( 0 ); + } + + TELSERVICE_LEAVEFN( "FindAndRipURIParametersL()" ) + return buf; + } + + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::FindAndRipVoipParametersL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::FindAndRipVoipParametersL( TDes& aNumber ) + { + TELSERVICE_ENTERFN( "FindAndRipVoipParametersL()" ) + + HBufC* buf = NULL; + TInt offset = aNumber.Locate( TChar( '@' ) ); + if( offset > 0 ) // Separator is not allowed to be a first char + { + __ASSERT_DEBUG( offset <= aNumber.Length(), User::Leave( KErrGeneral ) ); + buf = aNumber.Mid( offset ).AllocL(); + aNumber.SetLength( offset ); + } + else + { + buf = HBufC::NewL( 0 ); + } + + TELSERVICE_LEAVEFN( "FindAndRipVoipParametersL()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::ValidateDTMFNumberL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::ValidateDTMFNumberL( TDes* aNumber ) + { + TELSERVICE_ENTERFN( "ValidateDTMFNumberL()" ) + + TPtrC validDTMFChars; + validDTMFChars.Set( KValidDTMFChars ); + + if( aNumber ) + { + for( TInt i = 0; i < aNumber->Length(); i++ ) + { + if( ( validDTMFChars.Locate( (*aNumber)[i] ) == KErrNotFound ) ) + { + // Invalid character found, remove it! + aNumber->Delete( i, 1 ); + i--; + } + } + } + TELSERVICE_LEAVEFN( "ValidateDTMFNumberL()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::ParseDTMFSequencesForDlg() +//--------------------------------------------------------------------------------------- +// +CArrayPtrFlat* CBrowserTelService::ParseDTMFSequencesForDlgL( + const TDesC* aDTMFString ) + { + TELSERVICE_ENTERFN( "ParseDTMFSequencesForDlgL()" ) + CArrayPtrFlat* parsedArray = NULL; + + if( aDTMFString ) + { + parsedArray = new ( ELeave ) CArrayPtrFlat( KParseArrayAllocation ); + + TLex dtmfSequence( *aDTMFString ); + + TChar previousChar = dtmfSequence.Peek(); // first char + + while( !dtmfSequence.Eos() ) + { + // + if ( dtmfSequence.Offset() ) // if not at start of line + { + TChar nextChar = dtmfSequence.Peek(); + if( nextChar == '/' || nextChar == 'w' || nextChar == 'p' || + nextChar == ',' ) + { + // if the previous wait char was either 'w' or '/' then skip it + // and mark new extraction mark. + if( previousChar == 'w' || previousChar == '/' ) + { + dtmfSequence.Mark(); + } + else + { + parsedArray->AppendL( + dtmfSequence.RemainderFromMark().Alloc() ); + dtmfSequence.Mark(); + } + } + previousChar = nextChar; + } + + dtmfSequence.Inc(); + } + + parsedArray->AppendL( dtmfSequence.RemainderFromMark().Alloc() ); + } + TELSERVICE_LEAVEFN( "ParseDTMFSequencesForDlgL()" ) + return parsedArray; + } + + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::ParseDTMFSequencesForDlg() +//--------------------------------------------------------------------------------------- +// +CArrayPtrFlat* CBrowserTelService::ParseDTMFSequencesL( + const TDesC* aDTMFString ) + { + TELSERVICE_ENTERFN( "ParseDTFMSequencesL()" ) + CArrayPtrFlat* parsedArray = NULL; + + if( aDTMFString ) + { + parsedArray = new ( ELeave ) CArrayPtrFlat( + KParseArrayAllocation ); + CleanupStack::PushL( parsedArray ); + + TLex dtmfSequence( *aDTMFString ); + + TChar previousChar = dtmfSequence.Peek(); // first char + + while( !dtmfSequence.Eos() ) + { + // + if ( dtmfSequence.Offset() ) // if not at start of line + { + TChar nextChar = dtmfSequence.Peek(); + if( nextChar == '/' || nextChar == 'w' || + nextChar == 'p' || nextChar == ',' ) + { + // if the previous wait char was either 'w' or '/' + // then skip it + // and mark new extraction mark. + if( previousChar == 'w' || previousChar == '/' ) + { + dtmfSequence.Mark(); + } + else + { + parsedArray->AppendL( + dtmfSequence.MarkedToken().Alloc() ); + dtmfSequence.Mark(); + } + } + previousChar = nextChar; + } + + dtmfSequence.Inc(); + } + + parsedArray->AppendL( dtmfSequence.RemainderFromMark().Alloc() ); + + CleanupStack::Pop( parsedArray ); + } + TELSERVICE_LEAVEFN( "ParseDTMFSequencesL()" ) + return parsedArray; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::DisplaySendDTMFDialog() +//--------------------------------------------------------------------------------------- +// +TBool CBrowserTelService::DisplaySendDTMFDialog( TDes* aNumber ) + { + TELSERVICE_ENTERFN( "DisplaySendDTMFDialog()" ) + TBool ret = EFalse; + + if( aNumber ) + { + TInt length = aNumber->Length(); + if( length ) + { + TChar waitChar = RipWaitChar( aNumber ); + + switch( waitChar ) + { + case '/': + case 'w': + { + ret = ETrue; + } + break; + + case 'p': + case ',': + { + ret = EFalse; + } + break; + + default: + { + ret = ((iDTMFAlwaysConfirm) || (!iConfirmedOnce)); + } + break; + } + } + } + TELSERVICE_LEAVEFN( "DisplaySendDTMFDialog()" ) + return ret; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::RipWaitChar() +//--------------------------------------------------------------------------------------- +// +TChar CBrowserTelService::RipWaitChar( TDes* aNumber ) + { + TELSERVICE_ENTERFN( "RipWaitChar()" ) + TChar waitChar = NULL; + if( aNumber ) + { + TInt length = aNumber->Length(); + if( length ) + { + TChar tempWaitChar = ( *aNumber )[0]; + if( tempWaitChar == 'w' || tempWaitChar == '/' || + tempWaitChar == 'p' || tempWaitChar == ',') + { + waitChar = tempWaitChar; + aNumber->Delete( 0, 1 ); + } + } + } + TELSERVICE_LEAVEFN( "RipWaitChar()" ) + return waitChar; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SendDTMF() +//--------------------------------------------------------------------------------------- +// +EXPORT_C TInt CBrowserTelService::SendDTMF( TDesC& aNumber, + TBool aSendDTMFAlwaysConfirm ) + { + TELSERVICE_ENTERFN( "SendDTMF() synchronous" ) + + iRetVal = KErrNone; + + TRAPD( err, SendDTMFL( aNumber, aSendDTMFAlwaysConfirm ) ); + + if( err ) + { + ErrorHandler( err ); + iRetVal = KErrCancel; + } + + TELSERVICE_LEAVEFN( "SendDTMF() synchronous" ) + return iRetVal; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SendDTMFL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C void CBrowserTelService::SendDTMF( TRequestStatus& aStatus, + TDesC& aNumber, + TBool aSendDTMFAlwaysConfirm ) + { + TELSERVICE_ENTERFN( "SendDTMF() asynchronous" ) + + iRetVal = KErrNone; + + TRAPD( err, SendDTMFL( aStatus, aNumber, aSendDTMFAlwaysConfirm ) ); + + if( err ) + { + TELSERVICE_WRITE_FORMAT( "Complete the request: %d", KErrInvocationError ) + + ErrorHandler( err ); + + User::RequestComplete( iUserRequestStatus, KErrInvocationError ); + } + + TELSERVICE_LEAVEFN( "SendDTMF() asynchronous" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::CancelSendDTMFL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C void CBrowserTelService::CancelSendDTMFL() + { + TELSERVICE_ENTERFN( "CancelSendDTMF()" ) + + if( State() == EDialingDTMF ) + { + RCall::TStatus callStatus; + User::LeaveIfError( iRCall.GetStatus( callStatus ) ); + + if( callStatus == RCall::EStatusConnected ) + { + if( State() == EDialingDTMF ) + { + Cancel(); + SetState( EConnected ); + } + } + } + + TELSERVICE_LEAVEFN( "CancelSendDTMF()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::AddPBEntryL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C TInt CBrowserTelService::AddPBEntryL( + TDesC& aNumber, + TDesC& aName, + TDesC& aEmail ) + { + TELSERVICE_ENTERFN( "AddPBEntryL()" ) + + CPbkContactEngine* pbkEngine = CPbkContactEngine::NewL(); + CleanupStack::PushL( pbkEngine ); + + // Make sure a resource file is available + RPbkViewResourceFile pbkResourceFile( *CCoeEnv::Static() ); + pbkResourceFile.OpenL(); + CleanupClosePushL ( pbkResourceFile ); + + // Step 1: Search Pb for matches and open existing or create new + TBool newContact; + CPbkContactItem* contactItem = SearchPBItemLC( *pbkEngine + , aNumber + , aEmail + , newContact ); + + TPtrC lastName; + TPtrC firstName; + TPtrC email; + + email.Set( aEmail ); + + // Step 2: Set values to the correct lines + // default focused dialog line + TInt formIndex = -1; + + if( JAPANESE ) + // Japanese version only. See Vodafone spec: + // http://developers.vodafone.jp/dp/tool_dl/download.php?docid=120 + { + TPtrC lastNameReading; + + TInt yomiganaInd = aName.LocateReverse( TChar('-') ); + + if( yomiganaInd != KErrNotFound ) + { + lastNameReading.Set( aName.Right( aName.Length() - yomiganaInd - 1 ) ); + lastName.Set( aName.Left( yomiganaInd ) ); + } + else + { + lastName.Set( aName ); + } + + SetPBEntryFieldL( EPbkFieldIdLastName, pbkEngine, contactItem, lastName, formIndex ); + SetPBEntryFieldL( EPbkFieldIdLastNameReading, pbkEngine, contactItem, lastNameReading, formIndex ); + } + else + { + TInt lastNameInd = aName.LocateReverse( TChar(' ') ); + TBool whichtag = EFalse; + if ( lastNameInd == KErrNotFound ) + { + _LIT( tag, "%20" ); + lastNameInd = aName.Find( tag ); + whichtag = ETrue; + } + + if( lastNameInd != KErrNotFound ) + { + if( lastNameInd ) + { + if ( whichtag ) + { + lastName.Set( aName.Right( aName.Length() - lastNameInd - 3 ) ); + } + else + { + lastName.Set( aName.Right( aName.Length() - lastNameInd - 1 ) ); + } + firstName.Set( aName.Left( lastNameInd ) ); + } + else + { + lastName.Set( aName ); + } + } + else + { + lastName.Set( aName ); + } + + SetPBEntryFieldL( EPbkFieldIdLastName, pbkEngine, contactItem, lastName, formIndex ); + SetPBEntryFieldL( EPbkFieldIdFirstName, pbkEngine, contactItem, firstName, formIndex ); + } + + // common fields + SetPBEntryFieldL( EPbkFieldIdPhoneNumberStandard, pbkEngine, contactItem, aNumber, formIndex ); + SetPBEntryFieldL( EPbkFieldIdEmailAddress, pbkEngine, contactItem, aEmail, formIndex ); + + // Step 3: Open the editor dialog + CPbkContactEditorDlg* dlg = CPbkContactEditorDlg::NewL( + *pbkEngine, *contactItem, newContact, formIndex, formIndex >= 0 ); + + // Execute phonebook editor + dlg->ExecuteLD(); + + CleanupStack::PopAndDestroy( 3 ); // contactItem, pbkResourceFile, pbkEngine + + TELSERVICE_LEAVEFN( "AddPBEntryL()" ) + + return KErrNone; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::State() +//--------------------------------------------------------------------------------------- +// +EXPORT_C TBrowserTelServiceState CBrowserTelService::State() const + { + TELSERVICE_WRITE_FORMAT( "State(): %d", iState ) + return iState; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SetState() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::SetState( TBrowserTelServiceState aState ) + { + TELSERVICE_WRITE( "SetState()" ) + iState = aState; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::AddObserver() +//--------------------------------------------------------------------------------------- +// +EXPORT_C void CBrowserTelService::AddObserver( + MBrowserTelServiceObserver* aObserver ) + { + TELSERVICE_ENTERFN( "AddObserver()" ) + + if( aObserver ) + { + iObserverList.Append( aObserver ); + } + TELSERVICE_LEAVEFN( "AddObserver()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::RemoveObserver() +//--------------------------------------------------------------------------------------- + +EXPORT_C void CBrowserTelService::RemoveObserver( + MBrowserTelServiceObserver* aObserver ) + { + TELSERVICE_ENTERFN( "RemoveObserver()" ) + + TInt count = iObserverList.Count(); + if( count ) + { + TInt index = iObserverList.Find( aObserver ); + if( index != KErrNotFound ) + { + iObserverList.Remove( index ); + iObserverList.GranularCompress(); + } + } + TELSERVICE_LEAVEFN( "AddObserver()" ) + } +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SendEmailMessageL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C TInt CBrowserTelService::SendEmailMessageL( + const TDesC& aToRecipients, + const TDesC& aCcRecipients, + const TDesC& aParams, + const TDesC& aBody ) + { + return this->SendEmailMessageL( aToRecipients, aCcRecipients, + aParams, aBody, 0 ); + } +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SendEmailMessageL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C TInt CBrowserTelService::SendEmailMessageL( + const TDesC& aToRecipients, + const TDesC& aCcRecipients, + const TDesC& aParams, + const TDesC& aBody, + TBool aLaunchEmbedded ) + { + TELSERVICE_ENTERFN( "SendEmailMessageL()" ) + + /////////////////////////////////////////////////////////////// + // Determine if mailto handled via MMS from variation mechanism + TBool sendMms( EFalse ); + TInt keyVal( 0 ); + CRepository* repository = CRepository::NewL( KCRUidBrowserUiLV ); + CleanupStack::PushL( repository ); + if(repository->Get( KBrowserMailtoSendingApp, keyVal ) == KErrNone ) + { + sendMms = ( keyVal == 1 ); + } + CleanupStack::PopAndDestroy( repository ); + + //Search for @ and .(dot) characters + TInt at = aToRecipients.Locate('@'); + TInt dot = aToRecipients.Locate('.'); + TInt len = aToRecipients.Length(); + if(len > 0 && KErrNotFound == at && KErrNotFound == dot) + { + TELSERVICE_WRITE("CBrowserTelService::SendEmailMessageL chars @ and .(dot) are not present"); + sendMms = ETrue; + //Make sure all chars are numbers only except first char '+' + TInt loopCounter = 0; + const TUint16 *ptr = aToRecipients.Ptr(); + + if(*ptr == '+') + { + ptr = ptr + 1; + loopCounter = 1; + } + + for(loopCounter; loopCounter= '0' && *ptr <= '9') || *ptr == ',') + { + TELSERVICE_WRITE_FORMAT("CBrowserTelService::SendEmailMessageL character: %c", *ptr ); + ptr = ptr + 1; + continue; + } + else + { + TELSERVICE_WRITE_FORMAT("CBrowserTelService::SendEmailMessageL found invalid character: %c", *ptr ); + TELSERVICE_WRITE("CBrowserTelService::SendEmailMessageL chars otherthan numbers are present"); + sendMms = EFalse; + break; + } + } + } + + if ( sendMms ) + { + TELSERVICE_WRITE("CBrowserTelService::SendEmailMessageL Sending MMS message"); + return SendMmsMessageL( aToRecipients, aCcRecipients, aParams, aBody, aLaunchEmbedded ); + } + + ///////////////////////////////// + // Email editor is launched. + TInt cleanUpCount = 0; + + CParaFormatLayer* paraFormat = CParaFormatLayer::NewL(); + CleanupStack::PushL( paraFormat ); + ++cleanUpCount; + + CCharFormatLayer* charFormat = CCharFormatLayer::NewL(); + CleanupStack::PushL( charFormat ); + ++cleanUpCount; + + CRichText* body = CRichText::NewL( paraFormat, charFormat ); + CleanupStack::PushL( body ); + ++cleanUpCount; + + if( aBody.Length() ) + { + body->InsertL( 0, aBody ); + } + else + { + body->InsertL( 0, KNullDesC ); + } + + CPtrC16Array* recipients = ParseRecipientsLC( aToRecipients ); + ++cleanUpCount; + CPtrC16Array* ccrecipients = ParseRecipientsLC( aCcRecipients ); + ++cleanUpCount; + + CSendUi* sendUi = CSendUi::NewL(); + CleanupStack::PushL( sendUi ); + ++cleanUpCount; + CMessageData* messageData = CMessageData::NewL(); + CleanupStack::PushL( messageData ); + ++cleanUpCount; + messageData->SetSubjectL( &aParams ); + messageData->SetBodyTextL( body ); + for( TInt i = 0; i < recipients->Count(); i++ ) + { + messageData->AppendToAddressL( (*recipients)[i] ); + } + for( TInt j = 0; j < ccrecipients->Count(); j++ ) + { + messageData->AppendCcAddressL( (*ccrecipients)[j] ); + } + // check first that the selected mtm supports bodytext +/* + TSendingCapabilities caps( aBody.Size(), + aBody.Size(), + TSendingCapabilities::ESupportsBodyText ); + if( sendUi->ValidateServiceL( KUidMsgTypeSMTP, caps ) ) + { + sendUi->CreateAndSendMessageL( KUidMsgTypeSMTP, messageData ); + } */ + sendUi->CreateAndSendMessageL( KUidMsgTypeSMTP, messageData ); + + CleanupStack::PopAndDestroy( cleanUpCount ); + + TELSERVICE_LEAVEFN( "SendEmailMessageL()" ) + return KErrNone; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SendMmsMessageL() +//--------------------------------------------------------------------------------------- +// +TInt CBrowserTelService::SendMmsMessageL( + const TDesC& aToRecipients, + const TDesC& aCcRecipients, + const TDesC& aParams, + const TDesC& aBody, + TBool aLaunchEmbedded ) + { + TELSERVICE_ENTERFN( "SendMmsMessageL()" ) + + TInt cleanUpCount = 0; + // We give NULL body for the SendUi. + CRichText* body = NULL; + + // We need to write body to file in order to give as a attachment + // for the SendUi. + CDesCArrayFlat* attachments = NULL; + TFileName fileName; + TFileName tempPath; + CCoeEnv* coeEnv = CCoeEnv::Static(); + RFs& fs = coeEnv->FsSession(); + + attachments = new (ELeave) CDesCArrayFlat(1); + CleanupStack::PushL(attachments); + ++cleanUpCount; + if ( aBody.Length() > 0 ) + { + // Create plaintext object from body + CPlainText* text = CPlainText::NewL( CEditableText::EFlatStorage ); + CleanupStack::PushL( text ); + text->InsertL( 0, aBody ); + + TInt err = KErrNone; + RFileWriteStream writer; + tempPath.Copy(KTempDrive); + tempPath.Append(KTempPath); + err = fs.MkDirAll( tempPath ); + if ( err != KErrNone && err != KErrAlreadyExists ) + { + User::Leave( err ); + } + writer.PushL(); + User::LeaveIfError( writer.Temp( fs, tempPath, fileName, EFileWrite ) ); + writer.WriteUint16L(CEditableText::EByteOrderMark); + text->ExportTextL( 0, writer, + CPlainText::EOrganiseByParagraph ); + CleanupStack::PopAndDestroy( 2 ); // text, writer + attachments->AppendL( fileName ); + } + + // Create address arrays + CPtrC16Array* recipients = ParseRecipientsLC( aToRecipients ); + ++cleanUpCount; + CPtrC16Array* ccrecipients = ParseRecipientsLC( aCcRecipients ); + ++cleanUpCount; + TInt count = ccrecipients->Count(); + if ( count > 0 ) + { + for (TInt i = 0; i < count; i++) + { + recipients->AppendL( ccrecipients->At(i) ); + } + } + CleanupStack::PopAndDestroy(ccrecipients); + --cleanUpCount; + ccrecipients = NULL; + + CSendUi* sendUi = CSendUi::NewL(); + CleanupStack::PushL( sendUi ); + ++cleanUpCount; + CMessageData* messageData = CMessageData::NewL(); + CleanupStack::PushL( messageData ); + ++cleanUpCount; + messageData->SetSubjectL( &aParams ); + messageData->SetBodyTextL( body ); + for( TInt i = 0; i < recipients->Count(); i++ ) + { + messageData->AppendToAddressL( (*recipients)[i] ); + } + for( TInt j = 0; j < attachments->Count(); j++ ) + { + messageData->AppendAttachmentL( (*attachments)[j] ); + } + sendUi->CreateAndSendMessageL( KSenduiMtmMmsUid, messageData, + KNullUid, aLaunchEmbedded ); + + fs.Delete( fileName ); + CleanupStack::PopAndDestroy( cleanUpCount ); + + TELSERVICE_LEAVEFN( "SendMmsMessageL()" ) + return KErrNone; + } +//--------------------------------------------------------------------------------------- +// CBrowserTelService::DisconnectActiveCSDConnectionL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C void CBrowserTelService::DisconnectActiveCSDConnectionL() + { + TELSERVICE_ENTERFN( "DisconnectActiveCSDConnectionL()" ) + + RSocketServ server; + RConnection connection; + TInt err( KErrNone ); + + User::LeaveIfError( server.Connect() ); + CleanupClosePushL( server ); + + User::LeaveIfError( connection.Open( server, KAfInet ) ); + CleanupClosePushL( connection ); + + TUint conns( 0 ); + connection.EnumerateConnections( conns ); + if( conns ) + // we need to check if there is any (HS)CSD conneciton + { + TPckgBuf connInfo; + TBool found = EFalse; + TUint index = 1; + for( index = 1; index <= conns; ++index ) + { + err = connection.GetConnectionInfo( index, connInfo ); + if( err == KErrNone ) + { + TApBearerType bearerType = EApBearerTypeGPRS; + + // Fixing SLAA-6k52P which only happens in MAGNUM. Since + // we only need to find if there is CSD or HSCSD, we should + // not leave here + TRAP_IGNORE( bearerType = ConnectionTypeL( connInfo().iIapId ) ); + + if( bearerType == EApBearerTypeCSD || + bearerType == EApBearerTypeHSCSD ) + { + found = ETrue; + } + } + } + + if( found ) + // there is active (HS)CSD. We need to close it. + { + if( ( err = connection.Attach( connInfo, + RConnection::EAttachTypeNormal ) ) == KErrNone ) + { + // disconnect + connection.Stop(); + } + TELSERVICE_WRITE( "Found active (HS)CSD connection" ) + } + } + + CleanupStack::PopAndDestroy( 2 ); // connection, server + + TELSERVICE_LEAVEFN( "DisconnectActiveCSDConnectionL()" ) + + User::LeaveIfError( err ); + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::ShowDialogL() +//--------------------------------------------------------------------------------------- +// +EXPORT_C TInt CBrowserTelService::ShowDialogL( + const TDesC& aDynamicText, + const TBrowserTelServiceDlgType& aDlgType) + { + TELSERVICE_ENTERFN( "ShowDialogL()" ) + + TInt retVal = 0; + + switch( aDlgType ) + { + case EConfirmMakeCall: + { + HBufC* number = NULL; + HBufC* valNumber = NULL; + HBufC* text = NULL; + number = aDynamicText.AllocLC(); + + valNumber = ValidateNumberL( *number ); + CleanupStack::PopAndDestroy( number ); // number; + + CleanupStack::PushL( valNumber ); + + HBufC* name = SearchPbForMatchL( *valNumber ); + if( name ) + { + CleanupStack::PushL( name ); + text = StringLoader::LoadL( + R_QTN_WML_WTAI_CALL_NO, *name ); + CleanupStack::PopAndDestroy(); // name + CleanupStack::PushL( text ); + } + else + { + text = StringLoader::LoadLC( + R_QTN_WML_WTAI_CALL_NO, *valNumber ); + } + + retVal = TDialerDialogs::ConfirmationDlgL( + *text, R_CONFIRMATION_DIALOG ); + + CleanupStack::PopAndDestroy( 2 ); // valNumber, text + } + break; + + case EConfirmSendDTMF: + { + HBufC* text = StringLoader::LoadLC( + R_QTN_WML_WTAI_SEND_DTMF, aDynamicText, CEikonEnv::Static() ); + retVal = TDialerDialogs::ConfirmationDlgL( + *text, R_CONFIRMATION_DIALOG ); + CleanupStack::PopAndDestroy(); // text + } + break; + + case EConfirmAddToPb: + { + TInt index = 0; + CAknListQueryDialog* dlg = + new( ELeave ) CAknListQueryDialog( &index ); + if ( dlg->ExecuteLD( R_ADD_TO_CONTACTS_DIALOG ) ) + { + return index; + } + else + { + User::Leave( KErrCancel ); + } + } + break; + + case ESendingDTMF: + { + HBufC* text = StringLoader::LoadLC( + R_QTN_DTMF_SENDING_WAIT_NOTE, + aDynamicText, CEikonEnv::Static() ); + if( !iWaitDlg ) + { + TELSERVICE_WRITE( "Create Sending DTMF wait dialog" ) + iWaitDlg = new ( ELeave ) CAknWaitDialog( + reinterpret_cast( &iWaitDlg ), ETrue ); + iWaitDlg->SetCallback( this ); + iWaitDlg->PrepareLC( R_SENDDTMF_DIALOG ); + iWaitDlg->SetTextL( *text ); + iWaitDlg->RunLD(); + } + else + { + TELSERVICE_WRITE( "Update Sending DTMF wait dialog" ) + iWaitDlg->SetTextL( *text ); // Just update the text + } + CleanupStack::PopAndDestroy(); // text + } + break; + default: + break; + } + TELSERVICE_LEAVEFN( "ShowDialogL()" ) + return retVal; + } + + + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::MakeVOIPCall() +//--------------------------------------------------------------------------------------- +// +EXPORT_C TInt CBrowserTelService::MakeVOIPCall( TDesC& aNumber, + TBool aSendDTMFAlwaysConfirm ) + { + TELSERVICE_ENTERFN( "MakeVOIPCall() synchronous" ) + + TInt retVal( KErrNone ); + + iRetVal = KErrNone; + + // Flag to indicate that synchronous method was called + iSynch = ETrue; + TBool voipCall = ETrue; + TRAP( retVal, MakeCallL( aNumber, aSendDTMFAlwaysConfirm, voipCall ) ); + + if( retVal != KErrNone ) + { + ErrorHandler( retVal ); + + retVal = KErrCancel; + } + iSynch = EFalse; + + TELSERVICE_LEAVEFN( "MakeVOIPCall() synchronous" ) + return retVal; + } + + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::DoCancel() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::DoCancel() + { + TELSERVICE_ENTERFN( "DoCancel()" ) + + switch( State() ) + { + case EDialing: + { + iRCall.DialCancel(); + } + break; + + case EDialingDTMF: + { + iRAdvGsmPhone.StopDTMFTone(); + if( iInternalDTMFWaitStarted ) + { + // We have to hold on a bit so that the CSendAppUi is + // properly initialized + iIdle->Start( TCallBack( IdleCallback,this ) ); + } + } + break; + + case EConnected: + { + } + break; + + case EIdle: + default: + break; + } + + TELSERVICE_LEAVEFN( "DoCancel()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::RunL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::RunL() + { + TELSERVICE_ENTERFN( "CBrowserTelService::RunL()" ) + + RCall::TStatus callStatus; + callStatus = RCall::EStatusUnknown; + + iRCall.GetStatus( callStatus ); + + TInt status = iStatus.Int(); + TELSERVICE_WRITE_FORMAT( "status: %d", status ); + TELSERVICE_WRITE_FORMAT( "callStatus: %d", callStatus ); + + if ( status != KErrNone ) + { + TELSERVICE_WRITE_FORMAT( "RunL() - iStatus error: %d", status ) + HandleError( status ); + return; + } + + if( status == KErrNone ) + { + switch( State() ) + { + // the call is now active + case EDialing: + { + TELSERVICE_WRITE( "RunL - KDialing" ) + + BringBrowserToForeground(); + + if( callStatus == RCall::EStatusConnected ) + { + SetState( EConnected ); + // Notify the observer + NotifyObservers(); + + if( iSynch ) + { + iWait.AsyncStop(); // stop the wait loop. + // Now DoMakeCallL will return + } + else + { // async variant was called + if( HandleInternalSendDTMFL() == EFalse ) + { // nothing to handle anymore + + // Complete the request + TELSERVICE_WRITE_FORMAT( + "Complete the request: %d",KErrNone ) + + User::RequestComplete( + iUserRequestStatus, KErrNone ); + } + } + } + } + break; + + // the DTMF tones have been sent + case EDialingDTMF: + { + TELSERVICE_WRITE( "RunL - KDialingDTMF" ) + + iRAdvGsmPhone.Close(); + + if( HandleInternalSendDTMFL() == EFalse ) + { // nothing to handle anymore + SetState( EConnected ); + // Notify the observer + NotifyObservers(); + + if( iSynch || iInternalDTMFWaitStarted ) + { + iWait.AsyncStop(); // stop the wait loop. + //Now SendDTMFL() will return + } + else + { + // Asynchronous method was called. + if( iWaitDlg ) + { + iWaitDlg->ProcessFinishedL(); + } + // Complete the request + TELSERVICE_WRITE_FORMAT( + "Complete the request: %d",KErrNone ) + + User::RequestComplete( iUserRequestStatus, KErrNone ); + } + } + } + break; + + // the call has been active, but + // the caller has hanged up. + case EConnected: + { + TELSERVICE_WRITE( "RunL - EPhoneAnswered,EConnected" ) + + if( iCallStatus == RCall::EStatusIdle || + iCallStatus == RCall::EStatusHangingUp ) + { + SetStateIdleAndNotifyObservers(); + } + } + break; + + case EIdle: + default: + { + TELSERVICE_WRITE( "RunL - Default" ) + break; + } + } + } + else + { + if ( State() == EDialing ) + { + BringBrowserToForeground(); + // If there is not activate voice call on + // changes state to EIdle. + CheckIsThereActivateVoiceCallOnL(); + // MakeCall must return error code Canceled in this case. + iRetVal = KErrCancel; + + if( iSynch ) + { + iWait.AsyncStop(); // stop the wait loop. + // Now DoMakeCallL will return + } + else + { // async variant was called + if( HandleInternalSendDTMFL() == EFalse ) + { // nothing to handle anymore + + // Complete the request + TELSERVICE_WRITE_FORMAT( + "Complete the request: %d",KErrNone ) + + User::RequestComplete( + iUserRequestStatus, KErrNone ); + } + } + } + } + TELSERVICE_LEAVEFN("CBrowserTelService::RunL()") + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::CloseAllSessions() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::CloseAllSessions() + { + TELSERVICE_ENTERFN( "CloseAllSessions()" ) + + iRCall.Close(); + iRLine.Close(); + iRPhone.Close(); + iRTelServer.Close(); + TELSERVICE_LEAVEFN( "CloseAllSessions()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SetStateIdleAndNotifyObserver() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::SetStateIdleAndNotifyObservers() + { + TELSERVICE_ENTERFN("SetStateIdleAndNotifyObservers()") + + SetState( EIdle ); + CloseAllSessions(); + // Notify the observers + NotifyObservers(); + TELSERVICE_LEAVEFN( "SetStateIdleAndNotifyObservers()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::NotifyObservers() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::NotifyObservers() + { + TELSERVICE_ENTERFN( "NotifyObservers()" ) + + TInt count = iObserverList.Count(); + + for( TInt i = 0; i < count ;i++ ) + { + iObserverList[i]->BrowserTelServiceEvent( State() ); + } + TELSERVICE_LEAVEFN( "NotifyObservers()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::NotifyObservers() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::NotifyObservers( TBrowserTelServiceError aError ) + { + TELSERVICE_ENTERFN( "NotifyObservers( TBrowserTelServiceError )" ) + + TInt count = iObserverList.Count(); + + for( TInt i = 0; i < count; i++) + { + iObserverList[i]->BrowserTelServiceError( aError ); + } + TELSERVICE_LEAVEFN( "NotifyObservers(TBrowserTelServiceError)" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::HandleError() +// +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::HandleError( TInt aError ) + { + TELSERVICE_ENTERFN( "HandleError()" ) + + switch( State() ) + { + case EDialingDTMF: + { + iRAdvGsmPhone.Close(); // close RAdvGsmPhone session. + NotifyObservers( ESendDTMFFailed ); + SetState( EConnected ); + NotifyObservers(); + } + break; + + case EDialing: + case EConnected: + { + Cancel(); + } + break; + + case EIdle: + default: + break; + } + + iRetVal = aError; + + if( iSynch || iInternalDTMFWaitStarted ) + { + iWait.AsyncStop(); // stop the wait loop. + // Now synchronous method will return + } + else + { + // Asynchronous method was called. + // Complete the request + TELSERVICE_WRITE_FORMAT( "Complete the request: %d", aError ) + User::RequestComplete( iUserRequestStatus, aError ); + } + TELSERVICE_LEAVEFN( "HandleError()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::EtelWatcherEvent() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::BrowserTelServiceEtelWatcherEvent( + RCall::TStatus& aStatus ) + { + TELSERVICE_ENTERFN( "EtelWatcherEvent()" ) + + if( aStatus == RCall::EStatusIdle ) + { + // the call recepient has hung up without answering the call, + // so lets reset our state and notify observers + + Cancel(); + SetStateIdleAndNotifyObservers(); + + iRetVal = KErrUserBusy; + + if( iSynch ) + { + iWait.AsyncStop(); // stop the wait loop. + // Now DoMakeCallL will return + } + else + { + // Asynchronous method was called. + // Complete the request + TELSERVICE_WRITE_FORMAT( "Complete the request: %d", KErrUserBusy ) + User::RequestComplete( iUserRequestStatus, KErrUserBusy ); + } + } + TELSERVICE_LEAVEFN( "EtelWatcherEvent()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::ConnectionStageAchievedL() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::ConnectionStageAchievedL() + { + TELSERVICE_ENTERFN( "ConnectionStageAchievedL()" ) + iAgentDisconnected = ETrue; + if( iWait.IsStarted() ) + { + iWait.AsyncStop(); + } + TELSERVICE_LEAVEFN( "ConnectionStageAchievedL()" ) + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SearchPbForMatchL() +//--------------------------------------------------------------------------------------- +// +HBufC* CBrowserTelService::SearchPbForMatchL( + const TDesC& aPhoneNumber ) + { + TELSERVICE_ENTERFN( "SearchPbForMatchL()" ) + + HBufC* matchingName = NULL; + + // Create phonebook engine + CPbkContactEngine* pbkEngine = CPbkContactEngine::NewL(); + CleanupStack::PushL( pbkEngine ); + + // Make sure a resource file is available + RPbkViewResourceFile pbkResourceFile( *CCoeEnv::Static() ); + pbkResourceFile.OpenL(); + CleanupClosePushL ( pbkResourceFile ); + + CContactIdArray* idArray = SearchPbForMatchLC( *pbkEngine + ,aPhoneNumber + ,EPhoneNumber + ); + + if( idArray->Count() ) + { + // retrive contact's full matching name + CPbkContactItem* item = pbkEngine->ReadMinimalContactLC( (*idArray)[0] ); + + matchingName = item->GetContactTitleOrNullL(); + + CleanupStack::PopAndDestroy( item ); + } + + CleanupStack::PopAndDestroy( 3 ); // idArray, pbkResourceFile, pbkEngine + + TELSERVICE_LEAVEFN("SearchPbForMatchL()") + + return matchingName; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::SearchPbForMatchLC() +//--------------------------------------------------------------------------------------- +// +CContactIdArray* CBrowserTelService::SearchPbForMatchLC( + CPbkContactEngine& aPbkEngine, + const TDesC& aToMatch, + const TMatchType& aMatchType ) + { + TELSERVICE_ENTERFN( "SearchPbForMatchLC()" ) + + CContactIdArray* idArray = NULL; + + if( aMatchType == EPhoneNumber ) + { + idArray = aPbkEngine.MatchPhoneNumberL( aToMatch, aToMatch.Length() ); + } + else if( aMatchType == EEmail ) + { + CPbkFieldIdArray* findFrom = new( ELeave ) CPbkFieldIdArray; + CleanupStack::PushL( findFrom ); + + findFrom->AppendL( EPbkFieldIdEmailAddress ); + idArray = aPbkEngine.FindLC( aToMatch, findFrom ); + + CleanupStack::Pop( idArray ); + CleanupStack::PopAndDestroy( findFrom ); + } + + CleanupStack::PushL( idArray ); + TELSERVICE_LEAVEFN( "SearchPbForMatchLC()" ) + return idArray; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::IdleCallback() +//--------------------------------------------------------------------------------------- +// +TInt CBrowserTelService::IdleCallback( TAny* aTelService ) + { + TELSERVICE_ENTERFN( "IdleCallback()" ) + ( ( CBrowserTelService* ) aTelService )->DoIdleCallback(); + TELSERVICE_LEAVEFN( "IdleCallback()" ) + return EFalse; // return false since we don't want to run idle again + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::IdleCallback() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::DoIdleCallback() + { + TELSERVICE_WRITE( "DoIdleCallback()" ) + iWait.AsyncStop(); + } + +// --------------------------------------------------------- +// CBrowserTelService::DialogDismissedL +// --------------------------------------------------------- +// +void CBrowserTelService::DialogDismissedL( TInt aButtonId ) + { + TELSERVICE_ENTERFN( "DialogDismissedL()" ) + + if ( aButtonId == EAknSoftkeyCancel ) + { + Cancel(); + } + iWaitDlg = NULL; // Dialog will delete itself; prevent DoCancel + // deleting it beforehand. + TELSERVICE_LEAVEFN( "DialogDismissedL()" ) + } + +// --------------------------------------------------------- +// CBrowserTelService::HandleInternalSendDTMFL +// --------------------------------------------------------- +// +TBool CBrowserTelService::HandleInternalSendDTMFL() + { + TELSERVICE_ENTERFN( "HandleInternalSendDTMFL()" ) + + iSynch = EFalse; // Reset to EFalse since the HandleInternalSendDTMFL() + // is asynchronous! + + if( !(iSendableDTMFNumbers && iDlgDTMFNumbers) ) + { + return EFalse; + } + + TBool retVal = EFalse; + + CRepository* repository = CRepository::NewL( KCRUidBrowser ); + CleanupStack::PushL (repository ); + repository->Get( KBrowserConfirmedDTMFOnce, iConfirmedOnce ); + + if( iSendableDTMFNumbers->Count() > 0 && iDlgDTMFNumbers->Count() > 0 ) + { + TELSERVICE_WRITE( "we have dtmf numbers to send" ) + TInt sendDTMF = 1; + TPtr sendableNumberPtr = iSendableDTMFNumbers->At(0)->Des(); + TPtr dlgNumberPtr = iDlgDTMFNumbers->At(0)->Des(); + + if( DisplaySendDTMFDialog( &dlgNumberPtr ) ) + { + if( dlgNumberPtr.Length() > 0 ) + { + TELSERVICE_WRITE( "display send dtmf dialog" ) + if( iDTMFAlwaysConfirm ) + { + sendDTMF = ShowDialogL( dlgNumberPtr,EConfirmSendDTMF ); + } + else if( iDTMFAlwaysConfirm == EFalse && + iConfirmedOnce == EFalse ) + { + sendDTMF = ShowDialogL( dlgNumberPtr, + EConfirmSendDTMF ); + iConfirmedOnce = ETrue; + repository->Set( KBrowserConfirmedDTMFOnce, iConfirmedOnce ); + } + else + { + sendDTMF = 1; + } + } + else + { + TELSERVICE_WRITE("don't display send dtmf dialog dlgNumberPtr.Length() < 0") + sendDTMF = 0; + } + } + else + { + TELSERVICE_WRITE( "don't display send dtmf dialog" ) + + if( dlgNumberPtr.Length() > 0 ) + { + TELSERVICE_WRITE( "start dtmf wait timer" ) + + RTimer timer; + TRequestStatus timerStatus; // request status + // associated with timer + timer.CreateLocal(); // create for this thread + timer.After( timerStatus, KTimerDelay ); // pause for 2,5 + // seconds + User::WaitForRequest( timerStatus ); + timer.Close(); + } + else + { + sendDTMF = 0; + } + } + + if( sendDTMF ) + { + TELSERVICE_WRITE( "Send the DTMF" ) + + RipWaitChar( &sendableNumberPtr ); + ValidateDTMFNumberL( &sendableNumberPtr ); + // Send DTMF tones + DoSendDTMFL( sendableNumberPtr ); + + TELSERVICE_WRITE( "DoSendDTMFL() ok!" ) + + ShowDialogL( dlgNumberPtr, ESendingDTMF ); + retVal = ETrue; + } + + iSendableDTMFNumbers->Delete(0); + iSendableDTMFNumbers->Compress(); + iDlgDTMFNumbers->Delete(0); + iDlgDTMFNumbers->Compress(); + } + + CleanupStack::PopAndDestroy( repository ); + + TELSERVICE_LEAVEFN( "HandleInternalSendDTMFL()" ) + return retVal; + } + +// --------------------------------------------------------------------------- +// CBrowserTelService::BringBrowserToForeground +// --------------------------------------------------------------------------- +// +void CBrowserTelService::BringBrowserToForeground() + { + TELSERVICE_ENTERFN( "BringBrowserToForeground()" ) + TApaTaskList taskList( CEikonEnv::Static()->WsSession() ); + TUid wapUid = KUidBrowserApplication; + TApaTask task = taskList.FindApp( wapUid ); + task.BringToForeground(); + TELSERVICE_LEAVEFN( "BringBrowserToForeground()" ) + } + +// --------------------------------------------------------------------------- +// CBrowserTelService::CheckIsThereActivateVoiceCallOnL +// --------------------------------------------------------------------------- +// +void CBrowserTelService::CheckIsThereActivateVoiceCallOnL() + { + RTelServer::TPhoneInfo info; + RPhone::TLineInfo lineInfo; + RLine::TLineInfo callInfo; + + // Connect to the telephony server and load the TSY. + User::LeaveIfError( iRTelServer.Connect() ); + User::LeaveIfError( iRTelServer.LoadPhoneModule( KMmTsyModuleName ) ); + // Get the details for the first (and only) phone. + User::LeaveIfError( iRTelServer.GetPhoneInfo( 0, info ) ); + // Open the phone. + iRPhone.Close(); + User::LeaveIfError( iRPhone.Open( iRTelServer, info.iName ) ); + // Get the information for the voice line, line 0. + User::LeaveIfError( iRPhone.GetLineInfo( 0, lineInfo ) ); + + if( lineInfo.iStatus > RCall::EStatusIdle ) + { + TELSERVICE_WRITE( "There's an active call" ); + // Open the line. iName will now be "VoiceLine1". + iRLine.Close(); + User::LeaveIfError( iRLine.Open( iRPhone, KMmTsyVoice1LineName ) ); + TInt count; + // Gets the number of calls opened from a line. + User::LeaveIfError( iRLine.EnumerateCall( count ) ); + if ( count >= 1 ) + { + SetState( EConnected ); + User::LeaveIfError( iRLine.GetInfo( callInfo ) ); + iRCall.Close(); + + User::LeaveIfError( iRCall.OpenExistingCall( iRLine, + callInfo.iNameOfLastCallAdded ) ); + } + else + { + SetState( EIdle ); + } + } + else + { + TELSERVICE_WRITE( "No active call" ); + SetState( EIdle ); + } + } + +// --------------------------------------------------------------------------- +// CBrowserTelService::CheckDTMFNumber +// --------------------------------------------------------------------------- +// +void CBrowserTelService::CheckDTMFNumberL( TDesC& aNumber ) + { + TBool multiw = EFalse; + TBool multikeno = EFalse; + + for ( TInt i = 0; i < aNumber.Length(); i++ ) + { + if( (KValidDTMFChars().Locate( aNumber[i] ) ) == KErrNotFound ) + { + User::Leave( KErrArgument ); + } + else + { + if( aNumber[i] == 'w' ) + { + if( multiw ) + { + User::Leave( KErrArgument ); + } + multiw = ETrue; + } + else if( aNumber[i] == '/' ) + { + if( multikeno ) + { + User::Leave( KErrArgument ); + } + multikeno = ETrue; + } + } + } + } + +// --------------------------------------------------------------------------- +// CBrowserTelService::CheckDTMFNumber +// --------------------------------------------------------------------------- +// +CPbkContactItem* CBrowserTelService::SearchPBItemLC( CPbkContactEngine& aPbkEngine, + TDesC& aNumber, + TDesC& aEmail, + TBool& aNewContact ) + { + CPbkContactItem* contactItem = NULL; + CContactIdArray* idArrayPhoneNr = SearchPbForMatchLC( aPbkEngine, aNumber, EPhoneNumber ); + CContactIdArray* idArrayEmail = SearchPbForMatchLC( aPbkEngine, aEmail, EEmail ); + + aNewContact = ETrue; + + if( idArrayPhoneNr->Count() && aNumber.Length() ) + { + // Open existing + if ( ShowDialogL( aNumber, EConfirmAddToPb ) ) + { + contactItem = aPbkEngine.OpenContactL( ( *idArrayPhoneNr )[0] ); + aNewContact = EFalse; + } + else + { + // Create a new contact + contactItem = aPbkEngine.CreateEmptyContactL(); + } + + } + else if( idArrayEmail->Count() && aEmail.Length() ) + { + if ( ShowDialogL( aEmail, EConfirmAddToPb ) ) + { + // Open existing + contactItem = aPbkEngine.OpenContactL( ( *idArrayEmail )[0] ); + aNewContact = EFalse; + } + else + { + // Create a new contact + contactItem = aPbkEngine.CreateEmptyContactL(); + } + } + else + { + // Create a new contact + contactItem = aPbkEngine.CreateEmptyContactL(); + } + + CleanupStack::PopAndDestroy( 2 ); // idArrayEmail,idArrayPhoneNr + + CleanupStack::PushL( contactItem ); + + return contactItem; + } + +// --------------------------------------------------------------------------- +// CBrowserTelService::SetPBEntryField() +// --------------------------------------------------------------------------- +// +void CBrowserTelService::SetPBEntryFieldL( TInt aField, + CPbkContactEngine* aPbkEngine, + CPbkContactItem* aContactItem, + const TPtrC& aFieldValue, + TInt& aFormIndex ) + { + if( aFieldValue.Length() ) + { + TPbkContactItemField *dataField = aContactItem->FindField( aField ); + + if( !dataField ) + { + CPbkFieldInfo* newFieldType = NULL; + + for ( TInt i = 0; !newFieldType && + i < aPbkEngine->FieldsInfo().Count(); ++i ) + { + CPbkFieldInfo* fieldInfo = aPbkEngine->FieldsInfo()[i]; + if( fieldInfo->FieldId() == aField ) + { + // we found the proper field. Yeah! + newFieldType = fieldInfo; + } + } + // add new field + dataField = aContactItem->AddOrReturnUnusedFieldL( *newFieldType ); + } + + if( dataField ) + { + // Put the data to the field + dataField->TextStorage()->SetTextL( aFieldValue ); + if( aFormIndex == -1 ) + { + aFormIndex = aContactItem->FindFieldIndex( *dataField ); + } + } + } + } + +// --------------------------------------------------------------------------- +// CBrowserTelService::ParseRecipientsLC +// --------------------------------------------------------------------------- +// +CPtrC16Array* CBrowserTelService::ParseRecipientsLC( const TDesC& aRecipients ) + { + CPtrC16Array* recips = new( ELeave ) CPtrC16Array( 2 ); + + CleanupStack::PushL( recips ); + + if( aRecipients.Length() ) + { + TPtrC tempRec( aRecipients ); + + do + { + int posComma = tempRec.Find( _L(",") ); + + + if( posComma != KErrNotFound ) + { + recips->AppendL( tempRec.Left( posComma ) ); + tempRec.Set( tempRec.Right( tempRec.Length() - posComma - 1 ) ); + } + else + { + recips->AppendL( tempRec ); + tempRec.Set( KNullDesC ); + } + + }while( tempRec.Length() ); + } + + return recips; + } + +// --------------------------------------------------------------------------- +// CBrowserTelService::ConnectionTypeL +// --------------------------------------------------------------------------- +// +TApBearerType CBrowserTelService::ConnectionTypeL( TUint aApId ) + { + CCommsDatabase* commsDb = CCommsDatabase::NewL( EDatabaseTypeIAP ); + CleanupStack::PushL( commsDb ); + + CApDataHandler* apDataHandler = CApDataHandler::NewLC( *commsDb ); + TUint32 apId = 0; + CApUtils* apUtils = CApUtils::NewLC( *commsDb ); + + apId = apUtils->WapIdFromIapIdL( aApId ); + + CleanupStack::PopAndDestroy(); //apUtils + apUtils = NULL; + + CApAccessPointItem* apItem = CApAccessPointItem::NewLC(); + + apDataHandler->AccessPointDataL( apId, *apItem ); + + TApBearerType bearerType = apItem->BearerTypeL(); + + CleanupStack::PopAndDestroy( 3 ); // apItem, apDataHandler, commsDb + + return bearerType; + } + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::ErrorHandler() +//--------------------------------------------------------------------------------------- +// +void CBrowserTelService::ErrorHandler( TInt aErrorId ) + { + TELSERVICE_WRITE_FORMAT( "Error handler: %d", aErrorId ); + + if( aErrorId == KErrCancel ) + { + return; + } + + TInt i; + for( i = 0; KErrorConvTable[i][0] && KErrorConvTable[i][0] != aErrorId; ++i ){}; + + if( KErrorConvTable[i][0] ) + { + // If KErrorConvTable[i][1] is 0 it's already handled by the system + if( KErrorConvTable[i][1] ) + { + TRAP_IGNORE( iErrorUi->ShowGlobalErrorNoteL( -(KErrorConvTable[i][1] + KKimonoBase )) ); + } + } + else + // global error id is received + { + TRAP_IGNORE( iErrorUi->ShowGlobalErrorNoteL( aErrorId ) ); + } + } + +#ifdef __BROWSER_TEL_SERVICES_CALLUI__ + +//--------------------------------------------------------------------------------------- +// CBrowserTelService::HandleNotifyL() +//--------------------------------------------------------------------------------------- +// +TInt CBrowserTelService::HandleNotifyL( TInt /*aCmdId*/, + TInt /*aEventId*/, + CAiwGenericParamList& /*aEventParamList*/, + const CAiwGenericParamList& /*aInParamList*/ ) + { + TELSERVICE_ENTERFN("CBrowserTelService::HandleNotifyL"); + + if( iSynch && iWait.IsStarted() ) + { + iWait.AsyncStop(); // stop the wait loop. + // Now DoMakeCallL will return + } + else + { + // The client is not interested what happened! + iSynch = EFalse; // Just in case not to start iWait after ExecuteServiceCmdL + if( iUserRequestStatus ) + { + User::RequestComplete( iUserRequestStatus, KErrNone ); + } + } + + TELSERVICE_LEAVEFN( "CBrowserTelService::HandleNotifyL" ); + return KErrNone; + } + +#endif // __BROWSER_TEL_SERVICES_CALLUI__ + +// ================= OTHER EXPORTED FUNCTIONS ============== +