bearermanagement/S60MCPR/src/s60tiermanagerselector.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Feb 2010 23:12:51 +0200
branchRCL_3
changeset 8 2e6c4614c58e
parent 0 5a93021fdf25
child 12 ea6e024ea6f9
permissions -rw-r--r--
Revision: 201003 Kit: 201007

/*
* Copyright (c) 2008-2009 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: S60 IP TM selector implementation
*
*/

/**
@file s60tiermanagerselector.cpp
S60 IP TM selector implementation
*/

#include <comms-infras/ss_log.h>
#include <comms-infras/ss_tiermanagerutils.h>
#include <commsdattypesv1_1.h> // CommsDat
#include <es_connpref.h>    //TConnIdList
#include <commdbconnpref.h>
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include <commsdattypeinfov1_1_internal.h>
#include <commsdattypesv1_1_partner.h> 
#endif

#include "s60tiermanagerselector.h"
#include "s60tiermanagerfactory.h"
#include "s60mcpr.h"

using namespace ESock;
using namespace CommsDat;

// -----------------------------------------------------------------------------
// IpProto Tier Manager's UID.
// Since meaning of the selection policy id changes with
// the legacy flavor it is difficult to derive the next layer
// tier's id dynamically when supporting all of the legacy scenarios.
// At the same time it is known that for all of these legacy
// setups this is and always will be the only next layer tier manager.
// -----------------------------------------------------------------------------
static const TUid KLegacyNextLayerTierId = { 0x10281DF0 }; //CIPProtoTierManagerFactory::iUid

#ifdef __CFLOG_ACTIVE
#define KS60TierMgrTag KESockMetaConnectionTag
_LIT8(KS60TierMgrSubTag, "netmcpr");
#endif

//Panic codes
#ifdef _DEBUG
_LIT(KS60SelectorPanic, "S60TMSelector");
enum TS60SelectorPanic
    {
    EExpectedAccessPointAwareSystem = 0,     //
    EUnExpectedSelectionPreferences = 1,
    };
#endif // _DEBUG

// -----------------------------------------------------------------------------
// CSimpleS60SelectorBase::CSimpleS60SelectorBase
// -----------------------------------------------------------------------------
//
CSimpleS60SelectorBase::CSimpleS60SelectorBase( const Meta::SMetaData& aSelectionPreferences )
    :    ASimpleSelectorBase( aSelectionPreferences )
    {
    }

// -----------------------------------------------------------------------------
// CSimpleS60SelectorBase::~CSimpleS60SelectorBase
// -----------------------------------------------------------------------------
//
CSimpleS60SelectorBase::~CSimpleS60SelectorBase()
    {
    }
    
// -----------------------------------------------------------------------------
// CSimpleS60SelectorBase::SelectL
// -----------------------------------------------------------------------------
//
void CSimpleS60SelectorBase::SelectL( ISelectionNotify& aSelectionNotify )
    {
    ASSERT(iDbs);
    ASSERT(iTierRecord);

    // Default access point is required as it will point the correct node UIDs for the next layer.
    iDefaultAp = iTierRecord->iDefaultAccessPoint;
    //Since we do not understand the preferences, we create a provider based on a default Access Point,
    //like in the implicit case, but we also pass the preferences down.
    __CFLOG_VAR((KS60TierMgrTag, KS60TierMgrSubTag, _L8("S60MCPR::CSimpleS60SelectorBase %08x::\tSelectL() Using Default AP:%d"),this,iDefaultAp));

    //Legacy Attach -case handling is in NetMCPR and IPProtoTM
    // 399 Attach is not supported
    const TConnPref& prefs = iSelectionPrefs.Prefs();
    iSubSessionUniqueId = iSelectionPrefs.SubSessionUniqueId();
    
    switch ( prefs.ExtensionId() )
        {
        case TConnPref::EConnPrefCommDbMulti:
            {
            // Sanity check.
            TCommDbMultiConnPref& multiPrefs = TCommDbMultiConnPref::Cast( prefs );
            TCommDbConnPref connpref;
            TInt error = multiPrefs.GetPreference( 1, connpref );
            // if bad connpref
            if ( error != KErrNone )
                {
                User::Leave( error );
                }
            //else ok. MPM handles the TConnPref parsing.
            break;
            }
        case TConnPref::EConnPrefUnknown: // same as IsEmpty() == ETrue
        case TConnPref::EConnPrefCommDb:
        case TConnPref::EConnPrefSnap:
            {
            // Supported. MPM handles the parsing.
            break;
            }
        case TConnPref::EConnPrefIdList:
        case TConnPref::EConnPrefSip:
        case TConnPref::EConnPrefProviderInfo:
        default:
            {
            // Unsupported
            User::Leave( KErrNotSupported );
            break;
            }
        }
    // We do the default behavior. AP is only needed to get proper UIds for TM etc..
    // TODO: change to use AP.
    aSelectionNotify.SelectComplete( this, FindOrCreateProviderL( iDefaultAp ));
    aSelectionNotify.SelectComplete( this, NULL );
    }
    
