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