--- /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 <cchserviceobserver.h>
+
+#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<TInt>& aIds ) const
+ {
+ SCPLOGSTRING2( "CScpService[0x%x]::GetSubServiceIds", this );
+ __ASSERT_DEBUG( aIds.Count() == 0, User::Panic( KNullDesC, KErrGeneral ) );
+
+ for( TInt i=0; i<iSubServices.Count(); i++)
+ {
+ const CScpSubService* subService = iSubServices[ i ];
+
+ aIds.Append( subService->Id() );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CScpService::GetSubService
+// -----------------------------------------------------------------------------
+//
+CScpSubService* CScpService::GetSubService( TInt aId ) const
+ {
+ SCPLOGSTRING3( "CScpService[0x%x]::GetSubService id: %d", this, aId );
+
+ for( TInt i=0; i<iSubServices.Count(); i++)
+ {
+ CScpService* self = const_cast<CScpService*>(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; i<iSubServices.Count(); i++)
+ {
+ CScpSubService* subService = iSubServices[ i ];
+ if( aId == subService->Id() )
+ {
+ 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; i<iSubServices.Count(); i++ )
+ {
+ const CScpSubService* subService = iSubServices[i];
+
+ if( state == ECCHUninitialized )
+ {
+ state = subService->State();
+ 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; i<iSubServices.Count(); i++)
+ {
+ CScpSubService* subService = iSubServices[ i ];
+ if( subService->SubServiceType() == 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; i<iSubServices.Count(); i++)
+ {
+ CScpSubService* subService = iSubServices[ i ];
+ if( subService->SubServiceType() == aSubServiceType )
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CScpService::SubServicesContainSameSipProfile
+// -----------------------------------------------------------------------------
+//
+TBool CScpService::SubServicesContainSameSipProfile() const
+ {
+ SCPLOGSTRING2( "CScpService[0x%x]::SubServicesContainSameSipProfile", this );
+
+ TInt sipProfileId( 0 );
+
+ for( TInt i=0; i<iSubServices.Count(); i++)
+ {
+ TInt oldSipProfileId = sipProfileId;
+
+ const CScpSubService* subService = iSubServices[ i ];
+ sipProfileId = subService->SipProfileId();
+
+ 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; i<iSubServices.Count(); i++)
+ {
+ CScpSubService* subService = iSubServices[ i ];
+
+ // 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;
+ }
+ }
+ }
+
+ 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; i<iSubServices.Count(); i++)
+ {
+ CScpSubService* subService = iSubServices[ i ];
+
+ TBool reserved = subService->IsReserved();
+
+ 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