phoneapp/phoneuivoipextension/src/cphonevoiperrormessageshandler.cpp
changeset 0 5f000ab63145
child 21 92ab7f8d0eab
child 61 41a7f70b3818
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneapp/phoneuivoipextension/src/cphonevoiperrormessageshandler.cpp	Mon Jan 18 20:18:27 2010 +0200
@@ -0,0 +1,586 @@
+/*
+* 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