// -----------------------------------------------------------------------------
// CSimpleS60SelectorBase::FindOrCreateProviderL
// -----------------------------------------------------------------------------
//
CMetaConnectionProviderBase* CSimpleS60SelectorBase::FindOrCreateProviderL( TUint aAccessPoint )
    {
    ASSERT(aAccessPoint); //Should not be 0 now.

    //Find factory
    TUid mCprUid = TierManagerUtils::ReadMCprUidL( aAccessPoint, *iDbs );
    CMetaConnectionProviderFactoryBase* factory = 
        static_cast<CMetaConnectionProviderFactoryBase*>(iMetaContainer.FindOrCreateFactoryL( mCprUid ));

    //Create the provider
    TUid tierId = TUid::Uid( iTierRecord->iRecordTag );
	TProviderInfo providerInfo( tierId, aAccessPoint );
	TUid tierImplUid = TierManagerUtils::MapTierIdtoTierImplIdL(tierId,*iDbs);
    TMetaConnectionFactoryQuery query( providerInfo, tierImplUid );
    
    //We are not looking for an existing provider, we always create a new one.
    //This is the legacy selection (can also be the legacy attach, one layer deep selection)
    CMetaConnectionProviderBase* provider = static_cast<CMetaConnectionProviderBase*>( factory->CreateObjectL( query ));
    CS60MetaConnectionProvider* prov = static_cast<CS60MetaConnectionProvider*>( provider );
    
    CleanupStack::PushL( provider );
    
    // Provision selection preferences to S60 NetMCPR.
    prov->SetSelectionPrefs( iSelectionPrefs );
    prov->SetSubSessionUniqueId( iSubSessionUniqueId );

    // Change the provider info so that this provider is never found by other selections
    const TProviderInfo& pi = provider->ProviderInfo();
    provider->SetProviderInfo( TProviderInfo( pi.TierId(), pi.APId(), provider )); //This provider will never be found
    
    // Override the selection policy as we always do for legacy prefs
    ASSERT(provider->AccessPointConfig().FindExtension(TOverridenSelectionPrefsExt::TypeId())==NULL);

	RMetaExtensionContainer mec;
	mec.Open(provider->AccessPointConfig());
	CleanupClosePushL(mec);
	
    TOverridenSelectionPrefsExt* ext = new (ELeave) TOverridenSelectionPrefsExt( KLegacyNextLayerTierId, iSelectionPrefs );
    CleanupStack::PushL( ext );
    mec.AppendExtensionL( ext ); //The ownership of the extension goes to AccessPointConfig now.
    CleanupStack::Pop( ext );

	provider->AccessPointConfig().Close();
	provider->AccessPointConfig().Open(mec);
	CleanupStack::PopAndDestroy(&mec);
	
    CleanupStack::Pop( provider );
    provider->IncrementBlockingDestroy();
    return provider;
    }

// -----------------------------------------------------------------------------
// TS60ProviderSelectorFactory::NewSelectorL
// -----------------------------------------------------------------------------
//
MProviderSelector* TS60ProviderSelectorFactory::NewSelectorL(const Meta::SMetaData& aSelectionPreferences)
    {
    __CFLOG_VAR((KS60TierMgrTag, KS60TierMgrSubTag, _L8("S60MCPR::CS60ProviderSelectorBase::\tNewSelectorL()")));
    ASSERT(aSelectionPreferences.IsTypeOf(TSelectionPrefs::TypeId()));
    //const ESock::TSelectionPrefs& sp = static_cast<const ESock::TSelectionPrefs&>(aSelectionPreferences);
    ASimpleSelectorBase* self = NULL;
    CBase* selfCleanupItem = NULL;
    CMDBSession* dbs = CMDBSession::NewLC(KCDVersion1_2);

    // Reveal hidden or private IAP records if a licensee has chosen to protect a record
    // using one of these flags - the API to do this is public so internal components
    // have to support the use of such records.
    dbs->SetAttributeMask( ECDHidden | ECDPrivate );

    // In all cases with S60 IP TM we want to use the S60 selector.
    // This means that it's pointless to allow any other selector to run besides CSimpleS60SelectorBase
    __CFLOG_VAR((KS60TierMgrTag, KS60TierMgrSubTag, _L8("S60MCPR::TIpProviderSelectorFactory::\tNewSelectorL() - Using S60 Simple Selector")));
    CSimpleS60SelectorBase* ipSelSelf = new (ELeave) CSimpleS60SelectorBase( aSelectionPreferences );
    selfCleanupItem = ipSelSelf;
    self = ipSelSelf;

    CleanupStack::PushL( selfCleanupItem );
    self->iTierRecord = TierManagerUtils::LoadTierRecordL( TUid::Uid(KAfInet), *dbs );
    __ASSERT_DEBUG(static_cast<TUint32>(self->iTierRecord->iDefaultAccessPoint)!=0,User::Panic(KS60SelectorPanic,EExpectedAccessPointAwareSystem));

    CleanupStack::Pop( selfCleanupItem );
    CleanupStack::Pop( dbs );
    ASSERT(self->iDbs==NULL);
    self->iDbs = dbs;
    return self;
    }