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