voipplugins/sipconnectionprovider/src/scppresencehandler.cpp
branchRCL_3
changeset 21 f742655b05bf
parent 20 65a3ef1d5bd0
child 22 d38647835c2e
--- a/voipplugins/sipconnectionprovider/src/scppresencehandler.cpp	Thu Aug 19 09:45:22 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1124 +0,0 @@
-/*
-* Copyright (c) 2002-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:  Presence handler.
-*
-*/
-#include <ximperrors.hrh>
-#include <ximpcontext.h>
-#include <presenceinfo.h> //MximpPresenceInfo
-#include <presenceinfofilter.h> //info filtter
-#include <presenceinfofield.h> //MximpPresenceInfoField
-#include <ximpobjectfactory.h>
-#include <presenceobjectfactory.h>
-#include <servicepresenceinfo.h> //MximpServicePresenceInfo
-#include <presenceinfofieldvalueenum.h> //MximpPresenceInfoFieldValueEnum
-#include <presenceinfofieldcollection.h> //MximpPresenceInfoFieldCollection
-#include <presenceinfofieldvaluetext.h> //MximpPresenceInfoFieldValueText
-#include <personpresenceinfo.h> // MximpPersonPresenceInfo
-#include <presencepublishing.h>//MPresencePublishing
-#include <ximpfeatureinfo.h>
-#include <presencefeatures.h>
-#include <ximpidentity.h> //for MXIMPIdentity
-#include <presentitygroups.h>
-
-#include <ximprequestcompleteevent.h>
-#include <ximpcontextstateevent.h>
-#include <ownpresenceevent.h>
-#include <ximpclient.h>
-#include <ximpcontext.h>
-#include <ximpstatus.h>
-#include <pressettingsapi.h> //presence settings
-#include <XdmSettingsApi.h>
-#include <cvimpstsettingsstore.h>
-
-#include "scppresencehandler.h"
-#include "scpsubservice.h"
-#include "scpservicestorage.h"
-#include "scplogger.h"
-#include "scputility.h"
-#include "scpservice.h"
-#include "scpprofilehandler.h"
-#include "scpsettinghandler.h"
-#include "scppresencehandlerrequest.h"
-
-const TInt KXdmDmMaxIntLength      = 10;   // max length of 32bit integer
-const TInt KMaxPresenceEnableCount = 5;
-const TInt KCustomMessageMaxLength = 75;
-const TInt KBufSize255 = 255;
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::NewL
-// -----------------------------------------------------------------------------
-//
-CScpPresenceHandler* CScpPresenceHandler::NewL( CScpSubService& aSubService )
-    {
-    SCPLOGSTRING( "CScpPresenceHandler::NewL" );
-    CScpPresenceHandler* self = new ( ELeave ) CScpPresenceHandler( aSubService );
-    CleanupStack::PushL( self );    
-    self->ConstructL();    
-    CleanupStack::Pop( self );
-    return self;
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::CCScpPresenceHandler
-// -----------------------------------------------------------------------------
-//
-CScpPresenceHandler::CScpPresenceHandler( CScpSubService& aSubService ) :
-    CScpServiceHandlerBase( aSubService ),
-    iPresenceState( ENoBind ),
-    iDisableAfterXimpRequestsCompleted( EFalse ),
-    iNetworkLostRoamingOngoing( EFalse )
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::CScpPresenceHandler", this );
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::ConstructL
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::ConstructL()
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::ConstructL", this );
-
-    BaseConstructL();
-    GetPresencePropertyIdL( ESubPropertyPresenceSettingsId, iPresenceSettingsId );
-    
-    iPresClient = MXIMPClient::NewClientL();
-    SCPLOGSTRING2( "CScpPresenceHandler::ConstructL, iPresClient [0x%x]", iPresClient );
-
-    if ( iPresClient )
-        {
-        // Set presence handler as observer of Voip subservice
-        CScpSubService* voipSubService = GetVoipSubService();
-        if ( voipSubService )
-            {
-            voipSubService->SetSubServiceObserver( this );
-            }
-        
-        MXIMPContext* tmp = iPresClient->NewPresenceContextLC();        
-        iFeature = MPresenceFeatures::NewL( tmp );
-        
-        RArray<TInt32> eventFilter;   
-        CleanupClosePushL( eventFilter );
-
-        eventFilter.Append( XIMP_IF_ID_REQUEST_COMPLETE_EVENT );     
-        eventFilter.Append( XIMP_IF_ID_CONTEXT_STATE_EVENT );
-        
-        TArray<TInt32> eventFilterArray = eventFilter.Array();
-        tmp->RegisterObserverL( *this, &eventFilterArray );
-        
-        CleanupStack::PopAndDestroy( &eventFilter );
-
-        CleanupStack::Pop(); // tmp
-        iPresenceCtx = tmp;
-        tmp = NULL; 
-        }
-    else
-        {
-        User::Leave( KErrGeneral );
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::~CScpPresenceHandler
-// -----------------------------------------------------------------------------
-//
-CScpPresenceHandler::~CScpPresenceHandler()
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::~CScpPresenceHandler", this );
-
-    CancelDisableTimer();
-    
-    iReqIdArray.Close();
-    
-    delete iFeature;
-    delete iPresenceCtx;
-    
-    // Set observer of Voip subservice to NULL
-    CScpSubService* voipSubService = GetVoipSubService();
-    if ( voipSubService )
-        {
-        voipSubService->SetSubServiceObserver( NULL );
-        }
-    
-    delete iPresClient;
-    }
-
-
-// ====================== From CScpServiceHandlerBase ==========================
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::EnableSubServiceL
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::EnableSubServiceL()
-    {
-    SCPLOGSTRING4( "CScpPresenceHandler[0x%x]::EnableSubServiceL: 0x%x type: %i", 
-                   this, &iSubService, iSubService.SubServiceType() );
-       
-    __ASSERT_DEBUG( iSubService.SubServiceType() == ECCHPresenceSub,
-                    User::Panic( KNullDesC, KErrGeneral ) );     
-
-    CScpServiceHandlerBase::RegisterProfileL();
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::DisableSubService
-// -----------------------------------------------------------------------------
-//
-TInt CScpPresenceHandler::DisableSubService()
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::DisableSubService", this );
-    __ASSERT_DEBUG( iSubService.SubServiceType() == ECCHPresenceSub,
-                    User::Panic( KNullDesC, KErrGeneral ) );  
-
-    TInt result = KErrNone;
-    // Publish offline and unbind presence context
-    TRAP( result, HandleDeregistrationL( ETrue ) );
-    
-    if ( KErrNone == result  )
-        {
-        // Deregister if still connecting
-        if ( iSubService.State() == ECCHConnecting )
-            {
-            DeregisterNow();            
-            }
-        else
-            {
-            StartForcedDisableTimer( CScpPresenceHandler::ForcePresenceServiceDisable );
-            }
-        }
-    else
-        {
-        
-        // Wait for XIMP request to be completed and handle 
-        // de-registration after that or after force disable timer expires
-        if ( iReqIdArray.Count() )
-            {
-            iDisableAfterXimpRequestsCompleted = ETrue;
-            StartForcedDisableTimer( CScpPresenceHandler::ForcePresenceServiceDisable );
-            }
-        else
-            {
-            DeregisterNow();
-            }
-        }
-
-    return result;
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::SubServiceType
-// -----------------------------------------------------------------------------
-//
-TCCHSubserviceType CScpPresenceHandler::SubServiceType() const
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::SubServiceType", this );
-    return ECCHPresenceSub;
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::HandleSipConnectionEvent
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::HandleSipConnectionEvent( const TUint32 aProfileId,
-                                                    TScpConnectionEvent aEvent )
-    {
-    SCPLOGSTRING4( "CScpPresenceHandler[0x%x]::HandleSipConnectionEvent id: %d event: %d",
-                   this, aProfileId, aEvent );
-    
-    iNetworkLostRoamingOngoing = EFalse;
-    
-    if ( iSubService.SipProfileId() == aProfileId &&
-        iSubService.EnableRequestedState() != CScpSubService::EScpNoRequest )
-        {
-        if ( EScpDeregistered == aEvent && 
-             iSubService.EnableRequestedState() == CScpSubService::EScpEnabled )
-            {
-            SCPLOGSTRING( "CScpPresenceHandler - EScpDeregistered -> unbind" );
-            TRAPD( err, HandleDeregistrationL( EFalse ) ); 
-            if ( KErrNotReady == err )
-                {
-                SCPLOGSTRING( "CScpPresenceHandler - EScpDeregistered -> not ready: unbind" );
-                TRAP_IGNORE( ServerUnBindL() );
-                }
-            }
-        //if network lost, unbind context
-        if ( EScpNetworkLost == aEvent )
-            {
-            SCPLOGSTRING( "CScpPresenceHandler - EScpNetworkLost -> unbind" );
-            TRAPD( err, HandleDeregistrationL( EFalse ) );
-            
-            if ( KErrNotReady == err )
-                {
-                SCPLOGSTRING( "CScpPresenceHandler - EScpNetworkLost -> not ready: unbind" );
-                TRAP_IGNORE( ServerUnBindL() );
-                }
-            
-            TUint32 snapId;
-            CScpProfileHandler& profileHandler = iSubService.ProfileHandler();
-            CScpSipConnection* sipConnection = profileHandler.GetSipConnection( iSubService.SipProfileId() );
-            
-            if ( sipConnection )
-                {
-                TInt error = sipConnection->GetSnap( snapId );
-                
-                if ( !error && sipConnection->IsSnapConnectionAvailable( snapId ) )
-                    {
-                    iNetworkLostRoamingOngoing = ETrue;
-                    }
-                }
-            }
-        
-        if ( EScpRoaming == aEvent )
-            {
-            SCPLOGSTRING( "CScpPresenceHandler - EScpRoaming -> unbind" );
-            TRAP_IGNORE( ServerUnBindL() );
-            }
-        
-        //if registered, time to bind context
-        if ( EScpRegistered == aEvent &&
-             CScpSubService::EScpEnabled == iSubService.EnableRequestedState() )
-            {
-            SCPLOGSTRING( "CScpPresenceHandler - EScpRegistered -> update iap and bind" );
-            // update xmd settings 
-            TRAPD( err, UpdateXdmSettingsL() );
-            
-            if ( KErrNone == err )
-                {
-                // Subscribe
-                TRAP( err, ServerBindL() );
-                iRebind = EFalse;
-                
-                if( KErrNone == err )
-                    {
-                    // Still connecting the service
-                    aEvent = EScpNetworkFound;    
-                    }
-                else
-                    {
-                    SCPLOGSTRING2( "ServerBindL failed: %d", err );
-                    aEvent = EScpRegistrationPending;
-                    if ( KErrAlreadyExists == err )
-                        {
-                        // Ximp does not set request to queue, so we have to do rebind later
-                        SCPLOGSTRING( "CScpPresenceHandler - rebind later" ); 
-                        iRebind = ETrue;
-                        }
-                    }
-                }
-            else
-                {
-                SCPLOGSTRING2( "UpdateXdmSettingsL: %d", err );
-                aEvent = EScpRegistrationFailed;
-                }
-            }
-        else if ( EScpDeregistered == aEvent &&
-                 iSubService.EnableRequestedState() == CScpSubService::EScpDisabled ||
-                 iSubService.EnableRequestedState() == CScpSubService::EScpRefreshed )
-            {
-            if ( EScpRegistered != aEvent && ECCHDisconnecting != iSubService.State() )
-                {
-                CancelDisableTimer();
-                }
-            
-            // If this flag is still true, it could be that presence server
-            // has not given answer -> ximp requests cannot be completed.
-            // But still have to unbind from ximp context
-            if ( iDisableAfterXimpRequestsCompleted )
-                {
-                TRAP_IGNORE( ServerUnBindL() );
-                }
-            
-            // When SIP is deregistered, change presence state to no bind
-            iPresenceState = ENoBind;
-            }
-        iSubService.HandleConnectionEvent( aEvent );
-        }
-    SCPLOGSTRING( "CScpPresenceHandler::HandleSipConnectionEvent OUT" );
-    }    
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::HandleSipConnectionEvent
-// -----------------------------------------------------------------------------
-//
-TBool CScpPresenceHandler::IsSipProfileAllowedToStartAlr()
-    {
-    return EFalse;
-    }
-
-// ======================= From MXIMPContextObserver ===========================
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::HandlePresenceContextEvent
-// -----------------------------------------------------------------------------
-//   
-void CScpPresenceHandler::HandlePresenceContextEvent(
-    const MXIMPContext& /*aContext*/,
-    const MXIMPBase& aEvent )
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::HandlePresenceContextEvent", this );
-
-    const TInt32 eventType = aEvent.GetInterfaceId();
-    
-    switch ( eventType )
-        {
-        case MXIMPContextStateEvent::KInterfaceId:
-            {
-            HandleContextStateEvent( aEvent );
-            break;
-            }
-
-        case MXIMPRequestCompleteEvent::KInterfaceId:
-            {
-            HandleRequestCompleteEvent( aEvent );
-            break;
-            }
-              
-        default:
-            {
-            break;
-            }
-        }
-    SCPLOGSTRING( "CScpPresenceHandler::HandlePresenceContextEvent end" ); 
-    }
-
-
-
-// ===================== From MScpSubServiceObserver ===========================
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::HandleSubServiceChange
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::HandleSubServiceChange( TCCHSubserviceState aState, TInt aError )
-    {
-    SCPLOGSTRING4( "CScpPresenceHandler::HandleSubServiceChange presence subservice state: %d, aState: %d, aError: %d", 
-                    iSubService.State(), aState, aError );
-                    
-    if ( iSubService.State() == ECCHEnabled && ( aError == KCCHErrorBandwidthInsufficient || aError == KErrNone ) )
-        {
-        if( aState == ECCHEnabled && aError == KErrNone )
-            {
-            if ( EPresenceOffline == iPresenceState )
-                {
-                SCPLOGSTRING( "CScpPresenceHandler::HandleSubServiceChange PublishOnline" );
-                TRAP_IGNORE( PublishPresenceL( ETrue ) );
-                }
-            }
-        else
-            {
-            if ( EPresenceOnline == iPresenceState && aState != ECCHConnecting )
-                {
-                SCPLOGSTRING( "CScpPresenceHandler::HandleSubServiceChange PublishOffline" );
-                // Unsubscribe from the list first
-                TRAP_IGNORE( UnsubscribePresentityGroupL() );
-                TRAP_IGNORE( PublishPresenceL( EFalse ) );
-                }
-            }
-        }
-    }
- 
-// ========================= Other member funcions =============================
-
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::GetVoipSubService
-// -----------------------------------------------------------------------------
-//
-CScpSubService* CScpPresenceHandler::GetVoipSubService()
-    {
-    CScpSubService* voipSubService = NULL;
-    CScpServiceStorage& serviceStorage = iSubService.ServiceStorage();
-    CScpService* service = serviceStorage.GetServiceByServiceId( iSubService.SubServiceId() );
-
-    if ( service )
-        {
-        voipSubService = service->GetSubServiceByType( ECCHVoIPSub );
-        }
-    
-    return voipSubService;
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::DeregisterNow
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::DeregisterNow()
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::DeregisterNow",
-                   this );
-    
-    CancelDisableTimer();
-  
-    iReqIdArray.Reset();
-    iPresenceState = ENoBind;
-
-    // Check if disable was not requested
-    if ( iSubService.EnableRequestedState() == CScpSubService::EScpEnabled )
-        {
-        // Check the last ximp error
-        if ( KErrNoMemory == iLastXimpError && 
-            KMaxPresenceEnableCount < iSubService.EnableCounter() )
-            {
-            // No memory means 401 Unauthorized, we are trying to enable  
-            // KMaxPresenceEnableCount times -> no more, this is truly
-            // autentication failed.
-            iSubService.HandleConnectionEvent( EScpAuthenticationFailed );
-            }
-        else
-            {
-            iSubService.HandleConnectionEvent( EScpDeregistered );
-            }
-        }
-    else
-        {
-        DeregisterProfile();
-        }
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::ForcePresenceServiceDisable
-// -----------------------------------------------------------------------------
-//
-TInt CScpPresenceHandler::ForcePresenceServiceDisable( TAny* aSelf )
-    {
-    SCPLOGSTRING( "CScpPresenceHandler::ForcePresenceServiceDisable" );
-
-    CScpPresenceHandler* self = static_cast<CScpPresenceHandler*>( aSelf );
-
-    self->DeregisterNow();
-
-    return 1;
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::UpdateXdmSettingsL
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::UpdateXdmSettingsL()
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::UpdateXdmSettingsL", this );
-    
-    // Get IAP id of sip profile
-    CScpProfileHandler& profileHandler = iSubService.ProfileHandler();
-    CScpSipConnection* sipConnection = profileHandler.GetSipConnection( iSubService.SipProfileId() );
-    if ( !sipConnection )
-        {
-        User::Leave( KErrNotFound );
-        }
-    
-    TUint32 apId = 0;
-    User::LeaveIfError( sipConnection->GetIap( apId ) );
-    
-    SCPLOGSTRING2( "CScpPresenceHandler::UpdateXdmSettingsL apId is %d", apId );
-    
-    TPresSettingsSet mySet;
-    User::LeaveIfError( PresSettingsApi::SettingsSetL( iPresenceSettingsId, mySet ));
-        
-    // set iap id to xdm settings
-    HBufC* idBuf = HBufC::NewLC( KXdmDmMaxIntLength );
-    TPtr ptrBuf = idBuf->Des();
-    ptrBuf.AppendNum( apId );
-        
-    TXdmSettingsApi::UpdatePropertyL( mySet.iXDMSetting, *idBuf, EXdmPropToNapId );
-    CleanupStack::PopAndDestroy( idBuf );
-
-    SCPLOGSTRING( "CScpPresenceHandler::UpdateXdmSettingsL status online end" );
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::GetPresencePropertyIdL
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::GetPresencePropertyIdL( TServicePropertyName aProperty,
-                                                    TInt& aValue ) const
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::GetPresenceSettingsId", this );
-    
-    CScpServiceStorage& serviceStorage = iSubService.ServiceStorage();
-    CScpSettingHandler& settingHandler = serviceStorage.SettingsHandler();
-    
-    settingHandler.GetSPSettingsIntPropertyL( iSubService.SubServiceId(),
-        aProperty, 
-        aValue );
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::PublishPresenceL
-// Publishes presence according to given parameter.
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::PublishPresenceL( TBool aPublishOnline )
-    {
-    SCPLOGSTRING3( "CScpPresenceHandler[0x%x]::PublishPresenceL, aPublishOnline = %d",
-        this, aPublishOnline );
-
-    // Get the management interface
-    MPresencePublishing* presPub = &( iFeature->PresencePublishing() );
-    // publish own presence in here
-    MPresenceInfo* info = CreateInfoLC( aPublishOnline );
-    TScpReqId reqId;
-    
-    if ( aPublishOnline )
-        {
-        reqId.SetType( EPublishOnlineReq );
-        iPresenceState = EPublishing;
-        }
-    else
-        {
-        reqId.SetType( EPublishOfflineReq );
-        iPresenceState = EPresenceOffline;
-        }
-        
-    reqId.SetId( presPub->PublishOwnPresenceL( *info ) ); 
-    iReqIdArray.Append( reqId );
-    
-    CleanupStack::PopAndDestroy( 1 );
-    
-    SCPLOGSTRING( "CScpPresenceHandler::PublishPresenceL end" ); 
-    }
-
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::ServerBindL
-// Binds the presence context
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::ServerBindL()
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::ServerBindL", this );
-    SCPLOGSTRING2( "CScpPresenceHandler::ServerBindL -> bind service: %d", 
-        iSubService.SubServiceId() );
-    
-    //Bind context to desired presence service
-    TInt propertyId = 0;
-    GetPresencePropertyIdL( EPropertyPCSPluginId, propertyId );
-    TUid protocolUid = TUid::Uid( propertyId );
-    
-    TScpReqId reqId;
-    reqId.SetType( EBindReq );
-    reqId.SetId( iPresenceCtx->BindToL( protocolUid, iSubService.SubServiceId() ) );
-    iReqIdArray.Append( reqId );
-    iPresenceState = EBinding;
-    SCPLOGSTRING( "CScpPresenceHandler::ServerBindL end" );
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::ServerUnBindL
-// Unbinds the presence context
-// -----------------------------------------------------------------------------
-//
-void  CScpPresenceHandler::ServerUnBindL()
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::ServerUnBindL", this );
-    TScpReqId reqId;
-    reqId.SetType( EUnBindReq );
-    reqId.SetId( iPresenceCtx->UnbindL() );
-    iReqIdArray.Append( reqId ); 
-    iPresenceState = EUnBinding;
-    SCPLOGSTRING( "CScpPresenceHandler::ServerUnBindL end" );
-    }
-    
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::HandleDeregistrationL
-// Handles the deregistration of presence.
-// -----------------------------------------------------------------------------
-//    
-void CScpPresenceHandler::HandleDeregistrationL( TBool aDoStopPublish )
-    {
-     SCPLOGSTRING4( "CScpPresenceHandler[0x%x]::HandleDeregistrationL, aDoStopPublish: %d, iPresenceState: %d",
-             this, aDoStopPublish, iPresenceState );
-
-    if ( EPresenceOnline == iPresenceState 
-        && aDoStopPublish && 
-        iSubService.LastReportedError() == KErrNone )
-        {
-        // Get the management interface
-        MPresencePublishing* presPub = &( iFeature->PresencePublishing() );
-        // publish own presence in here
-        MPresenceInfo* info = CreateInfoLC( EFalse );
-        TScpReqId reqId;
-        // After publishing offline, we need to unbind because we are
-        // deregistering, so offline request id needs to be saved and handled
-        reqId.SetType( EPublishOfflineReq );
-        reqId.SetId( presPub->PublishOwnPresenceL( *info ) );
-        iPresenceState = EPresenceOffline;
-        iReqIdArray.Append( reqId );
-        CleanupStack::PopAndDestroy( 1 );  // info
-        }
-    else
-        {
-        //unbind if there are no other requests going on. 
-        //in case of ongoing unprocessed requests, 
-        //reset array (further events ignored) and
-        //leave here to deregister properly
-        if ( iReqIdArray.Count() > 0 )
-            {
-            User::Leave( KErrNotReady );
-            }
-        else
-            {
-            ServerUnBindL();
-            }
-        }
-
-    SCPLOGSTRING( "CScpPresenceHandler::HandleDeregistrationL end" );
-    } 
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::CreateInfoLC
-// Creates presence info item
-// -----------------------------------------------------------------------------
-//  
-MPresenceInfo* CScpPresenceHandler::CreateInfoLC( TBool aState )
-    {
-    SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::CreateInfoLC", this );
-    
-    MPresenceInfo* info = 
-        iFeature->PresenceObjectFactory().NewPresenceInfoLC();
-    // fill service info
-    MServicePresenceInfo* srvInfo = 
-        iFeature->PresenceObjectFactory().NewServicePresenceInfoLC();
-    srvInfo->SetServiceTypeL( 
-        NPresenceInfo::NServiceType::KVoip );  // voip
-
-    MPresenceInfoField* infoField = 
-        iFeature->PresenceObjectFactory().NewInfoFieldLC();
-    
-    MPresenceInfoFieldValueEnum* enumField = 
-       iFeature->PresenceObjectFactory().NewEnumInfoFieldLC();
-       
-    // Set the textfield's value according to aState    
-    if ( aState )
-        {  
-        enumField->SetValueL( NPresenceInfo::EAvailable );
-        }
-     else
-        {
-        enumField->SetValueL( NPresenceInfo::ENotAvailable );
-        }
-    
-    infoField->SetFieldTypeL( 
-        NPresenceInfo::NFieldType::KAvailabilityEnum ); // "availability"
-    infoField->SetFieldValue( enumField );
-    CleanupStack::Pop(); // enumField
-    
-    srvInfo->Fields().AddOrReplaceFieldL( infoField );
-    CleanupStack::Pop(); // infoField 
-
-    info->AddServicePresenceL( srvInfo );
-    CleanupStack::Pop(); // srvInfo 
-
-    // fill person info
-    MPersonPresenceInfo* persInfo = 
-        iFeature->PresenceObjectFactory().NewPersonPresenceInfoLC();
-    
-    MPresenceInfoField* infoField2 = 
-        iFeature->PresenceObjectFactory().NewInfoFieldLC();
-    
-    MPresenceInfoFieldValueEnum* enumField2 = 
-        iFeature->PresenceObjectFactory().NewEnumInfoFieldLC();
-    TInt availabilityEnum(0);
-    RBuf customMessage;
-    CleanupClosePushL( customMessage );
-    customMessage.Create( KCustomMessageMaxLength );
-    GetStoredPresenceValuesL( availabilityEnum, customMessage );
-    
-    switch( availabilityEnum )
-        {
-        case NPresenceInfo::EAvailable:
-            {
-            enumField2->SetValueL( NPresenceInfo::EAvailable );
-            break;
-            }
-
-        case NPresenceInfo::ENotAvailable:
-            {
-            enumField2->SetValueL( NPresenceInfo::ENotAvailable );
-            break;
-            }
-            
-        case NPresenceInfo::EBusy:
-            {
-            enumField2->SetValueL( NPresenceInfo::EBusy );
-            break;
-            }
-            
-        case NPresenceInfo::EDoNotDisturb:
-            {
-            enumField2->SetValueL( NPresenceInfo::EDoNotDisturb );
-            break;
-            }
-                
-        case NPresenceInfo::EAway:
-            {
-            enumField2->SetValueL( NPresenceInfo::EAway );
-            break;
-            }
-            
-        // if presence availability is not stored     
-        default:
-            {
-            if ( aState )
-                {  
-                enumField2->SetValueL( NPresenceInfo::EAvailable );
-                }
-            else
-                {
-                enumField2->SetValueL( NPresenceInfo::ENotAvailable );
-                }
-            break;
-            }
-        }
-    
-    // set custom message if available
-    if( customMessage.Length() ) 
-        {
-        MPresenceInfoField* customMessageinfoField = 
-            iFeature->PresenceObjectFactory().NewInfoFieldLC();
-                
-        MPresenceInfoFieldValueText* textField = 
-            iFeature->PresenceObjectFactory().NewTextInfoFieldLC();
-        textField->SetTextValueL( customMessage );
-        customMessageinfoField->SetFieldTypeL( 
-        NPresenceInfo::NFieldType::KStatusMessage );
-        customMessageinfoField->SetFieldValue( textField );
-        CleanupStack::Pop(); //textField
-        persInfo->Fields().AddOrReplaceFieldL( customMessageinfoField );
-        CleanupStack::Pop(); //customMessageinfoField
-        }
-    
-    CleanupStack::PopAndDestroy( &customMessage );
-   
-    infoField2->SetFieldTypeL( 
-        NPresenceInfo::NFieldType::KAvailabilityEnum );
-    infoField2->SetFieldValue( enumField2 );
-    CleanupStack::Pop(); // enumField2
-
-    persInfo->Fields().AddOrReplaceFieldL( infoField2 );
-    CleanupStack::Pop(); // infoField2
-
-    info->SetPersonPresenceL( persInfo );
-    CleanupStack::Pop(); // persInfo
-
-    return info;
-    } 
-
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::HandleContextStateEvent
-// Handles the XIMP context state events
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::HandleContextStateEvent( const MXIMPBase& aEvent )
-    {
-    const MXIMPContextStateEvent* event =
-    TXIMPGetInterface< const MXIMPContextStateEvent >::From( aEvent, MXIMPBase::EPanicIfUnknown );
-
-    MXIMPContextState::TState ctxState = event->ContextState().ContextState();
-    SCPLOGSTRING2( "CScpPresenceHandler: MXIMPContextStateEvent: %d", (TInt)ctxState );
-    
-    const MXIMPStatus* status = event->StateChangeReason();
-    if ( status )
-        {
-        iLastXimpError = status->ResultCode();
-        }
-    SCPLOGSTRING2( "CScpPresenceHandler -> context ximp error: %d", iLastXimpError );
-        
-    // Go through the reqid array to see, if unbind has been requested
-    TBool unBindRequested( EFalse );
-    for ( TInt i = 0; i < iReqIdArray.Count(); i++ )
-        {
-        if ( iReqIdArray[i].Type() == EUnBindReq )
-            {
-            unBindRequested = ETrue;
-            }
-        }
-    
-    if ( ctxState == MXIMPContextState::EInactive && 
-        iReqIdArray.Count() > 0 &&
-        !unBindRequested )
-        {
-        //Unbind was not requested, but EInactive state event received => try forced unbind
-        TRAPD( binderr, HandleDeregistrationL( EFalse ) );
-        SCPLOGSTRING2( "CScpPresenceHandler::HandleContextStateEvent: Unbind err:%d", binderr );
-        if ( KErrNone != binderr )
-            {
-            DeregisterNow();
-            }
-        }
-    }
-
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::HandleRequestCompleteEvent
-// Handles the XIMP request complete events
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::HandleRequestCompleteEvent( const MXIMPBase& aEvent )
-    {
-    SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent event MximpRequestCompleteEvent" );
-    const MXIMPRequestCompleteEvent* event =
-        TXIMPGetInterface< const MXIMPRequestCompleteEvent >::From( aEvent, MXIMPBase::EPanicIfUnknown );
-
-    const TXIMPRequestId& reqId = event->RequestId();
-    const MXIMPStatus& status = event->CompletionResult();
-    if ( &status )
-        {
-        iLastXimpError = status.ResultCode();
-        }
-    SCPLOGSTRING2( "CScpPresenceHandler -> request ximp error: %d", iLastXimpError );
-       
-    if ( iLastXimpError == KXIMPErrServicRequestTimeouted )
-        {
-        iSubService.HandleConnectionEvent( EScpRegistrationFailed );
-        }
-    
-    // Find the reqId from the reqid array and store it's type
-    TInt index( KErrNotFound );
-    TScpReqType reqType( EUnknownReq );
-    for ( TInt i = 0; i < iReqIdArray.Count(); i++ )
-        {
-        if ( iReqIdArray[i].ReqId() == reqId )
-            {
-            index = i;
-            reqType = iReqIdArray[i].Type();
-            }
-        }
-    
-    if ( index != KErrNotFound )
-        {
-        iReqIdArray.Remove( index );             
-        }
-    
-    SCPLOGSTRING2( "CScpPresenceHandler -> request type: %d", reqType );
-
-    // Bind complete event
-    if ( ( reqType == EBindReq ) &&
-        ( EBinding == iPresenceState ) &&
-        ( iLastXimpError == KErrNone ) )
-        {
-        HandleBindCompleteEvent();
-        }
-    // Published online request complete
-    else if ( ( reqType == EPublishOnlineReq ) && 
-        ( iLastXimpError == KErrNone ) )
-        {
-        TRAP_IGNORE( SubscribePresentityGroupL() );
-        iPresenceState = ESubscribing;
-        }
-    
-    else if ( ( reqType == ESubscribeReq ) &&
-        ( iLastXimpError == KErrNone ) )
-        {
-        // Set subservice enabled after subscribe is successfully done
-        iPresenceState = EPresenceOnline;
-        iSubService.HandleConnectionEvent( EScpRegistered );
-        }
-    
-    // Published offline request complete
-    else if ( reqType == EPublishOfflineReq )
-        {
-        SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent status offline Unbind now" );
-        TRAPD( err, ServerUnBindL() );
-        // Deregistration ongoing, so if unbind fails, deregisterNow is called
-        if ( err )
-            {
-            DeregisterNow();
-            SCPLOGSTRING2( "CScpPresenceHandler::HandleRequestCompleteEvent status offline Unbind now end, err %d", err );
-            }
-        }
-    
-    // Unbind request complete
-    else if ( reqType == EUnBindReq && EUnBinding == iPresenceState )
-        {
-        SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent status offline" );
-        // Do not send info to our client if roaming is ongoing 
-        if ( !iNetworkLostRoamingOngoing )
-            {
-            if ( !iSubService.IsRoaming() )
-                {
-                DeregisterNow();
-                }
-            else
-                {
-                // Inform SIP to start ALR migration
-                iSubService.ProfileHandler().StartAlrMigration(
-                    iSubService.SipProfileId() );
-                }
-            }
-        SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent status offline end" );
-        }
-    
-    if ( iRebind )
-        {
-         TRAPD( err, ServerBindL() );
-         iRebind = EFalse;
-         SCPLOGSTRING2( "CScpPresenceHandler - ServerBindL failed: %d", err );
-         
-         if ( KErrAlreadyExists == err )
-             {
-             iRebind = ETrue;
-             }
-        }
-    
-    if ( iDisableAfterXimpRequestsCompleted && !iReqIdArray.Count() )
-        {
-        iDisableAfterXimpRequestsCompleted = EFalse;
-        DeregisterNow();
-        }
-    
-    SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent OUT" ); 
-    }
-
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::HandleBindCompleteEvent
-// Handles the bind complete event
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::HandleBindCompleteEvent()
-    {
-    SCPLOGSTRING( "CScpPresenceHandler::HandleBindCompleteEvent" );
-    
-    iPresenceState = EBindComplete;
-    
-    TInt err( KErrNone );
-    CScpSubService* voipSubService = GetVoipSubService();
-    if ( voipSubService )
-        {
-        if ( voipSubService->State() == ECCHEnabled &&
-            voipSubService->LastReportedError() == KErrNone )
-            {
-            SCPLOGSTRING( "CScpPresenceHandler::HandleBindCompleteEvent PublishOnline");
-            TRAP( err, PublishPresenceL( ETrue ) );
-            }
-        else
-            {
-            SCPLOGSTRING( "CScpPresenceHandler::HandleBindCompleteEvent PublishOffline");
-            TRAP( err, PublishPresenceL( EFalse ) );
-            }
-        }
-    else
-        {
-        SCPLOGSTRING( "CScpPresenceHandler::HandleBindCompleteEvent PublishOffline, no VoIP");
-        TRAP( err, PublishPresenceL( EFalse ) );
-        err = KErrNotFound;
-        }
-     
-    if ( err )
-        {
-        SCPLOGSTRING2( "CScpPresenceHandler::HandleBindCompleteEvent err %d", err );
-        }   
-    }
-
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::SubscribePresentityGroupL
-// 
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::SubscribePresentityGroupL()
-    {
-    SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL subsribe buddies" );
-    MXIMPObjectFactory& objFactoryFromXIMP = iPresenceCtx->ObjectFactory();
-    
-    //First we have to make identity
-    SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL create buddy list identity" );
-    MXIMPIdentity* groupIdentity = objFactoryFromXIMP.NewIdentityLC();
-    groupIdentity->SetIdentityL( _L("buddylist") ); // NEEDS TO BE DEFINED IN XIMP API
-    
-    SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL subsribe group content" );
-    TScpReqId reqId;
-
-    reqId.SetType( ESubscribeReq );
-    reqId.SetId( iFeature->PresentityGroups().SubscribePresentityGroupContentL(
-        *groupIdentity ) );
-    SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL append req to array" );
-    iReqIdArray.Append( reqId );
-
-    SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL subsribe group content ok" );
-    CleanupStack::PopAndDestroy( 1 ); // groupIdentity
-    }
-
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::UnsubscribePresentityGroupL
-// 
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::UnsubscribePresentityGroupL()
-    {
-    MXIMPObjectFactory& objFactoryFromXIMP = iPresenceCtx->ObjectFactory();
-    
-    //First we have to make identity
-    MXIMPIdentity* groupIdentity = objFactoryFromXIMP.NewIdentityLC();
-    groupIdentity->SetIdentityL( _L("buddylist") ); // NEEDS TO BE DEFINED IN XIMP API
-    
-    TScpReqId reqId;
-    // Set type to Unknown, because we don't need to handle the
-    // request complete event
-    reqId.SetType( EUnknownReq );
-    reqId.SetId( iFeature->PresentityGroups().UnsubscribePresentityGroupContentL(
-        *groupIdentity ) );
-    iReqIdArray.Append( reqId );
-    
-    CleanupStack::PopAndDestroy( 1 );
-    }
-
-// -----------------------------------------------------------------------------
-// CScpPresenceHandler::GetStoredPresenceValuesL
-// 
-// -----------------------------------------------------------------------------
-//
-void CScpPresenceHandler::GetStoredPresenceValuesL( TInt& aAvailabilityEnum, RBuf& aCustomMessage )
-    {
-    MVIMPSTSettingsStore* settings = CVIMPSTSettingsStore::NewLC();
-        
-    TInt serviceId = iSubService.SubServiceId();
-    RBuf8 documentId;
-    CleanupClosePushL( documentId );
-    documentId.CreateL( KBufSize255 );
-    TInt error = settings->GetL( 
-        serviceId, EServicePresenceSessionIdentifier, documentId );
-    TInt i = documentId.Length();
-    TInt err1(0);
-    TInt err2(0);
-    
-    if( documentId.Length() )
-        {
-        err1 = settings->GetL( 
-            serviceId, EServicePresenceAvailablilityValue, aAvailabilityEnum );
-        err2 = settings->GetL( 
-            serviceId, EServiceCustomStatusMessage, aCustomMessage );
-        
-        // if other GetL fails -> clear both
-        if( err1 || err2 )
-            {
-            aAvailabilityEnum = KErrNotFound;
-            aCustomMessage.Zero();
-            }
-        }   
-    else 
-        {
-        aAvailabilityEnum = KErrNotFound;
-        }
-
-    CleanupStack::PopAndDestroy( &documentId );
-    CleanupStack::PopAndDestroy(); //settings
-    }
-
-//  End of File