diff -r f742655b05bf -r d38647835c2e voipplugins/sipconnectionprovider/src/scpvmbxhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/voipplugins/sipconnectionprovider/src/scpvmbxhandler.cpp Wed Sep 01 12:29:57 2010 +0100 @@ -0,0 +1,416 @@ +/* +* 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: Vmbx handler. +* +*/ + + +#include "ipvmbxinterface.h" +#include "scpvmbxhandler.h" +#include "scplogger.h" +#include "scpservice.h" +#include "scpsubservice.h" +#include "scpservicestorage.h" +#include "scputility.h" +#include "scpsipconnection.h" +#include "scpprofilehandler.h" + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::CCScpVmbxHandler +// ----------------------------------------------------------------------------- +// +CScpVmbxHandler::CScpVmbxHandler( CScpSubService& aSubService ) : + CScpServiceHandlerBase( aSubService ) + { + SCPLOGSTRING2( "CScpVmbxHandler[0x%x]::CScpVmbxHandler", this ); + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::ConstructL +// ----------------------------------------------------------------------------- +// +void CScpVmbxHandler::ConstructL() + { + SCPLOGSTRING2( "CScpVmbxHandler[0x%x]::ConstructL", this ); + + BaseConstructL(); + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::NewL +// ----------------------------------------------------------------------------- +// +CScpVmbxHandler* CScpVmbxHandler::NewL( CScpSubService& aSubService ) + { + SCPLOGSTRING( "CScpVmbxHandler::NewL" ); + + CScpVmbxHandler* self = new(ELeave) CScpVmbxHandler( aSubService ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::~CScpVmbxHandler +// ----------------------------------------------------------------------------- +// +CScpVmbxHandler::~CScpVmbxHandler() + { + SCPLOGSTRING2( "CScpVmbxHandler[0x%x]::~CScpVmbxHandler", this ); + + if ( !IsAnotherVmbxSubServiceAlreadyEnabled() ) + { + iSubService.ProfileHandler().DeleteVmbxInterface(); + } + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::EnableSubServiceL +// ----------------------------------------------------------------------------- +// +void CScpVmbxHandler::EnableSubServiceL() + { + SCPLOGSTRING4( "CScpVmbxHandler[0x%x]::EnableSubServiceL: 0x%x type: %i", + this, &iSubService, iSubService.SubServiceType() ); + __ASSERT_DEBUG( iSubService.SubServiceType() == ECCHVMBxSub, + User::Panic( KNullDesC, KErrGeneral ) ); + + // Only one enabled vmbx service is allowed at a time. + if( IsAnotherVmbxSubServiceAlreadyEnabled() ) + { + User::Leave( KErrInUse ); + } + + CScpServiceHandlerBase::RegisterProfileL(); + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::IsAnotherVmbxSubServiceAlreadyEnabled +// ----------------------------------------------------------------------------- +// +TBool CScpVmbxHandler::IsAnotherVmbxSubServiceAlreadyEnabled() const + { + SCPLOGSTRING2( "CScpVmbxHandler[0x%x]::IsAnotherVmbxSubServiceAlreadyEnabled", this ); + + TBool result = EFalse; + + CScpServiceStorage& storage = iSubService.ServiceStorage(); + RArray ids; + + storage.GetSubServiceIds( ECCHVMBxSub, ids ); + + TInt count( ids.Count() ); + + for ( TInt i( 0 ); i < count; i++ ) + { + CScpSubService* subService = storage.GetSubService( ids[i] ); + + if ( subService && ECCHDisabled != subService->State() ) + { + result = ETrue; + break; + } + } + + ids.Close(); + return result; + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::DisableSubService +// ----------------------------------------------------------------------------- +// +TInt CScpVmbxHandler::DisableSubService() + { + SCPLOGSTRING4( "CScpVmbxHandler[0x%x]::DisableSubService: 0x%x type: %i", + this, &iSubService, iSubService.SubServiceType() ); + __ASSERT_DEBUG( iSubService.SubServiceType() == ECCHVMBxSub, + User::Panic( KNullDesC, KErrGeneral ) ); + + TInt result = KErrNone; + + if( iSubService.State() != ECCHDisabled ) + { + TRAP( result, UnsubscribeL() ); + + if( result == KErrNone ) + { + // Deregister if still connecting and subscribed message + // not yet received + if( iSubService.State() == ECCHConnecting ) + { + DeregisterProfile(); + } + else + { + StartForcedDisableTimer( CScpVmbxHandler::ForceVmbxServiceDisable ); + } + } + else + { + DeregisterProfile(); + } + } + else + { + result = KErrNotSupported; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::UnsubscribeL +// ----------------------------------------------------------------------------- +// +void CScpVmbxHandler::UnsubscribeL() + { + SCPLOGSTRING2( "CScpVmbxHandler[0x%x]::UnsubscribeL", this ); + + CScpProfileHandler& profileHandler = iSubService.ProfileHandler(); + + // Unsubscribe is not called when refreshing the connection + if( iSubService.EnableRequestedState() != CScpSubService::EScpRefreshed ) + { + CIpVmbxInterface& vmbxInterface = profileHandler.VmbxInterfaceL( *this ); + vmbxInterface.UnsubscribeL( iSubService.SubServiceId() ); + } + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::HandleMessage +// ----------------------------------------------------------------------------- +// +void CScpVmbxHandler::HandleMessage( TUint32 aServiceId, TVmbxMessage aMessage ) + { + SCPLOGSTRING4( "CScpVmbxHandler[0x%x]::HandleMessage: id: %d message: %d", + this, aServiceId, aMessage ); + + TInt result = KErrNone; + + if( iSubService.SubServiceId() == aServiceId ) + { + switch( aMessage ) + { + case ESubscribed: + { + iSubService.HandleConnectionEvent( EScpRegistered ); + } + break; + + case EUnsubscribed: + { + // Check if disable was requested + if( iSubService.EnableRequestedState() == CScpSubService::EScpDisabled ) + { + CancelDisableTimer(); + DeregisterProfile(); + } + else + { + if ( iResubscribe ) + { + iResubscribe = EFalse; + TRAP( result, SubscribeL() ) + SCPLOGSTRING2( "Subscribe result: %d", result ); + + if( result == KErrNone ) + { + // Still connecting the service + iSubService.HandleConnectionEvent( EScpNetworkFound ); + } + else if ( KErrAlreadyExists == result ) + { + iSubService.HandleConnectionEvent( EScpRegistrationPending ); + } + else + { + iSubService.HandleConnectionEvent( EScpRegistrationFailed ); + } + } + else + { + // Connection to VMBx server lost + iSubService.HandleConnectionEvent( EScpDeregistered ); + } + } + } + break; + + case ENetworkError: + { + // Network lost errors may have already been reported + if( iSubService.LastReportedError() == KErrNone ) + { + // Connection to VMBx server lost + iSubService.HandleConnectionEvent( EScpRegistrationFailed ); + } + break; + } + + case EFatalNetworkError: + { + // In case of fatal network error forced disable is done to + // SIP profile. + PerformInstantForceSipProfileDisable(); + break; + } + + case EIncorrectSettings: + { + iSubService.HandleConnectionEvent( EScpRegistrationFailed ); + } + break; + + case ENoMemory: + case ESmsError: + { + // : + // Error handling for VMBx errors + // In network error case we should change the state to connecting + + // "service not respondig" error + SCPLOGSTRING( "Error message from VMBx interface" ) + } + break; + + default: + { + __ASSERT_DEBUG( EFalse, User::Panic( KNullDesC, KErrGeneral ) ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::SubServiceType +// ----------------------------------------------------------------------------- +// +TCCHSubserviceType CScpVmbxHandler::SubServiceType() const + { + SCPLOGSTRING2( "CScpVmbxHandler[0x%x]::SubServiceType", this ); + + return ECCHVMBxSub; + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::HandleSipConnectionEvent +// ----------------------------------------------------------------------------- +// +void CScpVmbxHandler::HandleSipConnectionEvent( TUint32 aProfileId, + TScpConnectionEvent aEvent ) + { + SCPLOGSTRING4( "CScpVmbxHandler[0x%x]::HandleSipConnectionEvent id: %d event: %d", + this, aProfileId, aEvent ); + + TInt result = KErrNone; + + if( iSubService.SipProfileId() == aProfileId && + iSubService.EnableRequestedState() != CScpSubService::EScpNoRequest ) + { + if ( EScpRoaming == aEvent ) + { + SCPLOGSTRING( "CScpVmbxHandler - EScpRoaming -> unsubscribe" ); + TRAP( result, UnsubscribeL() ); + SCPLOGSTRING2( "CScpVmbxHandler - unsubscribe error: %d", result ); + } + + if( aEvent == EScpRegistered && + iSubService.EnableRequestedState() == CScpSubService::EScpEnabled ) + { + TRAP( result, SubscribeL() ) + + SCPLOGSTRING2( "Subscribe result: %d", result ); + + if( result == KErrNone ) + { + // Still connecting the service + aEvent = EScpNetworkFound; + } + else + { + if ( iSubService.IsRoaming() && KErrAlreadyExists == result ) + { + // There's still unsubscribe ongoing, we have to wait + // ipvoicemailengine event EUnsubscribed and try to + // make subscribe again + SCPLOGSTRING( "Resubscribe later" ); + iResubscribe = ETrue; + // Still connecting the service + aEvent = EScpNetworkFound; + } + else + { + aEvent = EScpRegistrationFailed; + } + } + } + else if( aEvent == EScpDeregistered && + iSubService.EnableRequestedState() == CScpSubService::EScpDisabled || + iSubService.EnableRequestedState() == CScpSubService::EScpRefreshed ) + { + CancelDisableTimer(); + } + + iSubService.HandleConnectionEvent( aEvent ); + } + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::SubscribeL +// ----------------------------------------------------------------------------- +// +void CScpVmbxHandler::SubscribeL() + { + SCPLOGSTRING2( "CScpVmbxHandler[0x%x]::SubscribeL", this ); + + TUint32 sipProfileId = iSubService.SipProfileId(); + CScpProfileHandler& profileHandler = iSubService.ProfileHandler(); + + CScpSipConnection* sipConnection = profileHandler.GetSipConnection( sipProfileId ); + + if( sipConnection ) + { + CIpVmbxInterface& vmbxInterface = profileHandler.VmbxInterfaceL( *this ); + + // It must be possible to add observers for the vmbx interface + + vmbxInterface.SubscribeL( iSubService.SubServiceId(), + sipConnection->SipProfile() ); + } + else + { + User::LeaveIfError( KErrNotFound ); + } + } + +// ----------------------------------------------------------------------------- +// CScpVmbxHandler::ForceDisable +// ----------------------------------------------------------------------------- +// +TInt CScpVmbxHandler::ForceVmbxServiceDisable( TAny* aSelf ) + { + SCPLOGSTRING( "CScpVmbxHandler[0x%x]::ForceVmbxServiceDisable" ); + + CScpVmbxHandler* self = static_cast( aSelf ); + + self->CancelDisableTimer(); + self->DeregisterProfile(); + + return 1; + } + + +// End of File