diff -r 000000000000 -r dfb7c4ff071f commsfwtools/preparedefaultcommsdatabase/src/CommsDatMapper.cpp --- /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 +#include "CommsDatMapper.h" +#include +#include + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#include +#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* tagField = new (ELeave) CMDBField(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 *defaultTier = new(ELeave) CMDBRecordLink(KCDTIdGlobalSettingsRecord | KCDTIdDefaultTier); + CleanupStack::PushL(defaultTier); + defaultTier->SetRecordId(1); + + defaultTier->LoadL(iSession.iOwner); + + if (CommsDat::CommsDatSchema::IsRecord(iElement.ElementId())) + { + CCDGlobalSettingsRecord& globalSettings = static_cast(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(&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(&iElement)); + } + break; + } + case KCDTIdPromptForSnap : + { + if (Changed(iElement)) + { + iPromptUser.SetL(*static_cast*>(&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(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(&iElement); + + globalSettings->iDefaultSnap.SetL(iDefaultAccessPoint); + //give back just the record number of the linked AP - as in the good old days... + CMDBRecordLink* defaultSnap = static_cast*>(&(globalSettings->iDefaultSnap)); + *defaultSnap = (*defaultSnap & KCDMaskShowRecordId) >> 8; + Sync(globalSettings->iDefaultSnap); + + globalSettings->iPromptForSnap.SetL(iPromptUser); + Sync(globalSettings->iPromptForSnap); + + break; + } + case KCDTIdDefaultSnap : + + { + //CMDBField* defaultSnap = static_cast*>(&iElement); + CMDBRecordLink* defaultSnap = static_cast*>(&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* promptUser = static_cast*>(&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*>(&iElement)); + } + break; + } + case KCDTIdRecordName : + { + if (Changed(iElement)) + { + iRecordName.SetL(*static_cast*>(&iElement)); + } + break; + } + case KCDTIdIapCount : + { + if (Changed(iElement)) + { + iApCount.SetL(*static_cast*>(&iElement)); + } + break; + } + + case KCDTIdIapPrioritySelectionPolicyRecord | KCDMaskShowFieldType: + { + + // NB. This function relies on APs being already present + + //CMDBElement& thisElement = static_cast(*this); + + CCDIAPPrioritySelectionPolicyRecord& inputElement = static_cast(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* inputFieldPtr = reinterpret_cast*>(iElement.GetAttribPtr(inputEntry->iOffset)); + //CMDBRecordLink* inputFieldPtr = reinterpret_cast*>(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* mapperFieldPtr = reinterpret_cast*>(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.. OR + // . 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(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* origInputFieldPtr = static_cast*>(&iElement); + + // NB this only works in this case because entries map exactly.... + while ( (mapperEntry = mapperAttribIter++) != NULL && + (inputEntry = inputAttribIter++) != NULL && + fieldCounter-- > 0 ) + { + CMDBField* inputFieldPtr = reinterpret_cast*>(iapPriorSelPol->GetAttribPtr(inputEntry->iOffset)); + + TMDBElementId filteredOrigInputElemId = origInputFieldPtr->ElementId() & KCDMaskShowType; + + if ( inputFieldPtr && + inputFieldPtr->ElementId() == filteredOrigInputElemId ) + { + CMDBRecordLink* mapperFieldPtr = reinterpret_cast*>(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.. OR + // . 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* 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* linkLevelAPTagId = new(ELeave) CMDBField(*apXLink | KCDTIdRecordTag); + CleanupStack::PushL(linkLevelAPTagId); + + linkLevelAPTagId->SetRecordId((*apXLink & KCDMaskShowRecordId) >> 8); + linkLevelAPTagId->LoadL(iSession.iOwner); + + CMDBRecordSet* apRecordSet = new(ELeave) CMDBRecordSet(KCDTIdAccessPointRecord); + CleanupStack::PushL(apRecordSet); + + CCDAccessPointRecord* apRecord = static_cast(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(CCDRecordBase::RecordFactoryL(KCDTIdApPrioritySelectionPolicyRecord)); + CleanupStack::PushL(probeApPrioritySelPol); + + //we know that which field was modified originally + CMDBRecordLink* 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(CCDRecordBase::RecordFactoryL(KCDTIdApPrioritySelectionPolicyRecord)); + origMappedDataInDB->SetRecordId(iElement.RecordId()); + + origMappedDataInDB->LoadL(iSession.iOwner); + + CCDAPPrioritySelectionPolicyRecord* origMappedRecord = static_cast(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* origMappedFieldPtr = &(origMappedRecord->iAp1); + CMDBRecordLink* 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(*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& recordTag = static_cast&>(iElement); + recordTag.SetL(iRecordTag); + Sync(recordTag); + break; + } + case KCDTIdRecordName : + { + CMDBField& recordName = static_cast&>(iElement); + recordName.SetL(iRecordName); + Sync(recordName); + break; + } + case KCDTIdIapCount : + { + CMDBField& iapCount = static_cast&>(iElement); + iapCount.SetL(iApCount); + Sync(iapCount); + break; + } + + case KCDTIdIapPrioritySelectionPolicyRecord | KCDMaskShowFieldType: + { + CCDIAPPrioritySelectionPolicyRecord& inputElement = static_cast(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* mapperFieldPtr = NULL; + + //just get into the right position with the attribute iterator for the mapper + while ( (mapperEntry = mapperAttribIter++) != NULL && + fieldPosition-- >= 0 ) + { + mapperFieldPtr = reinterpret_cast*>(GetAttribPtr(mapperEntry->iOffset)); + } + + CMDBField* custSelPolOfTheMappedRecord = new(ELeave) CMDBField((*mapperFieldPtr) | KCDTIdCustomSelectionPolicy); + CleanupStack::PushL(custSelPolOfTheMappedRecord); + custSelPolOfTheMappedRecord->LoadL(iSession.iOwner); + + TInt mappedIAPRecId = (*custSelPolOfTheMappedRecord) << 8; + + CleanupStack::PopAndDestroy(custSelPolOfTheMappedRecord); + + CMDBField& mappedField = reinterpret_cast& >(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* mapperFieldPtr = reinterpret_cast*>(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* tagFieldOfTheMappedRecord = new(ELeave) CMDBField((*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* custSelPolOfTheMappedRecord = new(ELeave) CMDBField((*mapperFieldPtr) | KCDTIdCustomSelectionPolicy); + CleanupStack::PushL(custSelPolOfTheMappedRecord); + custSelPolOfTheMappedRecord->LoadL(iSession.iOwner); + + mappedIAPRecId = (*custSelPolOfTheMappedRecord) << 8; + + CleanupStack::PopAndDestroy(custSelPolOfTheMappedRecord); + } + + CMDBField* inputFieldPtr = reinterpret_cast*>(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* apXField = &iAp1; + + CCDAPPrioritySelectionPolicyRecord* origMappedRecord = NULL; + CMDBRecordLink* origApXField = NULL; + + if (origMappedDataInDB) + { + origMappedRecord = static_cast(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(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* inputFieldPtr = reinterpret_cast*>(origMappedRecord->GetAttribPtr(inputEntry->iOffset)); + if ( inputFieldPtr ) + { + CMDBField* copyFieldPtr = reinterpret_cast*>(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(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(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(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* defTierAP = new(ELeave)CMDBRecordLink(KCDTIdDefaultAccessPoint); + CMDBField* defTierAP = new(ELeave)CMDBField(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* currAPLink = &(this->iAp15); + + for (; linkNum > 0; --linkNum) + { + if ( currAPLink && + *currAPLink ) + { + break; + } + --currAPLink; + } + + return linkNum; + } + +void CCDMapperIAPPrioritySelectionPolicyRecord::CheckIPProtoAPL(CMDBRecordLink*& aAPPriorityField, + TInt aLinkNumber, + TBool aIsDefaultAP) + { + TInt linkAPTagId = 0; + + if ( KCDMaskShowFieldType == (iElement.ElementId() & KCDMaskShowFieldType) ) + { + //it's a record mapping + CCDIAPPrioritySelectionPolicyRecord* ptrIAPPrioritySelPol = static_cast(&iElement); + linkAPTagId = GetTheLinkAPTagIdL(ptrIAPPrioritySelPol, aLinkNumber); + } + else + { + //it's field mapping + if (Changed(*aAPPriorityField)) + { + CMDBRecordLink* ptrIAPPrioritySelPol = static_cast*>(&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* custSelPolField = new(ELeave) CMDBField(*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*& aAPPriorityFieldToModify, + TInt aLinkNumber, + TBool aIsDefaultAP) + + { + TInt linkAPTagId = 0; + + if ( KCDMaskShowFieldType == (iElement.ElementId() & KCDMaskShowFieldType) ) + { + //it's a record mapping + CCDIAPPrioritySelectionPolicyRecord* ptrIAPPrioritySelPol = static_cast(&iElement); + linkAPTagId = GetTheLinkAPTagIdL(ptrIAPPrioritySelPol, aLinkNumber); + } + else + { + //it's field mapping + if (Changed(*aAPPriorityFieldToModify)) + { + CMDBRecordLink* ptrIAPPrioritySelPol = static_cast*>(&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*& 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(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*& 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(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* iapXField = &aOrigIAPPrioritySelPolRec->iIap1; + CMDBField* 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(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* aOrigIAPPrioritySelPolField/*, + TInt aLinkNumber*/) + { + CMDBField* apTagId = NULL; + TInt tagId = 0; + //read the tagId of the generated Link level AP (if there is any)... + + apTagId = new(ELeave) CMDBField(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* tierField = new(ELeave) CMDBRecordLink(aElementId | KCDTIdTier); + CleanupStack::PushL(tierField); + + tierField->LoadL(iSession.iOwner); + + CMDBField* tiertagId = new(ELeave) CMDBField(*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* theGIDField = NULL; + + SetRecordId(iElement.RecordId()); + + if(CommsDat::CommsDatSchema::IsRecord(iElement.ElementId())) + { + CCDAccessPointRecord& inputRecord = static_cast(iElement); + + theGIDField = static_cast*>(&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*>(&iElement); + } + else + { + //selectionPolicy field... + this->iSelectionPolicy.SetL(KCDTIdApPrioritySelectionPolicyRecord | static_cast&>(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(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(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* theGIDField = NULL; + + if(CommsDat::CommsDatSchema::IsRecord(iElement.ElementId())) + { + CCDAccessPointRecord& inputRecord = static_cast(iElement); + + theGIDField = static_cast*>(&inputRecord.iAccessPointGID); + } + else + { + if ( (iElement.ElementId() & KCDMaskShowType) == KCDTIdAccessPointGID ) + { + theGIDField = static_cast*>(&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* apTierField = new(ELeave) CMDBRecordLink(KCDTIdTier); + CleanupStack::PushL(apTierField); + apTierField->SetRecordId(iElement.RecordId()); + + //tier link in the GS record + CMDBRecordLink* gsTierField = new(ELeave) CMDBRecordLink(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(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* selectionPolicy = new(ELeave) CMDBRecordLink(KCDTIdSelectionPolicy); + selectionPolicy->SetRecordId(RecordId()); + + selectionPolicy->DeleteL(iSession.iOwner); + } + + +TMDBElementId CCDMapper::CheckIsSnapL(TMDBElementId aInputId) + { + // first find the default tier record + CMDBRecordLink *tierLinkField = new(ELeave) CMDBRecordLink(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* gidInputElement = NULL; + CMDBRecordLink* selectionPolicy; + + if(CommsDat::CommsDatSchema::IsRecord(iElement.ElementId())) + { + CCDAccessPointRecord& inputRecord = static_cast(iElement); + gidInputElement = static_cast*>(&inputRecord.iAccessPointGID); + selectionPolicy = static_cast*>(&inputRecord.iSelectionPolicy); + + TInt mappedLinkValue = static_cast(iSelectionPolicy); + if (mappedLinkValue) + { + *selectionPolicy = KCDTIdIapPrioritySelectionPolicyRecord | (mappedLinkValue & KCDMaskShowRecordId); + } + } + else + { + if( (iElement.ElementId() & KCDMaskShowType) == KCDTIdAccessPointGID) + { + gidInputElement=static_cast*>(&iElement); + } + else + { + //selection policy field mapping + TInt selPolVal = static_cast(iSelectionPolicy); + if (selPolVal) + { + CMDBField* inputSelPolField = static_cast*>(&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 + + + + + + + + + + + + +