voipplugins/sipconnectionprovider/src/scpservice.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 15 Mar 2010 12:39:55 +0200
branchRCL_3
changeset 11 bddb6d4447db
parent 0 a4daefaec16c
permissions -rw-r--r--
Revision: 201009 Kit: 201010

/*
* 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