--- /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 <BrowserTelService.rsg>
+#include <coemain.h>
+#include <data_caging_path_literals.hrh>
+
+// For phonebook API
+#include <CPbkContactItem.h> // Phonebook Contact
+#include <CPbkContactEngine.h> // Phonebook Engine
+#include <CPbkFieldsInfo.h> // Phonebook field types
+#include <RPbkViewResourceFile.h>
+#include <CPbkContactEditorDlg.h> // Phonebook editor
+// For searching a matching number from contact's db
+#include <TPbkContactItemField.h>
+#include <CNTFLDST.H>
+
+#include <FeatMgr.h>
+//
+#include <txtrich.h>
+#include <badesca.h>
+#include <miutset.h>
+#include <s32strm.h>
+
+// For email API
+#include <sendui.h>
+#include <CMessageData.h>
+#include <TSendingCapabilities.h>
+#include <SenduiMtmUids.h>
+
+// For BaflUtils
+#include <bautils.h>
+
+// Stringloader
+#include <StringLoader.h>
+
+// TApaTask, TApaTaskList
+#include <apgtask.h>
+
+// Connection management
+#include <in_sock.h>
+#include <es_enum.h>
+
+#include <ApUtils.h>
+#include <APDataHandler.h>
+#include <ApAccessPointItem.h>
+#include <commdb.h>
+
+#include <f32file.h>
+// Const file name for make call
+#include <mmtsy_names.h>
+
+#include <BrowserUiSDKCRKeys.h>
+#include <centralrepository.h>
+
+#include <nwx_status.h>
+
+#include <DialUtils.h>
+
+#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<HBufC>* CBrowserTelService::ParseDTMFSequencesForDlgL(
+ const TDesC* aDTMFString )
+ {
+ TELSERVICE_ENTERFN( "ParseDTMFSequencesForDlgL()" )
+ CArrayPtrFlat<HBufC>* parsedArray = NULL;
+
+ if( aDTMFString )
+ {
+ parsedArray = new ( ELeave ) CArrayPtrFlat<HBufC>( 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<HBufC>* CBrowserTelService::ParseDTMFSequencesL(
+ const TDesC* aDTMFString )
+ {
+ TELSERVICE_ENTERFN( "ParseDTFMSequencesL()" )
+ CArrayPtrFlat<HBufC>* parsedArray = NULL;
+
+ if( aDTMFString )
+ {
+ parsedArray = new ( ELeave ) CArrayPtrFlat<HBufC>(
+ 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<RPbkViewResourceFile> ( 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<len; loopCounter++)
+ {
+ if( (*ptr >= '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<RSocketServ>( server );
+
+ User::LeaveIfError( connection.Open( server, KAfInet ) );
+ CleanupClosePushL<RConnection>( connection );
+
+ TUint conns( 0 );
+ connection.EnumerateConnections( conns );
+ if( conns )
+ // we need to check if there is any (HS)CSD conneciton
+ {
+ TPckgBuf<TConnectionInfo> 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<CEikDialog**>( &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<RPbkViewResourceFile> ( 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 ==============
+