voipplugins/sipconnectionprovider/src/scpservice.cpp
branchRCL_3
changeset 22 d38647835c2e
parent 0 a4daefaec16c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/voipplugins/sipconnectionprovider/src/scpservice.cpp	Wed Sep 01 12:29:57 2010 +0100
@@ -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