/*
* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Implementation of CPhoneVoIPErrorMessagesHandler class.
*
*/
// INCLUDES
#include <ccpdefs.h>
#include <mpeengineinfo.h>
#include <StringLoader.h>
#include <ccherror.h>
#include <spsettings.h>
#include <spentry.h>
#include <telephonydomainpskeys.h>
#include <UikonInternalPSKeys.h>
#include <aknnotedialog.h>
#include "cphonevoiperrormessageshandler.h"
#include "cphonemainerrormessageshandler.h"
#include "cphoneerrormessageshandler.h"
#include "cphonestatehandle.h"
#include "phonerssvoip.h"
#include "phonelogger.h"
#include "tphonecmdparamglobalnote.h"
#include "tphonecmdparaminteger.h"
#include "cphonemainresourceresolver.h"
#include "phoneui.pan"
#include "cphonepubsubproxy.h"
#include "tphonecmdparamboolean.h"
#include "cphonestatemachinevoip.h"
#include "cphonecustomizationvoip.h"
// ================= MEMBER FUNCTIONS =======================
// C++ default constructor can NOT contain any code, that
// might leave.
//
CPhoneVoIPErrorMessagesHandler::CPhoneVoIPErrorMessagesHandler(
MPhoneViewCommandHandle* aViewCommandHandle,
MPhoneStateMachine* aPhoneStateMachine ) :
CPhoneErrorMessagesHandler( aViewCommandHandle, aPhoneStateMachine )
{
static_cast<CPhoneStateMachineVoIP*>( iStateMachine )->
SetVoipErrorMessageHandler( *this );
}
// -----------------------------------------------------------
// CPhoneErrorMessagesHandler::~CPhoneErrorMessagesHandler()
// Destructor
// (other items were commented in a header).
// -----------------------------------------------------------
//
CPhoneVoIPErrorMessagesHandler::~CPhoneVoIPErrorMessagesHandler()
{
}
// -----------------------------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CPhoneVoIPErrorMessagesHandler::ConstructL()
{
// Register error handler
CPhoneMainErrorMessagesHandler::Instance()->
RegisterErrorMessagesHandler( this );
}
// -----------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::NewL()
// Constructor
// -----------------------------------------------------------
//
CPhoneVoIPErrorMessagesHandler* CPhoneVoIPErrorMessagesHandler::NewL(
MPhoneViewCommandHandle* aViewCommandHandle,
MPhoneStateMachine* aPhoneStateMachine )
{
CPhoneVoIPErrorMessagesHandler* self =
new( ELeave ) CPhoneVoIPErrorMessagesHandler(
aViewCommandHandle,
aPhoneStateMachine );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
// -----------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::ShowErrorSpecificNoteL
// -----------------------------------------------------------
//
void CPhoneVoIPErrorMessagesHandler::ShowErrorSpecificNoteL(
const TPEErrorInfo& aErrorInfo )
{
__LOGMETHODSTARTEND(PhoneUIVoIPExtension, "CPhoneVoipErrorMessagesHandler::ShowErrorSpecificNoteL()");
__PHONELOG1( EBasic, PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::ShowErrorSpecificNoteL - aErrorInfo.iErrorCode =%d ",
aErrorInfo.iErrorCode);
if ( aErrorInfo.iErrorType == EPECcp && IsVoIPCall( aErrorInfo.iCallId ) )
{
switch( aErrorInfo.iErrorCode )
{
case ECCPErrorNotAcceptable:
case ECCPErrorCCServiceNotImplemented:
SendGlobalErrorNoteL( EPhoneVoIPNoAudioSupport );
break;
case ECCPLocalResumeFail:
if ( HasSwapFailed() )
{
SendGlobalErrorNoteL( EPhoneVoIPSwapFail );
}
else
{
HandleHoldErrorNotesL( aErrorInfo.iCallId, EFalse );
}
break;
case ECCPLocalHoldFail:
if ( HasSwapFailed() )
{
SendGlobalErrorNoteL( EPhoneVoIPSwapFail );
}
else
{
HandleHoldErrorNotesL( aErrorInfo.iCallId, ETrue );
}
break;
case ECCPServerFailure:
case ECCPErrorNetworkBusy:
SendGlobalErrorNoteL( EPhoneVoIPNoService );
break;
case ECCPErrorNotReached:
SendGlobalErrorNoteL( EPhoneVoIPNotFound );
break;
case ECCPErrorCCIncompatibleDestination:
SendGlobalErrorNoteL( EPhoneVoIPAddressNotInUse );
break;
case ECCPErrorTimedOut:
case ECCPErrorCCNoRouteToDestination:
SendGlobalErrorNoteL( EPhoneVoIPRequestTimeOut );
break;
case KErrArgument:
case ECCPErrorInvalidPhoneNumber:
case ECCPErrorInvalidURI:
SendGlobalErrorNoteL( EPhoneVoIPInvalidRecipientAddress );
break;
case ECCPErrorBusy:
case ECCPErrorCCCallRejected:
SendGlobalErrorNoteL( EPhoneVoIPNumberBusy );
break;
case ECCPErrorMovedPermanently:
SendGlobalErrorNoteL( EPhoneVoIPAddressNotInUse );
break;
case ECCPErrorCCUserNotResponding:
case ECCPErrorNotResponding:
SendGlobalErrorNoteL( EPhoneVoIPNoAnswer );
break;
case ECCPGlobalFailure:
SendGlobalErrorNoteL( EPhoneVoIPErrorInConnection );
break;
case ECCPSecureCallFailed:
case ECCPErrorUnacceptableChannel:
SendGlobalErrorNoteL( EPhoneSSNotificationTextVoipSipsFailed );
break;
case ECCPErrorNetworkOutOfOrder:
case ECCPErrorMedia:
SendGlobalErrorNoteL( EPhoneVoIPNetworkError );
break;
case ECCPTransferFailed:
iViewCommandHandle->ExecuteCommandL( EPhoneViewRemoveGlobalNote );
SendGlobalErrorNoteL( EPhoneVoIPTransferFail );
break;
case ECCPErrorNoService:
{
TInt serviceID = iStateMachine->PhoneEngineInfo()->ServiceId(
aErrorInfo.iCallId );
ShowErrorNoteWithServiceNameL( EPhoneVoIPServiceUnavailable,
serviceID );
}
break;
default:
CPhoneErrorMessagesHandler::ShowErrorSpecificNoteL( aErrorInfo );
break;
}
}
else if ( aErrorInfo.iErrorType == EPECch )
{
ShowRegistrationErrorNotesL( aErrorInfo.iErrorCode );
}
else
{
CPhoneErrorMessagesHandler::ShowErrorSpecificNoteL( aErrorInfo );
}
}
// -----------------------------------------------------------
// CPhoneVoipErrorMessagesHandler::IsVoIPCall
// -----------------------------------------------------------
//
TBool CPhoneVoIPErrorMessagesHandler::IsVoIPCall( const TInt aCallId ) const
{
__LOGMETHODSTARTEND( PhoneUIVoIPExtension, "CPhoneVoIPErrorMessagesHandler::IsVoipCall() ");
if( aCallId == KErrNotFound )
{
// Illegal call id, check call type command
return ( iStateMachine->PhoneEngineInfo()->CallTypeCommand()
== EPECallTypeVoIP );
}
return ( iStateMachine->PhoneEngineInfo()
->CallType( aCallId )== EPECallTypeVoIP );
}
// -----------------------------------------------------------
// CPhoneVoipErrorMessagesHandler::HandleHoldErrorNotesL
// -----------------------------------------------------------
//
void CPhoneVoIPErrorMessagesHandler::HandleHoldErrorNotesL(
const TInt aCallId, TBool aHold )
{
__LOGMETHODSTARTEND( PhoneUIVoIPExtension, "CPhoneVoIPErrorMessagesHandler::HandleHoldNoteL()");
TPhoneCmdParamGlobalNote globalNoteParam;
HBufC* text = HBufC::NewLC( KPhoneContactNameMaxLength );
TPtr tmp = text->Des();
// Should add name( or RemotePartyName or CompanyName) to Note, if someone found
GetRemoteInfoDataL( aCallId, tmp );
if ( text->Length() )
{
// RemotePartyName, CompanyName or RemoteName found
// Resource text which will use found text will be loaded later
TInt resource( EPhoneVoIPResumeFail );
if ( aHold )
{
resource = EPhoneVoIPHoldFail;
}
// qtn_voip_resume_failed / qtn_voip_hold_failed
globalNoteParam.SetTextResourceId(
CPhoneMainResourceResolver::Instance()->
ResolveResourceID( resource ) );
}
else
{
// Decides note with call id
// Resource is loaded here
TInt resource = EPhoneVoIPResumeNumberFail;
if ( aHold )
{
resource = EPhoneVoIPHoldNumberFail;
}
// qtn_voip_resume_number_failed / qtn_voip_hold_number_failed
const TInt tmpResourceId = CPhoneMainResourceResolver::Instance()->
ResolveResourceID( resource );
TInt callId = aCallId;
callId++; // Real call id index starts from 0, increase value by one
CleanupStack::PopAndDestroy( text ); // Delete reserver buffer
text = StringLoader::LoadLC(
tmpResourceId,
callId,
CCoeEnv::Static() ); // Load new buffer
}
globalNoteParam.SetText( *text );
globalNoteParam.SetType( EAknGlobalConfirmationNote );
globalNoteParam.SetTone( EAvkonSIDInformationTone );
iViewCommandHandle->ExecuteCommandL(
EPhoneViewShowGlobalNote, &globalNoteParam );
CleanupStack::PopAndDestroy( text );
}
// -----------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::GetRemoteInfoDataL
// -----------------------------------------------------------
//
void CPhoneVoIPErrorMessagesHandler::GetRemoteInfoDataL(
TInt aCallId,
TDes& aData ) const
{
__LOGMETHODSTARTEND( PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::GetRemoteInfoDataL()" );
__ASSERT_DEBUG( iStateMachine->PhoneEngineInfo(),
Panic( EPhoneCtrlInvariant ) );
// Note next if-statements are in priority order so be careful if you change order
// or add new if-statements.
if ( iStateMachine->PhoneEngineInfo()->RemoteName( aCallId ).Length() )
{
__PHONELOG1( EBasic, PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::GetRemoteInfoDataL - remote name = %S",
&iStateMachine->PhoneEngineInfo()->RemoteName( aCallId ) );
if ( iStateMachine->PhoneEngineInfo()->RemoteName( aCallId ).Length()
< KPhoneContactNameMaxLength )
{
// Display the contact name if it is available
aData.Copy( iStateMachine->PhoneEngineInfo()->RemoteName( aCallId ) );
}
}
else if ( iStateMachine->PhoneEngineInfo()->RemoteCompanyName( aCallId ).Length() )
{
__PHONELOG1( EBasic, PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::GetRemoteInfoDataL - remote company name = %S",
&iStateMachine->PhoneEngineInfo()->RemoteCompanyName( aCallId ) );
if ( iStateMachine->PhoneEngineInfo()->RemoteCompanyName( aCallId ).Length()
< KPhoneContactNameMaxLength )
{
// Display the company name if it is available
aData.Copy( iStateMachine->PhoneEngineInfo()->RemoteCompanyName( aCallId ) );
}
}
else if( iStateMachine->PhoneEngineInfo()->RemotePartyName( aCallId ).Length() )
{
__PHONELOG1( EBasic, PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::GetRemoteInfoDataL - remote party name = %S",
&iStateMachine->PhoneEngineInfo()->RemotePartyName( aCallId ) );
if ( iStateMachine->PhoneEngineInfo()->RemotePartyName( aCallId ).Length()
< KPhoneContactNameMaxLength )
{
// Display the remote party name if it is available
aData.Copy( iStateMachine->PhoneEngineInfo()->RemotePartyName( aCallId ) );
}
}
else
{
__PHONELOG( EBasic, PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::GetRemoteInfoDataL - not found" );
aData.Zero();
}
}
// -----------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::ShowRegistrationErrorNotesL
// -----------------------------------------------------------
//
void CPhoneVoIPErrorMessagesHandler::ShowRegistrationErrorNotesL(
TInt aErrorCode )
{
__LOGMETHODSTARTEND( PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::ShowRegistrationErrorNotesL()" );
// Dismiss service enabling wait note
iViewCommandHandle->ExecuteCommandL( EPhoneViewRemoveGlobalWaitNote );
switch ( aErrorCode )
{
case KCCHErrorAccessPointNotDefined:
{
TUint32 serviceId =
iStateMachine->PhoneEngineInfo()->ServiceIdCommand();
ShowErrorNoteWithServiceNameL( EPhoneVoIPNoConnectionsDefined,
serviceId );
break;
}
case KCCHErrorBandwidthInsufficient:
{
TUint32 serviceId =
iStateMachine->PhoneEngineInfo()->ServiceIdCommand();
ShowErrorNoteWithServiceNameL( EPhoneVoIPCallsNotSupported,
serviceId );
break;
}
case KCCHErrorInvalidSettings:
{
TUint32 serviceId =
iStateMachine->PhoneEngineInfo()->ServiceIdCommand();
ShowErrorNoteWithServiceNameL( EPhoneVoIPDefectiveSettings,
serviceId );
break;
}
case KCCHErrorAuthenticationFailed:
{
SendGlobalErrorNoteL( EPhoneVoIPAuthenticationFailed );
break;
}
case KCCHErrorInvalidIap:
case KCCHErrorNetworkLost:
case KCCHErrorServiceNotResponding:
{
TUint32 serviceId =
iStateMachine->PhoneEngineInfo()->ServiceIdCommand();
ShowErrorNoteWithServiceNameL( EPhoneVoIPNoConnectionsAvailable,
serviceId );
break;
}
case KCCHErrorLoginFailed:
default:
{
TUint32 serviceId =
iStateMachine->PhoneEngineInfo()->ServiceIdCommand();
ShowErrorNoteWithServiceNameL( EPhoneVoIPServiceUnavailable,
serviceId );
break;
}
}
}
// ---------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::SendGlobalErrorNoteWithTextL
// ---------------------------------------------------------
//
void CPhoneVoIPErrorMessagesHandler::SendGlobalErrorNoteWithTextL(
TInt aResourceId,
RBuf& aText )
{
__LOGMETHODSTARTEND( PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::SendGlobalErrorNoteL()" );
__ASSERT_DEBUG( aResourceId, Panic( EPhoneCtrlParameterNotInitialized ) );
if ( CPhonePubSubProxy::Instance()->Value(
KPSUidUikon, KUikGlobalNotesAllowed ) == 1 )
{
// Re-enable global notes
TPhoneCmdParamBoolean globalNotifierParam;
globalNotifierParam.SetBoolean( EFalse );
iViewCommandHandle->ExecuteCommandL(
EPhoneViewSetGlobalNotifiersDisabled,
&globalNotifierParam );
TPhoneCmdParamGlobalNote globalNoteParam;
globalNoteParam.SetType( EAknGlobalErrorNote );
globalNoteParam.SetTextResourceId(
CPhoneMainResourceResolver::Instance()->
ResolveResourceID( aResourceId ) );
globalNoteParam.SetText( aText );
globalNoteParam.SetTone( CAknNoteDialog::EErrorTone );
iViewCommandHandle->ExecuteCommandL(
EPhoneViewShowGlobalNote, &globalNoteParam );
}
}
// -----------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::GetServiceProviderNameL
// -----------------------------------------------------------
//
void CPhoneVoIPErrorMessagesHandler::GetServiceProviderNameL(
RBuf& aServiceName,
TUint32 aServiceId )
{
__LOGMETHODSTARTEND( PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::GetServiceProviderNameL" )
CSPEntry* serviceEntry = CSPEntry::NewLC();
CSPSettings* serviceProviderSettings = CSPSettings::NewLC();
User::LeaveIfError(
serviceProviderSettings->FindEntryL( aServiceId, *serviceEntry ) );
User::LeaveIfError(
aServiceName.Create( serviceEntry->GetServiceName() ) );
CleanupStack::PopAndDestroy( serviceProviderSettings );
CleanupStack::PopAndDestroy( serviceEntry );
}
// -----------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::ShowErrorNoteContainingServiceNameL
// -----------------------------------------------------------
//
void CPhoneVoIPErrorMessagesHandler::ShowErrorNoteWithServiceNameL(
TInt aResourceId,
TUint32 aServiceId )
{
__LOGMETHODSTARTEND( PhoneUIVoIPExtension,
"CPhoneVoIPErrorMessagesHandler::ShowErrorNoteWithServiceNameL" )
RBuf serviceName;
CleanupClosePushL( serviceName );
GetServiceProviderNameL( serviceName, aServiceId );
SendGlobalErrorNoteWithTextL( aResourceId, serviceName );
CleanupStack::PopAndDestroy( &serviceName );
}
// -----------------------------------------------------------
// CPhoneVoIPErrorMessagesHandler::HasSwapFailed
// -----------------------------------------------------------
//
TBool CPhoneVoIPErrorMessagesHandler::HasSwapFailed() const
{
TPEState callState( EPEStateUnknown );
TPECallType callType( EPECallTypeUninitialized );
TPEState confCallState( EPEStateUnknown );
TInt connectedCalls( 0 );
TInt heldCalls( 0 );
TInt voipCalls( 0 );
TBool ret( EFalse );
for ( TInt i=0; i < KPEMaximumNumberOfVoiceCalls; i++ )
{
callState = iStateMachine->PhoneEngineInfo()->CallState( i );
callType = iStateMachine->PhoneEngineInfo()->CallType( i );
if ( EPEStateConnected == callState )
{
connectedCalls++;
if ( EPECallTypeVoIP == callType )
{
voipCalls++;
}
}
else if ( EPEStateHeld == callState )
{
heldCalls++;
if ( EPECallTypeVoIP == callType )
{
voipCalls++;
}
}
}
confCallState = iStateMachine->PhoneEngineInfo()->CallState( KPEConferenceCallID );
// At least one of the calls is VoIP call (conference or single)
if ( voipCalls )
{
if ( EPEStateConferenceIdle == confCallState )
{
// Look for connected/hold and hold/hold combinations
if ( ( 1 == connectedCalls && 1 == heldCalls ) ||
2 == heldCalls )
{
ret = ETrue;
}
}
/* Check scenario that the other call is conference
* 1) Putting VoIP call on hold fails, as a result there is a single connected
* call and conference is on hold
* 2) Resuming VoIP call fails, all calls are on hold (because conference is
* first put on hold successfully)
*/
else if ( ( 1 == connectedCalls && EPEStateHeldConference == confCallState ) ||
( 0 == connectedCalls && EPEStateHeldConference == confCallState ) )
{
ret = ETrue;
}
}
__PHONELOG1( EBasic, PhoneUIVoIPExtension, "CPhoneVoIPErrorMessagesHandler::HasSwapFailed() returned %D", ret );
return ret;
}
// End of File