voipplugins/sipconnectionprovider/src/scppresencehandler.cpp
branchRCL_3
changeset 21 f742655b05bf
parent 20 65a3ef1d5bd0
child 22 d38647835c2e
equal deleted inserted replaced
20:65a3ef1d5bd0 21:f742655b05bf
     1 /*
       
     2 * Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Presence handler.
       
    15 *
       
    16 */
       
    17 #include <ximperrors.hrh>
       
    18 #include <ximpcontext.h>
       
    19 #include <presenceinfo.h> //MximpPresenceInfo
       
    20 #include <presenceinfofilter.h> //info filtter
       
    21 #include <presenceinfofield.h> //MximpPresenceInfoField
       
    22 #include <ximpobjectfactory.h>
       
    23 #include <presenceobjectfactory.h>
       
    24 #include <servicepresenceinfo.h> //MximpServicePresenceInfo
       
    25 #include <presenceinfofieldvalueenum.h> //MximpPresenceInfoFieldValueEnum
       
    26 #include <presenceinfofieldcollection.h> //MximpPresenceInfoFieldCollection
       
    27 #include <presenceinfofieldvaluetext.h> //MximpPresenceInfoFieldValueText
       
    28 #include <personpresenceinfo.h> // MximpPersonPresenceInfo
       
    29 #include <presencepublishing.h>//MPresencePublishing
       
    30 #include <ximpfeatureinfo.h>
       
    31 #include <presencefeatures.h>
       
    32 #include <ximpidentity.h> //for MXIMPIdentity
       
    33 #include <presentitygroups.h>
       
    34 
       
    35 #include <ximprequestcompleteevent.h>
       
    36 #include <ximpcontextstateevent.h>
       
    37 #include <ownpresenceevent.h>
       
    38 #include <ximpclient.h>
       
    39 #include <ximpcontext.h>
       
    40 #include <ximpstatus.h>
       
    41 #include <pressettingsapi.h> //presence settings
       
    42 #include <XdmSettingsApi.h>
       
    43 #include <cvimpstsettingsstore.h>
       
    44 
       
    45 #include "scppresencehandler.h"
       
    46 #include "scpsubservice.h"
       
    47 #include "scpservicestorage.h"
       
    48 #include "scplogger.h"
       
    49 #include "scputility.h"
       
    50 #include "scpservice.h"
       
    51 #include "scpprofilehandler.h"
       
    52 #include "scpsettinghandler.h"
       
    53 #include "scppresencehandlerrequest.h"
       
    54 
       
    55 const TInt KXdmDmMaxIntLength      = 10;   // max length of 32bit integer
       
    56 const TInt KMaxPresenceEnableCount = 5;
       
    57 const TInt KCustomMessageMaxLength = 75;
       
    58 const TInt KBufSize255 = 255;
       
    59 
       
    60 // -----------------------------------------------------------------------------
       
    61 // CScpPresenceHandler::NewL
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 CScpPresenceHandler* CScpPresenceHandler::NewL( CScpSubService& aSubService )
       
    65     {
       
    66     SCPLOGSTRING( "CScpPresenceHandler::NewL" );
       
    67     CScpPresenceHandler* self = new ( ELeave ) CScpPresenceHandler( aSubService );
       
    68     CleanupStack::PushL( self );    
       
    69     self->ConstructL();    
       
    70     CleanupStack::Pop( self );
       
    71     return self;
       
    72     }
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CScpPresenceHandler::CCScpPresenceHandler
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 CScpPresenceHandler::CScpPresenceHandler( CScpSubService& aSubService ) :
       
    79     CScpServiceHandlerBase( aSubService ),
       
    80     iPresenceState( ENoBind ),
       
    81     iDisableAfterXimpRequestsCompleted( EFalse ),
       
    82     iNetworkLostRoamingOngoing( EFalse )
       
    83     {
       
    84     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::CScpPresenceHandler", this );
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CScpPresenceHandler::ConstructL
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 void CScpPresenceHandler::ConstructL()
       
    92     {
       
    93     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::ConstructL", this );
       
    94 
       
    95     BaseConstructL();
       
    96     GetPresencePropertyIdL( ESubPropertyPresenceSettingsId, iPresenceSettingsId );
       
    97     
       
    98     iPresClient = MXIMPClient::NewClientL();
       
    99     SCPLOGSTRING2( "CScpPresenceHandler::ConstructL, iPresClient [0x%x]", iPresClient );
       
   100 
       
   101     if ( iPresClient )
       
   102         {
       
   103         // Set presence handler as observer of Voip subservice
       
   104         CScpSubService* voipSubService = GetVoipSubService();
       
   105         if ( voipSubService )
       
   106             {
       
   107             voipSubService->SetSubServiceObserver( this );
       
   108             }
       
   109         
       
   110         MXIMPContext* tmp = iPresClient->NewPresenceContextLC();        
       
   111         iFeature = MPresenceFeatures::NewL( tmp );
       
   112         
       
   113         RArray<TInt32> eventFilter;   
       
   114         CleanupClosePushL( eventFilter );
       
   115 
       
   116         eventFilter.Append( XIMP_IF_ID_REQUEST_COMPLETE_EVENT );     
       
   117         eventFilter.Append( XIMP_IF_ID_CONTEXT_STATE_EVENT );
       
   118         
       
   119         TArray<TInt32> eventFilterArray = eventFilter.Array();
       
   120         tmp->RegisterObserverL( *this, &eventFilterArray );
       
   121         
       
   122         CleanupStack::PopAndDestroy( &eventFilter );
       
   123 
       
   124         CleanupStack::Pop(); // tmp
       
   125         iPresenceCtx = tmp;
       
   126         tmp = NULL; 
       
   127         }
       
   128     else
       
   129         {
       
   130         User::Leave( KErrGeneral );
       
   131         }
       
   132     }
       
   133 
       
   134 // -----------------------------------------------------------------------------
       
   135 // CScpPresenceHandler::~CScpPresenceHandler
       
   136 // -----------------------------------------------------------------------------
       
   137 //
       
   138 CScpPresenceHandler::~CScpPresenceHandler()
       
   139     {
       
   140     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::~CScpPresenceHandler", this );
       
   141 
       
   142     CancelDisableTimer();
       
   143     
       
   144     iReqIdArray.Close();
       
   145     
       
   146     delete iFeature;
       
   147     delete iPresenceCtx;
       
   148     
       
   149     // Set observer of Voip subservice to NULL
       
   150     CScpSubService* voipSubService = GetVoipSubService();
       
   151     if ( voipSubService )
       
   152         {
       
   153         voipSubService->SetSubServiceObserver( NULL );
       
   154         }
       
   155     
       
   156     delete iPresClient;
       
   157     }
       
   158 
       
   159 
       
   160 // ====================== From CScpServiceHandlerBase ==========================
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CScpPresenceHandler::EnableSubServiceL
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 void CScpPresenceHandler::EnableSubServiceL()
       
   167     {
       
   168     SCPLOGSTRING4( "CScpPresenceHandler[0x%x]::EnableSubServiceL: 0x%x type: %i", 
       
   169                    this, &iSubService, iSubService.SubServiceType() );
       
   170        
       
   171     __ASSERT_DEBUG( iSubService.SubServiceType() == ECCHPresenceSub,
       
   172                     User::Panic( KNullDesC, KErrGeneral ) );     
       
   173 
       
   174     CScpServiceHandlerBase::RegisterProfileL();
       
   175     }
       
   176 
       
   177 // -----------------------------------------------------------------------------
       
   178 // CScpPresenceHandler::DisableSubService
       
   179 // -----------------------------------------------------------------------------
       
   180 //
       
   181 TInt CScpPresenceHandler::DisableSubService()
       
   182     {
       
   183     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::DisableSubService", this );
       
   184     __ASSERT_DEBUG( iSubService.SubServiceType() == ECCHPresenceSub,
       
   185                     User::Panic( KNullDesC, KErrGeneral ) );  
       
   186 
       
   187     TInt result = KErrNone;
       
   188     // Publish offline and unbind presence context
       
   189     TRAP( result, HandleDeregistrationL( ETrue ) );
       
   190     
       
   191     if ( KErrNone == result  )
       
   192         {
       
   193         // Deregister if still connecting
       
   194         if ( iSubService.State() == ECCHConnecting )
       
   195             {
       
   196             DeregisterNow();            
       
   197             }
       
   198         else
       
   199             {
       
   200             StartForcedDisableTimer( CScpPresenceHandler::ForcePresenceServiceDisable );
       
   201             }
       
   202         }
       
   203     else
       
   204         {
       
   205         
       
   206         // Wait for XIMP request to be completed and handle 
       
   207         // de-registration after that or after force disable timer expires
       
   208         if ( iReqIdArray.Count() )
       
   209             {
       
   210             iDisableAfterXimpRequestsCompleted = ETrue;
       
   211             StartForcedDisableTimer( CScpPresenceHandler::ForcePresenceServiceDisable );
       
   212             }
       
   213         else
       
   214             {
       
   215             DeregisterNow();
       
   216             }
       
   217         }
       
   218 
       
   219     return result;
       
   220     }
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 // CScpPresenceHandler::SubServiceType
       
   224 // -----------------------------------------------------------------------------
       
   225 //
       
   226 TCCHSubserviceType CScpPresenceHandler::SubServiceType() const
       
   227     {
       
   228     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::SubServiceType", this );
       
   229     return ECCHPresenceSub;
       
   230     }
       
   231 
       
   232 // -----------------------------------------------------------------------------
       
   233 // CScpPresenceHandler::HandleSipConnectionEvent
       
   234 // -----------------------------------------------------------------------------
       
   235 //
       
   236 void CScpPresenceHandler::HandleSipConnectionEvent( const TUint32 aProfileId,
       
   237                                                     TScpConnectionEvent aEvent )
       
   238     {
       
   239     SCPLOGSTRING4( "CScpPresenceHandler[0x%x]::HandleSipConnectionEvent id: %d event: %d",
       
   240                    this, aProfileId, aEvent );
       
   241     
       
   242     iNetworkLostRoamingOngoing = EFalse;
       
   243     
       
   244     if ( iSubService.SipProfileId() == aProfileId &&
       
   245         iSubService.EnableRequestedState() != CScpSubService::EScpNoRequest )
       
   246         {
       
   247         if ( EScpDeregistered == aEvent && 
       
   248              iSubService.EnableRequestedState() == CScpSubService::EScpEnabled )
       
   249             {
       
   250             SCPLOGSTRING( "CScpPresenceHandler - EScpDeregistered -> unbind" );
       
   251             TRAPD( err, HandleDeregistrationL( EFalse ) ); 
       
   252             if ( KErrNotReady == err )
       
   253                 {
       
   254                 SCPLOGSTRING( "CScpPresenceHandler - EScpDeregistered -> not ready: unbind" );
       
   255                 TRAP_IGNORE( ServerUnBindL() );
       
   256                 }
       
   257             }
       
   258         //if network lost, unbind context
       
   259         if ( EScpNetworkLost == aEvent )
       
   260             {
       
   261             SCPLOGSTRING( "CScpPresenceHandler - EScpNetworkLost -> unbind" );
       
   262             TRAPD( err, HandleDeregistrationL( EFalse ) );
       
   263             
       
   264             if ( KErrNotReady == err )
       
   265                 {
       
   266                 SCPLOGSTRING( "CScpPresenceHandler - EScpNetworkLost -> not ready: unbind" );
       
   267                 TRAP_IGNORE( ServerUnBindL() );
       
   268                 }
       
   269             
       
   270             TUint32 snapId;
       
   271             CScpProfileHandler& profileHandler = iSubService.ProfileHandler();
       
   272             CScpSipConnection* sipConnection = profileHandler.GetSipConnection( iSubService.SipProfileId() );
       
   273             
       
   274             if ( sipConnection )
       
   275                 {
       
   276                 TInt error = sipConnection->GetSnap( snapId );
       
   277                 
       
   278                 if ( !error && sipConnection->IsSnapConnectionAvailable( snapId ) )
       
   279                     {
       
   280                     iNetworkLostRoamingOngoing = ETrue;
       
   281                     }
       
   282                 }
       
   283             }
       
   284         
       
   285         if ( EScpRoaming == aEvent )
       
   286             {
       
   287             SCPLOGSTRING( "CScpPresenceHandler - EScpRoaming -> unbind" );
       
   288             TRAP_IGNORE( ServerUnBindL() );
       
   289             }
       
   290         
       
   291         //if registered, time to bind context
       
   292         if ( EScpRegistered == aEvent &&
       
   293              CScpSubService::EScpEnabled == iSubService.EnableRequestedState() )
       
   294             {
       
   295             SCPLOGSTRING( "CScpPresenceHandler - EScpRegistered -> update iap and bind" );
       
   296             // update xmd settings 
       
   297             TRAPD( err, UpdateXdmSettingsL() );
       
   298             
       
   299             if ( KErrNone == err )
       
   300                 {
       
   301                 // Subscribe
       
   302                 TRAP( err, ServerBindL() );
       
   303                 iRebind = EFalse;
       
   304                 
       
   305                 if( KErrNone == err )
       
   306                     {
       
   307                     // Still connecting the service
       
   308                     aEvent = EScpNetworkFound;    
       
   309                     }
       
   310                 else
       
   311                     {
       
   312                     SCPLOGSTRING2( "ServerBindL failed: %d", err );
       
   313                     aEvent = EScpRegistrationPending;
       
   314                     if ( KErrAlreadyExists == err )
       
   315                         {
       
   316                         // Ximp does not set request to queue, so we have to do rebind later
       
   317                         SCPLOGSTRING( "CScpPresenceHandler - rebind later" ); 
       
   318                         iRebind = ETrue;
       
   319                         }
       
   320                     }
       
   321                 }
       
   322             else
       
   323                 {
       
   324                 SCPLOGSTRING2( "UpdateXdmSettingsL: %d", err );
       
   325                 aEvent = EScpRegistrationFailed;
       
   326                 }
       
   327             }
       
   328         else if ( EScpDeregistered == aEvent &&
       
   329                  iSubService.EnableRequestedState() == CScpSubService::EScpDisabled ||
       
   330                  iSubService.EnableRequestedState() == CScpSubService::EScpRefreshed )
       
   331             {
       
   332             if ( EScpRegistered != aEvent && ECCHDisconnecting != iSubService.State() )
       
   333                 {
       
   334                 CancelDisableTimer();
       
   335                 }
       
   336             
       
   337             // If this flag is still true, it could be that presence server
       
   338             // has not given answer -> ximp requests cannot be completed.
       
   339             // But still have to unbind from ximp context
       
   340             if ( iDisableAfterXimpRequestsCompleted )
       
   341                 {
       
   342                 TRAP_IGNORE( ServerUnBindL() );
       
   343                 }
       
   344             
       
   345             // When SIP is deregistered, change presence state to no bind
       
   346             iPresenceState = ENoBind;
       
   347             }
       
   348         iSubService.HandleConnectionEvent( aEvent );
       
   349         }
       
   350     SCPLOGSTRING( "CScpPresenceHandler::HandleSipConnectionEvent OUT" );
       
   351     }    
       
   352 
       
   353 // -----------------------------------------------------------------------------
       
   354 // CScpPresenceHandler::HandleSipConnectionEvent
       
   355 // -----------------------------------------------------------------------------
       
   356 //
       
   357 TBool CScpPresenceHandler::IsSipProfileAllowedToStartAlr()
       
   358     {
       
   359     return EFalse;
       
   360     }
       
   361 
       
   362 // ======================= From MXIMPContextObserver ===========================
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // CScpPresenceHandler::HandlePresenceContextEvent
       
   366 // -----------------------------------------------------------------------------
       
   367 //   
       
   368 void CScpPresenceHandler::HandlePresenceContextEvent(
       
   369     const MXIMPContext& /*aContext*/,
       
   370     const MXIMPBase& aEvent )
       
   371     {
       
   372     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::HandlePresenceContextEvent", this );
       
   373 
       
   374     const TInt32 eventType = aEvent.GetInterfaceId();
       
   375     
       
   376     switch ( eventType )
       
   377         {
       
   378         case MXIMPContextStateEvent::KInterfaceId:
       
   379             {
       
   380             HandleContextStateEvent( aEvent );
       
   381             break;
       
   382             }
       
   383 
       
   384         case MXIMPRequestCompleteEvent::KInterfaceId:
       
   385             {
       
   386             HandleRequestCompleteEvent( aEvent );
       
   387             break;
       
   388             }
       
   389               
       
   390         default:
       
   391             {
       
   392             break;
       
   393             }
       
   394         }
       
   395     SCPLOGSTRING( "CScpPresenceHandler::HandlePresenceContextEvent end" ); 
       
   396     }
       
   397 
       
   398 
       
   399 
       
   400 // ===================== From MScpSubServiceObserver ===========================
       
   401 
       
   402 // -----------------------------------------------------------------------------
       
   403 // CScpPresenceHandler::HandleSubServiceChange
       
   404 // -----------------------------------------------------------------------------
       
   405 //
       
   406 void CScpPresenceHandler::HandleSubServiceChange( TCCHSubserviceState aState, TInt aError )
       
   407     {
       
   408     SCPLOGSTRING4( "CScpPresenceHandler::HandleSubServiceChange presence subservice state: %d, aState: %d, aError: %d", 
       
   409                     iSubService.State(), aState, aError );
       
   410                     
       
   411     if ( iSubService.State() == ECCHEnabled && ( aError == KCCHErrorBandwidthInsufficient || aError == KErrNone ) )
       
   412         {
       
   413         if( aState == ECCHEnabled && aError == KErrNone )
       
   414             {
       
   415             if ( EPresenceOffline == iPresenceState )
       
   416                 {
       
   417                 SCPLOGSTRING( "CScpPresenceHandler::HandleSubServiceChange PublishOnline" );
       
   418                 TRAP_IGNORE( PublishPresenceL( ETrue ) );
       
   419                 }
       
   420             }
       
   421         else
       
   422             {
       
   423             if ( EPresenceOnline == iPresenceState && aState != ECCHConnecting )
       
   424                 {
       
   425                 SCPLOGSTRING( "CScpPresenceHandler::HandleSubServiceChange PublishOffline" );
       
   426                 // Unsubscribe from the list first
       
   427                 TRAP_IGNORE( UnsubscribePresentityGroupL() );
       
   428                 TRAP_IGNORE( PublishPresenceL( EFalse ) );
       
   429                 }
       
   430             }
       
   431         }
       
   432     }
       
   433  
       
   434 // ========================= Other member funcions =============================
       
   435 
       
   436 
       
   437 // -----------------------------------------------------------------------------
       
   438 // CScpPresenceHandler::GetVoipSubService
       
   439 // -----------------------------------------------------------------------------
       
   440 //
       
   441 CScpSubService* CScpPresenceHandler::GetVoipSubService()
       
   442     {
       
   443     CScpSubService* voipSubService = NULL;
       
   444     CScpServiceStorage& serviceStorage = iSubService.ServiceStorage();
       
   445     CScpService* service = serviceStorage.GetServiceByServiceId( iSubService.SubServiceId() );
       
   446 
       
   447     if ( service )
       
   448         {
       
   449         voipSubService = service->GetSubServiceByType( ECCHVoIPSub );
       
   450         }
       
   451     
       
   452     return voipSubService;
       
   453     }
       
   454 
       
   455 // -----------------------------------------------------------------------------
       
   456 // CScpPresenceHandler::DeregisterNow
       
   457 // -----------------------------------------------------------------------------
       
   458 //
       
   459 void CScpPresenceHandler::DeregisterNow()
       
   460     {
       
   461     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::DeregisterNow",
       
   462                    this );
       
   463     
       
   464     CancelDisableTimer();
       
   465   
       
   466     iReqIdArray.Reset();
       
   467     iPresenceState = ENoBind;
       
   468 
       
   469     // Check if disable was not requested
       
   470     if ( iSubService.EnableRequestedState() == CScpSubService::EScpEnabled )
       
   471         {
       
   472         // Check the last ximp error
       
   473         if ( KErrNoMemory == iLastXimpError && 
       
   474             KMaxPresenceEnableCount < iSubService.EnableCounter() )
       
   475             {
       
   476             // No memory means 401 Unauthorized, we are trying to enable  
       
   477             // KMaxPresenceEnableCount times -> no more, this is truly
       
   478             // autentication failed.
       
   479             iSubService.HandleConnectionEvent( EScpAuthenticationFailed );
       
   480             }
       
   481         else
       
   482             {
       
   483             iSubService.HandleConnectionEvent( EScpDeregistered );
       
   484             }
       
   485         }
       
   486     else
       
   487         {
       
   488         DeregisterProfile();
       
   489         }
       
   490     }
       
   491 
       
   492 // -----------------------------------------------------------------------------
       
   493 // CScpPresenceHandler::ForcePresenceServiceDisable
       
   494 // -----------------------------------------------------------------------------
       
   495 //
       
   496 TInt CScpPresenceHandler::ForcePresenceServiceDisable( TAny* aSelf )
       
   497     {
       
   498     SCPLOGSTRING( "CScpPresenceHandler::ForcePresenceServiceDisable" );
       
   499 
       
   500     CScpPresenceHandler* self = static_cast<CScpPresenceHandler*>( aSelf );
       
   501 
       
   502     self->DeregisterNow();
       
   503 
       
   504     return 1;
       
   505     }
       
   506 
       
   507 // -----------------------------------------------------------------------------
       
   508 // CScpPresenceHandler::UpdateXdmSettingsL
       
   509 // -----------------------------------------------------------------------------
       
   510 //
       
   511 void CScpPresenceHandler::UpdateXdmSettingsL()
       
   512     {
       
   513     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::UpdateXdmSettingsL", this );
       
   514     
       
   515     // Get IAP id of sip profile
       
   516     CScpProfileHandler& profileHandler = iSubService.ProfileHandler();
       
   517     CScpSipConnection* sipConnection = profileHandler.GetSipConnection( iSubService.SipProfileId() );
       
   518     if ( !sipConnection )
       
   519         {
       
   520         User::Leave( KErrNotFound );
       
   521         }
       
   522     
       
   523     TUint32 apId = 0;
       
   524     User::LeaveIfError( sipConnection->GetIap( apId ) );
       
   525     
       
   526     SCPLOGSTRING2( "CScpPresenceHandler::UpdateXdmSettingsL apId is %d", apId );
       
   527     
       
   528     TPresSettingsSet mySet;
       
   529     User::LeaveIfError( PresSettingsApi::SettingsSetL( iPresenceSettingsId, mySet ));
       
   530         
       
   531     // set iap id to xdm settings
       
   532     HBufC* idBuf = HBufC::NewLC( KXdmDmMaxIntLength );
       
   533     TPtr ptrBuf = idBuf->Des();
       
   534     ptrBuf.AppendNum( apId );
       
   535         
       
   536     TXdmSettingsApi::UpdatePropertyL( mySet.iXDMSetting, *idBuf, EXdmPropToNapId );
       
   537     CleanupStack::PopAndDestroy( idBuf );
       
   538 
       
   539     SCPLOGSTRING( "CScpPresenceHandler::UpdateXdmSettingsL status online end" );
       
   540     }
       
   541 
       
   542 // -----------------------------------------------------------------------------
       
   543 // CScpPresenceHandler::GetPresencePropertyIdL
       
   544 // -----------------------------------------------------------------------------
       
   545 //
       
   546 void CScpPresenceHandler::GetPresencePropertyIdL( TServicePropertyName aProperty,
       
   547                                                     TInt& aValue ) const
       
   548     {
       
   549     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::GetPresenceSettingsId", this );
       
   550     
       
   551     CScpServiceStorage& serviceStorage = iSubService.ServiceStorage();
       
   552     CScpSettingHandler& settingHandler = serviceStorage.SettingsHandler();
       
   553     
       
   554     settingHandler.GetSPSettingsIntPropertyL( iSubService.SubServiceId(),
       
   555         aProperty, 
       
   556         aValue );
       
   557     }
       
   558 
       
   559 // -----------------------------------------------------------------------------
       
   560 // CScpPresenceHandler::PublishPresenceL
       
   561 // Publishes presence according to given parameter.
       
   562 // -----------------------------------------------------------------------------
       
   563 //
       
   564 void CScpPresenceHandler::PublishPresenceL( TBool aPublishOnline )
       
   565     {
       
   566     SCPLOGSTRING3( "CScpPresenceHandler[0x%x]::PublishPresenceL, aPublishOnline = %d",
       
   567         this, aPublishOnline );
       
   568 
       
   569     // Get the management interface
       
   570     MPresencePublishing* presPub = &( iFeature->PresencePublishing() );
       
   571     // publish own presence in here
       
   572     MPresenceInfo* info = CreateInfoLC( aPublishOnline );
       
   573     TScpReqId reqId;
       
   574     
       
   575     if ( aPublishOnline )
       
   576         {
       
   577         reqId.SetType( EPublishOnlineReq );
       
   578         iPresenceState = EPublishing;
       
   579         }
       
   580     else
       
   581         {
       
   582         reqId.SetType( EPublishOfflineReq );
       
   583         iPresenceState = EPresenceOffline;
       
   584         }
       
   585         
       
   586     reqId.SetId( presPub->PublishOwnPresenceL( *info ) ); 
       
   587     iReqIdArray.Append( reqId );
       
   588     
       
   589     CleanupStack::PopAndDestroy( 1 );
       
   590     
       
   591     SCPLOGSTRING( "CScpPresenceHandler::PublishPresenceL end" ); 
       
   592     }
       
   593 
       
   594 
       
   595 // -----------------------------------------------------------------------------
       
   596 // CScpPresenceHandler::ServerBindL
       
   597 // Binds the presence context
       
   598 // -----------------------------------------------------------------------------
       
   599 //
       
   600 void CScpPresenceHandler::ServerBindL()
       
   601     {
       
   602     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::ServerBindL", this );
       
   603     SCPLOGSTRING2( "CScpPresenceHandler::ServerBindL -> bind service: %d", 
       
   604         iSubService.SubServiceId() );
       
   605     
       
   606     //Bind context to desired presence service
       
   607     TInt propertyId = 0;
       
   608     GetPresencePropertyIdL( EPropertyPCSPluginId, propertyId );
       
   609     TUid protocolUid = TUid::Uid( propertyId );
       
   610     
       
   611     TScpReqId reqId;
       
   612     reqId.SetType( EBindReq );
       
   613     reqId.SetId( iPresenceCtx->BindToL( protocolUid, iSubService.SubServiceId() ) );
       
   614     iReqIdArray.Append( reqId );
       
   615     iPresenceState = EBinding;
       
   616     SCPLOGSTRING( "CScpPresenceHandler::ServerBindL end" );
       
   617     }
       
   618 
       
   619 // -----------------------------------------------------------------------------
       
   620 // CScpPresenceHandler::ServerUnBindL
       
   621 // Unbinds the presence context
       
   622 // -----------------------------------------------------------------------------
       
   623 //
       
   624 void  CScpPresenceHandler::ServerUnBindL()
       
   625     {
       
   626     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::ServerUnBindL", this );
       
   627     TScpReqId reqId;
       
   628     reqId.SetType( EUnBindReq );
       
   629     reqId.SetId( iPresenceCtx->UnbindL() );
       
   630     iReqIdArray.Append( reqId ); 
       
   631     iPresenceState = EUnBinding;
       
   632     SCPLOGSTRING( "CScpPresenceHandler::ServerUnBindL end" );
       
   633     }
       
   634     
       
   635 // -----------------------------------------------------------------------------
       
   636 // CScpPresenceHandler::HandleDeregistrationL
       
   637 // Handles the deregistration of presence.
       
   638 // -----------------------------------------------------------------------------
       
   639 //    
       
   640 void CScpPresenceHandler::HandleDeregistrationL( TBool aDoStopPublish )
       
   641     {
       
   642      SCPLOGSTRING4( "CScpPresenceHandler[0x%x]::HandleDeregistrationL, aDoStopPublish: %d, iPresenceState: %d",
       
   643              this, aDoStopPublish, iPresenceState );
       
   644 
       
   645     if ( EPresenceOnline == iPresenceState 
       
   646         && aDoStopPublish && 
       
   647         iSubService.LastReportedError() == KErrNone )
       
   648         {
       
   649         // Get the management interface
       
   650         MPresencePublishing* presPub = &( iFeature->PresencePublishing() );
       
   651         // publish own presence in here
       
   652         MPresenceInfo* info = CreateInfoLC( EFalse );
       
   653         TScpReqId reqId;
       
   654         // After publishing offline, we need to unbind because we are
       
   655         // deregistering, so offline request id needs to be saved and handled
       
   656         reqId.SetType( EPublishOfflineReq );
       
   657         reqId.SetId( presPub->PublishOwnPresenceL( *info ) );
       
   658         iPresenceState = EPresenceOffline;
       
   659         iReqIdArray.Append( reqId );
       
   660         CleanupStack::PopAndDestroy( 1 );  // info
       
   661         }
       
   662     else
       
   663         {
       
   664         //unbind if there are no other requests going on. 
       
   665         //in case of ongoing unprocessed requests, 
       
   666         //reset array (further events ignored) and
       
   667         //leave here to deregister properly
       
   668         if ( iReqIdArray.Count() > 0 )
       
   669             {
       
   670             User::Leave( KErrNotReady );
       
   671             }
       
   672         else
       
   673             {
       
   674             ServerUnBindL();
       
   675             }
       
   676         }
       
   677 
       
   678     SCPLOGSTRING( "CScpPresenceHandler::HandleDeregistrationL end" );
       
   679     } 
       
   680 
       
   681 // -----------------------------------------------------------------------------
       
   682 // CScpPresenceHandler::CreateInfoLC
       
   683 // Creates presence info item
       
   684 // -----------------------------------------------------------------------------
       
   685 //  
       
   686 MPresenceInfo* CScpPresenceHandler::CreateInfoLC( TBool aState )
       
   687     {
       
   688     SCPLOGSTRING2( "CScpPresenceHandler[0x%x]::CreateInfoLC", this );
       
   689     
       
   690     MPresenceInfo* info = 
       
   691         iFeature->PresenceObjectFactory().NewPresenceInfoLC();
       
   692     // fill service info
       
   693     MServicePresenceInfo* srvInfo = 
       
   694         iFeature->PresenceObjectFactory().NewServicePresenceInfoLC();
       
   695     srvInfo->SetServiceTypeL( 
       
   696         NPresenceInfo::NServiceType::KVoip );  // voip
       
   697 
       
   698     MPresenceInfoField* infoField = 
       
   699         iFeature->PresenceObjectFactory().NewInfoFieldLC();
       
   700     
       
   701     MPresenceInfoFieldValueEnum* enumField = 
       
   702        iFeature->PresenceObjectFactory().NewEnumInfoFieldLC();
       
   703        
       
   704     // Set the textfield's value according to aState    
       
   705     if ( aState )
       
   706         {  
       
   707         enumField->SetValueL( NPresenceInfo::EAvailable );
       
   708         }
       
   709      else
       
   710         {
       
   711         enumField->SetValueL( NPresenceInfo::ENotAvailable );
       
   712         }
       
   713     
       
   714     infoField->SetFieldTypeL( 
       
   715         NPresenceInfo::NFieldType::KAvailabilityEnum ); // "availability"
       
   716     infoField->SetFieldValue( enumField );
       
   717     CleanupStack::Pop(); // enumField
       
   718     
       
   719     srvInfo->Fields().AddOrReplaceFieldL( infoField );
       
   720     CleanupStack::Pop(); // infoField 
       
   721 
       
   722     info->AddServicePresenceL( srvInfo );
       
   723     CleanupStack::Pop(); // srvInfo 
       
   724 
       
   725     // fill person info
       
   726     MPersonPresenceInfo* persInfo = 
       
   727         iFeature->PresenceObjectFactory().NewPersonPresenceInfoLC();
       
   728     
       
   729     MPresenceInfoField* infoField2 = 
       
   730         iFeature->PresenceObjectFactory().NewInfoFieldLC();
       
   731     
       
   732     MPresenceInfoFieldValueEnum* enumField2 = 
       
   733         iFeature->PresenceObjectFactory().NewEnumInfoFieldLC();
       
   734     TInt availabilityEnum(0);
       
   735     RBuf customMessage;
       
   736     CleanupClosePushL( customMessage );
       
   737     customMessage.Create( KCustomMessageMaxLength );
       
   738     GetStoredPresenceValuesL( availabilityEnum, customMessage );
       
   739     
       
   740     switch( availabilityEnum )
       
   741         {
       
   742         case NPresenceInfo::EAvailable:
       
   743             {
       
   744             enumField2->SetValueL( NPresenceInfo::EAvailable );
       
   745             break;
       
   746             }
       
   747 
       
   748         case NPresenceInfo::ENotAvailable:
       
   749             {
       
   750             enumField2->SetValueL( NPresenceInfo::ENotAvailable );
       
   751             break;
       
   752             }
       
   753             
       
   754         case NPresenceInfo::EBusy:
       
   755             {
       
   756             enumField2->SetValueL( NPresenceInfo::EBusy );
       
   757             break;
       
   758             }
       
   759             
       
   760         case NPresenceInfo::EDoNotDisturb:
       
   761             {
       
   762             enumField2->SetValueL( NPresenceInfo::EDoNotDisturb );
       
   763             break;
       
   764             }
       
   765                 
       
   766         case NPresenceInfo::EAway:
       
   767             {
       
   768             enumField2->SetValueL( NPresenceInfo::EAway );
       
   769             break;
       
   770             }
       
   771             
       
   772         // if presence availability is not stored     
       
   773         default:
       
   774             {
       
   775             if ( aState )
       
   776                 {  
       
   777                 enumField2->SetValueL( NPresenceInfo::EAvailable );
       
   778                 }
       
   779             else
       
   780                 {
       
   781                 enumField2->SetValueL( NPresenceInfo::ENotAvailable );
       
   782                 }
       
   783             break;
       
   784             }
       
   785         }
       
   786     
       
   787     // set custom message if available
       
   788     if( customMessage.Length() ) 
       
   789         {
       
   790         MPresenceInfoField* customMessageinfoField = 
       
   791             iFeature->PresenceObjectFactory().NewInfoFieldLC();
       
   792                 
       
   793         MPresenceInfoFieldValueText* textField = 
       
   794             iFeature->PresenceObjectFactory().NewTextInfoFieldLC();
       
   795         textField->SetTextValueL( customMessage );
       
   796         customMessageinfoField->SetFieldTypeL( 
       
   797         NPresenceInfo::NFieldType::KStatusMessage );
       
   798         customMessageinfoField->SetFieldValue( textField );
       
   799         CleanupStack::Pop(); //textField
       
   800         persInfo->Fields().AddOrReplaceFieldL( customMessageinfoField );
       
   801         CleanupStack::Pop(); //customMessageinfoField
       
   802         }
       
   803     
       
   804     CleanupStack::PopAndDestroy( &customMessage );
       
   805    
       
   806     infoField2->SetFieldTypeL( 
       
   807         NPresenceInfo::NFieldType::KAvailabilityEnum );
       
   808     infoField2->SetFieldValue( enumField2 );
       
   809     CleanupStack::Pop(); // enumField2
       
   810 
       
   811     persInfo->Fields().AddOrReplaceFieldL( infoField2 );
       
   812     CleanupStack::Pop(); // infoField2
       
   813 
       
   814     info->SetPersonPresenceL( persInfo );
       
   815     CleanupStack::Pop(); // persInfo
       
   816 
       
   817     return info;
       
   818     } 
       
   819 
       
   820 
       
   821 // -----------------------------------------------------------------------------
       
   822 // CScpPresenceHandler::HandleContextStateEvent
       
   823 // Handles the XIMP context state events
       
   824 // -----------------------------------------------------------------------------
       
   825 //
       
   826 void CScpPresenceHandler::HandleContextStateEvent( const MXIMPBase& aEvent )
       
   827     {
       
   828     const MXIMPContextStateEvent* event =
       
   829     TXIMPGetInterface< const MXIMPContextStateEvent >::From( aEvent, MXIMPBase::EPanicIfUnknown );
       
   830 
       
   831     MXIMPContextState::TState ctxState = event->ContextState().ContextState();
       
   832     SCPLOGSTRING2( "CScpPresenceHandler: MXIMPContextStateEvent: %d", (TInt)ctxState );
       
   833     
       
   834     const MXIMPStatus* status = event->StateChangeReason();
       
   835     if ( status )
       
   836         {
       
   837         iLastXimpError = status->ResultCode();
       
   838         }
       
   839     SCPLOGSTRING2( "CScpPresenceHandler -> context ximp error: %d", iLastXimpError );
       
   840         
       
   841     // Go through the reqid array to see, if unbind has been requested
       
   842     TBool unBindRequested( EFalse );
       
   843     for ( TInt i = 0; i < iReqIdArray.Count(); i++ )
       
   844         {
       
   845         if ( iReqIdArray[i].Type() == EUnBindReq )
       
   846             {
       
   847             unBindRequested = ETrue;
       
   848             }
       
   849         }
       
   850     
       
   851     if ( ctxState == MXIMPContextState::EInactive && 
       
   852         iReqIdArray.Count() > 0 &&
       
   853         !unBindRequested )
       
   854         {
       
   855         //Unbind was not requested, but EInactive state event received => try forced unbind
       
   856         TRAPD( binderr, HandleDeregistrationL( EFalse ) );
       
   857         SCPLOGSTRING2( "CScpPresenceHandler::HandleContextStateEvent: Unbind err:%d", binderr );
       
   858         if ( KErrNone != binderr )
       
   859             {
       
   860             DeregisterNow();
       
   861             }
       
   862         }
       
   863     }
       
   864 
       
   865 
       
   866 // -----------------------------------------------------------------------------
       
   867 // CScpPresenceHandler::HandleRequestCompleteEvent
       
   868 // Handles the XIMP request complete events
       
   869 // -----------------------------------------------------------------------------
       
   870 //
       
   871 void CScpPresenceHandler::HandleRequestCompleteEvent( const MXIMPBase& aEvent )
       
   872     {
       
   873     SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent event MximpRequestCompleteEvent" );
       
   874     const MXIMPRequestCompleteEvent* event =
       
   875         TXIMPGetInterface< const MXIMPRequestCompleteEvent >::From( aEvent, MXIMPBase::EPanicIfUnknown );
       
   876 
       
   877     const TXIMPRequestId& reqId = event->RequestId();
       
   878     const MXIMPStatus& status = event->CompletionResult();
       
   879     if ( &status )
       
   880         {
       
   881         iLastXimpError = status.ResultCode();
       
   882         }
       
   883     SCPLOGSTRING2( "CScpPresenceHandler -> request ximp error: %d", iLastXimpError );
       
   884        
       
   885     if ( iLastXimpError == KXIMPErrServicRequestTimeouted )
       
   886         {
       
   887         iSubService.HandleConnectionEvent( EScpRegistrationFailed );
       
   888         }
       
   889     
       
   890     // Find the reqId from the reqid array and store it's type
       
   891     TInt index( KErrNotFound );
       
   892     TScpReqType reqType( EUnknownReq );
       
   893     for ( TInt i = 0; i < iReqIdArray.Count(); i++ )
       
   894         {
       
   895         if ( iReqIdArray[i].ReqId() == reqId )
       
   896             {
       
   897             index = i;
       
   898             reqType = iReqIdArray[i].Type();
       
   899             }
       
   900         }
       
   901     
       
   902     if ( index != KErrNotFound )
       
   903         {
       
   904         iReqIdArray.Remove( index );             
       
   905         }
       
   906     
       
   907     SCPLOGSTRING2( "CScpPresenceHandler -> request type: %d", reqType );
       
   908 
       
   909     // Bind complete event
       
   910     if ( ( reqType == EBindReq ) &&
       
   911         ( EBinding == iPresenceState ) &&
       
   912         ( iLastXimpError == KErrNone ) )
       
   913         {
       
   914         HandleBindCompleteEvent();
       
   915         }
       
   916     // Published online request complete
       
   917     else if ( ( reqType == EPublishOnlineReq ) && 
       
   918         ( iLastXimpError == KErrNone ) )
       
   919         {
       
   920         TRAP_IGNORE( SubscribePresentityGroupL() );
       
   921         iPresenceState = ESubscribing;
       
   922         }
       
   923     
       
   924     else if ( ( reqType == ESubscribeReq ) &&
       
   925         ( iLastXimpError == KErrNone ) )
       
   926         {
       
   927         // Set subservice enabled after subscribe is successfully done
       
   928         iPresenceState = EPresenceOnline;
       
   929         iSubService.HandleConnectionEvent( EScpRegistered );
       
   930         }
       
   931     
       
   932     // Published offline request complete
       
   933     else if ( reqType == EPublishOfflineReq )
       
   934         {
       
   935         SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent status offline Unbind now" );
       
   936         TRAPD( err, ServerUnBindL() );
       
   937         // Deregistration ongoing, so if unbind fails, deregisterNow is called
       
   938         if ( err )
       
   939             {
       
   940             DeregisterNow();
       
   941             SCPLOGSTRING2( "CScpPresenceHandler::HandleRequestCompleteEvent status offline Unbind now end, err %d", err );
       
   942             }
       
   943         }
       
   944     
       
   945     // Unbind request complete
       
   946     else if ( reqType == EUnBindReq && EUnBinding == iPresenceState )
       
   947         {
       
   948         SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent status offline" );
       
   949         // Do not send info to our client if roaming is ongoing 
       
   950         if ( !iNetworkLostRoamingOngoing )
       
   951             {
       
   952             if ( !iSubService.IsRoaming() )
       
   953                 {
       
   954                 DeregisterNow();
       
   955                 }
       
   956             else
       
   957                 {
       
   958                 // Inform SIP to start ALR migration
       
   959                 iSubService.ProfileHandler().StartAlrMigration(
       
   960                     iSubService.SipProfileId() );
       
   961                 }
       
   962             }
       
   963         SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent status offline end" );
       
   964         }
       
   965     
       
   966     if ( iRebind )
       
   967         {
       
   968          TRAPD( err, ServerBindL() );
       
   969          iRebind = EFalse;
       
   970          SCPLOGSTRING2( "CScpPresenceHandler - ServerBindL failed: %d", err );
       
   971          
       
   972          if ( KErrAlreadyExists == err )
       
   973              {
       
   974              iRebind = ETrue;
       
   975              }
       
   976         }
       
   977     
       
   978     if ( iDisableAfterXimpRequestsCompleted && !iReqIdArray.Count() )
       
   979         {
       
   980         iDisableAfterXimpRequestsCompleted = EFalse;
       
   981         DeregisterNow();
       
   982         }
       
   983     
       
   984     SCPLOGSTRING( "CScpPresenceHandler::HandleRequestCompleteEvent OUT" ); 
       
   985     }
       
   986 
       
   987 
       
   988 // -----------------------------------------------------------------------------
       
   989 // CScpPresenceHandler::HandleBindCompleteEvent
       
   990 // Handles the bind complete event
       
   991 // -----------------------------------------------------------------------------
       
   992 //
       
   993 void CScpPresenceHandler::HandleBindCompleteEvent()
       
   994     {
       
   995     SCPLOGSTRING( "CScpPresenceHandler::HandleBindCompleteEvent" );
       
   996     
       
   997     iPresenceState = EBindComplete;
       
   998     
       
   999     TInt err( KErrNone );
       
  1000     CScpSubService* voipSubService = GetVoipSubService();
       
  1001     if ( voipSubService )
       
  1002         {
       
  1003         if ( voipSubService->State() == ECCHEnabled &&
       
  1004             voipSubService->LastReportedError() == KErrNone )
       
  1005             {
       
  1006             SCPLOGSTRING( "CScpPresenceHandler::HandleBindCompleteEvent PublishOnline");
       
  1007             TRAP( err, PublishPresenceL( ETrue ) );
       
  1008             }
       
  1009         else
       
  1010             {
       
  1011             SCPLOGSTRING( "CScpPresenceHandler::HandleBindCompleteEvent PublishOffline");
       
  1012             TRAP( err, PublishPresenceL( EFalse ) );
       
  1013             }
       
  1014         }
       
  1015     else
       
  1016         {
       
  1017         SCPLOGSTRING( "CScpPresenceHandler::HandleBindCompleteEvent PublishOffline, no VoIP");
       
  1018         TRAP( err, PublishPresenceL( EFalse ) );
       
  1019         err = KErrNotFound;
       
  1020         }
       
  1021      
       
  1022     if ( err )
       
  1023         {
       
  1024         SCPLOGSTRING2( "CScpPresenceHandler::HandleBindCompleteEvent err %d", err );
       
  1025         }   
       
  1026     }
       
  1027 
       
  1028 
       
  1029 // -----------------------------------------------------------------------------
       
  1030 // CScpPresenceHandler::SubscribePresentityGroupL
       
  1031 // 
       
  1032 // -----------------------------------------------------------------------------
       
  1033 //
       
  1034 void CScpPresenceHandler::SubscribePresentityGroupL()
       
  1035     {
       
  1036     SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL subsribe buddies" );
       
  1037     MXIMPObjectFactory& objFactoryFromXIMP = iPresenceCtx->ObjectFactory();
       
  1038     
       
  1039     //First we have to make identity
       
  1040     SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL create buddy list identity" );
       
  1041     MXIMPIdentity* groupIdentity = objFactoryFromXIMP.NewIdentityLC();
       
  1042     groupIdentity->SetIdentityL( _L("buddylist") ); // NEEDS TO BE DEFINED IN XIMP API
       
  1043     
       
  1044     SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL subsribe group content" );
       
  1045     TScpReqId reqId;
       
  1046 
       
  1047     reqId.SetType( ESubscribeReq );
       
  1048     reqId.SetId( iFeature->PresentityGroups().SubscribePresentityGroupContentL(
       
  1049         *groupIdentity ) );
       
  1050     SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL append req to array" );
       
  1051     iReqIdArray.Append( reqId );
       
  1052 
       
  1053     SCPLOGSTRING( "CScpPresenceHandler::SubscribePresentityGroupL subsribe group content ok" );
       
  1054     CleanupStack::PopAndDestroy( 1 ); // groupIdentity
       
  1055     }
       
  1056 
       
  1057 
       
  1058 // -----------------------------------------------------------------------------
       
  1059 // CScpPresenceHandler::UnsubscribePresentityGroupL
       
  1060 // 
       
  1061 // -----------------------------------------------------------------------------
       
  1062 //
       
  1063 void CScpPresenceHandler::UnsubscribePresentityGroupL()
       
  1064     {
       
  1065     MXIMPObjectFactory& objFactoryFromXIMP = iPresenceCtx->ObjectFactory();
       
  1066     
       
  1067     //First we have to make identity
       
  1068     MXIMPIdentity* groupIdentity = objFactoryFromXIMP.NewIdentityLC();
       
  1069     groupIdentity->SetIdentityL( _L("buddylist") ); // NEEDS TO BE DEFINED IN XIMP API
       
  1070     
       
  1071     TScpReqId reqId;
       
  1072     // Set type to Unknown, because we don't need to handle the
       
  1073     // request complete event
       
  1074     reqId.SetType( EUnknownReq );
       
  1075     reqId.SetId( iFeature->PresentityGroups().UnsubscribePresentityGroupContentL(
       
  1076         *groupIdentity ) );
       
  1077     iReqIdArray.Append( reqId );
       
  1078     
       
  1079     CleanupStack::PopAndDestroy( 1 );
       
  1080     }
       
  1081 
       
  1082 // -----------------------------------------------------------------------------
       
  1083 // CScpPresenceHandler::GetStoredPresenceValuesL
       
  1084 // 
       
  1085 // -----------------------------------------------------------------------------
       
  1086 //
       
  1087 void CScpPresenceHandler::GetStoredPresenceValuesL( TInt& aAvailabilityEnum, RBuf& aCustomMessage )
       
  1088     {
       
  1089     MVIMPSTSettingsStore* settings = CVIMPSTSettingsStore::NewLC();
       
  1090         
       
  1091     TInt serviceId = iSubService.SubServiceId();
       
  1092     RBuf8 documentId;
       
  1093     CleanupClosePushL( documentId );
       
  1094     documentId.CreateL( KBufSize255 );
       
  1095     TInt error = settings->GetL( 
       
  1096         serviceId, EServicePresenceSessionIdentifier, documentId );
       
  1097     TInt i = documentId.Length();
       
  1098     TInt err1(0);
       
  1099     TInt err2(0);
       
  1100     
       
  1101     if( documentId.Length() )
       
  1102         {
       
  1103         err1 = settings->GetL( 
       
  1104             serviceId, EServicePresenceAvailablilityValue, aAvailabilityEnum );
       
  1105         err2 = settings->GetL( 
       
  1106             serviceId, EServiceCustomStatusMessage, aCustomMessage );
       
  1107         
       
  1108         // if other GetL fails -> clear both
       
  1109         if( err1 || err2 )
       
  1110             {
       
  1111             aAvailabilityEnum = KErrNotFound;
       
  1112             aCustomMessage.Zero();
       
  1113             }
       
  1114         }   
       
  1115     else 
       
  1116         {
       
  1117         aAvailabilityEnum = KErrNotFound;
       
  1118         }
       
  1119 
       
  1120     CleanupStack::PopAndDestroy( &documentId );
       
  1121     CleanupStack::PopAndDestroy(); //settings
       
  1122     }
       
  1123 
       
  1124 //  End of File