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