--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwtools/preparedefaultcommsdatabase/src/CommsDatMapper.cpp Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,2258 @@
+// Copyright (c) 2004-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:
+// Mapping rules for deprecated elements in the comms database schema
+// All data in file
+// CONTENTS OF FILE
+// 1/ Utilities
+// 2/ CCDMapper Base class implementation
+// 3/ Mapper classes for individual elements in the database
+// a) CCDMapperGlobalSettingsRecord
+// b) CCDMapperIAPPrioritySelectionPolicyRecord
+// c) CCDMapperAccessPointRecord
+// MAINTENANCE - some rules may need adding or amending whenever the database schema changes
+//
+//
+
+/**
+ @file CommsDatMapper.cpp
+ @internalComponent
+*/
+
+
+#include "CommsDatInternalDefs.h"
+#include <commsdattypesv1_1.h>
+#include "CommsDatMapper.h"
+#include <comms-infras/commsdatschema.h>
+#include <commsdat.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <commsdattypesv1_1_partner.h>
+#include <commsdat_partner.h>
+#endif
+
+using namespace Meta;
+using namespace CommsDatInternal;
+using namespace CommsDat;
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+//anonymous namespace
+namespace
+ {
+ const TInt NetworkBaseTagId = 10000;
+ }
+#endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+/***************************************************************************************
+ * 1/ Utilities
+ */
+
+
+
+TBool Changed(const CMDBElement& aElement)
+/*
+Utility function to check if an element has been changed
+@internalComponent
+*/
+ {
+ if ( aElement.ElementId() & KCDChangedFlag )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+
+void Sync(CMDBElement& aElement)
+/*
+Utility function to mark an element in sync with Database
+@internalComponent
+*/
+ {
+ aElement.SetElementId(aElement.ElementId() & ~KCDChangedFlag);
+ }
+
+
+
+TInt CCDMapper::FindLinkElementIdL(TInt aVal, TInt aTargetTable)
+/*
+utility for mapping link fields - when link fields fixed this will be unnecessary
+*/ {
+ TInt ret(KErrNone);
+
+ if (KLinkableTag & aVal)
+ {
+ // this is a link by tag so need to do a find for the tag in the target field
+ CMDBField<TUint32>* tagField = new (ELeave) CMDBField<TUint32>(aTargetTable |KCDTIdRecordTag);
+ CleanupStack::PushL(tagField);
+
+ *tagField = aVal;
+
+ if (tagField->FindL(iSession.iOwner))
+ {
+ ret = (tagField->ElementId() | KCDMaskShowRecordTypeAndId);
+ }
+
+ CleanupStack::PopAndDestroy(tagField);
+
+ }
+
+ // add a check for the record id too.
+
+ // otherwise the value already gives the element id directly
+
+ return ret;
+ }
+
+
+/****************************************************************************************
+ * 2/ CCDMapper base class implementation
+ ***************************************************************************************/
+
+CCDMapper::CCDMapper(TMDBElementId aElementId, CMDBElement& aElement,CMDBSessionImpl& aSession
+ ,const TOperation& aOperation)
+ : CMDBRecordBase(aElementId)
+ , iElement(aElement)
+ , iSession(aSession)
+ , iOperation(aOperation)
+ {
+ iSession.iMapping = ETrue;
+ }
+
+
+CCDMapper::~CCDMapper()
+ {
+ iSession.iMapping = EFalse;
+ }
+
+
+
+CCDMapper* CCDMapper::MaybeCreateMapperLC(CMDBElement& aElement,CMDBSessionImpl& aSession, const TOperation& aOperation)
+/*
+Static Factory function.
+
+ Creates a mapping object of the appropriate type
+
+@internalComponent
+*/
+ {
+ if (aSession.UsingLatestVersion() || aSession.iMapping)
+ {
+ // only map if client has asked to manage deprecated fields
+ // and if no mapping or validation going on already
+ return NULL;
+ }
+
+ if(CommsDat::CommsDatSchema::IsTable(aElement.ElementId()))
+ {
+ // only need mapper for records and fields, not tables
+ return NULL;
+ }
+
+ CCDMapper* mapper = NULL;
+
+ switch((TUint32)aElement.TypeId() & KCDMaskShowRecordType)
+ {
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+
+ case KCDTIdGlobalSettingsRecord:
+ {
+ mapper = new(ELeave)CCDMapperGlobalSettingsRecord(aElement,aSession, aOperation);
+ break;
+ }
+
+ case KCDTIdIapPrioritySelectionPolicyRecord:
+ {
+ mapper = new(ELeave)CCDMapperIAPPrioritySelectionPolicyRecord(aElement,aSession, aOperation);
+ break;
+ }
+
+ case KCDTIdAccessPointRecord:
+ {
+ mapper = new(ELeave)CCDMapperAccessPointRecord(aElement,aSession, aOperation);
+ break;
+ }
+
+#endif // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+
+ default :
+ {
+ // Nothing to do so exit quickly
+ mapper = NULL;
+ }
+ }
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+
+ if(! mapper)
+ {
+ return NULL;
+ }
+
+ if (mapper->NeedsMapping(aElement))
+ {
+
+ CleanupStack::PushL(mapper);
+ mapper->ConstructL();
+ }
+ else
+ {
+ delete mapper;
+ mapper = NULL;
+ }
+
+#endif // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+
+ return mapper;
+ }
+
+
+
+
+void CCDMapper::ConstructL()
+/*
+following a unique set of mapping rules implemented in derived classes and
+using information from both the input element and the database
+1/ Set up record id(s) for elements in the map
+2/ where deprecated elements in the input element (iElement) have values that
+have been changed by the user, populate the values of the corresponding map element(s)
+@internalTechnology
+*/
+ {
+ // Default is nothing to construct
+ return;
+ }
+
+void CCDMapper::PrepareToStoreL()
+ {
+ // Default is nothing to prepare
+ return;
+ }
+
+
+//TBool CCDMapper::Mapped(TMDBElementId aElementId)
+/*
+Return ETrue if the sub-element (always a field) is mapped.
+Otherwise return EFalse
+
+@internalTechnology
+*/
+ // {
+ // return aElementId != aElementId;
+ // }
+
+
+void CCDMapper::MapResultsL()
+/*
+Set up record id(s) for the map and populate each entry in the map
+following a unique set of mapping rules (implemented in derived classes)
+using information from both the input element and the database
+
+@internalTechnology
+*/
+ {
+ // Default is nothing to map
+ return;
+ }
+
+/*virtual*/ void CCDMapper::PostMappingsL()
+/*
+@internalTechnology
+*/
+ {
+ // Default is nothing to process...
+ (void)iOperation; //just to bypass the comp. warning
+ return;
+ }
+
+/*virtual*/ void CCDMapper::PreMappingsL()
+/*
+@internalTechnology
+*/
+ {
+ // Default is nothing to process...
+ (void)iOperation; //just to bypass the comp. warning
+ return;
+ }
+
+/*****************************************************************************************
+ * 3/ MAPPER CLASSES FOR INDIVIDUAL ELEMENTS
+ *****************************************************************************************/
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+
+/************************* 3/ a) Mapper for GlobalSettings Table ************************************
+ * KCDTIdGlobalSettingsRecord
+ *
+ * These 2 fields are now stored against the Default Tier record in the Tier table
+ * DefaultSnap KCDTIdDefaultSnap CCDGlobalSettingsRecord::iDefaultSnap
+ * PromptUser KCDTIdPromptForSnap CCDGlobalSettingsRecord::iPromptForSnap
+ *
+ * Corresponding fields in the Tier table (KCDTIdTierRecord) are
+ * DefaultSnap KCDTIdDefaultAccessPoint CCDTierRecord::iDefaultAccessPoint
+ * PromptUser KCDTIdPromptUser CCDTierRecord::iPromptUser
+ *
+ * The mapping relies on the presence of the DefaultTier field in the GlobalSettings Table
+ * DefaultTier KCDTIdDefaultTier CCDGlobalSettingsRecord::iDefaultTier
+ *
+ * The DefaultTier must always be present as a real or default value in the GlobalSettings
+ * Table. A preface config file may be the best way to set this value.
+ *
+ * If KCDTIdDefaultTier field is not present in the GlobalSettings Table,
+ * these fields cannot be mapped [They could be set as default values in Template of Tier Table?]
+ */
+#define KCDTIdGlobalSettingsRecordMapper 9879
+START_ATTRIBUTE_TABLE( CCDMapperGlobalSettingsRecord, KCDTIdGlobalSettingsRecordMapper, KCDTIdGlobalSettingsRecordMapper)
+ X_REGISTER_ATTRIBUTE( CCDMapperGlobalSettingsRecord, iPromptUser, TMDBNum)
+ //X_REGISTER_ATTRIBUTE( CCDMapperGlobalSettingsRecord, iDefaultAccessPoint, TMDBNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperGlobalSettingsRecord, iDefaultAccessPoint, TMDBLinkNum)
+END_ATTRIBUTE_TABLE()
+
+CCDMapperGlobalSettingsRecord::CCDMapperGlobalSettingsRecord(CMDBElement& aElement,CMDBSessionImpl& aSession, const TOperation& aOperation)
+: CCDMapper(0, aElement,aSession,aOperation),
+ iPromptUser(KCDTIdPromptUser),
+ iDefaultAccessPoint(KCDTIdDefaultAccessPoint)
+ {}
+
+
+void CCDMapperGlobalSettingsRecord::ConstructL()
+/*
+Set up record id(s) for elements in the map and populate the values of
+each each element in the map following a unique set of mapping rules
+(implemented in derived classes) using information from both the input
+element and the database
+
+ * Rules
+ a) find DefaultTier in GlobalSettings record (from inputElement or database)
+ b) use the value to give the record id of the Tier record
+
+@internalComponent
+*/
+ {
+ CMDBRecordLink<CCDTierRecord> *defaultTier = new(ELeave) CMDBRecordLink<CCDTierRecord>(KCDTIdGlobalSettingsRecord | KCDTIdDefaultTier);
+ CleanupStack::PushL(defaultTier);
+ defaultTier->SetRecordId(1);
+
+ defaultTier->LoadL(iSession.iOwner);
+
+ if (CommsDat::CommsDatSchema::IsRecord(iElement.ElementId()))
+ {
+ CCDGlobalSettingsRecord& globalSettings = static_cast<CCDGlobalSettingsRecord&>(iElement);
+
+ if (! globalSettings.iDefaultTier.IsNull())
+ {
+ defaultTier->SetL(globalSettings.iDefaultTier);
+ }
+ }
+
+ TMDBElementId targetId = CommsDatSchema::GetLinkIdL(iSession.iOwner, defaultTier->ElementId(), defaultTier->GetL(), KCDTIdTierRecord/*, NULL*/);
+
+ CleanupStack::PopAndDestroy(defaultTier);
+
+ SetRecordId(targetId);
+
+ // Now populate the data from the input element
+ CreateMapL();
+ }
+
+
+void CCDMapperGlobalSettingsRecord::CreateMapL()
+/*
+Populate the values of each each element in the map from data in the input element
+following a unique set of mapping rules.
+NB. Should only use data in the input element (iElement), not the database
+The record ids of the mapping elements have already been set in InitMapL
+
+@internalComponent
+*/
+ {
+ //switch (iElement.TypeId())
+ switch (iElement.ElementId() & KCDMaskShowType)
+ {
+
+ case KCDTIdGlobalSettingsRecord | KCDMaskShowFieldType:
+ {
+ CCDGlobalSettingsRecord* globalSettings = static_cast<CCDGlobalSettingsRecord*>(&iElement);
+
+ if (Changed(globalSettings->iDefaultSnap))
+ {
+ /* There are cases when the 'DefaultSnap' field in the GS record
+ * is 0 (explicitly). In this case the GS mapper checks wheather
+ * the given field is changed or not (it's changed) BUT during the
+ * STORE operation we don't want to store and map the 0 value because
+ * this would mean to overwrite the default AP field in the NetworkTier,
+ * which is set to a default value form the meshpreface.cfg file.
+ * So the check here checks:
+ * if we are in a STORE operation and the DefualtSNAP field in the GS
+ * record is 0 then we change the field back to the 'unchanged state'.*/
+ if (0 == globalSettings->iDefaultSnap.GetL() &&
+ EStore == iOperation)
+ {
+ //change back the field to the 'unchanged' state
+ iDefaultAccessPoint.SetElementId(iDefaultAccessPoint.ElementId() & ~KCDChangedFlag);
+ }
+ else
+ {
+ //Assuming that the defaultSnap id the Snap config file is an AP record id
+ iDefaultAccessPoint.SetL(KCDTIdAccessPointRecord | (globalSettings->iDefaultSnap << 8));
+ }
+ }
+
+ if (Changed(globalSettings->iPromptForSnap))
+ {
+ iPromptUser.SetL(globalSettings->iPromptForSnap);
+ }
+
+ break;
+ }
+ //case KCDTIdDefaultAccessPoint :
+ case KCDTIdDefaultSnap :
+ {
+ if (Changed(iElement))
+ {
+ iDefaultAccessPoint.SetL(*static_cast<CMDBRecordLinkBase*>(&iElement));
+ }
+ break;
+ }
+ case KCDTIdPromptForSnap :
+ {
+ if (Changed(iElement))
+ {
+ iPromptUser.SetL(*static_cast<CMDBField<TBool>*>(&iElement));
+ }
+ break;
+ }
+ default :
+ {
+ ASSERT(KErrNotFound); // hmmm... shouldn't get here.
+ User::Leave(KErrNotFound);
+ }
+ }
+ }
+
+/**
+ if the mapped fields are already existing in the Tier record on the Network
+ level, they should be deleted.
+*/
+/*virtual*/ void CCDMapperGlobalSettingsRecord::PrepareToStoreL()
+ {
+ //Create the storage for the original GlobalSettings record...
+ iSession.MaybeCreateNodeL(iElement);
+
+ if (Changed(iPromptUser))
+ {
+ iPromptUser.SetRecordId(RecordId());
+ iPromptUser.DeleteL(iSession.iOwner);
+ }
+
+ if (Changed(iDefaultAccessPoint))
+ {
+ iDefaultAccessPoint.SetRecordId(RecordId());
+ iDefaultAccessPoint.DeleteL(iSession.iOwner);
+ }
+
+ }
+
+TBool CCDMapperGlobalSettingsRecord::Mapped(TMDBElementId aElementId)
+/*
+Return ETrue for any element that is mapped.
+
+@internalComponent
+*/
+ {
+ //switch(aElementId & KCDMaskShowFieldType)
+ switch(aElementId & KCDMaskShowType)
+ {
+ case KCDTIdDefaultSnap :
+ case KCDTIdPromptForSnap :
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+TBool CCDMapperGlobalSettingsRecord::NeedsMapping(CMDBElement& aElement)
+/*
+Return ETrue for any element that is mapped.
+
+@internalComponent
+*/
+ {
+ if(CommsDat::CommsDatSchema::IsRecord(iElement.ElementId()))
+ {
+ //this is a record mapping and the session used is not the latest. So let's have a mapper...
+ /*CCDGlobalSettingsRecord& globalSettings = static_cast<CCDGlobalSettingsRecord&>(iElement);
+
+ if (Changed(globalSettings.iDefaultSnap) ||
+ Changed(globalSettings.iPromptForSnap) )
+ {
+ return ETrue;
+ }*/
+ return ETrue;
+ }
+
+ return Mapped(aElement.ElementId());
+ }
+
+
+void CCDMapperGlobalSettingsRecord::MapResultsL()
+/*
+Map results to original element
+
+@internalComponent
+*/
+ {
+ //switch (iElement.TypeId())
+ switch (iElement.ElementId() & KCDMaskShowType)
+ {
+
+ case KCDTIdGlobalSettingsRecord | KCDMaskShowFieldType:
+ {
+ CCDGlobalSettingsRecord* globalSettings = static_cast<CCDGlobalSettingsRecord*>(&iElement);
+
+ globalSettings->iDefaultSnap.SetL(iDefaultAccessPoint);
+ //give back just the record number of the linked AP - as in the good old days...
+ CMDBRecordLink<CCDAccessPointRecord>* defaultSnap = static_cast<CMDBRecordLink<CCDAccessPointRecord>*>(&(globalSettings->iDefaultSnap));
+ *defaultSnap = (*defaultSnap & KCDMaskShowRecordId) >> 8;
+ Sync(globalSettings->iDefaultSnap);
+
+ globalSettings->iPromptForSnap.SetL(iPromptUser);
+ Sync(globalSettings->iPromptForSnap);
+
+ break;
+ }
+ case KCDTIdDefaultSnap :
+
+ {
+ //CMDBField<TInt>* defaultSnap = static_cast<CMDBField<TInt>*>(&iElement);
+ CMDBRecordLink<CCDAccessPointRecord>* defaultSnap = static_cast<CMDBRecordLink<CCDAccessPointRecord>*>(&iElement);
+ defaultSnap->SetL(iDefaultAccessPoint);
+ //give back just the record number of the linked AP - as in the good old days...
+ *defaultSnap = (*defaultSnap & KCDMaskShowRecordId) >> 8;
+ Sync(*defaultSnap);
+ break;
+ }
+ case KCDTIdPromptForSnap :
+ {
+ CMDBField<TBool>* promptUser = static_cast<CMDBField<TBool>*>(&iElement);
+ promptUser->SetL(iPromptUser);
+ Sync(*promptUser);
+ break;
+ }
+ default :
+ {
+ ASSERT(KErrNotFound); // hmmm... shouldn't get here.
+ User::Leave(KErrNotFound);
+ }
+ }
+ }
+
+
+/************************* Mapper for IAPSelection Table **************************************
+ * KCDTIdIapPrioritySelectionPolicyRecord CCDIAPPrioritySelectionPolicyRecord
+ *
+ * The IAP Selection table is deprecated and completely replaced by the APSelectionTable,
+ *
+ * KCDTIdApPrioritySelectionPolicyRecord CCDIAPPrioritySelectionPolicyRecord
+ *
+ * As IAPs map directly to APs, the IAP Selection Table that links to IAPs can map directly to
+ * an AP selecton Table that points to APs that each map to a single IAP
+ *
+ * The mapping can be very simple because the record id, name, tag and so on can be identical
+ */
+
+#define KCDTIdIapPrioritySelectionPolicyRecordMapper 9880
+START_ATTRIBUTE_TABLE( CCDMapperIAPPrioritySelectionPolicyRecord, KCDTIdIapPrioritySelectionPolicyRecordMapper, KCDTIdIapPrioritySelectionPolicyRecordMapper)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp1, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp2, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp3, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp4, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp5, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp6, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp7, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp8, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp9, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp10, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp11, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp12, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp13, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp14, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iAp15, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iApCount, TMDBNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iRecordTag, TMDBNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperIAPPrioritySelectionPolicyRecord, iRecordName, TMDBText)
+END_ATTRIBUTE_TABLE()
+
+CCDMapperIAPPrioritySelectionPolicyRecord::CCDMapperIAPPrioritySelectionPolicyRecord(CMDBElement& aElement,CMDBSessionImpl& aSession, const TOperation& aOperation)
+ : CCDMapper(KCDTIdApPrioritySelectionPolicyRecord | (aElement.ElementId() & KCDMaskShowRecordId), aElement, aSession, aOperation),
+ iAp1(KCDTIdAp1),
+ iAp2(KCDTIdAp2),
+ iAp3(KCDTIdAp3),
+ iAp4(KCDTIdAp4),
+ iAp5(KCDTIdAp5),
+ iAp6(KCDTIdAp6),
+ iAp7(KCDTIdAp7),
+ iAp8(KCDTIdAp8),
+ iAp9(KCDTIdAp9),
+ iAp10(KCDTIdAp10),
+ iAp11(KCDTIdAp11),
+ iAp12(KCDTIdAp12),
+ iAp13(KCDTIdAp13),
+ iAp14(KCDTIdAp14),
+ iAp15(KCDTIdAp15),
+ iApCount(KCDTIdApCount),
+ iRecordTag(KCDTIdRecordTag | KCDTIdApPrioritySelectionPolicyRecord),
+ iRecordName(KCDTIdRecordName | KCDTIdApPrioritySelectionPolicyRecord)
+ {
+ //Check whether the original record is set as a 'KCDNewRecordRequest'...
+ if (CommsDatSchema::IsNewRecordRequest(iElement.ElementId()))
+ {
+ SetRecordId(KCDNewRecordRequest);
+ }
+ }
+
+CCDMapperIAPPrioritySelectionPolicyRecord::~CCDMapperIAPPrioritySelectionPolicyRecord()
+ {
+ delete origMappedDataInDB;
+ }
+
+void CCDMapperIAPPrioritySelectionPolicyRecord::ConstructL()
+/*
+Iterate through the mapper element and populate each entry
+following a unique set of mapping rules.
+The element is populated by information from both the input element and the database
+ConstructL is performed on data input and retrieval. Mustn't include calls specific to only one or the other
+@internalComponent
+*/
+ {
+ switch (iElement.TypeId())
+ {
+ case KCDTIdRecordTag :
+ {
+ if (Changed(iElement))
+ {
+ iRecordTag.SetL(*static_cast<CMDBField<TInt>*>(&iElement));
+ }
+ break;
+ }
+ case KCDTIdRecordName :
+ {
+ if (Changed(iElement))
+ {
+ iRecordName.SetL(*static_cast<CMDBField<TDesC>*>(&iElement));
+ }
+ break;
+ }
+ case KCDTIdIapCount :
+ {
+ if (Changed(iElement))
+ {
+ iApCount.SetL(*static_cast<CMDBField<TInt>*>(&iElement));
+ }
+ break;
+ }
+
+ case KCDTIdIapPrioritySelectionPolicyRecord | KCDMaskShowFieldType:
+ {
+
+ // NB. This function relies on APs being already present
+
+ //CMDBElement& thisElement = static_cast<CMDBElement&>(*this);
+
+ CCDIAPPrioritySelectionPolicyRecord& inputElement = static_cast<CCDIAPPrioritySelectionPolicyRecord&>(iElement);
+
+ if (Changed(inputElement.iRecordTag))
+ {
+ iRecordTag.SetL(inputElement.iRecordTag);
+ }
+ if (Changed(inputElement.iRecordName))
+ {
+ iRecordName.SetL(inputElement.iRecordName);
+ }
+ if (Changed(inputElement.iIapCount))
+ {
+ iApCount.SetL(inputElement.iIapCount);
+ }
+
+ // as every other field is the same type and the mapping rule is identical for each
+ // and mapping is 1:1, just iterate through the fields and map each one
+ TInt fieldCounter(15); // only need to map this many fields
+
+ TMetaVTableIterator mapperAttribIter(this);
+ SVDataTableEntry const* mapperEntry = NULL;
+
+ TMetaVTableIterator inputAttribIter(&iElement);
+ SVDataTableEntry const* inputEntry = NULL;
+
+ // NB this only works in this case because entries map exactly....
+ while ( (mapperEntry = mapperAttribIter++) != NULL &&
+ (inputEntry = inputAttribIter++) != NULL &&
+ fieldCounter-- > 0 )
+ {
+ CMDBField<TUint32>* inputFieldPtr = reinterpret_cast<CMDBField<TUint32>*>(iElement.GetAttribPtr(inputEntry->iOffset));
+ //CMDBRecordLink<CCDIAPRecord>* inputFieldPtr = reinterpret_cast<CMDBRecordLink<CCDIAPRecord>*>(GetAttribPtr(mapperEntry->iOffset));
+ //if (inputFieldPtr && Changed(*inputFieldPtr) )
+ //we need to check the changed flag too -> somebody changes a link to 0...
+ if (inputFieldPtr/* && ((*inputFieldPtr != NULL) || Changed(*inputFieldPtr)) */)
+ {
+ CMDBRecordLink<CCDAccessPointRecord>* mapperFieldPtr = reinterpret_cast<CMDBRecordLink<CCDAccessPointRecord>*>(GetAttribPtr(mapperEntry->iOffset));
+ if (mapperFieldPtr)
+ {
+ if ( ( (*inputFieldPtr) & KCDMaskShowType ) == 0 &&
+ ( (*inputFieldPtr) & KLinkableTag ) == 0 )
+ //there is only a number for the IAP link in the table...
+ {
+ if (*inputFieldPtr == 0)
+ {
+ //special case, the link is 0
+ mapperFieldPtr->SetL(*inputFieldPtr);
+
+ if (!Changed(*inputFieldPtr))
+ {
+ //this means that we have to remove the changed flag from our mapped field
+ //because orginally no value was set for the input field that's why it's 0.
+ mapperFieldPtr->SetElementId(mapperFieldPtr->ElementId() & ~KCDChangedFlag);
+ }
+ }
+ else
+ {
+ mapperFieldPtr->SetL(*inputFieldPtr | KLinkableTag);
+ }
+ }
+ else
+ //the link is correctly set:
+ //it's in Link.<TableName>.<TagId> OR
+ // <TableName>.<RecordId> format.
+ {
+ /*IMPORTANT: this code will work ONLY if the linking in the original
+ IAPPrioritySelectionPolicyTable is done by record ID.
+
+ If the linking is by TagId then a FindL is needed here...*/
+ if (!Changed(*inputFieldPtr))
+ {
+ //This means that there is a link field in the IAPPrioritySelPol record where
+ //the link field is correctly set but is't not changed. This means that this field
+ //is already stored in the DB. So we can try to read the already mapped element.
+ mapperFieldPtr->SetRecordId(iElement.RecordId());
+ TRAPD(err, mapperFieldPtr->LoadL(iSession.iOwner));
+ if (KErrNone != err)
+ {
+ //the field is not in the database. Is the client playing with us??
+ TUint field = *inputFieldPtr & KCDMaskShowRecordId;
+
+ mapperFieldPtr->SetL( (field >> 8) | KLinkableTag);
+ }
+ }
+ else
+ {
+ //this is a modified field
+ TUint field = *inputFieldPtr & KCDMaskShowRecordId;
+
+ mapperFieldPtr->SetL( (field >> 8) | KLinkableTag);
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ //find out which field is used in the IAPPriorityselPol record
+ CCDIAPPrioritySelectionPolicyRecord* iapPriorSelPol = static_cast<CCDIAPPrioritySelectionPolicyRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdIapPrioritySelectionPolicyRecord));
+ CleanupStack::PushL(iapPriorSelPol);
+
+ TInt fieldCounter(15); // only need to map this many fields
+
+ TMetaVTableIterator mapperAttribIter(this);
+ SVDataTableEntry const* mapperEntry = NULL;
+
+ TMetaVTableIterator inputAttribIter(iapPriorSelPol);
+ SVDataTableEntry const* inputEntry = NULL;
+
+ CMDBField<TUint32>* origInputFieldPtr = static_cast<CMDBField<TUint32>*>(&iElement);
+
+ // NB this only works in this case because entries map exactly....
+ while ( (mapperEntry = mapperAttribIter++) != NULL &&
+ (inputEntry = inputAttribIter++) != NULL &&
+ fieldCounter-- > 0 )
+ {
+ CMDBField<TUint32>* inputFieldPtr = reinterpret_cast<CMDBField<TUint32>*>(iapPriorSelPol->GetAttribPtr(inputEntry->iOffset));
+
+ TMDBElementId filteredOrigInputElemId = origInputFieldPtr->ElementId() & KCDMaskShowType;
+
+ if ( inputFieldPtr &&
+ inputFieldPtr->ElementId() == filteredOrigInputElemId )
+ {
+ CMDBRecordLink<CCDAccessPointRecord>* mapperFieldPtr = reinterpret_cast<CMDBRecordLink<CCDAccessPointRecord>*>(GetAttribPtr(mapperEntry->iOffset));
+ if (mapperFieldPtr)
+ {
+ if ( ( (*origInputFieldPtr) & KCDMaskShowType ) == 0 &&
+ ( (*origInputFieldPtr) & KLinkableTag ) == 0 )
+ //there is only a number for the IAP link in the table...
+ {
+ if (*origInputFieldPtr == 0)
+ {
+ //special case, the link is 0
+ mapperFieldPtr->SetL(*origInputFieldPtr);
+
+ if (!Changed(*origInputFieldPtr))
+ {
+ //this means that we have to remove the changed flag from our mapped field
+ //because orginally no value was set for the input field that's why it's 0.
+ mapperFieldPtr->SetElementId(mapperFieldPtr->ElementId() & ~KCDChangedFlag);
+ }
+ }
+ else
+ {
+ mapperFieldPtr->SetL(*origInputFieldPtr | KLinkableTag);
+ }
+ }
+ else
+ //the link is correctly set:
+ //it's in Link.<TableName>.<TagId> OR
+ // <TableName>.<RecordId> format.
+ {
+ /*IMPORTANT: this code will work ONLY if the linking in the original
+ IAPPrioritySelectionPolicyTable is done by record ID.
+
+ If the linking is by TagId then a FindL is needed here...*/
+ if (!Changed(*origInputFieldPtr))
+ {
+ //This means that there is a link field in the IAPPrioritySelPol record where
+ //the link field is correctly set but is't not changed. This means that this field
+ //is already stored in the DB. So we can try to read the already mapped element.
+ mapperFieldPtr->SetRecordId(iElement.RecordId());
+ TRAPD(err, mapperFieldPtr->LoadL(iSession.iOwner));
+ if (KErrNone != err)
+ {
+ //the field is not in the database. Is the client playing with us??
+ TUint field = *origInputFieldPtr & KCDMaskShowRecordId;
+
+ mapperFieldPtr->SetL( (field >> 8) | KLinkableTag);
+ }
+ }
+ else
+ {
+ //this is a modified field
+ TUint field = *origInputFieldPtr & KCDMaskShowRecordId;
+ if (field)
+ {
+ mapperFieldPtr->SetL( (field >> 8) | KLinkableTag);
+ }
+ else
+ {
+ mapperFieldPtr->SetL(0);
+ }
+ }
+ }
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(iapPriorSelPol);
+ break;
+ }
+ }
+ }
+
+void CCDMapperIAPPrioritySelectionPolicyRecord::PreMappingsL()
+ {
+ if ( KCDTIdRecordTag != iElement.TypeId() &&
+ KCDTIdRecordName != iElement.TypeId() &&
+ KCDTIdIapCount != iElement.TypeId() )
+ {
+ if (EFind == iOperation)
+ {
+ //we don't know the elementId of the orig container so we can't call LoadL
+ //from the input value we can find the link level AP. Following the link
+ //backwards we can find the IPProto level AP.
+ //1. find the already changed element in the mapper object
+ CMDBRecordLink<CCDAccessPointRecord>* apXLink = &(this->iAp1);
+ for (TInt i = 1; i<= MaxLinkCount; ++i)
+ {
+ if (Changed(*apXLink))
+ {
+ //this is the changed element
+ *apXLink = CommsDatSchema::GetLinkIdL(iSession.iOwner, apXLink->ElementId(), *apXLink, 0);
+
+ //at this point we know that what is the link level AP which is the pair of the IAP given as
+ //a value in the IAPPrioritySelPol link. Let's find the IPProto level AP which this link level
+ //AP is linking from.
+ CMDBField<TInt>* linkLevelAPTagId = new(ELeave) CMDBField<TInt>(*apXLink | KCDTIdRecordTag);
+ CleanupStack::PushL(linkLevelAPTagId);
+
+ linkLevelAPTagId->SetRecordId((*apXLink & KCDMaskShowRecordId) >> 8);
+ linkLevelAPTagId->LoadL(iSession.iOwner);
+
+ CMDBRecordSet<CCDAccessPointRecord>* apRecordSet = new(ELeave) CMDBRecordSet<CCDAccessPointRecord>(KCDTIdAccessPointRecord);
+ CleanupStack::PushL(apRecordSet);
+
+ CCDAccessPointRecord* apRecord = static_cast<CCDAccessPointRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdAccessPointRecord));
+ CleanupStack::PushL(apRecord);
+
+ apRecord->iCustomSelectionPolicy.SetL(*linkLevelAPTagId);
+
+ /* Find all of the AccessPoint records records in the database which have the given
+ * customSelectionPolicy value. It's VERY VERY VERY expensive. However this is the only way we can
+ * search back the links from the link level up to the APPrioritySelPol record.
+ */
+ apRecordSet->iRecords.AppendL(apRecord);
+
+ //the ownership is at the recordset already
+ //CleanupStack::PopAndDestroy(apRecord);
+ CleanupStack::Pop(apRecord);
+
+ TInt recCount = 0;
+ if(apRecordSet->FindL(iSession.iOwner))
+ {
+ recCount = apRecordSet->iRecords.Count();
+ }
+ if (recCount > 0)
+ {
+ //we have records with the given customSelectionPolicy value
+ //now have to find that which accesspoint elementID ws set in the given position of the mapper object
+ //originally.
+
+ CCDAPPrioritySelectionPolicyRecord* probeApPrioritySelPol = static_cast<CCDAPPrioritySelectionPolicyRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdApPrioritySelectionPolicyRecord));
+ CleanupStack::PushL(probeApPrioritySelPol);
+
+ //we know that which field was modified originally
+ CMDBRecordLink<CCDAccessPointRecord>* probeField = &(probeApPrioritySelPol->iAp1);
+
+ //position the field correctly
+ for (TInt j = 1; j < i; ++j)
+ {
+ ++probeField;
+ }
+
+ TBool found = EFalse;
+ for (TInt j = 0; (j < apRecordSet->iRecords.Count()) && !found; ++j)
+ {
+ probeField->SetL(apRecordSet->iRecords[j]->ElementId());
+ if (probeApPrioritySelPol->FindL(iSession.iOwner))
+ {
+ found = ETrue;
+ }
+ }
+
+ if (found)
+ {
+ //ok, got the correct record
+ apXLink->SetL(*probeField);
+ }
+ else
+ {
+ // no apprioritySelPol record found with the given accesspoint link
+ //User::Leave(KErrNotFound);
+ return;
+ }
+
+ CleanupStack::PopAndDestroy(probeApPrioritySelPol);
+ }
+ else
+ {
+ //no records were found with the given customSelectionPolicy value
+ //User::Leave(KErrNotFound);
+ return;
+ }
+
+ CleanupStack::PopAndDestroy(apRecordSet);
+ CleanupStack::PopAndDestroy(linkLevelAPTagId);
+ }
+ ++apXLink;
+ }
+ }
+ else
+ {
+ //load the original mapped element.
+ origMappedDataInDB = static_cast<CCDAPPrioritySelectionPolicyRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdApPrioritySelectionPolicyRecord));
+ origMappedDataInDB->SetRecordId(iElement.RecordId());
+
+ origMappedDataInDB->LoadL(iSession.iOwner);
+
+ CCDAPPrioritySelectionPolicyRecord* origMappedRecord = static_cast<CCDAPPrioritySelectionPolicyRecord*>(origMappedDataInDB);
+ if ( KCDMaskShowFieldType != (iElement.ElementId() & KCDMaskShowFieldType) )
+ {
+ //this is a field. What happens here is we fill up the mapper with the mapped object
+ //already stored in the db except that field which is currently changed and already set in the
+ //ConstructL of the mapper.
+ CMDBRecordLink<CCDAccessPointRecord>* origMappedFieldPtr = &(origMappedRecord->iAp1);
+ CMDBRecordLink<CCDAccessPointRecord>* currentMappedFieldPtr = &(this->iAp1);
+
+ for (TInt i = 1; i <= MaxLinkCount; ++i)
+ {
+ if (!Changed(*currentMappedFieldPtr) && currentMappedFieldPtr->IsNull())
+ {
+ //it's not the field which has been changed so fill up from the DB
+ currentMappedFieldPtr->SetL(*origMappedFieldPtr);
+ currentMappedFieldPtr->SetElementId(currentMappedFieldPtr->ElementId() & ~ KCDChangedFlag);
+ //it's possible that the field value is 0 -> so remove the not_null flag in this case
+ if (0 == *currentMappedFieldPtr)
+ {
+ currentMappedFieldPtr->SetElementId(currentMappedFieldPtr->ElementId() & ~ KCDNotNullFlag);
+ }
+ }
+ else
+ {
+ //there is a changed element
+ if (EDelete == iOperation)
+ {
+ //this is a tricky case here. There is a DeleteL call on a field in some IAPPrioritySelPol
+ //record. Since the mapping is record based we cannot delete the whole record (I mean the
+ //mapped APPrioritySelPol record) so we have to change the elementId of the mapper object
+ //because wwithout this the MaybeDeleteNodeL call would delete the whole record and this is
+ //not we would like to do here...
+ SetElementId(ElementId() & ~KCDMaskShowFieldType);
+ SetElementId(ElementId() | (currentMappedFieldPtr->ElementId() & KCDMaskShowFieldType));
+ currentMappedFieldPtr->SetElementId(currentMappedFieldPtr->ElementId() | KCDChangedFlag);
+ }
+ }
+ ++origMappedFieldPtr;
+ ++currentMappedFieldPtr;
+ }
+ //ok all of the fields are now ready to handle. Set the count field too
+ this->iApCount.SetL(origMappedRecord->iApCount);
+ }
+ }
+ }
+ }
+
+
+TBool CCDMapperIAPPrioritySelectionPolicyRecord::NeedsMapping(CMDBElement& /*aElement*/)
+ {
+ return ETrue;
+ }
+
+/*virtual*/ void CCDMapperIAPPrioritySelectionPolicyRecord::PrepareToStoreL()
+ {
+ CMDBElement& thisElement = static_cast<CMDBElement&>(*this);
+
+ iSession.MaybeCreateNodeL(thisElement);
+ if (iElement.ElementId() & KCDNewRecordRequest == KCDNewRecordRequest)
+ {
+ iElement.SetRecordId(this->RecordId());
+ }
+ }
+
+TBool CCDMapperIAPPrioritySelectionPolicyRecord::Mapped(TMDBElementId /*aElementId*/)
+/*
+Return ETrue for any element that is mapped.
+
+@internalComponent
+*/
+ {
+ // Every element is mapped in this record so return true
+ return ETrue;
+ }
+
+
+void CCDMapperIAPPrioritySelectionPolicyRecord::MapResultsL()
+/*
+Map results to original element
+
+@internalComponent
+*/
+ {
+ switch (iElement.TypeId())
+ {
+ case KCDTIdRecordTag :
+ {
+ CMDBField<TUint32>& recordTag = static_cast<CMDBField<TUint32>&>(iElement);
+ recordTag.SetL(iRecordTag);
+ Sync(recordTag);
+ break;
+ }
+ case KCDTIdRecordName :
+ {
+ CMDBField<TDesC>& recordName = static_cast<CMDBField<TDesC>&>(iElement);
+ recordName.SetL(iRecordName);
+ Sync(recordName);
+ break;
+ }
+ case KCDTIdIapCount :
+ {
+ CMDBField<TUint32>& iapCount = static_cast<CMDBField<TUint32>&>(iElement);
+ iapCount.SetL(iApCount);
+ Sync(iapCount);
+ break;
+ }
+
+ case KCDTIdIapPrioritySelectionPolicyRecord | KCDMaskShowFieldType:
+ {
+ CCDIAPPrioritySelectionPolicyRecord& inputElement = static_cast<CCDIAPPrioritySelectionPolicyRecord&>(iElement);
+
+ inputElement.iRecordTag.SetL(iRecordTag);
+ Sync(inputElement.iRecordTag);
+
+ inputElement.iRecordName.SetL(iRecordName);
+ Sync(inputElement.iRecordName);
+
+ inputElement.iIapCount.SetL(iApCount);
+ Sync(inputElement.iIapCount);
+
+ //NO BREAK HERE - FALL THROUGH TO DEFAULT
+ }
+ default :
+ {
+ if ( KCDMaskShowFieldType != (iElement.ElementId() & KCDMaskShowFieldType ) )
+ //Field mapping
+ {
+ const STableLookup* tableInfoPtr = CommsDatSchemaV1_1::iTableLookup;
+ TMDBElementId origTableId = iElement.ElementId() & KCDMaskShowRecordType;
+ TInt i = 0;
+
+ while( tableInfoPtr && tableInfoPtr->iTableId != 0 && (tableInfoPtr->iTableId) != origTableId)
+ {
+ ++i;
+ ++tableInfoPtr;
+ }
+
+ //At this point we know that what is the table of the mapped field.
+ //Now we should search for the field in the table and get the position of it.
+ //it is important because as the mapping here is 1:1 this position will be the
+ //position of the mapped field either.
+ const CommsDat::SRecordTypeInfo* fieldInfoPtr = CommsDatSchemaV1_1::iTableLookup[i].iFields;
+ TMDBElementId cleanOrigFieldId = iElement.ElementId() & KCDMaskShowType;
+ TInt fieldPosition = 0;
+
+ //Skip the tagId and the name fields...
+ ++fieldInfoPtr;
+ ++fieldInfoPtr;
+
+ while( fieldInfoPtr && fieldInfoPtr->iTypeId != 0 && (fieldInfoPtr->iTypeId) != cleanOrigFieldId)
+ {
+ ++fieldPosition;
+ ++fieldInfoPtr;
+ }
+
+ TMetaVTableIterator mapperAttribIter(this);
+ SVDataTableEntry const* mapperEntry = NULL;
+ CMDBField<TUint32>* mapperFieldPtr = NULL;
+
+ //just get into the right position with the attribute iterator for the mapper
+ while ( (mapperEntry = mapperAttribIter++) != NULL &&
+ fieldPosition-- >= 0 )
+ {
+ mapperFieldPtr = reinterpret_cast<CMDBField<TUint32>*>(GetAttribPtr(mapperEntry->iOffset));
+ }
+
+ CMDBField<TUint32>* custSelPolOfTheMappedRecord = new(ELeave) CMDBField<TUint32>((*mapperFieldPtr) | KCDTIdCustomSelectionPolicy);
+ CleanupStack::PushL(custSelPolOfTheMappedRecord);
+ custSelPolOfTheMappedRecord->LoadL(iSession.iOwner);
+
+ TInt mappedIAPRecId = (*custSelPolOfTheMappedRecord) << 8;
+
+ CleanupStack::PopAndDestroy(custSelPolOfTheMappedRecord);
+
+ CMDBField<TUint32>& mappedField = reinterpret_cast<CMDBField<TUint32>& >(iElement);
+ mappedField.SetL(KCDTIdIAPRecord | mappedIAPRecId);
+ Sync(mappedField);
+ }
+ else
+ //Record mapping
+ {
+ // as every other field is the same type and the mapping rule is identical for each
+ // and mapping is 1:1, just iterate through the fields and map each one
+ TMetaVTableIterator inputAttribIter(&iElement);
+ SVDataTableEntry const* inputEntry = NULL;
+
+ TMetaVTableIterator mapperAttribIter(this);
+ SVDataTableEntry const* mapperEntry = NULL;
+
+ TInt fieldCounter(15); // only need to map this many fields (from start of record)
+
+ while ( (mapperEntry = mapperAttribIter++) != NULL &&
+ (inputEntry = inputAttribIter++) != NULL &&
+ fieldCounter-- > 0 )
+ {
+ CMDBField<TUint32>* mapperFieldPtr = reinterpret_cast<CMDBField<TUint32>*>(GetAttribPtr(mapperEntry->iOffset));
+ if( mapperFieldPtr )
+ /*At this point we already know that what is recordNumber of the MAPPED element.
+ So all we have to do is to load the mapped element and read its TagId.*/
+ {
+ if ((mapperFieldPtr->ElementId() & KCDNotNullFlag) != 0)
+ {
+ if (0 != *mapperFieldPtr)
+ {
+ //it's possible that the link value is 0 because there can be holes
+ //in the record links...
+ CommsDatMapperAndValidator::TAPTypes apType = CheckLinkLevelAPL(*mapperFieldPtr);
+ TInt mappedIAPRecId = 0;
+
+ if (CommsDatMapperAndValidator::ELinkLevel == apType)
+ //this is already a link level AP so the tagId of it can be used as record ID
+ //for the pointed IAP record
+ {
+ CMDBField<TUint32>* tagFieldOfTheMappedRecord = new(ELeave) CMDBField<TUint32>((*mapperFieldPtr) | KCDTIdRecordTag);
+ CleanupStack::PushL(tagFieldOfTheMappedRecord);
+ tagFieldOfTheMappedRecord->LoadL(iSession.iOwner);
+
+ mappedIAPRecId = (*tagFieldOfTheMappedRecord) << 8;
+
+ CleanupStack::PopAndDestroy(tagFieldOfTheMappedRecord);
+ }
+ else
+ //the other case is that this is an IPProto level AP (it cannot be network level
+ //because it is checked when storing the mapped APPrioritySelPol record).
+ //here we have to read the customSelectionPolicy field of the AP which gives us
+ //the TagId of the link level AP which the tag id of it is the same as the
+ //recordId of the mapped IAP recordId. :)
+ {
+ CMDBField<TUint32>* custSelPolOfTheMappedRecord = new(ELeave) CMDBField<TUint32>((*mapperFieldPtr) | KCDTIdCustomSelectionPolicy);
+ CleanupStack::PushL(custSelPolOfTheMappedRecord);
+ custSelPolOfTheMappedRecord->LoadL(iSession.iOwner);
+
+ mappedIAPRecId = (*custSelPolOfTheMappedRecord) << 8;
+
+ CleanupStack::PopAndDestroy(custSelPolOfTheMappedRecord);
+ }
+
+ CMDBField<TUint32>* inputFieldPtr = reinterpret_cast<CMDBField<TUint32>*>(iElement.GetAttribPtr(inputEntry->iOffset));
+ if (inputFieldPtr)
+ {
+ inputFieldPtr->SetL(KCDTIdIAPRecord | mappedIAPRecId);
+ Sync(*inputFieldPtr);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+//this method compared the current mapped APPrioritySelPol record with the one in the database which is the default
+TBool CCDMapperIAPPrioritySelectionPolicyRecord::IsItTheDefaultAPPrioritySelPolRec(/*CCDAPPrioritySelectionPolicyRecord* aDefAPPrioritySelPolRec*/)
+ {
+ TInt defSelPolLinkValue = CommsDatMapperAndValidator::GetDefAPPrioritySelPolLinkValueL(iSession.iOwner);
+
+ TInt myId = ElementId() & ~KCDMaskShowFieldType;
+
+ if (defSelPolLinkValue == myId)
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+/*virtual*/ void CCDMapperIAPPrioritySelectionPolicyRecord::PostMappingsL()
+ {
+ if ( KCDTIdRecordTag != iElement.TypeId() &&
+ KCDTIdRecordName != iElement.TypeId() &&
+ KCDTIdIapCount != iElement.TypeId() )
+ {
+ TBool def = IsItTheDefaultAPPrioritySelPolRec();
+ CMDBRecordLink<CCDAccessPointRecord>* apXField = &iAp1;
+
+ CCDAPPrioritySelectionPolicyRecord* origMappedRecord = NULL;
+ CMDBRecordLink<CCDAccessPointRecord>* origApXField = NULL;
+
+ if (origMappedDataInDB)
+ {
+ origMappedRecord = static_cast<CCDAPPrioritySelectionPolicyRecord*>(origMappedDataInDB);
+ origApXField = &(origMappedRecord->iAp1);
+ }
+
+ TInt lastValidAPLinkNum = 0;
+ /*
+ * We have to go through the list because it's possible that the client modified an IAP link in
+ * the IAPPriorirytSelPol record and didn't update the IAPCount field. This loop here goes through the
+ * AP links in the mapped APPrioritySelPol table and counts the valid links and updates the APCount field.
+ * It's important since it's used during the selection.
+ * we have to go through all of the links because it's possible that there are 'holes' in the links.
+ * iap1 = valid link
+ * iap2 = 0
+ * iap3 = valid link
+ * In this special case the apCount will be 3 meaning that there are valid links in the first 3 slots.
+ */
+ for (TInt i = 1; /*(*apXField != NULL) &&*/ (i<=MaxLinkCount); ++i)
+ {
+ if ( (EDelete != iOperation) &&
+ (0 != *apXField) )
+ {
+ CommsDatMapperAndValidator::TAPTypes apType;
+ apType = CheckLinkLevelAPL(*apXField);
+
+ if (CommsDatMapperAndValidator::ELinkLevel == apType)
+ //The IPProto AP has to be generated...
+ {
+ GenerateIPProtoAPL(apXField, i, def);
+ }
+ else if (CommsDatMapperAndValidator::EIPProtoLevel == apType)
+ //this link already points to an IPProto level AP check whether it has the correct linking
+ //to the link level AP
+ {
+ CheckIPProtoAPL(apXField, i, def);
+ }
+ else
+ //hm... Something is really bad here. Leaving...
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ lastValidAPLinkNum = i;
+
+ }
+ else
+ {
+ if (KCDMaskShowFieldType == (ElementId() & KCDMaskShowFieldType))
+ {
+ //the given field is NULL. Is this NULL a result of a modification or was it originally NULL? If it's
+ //NULL because of a modification (user set the field to 0) this means that we have to delete the IPProto
+ //level AP linked from the mapped APPrioritySelPol record.
+
+ /* There is a little trick here. If there are 2 APPrioritySelPol records in the DB where
+ * 1 link in each record is linking against the same IPProto AP then the situation
+ * can be the following:
+ * APPrioritySelPolRec_1:
+ * AP1 = IPProto_link_record1
+ *
+ * APPrioritySelPolRec_2:
+ * AP1 = IPProto_link_record1
+ *
+ * One APPrioritySelPol record can be already deleted (by the MaybeDeleteNodeL call which was made
+ * previously to this postmappings call).
+ * So when the program logic tries to find that how many reference does a given
+ * IPProto AP have (IPProto_link_record1 in the example above) then it finds that it's only 1 because the
+ * other record from which it was linked the 2nd time is already deleted. That's why
+ * we give for the search algorithm the original (already deleted) APPrioritySelPol record.
+ */
+
+ if (origApXField && (*origApXField) && origMappedRecord )
+ {
+ //originally this was not NULL. So we have to delete the linked IPProto level AP.
+ //do a deep copy from the original APPrioritySelPol record
+ CCDAPPrioritySelectionPolicyRecord* origSelPolRecCopy = static_cast<CCDAPPrioritySelectionPolicyRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdApPrioritySelectionPolicyRecord));
+ CleanupStack::PushL(origSelPolRecCopy);
+
+ TMetaVTableIterator inputAttribIter(origMappedRecord);
+ SVDataTableEntry const* inputEntry = NULL;
+
+ TMetaVTableIterator copiedAttribIter(origSelPolRecCopy);
+ SVDataTableEntry const* copiedEntry = NULL;
+
+ TInt fieldCounter = CCDAPPrioritySelectionPolicyRecord::EMaxNrOfAps;
+
+ while ( (inputEntry = inputAttribIter++) != NULL &&
+ (copiedEntry = copiedAttribIter++) != NULL &&
+ fieldCounter-- > 0 )
+ {
+ //loop for the fields
+ CMDBField<TUint32>* inputFieldPtr = reinterpret_cast<CMDBField<TUint32>*>(origMappedRecord->GetAttribPtr(inputEntry->iOffset));
+ if ( inputFieldPtr )
+ {
+ CMDBField<TUint32>* copyFieldPtr = reinterpret_cast<CMDBField<TUint32>*>(origSelPolRecCopy->GetAttribPtr(copiedEntry->iOffset));
+ copyFieldPtr->SetL(*inputFieldPtr);
+ }
+ }
+
+ origSelPolRecCopy->iApCount.SetL(origMappedRecord->iApCount);
+
+ //we transfer the ownership of this pointer!!!!!!
+
+ CleanupStack::Pop(origSelPolRecCopy);
+
+ DeleteIPProtoAPL(origApXField, origSelPolRecCopy);
+
+ lastValidAPLinkNum = ForcedCountAPLinks();
+ }
+ }
+ else
+ {
+ //deleting a field
+ //in the PreMappings function the elementId of the field to be deleted was changed by turning on the
+ //changed flag on it. In this step we can exemine this flag. If found the corresponding IPProto level
+ //AP should be deleted.
+ if (Changed(*apXField))
+ {
+ DeleteIPProtoAPL(origApXField);
+
+ lastValidAPLinkNum = ForcedCountAPLinks();
+ }
+ }
+ }
+ ++apXField;
+
+ if (origMappedRecord)
+ {
+ ++origApXField;
+ }
+ }
+
+ TBool countChanged = EFalse;
+
+ if (iElement.TypeId() == (KCDTIdIapPrioritySelectionPolicyRecord | KCDMaskShowFieldType))
+ {
+ CCDIAPPrioritySelectionPolicyRecord& inputElement = static_cast<CCDIAPPrioritySelectionPolicyRecord&>(iElement);
+ if (KCDChangedFlag == ((inputElement.iIapCount).ElementId() & KCDChangedFlag))
+ {
+ //the client has changed the iap count field, don't overwrite it
+ countChanged = ETrue;
+ }
+ }
+
+ if ( ( ( KCDMaskShowFieldType == (ElementId() & KCDMaskShowFieldType) &&
+ EDelete != iOperation ) ||
+ ( 0 != (ElementId() & KCDMaskShowFieldType) ) ) &&
+ static_cast<TInt>(iApCount) != lastValidAPLinkNum &&
+ !countChanged )
+ {
+ // ( if it's not a record delete _OR_
+ // it's a simple field operation) _AND_
+ // the original link number is not the same as we counted _AND_
+ // the user isn't modifying explicitly the link number
+ //then we update the record count field
+ iApCount.SetL(lastValidAPLinkNum);
+ this->ModifyL(iSession.iOwner);
+ }
+
+/* if (EDelete != aOperation &&
+ !countChanged &&
+ static_cast<TInt>(iApCount) != lastValidAPLinkNum)
+ {
+ //modify the APCount field. It's important since it's used during the selection process in ESock.
+ iApCount.SetL(lastValidAPLinkNum);
+ this->ModifyL(iSession.iOwner);
+ }*/
+
+ /* final check:
+ * if the default IAPPrioritySelPol (mapped APPrioritySelPol) OR
+ * the 1st link form the default IAPPrioritySelPol (mapped APPrioritySelPol)
+ * was deleted then the default IPProto AP (from the meshpreface file)
+ * should be linked from the APPrioritySelPol and the IPProto tier records.
+ */
+ if ( (EDelete == iOperation ||
+ 0 == iApCount ) &&
+ def &&
+ ( KCDMaskShowFieldType == (ElementId() & KCDMaskShowFieldType) ||
+ KCDTIdAp1 == (ElementId() & KCDMaskShowType) ) )
+ {
+ //generate/link the def IPProto AP
+ //1. Is DefIPProto AP in the database
+
+ CCDAccessPointRecord* defIpprotoAP = NULL;
+
+ if (CommsDatMapperAndValidator::IsDefIPProtoAPInDB(iSession.iOwner))
+ {
+ //yes, there is -> use it
+ defIpprotoAP = CommsDatMapperAndValidator::GetTheDefIPProtoAP(iSession.iOwner);
+ CleanupStack::PushL(defIpprotoAP);
+ }
+ else
+ {
+ //no there isn't -> generate one
+ defIpprotoAP = CommsDatMapperAndValidator::GenerateIPProtoAPL(IPProtoBaseTagId,
+ CCDAccessPointRecord::KNoPolicy,
+ iSession.iOwner);
+ CleanupStack::PushL(defIpprotoAP);
+
+ defIpprotoAP->StoreL(iSession.iOwner);
+ }
+
+ TPtrC recName(defIpprotoAP->iRecordName);
+ if (0 != recName.Compare(KDefaultIPProtoRecName))
+ {
+ //the name of the selected default IPProto AP is not 'IPProtoDefault'.
+ defIpprotoAP->iRecordName.SetMaxLengthL(KDefaultIPProtoRecName().Length());
+ defIpprotoAP->iRecordName.SetL(KDefaultIPProtoRecName);
+
+ defIpprotoAP->ModifyL(iSession.iOwner);
+ }
+
+ //2. correct the link in the ipproto Tier record to point to the default IPProto AP
+ TInt ipproroTierRecId = CommsDatMapperAndValidator::GetIPProtoTierRecordIdL(iSession.iOwner);
+
+ //CMDBRecordLink<CCDAccessPointRecord>* defTierAP = new(ELeave)CMDBRecordLink<CCDAccessPointRecord>(KCDTIdDefaultAccessPoint);
+ CMDBField<TInt>* defTierAP = new(ELeave)CMDBField<TInt>(KCDTIdDefaultAccessPoint);
+ CleanupStack::PushL(defTierAP);
+
+ defTierAP->SetRecordId(ipproroTierRecId);
+ defTierAP->LoadL(iSession.iOwner);
+
+ TMDBElementId elemId = defIpprotoAP->ElementId();
+ elemId &= KCDMaskHideAttrAndRes;
+ TMDBElementId tableAndRecordBitMask = KCDMaskShowRecordType | KCDMaskShowRecordId;
+ elemId &= tableAndRecordBitMask;
+
+ *defTierAP = elemId;
+
+ defTierAP->ModifyL(iSession.iOwner);
+
+ CleanupStack::PopAndDestroy(defTierAP);
+ CleanupStack::PopAndDestroy(defIpprotoAP);
+
+ }
+ }
+ }
+
+TInt CCDMapperIAPPrioritySelectionPolicyRecord::ForcedCountAPLinks()
+ {
+ TInt linkNum = 15;
+
+ /* Walk backwards on the AP links and return the first valid AP link.
+ * This is the APCount number.
+ */
+ CMDBRecordLink<CCDAccessPointRecord>* currAPLink = &(this->iAp15);
+
+ for (; linkNum > 0; --linkNum)
+ {
+ if ( currAPLink &&
+ *currAPLink )
+ {
+ break;
+ }
+ --currAPLink;
+ }
+
+ return linkNum;
+ }
+
+void CCDMapperIAPPrioritySelectionPolicyRecord::CheckIPProtoAPL(CMDBRecordLink<CCDAccessPointRecord>*& aAPPriorityField,
+ TInt aLinkNumber,
+ TBool aIsDefaultAP)
+ {
+ TInt linkAPTagId = 0;
+
+ if ( KCDMaskShowFieldType == (iElement.ElementId() & KCDMaskShowFieldType) )
+ {
+ //it's a record mapping
+ CCDIAPPrioritySelectionPolicyRecord* ptrIAPPrioritySelPol = static_cast<CCDIAPPrioritySelectionPolicyRecord*>(&iElement);
+ linkAPTagId = GetTheLinkAPTagIdL(ptrIAPPrioritySelPol, aLinkNumber);
+ }
+ else
+ {
+ //it's field mapping
+ if (Changed(*aAPPriorityField))
+ {
+ CMDBRecordLink<CCDIAPRecord>* ptrIAPPrioritySelPol = static_cast<CMDBRecordLink<CCDIAPRecord>*>(&iElement);
+ linkAPTagId = GetTheLinkAPTagIdL(ptrIAPPrioritySelPol);
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ //got the original elementID of the linked IAP record
+
+ //read the CustomSelectionPolicy field of the IPProto level AP
+ CMDBField<TInt>* custSelPolField = new(ELeave) CMDBField<TInt>(*aAPPriorityField | KCDTIdCustomSelectionPolicy);
+ CleanupStack::PushL(custSelPolField);
+
+ custSelPolField->LoadL(iSession.iOwner);
+
+ if (linkAPTagId != *custSelPolField)
+ //The IPProto AP has a wrong linking to the Link level AP. Modify it...
+ {
+ *custSelPolField = linkAPTagId;
+
+ custSelPolField->ModifyL(iSession.iOwner);
+ }
+
+ //if this is the default APPrioritySelPol record and the linkNumber is 1 then
+ //update the defaultAccessPoint link in the network Tier record
+ if (aIsDefaultAP/* &&
+ 1 == aLinkNumber*/)
+ {
+ CommsDatMapperAndValidator::ModifyDefaultTierRecordL((custSelPolField->ElementId() & ~KCDMaskShowFieldType) & ~KCDNotNullFlag,
+ iSession.iOwner);
+ }
+
+ CleanupStack::PopAndDestroy(custSelPolField);
+ }
+
+void CCDMapperIAPPrioritySelectionPolicyRecord::GenerateIPProtoAPL(CMDBRecordLink<CCDAccessPointRecord>*& aAPPriorityFieldToModify,
+ TInt aLinkNumber,
+ TBool aIsDefaultAP)
+
+ {
+ TInt linkAPTagId = 0;
+
+ if ( KCDMaskShowFieldType == (iElement.ElementId() & KCDMaskShowFieldType) )
+ {
+ //it's a record mapping
+ CCDIAPPrioritySelectionPolicyRecord* ptrIAPPrioritySelPol = static_cast<CCDIAPPrioritySelectionPolicyRecord*>(&iElement);
+ linkAPTagId = GetTheLinkAPTagIdL(ptrIAPPrioritySelPol, aLinkNumber);
+ }
+ else
+ {
+ //it's field mapping
+ if (Changed(*aAPPriorityFieldToModify))
+ {
+ CMDBRecordLink<CCDIAPRecord>* ptrIAPPrioritySelPol = static_cast<CMDBRecordLink<CCDIAPRecord>*>(&iElement);
+ linkAPTagId = GetTheLinkAPTagIdL(ptrIAPPrioritySelPol);
+ }
+ else
+ {
+ //the given field is not changed -> don't touch anything...
+ return;
+ }
+ }
+
+ CCDAccessPointRecord* ipprotoAP = NULL;
+
+ if (!CommsDatMapperAndValidator::IsIPProtoAPAlreadyExistL(linkAPTagId, iSession.iOwner))
+ {
+ //The IPProto AP is not existing yet. Generate one.
+ ipprotoAP = CommsDatMapperAndValidator::GenerateIPProtoAPL(IPProtoBaseTagId,
+ linkAPTagId,
+ iSession.iOwner);
+
+ CleanupStack::PushL(ipprotoAP);
+
+ //save the generated AP record
+ ipprotoAP->StoreL(iSession.iOwner);
+ }
+ else
+ {
+ //The IPProto AP is already exsiting. Use that one.
+ ipprotoAP = CommsDatMapperAndValidator::LoadTheAPL(linkAPTagId, iSession.iOwner);
+
+ CleanupStack::PushL(ipprotoAP);
+ }
+
+ TMDBElementId elemId = ipprotoAP->ElementId();
+ elemId &= KCDMaskHideAttrAndRes;
+ TMDBElementId tableAndRecordBitMask = KCDMaskShowRecordType | KCDMaskShowRecordId;
+ elemId &= tableAndRecordBitMask;
+
+ //a) update the APPrioritySelPol record to point to the newly creeated AP record
+ *aAPPriorityFieldToModify = elemId;
+
+ this->ModifyL(iSession.iOwner);
+
+ //b) if this is the default APPrioritySelPol record and the linkNumber is 1 then
+ // update the defaultAccessPoint link in the network Tier record
+ if (aIsDefaultAP/* &&
+ 1 == aLinkNumber*/)
+ {
+ CommsDatMapperAndValidator::ModifyDefaultTierRecordL(elemId, iSession.iOwner);
+ }
+
+ CleanupStack::PopAndDestroy(ipprotoAP);
+ }
+
+void CCDMapperIAPPrioritySelectionPolicyRecord::DeleteIPProtoAPL(CMDBRecordLink<CCDAccessPointRecord>*& aAPPriorityField)
+ {
+ TInt refCount = CommsDatMapperAndValidator::CountReferenceToThisIPProtoAPL(*aAPPriorityField, iSession.iOwner);
+ if (1 == refCount)
+ {
+ //ok, we have only 1 reference to the given IPProto AP -> it can be deleted
+ CCDAccessPointRecord* apRecordToBeDeleted = static_cast<CCDAccessPointRecord*>(CCDRecordBase::RecordFactoryL(*aAPPriorityField));
+ CleanupStack::PushL(apRecordToBeDeleted);
+
+ apRecordToBeDeleted->DeleteL(iSession.iOwner);
+
+ CleanupStack::PopAndDestroy(apRecordToBeDeleted);
+ }
+ }
+
+//Note - the ownership of the 'aTheAlreadyDeletedRecord' is transferred here!!!!!!
+void CCDMapperIAPPrioritySelectionPolicyRecord::DeleteIPProtoAPL(CMDBRecordLink<CCDAccessPointRecord>*& aAPPriorityField,
+ CCDAPPrioritySelectionPolicyRecord* aTheAlreadyDeletedRecord)
+ {
+ //Note - the ownership of the 'aTheAlreadyDeletedRecord' is transferred to the CountReferenceToThisIPProtoAPL!!!!!!
+ TInt refCount = CommsDatMapperAndValidator::CountReferenceToThisIPProtoAPL(*aAPPriorityField, aTheAlreadyDeletedRecord, iSession.iOwner);
+ if (1 == refCount)
+ {
+ //ok, we have only 1 reference to the given IPProto AP -> it can be deleted
+ CCDAccessPointRecord* apRecordToBeDeleted = static_cast<CCDAccessPointRecord*>(CCDRecordBase::RecordFactoryL(*aAPPriorityField));
+ CleanupStack::PushL(apRecordToBeDeleted);
+
+ apRecordToBeDeleted->DeleteL(iSession.iOwner);
+
+ CleanupStack::PopAndDestroy(apRecordToBeDeleted);
+ }
+ }
+
+TInt CCDMapperIAPPrioritySelectionPolicyRecord::GetTheLinkAPTagIdL(CCDIAPPrioritySelectionPolicyRecord* aOrigIAPPrioritySelPolRec,
+ TInt aLinkNumber)
+ {
+ //TInt iapCount = aOrigIAPPrioritySelPolRec->iIapCount;
+ CMDBRecordLink<CCDIAPRecord>* iapXField = &aOrigIAPPrioritySelPolRec->iIap1;
+ CMDBField<TInt>* apTagId = NULL;
+ TInt tagId = 0;
+
+ /*for (TInt i = 1; i!=aLinkNumber && i<=iapCount; ++i)
+ {
+ ++iapXField;
+ }*/
+
+ for (TInt i = 1; i!=aLinkNumber && i<=MaxLinkCount; ++i)
+ {
+ ++iapXField;
+ }
+
+ //got the original elementID of the linked IAP record
+
+
+ //read the tagId of the generated Link level AP (if there is any)...
+
+ apTagId = new(ELeave) CMDBField<TInt>(KCDTIdAccessPointRecord | KCDTIdRecordTag);
+ CleanupStack::PushL(apTagId);
+
+
+ if ( ( (*iapXField) & KCDMaskShowType ) == 0 &&
+ ( (*iapXField) & KLinkableTag ) == 0 )
+ {
+ //there is only a number for the IAP link in the table...
+ *apTagId = *iapXField;
+ }
+ else
+ {
+ //the IAP link is correctly set. Let's use the recordId from the value field.
+ *apTagId = (*iapXField & KCDMaskShowRecordId) >> 8;
+ }
+
+ if ( !(apTagId->FindL(iSession.iOwner)) )
+ //the link level AP cannot be found. Leaving...
+ {
+ User::Leave(KErrNotFound);
+ }
+ else
+ {
+ tagId = *apTagId;
+ }
+
+ CleanupStack::PopAndDestroy(apTagId);
+
+ return tagId;
+ }
+
+
+TInt CCDMapperIAPPrioritySelectionPolicyRecord::GetTheLinkAPTagIdL(CMDBRecordLink<CCDIAPRecord>* aOrigIAPPrioritySelPolField/*,
+ TInt aLinkNumber*/)
+ {
+ CMDBField<TInt>* apTagId = NULL;
+ TInt tagId = 0;
+ //read the tagId of the generated Link level AP (if there is any)...
+
+ apTagId = new(ELeave) CMDBField<TInt>(KCDTIdAccessPointRecord | KCDTIdRecordTag);
+ CleanupStack::PushL(apTagId);
+
+
+ if ( ( (*aOrigIAPPrioritySelPolField) & KCDMaskShowType ) == 0 &&
+ ( (*aOrigIAPPrioritySelPolField) & KLinkableTag ) == 0 )
+ {
+ //there is only a number for the IAP link in the table...
+ *apTagId = *aOrigIAPPrioritySelPolField;
+ }
+ else
+ {
+ //the IAP link is correctly set. Let's use the recordId from the value field.
+ *apTagId = (*aOrigIAPPrioritySelPolField & KCDMaskShowRecordId) >> 8;
+ }
+
+ if ( !(apTagId->FindL(iSession.iOwner)) )
+ //the link level AP cannot be found. Leaving...
+ {
+ User::Leave(KErrNotFound);
+ }
+ else
+ {
+ tagId = *apTagId;
+ }
+
+ CleanupStack::PopAndDestroy(apTagId);
+
+ return tagId;
+ }
+
+CommsDatMapperAndValidator::TAPTypes CCDMapperIAPPrioritySelectionPolicyRecord::CheckLinkLevelAPL(TMDBElementId aElementId)
+//Assumption: an AP record always has a Tier field.
+ {
+ CommsDatMapperAndValidator::TAPTypes ret = CommsDatMapperAndValidator::EUndefined;
+
+ CMDBRecordLink<CCDTierRecord>* tierField = new(ELeave) CMDBRecordLink<CCDTierRecord>(aElementId | KCDTIdTier);
+ CleanupStack::PushL(tierField);
+
+ tierField->LoadL(iSession.iOwner);
+
+ CMDBField<TInt>* tiertagId = new(ELeave) CMDBField<TInt>(*tierField | KCDTIdRecordTag);
+ CleanupStack::PushL(tiertagId);
+
+ tiertagId->LoadL(iSession.iOwner);
+
+ TInt tagId = *tiertagId;
+
+ switch (tagId)
+ {
+ case CommsDatMapperAndValidator::ENetworkLevelTierId :
+ {
+ ret = CommsDatMapperAndValidator::ENetworkLevel;
+ break;
+ }
+ case CommsDatMapperAndValidator::EIPProtoTierId :
+ {
+ ret = CommsDatMapperAndValidator::EIPProtoLevel;
+ break;
+ }
+ case CommsDatMapperAndValidator::ELinkTierId :
+ {
+ ret = CommsDatMapperAndValidator::ELinkLevel;
+ break;
+ }
+ default:
+ {
+ User::Leave(KErrNotFound);
+ }
+ };
+
+
+ CleanupStack::PopAndDestroy(tiertagId);
+ CleanupStack::PopAndDestroy(tierField);
+
+ return ret;
+ }
+
+/************************* Mapper for AccessPoint Table ***************************************
+ * KCDTIdAccessPointRecord CCDAccessPointRecord
+ *
+ * The following fields are deprecated
+ * APGID CCDAccessPointRecord::iAccessPointGID
+ *
+ * They map to new fields within the AccessPointRecord
+ * APTier CCDAccessPointRecord::iTier
+ *
+ * The following fields have some deprecated usage which is mapped
+ * though the same field remains
+ * APSelectionPolicy CCDAccessPointRecord::iSelectionPolicy
+ *
+ *
+ */
+
+#define KCDTIdMapperAccessPointRecord 9881
+START_ATTRIBUTE_TABLE( CCDMapperAccessPointRecord, KCDTIdMapperAccessPointRecord, KCDTIdMapperAccessPointRecord)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iTier, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iMCpr, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iCpr, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iSCpr, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iProtocol, TMDBLinkNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iCprConfig, TMDBNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iAppSID, TMDBNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iConfigAPIdList, TMDBText)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iSelectionPolicy, TMDBNum)
+ X_REGISTER_ATTRIBUTE( CCDMapperAccessPointRecord, iRecordTag, TMDBNum)
+END_ATTRIBUTE_TABLE()
+
+CCDMapperAccessPointRecord::CCDMapperAccessPointRecord(CMDBElement& aElement,CMDBSessionImpl& aSession, const TOperation& aOperation)
+ : CCDMapper(aElement.ElementId(), aElement, aSession, aOperation),
+ iTier(KCDTIdTier),
+ iMCpr(KCDTIdMCpr),
+ iCpr(KCDTIdCpr),
+ iSCpr(KCDTIdSCpr),
+ iProtocol(KCDTIdProtocol),
+ iCprConfig(KCDTIdCprConfig),
+ iAppSID(KCDTIdAppSID),
+ iConfigAPIdList(KCDTIdConfigAPIdList),
+ iSelectionPolicy(KCDTIdSelectionPolicy),
+ iRecordTag(KCDTIdRecordTag | KCDTIdAccessPointRecord)
+ {}
+
+void CCDMapperAccessPointRecord::ConstructL()
+/*
+Initialise the mapper element for any read or write operation
+Only do the minimum work here as the call might be LoadL
+
+@internalTechnology
+*/
+ {
+ // Will either be mappng the whole record or just the GID field
+
+ CMDBField<TUint32>* theGIDField = NULL;
+
+ SetRecordId(iElement.RecordId());
+
+ if(CommsDat::CommsDatSchema::IsRecord(iElement.ElementId()))
+ {
+ CCDAccessPointRecord& inputRecord = static_cast<CCDAccessPointRecord&>(iElement);
+
+ theGIDField = static_cast<CMDBField<TUint32>*>(&inputRecord.iAccessPointGID);
+
+ if (!inputRecord.iSelectionPolicy.IsNull())
+ {
+ //create the link which will be valid at the time of the insertion of the IAPPrioritySelPol
+ //record
+ iSelectionPolicy.SetL(KCDTIdApPrioritySelectionPolicyRecord | inputRecord.iSelectionPolicy & KCDMaskShowRecordId);
+ }
+
+ // These elements are quite likely to be NULL
+ if (!inputRecord.iTier.IsNull())
+ {
+ iTier.SetL(inputRecord.iTier);
+ }
+ if (!inputRecord.iMCpr.IsNull())
+ {
+ iMCpr.SetL(inputRecord.iMCpr);
+ }
+ if (!inputRecord.iCpr.IsNull())
+ {
+ iCpr.SetL(inputRecord.iCpr);
+ }
+ if (!inputRecord.iSCpr.IsNull())
+ {
+ iSCpr.SetL(inputRecord.iSCpr);
+ }
+ if (!inputRecord.iProtocol.IsNull())
+ {
+ iProtocol.SetL(inputRecord.iProtocol);
+ }
+ if (!inputRecord.iCprConfig.IsNull())
+ {
+ iCprConfig.SetL(inputRecord.iCprConfig);
+ }
+ if (!inputRecord.iAppSID.IsNull())
+ {
+ iAppSID.SetL(inputRecord.iAppSID);
+ }
+ if (!inputRecord.iConfigAPIdList.IsNull())
+ {
+ iConfigAPIdList.SetL(inputRecord.iConfigAPIdList);
+ }
+ }
+ else
+ {
+ if ( (iElement.ElementId() & KCDMaskShowType) == KCDTIdAccessPointGID )
+ {
+ theGIDField = static_cast<CMDBField<TUint32>*>(&iElement);
+ }
+ else
+ {
+ //selectionPolicy field...
+ this->iSelectionPolicy.SetL(KCDTIdApPrioritySelectionPolicyRecord | static_cast<CMDBField<TUint32>&>(iElement) & KCDMaskShowRecordId);
+ this->iSelectionPolicy.SetRecordId(iElement.RecordId());
+ }
+ }
+
+ // Don't do validation - leave that til later. Just copy the fields
+ if (theGIDField &&
+ 0 != (*theGIDField) &&
+ iTier.IsNull())
+ {
+ if (Changed(*theGIDField))
+ {
+ iTier.SetL(*theGIDField);
+ }
+ }
+ }
+
+void CCDMapperAccessPointRecord::PreMappingsL()
+ {
+ if (EStore == iOperation)
+ {
+ // 2. Map the fields
+ if ( iMCpr.IsNull() )
+ {
+ // this would indicate the mapper was incomplete
+ // not trying to validate away completely pathological case where scattered fields are set
+
+ //load the template AP for the Network layer form the BearerType table
+ _LIT(KTemplateRecName,"NetworkDefaultTemplate");
+
+ CCDBearerTypeRecord* templateForTheAPRec = static_cast<CCDBearerTypeRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdBearerTypeRecord));
+ CleanupStack::PushL(templateForTheAPRec);
+
+ templateForTheAPRec->iRecordName.SetMaxLengthL(KTemplateRecName().Length());
+ templateForTheAPRec->iRecordName = KTemplateRecName();
+
+ if (!templateForTheAPRec->FindL(iSession.iOwner))
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // Copy the fields from the template record. The recordId will be the same as the one of the
+ //input record
+ iTier.SetL(templateForTheAPRec->iTier);
+ iMCpr.SetL(templateForTheAPRec->iMCpr);
+ iCpr.SetL(templateForTheAPRec->iCpr);
+ iSCpr.SetL(templateForTheAPRec->iSCpr);
+ iProtocol.SetL(templateForTheAPRec->iProtocol);
+ //the SelectionPolicy field was set in the ConstructL function...
+
+ CCDAccessPointRecord& inputRecord = static_cast<CCDAccessPointRecord&>(iElement);
+ if (inputRecord.iRecordTag.IsNull() )
+ //APs have to have tagIds....
+ {
+ iRecordTag = CommsDatMapperAndValidator::GenerateTagIdL(NetworkBaseTagId, iSession.iOwner);
+ }
+
+ CleanupStack::PopAndDestroy(templateForTheAPRec);
+ }
+ }
+ else if (EDelete == iOperation)
+ {
+ if (KCDMaskShowFieldType != (iElement.ElementId() & KCDMaskShowFieldType))
+ {
+ //field mapping -> change the elementId of the whole mapper object so the MaybeDeleteNodeL will delete
+ //only the given field and not the whole mapper.
+ if (KCDTIdSelectionPolicy == (iElement.ElementId() & KCDMaskShowType))
+ {
+ SetElementId(ElementId() & ~KCDMaskShowFieldType);
+ SetElementId(ElementId() | KCDTIdSelectionPolicy);
+ }
+ else
+ {
+ //the GID field is mapped into the Tier field
+ SetElementId(ElementId() | KCDTIdTier);
+ }
+ }
+ }
+ }
+
+
+void CCDMapperAccessPointRecord::PrepareToStoreL()
+/*
+Prepare the mapper for a write operation
+
+Create any new node(s) that may be required.
+Sometimes more than one mapper node might be needed for one input node.
+
+The mapper element will have been populated from the input element already,
+but now complete the population where necessary following the unique set of
+rules for this class
+
+validate the information (only where valid data is critical)
+
+The element can be populated by using information from both the input element and the database
+
+@internalTechnology
+*/
+ {
+ // Create new node if necessary (only one new node in this case) and only when the input element is a record
+ iSession.MaybeCreateNodeL((CMDBElement&)*this);
+ if ( (iElement.ElementId() & KCDNewRecordRequest == KCDNewRecordRequest) &&
+ (iElement.ElementId() & KCDMaskShowFieldType) == KCDMaskShowFieldType )
+ {
+ iElement.SetRecordId(this->RecordId());
+ }
+
+ // Check that the tier matches the default tier (leave if it doesn't)
+ CMDBField<TUint32>* theGIDField = NULL;
+
+ if(CommsDat::CommsDatSchema::IsRecord(iElement.ElementId()))
+ {
+ CCDAccessPointRecord& inputRecord = static_cast<CCDAccessPointRecord&>(iElement);
+
+ theGIDField = static_cast<CMDBField<TUint32>*>(&inputRecord.iAccessPointGID);
+ }
+ else
+ {
+ if ( (iElement.ElementId() & KCDMaskShowType) == KCDTIdAccessPointGID )
+ {
+ theGIDField = static_cast<CMDBField<TUint32>*>(&iElement);
+ }
+ }
+
+ // 1. lookup defaultTier record from global settings and check it matches.
+ if (NULL == theGIDField ||
+ 0 == *theGIDField)
+ {
+ //GID field is not filled in the record so let's try to read the tier field in the mapped AP with the same
+ //recordId as the one from the client...
+
+ //tier link in the AP record
+ CMDBRecordLink<CCDTierRecord>* apTierField = new(ELeave) CMDBRecordLink<CCDTierRecord>(KCDTIdTier);
+ CleanupStack::PushL(apTierField);
+ apTierField->SetRecordId(iElement.RecordId());
+
+ //tier link in the GS record
+ CMDBRecordLink<CCDTierRecord>* gsTierField = new(ELeave) CMDBRecordLink<CCDTierRecord>(KCDTIdDefaultTier);
+ CleanupStack::PushL(gsTierField);
+ gsTierField->SetRecordId(1);
+
+ apTierField->LoadL(iSession.iOwner);
+ gsTierField->LoadL(iSession.iOwner);
+
+ if ( *gsTierField != ((*apTierField & KCDMaskShowRecordId) >> 8) )
+ {
+ //this is not a network level AP -> leaving
+ User::Leave(KErrArgument);
+ }
+ CleanupStack::PopAndDestroy(gsTierField);
+ CleanupStack::PopAndDestroy(apTierField);
+ }
+ else
+ {
+ CheckIsSnapL(*theGIDField); // returned default tier id is not used here
+ }
+ }
+
+
+
+TBool CCDMapperAccessPointRecord::NeedsMapping(CMDBElement& aElement)
+// NB it is correct that the fields listed here are different from the fields in the Mapped() function
+ {
+ if( CommsDat::CommsDatSchema::IsRecord(aElement.ElementId()) )
+ {
+ CCDAccessPointRecord& ap = static_cast<CCDAccessPointRecord&>(aElement);
+ if (ap.iTier.IsNull() )
+ {
+ // either reading into an empty record or storing and haven't set the tier so map
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+
+ if( (aElement.ElementId() & KCDMaskShowType) == KCDTIdAccessPointGID ||
+ (aElement.ElementId() & KCDMaskShowType) == KCDTIdSelectionPolicy )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+
+TBool CCDMapperAccessPointRecord::Mapped(TMDBElementId aElementId)
+// Lists the fields in this record that will be handled by the mapper not the caller
+ {
+ TInt fieldTypeId = aElementId & KCDMaskShowType;
+
+ switch(fieldTypeId)
+ {
+ case KCDTIdAccessPointGID :
+ case KCDTIdTier :
+ case KCDTIdMCpr :
+ case KCDTIdCpr :
+ case KCDTIdSCpr :
+ case KCDTIdProtocol :
+ case KCDTIdCprConfig :
+ case KCDTIdAppSID :
+ case KCDTIdConfigAPIdList :
+ case KCDTIdSelectionPolicy :
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+//Delete the previously stored selectionPolicy field...
+/*virtual*/ void CCDMapperAccessPointRecord::FinalPreparationsL()
+ {
+ CMDBRecordLink<CCDSelectionPolicyRecordBase>* selectionPolicy = new(ELeave) CMDBRecordLink<CCDSelectionPolicyRecordBase>(KCDTIdSelectionPolicy);
+ selectionPolicy->SetRecordId(RecordId());
+
+ selectionPolicy->DeleteL(iSession.iOwner);
+ }
+
+
+TMDBElementId CCDMapper::CheckIsSnapL(TMDBElementId aInputId)
+ {
+ // first find the default tier record
+ CMDBRecordLink<CCDTierRecord> *tierLinkField = new(ELeave) CMDBRecordLink<CCDTierRecord>(KCDTIdGlobalSettingsRecord | KCDTIdDefaultTier | KCDGlobalSettingsRecordId);
+ CleanupStack::PushL(tierLinkField);
+
+ tierLinkField->LoadL(iSession.iOwner);
+
+ TMDBElementId defaultTierId = (tierLinkField->iLinkedRecord->ElementId()) & KCDMaskShowRecordTypeAndId;
+
+ // now prime the same container with aId and check we get to the same tier record id
+ tierLinkField->SetL(aInputId);
+
+ TMDBElementId resolvedInputId = CommsDatSchema::GetLinkIdL(iSession.iOwner, tierLinkField->ElementId(), tierLinkField->GetL(), KCDTIdTierRecord/*, NULL*/);
+
+ if (defaultTierId != resolvedInputId)
+ {
+ __FLOG_STATIC3(KLogComponent, KCDErrLog,
+ _L("CCDMapper::CheckIsSnapL() - iGID <%08x> resolves to <%08x> not to the default (SNAP) Tier <%08x>"),
+ aInputId, resolvedInputId, defaultTierId);
+
+ User::Leave(KErrArgument);
+ }
+
+ CleanupStack::PopAndDestroy(tierLinkField);
+
+ return defaultTierId;
+ }
+
+
+
+void CCDMapperAccessPointRecord::MapResultsL()
+/*
+Map results to client element following mapping rules
+
+only the GID and SelPol field need mapping
+
+@internalComponent
+*/
+ {
+ CMDBField<TUint32>* gidInputElement = NULL;
+ CMDBRecordLink<CCDSelectionPolicyRecordBase>* selectionPolicy;
+
+ if(CommsDat::CommsDatSchema::IsRecord(iElement.ElementId()))
+ {
+ CCDAccessPointRecord& inputRecord = static_cast<CCDAccessPointRecord&>(iElement);
+ gidInputElement = static_cast<CMDBField<TUint32>*>(&inputRecord.iAccessPointGID);
+ selectionPolicy = static_cast<CMDBRecordLink<CCDSelectionPolicyRecordBase>*>(&inputRecord.iSelectionPolicy);
+
+ TInt mappedLinkValue = static_cast<TInt>(iSelectionPolicy);
+ if (mappedLinkValue)
+ {
+ *selectionPolicy = KCDTIdIapPrioritySelectionPolicyRecord | (mappedLinkValue & KCDMaskShowRecordId);
+ }
+ }
+ else
+ {
+ if( (iElement.ElementId() & KCDMaskShowType) == KCDTIdAccessPointGID)
+ {
+ gidInputElement=static_cast<CMDBField<TUint32>*>(&iElement);
+ }
+ else
+ {
+ //selection policy field mapping
+ TInt selPolVal = static_cast<TInt>(iSelectionPolicy);
+ if (selPolVal)
+ {
+ CMDBField<TInt>* inputSelPolField = static_cast<CMDBField<TInt>*>(&iElement);
+ inputSelPolField->SetL(KCDTIdIapPrioritySelectionPolicyRecord | selPolVal & KCDMaskShowRecordId);
+ Sync(*inputSelPolField);
+ }
+ }
+ }
+
+ // Tier may not be default, but it's still ok to copy tier id to GID
+ // Though remember only default tier can be stored via a mapped access point
+ if ( (CommsDat::CommsDatSchema::IsRecord(iElement.ElementId())) ||
+ ((iElement.ElementId() & KCDMaskShowType) == KCDTIdAccessPointGID) &&
+ !iTier.IsNull() )
+ {
+ gidInputElement->SetL(iTier);
+ Sync(*gidInputElement);
+ }
+ }
+
+
+#endif // SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+
+
+
+//EOF
+
+
+
+
+
+
+
+
+
+
+
+
+