voipplugins/sipconnectionprovider/src/scpsipconnection.cpp
branchRCL_3
changeset 22 d38647835c2e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/voipplugins/sipconnectionprovider/src/scpsipconnection.cpp	Wed Sep 01 12:29:57 2010 +0100
@@ -0,0 +1,1155 @@
+/*
+* Copyright (c) 2007-2010 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:  Interface to SIP profiles.
+*
+*/
+
+#include <sipprofileregistry.h>
+#include <sipprofile.h>
+#include <sipmanagedprofile.h>
+#include <sipmanagedprofileregistry.h>
+#include <sipconnection.h>
+#include <commdb.h>
+#include <ccherror.h>
+
+#include "scpsipconnection.h"
+#include "scplogger.h"
+#include "scpsipconnectionobserver.h"
+#include "scputility.h"
+#include "voipeventlog.h"
+
+// If EnableL fails a timeout for reporting error
+const TInt KEnableTimeout = 120000000;
+
+const TInt KUsernameMaxLength = 255;
+
+_LIT8( KSCPAt8, "@" );
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::CScpSipConnection
+// -----------------------------------------------------------------------------
+//
+CScpSipConnection::CScpSipConnection( 
+    TInt aProfileId, 
+    CSIPProfileRegistry& aProfileRegistry,
+    CSIPManagedProfileRegistry& aManagedProfileRegistry,
+    CSIP& aSip ) :
+    iProfileId( aProfileId ),
+    iProfileRegistry( aProfileRegistry ),
+    iManagedProfileRegistry( aManagedProfileRegistry ),
+    iSip( aSip ),
+    iRegistrationRequestState( ENoRequest ),
+    iConnectionStateError( KErrNone ),
+    iReserved( EFalse ),
+    iIapAvailableOffered( EFalse )
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::CScpSipConnection profile id: %d", 
+                   this, aProfileId );
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::ConstructL()
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::ConstructL", this );
+
+    iSipProfile = iProfileRegistry.ProfileL( iProfileId );
+
+    if ( !iSipProfile )
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    iEnableTimeoutTimer = CPeriodic::NewL( CPeriodic::EPriorityStandard );
+    
+    User::LeaveIfError( iConnectionMonitor.ConnectL() );
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::NewL
+// -----------------------------------------------------------------------------
+//
+CScpSipConnection* CScpSipConnection::NewL( 
+    TInt aProfileId, 
+    CSIPProfileRegistry& aProfileRegistry,
+    CSIPManagedProfileRegistry& aManagedProfileRegistry,
+    CSIP& aSip )
+    {
+    SCPLOGSTRING( "CScpSipConnection::NewL" );
+    __ASSERT_DEBUG( aProfileId > 0, User::Panic( KNullDesC, KErrGeneral ) );
+
+    CScpSipConnection* self = new (ELeave) CScpSipConnection( aProfileId,
+                                                              aProfileRegistry,
+                                                              aManagedProfileRegistry,
+                                                              aSip );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+    
+// -----------------------------------------------------------------------------
+// CScpSipConnection::~CScpSipConnection
+// -----------------------------------------------------------------------------
+//
+CScpSipConnection::~CScpSipConnection()
+    {  
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::~CScpSipConnection", this );
+
+    delete iSipConnection;
+    iConnectionMonitor.Close();
+    delete iEnableTimeoutTimer;
+    delete iSipProfile;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::AddObserver
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::AddObserver( MScpSipConnectionObserver& aObserver )
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::AddObserverL: 0x%x",this, &aObserver );
+
+    iObserver = &aObserver;
+    } 
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::RemoveObserver
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::RemoveObserver( MScpSipConnectionObserver& aObserver )
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::RemoveObserver: 0x%x", this, &aObserver );
+
+    if ( &aObserver == iObserver )
+        {
+        iObserver = NULL;
+        return KErrNone;
+        }
+
+    return KErrNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::ProfileId
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::ProfileId() const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::ProfileId", this );
+
+    return iProfileId;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::EnableL
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::EnableL()
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::EnableL", this );
+
+    if ( iRegistrationRequestState != ERegistrationRequested )
+        {
+        iConnectionStateError = KErrNone;
+        iRegistrationRequestState = ERegistrationRequested;
+
+        TUint32 iapId( 0 );
+        TUint32 snapId( 0 );
+
+        TInt result = GetSnap( snapId );
+
+        if ( result == KErrNotFound || snapId == 0 )
+            {
+            SCPLOGSTRING2( "CScpSipConnection[0x%x]::EnableL - SNAP not found", this );
+            result = GetIap( iapId );
+            }
+   
+        // If username is not set leave directly with KCCHErrorAuthenticationFailed
+        if ( !IsUsernameSetL() )
+            {
+            SCPLOGSTRING2( "CScpSipConnection[0x%x]::EnableL - AuthenticationFailed !!!", this );
+            User::Leave( KCCHErrorAuthenticationFailed );
+            }
+        
+        iProfileRegistry.EnableL( *iSipProfile, *this );
+          
+        if ( !iSipConnection && 0 != iapId )
+             {
+             iSipConnection = CSIPConnection::NewL( iSip, iapId, *this );
+             }
+        
+        TBool connectionAvailable = IsNetworkConnectionAvailable();
+        
+        if ( connectionAvailable )
+            {
+            TBool registered( EFalse );
+            User::LeaveIfError( iSipProfile->GetParameter( KSIPProfileRegistered, 
+                                                           registered ) );
+
+            if ( !registered )
+                {
+                StartEnableTimeoutTimer( CScpSipConnection::EnableTimeout );
+                }
+            }        
+        else
+            {
+            iConnectionStateError = KCCHErrorNetworkLost;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::Disable
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::Disable()
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::Disable", this );
+
+    iRegistrationRequestState = EDeregistrationRequested;
+    
+    CancelEnableTimeoutTimer();
+    
+    delete iSipConnection;
+    iSipConnection = NULL;
+    
+    TInt err = iProfileRegistry.Disable( *iSipProfile );
+    TRAPD( err1, DisableAlwaysOnModeL() );
+       
+    if ( err == KErrNone )
+        {
+        err = err1;
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::ForceDisable
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::ForceDisable()
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::ForceDisable", this );
+
+    iRegistrationRequestState = EDeregistrationRequested;   
+    CancelEnableTimeoutTimer();
+    
+    delete iSipConnection;
+    iSipConnection = NULL;
+    
+    TInt err = iProfileRegistry.ForceDisable( *iSipProfile );
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::DisableAlwaysOnModeL()
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::DisableAlwaysOnModeL()
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::DisableAlwaysOnModeL", this );
+
+    TBool autoRegistration( EFalse );
+    User::LeaveIfError( iSipProfile->GetParameter( KSIPAutoRegistration, 
+                                                   autoRegistration ) );
+
+    if ( autoRegistration )
+        {
+        CSIPManagedProfile* profile = static_cast<CSIPManagedProfile*> ( iSipProfile );
+        User::LeaveIfError( profile->SetParameter( KSIPAutoRegistration, EFalse ) );
+        iManagedProfileRegistry.SaveL( *profile );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::RegistrationRequestState
+// -----------------------------------------------------------------------------
+//
+CScpSipConnection::TRegistrationRequestState 
+    CScpSipConnection::RegistrationRequestState() const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::RegistrationRequestState", this );
+
+    return iRegistrationRequestState;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::GetState
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::GetState( CScpSipConnection::TConnectionState& aState,
+                                  TInt& aError ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::GetState", this );
+
+    aError = iConnectionStateError;
+
+    TBool registered( EFalse );
+    TInt result = iSipProfile->GetParameter( KSIPProfileRegistered, registered );
+    
+    if ( result == KErrNone )
+        {
+        switch ( iRegistrationRequestState )
+            {
+            case ENoRequest:
+                if( registered )
+                    {
+                    aState = ERegistered;
+                    }
+                else
+                    {
+                    aState = EDeregistered;
+                    }
+                break;
+
+            case ERegistrationRequested:
+                if ( registered )
+                    {
+                    aState = ERegistered;
+                    }
+                else
+                    {
+                    aState = ERegistering;
+                    }
+                break;
+
+            case EDeregistrationRequested:
+                if ( registered )
+                    {
+                    aState = EDeregistering;
+                    }
+                else
+                    {
+                    aState = EDeregistered;
+                    }
+                break;
+
+            default:
+                __ASSERT_DEBUG( EFalse, User::Panic( KNullDesC, KErrGeneral ) );
+                break;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::ProfileRegistryEventOccurred
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::ProfileRegistryEventOccurred( 
+    MSIPProfileRegistryObserver::TEvent aEvent )
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::ProfileRegistryEventOccurred event: %d", 
+                   this, aEvent );
+    
+    TScpConnectionEvent event( EScpUnknown );
+    
+    switch ( aEvent )
+        {
+        case MSIPProfileRegistryObserver::EProfileRegistered:
+            {
+            CancelEnableTimeoutTimer();
+            
+            delete iSipConnection;
+            iSipConnection = NULL;
+            
+            iConnectionStateError = KErrNone;
+            event = EScpRegistered;
+            }
+            break;
+
+        case MSIPProfileRegistryObserver::EProfileDeregistered:
+            {
+            CancelEnableTimeoutTimer();
+                
+            if ( iRegistrationRequestState == EDeregistrationRequested )
+                {
+                iConnectionStateError = KErrNone;
+                event = EScpDeregistered;            
+                }
+            else
+                {
+
+                // SIP will still notify the client with 
+                // MSIPProfileRegistryObserver::ProfileRegistryEventOccurred( EProfileDeregistered ) 
+                // but the reason for this event can be checked by the client
+                // by calling CSIPProfileRegistryBase::LastRegistrationError.
+                // If this function returns KErrDisconnected,
+                // the client can determine that the reason for the event was that the network connection was dropped.
+
+                TInt lastRegistrationError =
+                    iProfileRegistry.LastRegistrationError( *iSipProfile );
+                
+                SCPLOGSTRING2( "    -> last registration error: %d", lastRegistrationError );
+                
+                if (  KErrDisconnected != lastRegistrationError )
+                    {
+                    if ( iProfileCurrentlyRoaming )
+                        {
+                        iProfileCurrentlyRoaming = EFalse;
+                        iConnectionStateError = KCCHErrorNetworkLost;
+                        event = EScpNetworkLost;
+                        }
+                    else
+                        {
+                        iConnectionStateError = KErrNone;
+                        event = EScpDeregistered;
+                        } 
+                    }
+                else
+                    {
+                    iConnectionStateError = KCCHErrorNetworkLost;
+                    event = EScpNetworkLost;
+                    }
+                }
+            }
+            break;
+
+        case MSIPProfileRegistryObserver::EProfileUpdated:
+            {
+            // Should we start EnableTimeoutTimer if registration
+            // was requested?
+            
+            if ( iProfileCurrentlyRoaming )
+                {
+                iProfileCurrentlyRoaming = EFalse;
+                iConnectionStateError = KErrNone;
+                event = EScpRegistered;
+                }
+            }
+            break;
+            
+        default:
+            break;
+        }
+
+    if ( event != EScpUnknown && iObserver )
+        {
+        SCPLOGSTRING3( "id: %d HandleSipConnectionEvent event: %d", 
+                       iProfileId, event );
+
+        iObserver->HandleSipConnectionEvent( iProfileId, event );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::ProfileRegistryErrorOccurred
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::ProfileRegistryErrorOccurred( TInt aError )
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::ProfileRegistryErrorOccurred error: %d", 
+                   this, aError );
+    
+    CancelEnableTimeoutTimer();
+
+    iConnectionStateError = TScpUtility::ConvertToCchError( aError );
+    TScpConnectionEvent event = EScpUnknown;
+    if ( iConnectionStateError == KCCHErrorAuthenticationFailed )
+        {
+        event = EScpAuthenticationFailed;
+        }
+    else if ( iConnectionStateError == KCCHErrorInvalidSettings )
+        {
+        event = EScpInvalidSettings;
+        }
+    else
+        {
+        if ( KErrCancel == aError )
+            {
+            iConnectionStateError = KErrCancel;
+            event = EScpRegistrationCanceled;
+            iRegistrationRequestState = EDeregistrationRequested;
+            }
+        else
+            {
+            iConnectionStateError = KCCHErrorLoginFailed;
+            event = EScpRegistrationFailed;
+            }
+        }    
+    
+    TInt error = KErrNone;
+    CVoipEventLog* eventLog = NULL;
+    
+    TRAP( error, eventLog = CVoipEventLog::NewL() );
+    
+    if ( KErrNone == error )
+        {
+        eventLog->WriteError( aError );
+        }
+    
+    delete eventLog;
+    
+    iObserver->HandleSipConnectionEvent( iProfileId, event );    
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::StartEnableTimeoutTimer
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::StartEnableTimeoutTimer( TInt (*aFunction)(TAny* aPtr) )
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::StartEnableTimeoutTimer", this );
+    __ASSERT_DEBUG( !iEnableTimeoutTimer->IsActive(), 
+                    User::Panic( KNullDesC, KErrGeneral ) );
+
+    if ( !iEnableTimeoutTimer->IsActive() )
+        {
+        iEnableTimeoutTimer->Start( KEnableTimeout, 
+                              0, 
+                              TCallBack( aFunction, this ) );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::CancelEnableTimeoutTimer
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::CancelEnableTimeoutTimer()
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::CancelEnableTimeoutTimer", this );
+
+    if ( iEnableTimeoutTimer->IsActive() )
+        {
+        iEnableTimeoutTimer->Cancel();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::EnableTimeout
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::EnableTimeout( TAny* aSelf )
+    {
+    SCPLOGSTRING( "CScpSipConnection::EnableTimeout" );
+
+    CScpSipConnection* self = static_cast<CScpSipConnection*>( aSelf );
+    
+    self->HandleEnableTimeout();
+
+    return 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::HandleEnableTimeout
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::HandleEnableTimeout()
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::HandleEnableTimeout",
+                   this );
+    ProfileRegistryErrorOccurred( EScpRegistrationFailed );
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::GetIap
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::GetIap( TUint32& aIapId ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::GetIap", this );
+    
+    return iSipProfile->GetParameter( KSIPAccessPointId, aIapId ); 
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::GetSnap
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::GetSnap( TUint32& aSnapId ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::GetSnap", this );
+
+    return iSipProfile->GetParameter( KSIPSnapId, aSnapId );          
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::GetUsername
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::GetUsername( TDes8& aUsername ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::GetUsername", this );
+
+    TInt result( KErrNotFound );
+    
+    // Check if profile is registered
+    TBool val( EFalse );
+    result = iSipProfile->GetParameter( KSIPProfileRegistered, val );
+    
+    const TDesC8* aor( NULL );
+
+    // Get SIP's Username    
+    result = iSipProfile->GetParameter( KSIPUserAor, aor );
+    
+    if ( result == KErrNone && aor->Length() > KErrNone  )
+        {
+        if ( aor->Length() <= aUsername.MaxLength() )
+            {
+            SCPLOGSTRING( "CScpSipConnection::GetUsername - Got username from AOR" );
+            aUsername.Copy( *aor );
+            }
+        else
+            {
+            SCPLOGSTRING( "CScpSipConnection::GetUsername - KErrOverflow" );
+            result = KErrOverflow;
+            }
+        }
+    else if ( val ) // registered
+        {
+        // Might be IMS case and UserAor is incomplete, then
+        // Get SIP's Username from registered AORs
+        const MDesC8Array* aors = 0;
+        result =  iSipProfile->GetParameter( KSIPRegisteredAors, aors );
+        if ( !aors || aors->MdcaCount() == 0 )
+            {
+            SCPLOGSTRING( "CScpSipConnection::GetUsername - KErrNotReady" );
+            result = KErrNotReady;
+            }
+        else
+            {            
+            TBuf8<KUsernameMaxLength> tmpUserName;
+            tmpUserName.Copy( aors->MdcaPoint( 0 ) );
+            
+            #ifdef _DEBUG
+                TBuf<KUsernameMaxLength> tmpUri;
+                tmpUri.Copy( aors->MdcaPoint( 0 ) );
+                SCPLOGSTRING2( "CScpSipConnection::GetUsername - use first registered AOR: %S", &tmpUri );
+            #endif
+                
+            TInt atPos = tmpUserName.Find( KSCPAt8 );
+            aUsername.Copy( tmpUserName.Left( atPos ) );
+            }
+        }
+    SCPLOGSTRING2( "CScpSipConnection::GetUsername - return error: %d", result );
+    return result;                
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::GetDomain
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::GetDomain( TDes8& aDomain ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::GetDomain", this );
+
+    TInt result( KErrNotFound );
+    const TDesC8* domain( NULL );
+
+    // Get SIP's Username    
+    result = iSipProfile->GetParameter( KSIPRegistrar, KSIPServerAddress, domain );
+    
+    if ( result == KErrNone && domain )
+        {
+        if ( domain->Length() <= aDomain.MaxLength() )
+            {
+            aDomain.Copy( *domain );
+            }
+        else
+            {
+            result = KErrOverflow;
+            }
+        }
+
+    return result;                
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::GetContactHeaderUser
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::GetContactHeaderUser( RBuf8& aContactHeaderUser ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::GetContactHeader", this );
+
+    TInt result( KErrNotFound );
+    const TDesC8* contactHeaderUser( NULL );
+
+    // Get SIP's Username    
+    result = iSipProfile->GetParameter( KSIPContactHeaderUser, contactHeaderUser );
+    
+    if ( result == KErrNone && contactHeaderUser )
+        {
+        result = aContactHeaderUser.ReAlloc( contactHeaderUser->Length() );
+        if ( KErrNone == result )
+            {
+            aContactHeaderUser.Copy( *contactHeaderUser );
+            }
+        }
+
+    return result;                
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::SipProfile
+// -----------------------------------------------------------------------------
+//
+CSIPProfile& CScpSipConnection::SipProfile() const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::SipProfile", this );
+    
+    return *iSipProfile;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::SetIap
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::SetIap( TUint32 aProfileIapId )
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::SetIap iap: %d",
+                   this, aProfileIapId );
+
+    TInt result( KErrNone );
+
+    // If snap exists, iap doesn't have an effect
+    TUint32 snapId( 0 );
+    result = GetSnap( snapId );
+
+    if ( result == KErrNotFound ||
+        snapId == 0 )
+        {
+        // Managed profile so we can change it
+        CSIPManagedProfile* profile = static_cast<CSIPManagedProfile*> ( iSipProfile );
+        
+        // Add new IAP Id to SIP Profile
+        result = profile->SetParameter( KSIPAccessPointId, aProfileIapId );
+        if ( KErrNone == result )
+            {
+            // Save changes
+            TRAP( result, iManagedProfileRegistry.SaveL( *profile ) );
+            }
+        }
+    else
+        {
+        result = KErrNotSupported;
+        }
+
+    return result; 
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::SetIap
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::SetSnap( TUint32 aProfileSnapId )
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::SetSnap snap: %d", 
+                   this, aProfileSnapId );
+        
+    // Managed profile so we can change it
+    CSIPManagedProfile* profile = static_cast<CSIPManagedProfile*> ( iSipProfile );
+    
+    // Add new SNAP Id to SIP Profile
+    TInt result = profile->SetParameter( KSIPSnapId, 
+                                         aProfileSnapId );
+
+    if ( KErrNone == result )
+        {
+        // Save changes
+        TRAP( result, iManagedProfileRegistry.SaveL( *profile ) );
+        }
+
+    return result; 
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::GetIapTypeL
+// -----------------------------------------------------------------------------
+//
+TScpIapType CScpSipConnection::GetIapTypeL() const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::GetIapTypeL", this );
+    
+    TScpIapType type = EScpUnknownType;
+
+    CCommsDatabase* commsDb = CCommsDatabase::NewL( EDatabaseTypeIAP );
+    CleanupStack::PushL( commsDb );
+
+    CCommsDbTableView* iapTable = commsDb->OpenTableLC( TPtrC( IAP ) );
+
+    if ( iapTable->GotoFirstRecord() == KErrNone )
+        { 
+        TUint32 profilesIap = 0;
+        User::LeaveIfError( GetIap( profilesIap ) );
+
+        do 
+            {
+            TUint32 uid = 0;
+            iapTable->ReadUintL( TPtrC( COMMDB_ID ), uid );
+
+            if ( uid == profilesIap )
+                {
+                // The length should be defined somewhere
+                TBuf<256> serviceType;
+                iapTable->ReadTextL( TPtrC( IAP_SERVICE_TYPE ), serviceType );
+
+                if ( serviceType == TPtrC( INCOMING_GPRS ) ||
+                    serviceType == TPtrC( OUTGOING_GPRS ) ||
+                    serviceType == TPtrC( INCOMING_WCDMA) ||
+                    serviceType == TPtrC( OUTGOING_WCDMA) )
+                    {
+                    type = EScpGprs;
+                    }
+                else if ( serviceType == TPtrC( LAN_SERVICE ) )
+                    {
+                    type = EScpWlan;
+                    }
+                else
+                    {
+                    type = EScpUnknownType;
+                    }
+
+                break;
+                }
+
+            }
+        while( iapTable->GotoNextRecord() == KErrNone );
+    }
+
+    CleanupStack::PopAndDestroy( iapTable );
+    CleanupStack::PopAndDestroy( commsDb );    
+
+    SCPLOGSTRING2( "GetIapTypeL result: %d", type );
+
+    return type;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::SetReserved
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::SetReserved( TBool aReserved )
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::SetReserved: %d", this, aReserved );
+    
+    iReserved = aReserved;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::Reserved
+// -----------------------------------------------------------------------------
+//
+TBool CScpSipConnection::Reserved() const
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::Reserved: %d", this, iReserved );
+
+    return iReserved;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::SetIapAvailableOffered
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::SetIapAvailableOffered( TBool aIapAvailableOffered )   
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::SetIapAvailableOffered: %d", 
+    this, aIapAvailableOffered );
+    
+    iIapAvailableOffered = aIapAvailableOffered;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::IapAvailableOffered
+// -----------------------------------------------------------------------------
+//
+TBool CScpSipConnection::IapAvailableOffered() const
+    {
+    SCPLOGSTRING3( "CScpSipConnection[0x%x]::IapAvaiableOffered: %d", 
+    this, iIapAvailableOffered );
+    
+    return iIapAvailableOffered;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::IapAvailableOffered
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::SetProfileCurrentlyRoaming()
+    {
+    SCPLOGSTRING( "CScpSipConnection[0x%x]::SetProfileCurrentlyRoaming" );
+    
+    iProfileCurrentlyRoaming = ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::IsPasswordSet
+// -----------------------------------------------------------------------------
+//
+TBool CScpSipConnection::IsPasswordSet() const
+    {
+    SCPLOGSTRING( "CScpSipConnection::IsPasswordSet" );
+
+    // no support exist in sip for getting is password set information */
+    SCPLOGSTRING( "CScpSipConnection::IsPasswordSet: pwd is set is always returned" );
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::IsUsernameSetL
+// -----------------------------------------------------------------------------
+//
+TBool CScpSipConnection::IsUsernameSetL() const
+    {
+    SCPLOGSTRING( "CScpSipConnection::IsUsernameSetL" );
+ 
+    TBool userNameSet( EFalse );
+    
+    // check from aor
+    RBuf8 username;
+    CleanupClosePushL( username );
+    username.CreateL( KUsernameMaxLength );
+    
+    TInt err = GetUsername( username );
+
+    if ( !err && username.Length() )
+        {
+        RBuf8 formattedUsername;
+        TScpUtility::RemovePrefixAndDomain( username, formattedUsername );
+        
+        if ( formattedUsername.Length() )
+            {
+            userNameSet = ETrue;
+            }   
+        
+        formattedUsername.Zero();
+        formattedUsername.Close();
+        }
+    else if ( KErrNone == err && SipProfileIMS() )
+        {
+        SCPLOGSTRING( "CScpSipConnection::IsUsernameSetL - SipProfileIMS" );
+        // Check if this is IMS case; then we can think username is set
+        // (SIP stack takes care of SIM handling)
+        userNameSet = ETrue;
+        }
+    
+    else
+        {
+        SCPLOGSTRING( "CScpSipConnection::IsUsernameSetL - ELSE!" );
+        }
+        
+    CleanupStack::PopAndDestroy( &username );
+    
+    return userNameSet;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::SipProfileIMS
+// -----------------------------------------------------------------------------
+//
+TBool CScpSipConnection::SipProfileIMS() const
+    {
+    SCPLOGSTRING( "CScpSipConnection::SipProfileIMS" );
+    if( TSIPProfileTypeInfo::EIms == iSipProfile->Type().iSIPProfileClass )
+        {
+        SCPLOGSTRING( "CScpSipConnection::SipProfileIMS - ETrue" );
+        return ETrue;
+        }
+    else
+        {
+        SCPLOGSTRING( "CScpSipConnection::SipProfileIMS - EFalse" );
+        return EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::HandleMigrationStarted
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::HandleMigrationStarted()
+    {
+    if( iObserver )
+        {
+        SCPLOGSTRING2( "    -> roaming - id: %d", iProfileId );
+
+        iObserver->HandleSipConnectionEvent( iProfileId, EScpRoaming );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::HandleMigrationError
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::HandleMigrationError(
+    TInt /*aError*/,
+    TUint32 /*aProfileId*/,
+    TUint32 /*aSnapId*/,
+    TUint32 /*aIapId*/ )
+    {
+    // Migration has failed -> check is sip still registered via old iap 
+    // and if is, set state back to registered
+    
+    TScpConnectionEvent event( EScpUnknown );
+    
+    if ( iProfileCurrentlyRoaming && iObserver )
+        {
+        iProfileCurrentlyRoaming = EFalse;
+        iConnectionStateError = KErrNone;
+        event = EScpRegistered;
+        SCPLOGSTRING3( "id: %d HandleSipConnectionEvent event: %d", 
+                       iProfileId, event );
+        iObserver->HandleSipConnectionEvent( iProfileId, event );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::IsNetworkConnectionAvailable
+// -----------------------------------------------------------------------------
+//
+TBool CScpSipConnection::IsNetworkConnectionAvailable() const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::IsNetworkConnectionAvailable", this );
+
+    TBool isAvailable = EFalse;
+
+    TUint32 snapId = 0;
+    TInt result = GetSnap( snapId );
+
+    if ( result == KErrNone ||
+        result == KErrNotFound )
+        {
+        if ( snapId != 0 )
+            {
+            isAvailable = IsSnapConnectionAvailable( snapId );
+            }   
+        else
+            {
+            TUint32 iapId = 0;
+            result = GetIap( iapId );
+
+            if( result == KErrNone )
+                {
+                isAvailable = IsIapConnectionAvailable( iapId );
+                }
+            }
+        }
+    
+    return isAvailable;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::IsSnapConnectionAvailable
+// -----------------------------------------------------------------------------
+//
+TBool CScpSipConnection::IsSnapConnectionAvailable( TInt aSnapId ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::IsSnapConnectionAvailable", this );
+
+    TBool isAvailable = EFalse;
+
+    TConnMonSNAPInfoBuf snapInfoBuf;
+    TRequestStatus status;
+    iConnectionMonitor.GetPckgAttribute( EBearerIdAll, 0, KSNAPsAvailability,
+                                         snapInfoBuf, status );
+
+    User::WaitForRequest( status );
+
+    for ( TInt i = 0; i < snapInfoBuf().Count(); i++ )
+        {
+        if ( aSnapId == snapInfoBuf().iSNAP[ i ].iSNAPId )
+            {
+            SCPLOGSTRING( "SNAP IS STILL ALIVE!!!" );
+            isAvailable = ETrue;
+            break;
+            } 
+        }
+
+    return isAvailable;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::IsIapConnectionAvailable
+// -----------------------------------------------------------------------------
+//
+TBool CScpSipConnection::IsIapConnectionAvailable( TInt aIapId ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::IsIapConnectionAvailable", this );
+
+    TBool isAvailable = EFalse;
+
+    TConnMonIapInfoBuf iapInfoBuf;
+    TRequestStatus status;
+    iConnectionMonitor.GetPckgAttribute( EBearerIdAll, 0, KIapAvailability,
+                                         iapInfoBuf, status );
+
+    User::WaitForRequest( status );
+
+    for ( TInt i = 0; i < iapInfoBuf().Count(); i++ )
+        {
+        if  ( aIapId == iapInfoBuf().iIap[ i ].iIapId )
+            {
+            SCPLOGSTRING( "IAP IS STILL ALIVE!!!" );
+            isAvailable = ETrue;
+            break;
+            } 
+        }
+
+    return isAvailable;
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::BearerFiltteringSetting
+// -----------------------------------------------------------------------------
+//
+TInt CScpSipConnection::BearerFiltteringSetting(
+    TUint32& aBearerFilttering ) const
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::BearerFiltteringSetting - IN", this );
+    return iSipProfile->GetParameter( KBearerType, aBearerFilttering );
+    }
+
+// -----------------------------------------------------------------------------
+// CScpSipConnection::ConnectionStateChanged
+// -----------------------------------------------------------------------------
+//
+void CScpSipConnection::ConnectionStateChanged( CSIPConnection::TState aState )
+    {
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::ConnectionStateChanged - IN", this );
+    
+    switch ( aState )
+            {
+            case CSIPConnection::EInactive:
+                {
+                SCPLOGSTRING2( "CScpSipConnection[0x%x]::ConnectionStateChanged: EInactive", this );
+                
+                TUint32 iapId( 0 );
+                TInt result = GetIap( iapId );
+                    
+                if ( KErrNone == result && iSipConnection &&
+                        iapId == iSipConnection->IapId() &&
+                        KErrNone == iConnectionStateError )
+                    {
+                    delete iSipConnection;
+                    iSipConnection = NULL;
+                    
+                    iConnectionStateError = KCCHErrorLoginFailed;
+                    iObserver->HandleSipConnectionEvent( iProfileId, EScpRegistrationFailed );
+                    }
+                }
+                break;
+                
+            default:
+                {
+                SCPLOGSTRING2( "CScpSipConnection[0x%x]::ConnectionStateChanged: default", this );
+                }
+                break;
+            }
+    SCPLOGSTRING2( "CScpSipConnection[0x%x]::ConnectionStateChanged - OUT", this );
+    }
+
+//  End of File