diff -r 000000000000 -r a4daefaec16c voipplugins/sipconnectionprovider/src/scpservice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/voipplugins/sipconnectionprovider/src/scpservice.cpp Mon Jan 18 20:12:36 2010 +0200 @@ -0,0 +1,636 @@ +/* +* Copyright (c) 2005-2007 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: +* +*/ + + +#include + +#include "scpservice.h" +#include "scpsubservice.h" +#include "scplogger.h" +#include "scputility.h" +#include "scpprofilehandler.h" + +// ----------------------------------------------------------------------------- +// CScpService::CScpService +// ----------------------------------------------------------------------------- +// +CScpService::CScpService( TInt aId, + TInt aServiceId, + CScpProfileHandler& aProfileHandler, + CScpServiceStorage& aServiceStorage, + MCchServiceObserver& aServiceObserver ) : + iId( aId ), + iServiceId( aServiceId ), + iProfileHandler( aProfileHandler ), + iServiceStorage( aServiceStorage ), + iServiceObserver( aServiceObserver ) + { + } + +// ----------------------------------------------------------------------------- +// CScpService::~CScpService +// ----------------------------------------------------------------------------- +// +CScpService::~CScpService() + { + SCPLOGSTRING2( "CScpService[0x%x]::~CScpService", this ); + + iSubServices.ResetAndDestroy(); + iSubServices.Close(); + } + +// ----------------------------------------------------------------------------- +// CScpService::NewL +// ----------------------------------------------------------------------------- +// +CScpService* CScpService::NewL( TInt aId, + TInt aServiceId, + CScpProfileHandler& aProfileHandler, + CScpServiceStorage& aServiceStorage, + MCchServiceObserver& aServiceObserver ) + { + SCPLOGSTRING3( "CScpService::NewL id: %d service id: %d", aId, aServiceId ); + + CScpService* self = new (ELeave) CScpService( aId, + aServiceId, + aProfileHandler, + aServiceStorage, + aServiceObserver ); + return self; + } + +// ----------------------------------------------------------------------------- +// CScpService::Id +// ----------------------------------------------------------------------------- +// +TInt CScpService::Id() const + { + SCPLOGSTRING2( "CScpService[0x%x]::Id", this ); + + return iId; + } + +// ----------------------------------------------------------------------------- +// CScpService::ProfileHandler +// ----------------------------------------------------------------------------- +// +CScpProfileHandler& CScpService::ProfileHandler() const + { + return iProfileHandler; + } + +// ----------------------------------------------------------------------------- +// CScpService::ServiceStorage +// ----------------------------------------------------------------------------- +// +CScpServiceStorage& CScpService::ServiceStorage() const + { + return iServiceStorage; + } + +// ----------------------------------------------------------------------------- +// CScpService::ServiceObserver +// ----------------------------------------------------------------------------- +// +MCchServiceObserver& CScpService::ServiceObserver() const + { + return iServiceObserver; + } + +// ----------------------------------------------------------------------------- +// CScpService::AddSubServiceL +// ----------------------------------------------------------------------------- +// +CScpSubService& + CScpService::AddSubServiceL( TCCHSubserviceType aSubServiceType ) + { + SCPLOGSTRING2( "CScpService[0x%x]::AddSubServiceL", this ); + + TInt newId = GenerateNewSubServiceId(); + CScpSubService* service = CScpSubService::NewL( newId, + ServiceId(), + aSubServiceType, + *this ); + CleanupStack::PushL( service ); + iSubServices.AppendL( service ); + CleanupStack::Pop( service ); + + return *iSubServices[ iSubServices.Count() - 1 ]; + } + +// ----------------------------------------------------------------------------- +// CScpService::SubServiceCount +// ----------------------------------------------------------------------------- +// +TInt CScpService::SubServiceCount() const + { + SCPLOGSTRING2( "CScpService[0x%x]::SubServiceCount", this ); + + return iSubServices.Count(); + } + +// ----------------------------------------------------------------------------- +// CScpService::GenerateNewSubServiceId +// ----------------------------------------------------------------------------- +// +TInt CScpService::GenerateNewSubServiceId() + { + SCPLOGSTRING2( "CScpService[0x%x]::GenerateNewSubServiceId", this ); + + iSubServiceIdCounter++; + + return iId + iSubServiceIdCounter; + } + +// ----------------------------------------------------------------------------- +// CScpService::GetSubServiceIds +// ----------------------------------------------------------------------------- +// +void CScpService::GetSubServiceIds( RArray& aIds ) const + { + SCPLOGSTRING2( "CScpService[0x%x]::GetSubServiceIds", this ); + __ASSERT_DEBUG( aIds.Count() == 0, User::Panic( KNullDesC, KErrGeneral ) ); + + for( TInt i=0; iId() ); + } + } + +// ----------------------------------------------------------------------------- +// CScpService::GetSubService +// ----------------------------------------------------------------------------- +// +CScpSubService* CScpService::GetSubService( TInt aId ) const + { + SCPLOGSTRING3( "CScpService[0x%x]::GetSubService id: %d", this, aId ); + + for( TInt i=0; i(this); + CScpSubService* subService = self->iSubServices[ i ]; + if( aId == subService->Id() ) + { + return subService; + } + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// CScpService::RemoveSubService +// ----------------------------------------------------------------------------- +// +TInt CScpService::RemoveSubService( TInt aId ) + { + SCPLOGSTRING3( "CScpService[0x%x]::RemoveSubService id: %d", this, aId ); + + for( TInt i=0; iId() ) + { + delete subService; + iSubServices.Remove( i ); + return KErrNone; + } + } + + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CScpService::ServiceId +// ----------------------------------------------------------------------------- +// +TInt CScpService::ServiceId() const + { + SCPLOGSTRING2( "CScpService[0x%x]::ServiceId", this ); + + return iServiceId; + } + +// ----------------------------------------------------------------------------- +// CScpService::SetServiceId +// ----------------------------------------------------------------------------- +// +void CScpService::SetServiceId( TInt aServiceId ) + { + SCPLOGSTRING3( "CScpService[0x%x]::SetServiceId service id: %d", + this, aServiceId ); + + iServiceId = aServiceId; + } + +// ----------------------------------------------------------------------------- +// CScpService::State +// ----------------------------------------------------------------------------- +// +TInt CScpService::State( TCCHSubserviceType aSubServiceType, + TCCHSubserviceState& aState ) const + { + SCPLOGSTRING2( "CScpService[0x%x]::State", this ); + + TInt result = KErrNone; + + if( ECCHUnknown == aSubServiceType ) + { + TCCHSubserviceState state( ECCHUninitialized ); + + // Return other than unknown state if all the subservices are in same state + for ( TInt i=0; iState(); + result = subService->LastReportedError(); + } + else + { + if ( state != subService->State() || + result != subService->LastReportedError() ) + { + // Sub services are in different states or have + // different error codes + SCPLOGSTRING( "Query failed: different states or error codes" ); + + state = ECCHUninitialized; + result = KErrUnknown; + break; + } + } + } + + aState = state; + } + else + { + CScpSubService* subService = GetSubServiceByType( aSubServiceType ); + + if( subService ) + { + aState = subService->State(); + result = subService->LastReportedError(); + } + else + { + result = KErrNotFound; + } + } + + SCPLOGSTRING3( "State: %d error: %d", aState, result ); + return result; + } + +// ----------------------------------------------------------------------------- +// CScpService::GetSubServiceByType +// ----------------------------------------------------------------------------- +// +CScpSubService* CScpService::GetSubServiceByType( TCCHSubserviceType aSubServiceType ) const + { + SCPLOGSTRING3( "CScpService[0x%x]::GetSubService type: %d", + this, aSubServiceType ); + + for( TInt i=0; iSubServiceType() == aSubServiceType ) + { + return subService; + } + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// CScpService::ContainsSubServiceType +// ----------------------------------------------------------------------------- +// +TBool CScpService::ContainsSubServiceType( TCCHSubserviceType aSubServiceType ) const + { + SCPLOGSTRING3( "CScpService[0x%x]::ContainsSubServiceType type: %d", + this, aSubServiceType ); + + for( TInt i=0; iSubServiceType() == aSubServiceType ) + { + return ETrue; + } + } + + return EFalse; + } + + +// ----------------------------------------------------------------------------- +// CScpService::SubServicesContainSameSipProfile +// ----------------------------------------------------------------------------- +// +TBool CScpService::SubServicesContainSameSipProfile() const + { + SCPLOGSTRING2( "CScpService[0x%x]::SubServicesContainSameSipProfile", this ); + + TInt sipProfileId( 0 ); + + for( TInt i=0; iSipProfileId(); + + if( oldSipProfileId != 0 && + sipProfileId != oldSipProfileId ) + { + return EFalse; + } + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CScpService::SetReserved +// ----------------------------------------------------------------------------- +// +TInt CScpService::SetReserved( TBool aReserved, + TCCHSubserviceType aSubServiceType ) + { + SCPLOGSTRING4( "CScpService[0x%x]::SetReserved: %d type: %d", + this, aSubServiceType, aReserved ); + + TInt result = KErrNone; + + if( aSubServiceType != ECCHUnknown ) + { + CScpSubService* subService = GetSubServiceByType( aSubServiceType ); + + if( subService ) + { + // If reserving the sub service must be enabled. + // It is always possible to free the service + if( subService->State() == ECCHEnabled || + aReserved == EFalse ) + { + subService->SetReserved( aReserved ); + } + else + { + result = KErrNotSupported; + } + } + else + { + result = KErrNotFound; + } + } + else + { + for( TInt i=0; iState() == ECCHEnabled || + aReserved == EFalse ) + { + subService->SetReserved( aReserved ); + } + else + { + result = KErrNotSupported; + } + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CScpService::IsReserved +// ----------------------------------------------------------------------------- +// +TBool CScpService::IsReserved( TCCHSubserviceType aSubServiceType ) const + { + SCPLOGSTRING3( "CScpService[0x%x]::IsReserved: type: %d", + this, aSubServiceType ); + + TBool result = EFalse; + + if( aSubServiceType == ECCHUnknown ) + { + for( TInt i=0; iIsReserved(); + + if( reserved ) + { + result = ETrue; + break; + } + } + } + else + { + CScpSubService* subService = GetSubServiceByType( aSubServiceType ); + + if( subService ) + { + result = subService->IsReserved(); + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CScpService::SetAccessPointId +// ----------------------------------------------------------------------------- +// +TInt CScpService::SetAccessPointId( TCCHSubserviceType aSubServiceType, + TScpAccessPointType aAccessPointType, + TInt aAccessPointId ) + { + SCPLOGSTRING4( "CScpService[0x%x]::SetAccessPointId: type: %d id: %d", + this, aSubServiceType, aAccessPointId ); + __ASSERT_DEBUG( iSubServices.Count() > 0, User::Panic( KNullDesC, KErrGeneral ) ); + + TInt result = KErrNotFound; + + if( IsAccessPointModifiable( aSubServiceType ) ) + { + TBool sipConnectionCreated = EFalse; + CScpSipConnection* sipConnection = GetSipConnection( aSubServiceType, + sipConnectionCreated ); + if( sipConnection ) + { + switch ( aAccessPointType ) + { + case EScpIap: + { + result = sipConnection->SetIap( aAccessPointId ); + } + break; + + case EScpSnap: + { + result = sipConnection->SetSnap( aAccessPointId ); + } + break; + + default: + break; + + } + + if( sipConnectionCreated ) + { + delete sipConnection; + } + } + } + else + { + result = KErrNotSupported; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CScpService::IsAccessPointModifiable +// ----------------------------------------------------------------------------- +// +TBool CScpService::IsAccessPointModifiable( TCCHSubserviceType aSubServiceType ) const + { + SCPLOGSTRING3( "CScpService[0x%x]::IsAccessPointModifiable: type: %d", + this, aSubServiceType ); + + TBool modifiable = EFalse; + + TCCHSubserviceState state = ECCHUninitialized; + + TInt error = State( aSubServiceType, state ); + + if( state == ECCHDisabled || ( state == ECCHConnecting && error != KErrNone ) ) + + { + if( !IsReserved( aSubServiceType ) ) + { + // We can't set any valid access point values if different + // sip profiles are in use + if( aSubServiceType != ECCHUnknown || ( aSubServiceType == ECCHUnknown && + SubServicesContainSameSipProfile() ) ) + { + modifiable = ETrue; + } + } + } + + return modifiable; + } + +// ----------------------------------------------------------------------------- +// CScpService::GetSipConnection +// ----------------------------------------------------------------------------- +// +CScpSipConnection* CScpService::GetSipConnection( TCCHSubserviceType aSubServiceType, + TBool& aSipConnectionCreated ) + { + SCPLOGSTRING3( "CScpService[0x%x]::GetSipConnection: type: %d", + this, aSubServiceType ); + + CScpSipConnection* sipConnection = NULL; + CScpSubService* subService = NULL; + + if( aSubServiceType == ECCHUnknown && iSubServices.Count() > 0 ) + { + subService = iSubServices[0]; + } + else + { + subService = GetSubServiceByType( aSubServiceType ); + } + + if( subService ) + { + TInt sipProfileId = subService->SipProfileId(); + + if( iProfileHandler.ProfileExists( sipProfileId ) ) + { + if( iProfileHandler.SipConnectionExists( sipProfileId ) ) + { + sipConnection = iProfileHandler.GetSipConnection( sipProfileId ); + } + else + { + aSipConnectionCreated = ETrue; + TRAP_IGNORE( sipConnection = + iProfileHandler.CreateSipConnectionL( sipProfileId ) ); + } + } + } + + return sipConnection; + } + +// ----------------------------------------------------------------------------- +// CScpService::IsAllSubservicesDisabled +// ----------------------------------------------------------------------------- +// +TBool CScpService::IsAllSubservicesDisabled() const + { + TBool response( ETrue ); + + for ( TInt i( 0 ); i < iSubServices.Count() && response; i++ ) + { + SCPLOGSTRING3( "CScpService[0x%x]::IsAllSubservicesDisabled: state: %d", + this, iSubServices[ i ]->State() ); + if ( ECCHDisabled != iSubServices[ i ]->State() ) + { + response = EFalse; + } + } + + return response; + } + +// ----------------------------------------------------------------------------- +// CScpService::ChangeLastReportedErrors +// ----------------------------------------------------------------------------- +// +void CScpService::ChangeLastReportedErrors( + const TInt aError ) + { + for ( TInt i( 0 ); i < iSubServices.Count(); i++ ) + { + iSubServices[ i ]->SetLastReportedError( aError ); + } + } + +// End of file