datacommsserver/esockserver/ssock/ss_tiermanagerutils.cpp
changeset 0 dfb7c4ff071f
child 21 4ccf8e394726
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/ss_tiermanagerutils.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1574 @@
+// Copyright (c) 2006-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:
+//
+
+/**
+ @file
+*/
+#include "ss_tiermanagerutils.h"
+
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_metaconnprov.h>
+#include <in_sock.h> //KAfInet
+#include <es_connpref.h>
+#include <commsdattypesv1_1.h> // CommsDat
+#include <comms-infras/commsdatschema.h> // CommsDat
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <commsdattypesv1_1_partner.h>
+#include <commsdattypesv1_1_internal.h>
+#include <es_sock_internal.h>
+#endif
+#include <commdbconnpref.h> //TCommDbConnPref
+#include <comms-infras/ss_thread.h>
+#include <comms-infras/esock_params.h> //TConnAPPref
+#include <comms-infras/ss_mcprnodemessages.h> //RConnPrefList
+#include <agentdialog.h> //TConnectionPrefs
+#include <elements/sd_std.h> //RTierThreadMap
+#include "ss_tierthreadmap.h"
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ESockSSockTrMngU, "ESockSSockTrMngU");
+#endif
+
+using namespace ESock;
+using namespace CommsDat;
+using namespace Den;
+using namespace CommsFW;
+
+
+/**
+   TierManagerUtils panic category
+*/
+_LIT(KTierManagerUtils, "TierManagerUtils");
+
+const TInt KEsockLinkFlag    =  0x80000000;
+
+/** Panics generated by the Comms Channels
+*/
+enum TTierManagerUtilsPanics
+	{
+	EInvalidTierId          = 0,
+	EInvalidAccessPointId   = 1,
+	EInvalidCprId           = 2,
+	EInvalidSCprId          = 3,
+	EInvalidIapId           = 4,
+	EInvalidProtocolId      = 5,
+	EInvalidAPSelPolId      = 6
+	};
+
+//private, not exported, used with legacy implicit flows only
+TUid TierManagerUtils::MapTierIdsForLegacyImplicitFlowsL(TUid aTierId, TUint aProtocol)
+	{
+	//If necessary, map the KAfInet to a default tier
+	TUid mappedTier = MapTierIdsL(aTierId, aProtocol);
+
+	//Now find the tier ID.
+	CMDBSession* dbs = CMDBSession::NewLC(KCDVersion1_2);
+	CCDTierRecord* tierRec = NULL;
+	TRAP_IGNORE(tierRec = TierManagerUtils::LoadTierRecordL(mappedTier, *dbs));
+	if(tierRec==NULL)
+		{
+		if(aTierId.iUid != KAfInet)
+			{
+			// In the absence of a trier record for this address family try using the KAfInet one
+			// This covers the case of legacy protocols such as SMS which only need the top tier
+			// The protocol argument is irrelevent for this.
+			mappedTier = TierManagerUtils::MapTierIdsL(TUid::Uid(KAfInet), 0);
+			tierRec = TierManagerUtils::LoadTierRecordL(mappedTier, *dbs);
+			}
+		else
+			{
+			User::Leave(KErrNotFound);
+			}
+		}
+
+	delete tierRec;
+	CleanupStack::PopAndDestroy(dbs);
+	return mappedTier;
+	}
+
+//only called from functions which are returning AP fields.
+TInt TierManagerUtils::ResolveDefAPtoTagL(TInt aElementId, CommsDat::CMDBSession& aDbs )
+    {
+    CMDBField<TInt>* iRecordTag = new (ELeave) CMDBField<TInt>(aElementId | KCDTIdRecordTag);
+    CleanupStack::PushL(iRecordTag);
+
+    iRecordTag->LoadL(aDbs);
+
+	TInt temp = *iRecordTag;
+	CleanupStack::PopAndDestroy(iRecordTag);
+	return temp;
+    }
+
+//Here we have an AccessPoint record Id. Based on that the TagId of the record
+//should be given back...
+EXPORT_C TInt TierManagerUtils::ConvertSNAPPrefToTagIdL(TUint aSNAPPref, CommsDat::CMDBSession& aDbs)
+	{
+    CMDBField<TInt>* apTag = new (ELeave) CMDBField<TInt>(KCDTIdAccessPointRecord | KCDTIdRecordTag);
+    CleanupStack::PushL(apTag);
+    apTag->SetRecordId(aSNAPPref);
+
+    apTag->LoadL(aDbs);
+
+	TInt temp = *apTag;
+	CleanupStack::PopAndDestroy(apTag);
+	return temp;
+	}
+
+EXPORT_C TUid TierManagerUtils::MapElementIdToTagId(TUint aElementId, CommsDat::CMDBSession& aDbs)
+    {
+    CMDBField<TInt>* recordTag = new (ELeave) CMDBField<TInt>((aElementId & KCDMaskShowRecordType) |
+                                                              (aElementId & KCDMaskShowRecordId) |
+                                                              KCDTIdRecordTag);
+    CleanupStack::PushL(recordTag);
+
+    recordTag->LoadL(aDbs);
+
+	TUid temp;
+	temp.iUid = *recordTag;
+
+	CleanupStack::PopAndDestroy(recordTag);
+
+	return temp;
+    }
+
+//
+//CTierManagerUtils - for commsdat manipulation
+EXPORT_C TUid TierManagerUtils::MapTierIdsL(TUid aTierId, TUint /*aProtocol*/)
+	{
+	// Defined here to avoid a dependency on SIP headers(sipconnpref.h)
+	const TUint KAFSip = 0x10000;
+	const TUint KAFSipTierMgrFactoryImplementionUid = 0x200041F7;
+
+	//Maps legacy or other thier ids (like the old address family) to new tier ids.
+	switch (aTierId.iUid)
+		{
+		case KAFSip:
+				return TUid::Uid(KAFSipTierMgrFactoryImplementionUid);
+		}
+
+	return aTierId;
+	}
+
+
+EXPORT_C CCDTierRecord* TierManagerUtils::LoadTierRecordL(TUid aTierId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aTierId.iUid>0,User::Panic(KTierManagerUtils,EInvalidTierId));
+
+    CCDTierRecord* tierRec = static_cast<CCDTierRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdTierRecord));
+    CleanupStack::PushL(tierRec);
+    tierRec->iRecordTag = aTierId.iUid;
+
+	TBool found = tierRec->FindL(aDbs);
+
+	if (!found)
+    	{
+    	User::Leave(KErrNotFound);
+    	}
+    if (static_cast<TInt>(tierRec->iDefaultAccessPoint)!=0)
+        {
+        TInt defTierElemId = ResolveDefAPtoTagL(static_cast<TInt>(tierRec->iDefaultAccessPoint), aDbs );
+        tierRec->iDefaultAccessPoint = defTierElemId;
+        }
+
+	__ASSERT_DEBUG(tierRec->iTierManagerName.TypeId() == KCDTIdTierManagerName, User::Panic(KSpecAssert_ESockSSockTrMngU, 1)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(tierRec);
+	return tierRec;
+	}
+
+
+EXPORT_C CCDTierRecord* TierManagerUtils::LoadTierRecordL(CommsDat::TMDBElementId aTierId, CommsDat::CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aTierId>0,User::Panic(KTierManagerUtils,EInvalidTierId));
+
+    CCDTierRecord* tierRec = static_cast<CCDTierRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdTierRecord));
+    CleanupStack::PushL(tierRec);
+
+    tierRec->SetRecordId(aTierId);
+
+	tierRec->LoadL(aDbs);
+
+    if (static_cast<TInt>(tierRec->iDefaultAccessPoint)!=0)
+        {
+        TInt defTierElemId = ResolveDefAPtoTagL(static_cast<TInt>(tierRec->iDefaultAccessPoint), aDbs );
+        tierRec->iDefaultAccessPoint = defTierElemId;
+        }
+	__ASSERT_DEBUG(tierRec->iTierManagerName.TypeId() == KCDTIdTierManagerName, User::Panic(KSpecAssert_ESockSSockTrMngU, 2)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(tierRec);
+	return tierRec;
+	}
+
+EXPORT_C CCDAPPrioritySelectionPolicyRecord* TierManagerUtils::LoadAPPrioritySelRecordL(CommsDat::TMDBElementId aApSelId, CommsDat::CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aApSelId>0,User::Panic(KTierManagerUtils,EInvalidAPSelPolId));
+
+    CCDAPPrioritySelectionPolicyRecord* apSelRec = static_cast<CCDAPPrioritySelectionPolicyRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdApPrioritySelectionPolicyRecord));
+    CleanupStack::PushL(apSelRec);
+
+    apSelRec->SetRecordId(aApSelId);
+
+	apSelRec->LoadL(aDbs);
+
+	CleanupStack::Pop(apSelRec);
+	return apSelRec;
+	}
+
+
+EXPORT_C CCDAccessPointRecord* TierManagerUtils::LoadAccessPointRecordL(TUint aAccessPointId, CMDBSession& aDbs)
+	{
+	/**
+	There are cases when ESock tries to load an access point record based on tag id but this id
+	is got as a TUint parameter. The conversion is here.
+	*/
+	__ASSERT_ALWAYS(aAccessPointId>0,User::Panic(KTierManagerUtils,EInvalidAccessPointId));
+
+	TUid temp;
+	temp.iUid = aAccessPointId;
+	return LoadAccessPointRecordL(temp, aDbs);
+	}
+
+
+EXPORT_C CCDAccessPointRecord* TierManagerUtils::LoadAccessPointRecordL(TUid aAccessPointId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aAccessPointId.iUid>0,User::Panic(KTierManagerUtils,EInvalidAccessPointId));
+
+    CCDAccessPointRecord* apRec = static_cast<CCDAccessPointRecord*>(CCDTierRecord::RecordFactoryL(KCDTIdAccessPointRecord));
+	CleanupStack::PushL(apRec);
+	apRec->iRecordTag = aAccessPointId.iUid;
+
+	TBool found = apRec->FindL(aDbs);
+
+	if (!found)
+    	{
+    	User::Leave(KErrNotFound);
+    	}
+	__ASSERT_DEBUG(apRec->iTier.TypeId() == KCDTIdTier, User::Panic(KSpecAssert_ESockSSockTrMngU, 3)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(apRec);
+	return apRec;
+	}
+
+
+EXPORT_C CCDAccessPointRecord* TierManagerUtils::LoadAccessPointRecordL(const TProviderInfo& aProviderInfo, CMDBSession& aDbs)
+	{
+	CCDAccessPointRecord* apRec = LoadAccessPointRecordL(aProviderInfo.APId(),aDbs);
+	__ASSERT_DEBUG(aProviderInfo.TierId().iUid==apRec->iTier, User::Panic(KSpecAssert_ESockSSockTrMngU, 4));
+	return apRec;
+	}
+
+EXPORT_C CMDBRecordSet<CCDAccessPointRecord>* TierManagerUtils::LoadAccessPointRecordsL(
+							TUid aTierId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aTierId.iUid>0,User::Panic(KTierManagerUtils,EInvalidTierId));
+
+	//Load all AP records that belong to this tier.
+	CMDBRecordSet<CCDAccessPointRecord>* apSet = new(ELeave) CMDBRecordSet<CCDAccessPointRecord>(KCDTIdAccessPointRecord);
+    CleanupStack::PushL(apSet);
+
+    //Create first record for priming
+    CCDAccessPointRecord* apRec = static_cast<CCDAccessPointRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdAccessPointRecord));
+    CleanupStack::PushL(apRec);
+
+    //Add record to record set
+    apRec->iTier = aTierId.iUid | KEsockLinkFlag;
+    apSet->iRecords.AppendL(apRec);
+    CleanupStack::Pop(apRec);
+
+    //Load set
+    TBool returned = apSet->FindL(aDbs);
+
+	//Check if apRec has been overwritten
+    if( ! returned )
+        {
+		User::Leave(KErrNotFound);
+        }
+
+    CleanupStack::Pop(apSet);
+	return apSet;
+	}
+
+EXPORT_C CMDBRecordSet<CCDAccessPointRecord>* TierManagerUtils::LoadAccessPointRecordsL(
+							TUid aTierId, const RArray<TAccessPointInfo>& aApIdsToMatch, CMDBSession& aDbs)
+	{
+	if(aApIdsToMatch.Count())
+		{
+		CMDBRecordSet<CCDAccessPointRecord>* apSet = new(ELeave) CMDBRecordSet<CCDAccessPointRecord>(KCDTIdAccessPointRecord);
+	    CleanupStack::PushL(apSet);
+
+		CCDAccessPointRecord* apRec = 0;
+		TInt i=0;
+		for( ; i<aApIdsToMatch.Count() ; ++i )
+			{
+			if(apRec == 0)
+				{
+				apRec = static_cast<CCDAccessPointRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdAccessPointRecord));
+   				CleanupStack::PushL(apRec);
+				}
+  			apRec->iTier = aTierId.iUid | KEsockLinkFlag;
+
+			apRec->iRecordTag = aApIdsToMatch[i].AccessPoint();
+			TBool returned = apRec->FindL(aDbs);
+			if(returned)
+				{
+			    apSet->iRecords.AppendL(apRec);
+				CleanupStack::Pop(apRec);
+				apRec = 0; // so a new one gets created on next iteration
+				}
+			}
+		if(apRec)
+			{
+			CleanupStack::PopAndDestroy(apRec);
+			}
+		CleanupStack::Pop(apSet);
+		return apSet;
+		}
+	else
+		{
+		// empty set means no filtering
+		return LoadAccessPointRecordsL(aTierId,aDbs);
+		}
+	}
+
+EXPORT_C CCDMCprRecord* TierManagerUtils::LoadMCprRecordL(TUint aMCprId, CMDBSession& aDbs)
+	{
+    CCDMCprRecord* mcprRec = static_cast<CCDMCprRecord*>(CCDMCprRecord::RecordFactoryL(KCDTIdMCprRecord));
+	CleanupStack::PushL(mcprRec);
+
+    mcprRec->SetRecordId(aMCprId);
+
+	mcprRec->LoadL(aDbs);
+
+	__ASSERT_DEBUG(mcprRec->iMCprUid.TypeId() == KCDTIdMCprUid, User::Panic(KSpecAssert_ESockSSockTrMngU, 5)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(mcprRec);
+	return mcprRec;
+	}
+
+EXPORT_C CCDMCprRecord* TierManagerUtils::LoadMCprRecordL(TUid aMCprFactoryUid, CMDBSession& aDbs)
+	{
+    CCDMCprRecord* mcprRec = static_cast<CCDMCprRecord*>(CCDMCprRecord::RecordFactoryL(KCDTIdMCprRecord));
+	CleanupStack::PushL(mcprRec);
+	mcprRec->iMCprUid = aMCprFactoryUid.iUid;
+	TBool found = mcprRec->FindL(aDbs);
+
+	if (!found)
+    	{
+    	User::Leave(KErrNotFound);
+    	}
+	__ASSERT_DEBUG(mcprRec->iMCprUid.TypeId() == KCDTIdMCprUid, User::Panic(KSpecAssert_ESockSSockTrMngU, 6)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(mcprRec);
+	return mcprRec;
+	}
+
+EXPORT_C CCDCprRecord* TierManagerUtils::LoadCprRecordL(TUint aCprId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aCprId>0,User::Panic(KTierManagerUtils,EInvalidCprId));
+
+    CCDCprRecord* cprRec = static_cast<CCDCprRecord*>(CCDCprRecord::RecordFactoryL(KCDTIdCprRecord));
+	CleanupStack::PushL(cprRec);
+
+    cprRec->SetRecordId(aCprId);
+
+	cprRec->LoadL(aDbs);
+
+	__ASSERT_DEBUG(cprRec->iCprUid.TypeId() == KCDTIdCprUid, User::Panic(KSpecAssert_ESockSSockTrMngU, 7)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(cprRec);
+	return cprRec;
+	}
+
+EXPORT_C CCDSCprRecord* TierManagerUtils::LoadSCprRecordL(TUint aSCprId, CMDBSession& aDbs)
+	{
+    __ASSERT_ALWAYS(aSCprId>0,User::Panic(KTierManagerUtils,EInvalidSCprId));
+
+    CCDSCprRecord* scprRec = static_cast<CCDSCprRecord*>(CCDSCprRecord::RecordFactoryL(KCDTIdSCprRecord));
+	CleanupStack::PushL(scprRec);
+
+    scprRec->SetRecordId(aSCprId);
+
+	scprRec->LoadL(aDbs);
+
+	__ASSERT_DEBUG(scprRec->iSCprUid.TypeId() == KCDTIdSCprUid, User::Panic(KSpecAssert_ESockSSockTrMngU, 8)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(scprRec);
+	return scprRec;
+	}
+
+EXPORT_C CCDProtocolRecord* TierManagerUtils::LoadProtocolRecordL(TUint aProtocolId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aProtocolId>0,User::Panic(KTierManagerUtils,EInvalidProtocolId));
+
+    CCDProtocolRecord* prtRec = static_cast<CCDProtocolRecord*>(CCDTierRecord::RecordFactoryL(KCDTIdProtocolRecord));
+	CleanupStack::PushL(prtRec);
+
+	prtRec->SetRecordId(aProtocolId);
+
+	prtRec->LoadL(aDbs);
+
+	__ASSERT_DEBUG(prtRec->iProtocolUid.TypeId() == KCDTIdProtocolUid, User::Panic(KSpecAssert_ESockSSockTrMngU, 9)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(prtRec);
+	return prtRec;
+	}
+
+EXPORT_C CCDGlobalSettingsRecord* TierManagerUtils::LoadGlobalSettingsRecordL(CMDBSession& aDbs)
+	{
+	CCDGlobalSettingsRecord* gsRec = static_cast<CCDGlobalSettingsRecord*>(CCDGlobalSettingsRecord::RecordFactoryL(KCDTIdGlobalSettingsRecord));
+	CleanupStack::PushL(gsRec);
+	gsRec->SetRecordId(1);
+	gsRec->LoadL(aDbs);
+	__ASSERT_DEBUG(gsRec->iDefaultTier.TypeId() == KCDTIdDefaultTier, User::Panic(KSpecAssert_ESockSSockTrMngU, 10)); // Panics if built against incorrect CommsDat.
+	CleanupStack::Pop(gsRec);
+	return gsRec;
+	}
+
+EXPORT_C CCDIAPRecord* TierManagerUtils::LoadIapRecordL(TUint aIapId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aIapId>0,User::Panic(KTierManagerUtils,EInvalidIapId));
+
+	CCDIAPRecord* iapRec = static_cast<CCDIAPRecord*>(CCDIAPRecord::RecordFactoryL(KCDTIdIAPRecord));
+	CleanupStack::PushL(iapRec);
+	iapRec->SetRecordId(aIapId);
+	iapRec->LoadL(aDbs);
+	CleanupStack::Pop(iapRec);
+	return iapRec;
+	}
+
+EXPORT_C CMDBRecordSet<CCDIAPRecord>* TierManagerUtils::LoadIapRecordsL(CMDBSession& aDbs)
+	{
+	//Load all IAP records
+	CMDBRecordSet<CCDIAPRecord>* iapSet = new(ELeave) CMDBRecordSet<CCDIAPRecord>(KCDTIdIAPRecord);
+    CleanupStack::PushL(iapSet);
+
+    //Create first record for priming
+	CCDIAPRecord* iapRec = static_cast<CCDIAPRecord*>(CCDIAPRecord::RecordFactoryL(KCDTIdIAPRecord));
+	CleanupStack::PushL(iapRec);
+
+    //Add record to record set
+    iapSet->iRecords.AppendL(iapRec);
+    CleanupStack::Pop(iapRec);
+
+    //Load set
+    TBool returned = iapSet->FindL(aDbs);
+
+	//Check if apRec has been overwritten
+    if( ! returned )
+        {
+		User::Leave(KErrNotFound);
+        }
+
+    CleanupStack::Pop(iapSet);
+	return iapSet;
+	}
+
+EXPORT_C TUint TierManagerUtils::ReadDefaultAccessPointL(TUid aTierId, CMDBSession& aDbs)
+	{
+	CCDTierRecord* tierRec = TierManagerUtils::LoadTierRecordL(aTierId,aDbs);
+	TUint accessPoint = tierRec->iDefaultAccessPoint;
+	delete tierRec;
+	return accessPoint;
+	}
+
+EXPORT_C TUid TierManagerUtils::ReadTierIdL(TUint aAccessPointId, CMDBSession& aDbs)
+	{
+
+	//it would be better to load 2 fields rather than load 2 record....
+
+	__ASSERT_ALWAYS(aAccessPointId>0,User::Panic(KTierManagerUtils,EInvalidAccessPointId));
+
+	CCDAccessPointRecord* apRec = TierManagerUtils::LoadAccessPointRecordL(aAccessPointId,aDbs);
+
+	CleanupStack::PushL(apRec);
+
+	//load the tag field for the given tier record
+	CMDBField<TInt>* iRecordTag = new (ELeave) CMDBField<TInt>(static_cast<TInt>(apRec->iTier) | KCDTIdRecordTag);
+    CleanupStack::PushL(iRecordTag);
+
+    iRecordTag->LoadL(aDbs);
+
+	TInt tempTag = *iRecordTag;
+	CleanupStack::PopAndDestroy(iRecordTag);
+
+	TUid tierId = TUid::Uid(tempTag);
+
+	CleanupStack::PopAndDestroy(apRec);
+	//delete apRec;
+	User::LeaveIfError(tierId.iUid? KErrNone : KErrCorrupt);
+	return tierId;
+	}
+
+EXPORT_C TUid TierManagerUtils::ReadMCprUidL(TUint aAccessPointId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aAccessPointId>0,User::Panic(KTierManagerUtils,EInvalidAccessPointId));
+
+	CCDAccessPointRecord* apRec = TierManagerUtils::LoadAccessPointRecordL(aAccessPointId,aDbs);
+	CleanupStack::PushL(apRec);
+	CCDMCprRecord* mcprRec = TierManagerUtils::LoadMCprRecordL(apRec->iMCpr,aDbs);
+	TUid mCprUid = TUid::Uid(mcprRec->iMCprUid);
+	delete mcprRec;
+	CleanupStack::PopAndDestroy(apRec);
+	return mCprUid;
+	}
+
+EXPORT_C TUint TierManagerUtils::ReadSelectionPolicyIdL(TUint aAccessPointId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aAccessPointId>0,User::Panic(KTierManagerUtils,EInvalidAccessPointId));
+
+	CCDAccessPointRecord* apRec = TierManagerUtils::LoadAccessPointRecordL(aAccessPointId,aDbs);
+	TUint policyId = apRec->iSelectionPolicy;
+	delete apRec;
+	return policyId;
+	}
+
+EXPORT_C TUint TierManagerUtils::ReadCustomSelectionPolicyIdL(TUint aAccessPointId, CommsDat::CMDBSession& aDbs)
+    {
+    __ASSERT_ALWAYS(aAccessPointId>0,User::Panic(KTierManagerUtils,EInvalidAccessPointId));
+
+	CCDAccessPointRecord* apRec = TierManagerUtils::LoadAccessPointRecordL(aAccessPointId,aDbs);
+	TUint customSelPolicyId = apRec->iCustomSelectionPolicy;
+	delete apRec;
+	return customSelPolicyId;
+    }
+
+EXPORT_C TUint TierManagerUtils::ReadCprConfigL(TUint aAccessPointId, CMDBSession& aDbs)
+	{
+	__ASSERT_ALWAYS(aAccessPointId>0,User::Panic(KTierManagerUtils,EInvalidAccessPointId));
+
+	CCDAccessPointRecord* apRec = TierManagerUtils::LoadAccessPointRecordL(aAccessPointId,aDbs);
+	TUint cprconfig = apRec->iCprConfig;
+	delete apRec;
+	return cprconfig;
+	}
+
+EXPORT_C ESock::RTierThreadMap* TierManagerUtils::BuildTierThreadMappingL(CMDBSession& aDbs)
+	{
+	RTierThreadMap* map = new (ELeave) RTierThreadMap;
+	CleanupClosePushL(*map);
+	CMDBRecordSet<CCDTierRecord>* recSet = new (ELeave) CMDBRecordSet<CCDTierRecord>(KCDTIdTierRecord);
+	CleanupStack::PushL(recSet);
+	recSet->LoadL(aDbs);
+	CommsFW::TCFModuleName narrowThreadName;
+	const TInt recCnt = recSet->iRecords.Count();
+	for(TInt i = 0; i < recCnt; ++i)
+		{
+		CCDTierRecord* rec = static_cast<CCDTierRecord*>(recSet->iRecords[i]);
+		narrowThreadName.Copy(rec->iTierThreadName);
+		TWorkerId worker;
+		if(!CWorkerThread::ResolveWorkerNameToId(narrowThreadName, worker))
+			{
+			LOG(ESockLog::Printf(KESockMetaConnectionTag, _L("TierManagerUtils::BuildTierThreadMappingL - worker name %S failed resolution"), &narrowThreadName));
+			continue;
+			}
+		map->AppendL(TTierMapEntry(rec->iRecordTag, worker));
+		}
+	CleanupStack::PopAndDestroy(recSet);
+	CleanupStack::Pop(map);
+	return map;
+	}
+
+//This function reads the IAP priority based selection policy table (CCDIAPPrioritySelectionPolicyRecord)
+//and fills the TConnIdList provided using the specified selectionPolicy (record id within the table).
+EXPORT_C void TierManagerUtils::FillListL(TConnIdList& aList, TUint selectionPolicy, CMDBSession& aDbs)
+	{
+	LOG(ESockLog::Printf(KESockMetaConnectionTag, _L("TierManagerUtils::FillListL()")));
+
+	//The provided list must be empty.
+	__ASSERT_DEBUG(aList.Count()==0, User::Panic(KSpecAssert_ESockSSockTrMngU, 11));
+
+	CCDAPPrioritySelectionPolicyRecord* policyRec = static_cast<CCDAPPrioritySelectionPolicyRecord*>
+		(CCDConnectionPrefsRecord::RecordFactoryL(KCDTIdApPrioritySelectionPolicyRecord));
+	CleanupStack::PushL(policyRec);
+	policyRec->SetRecordId(selectionPolicy);
+	policyRec->LoadL(aDbs);
+
+//	CMDBField<TUint32>* theAp = &policyRec->iAp1;
+	CMDBRecordLink<CCDAccessPointRecord>* theAp = &policyRec->iAp1;
+	TUint32 theCount = policyRec->iApCount;
+	__ASSERT_DEBUG(theCount <= CCDAPPrioritySelectionPolicyRecord::EMaxNrOfAps, User::Panic(KSpecAssert_ESockSSockTrMngU, 12));
+
+	for (TInt i = 0; i < theCount; i++, theAp++)
+		{
+		//TInt apId = static_cast<TInt>(*theAp);
+		TInt apId = ResolveDefAPtoTagL((*theAp), aDbs );
+		__ASSERT_DEBUG(apId>0, User::Panic(KSpecAssert_ESockSSockTrMngU, 13));
+		LOG(ESockLog::Printf(KESockMetaConnectionTag, _L("ListCount[%d] Append(%d)"),aList.Count(),apId));
+		aList.Append(apId);
+		}
+
+	CleanupStack::PopAndDestroy(policyRec);
+	}
+
+//This function reads the AP priority based selection policy table (CCDAPPrioritySelectionPolicyRecord)
+//and fills the RConnPrefList provided using the specified selectionPolicy (record id within the table).
+EXPORT_C void TierManagerUtils::FillListL(RConnPrefList& aList, TUint selectionPolicy, CMDBSession& aDbs)
+	{
+	LOG(ESockLog::Printf(KESockMetaConnectionTag, _L("TierManagerUtils::FillListL()")));
+
+	CCDAPPrioritySelectionPolicyRecord* policyRec = static_cast<CCDAPPrioritySelectionPolicyRecord*>
+		(CCDConnectionPrefsRecord::RecordFactoryL(KCDTIdApPrioritySelectionPolicyRecord));
+	CleanupStack::PushL(policyRec);
+	policyRec->SetRecordId(selectionPolicy);
+	policyRec->LoadL(aDbs);
+
+	CMDBRecordLink<CCDAccessPointRecord>* theAp = &policyRec->iAp1;
+	TUint32 theCount = policyRec->iApCount;
+	__ASSERT_DEBUG(theCount <= CCDAPPrioritySelectionPolicyRecord::EMaxNrOfAps, User::Panic(KSpecAssert_ESockSSockTrMngU, 14));
+
+	for (TInt i = 0; i < theCount; i++, theAp++)
+		{
+		TInt apId = ResolveDefAPtoTagL((*theAp), aDbs );
+		TConnAPPref* pref = TConnAPPref::NewL(apId);
+		CleanupStack::PushL(pref);
+		__ASSERT_DEBUG(apId>0, User::Panic(KSpecAssert_ESockSSockTrMngU, 15));
+		LOG(ESockLog::Printf(KESockMetaConnectionTag, _L("ListCount[%d] Append(%d)"),aList.Count(),apId));
+		aList.AppendL(pref);
+		CleanupStack::Pop();
+		}
+
+	CleanupStack::PopAndDestroy(policyRec);
+	}
+
+EXPORT_C TUint TierManagerUtils::GetConnectionAttemptsL(CMDBSession& aDbs)
+	{
+	//it's enough to load the appropriate field...
+	CCDGlobalSettingsRecord* glRec = TierManagerUtils::LoadGlobalSettingsRecordL(aDbs);
+	CleanupStack::PushL(glRec);
+	TUint connectionAttempts = glRec->iMaxConnectionAttempts;
+	CleanupStack::PopAndDestroy(glRec);
+	return connectionAttempts;
+	}
+
+EXPORT_C void TierManagerUtils::MapRankingToPrefsL(TUint aRanking, TCommDbConnPref& aPrefs, CMDBSession& aDbs)
+	{
+	CCDConnectionPrefsRecord* cpRec = static_cast<CCDConnectionPrefsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdConnectionPrefsRecord));
+	CleanupStack::PushL(cpRec);
+	cpRec->iRanking = aRanking;
+	TBool found = cpRec->FindL(aDbs);
+	if (!found)
+    	{ //CommsDat API is a widely known problem
+    	User::Leave(KErrNotFound);
+    	}
+
+	//CommDat records do not like to be casted, this is why we have double cast here.. (!?!)
+	aPrefs.SetIapId(cpRec->iDefaultIAP);
+	aPrefs.SetDialogPreference(static_cast<TCommDbDialogPref>((TUint)cpRec->iDialogPref));
+	aPrefs.SetDirection(static_cast<TCommDbConnectionDirection>((TUint)cpRec->iDirection));
+	aPrefs.SetBearerSet(cpRec->iBearerSet);
+
+	CleanupStack::PopAndDestroy(cpRec);
+	}
+
+EXPORT_C void TierManagerUtils::ParseTLConfigAccessPointIdsL(RArray<TUint> &aIds, const TDesC& aIdList)
+    {
+    TLex lexer(aIdList);
+    while (!lexer.Eos())
+	{
+	TUint val = 0;
+	TInt err = lexer.Val(val);
+	if (err != KErrNone)
+	    User::Leave(KErrArgument);
+	aIds.AppendL(val);
+
+	lexer.SkipSpaceAndMark();
+	if (lexer.Peek() == ',')
+	    lexer.Inc();
+	}
+    }
+
+EXPORT_C CCDConfigAccessPointRecord* TierManagerUtils::LoadConfigAccessPointRecordL(TUint aId, CommsDat::CMDBSession& aDBs)
+    {
+    CCDConfigAccessPointRecord* capRec = static_cast<CCDConfigAccessPointRecord*>(CCDConfigAccessPointRecord::RecordFactoryL(KCDTIdConfigAccessPointRecord));
+
+    CleanupStack::PushL(capRec);
+    capRec->SetRecordId(aId);
+    capRec->LoadL(aDBs);
+
+    CleanupStack::Pop(capRec);
+    return capRec;
+    }
+
+EXPORT_C void TierManagerUtils::MapRankingAndDirectionToPrefsL(TUint aRanking, TCommDbConnectionDirection aDirection, TCommDbConnPref& aPrefs, CMDBSession& aDbs)
+	{
+	CCDConnectionPrefsRecord* cpRec = static_cast<CCDConnectionPrefsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdConnectionPrefsRecord));
+	CleanupStack::PushL(cpRec);
+	cpRec->iRanking = aRanking;
+	cpRec->iDirection = aDirection;
+
+	TBool found = cpRec->FindL(aDbs);
+	if (!found)
+    	{
+    	User::Leave(KErrNotFound);
+    	}
+
+	//CommDat records do not like to be casted, this is why we have double cast here.. (!?!)
+	aPrefs.SetIapId(cpRec->iDefaultIAP);
+	aPrefs.SetDialogPreference(static_cast<TCommDbDialogPref>((TUint)cpRec->iDialogPref));
+	aPrefs.SetDirection(static_cast<TCommDbConnectionDirection>((TUint)cpRec->iDirection));
+	aPrefs.SetBearerSet(cpRec->iBearerSet);
+
+	CleanupStack::PopAndDestroy(cpRec);
+	}
+
+EXPORT_C  void TierManagerUtils::GetPrefsFromConnPrefRecL(TUint aConnPrefRecElemId,
+											  			  CommsDat::CMDBSession& aDbs,
+											  			  TConnectionPrefs& aConnPrefs)
+	{
+	CCDConnectionPrefsRecord* cpRec = static_cast<CCDConnectionPrefsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdConnectionPrefsRecord));
+	CleanupStack::PushL(cpRec);
+	cpRec->SetElementId(aConnPrefRecElemId);
+
+	cpRec->LoadL(aDbs);
+
+	aConnPrefs.iRank = cpRec->iRanking;
+	aConnPrefs.iDirection = cpRec->iDirection;
+	aConnPrefs.iBearerSet = cpRec->iBearerSet;
+
+	CleanupStack::PopAndDestroy(cpRec);
+	}
+
+EXPORT_C TUid TierManagerUtils::MapTierIdtoTierImplIdL(TUid aTierUid,CommsDat::CMDBSession& aDbs )
+/** mapping TM Id to TM ImplId in Commsdat */
+	{
+	TUid ImplUid;
+	// if it does not exist, it returns tier id
+	ImplUid = aTierUid;
+
+	CMDBRecordSet<CCDTierRecord>* recSet = new (ELeave) CMDBRecordSet<CCDTierRecord>(KCDTIdTierRecord);
+	CleanupStack::PushL(recSet);
+	recSet->LoadL(aDbs);
+	const TInt recCnt = recSet->iRecords.Count();
+	
+	for(TInt i = 0; i < recCnt; i++)
+		{
+		CCDTierRecord* rec = static_cast<CCDTierRecord*>(recSet->iRecords[i]);
+		if(rec->iRecordTag == aTierUid.iUid)
+			{
+			ImplUid.iUid = rec->iTierImplUid;
+			}
+		}
+	
+	CleanupStack::PopAndDestroy(recSet);	
+	return ImplUid;
+	}
+//
+// CCommsDatIapView
+//
+// Class used to retrieve CommsDat values based on a view specific to an IAP.
+//
+
+EXPORT_C CCommsDatIapView* CCommsDatIapView::NewL(TUint aIapId)
+/**
+Create a new IAP view object based on the IAP number specified.
+
+@param aIapId IAP number
+@return IAP view object
+*/
+	{
+	CCommsDatIapView* self = new (ELeave) CCommsDatIapView();
+	CleanupStack::PushL(self);
+
+	// Second phase construction
+	self->iDbs = CMDBSession::NewL(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.
+	self->iDbs->SetAttributeMask( ECDHidden | ECDPrivate );
+
+	self->iIapRec = TierManagerUtils::LoadIapRecordL(aIapId, *self->iDbs);
+	self->iUmtsR99QoSAndOnRecId = -1;
+
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+EXPORT_C CCommsDatIapView* CCommsDatIapView::NewLC(TUint aIapId)
+/**
+Create a new IAP view object based on the IAP number specified, and leave
+a cleanup item on the cleanup stack.
+
+@param aIapId IAP number
+@return IAP view object
+*/
+	{
+	CCommsDatIapView* self = NewL(aIapId);
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+EXPORT_C CCommsDatIapView::~CCommsDatIapView()
+	{
+	delete iBool;
+	delete iUint;
+	delete iInt;
+	delete iText8;
+	delete iText16;
+
+	delete iIapRec;
+	delete iDbs;
+	}
+
+
+/**
+Retrieve an unsigned integer value from CommsDat.
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+This field can take the special value KCDTIdIAPNetwork to retrieve the Network Id.
+@param aValue returned integer value
+*/
+EXPORT_C void CCommsDatIapView::GetIntL(TMDBElementId aElementId, TUint32& aValue)
+	{
+	if ((aElementId & KCDMaskShowRecordType) == KCDTIdIAPRecord)
+		{
+		GetIapRecordIntL(aElementId, aValue);
+		return;
+		}
+
+	if (iUint == NULL)
+		{
+		iUint = new (ELeave) CMDBField<TUint32>();
+		}
+	SetElementAndRecordIdL(iUint, aElementId);
+
+	IntFieldTypeCheckL(iUint->ElementId());
+
+	iUint->LoadL(*iDbs);
+	aValue = *iUint;
+	}
+
+
+/**
+Retrieve an unsigned integer value from CommsDat (non-leaving)
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue returned integer value
+@return KErrNone or a system wide error code
+*/
+EXPORT_C TInt CCommsDatIapView::GetInt(TMDBElementId aElementId, TUint32& aValue)
+	{
+	TRAPD(err, GetIntL(aElementId, aValue));
+	return err;
+	}
+
+
+/**
+Retrieve a signed integer value from CommsDat.
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+This field can take the special value KCDTIdIAPNetwork to retrieve the Network Id.
+@param aValue returned integer value
+*/
+EXPORT_C void CCommsDatIapView::GetIntL(TMDBElementId aElementId, TInt& aValue)
+	{
+	if ((aElementId & KCDMaskShowRecordType) == KCDTIdIAPRecord)
+		{
+		GetIapRecordIntL(aElementId, aValue);
+		return;
+		}
+
+	if (iInt == NULL)
+		{
+		iInt = new (ELeave) CMDBField<TInt>();
+		}
+	SetElementAndRecordIdL(iInt, aElementId);
+
+	IntFieldTypeCheckL(iInt->ElementId());
+
+	iInt->LoadL(*iDbs);
+	aValue = *iInt;
+	}
+
+
+/**
+Retrieve a signed integer value from CommsDat (non-leaving)
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue returned integer value
+@return KErrNone or a system wide error code
+*/
+EXPORT_C TInt CCommsDatIapView::GetInt(TMDBElementId aElementId, TInt& aValue)
+	{
+	TRAPD(err, GetIntL(aElementId, aValue));
+	return err;
+	}
+
+
+/**
+Retrieve a boolean value from CommsDat
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue returned boolean value
+*/
+EXPORT_C void CCommsDatIapView::GetBoolL(TMDBElementId aElementId, TBool& aValue)
+	{
+	if (NULL == iBool)
+		{
+		iBool = new (ELeave) CMDBField<TBool>();
+		}
+	SetElementAndRecordIdL(iBool, aElementId);
+
+	BoolFieldTypeCheckL(iBool->ElementId());
+
+	iBool->LoadL(*iDbs);
+	aValue = *iBool;
+	}
+
+
+/**
+Retrieve a boolean value from CommsDat (non-leaving)
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue returned boolean value
+@return KErrNone or a system wide error code
+*/
+EXPORT_C TInt CCommsDatIapView::GetBool(TMDBElementId aElementId, TBool& aValue)
+	{
+	TRAPD(err, GetBoolL(aElementId, aValue));
+	return err;
+	}
+
+
+/**
+Retrieve a text value from CommsDat
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue In this field the caller receives ownership of a HBufC containing the text value.
+The following function will read in 8 bit text and output 16 bit convertion to keep up with legacy behaviour
+*/
+EXPORT_C void CCommsDatIapView::GetTextL(TMDBElementId aElementId, HBufC8*& aValue)
+	{
+    aValue = NULL;
+    if (NULL == iText8)
+        {
+        iText8 = new (ELeave) CMDBField<TDesC8>();
+        }
+    SetElementAndRecordIdL(iText8, aElementId);
+
+    TextOrBinFieldTypeCheckL(iText8->ElementId());
+
+    TRAPD(err, iText8->LoadL(*iDbs)); // trap first attempt for retry with larger buffer
+    if (err == KErrOverflow)
+        {
+        iText8->SetMaxLengthL(1024);
+        iText8->LoadL(*iDbs);
+        err = KErrNone;
+        }
+    User::LeaveIfError(err);
+
+    CMDBRecordBase* recordBase = CCDRecordBase::RecordFactoryL(iText8->TableId());
+	CleanupStack::PushL(recordBase);
+	CMDBElement* el = recordBase->GetFieldByIdL(iText8->TypeId());
+	if (EText == el->Type())
+		{
+		const TDesC8& des8 = iText8->GetL();
+		TPtrC ptr16(reinterpret_cast<const TUint16 *>(des8.Ptr()), des8.Length() / 2);
+	    // Create a HBufC to return to the caller, containing a copy of the field.
+	    aValue = HBufC8::NewMaxL(ptr16.Length());
+		aValue->Des().Copy(ptr16);
+		}
+    else
+	   {
+	    // Create a HBufC to return to the caller, containing a copy of the field.
+	    aValue = HBufC8::NewMaxL(static_cast<const TDesC8&>(*iText8).Length());
+	    *aValue = *iText8;
+	   }
+
+	CleanupStack::PopAndDestroy(recordBase);
+	}
+
+
+/**
+Retrieve a text value from CommsDat (non-leaving)
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue In this field the caller receives ownership of a HBufC containing the text value.
+@return KErrNone or a system wide error code
+The following function will read in 16 bit text and output 8 bit convertion to keep up with legacy behaviour
+*/
+EXPORT_C TInt CCommsDatIapView::GetText(TMDBElementId aElementId, HBufC8*& aValue)
+	{
+	TRAPD(err, GetTextL(aElementId, aValue));
+	return err;
+	}
+
+
+/**
+Retrieve a text value from CommsDat
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue In this field the caller receives ownership of a HBufC containing the text value.
+*/
+
+EXPORT_C void CCommsDatIapView::GetTextL(TMDBElementId aElementId, HBufC16*& aValue)
+	{
+	if ((aElementId & KCDMaskShowRecordType) == KCDTIdIAPRecord)
+		{
+		GetIapRecordTextL(aElementId, aValue);
+		return;
+		}
+
+	aValue = NULL;
+    if (NULL == iText16)
+        {
+        iText16 = new (ELeave) CMDBField<TDesC16>();
+        }
+    SetElementAndRecordIdL(iText16, aElementId);
+
+    TextOrBinFieldTypeCheckL(iText16->ElementId());
+
+    TRAPD(err, iText16->LoadL(*iDbs)); // trap first attempt for retry with larger buffer
+    if (err == KErrOverflow)
+        {
+        iText16->SetMaxLengthL(1024);
+        iText16->LoadL(*iDbs);
+        err = KErrNone;
+        }
+    User::LeaveIfError(err);
+
+    CMDBRecordBase* recordBase = CCDRecordBase::RecordFactoryL(iText16->TableId());
+	CleanupStack::PushL(recordBase);
+	CMDBElement* el = recordBase->GetFieldByIdL(iText16->TypeId());
+	if (EDesC8 == el->Type())
+		{
+		const TDesC16& des16 = iText16->GetL();
+		TPtrC8 ptr8(reinterpret_cast<const TUint8 *>(des16.Ptr()), des16.Size());
+
+	    // Create a HBufC to return to the caller, containing a copy of the field.
+	    aValue = HBufC16::NewMaxL(ptr8.Length());
+		aValue->Des().Copy(ptr8);
+		}
+    else
+	   {
+	    // Create a HBufC to return to the caller, containing a copy of the field.
+	    aValue = HBufC16::NewMaxL(static_cast<const TDesC16&>(*iText16).Length());
+	    *aValue = *iText16;
+	   }
+
+	CleanupStack::PopAndDestroy(recordBase);
+	}
+
+
+/**
+Retrieve a text value from CommsDat (non-leaving)
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue In this field the caller receives ownership of a HBufC containing the text value.
+@return KErrNone or a system wide error code
+*/
+EXPORT_C TInt CCommsDatIapView::GetText(TMDBElementId aElementId, HBufC16*& aValue)
+	{
+	TRAPD(err, GetTextL(aElementId, aValue));
+	return err;
+	}
+
+
+void CCommsDatIapView::GetIapRecordIntL(TMDBElementId aElementId, TUint32& aValue)
+	{
+	switch(aElementId)
+		{
+		case (KCDTIdIAPRecord | KCDTIdRecordTag):
+			aValue = iIapRec->iRecordTag;
+			break;
+
+		case KCDTIdIAPService:
+			aValue = iIapRec->iService;
+			break;
+
+		case KCDTIdIAPBearer:
+			aValue = iIapRec->iBearer;
+			break;
+
+		case KCDTIdIAPNetwork:
+			aValue = iIapRec->iNetwork;
+			break;
+
+		case KCDTIdIAPNetworkWeighting:
+			aValue = iIapRec->iNetworkWeighting;
+			break;
+
+		case KCDTIdIAPLocation:
+			aValue = iIapRec->iLocation;
+			break;
+
+		case KCDTIdIAPAppSid:
+			aValue = iIapRec->iAppSid;
+			break;
+
+		case KCDTIdRealIAP:
+			{
+			const TDesC& serviceType = iIapRec->iServiceType;
+			if (serviceType.Compare(TPtrC(KCDTypeNameVPNService)) == 0)
+				{
+				GetIntL(KCDTIdVPNIAPRecord, aValue);
+				}
+			else
+				{
+				aValue = iIapRec->iRecordTag;
+				}
+			}
+			break;
+
+		default:
+			{
+			User::Leave(KErrBadName);
+			}
+		}
+	}
+
+
+void CCommsDatIapView::GetIapRecordIntL(TMDBElementId aElementId, TInt& aValue)
+	{
+	// Ok since this table only contains Uints, but none that
+	// tickle the top bit
+	TUint32 value;
+	GetIapRecordIntL(aElementId, value);
+	aValue = (TInt)value;
+	}
+
+
+void CCommsDatIapView::GetIapRecordTextL(TMDBElementId aElementId, HBufC16*& aValue)
+	{
+	switch(aElementId)
+		{
+		case (KCDTIdIAPRecord | KCDTIdRecordName):
+			{
+			const TDesC16& record = iIapRec->iRecordName;
+			aValue = HBufC16::NewMaxL(record.Length());
+			*aValue = record;
+			}
+			break;
+
+		case KCDTIdIAPBearerType:
+			{
+			const TDesC16& record = iIapRec->iBearerType;
+			aValue = HBufC16::NewMaxL(record.Length());
+			*aValue = record;
+			}
+			break;
+
+		case KCDTIdIAPServiceType:
+			{
+			const TDesC16& record = iIapRec->iServiceType;
+			aValue = HBufC16::NewMaxL(record.Length());
+			*aValue = record;
+			}
+			break;
+
+		default:
+			{
+			User::Leave(KErrBadName);
+			}
+		}
+	}
+
+
+EXPORT_C TUint CCommsDatIapView::IapId()
+/**
+Return the IAP number associated with this IAP view object.
+*/
+	{
+	//normally iRecordTag will be empty and anyway is not intended to hold the record id.
+	// assuming the record id of the IAP is what is needed this call needs to be different
+	//return iIapRec->iRecordTag;
+	return iIapRec->RecordId();
+
+	}
+
+EXPORT_C CommsDat::TMDBElementId CCommsDatIapView::GetServiceTableType() const
+    {
+    CommsDat::TMDBElementId el;
+    TInt err = ConvertServiceTypeToTableId(iIapRec->iServiceType,el);
+    __ASSERT_DEBUG(err == KErrNone, User::Panic(KSpecAssert_ESockSSockTrMngU, 16));
+    return el;
+    }
+
+EXPORT_C CommsDat::TMDBElementId CCommsDatIapView::GetBearerTableType() const
+    {
+    CommsDat::TMDBElementId el;
+    TInt err = ConvertBearerTypeToTableId(iIapRec->iBearerType, el);
+    __ASSERT_DEBUG(err == KErrNone, User::Panic(KSpecAssert_ESockSSockTrMngU, 17));
+    return el;
+    }
+
+
+EXPORT_C void CCommsDatIapView::GetTableCommonTextFieldL(CCommsDatIapView::TFieldId aField, HBufC*& aValue)
+/**
+Generalised routine for reading the value of a specified text field from the current bearer or
+service table.
+
+The caller does not need to specify the particular CommsDat id.  In some ways this is similar
+functionality to the CommsDat ability to read a field by name, but that mechanism was considered
+too inefficient as this routine is likely to be called on every connection startup.
+
+This routine does the work of determining the CommsDat id of the field with respect to the
+current service or bearer table.
+
+@param aElementId element id of the field required.  The record id does not need to be specified.
+@param aValue In this field the caller receives ownership of a HBufC containing the text value.
+*/
+	{
+	TMDBElementId el = 0;
+
+	// Determine the CommsDat id of the field.
+	switch (aField)
+		{
+	case EIfNetworks:
+		switch (GetServiceTableType())
+			{
+		case KCDTIdDialOutISPRecord:
+			el = KCDTIdIfNetworks;
+			break;
+
+		case KCDTIdOutgoingGprsRecord:
+        case KCDTIdIncomingGprsRecord:
+			el = KCDTIdWCDMAIfNetworks | GetServiceTableType();
+			break;
+
+		case KCDTIdLANServiceRecord:
+			el = KCDTIdLANIfNetworks;
+			break;
+
+		case KCDTIdDialInISPRecord:
+			el = KCDTIdDINIfNetworks;
+			break;
+
+		default:
+			User::Leave(KErrCorrupt);
+			} // inner switch
+		break;
+	case EConfigDaemonManagerName:
+		switch (GetServiceTableType())
+			{
+		case KCDTIdDialOutISPRecord:
+			el = KCDTIdConfigDaemonManagerName;
+			break;
+
+		case KCDTIdOutgoingGprsRecord:
+        case KCDTIdIncomingGprsRecord:
+			el = KCDTIdWCDMAConfigDaemonManagerName | GetServiceTableType();
+			break;
+
+		case KCDTIdLANServiceRecord:
+			el = KCDTIdLANConfigDaemonManagerName;
+			break;
+
+		default:
+			User::Leave(KErrCorrupt);
+			} // inner switch
+		break;
+	case EConfigDaemonName:
+		switch (GetServiceTableType())
+			{
+		case KCDTIdDialOutISPRecord:
+			el = KCDTIdConfigDaemonName;
+			break;
+
+		case KCDTIdOutgoingGprsRecord:
+        case KCDTIdIncomingGprsRecord:
+			el = KCDTIdWCDMAConfigDaemonName | GetServiceTableType();
+			break;
+
+		case KCDTIdLANServiceRecord:
+			el = KCDTIdLANConfigDaemonName;
+			break;
+
+		default:
+			User::Leave(KErrCorrupt);
+			} // inner switch
+		break;
+		} // outer switch
+
+	GetTextL(el, aValue);
+	}
+
+EXPORT_C void CCommsDatIapView::GetTimeoutValuesL(TUint32& aShortTimeout, TUint32& aMediumTimeout, TUint32& aLongTimeout)
+/**
+Retrieve the idle timeout values based on the current IAP view.
+
+@param aShortTimeout populated with LastSessionClosedTimeout field
+@param aMediumTimeout populated with LastSocketClosedTimeout field
+@param aLongTimeout populated with LastSocketActivityTimeout field
+*/
+	{
+	TMDBElementId shortId = 0;
+	TMDBElementId mediumId = 0;
+	TMDBElementId longId = 0;
+
+	//
+	// Check the bearer type and setup the correct elementId's for the timeout fields
+	//
+	const TDesC& bearerType = iIapRec->iBearerType;
+	if (bearerType.Compare(TPtrC(KCDTypeNameModemBearer)) == 0)
+		{
+	    longId = KCDTIdLastSocketActivityTimeout;
+		shortId = KCDTIdLastSessionClosedTimeout;
+		mediumId = KCDTIdLastSocketClosedTimeout;
+		}
+	else
+	if (bearerType.Compare(TPtrC(KCDTypeNameLANBearer)) == 0)
+		{
+	    longId = KCDTIdLANLastSocketActivityTimeout;
+		shortId = KCDTIdLANLastSessionClosedTimeout;
+		mediumId = KCDTIdLANLastSocketClosedTimeout;
+		}
+	else
+	if (bearerType.Compare(TPtrC(KCDTypeNameVirtualBearer)) == 0)
+		{
+	    longId = KCDTIdVBLastSocketActivityTimeout;
+		shortId = KCDTIdVBLastSessionClosedTimeout;
+		mediumId = KCDTIdVBLastSocketClosedTimeout;
+		}
+	else
+		{
+		User::Leave(KErrCorrupt);
+		}
+
+	// Retrieve the timeout fields
+	GetIntL(longId, aLongTimeout);
+	GetIntL(mediumId, aMediumTimeout);
+	GetIntL(shortId, aShortTimeout);
+	}
+
+void CCommsDatIapView::SetElementAndRecordIdL(CMDBElement* aElement, TMDBElementId aElementId)
+/**
+Set the elementid of an element based on the current IAP view.
+
+Essentially, this routine selects the service/bearer table entry to be retrieved,
+based on the IAP specified.
+*/
+	{
+	const TDesC& bearerType = iIapRec->iBearerType;
+	const TDesC& serviceType = iIapRec->iServiceType;
+
+	aElement->SetElementId(aElementId);
+	TInt recordId = -1;
+
+    if (aElementId == KCDTIdBearerAgent)
+        {
+        // Special case for reading the Agent name.  We have to determine the tableId
+        // (by comparison of bearerType string) and then set the recordId from the
+        // bearer record number.
+        TMDBElementId tableId = 0;
+        User::LeaveIfError(ConvertBearerTypeToTableId(bearerType, tableId));
+        aElement->SetTypeId(KCDTIdBearerAgent | tableId);
+        recordId = iIapRec->iBearer;
+        }
+    else
+        {
+        TInt elementId = aElement->TableId();
+    	switch (elementId) // note: relies on above SetElementId() having been called
+    		{
+    	case KCDTIdGlobalSettingsRecord:
+    		recordId = 1; // only one record for global settings table
+    		break;
+
+    	//Location Tables
+    	case KCDTIdLocationRecord:
+    		recordId = iIapRec->iLocation;
+    	    break;
+
+
+    	// Service Tables
+    	case KCDTIdDialOutISPRecord:
+    	    if (serviceType.Compare(TPtrC(KCDTypeNameDialOutISP)) == 0)
+    	        {
+        	    recordId = iIapRec->iService;
+    	        }
+    	    break;
+
+    	case KCDTIdDialInISPRecord:
+    	    if (serviceType.Compare(TPtrC(KCDTypeNameDialInISP)) == 0)
+    	        {
+        	    recordId = iIapRec->iService;
+    	        }
+    	    break;
+
+    	case KCDTIdLANServiceRecord:
+    	    if (serviceType.Compare(TPtrC(KCDTypeNameLANService)) == 0)
+    	        {
+        	    recordId = iIapRec->iService;
+    	        }
+    	    break;
+
+    	case KCDTIdVPNServiceRecord:
+    	    if (serviceType.Compare(TPtrC(KCDTypeNameVPNService)) == 0)
+    	        {
+        	    recordId = iIapRec->iService;
+    	        }
+    	    break;
+
+        case KCDTIdOutgoingGprsRecord:
+        case KCDTIdIncomingGprsRecord:
+    	    if (serviceType.Compare(TPtrC(KCDTypeNameOutgoingWCDMA)) == 0 ||
+    	        serviceType.Compare(TPtrC(KCDTypeNameIncomingWCDMA)) == 0 )
+    	        {
+        	    recordId = iIapRec->iService;
+    	        }
+    	    break;
+
+        // Bearer Tables
+    	case KCDTIdModemBearerRecord:
+    	    if (bearerType.Compare(TPtrC(KCDTypeNameModemBearer)) == 0)
+    	        {
+        	    recordId = iIapRec->iBearer;
+    	        }
+    	    break;
+
+    	case KCDTIdLANBearerRecord:
+    	    if (bearerType.Compare(TPtrC(KCDTypeNameLANBearer)) == 0)
+    	        {
+        	    recordId = iIapRec->iBearer;
+    	        }
+    	    break;
+
+    	case KCDTIdVirtualBearerRecord:
+    	    if (bearerType.Compare(TPtrC(KCDTypeNameVirtualBearer)) == 0)
+    	        {
+        	    recordId = iIapRec->iBearer;
+    	        }
+    	    break;
+
+
+        // Other tables
+        case KCDTIdUmtsR99QoSAndOnTableRecord:
+    	    if (serviceType.Compare(TPtrC(KCDTypeNameOutgoingWCDMA)) == 0 ||
+    	        serviceType.Compare(TPtrC(KCDTypeNameIncomingWCDMA)) == 0 )
+    	        {
+    	        if (iUmtsR99QoSAndOnRecId == -1)
+        	        {
+                    CCDOutgoingGprsRecord* packetRec = static_cast<CCDOutgoingGprsRecord*>
+                                        (CCDRecordBase::RecordFactoryL(KCDTIdOutgoingGprsRecord));
+                    CleanupStack::PushL(packetRec);
+                    packetRec->SetRecordId(iIapRec->iService);
+            	    packetRec->LoadL(*iDbs);
+            	    iUmtsR99QoSAndOnRecId = packetRec->iUmtsR99QoSAndOnTable;
+            	    CleanupStack::PopAndDestroy(packetRec);
+        	        }
+        	    recordId = iUmtsR99QoSAndOnRecId;
+    	        }
+    	    break;
+
+    	default:
+    		User::Leave(KErrNotFound);
+    		}
+        }
+
+	if (recordId != -1)
+	    {
+    	aElement->SetRecordId(recordId);
+	    }
+	else
+	    {
+	    User::Leave(KErrNotFound);
+	    }
+	}
+
+TInt CCommsDatIapView::ConvertBearerTypeToTableId(const TDesC& aBearerType, TMDBElementId& aElementId)
+    {
+    if (aBearerType.Compare(TPtrC(KCDTypeNameModemBearer)) == 0)
+        {
+   	    aElementId = KCDTIdModemBearerRecord;
+   	    return KErrNone;
+        }
+    else
+    if (aBearerType.Compare(TPtrC(KCDTypeNameLANBearer)) == 0)
+	    {
+        aElementId = KCDTIdLANBearerRecord;
+        return KErrNone;
+	    }
+	else
+    if (aBearerType.Compare(TPtrC(KCDTypeNameVirtualBearer)) == 0)
+	    {
+    	aElementId = KCDTIdVirtualBearerRecord;
+    	return KErrNone;
+	    }
+	else
+	    {
+	    return KErrNotFound;
+	    }
+    }
+
+TInt CCommsDatIapView::ConvertServiceTypeToTableId(const TDesC& aServiceType, TMDBElementId& aElementId)
+    {
+    if (aServiceType.Compare(TPtrC(KCDTypeNameDialOutISP)) == 0)
+        {
+        aElementId = KCDTIdDialOutISPRecord;
+        return KErrNone;
+        }
+	else if (aServiceType.Compare(TPtrC(KCDTypeNameDialInISP)) == 0)
+        {
+	    aElementId = KCDTIdDialInISPRecord;
+        return KErrNone;
+        }
+	else if (aServiceType.Compare(TPtrC(KCDTypeNameLANService)) == 0)
+        {
+	    aElementId = KCDTIdLANServiceRecord;
+        return KErrNone;
+        }
+	else if (aServiceType.Compare(TPtrC(KCDTypeNameVPNService)) == 0)
+        {
+	    aElementId = KCDTIdVPNServiceRecord;
+        return KErrNone;
+        }
+    else if (aServiceType.Compare(TPtrC(KCDTypeNameOutgoingWCDMA)) == 0)
+        {
+	    aElementId = KCDTIdOutgoingGprsRecord;
+        return KErrNone;
+        }
+    else if (aServiceType.Compare(TPtrC(KCDTypeNameIncomingWCDMA)) == 0)
+        {
+	    aElementId = KCDTIdIncomingGprsRecord;
+        return KErrNone;
+        }
+
+	return KErrNotFound;
+    }
+
+void CCommsDatIapView::IntFieldTypeCheckL(TInt aElementId)
+	{
+	CommsDat::TCDFieldValueTypes commsdat_type = static_cast<CommsDat::TCDFieldValueTypes>(
+									CommsDat::CommsDatSchemaV1_1::GetFieldTypeInfoL(aElementId));
+
+	if (CommsDat::EUint32 != commsdat_type &&
+		CommsDat::EInt != commsdat_type &&
+		CommsDat::ELink != (commsdat_type & CommsDat::ELink))
+		{
+		User::Leave(KErrBadName);
+		}
+	}
+
+void CCommsDatIapView::BoolFieldTypeCheckL(TInt aElementId)
+	{
+	CommsDat::TCDFieldValueTypes commsdat_type = static_cast<CommsDat::TCDFieldValueTypes>(
+									CommsDat::CommsDatSchemaV1_1::GetFieldTypeInfoL(aElementId));
+
+	if (CommsDat::EBool != commsdat_type)
+		{
+		User::Leave(KErrBadName);
+		}
+	}
+
+void CCommsDatIapView::TextOrBinFieldTypeCheckL(TInt aElementId)
+	{
+	CommsDat::TCDFieldValueTypes commsdat_type = static_cast<CommsDat::TCDFieldValueTypes>(
+									CommsDat::CommsDatSchemaV1_1::GetFieldTypeInfoL(aElementId));
+
+	if (CommsDat::EText != commsdat_type &&
+		CommsDat::EMedText != commsdat_type &&
+		CommsDat::ELongText != commsdat_type &&
+		CommsDat::EDesC8 != commsdat_type)
+		{
+		User::Leave(KErrBadName);
+		}
+	}
+
+