--- a/telephonyserverplugins/simtsy/src/CSimPhBkStore.cpp Mon May 03 13:37:20 2010 +0300
+++ b/telephonyserverplugins/simtsy/src/CSimPhBkStore.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,1295 +1,1295 @@
-// Copyright (c) 2001-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:
-// Implements the Phonebook Store manipulation code.
-//
-//
-
-/**
- @file
-*/
-
-#include "CSimPhBkStore.h"
-#include "CSimPhone.h"
-#include "Simlog.h"
-#include <testconfigfileparser.h>
-
-const TUint16 KNpiTonInternational=145; // < The Number Plan Identifier and Type of Number for an international telephone number.
-const TUint16 KNpiTonNational=129; // < The Number Plan Identifier and Type of Number for a national telephone number.
-const TInt KPhonebookErrorGranularity=3; // < Granularity of phonebook error list array.
-//
-// CSimPhBkStore
-//
-void CSimPhBkStore::ClosePhone(TAny* aObj)
-/**
- * A utility function for cleaning up the stack.
- */
- {
- ((CObject*)aObj)->Close();
- }
-
-CSimPhBkStore* CSimPhBkStore::NewL(CSimPhone* aPhone, const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen)
-/**
- * Standard two phase constructor.
- * @param aPhone The phone object from which this Phonebook was opened.
- * @param aName The name of the created Phonebook.
- * @param aMaxNumSlots The maximum number of slots in the Phonebook.
- * @return CSimPhBkStore* The newly created object.
- */
- {
- CSimPhBkStore* store=new(ELeave) CSimPhBkStore(aPhone);
- TCleanupItem newObjClose(ClosePhone,store);
- CleanupStack::PushL(newObjClose);
- store->ConstructL(aName,aMaxNumSlots,aMaxNumLen,aMaxTextLen);
- CleanupStack::Pop();
- return store;
- }
-
-CSimPhBkStore::CSimPhBkStore(CSimPhone* aPhone)
- : CSimPhone(iDummyPhoneBaseRef), iPhone(aPhone),iIpcCnt(0),iEvOutstandingReq(EFalse)
-/**
- * Trivial first phase constructor.
- * @param aPhone The phone object from which this phonebook was opened.
- */
- {}
-
-void CSimPhBkStore::ConstructL(const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen)
-/**
- * Second phase constructor that allocates memory for the phonebook, batch read buffer and
- * a delayed completion timer. The constructor also reads the individual and batch read
- * delays from the configuration file.
- *
- * @param aName The name of the created phonebook.
- * @param aMaxNumLen The maximum length of a telephone number.
- * @param aMaxTextLen The maximum length of an alpha tag.
- */
- {
- LOGPHBK1("Starting to parse Phonebook store additional config parameters...");
- __ASSERT_ALWAYS(aMaxNumLen<=KPhBkMaxTelNumSize,SimPanic(EPhonebookNameOrNumberTooLarge));
- __ASSERT_ALWAYS(aMaxTextLen<=KPhBkMaxAlphaTagSize,SimPanic(EPhonebookNameOrNumberTooLarge));
-
- iPhBkStoreEntries=new(ELeave) TPhBkStoreEntry[aMaxNumSlots+1]; //slot 0 is unused
- iPhBkMaxNumSlots=aMaxNumSlots;
- iPhBkMaxTelNumLen=aMaxNumLen;
- iPhBkMaxTextLen=aMaxTextLen;
- iPhBkStoreName.Copy(aName);
-
- iReqTimer=CSimTimer::NewL(iPhone);
- iOOBWriteTimer=CSimTimer::NewL(iPhone);
- iOOBDeleteTimer=CSimTimer::NewL(iPhone);
- iPhBkRwBuffer=new(ELeave) CPhoneBookBuffer();
- iPhBkError=new(ELeave) CArrayFixFlat<TPhBkError>(KPhonebookErrorGranularity);
-
- const CTestConfigItem* item=NULL;
- TInt ret=KErrNone;
- item=CfgFile()->Item(KTriggerEventIPC,0);
- if(item)
- {
- TInt ipc, cnt, event;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,ipc);
- if(ret!=KErrNone)
- {
- LOGPARSERR("ipc",ret,0,&KTriggerEventIPC);
- }
- else
- iTriggerEventIPC.iIPC=ipc;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,cnt);
- if(ret!=KErrNone)
- {
- LOGPARSERR("cnt",ret,1,&KTriggerEventIPC);
- }
- else
- iTriggerEventIPC.iIPCCnt=cnt;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,event);
- if(ret!=KErrNone)
- {
- LOGPARSERR("event",ret,2,&KTriggerEventIPC);
- }
- else
- iTriggerEventIPC.iEvent=RMobilePhone::TMobilePhoneSecurityEvent(event);
-
-
- }
-
- const CTestConfigItem* item0=NULL;
- item0=CfgFile()->Item(KPhBkPhoneStoreCaps,0);
- if (item0)
- {
- TPtrC8 value0;
- TInt ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,0,value0);
- if(ret0!=KErrNone)
- {
- iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
- LOGPARSERR("value0",ret0,0,&KPhBkPhoneStoreCaps);
- }
- else
- {
- TUint32 intValue;
- TInt ret = AsciiToNum(value0, intValue);
- if(ret!=KErrNone)
- iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
- else
- iPhBkStoreCaps = intValue;
- }
- }
- else
- iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
-
-
- LOGPHBK1("...Finished parsing Phonebook store additional config parameters...");
- }
-
-void CSimPhBkStore::PopulateStoreFromConfigFileL()
-/**
- * Populate the Phonebook Store from information in the configuration file. This is performed
- * after the standard Phonebook Store construction in order to prevent reseting the configuation
- * file accessor class' pointers while possibly multiple Phonebook Stores are created.
- *
- * The store entries comply to the following format:
- * "PhBkStoreEntry = <store name>, <slot number>, <telephone number>, <alphatag>"
- */
- {
- LOGPHBK1("Starting to read Phonebook store entries...");
- iPhBkIndividualPause=CfgFile()->ItemValue(KPhBkStoreIndividualReqPause,KDefaultPhBkStoreIndividualReqPause);
- iPhBkBatchPause=CfgFile()->ItemValue(KPhBkStoreBatchReqPause,KDefaultPhBkStoreBatchReqPause);
-
- TInt count=CfgFile()->ItemCount(KPhBkStoreEntry);
- const CTestConfigItem* item=NULL;
- TInt ret=KErrNone;
-
- TInt i;
- for(i=0;i<count;i++)
- {
- item=CfgFile()->Item(KPhBkStoreEntry,i);
- if(!item)
- break;
-
- TPtrC8 phonebookName,alphaTag,telNum;
- TInt index;
- TUint8 npiTon;
- ret=GetPhBkEntry(item,0,phonebookName,index,telNum,alphaTag,npiTon);
- if(ret!=KErrNone)
- {
- LOGPARSERR("Phonebook Entry",ret,index,&KPhBkStoreEntry);
- continue;
- }
- if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
- continue;
-
- iPhBkStoreEntries[index].iAlphaTag.Copy(alphaTag);
- iPhBkStoreEntries[index].iTelNum.Copy(telNum);
- iPhBkStoreEntries[index].iTonNpi=npiTon;
- }
-
- count=CfgFile()->ItemCount(KPhBkError);
- item=NULL;
-
- for(i=0;i<count;i++)
- {
- item=CfgFile()->Item(KPhBkError,i);
- if(!item)
- break;
-
- TInt count,error;
- TPtrC8 phonebookName, phonebookStore;
-
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
- if(ret!=KErrNone)
- {
- LOGPARSERR("count",ret,0,&KPhBkError);
- continue;
- }
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,error);
- if(ret!=KErrNone)
- {
- LOGPARSERR("error",ret,1,&KPhBkError);
- continue;
- }
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,phonebookName);
- if(ret!=KErrNone)
- {
- LOGPARSERR("phonebookName",ret,2,&KPhBkError);
- continue;
- }
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,phonebookStore);
- if(ret!=KErrNone)
- {
- LOGPARSERR("phonebookStore",ret,3,&KPhBkError);
- }
- else //not for the global phonebook
- continue;
-
- if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
- continue;
-
-
- TPhBkError entry;
- entry.iCount=count;
- entry.iError=error;
- iPhBkError->AppendL(entry);
- }
- PopulateOOBWrite();
- PopulateOOBDelete();
- LOGPHBK1("...Finished reading Phonebook store entries...");
-
- if(iPhBkOOBWriteDuration!=-1)
- iOOBWriteTimer->Start(iPhBkOOBWriteDuration,this,ETimerIdPhBkStorOOBWrite);
- if(iPhBkOOBDeleteDuration!=-1)
- iOOBDeleteTimer->Start(iPhBkOOBDeleteDuration,this,ETimerIdPhBkStorOOBDelete);
- }
-
-void CSimPhBkStore::PopulateOOBWrite()
-/**
- * Populate the member variables required to operate the OOB Store functionality from
- * the configuration file.
- * The OOBPhBkStore configuration file tag should have the following format:
- * "OOBPhBkStore= <duration>, <phonebook name>, <index>, <telephone number>, <alpha tag>"
- */
- {
- iPhBkOOBWriteDuration=KErrNotFound;
- const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkWrite);
- if(!item)
- return;
-
- TInt count;
- TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
- if(ret!=KErrNone)
- {
- LOGPARSERR("count",ret,0,&KOOBPhBkWrite);
- return;
- }
-
- TPtrC8 phonebookName,alphaTag,telNum;
- TInt index;
- TUint8 npiTon;
- ret=GetPhBkEntry(item,1,phonebookName,index,telNum,alphaTag,npiTon);
- if(ret!=KErrNone)
- {
- LOGPARSERR("npiTon",ret,index,&KOOBPhBkWrite);
- return;
- }
- if(phonebookName.MatchF(iPhBkStoreName)!=0)
- return; // Not this phonebook
-
- iPhBkOOBWriteDuration=count;
- iPhBkOOBWriteIndex=index;
- iPhBkOOBWrite.iAlphaTag.Copy(alphaTag);
- iPhBkOOBWrite.iTelNum.Copy(telNum);
- iPhBkOOBWrite.iTonNpi=npiTon;
- }
-
-void CSimPhBkStore::PopulateOOBDelete()
-/**
- * Populate the member variables required to operate the OOB Delete functionality from
- * the configuration file.
- * The OOBPhBkDelete configuration file tag should have the following format:
- * "OOBPhBkDelete= <duration>, <phonebook name>, <index>
- */
- {
- iPhBkOOBDeleteDuration=KErrNotFound;
- const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkDelete);
- if(!item)
- return;
-
- TInt count;
- TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
- if(ret!=KErrNone)
- {
- LOGPARSERR("count",ret,0,&KOOBPhBkDelete);
- return;
- }
-
- TPtrC8 phonebookName;
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,phonebookName);
- if(ret!=KErrNone)
- {
- LOGPARSERR("phonebookName",ret,1,&KOOBPhBkDelete);
- return;
- }
- if(phonebookName.MatchF(iPhBkStoreName)!=0)
- return; // Not this phonebook
-
- TInt index;
- ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,index);
- if(ret!=KErrNone)
- {
- LOGPARSERR("index",ret,2,&KOOBPhBkDelete);
- return;
- }
-
- iPhBkOOBDeleteDuration=count;
- iPhBkOOBDeleteIndex=index;
- }
-
-TInt CSimPhBkStore::GetPhBkEntry(const CTestConfigItem* aItem, TInt aItemIndex,
- TPtrC8& aPhonebookName, TInt& aIndex,
- TPtrC8& aTelNum, TPtrC8& aAlphaTag, TUint8& aNpiTon)
-/**
- * Retrieve a phonebook entry from the configuration file, starting at a given item index
- * value.
- * @param aItem Pointer to the config file item from which the phonebook entry will be read.
- * @param aItemIndex The index number within the item from which the phonebook entry will be read.
- * @param aPhonebookName The returned phonebook name
- * @param aIndex The returned index number
- * @param aTelNum The returned telephone number
- * @param aAlphaTag The returned alpha tag
- * @param aNpiTon The returned Number Plan Identifier and Type of Number information
- * @return TInt Standard error value.
- */
- {
- TInt ret;
- ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aPhonebookName);
- if(ret!=KErrNone)
- return ret;
-
- ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aIndex);
- if(ret!=KErrNone)
- return ret;
-
- if(aIndex>iPhBkMaxNumSlots) //the max number of slot is a valid slot
- return KErrArgument;
-
- ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aTelNum);
- if(ret!=KErrNone)
- return ret;
- if(aTelNum.Length()>iPhBkMaxTelNumLen)
- return KErrArgument;
-
- ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag);
- if(ret!=KErrNone)
- return ret;
- if(aAlphaTag.Length()>iPhBkMaxTextLen)
- return KErrArgument;
-
- if((aTelNum.Length()>0) && (aTelNum[0]=='+'))
- {
- aTelNum.Set(aTelNum.Mid(1));
- aNpiTon=KNpiTonInternational;
- }
- else
- aNpiTon=KNpiTonNational;
- return ret;
- }
-
-CSimPhBkStore::~CSimPhBkStore()
-/**
- * Standard destructor. Any objects created by the ::ConstructL() function
- * will be destroyed here.
- */
- {
- delete[] iPhBkStoreEntries;
- delete iPhBkError;
- delete iPhBkRwBuffer;
- delete iOOBWriteTimer;
- delete iOOBDeleteTimer;
- delete iReqTimer;
- }
-
-TInt CSimPhBkStore::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
-/**
- * Dispatch function for all Phonebook Store requests.
- * @param aReqHandle The TSY request handle for this request.
- * @param aIpc The IPC number of this request.
- * @param aPckg The parameter package related to this request.
- * @return TInt The return error condition.
- */
- {
- iIpcCnt++;
- TInt error=KErrNone;
- if(FindIpcErrorMatch(error))
- {
- ReqCompleted(aReqHandle,error);
- return KErrNone;
- }
-
-// The following requests can be completed even if the completion of another request is pending.
- switch(aIpc)
- {
- case EMobilePhoneStoreGetInfo:
- error = GetInfo(aReqHandle,aPckg.Des1n());
- if(iTriggerEventIPC.iIPC==aIpc)
- {
- iTriggerCnt++;
- if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
- iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
- }
- return error;
-
- case EMobilePhoneStoreNotifyStoreEvent:
- error = NotifyStoreEvent(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
- if(iTriggerEventIPC.iIPC==aIpc)
- {
- iTriggerCnt++;
- if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
- iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
- }
- return error;
-
- default:
- break;
- }
-
-
-// The TSY can only process one of the following requests at a time. If a second is received
-// while processing the first, then it will be errored with KErrInUse. This restriction will
-// be removed later, by inserting a request queuing mechanism. Note that the standard TSY
-// "flow control" mechanism works phone-wide and so is not suitable.
-
- if(iReqTimer->IsActive())
- {
- ReqCompleted(aReqHandle,KErrInUse);
- return KErrNone;
- }
-
- switch(aIpc)
- {
-// The standard multimode store read and write are not supported.
- case EMobilePhoneStoreRead:
- case EMobilePhoneStoreWrite:
- case EMobilePhoneStoreReadAllPhase1:
- case EMobilePhoneStoreReadAllPhase2:
- ReqCompleted(aReqHandle,KErrNotSupported);
- return KErrNone;
-
- case EMobilePhoneBookStoreRead:
- error = Read(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
- if(iTriggerEventIPC.iIPC==aIpc)
- {
- iTriggerCnt++;
- if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
- iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
- }
- return error;
-
- case EMobilePhoneBookStoreWrite:
- error = Write(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
- if(iTriggerEventIPC.iIPC==aIpc)
- {
- iTriggerCnt++;
- if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
- iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
- }
- return error;
-
- case EMobilePhoneStoreDelete:
- error = Delete(aReqHandle,aPckg.Des1n());
- if(iTriggerEventIPC.iIPC==aIpc)
- {
- iTriggerCnt++;
- if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
- iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
- }
- return error;
-
- case EMobilePhoneStoreDeleteAll:
- error = DeleteAll(aReqHandle);
- if(iTriggerEventIPC.iIPC==aIpc)
- {
- iTriggerCnt++;
- if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
- iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
- }
- return error;
-
- default:
- break;
- }
-
- return KErrNotSupported;
- }
-
-CTelObject* CSimPhBkStore::OpenNewObjectByNameL(const TDesC& /*aName*/)
-/**
- * The API does not support any objects that could be opened from this one.
- */
- {
- User::Leave(KErrNotSupported);
- return NULL;
- }
-
-CTelObject* CSimPhBkStore::OpenNewObjectL(TDes&)
-/**
- * The API does not support any objects that could be opened from this one.
- */
- {
- User::Leave(KErrNotSupported);
- return NULL;
- }
-
-CTelObject::TReqMode CSimPhBkStore::ReqModeL(const TInt aIpc)
-/**
- * This function returns the Request Mode for the request with the passed IPC value.
- * @param aIpc The IPC number of the request.
- * @return TReqMode The request mode.
- */
- {
- CTelObject::TReqMode ret=0;
-
- switch(aIpc)
- {
- case EMobilePhoneStoreGetInfo:
- case EMobilePhoneStoreDelete:
- case EMobilePhoneStoreDeleteAll:
- case EMobilePhoneBookStoreRead:
- case EMobilePhoneBookStoreWrite:
- break;
-
- case EMobilePhoneStoreNotifyStoreEvent:
- ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
- break;
-
- default:
- User::Leave(KErrNotSupported);
- break;
- }
-
- return ret;
- }
-
-TInt CSimPhBkStore::RegisterNotification(const TInt /*aIpc*/)
-/**
- * The ETel Server calls this function when the first client makes a notification
- * request. If supported by the underlying protocol controlling the
- * signalling stack, this can be used to start requesting updates for the relevant
- * service.
- */
- {
- return KErrNone;
- }
-
-TInt CSimPhBkStore::DeregisterNotification(const TInt /*aIpc*/)
-/**
- * The ETel Server calls this function when the last client that had previously
- * made a notification request closes its ETel Server handle. If supported by
- * the underlying protocol controlling the signalling stack, this can be used
- * to stop requesting updates for the relevant service.
- */
- {
- return KErrNone;
- }
-
-TInt CSimPhBkStore::NumberOfSlotsL(const TInt /*aIpc*/)
-/**
- * Return the number of slots that the ETel Server should allocate for buffering requests
- * of the given IPC number.
- */
- {
- return KDefaultNumberOfSlots;
- }
-
-TInt CSimPhBkStore::CancelService(const TInt aIpc,const TTsyReqHandle /*aTsyReqHandle*/)
-/**
- * Cancel an outstanding request.
- * @param aIpc The IPC number of the request that is to be cancelled.
- * @param aTsyReqHandle The TSY request handle of the request that is to be cancelled.
- * @param TInt Standard return value.
- */
- {
- switch(aIpc)
- {
- case EMobilePhoneStoreGetInfo:
- case EMobilePhoneStoreDelete:
- case EMobilePhoneStoreDeleteAll:
- case EMobilePhoneBookStoreRead:
- case EMobilePhoneBookStoreWrite:
- break;
-
- case EMobilePhoneStoreNotifyStoreEvent:
- NotifyStoreEventCancel();
- break;
-
- default:
- break;
- }
- return KErrNone;
- }
-
-void CSimPhBkStore::Init()
-/**
- * This function can be used to perform any necessary synchronous initialisation.
- */
- {
- }
-
-TInt CSimPhBkStore::GetInfo(TTsyReqHandle aReqHandle, TDes8* aPckg)
-/**
- * Retrieve Phonebook Store information. This request is completed immediately, as it is assumed
- * that in a real TSY, all this data will be cached in the TSY.
- *
- * @param aReqHandle The TSY request handle associated with this request.
- * @param aPckg The parameter package associated with this request.
- */
- {
-
- if(iPhone->IsICCLocked()!=EFalse)
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg* getInfoPckg=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg*)aPckg;
- RMobilePhoneBookStore::TMobilePhoneBookInfoV1& getInfo=(*getInfoPckg)();
-
- PopulatePhBkStoreInfo(&getInfo);
-
- if(&getInfo!=NULL) // This will be the case if the version checking within PopulatePhBkStoreInfo has failed.
- {
- ReqCompleted(aReqHandle,KErrNone);
- }
- else
- {
- ReqCompleted(aReqHandle,KErrNotSupported);
- }
-
- return KErrNone;
- }
-
-void CSimPhBkStore::PopulatePhBkStoreInfo(RMobilePhoneStore::TMobilePhoneStoreInfoV1* aStoreInfo)
-/**
- * Populate the passed parameter with Phonebook Store information.
- * @param aStoreInfo Pointer to phonebook store information structure to be populated.
- */
- {
- __ASSERT_ALWAYS(aStoreInfo, SimPanic(EIllegalNullPtrParameter));
-
- aStoreInfo->iType=RMobilePhoneStore::EPhoneBookStore;
- aStoreInfo->iTotalEntries=MaxSlots();
- aStoreInfo->iCaps=iPhBkStoreCaps;
- aStoreInfo->iName.Copy(iPhBkStoreName);
- aStoreInfo->iUsedEntries=UsedEntries();
-
- if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV1)
- {
- RMobilePhoneBookStore::TMobilePhoneBookInfoV1* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1*)aStoreInfo;
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
- if(err != KErrNone)
- {
- getExtraInfo = NULL;
- return;
- }
-
- getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
- getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
- getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
- getExtraInfo->iChangeCounter=0;
- getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
- }
- else if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV2)
- {
- RMobilePhoneBookStore::TMobilePhoneBookInfoV2* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV2*)aStoreInfo;
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
- if(err != KErrNone)
- {
- getExtraInfo = NULL;
- return;
- }
-
- getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
- getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
- getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
- getExtraInfo->iChangeCounter=0;
- getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
-
- getExtraInfo->iPhBkMode.Zero();
- }
- else if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV5)
- {
- RMobilePhoneBookStore::TMobilePhoneBookInfoV5* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV5*)aStoreInfo;
-
- // Check that the data structure is supported by the simulated TSY version
- TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
- if(err != KErrNone)
- {
- getExtraInfo = NULL;
- return;
- }
-
- getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
- getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
- getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
- getExtraInfo->iChangeCounter=0;
- getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
-
- getExtraInfo->iPhBkMode.Zero();
-
- getExtraInfo->iMaxSecondNames = 0;
- getExtraInfo->iMaxTextLengthSecondName = 0;
- getExtraInfo->iMaxAdditionalNumbers = 0;
- getExtraInfo->iMaxTextLengthAdditionalNumber = 0;
- getExtraInfo->iMaxNumLengthAdditionalNumber = 0;
- getExtraInfo->iMaxGroupNames = 0;
- getExtraInfo->iMaxTextLengthGroupName = 0;
- getExtraInfo->iMaxEmailAddr = 0;
- getExtraInfo->iMaxTextLengthEmailAddr = 0;
- }
- }
-
-TInt CSimPhBkStore::Read(TTsyReqHandle aReqHandle, TDes8* aPckg1,TDes8* aPckg2)
-/**
- * Read Phonebook store entries. The completion of this request is delayed in order to
- * simulate a real TSY that would have to go and get the information from a SIM card.
- *
- * @param aReqHandle The TSY request handle associated with this request.
- * @param aPckg1 The first parameter package associated with this request.
- * It contains the index from which the read should start and
- * the number of entries which should be read.
- * @param aPckg2 The second parameter package associated with this request.
- * It contains the buffer, which will be populated with the retrieved
- * values.
- * @return TInt Standard return value.
- */
- {
- if(iPhone->IsICCLocked()!=EFalse)
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- TPckg<RMobilePhoneBookStore::TPBIndexAndNumEntries>* indexNumPckg=(TPckg<RMobilePhoneBookStore::TPBIndexAndNumEntries>*)aPckg1;
- RMobilePhoneBookStore::TPBIndexAndNumEntries& indexNum=(*indexNumPckg)();
-
- if(indexNum.iNumSlots==iPhBkMaxNumSlots)
- {
- if (!(iPhBkStoreCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsReadAccess))
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
- }
- else if((indexNum.iIndex+indexNum.iNumSlots - 1)>iPhBkMaxNumSlots)
- {
- ReqCompleted(aReqHandle,KErrArgument);
- return KErrNone;
- }
-
- else if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsReadAccess))
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- iPhBkRwBuffer->Set(aPckg2);
-
- TInt cnt=0;
- TInt ret=0;
- TBool partial=EFalse;
- for(TInt i=indexNum.iIndex;i<=iPhBkMaxNumSlots;i++)
- {
- if((iPhBkStoreEntries[i].iTelNum.Length()!=0)||(iPhBkStoreEntries[i].iAlphaTag.Length()!=0))
- {
- ret=iPhBkRwBuffer->AddNewEntryTag();
- if(ret!=KErrNone)
- break;
-
- partial=ETrue;
- ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i);
- if(ret!=KErrNone)
- break;
- ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,iPhBkStoreEntries[i].iAlphaTag);
- if(ret!=KErrNone)
- break;
- ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,iPhBkStoreEntries[i].iTonNpi);
- if(ret!=KErrNone)
- break;
- ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,iPhBkStoreEntries[i].iTelNum);
- if(ret!=KErrNone)
- break;
-
- partial=EFalse;
- if(++cnt>=indexNum.iNumSlots)
- break;
- }
- }
- if(partial)
- // EXPORT - but return value not relevant
- (void)iPhBkRwBuffer->RemovePartialEntry();
-
- indexNum.iNumSlots=cnt;
-
- if((cnt==0)&&(partial))
- ReqCompleted(aReqHandle,KErrArgument); // An entry was found, but the buffer was too small to return it.
- else if((cnt==0)&&(!partial))
- ReqCompleted(aReqHandle,KErrNotFound); // No entries found.
- else
- ReqCompleted(aReqHandle,KErrNone);
-
- return KErrNone;
- }
-
-TInt CSimPhBkStore::Write(TTsyReqHandle aReqHandle,TDes8* aPckg1,TDes8* aPckg2)
-/**
- * Write a phonebook store entries. The completion of this request is delayed in order to
- * simulate a real TSY that would have to write the information to a SIM card. A store
- * event may be triggered by this request.
- *
- * @param aReqHandle The TSY request handle associated with this request.
- * @param aPckg1 The first parameter package associated with this request.
- * This contains the TLV phonebook entry to be written.
- * @param aPckg2 The second parameter package associated with this request.
- * This contains the slot index number to which the entry must be written.
- */
- {
- if(iPhone->IsICCLocked()!=EFalse)
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg2;
- TInt& index=(*indexPckg)();
-
-// If the index is -1, then use the first available free slot.
- if(index==-1)
- {
- for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
- {
- if((iPhBkStoreEntries[i].iTelNum.Length()==0)&&(iPhBkStoreEntries[i].iAlphaTag.Length()==0))
- {
- index=i;
- break;
- }
- }
- }
-
- if(index==-1)
- {
- ReqCompleted(aReqHandle,EXTENDEDERROR(KErrNoMemory, KErrPhonebookNoMemory));
- return KErrNone;
- }
-
- if((index<1)||(index>iPhBkMaxNumSlots))
- {
- ReqCompleted(aReqHandle,KErrArgument);
- return KErrNone;
- }
-
- TBool isSlotAlreadyUsed=EFalse;
- if(iPhBkStoreEntries[index].iTelNum.Length()!=0)
- isSlotAlreadyUsed=ETrue;
-
-// Unpick the phonebook entry.
- iPhBkRwBuffer->Set(aPckg1);
- iPhBkRwBuffer->StartRead();
-
- TUint8 tagVal;
- TUint8 npiTon=0;
- TPtrC alphaTag;
- TPtrC telNum;
- TPtrC alphaTag2;
- TBool skipToNextEntry=EFalse;
- CPhoneBookBuffer::TPhBkTagType tagType;
- TInt ret=KErrNone;
-
- while(ret==KErrNone)
- {
- ret=iPhBkRwBuffer->GetTagAndType(tagVal,tagType);
- if(ret==KErrNotFound)
- {
- ret=KErrNone;
- break;
- }
- else if(ret!=KErrNone)
- break;
-
-
- switch(tagVal)
- {
- case RMobilePhoneBookStore::ETagPBNewEntry:
- skipToNextEntry=EFalse;
- break;
-
- case RMobilePhoneBookStore::ETagPBText:
- if(!skipToNextEntry)
- ret=iPhBkRwBuffer->GetValue(alphaTag);
- else
- {
- TPtrC throwAway;
- ret=iPhBkRwBuffer->GetValue(throwAway);
- }
- break;
-
- case RMobilePhoneBookStore::ETagPBNumber:
- if(!skipToNextEntry)
- ret=iPhBkRwBuffer->GetValue(telNum);
- else
- {
- TPtrC throwAway;
- ret=iPhBkRwBuffer->GetValue(throwAway);
- }
- break;
-
- case RMobilePhoneBookStore::ETagPBTonNpi:
- if(!skipToNextEntry)
- ret=iPhBkRwBuffer->GetValue(npiTon);
- else
- {
- TUint8 throwAway;
- ret=iPhBkRwBuffer->GetValue(throwAway);
- }
- break;
-
- // Alexandros - phbksync "shortcut" should be discussed and removed
- case RMobilePhoneBookStore::ETagPBAnrStart:
- skipToNextEntry=ETrue;
- break;
-
- case RMobilePhoneBookStore::ETagPBEmailAddress:
- case RMobilePhoneBookStore::ETagPBGroupName:
- case RMobilePhoneBookStore::ETagPBSecondName:
- ret=iPhBkRwBuffer->GetValue(alphaTag2);
- break;
- case RMobilePhoneBookStore::ETagPBHiddenInfo:
- TUint8 throwAway;
- ret=iPhBkRwBuffer->GetValue(throwAway);
- break;
-
- default:
- //DEF001769 - SIM TSY should ignore extra fields in short entries
- //ret=KErrNotSupported;
- break;
- }
- }
-
- if(ret!=KErrNone)
- {
- ReqCompleted(aReqHandle,ret);
- return KErrNone;
- }
-
- LOGPHBK2("alphaTag Length = (%d)",alphaTag.Length());
- LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen);
- LOGPHBK2("TelNum Length = (%d)",telNum.Length());
- LOGPHBK2("TelNum Max Length = (%d)",iPhBkMaxTelNumLen);
-
- if(alphaTag.Length()>iPhBkMaxTextLen)
- {
- ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookTextOverflow));
- return KErrNone;
- }
- else if(telNum.Length()>iPhBkMaxTelNumLen)
- {
- ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookNumberOverflow));
- return KErrNone;
- }
-
- iPhBkStoreEntries[index].iAlphaTag.Copy(alphaTag);
- iPhBkStoreEntries[index].iTelNum.Copy(telNum);
- iPhBkStoreEntries[index].iTonNpi=npiTon;
- if(isSlotAlreadyUsed)
- DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventChanged,index);
- else
- DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventAdded,index);
- return KErrNone;
- }
-
-TInt CSimPhBkStore::Delete(TTsyReqHandle aReqHandle,TDes8* aPckg)
-/**
- * Delete a single Phonebook store entry. The completion of this request is delayed in order to
- * simulate a real TSY that would have to write the information to a SIM card. A store
- * event may be triggered by this request.
- *
- * @param aReqHandle The TSY request handle associated with this request.
- * @param aPckg The parameter package associated with this request.
- * @return Standard return value.
- */
- {
- if(iPhone->IsICCLocked()!=EFalse)
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
-
- TPckg<TInt>* intPckg=(TPckg<TInt>*)aPckg;
- TInt& index=(*intPckg)();
-
- if((index<1)||(index>iPhBkMaxNumSlots))
- {
- ReqCompleted(aReqHandle,KErrArgument);
- return KErrNone;
- }
-
- iPhBkStoreEntries[index].iTelNum.Zero();
- iPhBkStoreEntries[index].iAlphaTag.Zero();
- DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventDeleted,index);
- return KErrNone;
- }
-
-TInt CSimPhBkStore::DeleteAll(TTsyReqHandle aReqHandle)
-/**
- * Delete all entries in the Phonebook Store. The completion of this function is delayed in
- * order to simulate the SIM operations a real TSY would have to carry out. This function
- * may trigger an Phonebook Store notification.
- *
- * @param aReqHandle The TSY request handle associated with this request.
- * @return Standard return value.
- */
- {
- if(iPhone->IsICCLocked()!=EFalse)
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- if (!(iPhBkStoreCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
- {
- ReqCompleted(aReqHandle, KErrAccessDenied);
- return KErrNone;
- }
-
- for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
- {
- iPhBkStoreEntries[i].iTelNum.Zero();
- iPhBkStoreEntries[i].iAlphaTag.Zero();
- }
- DelayCompletion(iPhBkBatchPause,aReqHandle,EStoreEventDeleted,-1);
- return KErrNone;
- }
-
-TInt CSimPhBkStore::NotifyStoreEvent(TTsyReqHandle aReqHandle,TDes8* aPckg1,TDes8* aPckg2)
-/**
- * Register a client's interest in Phonebook Store events.
- *
- * @param aReqHandle The TSY request handle associated with this request.
- * @param aPckg1 The first parameter package associated with this request.
- * It contains the event flags that will be returned to the client.
- * @param aPckg2 The second parameter package associated with this request.
- * It contains the index value associated with the event
- * that will be returned to the client.
- * @return Standard return value.
- */
- {
- TPckg<TUint32>* eventPckg=(TPckg<TUint32>*)aPckg1;
- TUint32& event=(*eventPckg)();
- TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg2;
- TInt& index=(*indexPckg)();
-
- iEvOutstandingReq=ETrue;
- iEvReqHandle=aReqHandle;
- iEvEvent=&event;
- iEvIndex=&index;
- return KErrNone;
- }
-
-void CSimPhBkStore::NotifyStoreEventCancel()
-/**
- * Cancel an outstanding notify store request.
- */
- {
- if(iEvOutstandingReq)
- {
- iEvOutstandingReq=EFalse;
- ReqCompleted(iEvReqHandle,KErrCancel);
- }
- }
-
-TPtrC8 CSimPhBkStore::Name()
-/**
- * Accessor function fot the Phonebook Store name.
- *
- * @return TPtrC8 The name of this Phonebook Store.
- */
- {
- return iPhBkStoreName;
- }
-
-TInt CSimPhBkStore::UsedEntries()
-/**
- * Count the number of used entries in the Phonebook Store.
- * @return TInt The number of used entries in the store.
- */
- {
- TInt cnt=0;
- for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
- {
- if((iPhBkStoreEntries[i].iTelNum.Length()!=0)||(iPhBkStoreEntries[i].iAlphaTag.Length()!=0))
- cnt++;
- }
- return cnt;
- }
-
-TInt CSimPhBkStore::MaxSlots()
-/**
- * Retrieve the maximum number of slots in this Phonebook Store.
- * @return TInt The maximum number of slots in this Phonebook Store.
- */
- {
- return iPhBkMaxNumSlots;
- }
-
-void CSimPhBkStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle)
-/**
- * A shell function for functions that wish to delay completion but do not trigger store
- * events.
- */
- {
- DelayCompletion(aDelayDuration,aReqHandle,EStoreEventNoEvent,0);
- }
-
-void CSimPhBkStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle,TStoreEvent aEvent,TInt aIndex)
-/**
- * Delay the completion of a TSY request. It is assumed that the member variable
- * manipulation associated with the request has already taken place, and so all that is
- * left to do is call the ETel server's request completion function when the timer expires.
- * So, just record the parameters and kick off the timer.
- *
- * @param aDelayDuration The time (in seconds) for which the request completion is to be delayed.
- * @param aReqHandle The TSY request handle related to the delayed completion.
- * @param aEvent The store event related to the delayed completion.
- * @param aIndex The index related to the event passed in aEvent.
- */
- {
- iPendingReqCompletion=aReqHandle;
- iPendingEvent=aEvent;
- iPendingIndex=aIndex;
- iReqTimer->Start(aDelayDuration,this,ETimerIdPhBkStorReq);
- }
-
-void CSimPhBkStore::TimerCallBack(TInt aId)
-/**
- * Process a timer call back event. There are three timers associated with this class
- * and this callback will be used for all of them. The timers can be identified from the
- * aId parameter passed with the callback.
- *
- * The "Request" timer is used to kick requests which have had their completions delayed.
- * The "Out of Band Write" timer is used to schedule a non-client phonebook write.
- * The "Out of Band Delete" timer is used to schedule a non-client phonebook delete.
- *
- * @param aId The Id of the timer to which this callback relates.
- */
- {
- switch(aId)
- {
- case ETimerIdPhBkStorReq:
- StoreEvent(iPendingEvent,iPendingIndex);
- ReqCompleted(iPendingReqCompletion,KErrNone);
- break;
-
- case ETimerIdPhBkStorOOBWrite:
- iPhBkStoreEntries[iPhBkOOBWriteIndex].iAlphaTag.Copy(iPhBkOOBWrite.iAlphaTag);
- iPhBkStoreEntries[iPhBkOOBWriteIndex].iTelNum.Copy(iPhBkOOBWrite.iTelNum);
- iPhBkStoreEntries[iPhBkOOBWriteIndex].iTonNpi=iPhBkOOBWrite.iTonNpi;
- StoreEvent(EStoreEventAdded,iPhBkOOBWriteIndex);
- break;
-
- case ETimerIdPhBkStorOOBDelete:
- iPhBkStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag.Zero();
- iPhBkStoreEntries[iPhBkOOBDeleteIndex].iTelNum.Zero();
- iPhBkStoreEntries[iPhBkOOBDeleteIndex].iTonNpi=0;
- StoreEvent(EStoreEventDeleted,iPhBkOOBDeleteIndex);
- break;
-
- default:
- break;
- }
- }
-
-void CSimPhBkStore::StoreEvent(TStoreEvent aEvent,TInt aIndex)
-/**
- * Determine if a store event notification should be completed.
- * @param aEvent The store event.
- * @param aIndex The index related to the store event.
- */
- {
- if(iEvOutstandingReq)
- {
- TUint event=0;
- switch(aEvent)
- {
- case EStoreEventNoEvent:
- return;
-
- case EStoreEventAdded:
- event|=RMobilePhoneStore::KStoreEntryAdded;
- break;
-
- case EStoreEventDeleted:
- event|=RMobilePhoneStore::KStoreEntryDeleted;
- break;
-
- case EStoreEventChanged:
- event|=RMobilePhoneStore::KStoreEntryChanged;
- break;
-
- default:
- break;
- }
-
- TInt cnt=UsedEntries();
- if(cnt==0)
- event|=RMobilePhoneStore::KStoreEmpty;
-
- if(cnt==iPhBkMaxNumSlots)
- event|=RMobilePhoneStore::KStoreFull;
- else
- event|=RMobilePhoneStore::KStoreHasSpace;
-
- *iEvEvent=event;
- *iEvIndex=aIndex;
- iEvOutstandingReq=EFalse;
- ReqCompleted(iEvReqHandle,KErrNone);
- }
- }
-
-TBool CSimPhBkStore::FindIpcErrorMatch(TInt& aError)
-/**
- * Determine whether the IPC counter has signalled that the current request should
- * be errored, rather than executed.
- *
- * @param aError If the function returns ETrue, this parameter will pass back the
- * number of the error to be propagated.
- * @return TBool Returns ETrue if a match with the IPC count is found, EFalse if not.
- */
- {
- TInt i;
- for(i=0;i<iPhBkError->Count();i++)
- {
- TInt pi=iPhBkError->At(i).iCount;
- if(pi==iIpcCnt)
- {
- aError=iPhBkError->At(i).iError;
- return ETrue;
- }
- }
- return EFalse;
- }
-
-const CTestConfigSection* CSimPhBkStore::CfgFile()
-/**
-* Returns a pointer to the config file section
-*
-* @return CTestConfigSection a pointer to the configuration file data section
-*/
- {
- LOGPHBK1(">>CSimPhBkStore::CfgFile");
- return iPhone->CfgFile();
- }
+// Copyright (c) 2001-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:
+// Implements the Phonebook Store manipulation code.
+//
+//
+
+/**
+ @file
+*/
+
+#include "CSimPhBkStore.h"
+#include "CSimPhone.h"
+#include "Simlog.h"
+#include <testconfigfileparser.h>
+
+const TUint16 KNpiTonInternational=145; // < The Number Plan Identifier and Type of Number for an international telephone number.
+const TUint16 KNpiTonNational=129; // < The Number Plan Identifier and Type of Number for a national telephone number.
+const TInt KPhonebookErrorGranularity=3; // < Granularity of phonebook error list array.
+//
+// CSimPhBkStore
+//
+void CSimPhBkStore::ClosePhone(TAny* aObj)
+/**
+ * A utility function for cleaning up the stack.
+ */
+ {
+ ((CObject*)aObj)->Close();
+ }
+
+CSimPhBkStore* CSimPhBkStore::NewL(CSimPhone* aPhone, const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen)
+/**
+ * Standard two phase constructor.
+ * @param aPhone The phone object from which this Phonebook was opened.
+ * @param aName The name of the created Phonebook.
+ * @param aMaxNumSlots The maximum number of slots in the Phonebook.
+ * @return CSimPhBkStore* The newly created object.
+ */
+ {
+ CSimPhBkStore* store=new(ELeave) CSimPhBkStore(aPhone);
+ TCleanupItem newObjClose(ClosePhone,store);
+ CleanupStack::PushL(newObjClose);
+ store->ConstructL(aName,aMaxNumSlots,aMaxNumLen,aMaxTextLen);
+ CleanupStack::Pop();
+ return store;
+ }
+
+CSimPhBkStore::CSimPhBkStore(CSimPhone* aPhone)
+ : CSimPhone(iDummyPhoneBaseRef), iPhone(aPhone),iIpcCnt(0),iEvOutstandingReq(EFalse)
+/**
+ * Trivial first phase constructor.
+ * @param aPhone The phone object from which this phonebook was opened.
+ */
+ {}
+
+void CSimPhBkStore::ConstructL(const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen)
+/**
+ * Second phase constructor that allocates memory for the phonebook, batch read buffer and
+ * a delayed completion timer. The constructor also reads the individual and batch read
+ * delays from the configuration file.
+ *
+ * @param aName The name of the created phonebook.
+ * @param aMaxNumLen The maximum length of a telephone number.
+ * @param aMaxTextLen The maximum length of an alpha tag.
+ */
+ {
+ LOGPHBK1("Starting to parse Phonebook store additional config parameters...");
+ __ASSERT_ALWAYS(aMaxNumLen<=KPhBkMaxTelNumSize,SimPanic(EPhonebookNameOrNumberTooLarge));
+ __ASSERT_ALWAYS(aMaxTextLen<=KPhBkMaxAlphaTagSize,SimPanic(EPhonebookNameOrNumberTooLarge));
+
+ iPhBkStoreEntries=new(ELeave) TPhBkStoreEntry[aMaxNumSlots+1]; //slot 0 is unused
+ iPhBkMaxNumSlots=aMaxNumSlots;
+ iPhBkMaxTelNumLen=aMaxNumLen;
+ iPhBkMaxTextLen=aMaxTextLen;
+ iPhBkStoreName.Copy(aName);
+
+ iReqTimer=CSimTimer::NewL(iPhone);
+ iOOBWriteTimer=CSimTimer::NewL(iPhone);
+ iOOBDeleteTimer=CSimTimer::NewL(iPhone);
+ iPhBkRwBuffer=new(ELeave) CPhoneBookBuffer();
+ iPhBkError=new(ELeave) CArrayFixFlat<TPhBkError>(KPhonebookErrorGranularity);
+
+ const CTestConfigItem* item=NULL;
+ TInt ret=KErrNone;
+ item=CfgFile()->Item(KTriggerEventIPC,0);
+ if(item)
+ {
+ TInt ipc, cnt, event;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,ipc);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("ipc",ret,0,&KTriggerEventIPC);
+ }
+ else
+ iTriggerEventIPC.iIPC=ipc;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,cnt);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("cnt",ret,1,&KTriggerEventIPC);
+ }
+ else
+ iTriggerEventIPC.iIPCCnt=cnt;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,event);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("event",ret,2,&KTriggerEventIPC);
+ }
+ else
+ iTriggerEventIPC.iEvent=RMobilePhone::TMobilePhoneSecurityEvent(event);
+
+
+ }
+
+ const CTestConfigItem* item0=NULL;
+ item0=CfgFile()->Item(KPhBkPhoneStoreCaps,0);
+ if (item0)
+ {
+ TPtrC8 value0;
+ TInt ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,0,value0);
+ if(ret0!=KErrNone)
+ {
+ iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
+ LOGPARSERR("value0",ret0,0,&KPhBkPhoneStoreCaps);
+ }
+ else
+ {
+ TUint32 intValue;
+ TInt ret = AsciiToNum(value0, intValue);
+ if(ret!=KErrNone)
+ iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
+ else
+ iPhBkStoreCaps = intValue;
+ }
+ }
+ else
+ iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
+
+
+ LOGPHBK1("...Finished parsing Phonebook store additional config parameters...");
+ }
+
+void CSimPhBkStore::PopulateStoreFromConfigFileL()
+/**
+ * Populate the Phonebook Store from information in the configuration file. This is performed
+ * after the standard Phonebook Store construction in order to prevent reseting the configuation
+ * file accessor class' pointers while possibly multiple Phonebook Stores are created.
+ *
+ * The store entries comply to the following format:
+ * "PhBkStoreEntry = <store name>, <slot number>, <telephone number>, <alphatag>"
+ */
+ {
+ LOGPHBK1("Starting to read Phonebook store entries...");
+ iPhBkIndividualPause=CfgFile()->ItemValue(KPhBkStoreIndividualReqPause,KDefaultPhBkStoreIndividualReqPause);
+ iPhBkBatchPause=CfgFile()->ItemValue(KPhBkStoreBatchReqPause,KDefaultPhBkStoreBatchReqPause);
+
+ TInt count=CfgFile()->ItemCount(KPhBkStoreEntry);
+ const CTestConfigItem* item=NULL;
+ TInt ret=KErrNone;
+
+ TInt i;
+ for(i=0;i<count;i++)
+ {
+ item=CfgFile()->Item(KPhBkStoreEntry,i);
+ if(!item)
+ break;
+
+ TPtrC8 phonebookName,alphaTag,telNum;
+ TInt index;
+ TUint8 npiTon;
+ ret=GetPhBkEntry(item,0,phonebookName,index,telNum,alphaTag,npiTon);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("Phonebook Entry",ret,index,&KPhBkStoreEntry);
+ continue;
+ }
+ if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
+ continue;
+
+ iPhBkStoreEntries[index].iAlphaTag.Copy(alphaTag);
+ iPhBkStoreEntries[index].iTelNum.Copy(telNum);
+ iPhBkStoreEntries[index].iTonNpi=npiTon;
+ }
+
+ count=CfgFile()->ItemCount(KPhBkError);
+ item=NULL;
+
+ for(i=0;i<count;i++)
+ {
+ item=CfgFile()->Item(KPhBkError,i);
+ if(!item)
+ break;
+
+ TInt count,error;
+ TPtrC8 phonebookName, phonebookStore;
+
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("count",ret,0,&KPhBkError);
+ continue;
+ }
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,error);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("error",ret,1,&KPhBkError);
+ continue;
+ }
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,phonebookName);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("phonebookName",ret,2,&KPhBkError);
+ continue;
+ }
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,phonebookStore);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("phonebookStore",ret,3,&KPhBkError);
+ }
+ else //not for the global phonebook
+ continue;
+
+ if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
+ continue;
+
+
+ TPhBkError entry;
+ entry.iCount=count;
+ entry.iError=error;
+ iPhBkError->AppendL(entry);
+ }
+ PopulateOOBWrite();
+ PopulateOOBDelete();
+ LOGPHBK1("...Finished reading Phonebook store entries...");
+
+ if(iPhBkOOBWriteDuration!=-1)
+ iOOBWriteTimer->Start(iPhBkOOBWriteDuration,this,ETimerIdPhBkStorOOBWrite);
+ if(iPhBkOOBDeleteDuration!=-1)
+ iOOBDeleteTimer->Start(iPhBkOOBDeleteDuration,this,ETimerIdPhBkStorOOBDelete);
+ }
+
+void CSimPhBkStore::PopulateOOBWrite()
+/**
+ * Populate the member variables required to operate the OOB Store functionality from
+ * the configuration file.
+ * The OOBPhBkStore configuration file tag should have the following format:
+ * "OOBPhBkStore= <duration>, <phonebook name>, <index>, <telephone number>, <alpha tag>"
+ */
+ {
+ iPhBkOOBWriteDuration=KErrNotFound;
+ const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkWrite);
+ if(!item)
+ return;
+
+ TInt count;
+ TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("count",ret,0,&KOOBPhBkWrite);
+ return;
+ }
+
+ TPtrC8 phonebookName,alphaTag,telNum;
+ TInt index;
+ TUint8 npiTon;
+ ret=GetPhBkEntry(item,1,phonebookName,index,telNum,alphaTag,npiTon);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("npiTon",ret,index,&KOOBPhBkWrite);
+ return;
+ }
+ if(phonebookName.MatchF(iPhBkStoreName)!=0)
+ return; // Not this phonebook
+
+ iPhBkOOBWriteDuration=count;
+ iPhBkOOBWriteIndex=index;
+ iPhBkOOBWrite.iAlphaTag.Copy(alphaTag);
+ iPhBkOOBWrite.iTelNum.Copy(telNum);
+ iPhBkOOBWrite.iTonNpi=npiTon;
+ }
+
+void CSimPhBkStore::PopulateOOBDelete()
+/**
+ * Populate the member variables required to operate the OOB Delete functionality from
+ * the configuration file.
+ * The OOBPhBkDelete configuration file tag should have the following format:
+ * "OOBPhBkDelete= <duration>, <phonebook name>, <index>
+ */
+ {
+ iPhBkOOBDeleteDuration=KErrNotFound;
+ const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkDelete);
+ if(!item)
+ return;
+
+ TInt count;
+ TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("count",ret,0,&KOOBPhBkDelete);
+ return;
+ }
+
+ TPtrC8 phonebookName;
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,phonebookName);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("phonebookName",ret,1,&KOOBPhBkDelete);
+ return;
+ }
+ if(phonebookName.MatchF(iPhBkStoreName)!=0)
+ return; // Not this phonebook
+
+ TInt index;
+ ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,index);
+ if(ret!=KErrNone)
+ {
+ LOGPARSERR("index",ret,2,&KOOBPhBkDelete);
+ return;
+ }
+
+ iPhBkOOBDeleteDuration=count;
+ iPhBkOOBDeleteIndex=index;
+ }
+
+TInt CSimPhBkStore::GetPhBkEntry(const CTestConfigItem* aItem, TInt aItemIndex,
+ TPtrC8& aPhonebookName, TInt& aIndex,
+ TPtrC8& aTelNum, TPtrC8& aAlphaTag, TUint8& aNpiTon)
+/**
+ * Retrieve a phonebook entry from the configuration file, starting at a given item index
+ * value.
+ * @param aItem Pointer to the config file item from which the phonebook entry will be read.
+ * @param aItemIndex The index number within the item from which the phonebook entry will be read.
+ * @param aPhonebookName The returned phonebook name
+ * @param aIndex The returned index number
+ * @param aTelNum The returned telephone number
+ * @param aAlphaTag The returned alpha tag
+ * @param aNpiTon The returned Number Plan Identifier and Type of Number information
+ * @return TInt Standard error value.
+ */
+ {
+ TInt ret;
+ ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aPhonebookName);
+ if(ret!=KErrNone)
+ return ret;
+
+ ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aIndex);
+ if(ret!=KErrNone)
+ return ret;
+
+ if(aIndex>iPhBkMaxNumSlots) //the max number of slot is a valid slot
+ return KErrArgument;
+
+ ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aTelNum);
+ if(ret!=KErrNone)
+ return ret;
+ if(aTelNum.Length()>iPhBkMaxTelNumLen)
+ return KErrArgument;
+
+ ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag);
+ if(ret!=KErrNone)
+ return ret;
+ if(aAlphaTag.Length()>iPhBkMaxTextLen)
+ return KErrArgument;
+
+ if((aTelNum.Length()>0) && (aTelNum[0]=='+'))
+ {
+ aTelNum.Set(aTelNum.Mid(1));
+ aNpiTon=KNpiTonInternational;
+ }
+ else
+ aNpiTon=KNpiTonNational;
+ return ret;
+ }
+
+CSimPhBkStore::~CSimPhBkStore()
+/**
+ * Standard destructor. Any objects created by the ::ConstructL() function
+ * will be destroyed here.
+ */
+ {
+ delete[] iPhBkStoreEntries;
+ delete iPhBkError;
+ delete iPhBkRwBuffer;
+ delete iOOBWriteTimer;
+ delete iOOBDeleteTimer;
+ delete iReqTimer;
+ }
+
+TInt CSimPhBkStore::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
+/**
+ * Dispatch function for all Phonebook Store requests.
+ * @param aReqHandle The TSY request handle for this request.
+ * @param aIpc The IPC number of this request.
+ * @param aPckg The parameter package related to this request.
+ * @return TInt The return error condition.
+ */
+ {
+ iIpcCnt++;
+ TInt error=KErrNone;
+ if(FindIpcErrorMatch(error))
+ {
+ ReqCompleted(aReqHandle,error);
+ return KErrNone;
+ }
+
+// The following requests can be completed even if the completion of another request is pending.
+ switch(aIpc)
+ {
+ case EMobilePhoneStoreGetInfo:
+ error = GetInfo(aReqHandle,aPckg.Des1n());
+ if(iTriggerEventIPC.iIPC==aIpc)
+ {
+ iTriggerCnt++;
+ if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
+ iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
+ }
+ return error;
+
+ case EMobilePhoneStoreNotifyStoreEvent:
+ error = NotifyStoreEvent(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
+ if(iTriggerEventIPC.iIPC==aIpc)
+ {
+ iTriggerCnt++;
+ if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
+ iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
+ }
+ return error;
+
+ default:
+ break;
+ }
+
+
+// The TSY can only process one of the following requests at a time. If a second is received
+// while processing the first, then it will be errored with KErrInUse. This restriction will
+// be removed later, by inserting a request queuing mechanism. Note that the standard TSY
+// "flow control" mechanism works phone-wide and so is not suitable.
+
+ if(iReqTimer->IsActive())
+ {
+ ReqCompleted(aReqHandle,KErrInUse);
+ return KErrNone;
+ }
+
+ switch(aIpc)
+ {
+// The standard multimode store read and write are not supported.
+ case EMobilePhoneStoreRead:
+ case EMobilePhoneStoreWrite:
+ case EMobilePhoneStoreReadAllPhase1:
+ case EMobilePhoneStoreReadAllPhase2:
+ ReqCompleted(aReqHandle,KErrNotSupported);
+ return KErrNone;
+
+ case EMobilePhoneBookStoreRead:
+ error = Read(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
+ if(iTriggerEventIPC.iIPC==aIpc)
+ {
+ iTriggerCnt++;
+ if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
+ iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
+ }
+ return error;
+
+ case EMobilePhoneBookStoreWrite:
+ error = Write(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
+ if(iTriggerEventIPC.iIPC==aIpc)
+ {
+ iTriggerCnt++;
+ if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
+ iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
+ }
+ return error;
+
+ case EMobilePhoneStoreDelete:
+ error = Delete(aReqHandle,aPckg.Des1n());
+ if(iTriggerEventIPC.iIPC==aIpc)
+ {
+ iTriggerCnt++;
+ if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
+ iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
+ }
+ return error;
+
+ case EMobilePhoneStoreDeleteAll:
+ error = DeleteAll(aReqHandle);
+ if(iTriggerEventIPC.iIPC==aIpc)
+ {
+ iTriggerCnt++;
+ if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
+ iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
+ }
+ return error;
+
+ default:
+ break;
+ }
+
+ return KErrNotSupported;
+ }
+
+CTelObject* CSimPhBkStore::OpenNewObjectByNameL(const TDesC& /*aName*/)
+/**
+ * The API does not support any objects that could be opened from this one.
+ */
+ {
+ User::Leave(KErrNotSupported);
+ return NULL;
+ }
+
+CTelObject* CSimPhBkStore::OpenNewObjectL(TDes&)
+/**
+ * The API does not support any objects that could be opened from this one.
+ */
+ {
+ User::Leave(KErrNotSupported);
+ return NULL;
+ }
+
+CTelObject::TReqMode CSimPhBkStore::ReqModeL(const TInt aIpc)
+/**
+ * This function returns the Request Mode for the request with the passed IPC value.
+ * @param aIpc The IPC number of the request.
+ * @return TReqMode The request mode.
+ */
+ {
+ CTelObject::TReqMode ret=0;
+
+ switch(aIpc)
+ {
+ case EMobilePhoneStoreGetInfo:
+ case EMobilePhoneStoreDelete:
+ case EMobilePhoneStoreDeleteAll:
+ case EMobilePhoneBookStoreRead:
+ case EMobilePhoneBookStoreWrite:
+ break;
+
+ case EMobilePhoneStoreNotifyStoreEvent:
+ ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
+ break;
+
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ }
+
+ return ret;
+ }
+
+TInt CSimPhBkStore::RegisterNotification(const TInt /*aIpc*/)
+/**
+ * The ETel Server calls this function when the first client makes a notification
+ * request. If supported by the underlying protocol controlling the
+ * signalling stack, this can be used to start requesting updates for the relevant
+ * service.
+ */
+ {
+ return KErrNone;
+ }
+
+TInt CSimPhBkStore::DeregisterNotification(const TInt /*aIpc*/)
+/**
+ * The ETel Server calls this function when the last client that had previously
+ * made a notification request closes its ETel Server handle. If supported by
+ * the underlying protocol controlling the signalling stack, this can be used
+ * to stop requesting updates for the relevant service.
+ */
+ {
+ return KErrNone;
+ }
+
+TInt CSimPhBkStore::NumberOfSlotsL(const TInt /*aIpc*/)
+/**
+ * Return the number of slots that the ETel Server should allocate for buffering requests
+ * of the given IPC number.
+ */
+ {
+ return KDefaultNumberOfSlots;
+ }
+
+TInt CSimPhBkStore::CancelService(const TInt aIpc,const TTsyReqHandle /*aTsyReqHandle*/)
+/**
+ * Cancel an outstanding request.
+ * @param aIpc The IPC number of the request that is to be cancelled.
+ * @param aTsyReqHandle The TSY request handle of the request that is to be cancelled.
+ * @param TInt Standard return value.
+ */
+ {
+ switch(aIpc)
+ {
+ case EMobilePhoneStoreGetInfo:
+ case EMobilePhoneStoreDelete:
+ case EMobilePhoneStoreDeleteAll:
+ case EMobilePhoneBookStoreRead:
+ case EMobilePhoneBookStoreWrite:
+ break;
+
+ case EMobilePhoneStoreNotifyStoreEvent:
+ NotifyStoreEventCancel();
+ break;
+
+ default:
+ break;
+ }
+ return KErrNone;
+ }
+
+void CSimPhBkStore::Init()
+/**
+ * This function can be used to perform any necessary synchronous initialisation.
+ */
+ {
+ }
+
+TInt CSimPhBkStore::GetInfo(TTsyReqHandle aReqHandle, TDes8* aPckg)
+/**
+ * Retrieve Phonebook Store information. This request is completed immediately, as it is assumed
+ * that in a real TSY, all this data will be cached in the TSY.
+ *
+ * @param aReqHandle The TSY request handle associated with this request.
+ * @param aPckg The parameter package associated with this request.
+ */
+ {
+
+ if(iPhone->IsICCLocked()!=EFalse)
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg* getInfoPckg=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg*)aPckg;
+ RMobilePhoneBookStore::TMobilePhoneBookInfoV1& getInfo=(*getInfoPckg)();
+
+ PopulatePhBkStoreInfo(&getInfo);
+
+ if(&getInfo!=NULL) // This will be the case if the version checking within PopulatePhBkStoreInfo has failed.
+ {
+ ReqCompleted(aReqHandle,KErrNone);
+ }
+ else
+ {
+ ReqCompleted(aReqHandle,KErrNotSupported);
+ }
+
+ return KErrNone;
+ }
+
+void CSimPhBkStore::PopulatePhBkStoreInfo(RMobilePhoneStore::TMobilePhoneStoreInfoV1* aStoreInfo)
+/**
+ * Populate the passed parameter with Phonebook Store information.
+ * @param aStoreInfo Pointer to phonebook store information structure to be populated.
+ */
+ {
+ __ASSERT_ALWAYS(aStoreInfo, SimPanic(EIllegalNullPtrParameter));
+
+ aStoreInfo->iType=RMobilePhoneStore::EPhoneBookStore;
+ aStoreInfo->iTotalEntries=MaxSlots();
+ aStoreInfo->iCaps=iPhBkStoreCaps;
+ aStoreInfo->iName.Copy(iPhBkStoreName);
+ aStoreInfo->iUsedEntries=UsedEntries();
+
+ if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV1)
+ {
+ RMobilePhoneBookStore::TMobilePhoneBookInfoV1* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1*)aStoreInfo;
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
+ if(err != KErrNone)
+ {
+ getExtraInfo = NULL;
+ return;
+ }
+
+ getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
+ getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
+ getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
+ getExtraInfo->iChangeCounter=0;
+ getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
+ }
+ else if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV2)
+ {
+ RMobilePhoneBookStore::TMobilePhoneBookInfoV2* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV2*)aStoreInfo;
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
+ if(err != KErrNone)
+ {
+ getExtraInfo = NULL;
+ return;
+ }
+
+ getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
+ getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
+ getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
+ getExtraInfo->iChangeCounter=0;
+ getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
+
+ getExtraInfo->iPhBkMode.Zero();
+ }
+ else if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV5)
+ {
+ RMobilePhoneBookStore::TMobilePhoneBookInfoV5* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV5*)aStoreInfo;
+
+ // Check that the data structure is supported by the simulated TSY version
+ TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
+ if(err != KErrNone)
+ {
+ getExtraInfo = NULL;
+ return;
+ }
+
+ getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
+ getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
+ getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
+ getExtraInfo->iChangeCounter=0;
+ getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
+
+ getExtraInfo->iPhBkMode.Zero();
+
+ getExtraInfo->iMaxSecondNames = 0;
+ getExtraInfo->iMaxTextLengthSecondName = 0;
+ getExtraInfo->iMaxAdditionalNumbers = 0;
+ getExtraInfo->iMaxTextLengthAdditionalNumber = 0;
+ getExtraInfo->iMaxNumLengthAdditionalNumber = 0;
+ getExtraInfo->iMaxGroupNames = 0;
+ getExtraInfo->iMaxTextLengthGroupName = 0;
+ getExtraInfo->iMaxEmailAddr = 0;
+ getExtraInfo->iMaxTextLengthEmailAddr = 0;
+ }
+ }
+
+TInt CSimPhBkStore::Read(TTsyReqHandle aReqHandle, TDes8* aPckg1,TDes8* aPckg2)
+/**
+ * Read Phonebook store entries. The completion of this request is delayed in order to
+ * simulate a real TSY that would have to go and get the information from a SIM card.
+ *
+ * @param aReqHandle The TSY request handle associated with this request.
+ * @param aPckg1 The first parameter package associated with this request.
+ * It contains the index from which the read should start and
+ * the number of entries which should be read.
+ * @param aPckg2 The second parameter package associated with this request.
+ * It contains the buffer, which will be populated with the retrieved
+ * values.
+ * @return TInt Standard return value.
+ */
+ {
+ if(iPhone->IsICCLocked()!=EFalse)
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ TPckg<RMobilePhoneBookStore::TPBIndexAndNumEntries>* indexNumPckg=(TPckg<RMobilePhoneBookStore::TPBIndexAndNumEntries>*)aPckg1;
+ RMobilePhoneBookStore::TPBIndexAndNumEntries& indexNum=(*indexNumPckg)();
+
+ if(indexNum.iNumSlots==iPhBkMaxNumSlots)
+ {
+ if (!(iPhBkStoreCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsReadAccess))
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+ }
+ else if((indexNum.iIndex+indexNum.iNumSlots - 1)>iPhBkMaxNumSlots)
+ {
+ ReqCompleted(aReqHandle,KErrArgument);
+ return KErrNone;
+ }
+
+ else if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsReadAccess))
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ iPhBkRwBuffer->Set(aPckg2);
+
+ TInt cnt=0;
+ TInt ret=0;
+ TBool partial=EFalse;
+ for(TInt i=indexNum.iIndex;i<=iPhBkMaxNumSlots;i++)
+ {
+ if((iPhBkStoreEntries[i].iTelNum.Length()!=0)||(iPhBkStoreEntries[i].iAlphaTag.Length()!=0))
+ {
+ ret=iPhBkRwBuffer->AddNewEntryTag();
+ if(ret!=KErrNone)
+ break;
+
+ partial=ETrue;
+ ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i);
+ if(ret!=KErrNone)
+ break;
+ ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,iPhBkStoreEntries[i].iAlphaTag);
+ if(ret!=KErrNone)
+ break;
+ ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,iPhBkStoreEntries[i].iTonNpi);
+ if(ret!=KErrNone)
+ break;
+ ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,iPhBkStoreEntries[i].iTelNum);
+ if(ret!=KErrNone)
+ break;
+
+ partial=EFalse;
+ if(++cnt>=indexNum.iNumSlots)
+ break;
+ }
+ }
+ if(partial)
+ // EXPORT - but return value not relevant
+ (void)iPhBkRwBuffer->RemovePartialEntry();
+
+ indexNum.iNumSlots=cnt;
+
+ if((cnt==0)&&(partial))
+ ReqCompleted(aReqHandle,KErrArgument); // An entry was found, but the buffer was too small to return it.
+ else if((cnt==0)&&(!partial))
+ ReqCompleted(aReqHandle,KErrNotFound); // No entries found.
+ else
+ ReqCompleted(aReqHandle,KErrNone);
+
+ return KErrNone;
+ }
+
+TInt CSimPhBkStore::Write(TTsyReqHandle aReqHandle,TDes8* aPckg1,TDes8* aPckg2)
+/**
+ * Write a phonebook store entries. The completion of this request is delayed in order to
+ * simulate a real TSY that would have to write the information to a SIM card. A store
+ * event may be triggered by this request.
+ *
+ * @param aReqHandle The TSY request handle associated with this request.
+ * @param aPckg1 The first parameter package associated with this request.
+ * This contains the TLV phonebook entry to be written.
+ * @param aPckg2 The second parameter package associated with this request.
+ * This contains the slot index number to which the entry must be written.
+ */
+ {
+ if(iPhone->IsICCLocked()!=EFalse)
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg2;
+ TInt& index=(*indexPckg)();
+
+// If the index is -1, then use the first available free slot.
+ if(index==-1)
+ {
+ for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
+ {
+ if((iPhBkStoreEntries[i].iTelNum.Length()==0)&&(iPhBkStoreEntries[i].iAlphaTag.Length()==0))
+ {
+ index=i;
+ break;
+ }
+ }
+ }
+
+ if(index==-1)
+ {
+ ReqCompleted(aReqHandle,EXTENDEDERROR(KErrNoMemory, KErrPhonebookNoMemory));
+ return KErrNone;
+ }
+
+ if((index<1)||(index>iPhBkMaxNumSlots))
+ {
+ ReqCompleted(aReqHandle,KErrArgument);
+ return KErrNone;
+ }
+
+ TBool isSlotAlreadyUsed=EFalse;
+ if(iPhBkStoreEntries[index].iTelNum.Length()!=0)
+ isSlotAlreadyUsed=ETrue;
+
+// Unpick the phonebook entry.
+ iPhBkRwBuffer->Set(aPckg1);
+ iPhBkRwBuffer->StartRead();
+
+ TUint8 tagVal;
+ TUint8 npiTon=0;
+ TPtrC alphaTag;
+ TPtrC telNum;
+ TPtrC alphaTag2;
+ TBool skipToNextEntry=EFalse;
+ CPhoneBookBuffer::TPhBkTagType tagType;
+ TInt ret=KErrNone;
+
+ while(ret==KErrNone)
+ {
+ ret=iPhBkRwBuffer->GetTagAndType(tagVal,tagType);
+ if(ret==KErrNotFound)
+ {
+ ret=KErrNone;
+ break;
+ }
+ else if(ret!=KErrNone)
+ break;
+
+
+ switch(tagVal)
+ {
+ case RMobilePhoneBookStore::ETagPBNewEntry:
+ skipToNextEntry=EFalse;
+ break;
+
+ case RMobilePhoneBookStore::ETagPBText:
+ if(!skipToNextEntry)
+ ret=iPhBkRwBuffer->GetValue(alphaTag);
+ else
+ {
+ TPtrC throwAway;
+ ret=iPhBkRwBuffer->GetValue(throwAway);
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBNumber:
+ if(!skipToNextEntry)
+ ret=iPhBkRwBuffer->GetValue(telNum);
+ else
+ {
+ TPtrC throwAway;
+ ret=iPhBkRwBuffer->GetValue(throwAway);
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBTonNpi:
+ if(!skipToNextEntry)
+ ret=iPhBkRwBuffer->GetValue(npiTon);
+ else
+ {
+ TUint8 throwAway;
+ ret=iPhBkRwBuffer->GetValue(throwAway);
+ }
+ break;
+
+ // Alexandros - phbksync "shortcut" should be discussed and removed
+ case RMobilePhoneBookStore::ETagPBAnrStart:
+ skipToNextEntry=ETrue;
+ break;
+
+ case RMobilePhoneBookStore::ETagPBEmailAddress:
+ case RMobilePhoneBookStore::ETagPBGroupName:
+ case RMobilePhoneBookStore::ETagPBSecondName:
+ ret=iPhBkRwBuffer->GetValue(alphaTag2);
+ break;
+ case RMobilePhoneBookStore::ETagPBHiddenInfo:
+ TUint8 throwAway;
+ ret=iPhBkRwBuffer->GetValue(throwAway);
+ break;
+
+ default:
+ //DEF001769 - SIM TSY should ignore extra fields in short entries
+ //ret=KErrNotSupported;
+ break;
+ }
+ }
+
+ if(ret!=KErrNone)
+ {
+ ReqCompleted(aReqHandle,ret);
+ return KErrNone;
+ }
+
+ LOGPHBK2("alphaTag Length = (%d)",alphaTag.Length());
+ LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen);
+ LOGPHBK2("TelNum Length = (%d)",telNum.Length());
+ LOGPHBK2("TelNum Max Length = (%d)",iPhBkMaxTelNumLen);
+
+ if(alphaTag.Length()>iPhBkMaxTextLen)
+ {
+ ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookTextOverflow));
+ return KErrNone;
+ }
+ else if(telNum.Length()>iPhBkMaxTelNumLen)
+ {
+ ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookNumberOverflow));
+ return KErrNone;
+ }
+
+ iPhBkStoreEntries[index].iAlphaTag.Copy(alphaTag);
+ iPhBkStoreEntries[index].iTelNum.Copy(telNum);
+ iPhBkStoreEntries[index].iTonNpi=npiTon;
+ if(isSlotAlreadyUsed)
+ DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventChanged,index);
+ else
+ DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventAdded,index);
+ return KErrNone;
+ }
+
+TInt CSimPhBkStore::Delete(TTsyReqHandle aReqHandle,TDes8* aPckg)
+/**
+ * Delete a single Phonebook store entry. The completion of this request is delayed in order to
+ * simulate a real TSY that would have to write the information to a SIM card. A store
+ * event may be triggered by this request.
+ *
+ * @param aReqHandle The TSY request handle associated with this request.
+ * @param aPckg The parameter package associated with this request.
+ * @return Standard return value.
+ */
+ {
+ if(iPhone->IsICCLocked()!=EFalse)
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+
+ TPckg<TInt>* intPckg=(TPckg<TInt>*)aPckg;
+ TInt& index=(*intPckg)();
+
+ if((index<1)||(index>iPhBkMaxNumSlots))
+ {
+ ReqCompleted(aReqHandle,KErrArgument);
+ return KErrNone;
+ }
+
+ iPhBkStoreEntries[index].iTelNum.Zero();
+ iPhBkStoreEntries[index].iAlphaTag.Zero();
+ DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventDeleted,index);
+ return KErrNone;
+ }
+
+TInt CSimPhBkStore::DeleteAll(TTsyReqHandle aReqHandle)
+/**
+ * Delete all entries in the Phonebook Store. The completion of this function is delayed in
+ * order to simulate the SIM operations a real TSY would have to carry out. This function
+ * may trigger an Phonebook Store notification.
+ *
+ * @param aReqHandle The TSY request handle associated with this request.
+ * @return Standard return value.
+ */
+ {
+ if(iPhone->IsICCLocked()!=EFalse)
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ if (!(iPhBkStoreCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
+ {
+ ReqCompleted(aReqHandle, KErrAccessDenied);
+ return KErrNone;
+ }
+
+ for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
+ {
+ iPhBkStoreEntries[i].iTelNum.Zero();
+ iPhBkStoreEntries[i].iAlphaTag.Zero();
+ }
+ DelayCompletion(iPhBkBatchPause,aReqHandle,EStoreEventDeleted,-1);
+ return KErrNone;
+ }
+
+TInt CSimPhBkStore::NotifyStoreEvent(TTsyReqHandle aReqHandle,TDes8* aPckg1,TDes8* aPckg2)
+/**
+ * Register a client's interest in Phonebook Store events.
+ *
+ * @param aReqHandle The TSY request handle associated with this request.
+ * @param aPckg1 The first parameter package associated with this request.
+ * It contains the event flags that will be returned to the client.
+ * @param aPckg2 The second parameter package associated with this request.
+ * It contains the index value associated with the event
+ * that will be returned to the client.
+ * @return Standard return value.
+ */
+ {
+ TPckg<TUint32>* eventPckg=(TPckg<TUint32>*)aPckg1;
+ TUint32& event=(*eventPckg)();
+ TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg2;
+ TInt& index=(*indexPckg)();
+
+ iEvOutstandingReq=ETrue;
+ iEvReqHandle=aReqHandle;
+ iEvEvent=&event;
+ iEvIndex=&index;
+ return KErrNone;
+ }
+
+void CSimPhBkStore::NotifyStoreEventCancel()
+/**
+ * Cancel an outstanding notify store request.
+ */
+ {
+ if(iEvOutstandingReq)
+ {
+ iEvOutstandingReq=EFalse;
+ ReqCompleted(iEvReqHandle,KErrCancel);
+ }
+ }
+
+TPtrC8 CSimPhBkStore::Name()
+/**
+ * Accessor function fot the Phonebook Store name.
+ *
+ * @return TPtrC8 The name of this Phonebook Store.
+ */
+ {
+ return iPhBkStoreName;
+ }
+
+TInt CSimPhBkStore::UsedEntries()
+/**
+ * Count the number of used entries in the Phonebook Store.
+ * @return TInt The number of used entries in the store.
+ */
+ {
+ TInt cnt=0;
+ for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
+ {
+ if((iPhBkStoreEntries[i].iTelNum.Length()!=0)||(iPhBkStoreEntries[i].iAlphaTag.Length()!=0))
+ cnt++;
+ }
+ return cnt;
+ }
+
+TInt CSimPhBkStore::MaxSlots()
+/**
+ * Retrieve the maximum number of slots in this Phonebook Store.
+ * @return TInt The maximum number of slots in this Phonebook Store.
+ */
+ {
+ return iPhBkMaxNumSlots;
+ }
+
+void CSimPhBkStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle)
+/**
+ * A shell function for functions that wish to delay completion but do not trigger store
+ * events.
+ */
+ {
+ DelayCompletion(aDelayDuration,aReqHandle,EStoreEventNoEvent,0);
+ }
+
+void CSimPhBkStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle,TStoreEvent aEvent,TInt aIndex)
+/**
+ * Delay the completion of a TSY request. It is assumed that the member variable
+ * manipulation associated with the request has already taken place, and so all that is
+ * left to do is call the ETel server's request completion function when the timer expires.
+ * So, just record the parameters and kick off the timer.
+ *
+ * @param aDelayDuration The time (in seconds) for which the request completion is to be delayed.
+ * @param aReqHandle The TSY request handle related to the delayed completion.
+ * @param aEvent The store event related to the delayed completion.
+ * @param aIndex The index related to the event passed in aEvent.
+ */
+ {
+ iPendingReqCompletion=aReqHandle;
+ iPendingEvent=aEvent;
+ iPendingIndex=aIndex;
+ iReqTimer->Start(aDelayDuration,this,ETimerIdPhBkStorReq);
+ }
+
+void CSimPhBkStore::TimerCallBack(TInt aId)
+/**
+ * Process a timer call back event. There are three timers associated with this class
+ * and this callback will be used for all of them. The timers can be identified from the
+ * aId parameter passed with the callback.
+ *
+ * The "Request" timer is used to kick requests which have had their completions delayed.
+ * The "Out of Band Write" timer is used to schedule a non-client phonebook write.
+ * The "Out of Band Delete" timer is used to schedule a non-client phonebook delete.
+ *
+ * @param aId The Id of the timer to which this callback relates.
+ */
+ {
+ switch(aId)
+ {
+ case ETimerIdPhBkStorReq:
+ StoreEvent(iPendingEvent,iPendingIndex);
+ ReqCompleted(iPendingReqCompletion,KErrNone);
+ break;
+
+ case ETimerIdPhBkStorOOBWrite:
+ iPhBkStoreEntries[iPhBkOOBWriteIndex].iAlphaTag.Copy(iPhBkOOBWrite.iAlphaTag);
+ iPhBkStoreEntries[iPhBkOOBWriteIndex].iTelNum.Copy(iPhBkOOBWrite.iTelNum);
+ iPhBkStoreEntries[iPhBkOOBWriteIndex].iTonNpi=iPhBkOOBWrite.iTonNpi;
+ StoreEvent(EStoreEventAdded,iPhBkOOBWriteIndex);
+ break;
+
+ case ETimerIdPhBkStorOOBDelete:
+ iPhBkStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag.Zero();
+ iPhBkStoreEntries[iPhBkOOBDeleteIndex].iTelNum.Zero();
+ iPhBkStoreEntries[iPhBkOOBDeleteIndex].iTonNpi=0;
+ StoreEvent(EStoreEventDeleted,iPhBkOOBDeleteIndex);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+void CSimPhBkStore::StoreEvent(TStoreEvent aEvent,TInt aIndex)
+/**
+ * Determine if a store event notification should be completed.
+ * @param aEvent The store event.
+ * @param aIndex The index related to the store event.
+ */
+ {
+ if(iEvOutstandingReq)
+ {
+ TUint event=0;
+ switch(aEvent)
+ {
+ case EStoreEventNoEvent:
+ return;
+
+ case EStoreEventAdded:
+ event|=RMobilePhoneStore::KStoreEntryAdded;
+ break;
+
+ case EStoreEventDeleted:
+ event|=RMobilePhoneStore::KStoreEntryDeleted;
+ break;
+
+ case EStoreEventChanged:
+ event|=RMobilePhoneStore::KStoreEntryChanged;
+ break;
+
+ default:
+ break;
+ }
+
+ TInt cnt=UsedEntries();
+ if(cnt==0)
+ event|=RMobilePhoneStore::KStoreEmpty;
+
+ if(cnt==iPhBkMaxNumSlots)
+ event|=RMobilePhoneStore::KStoreFull;
+ else
+ event|=RMobilePhoneStore::KStoreHasSpace;
+
+ *iEvEvent=event;
+ *iEvIndex=aIndex;
+ iEvOutstandingReq=EFalse;
+ ReqCompleted(iEvReqHandle,KErrNone);
+ }
+ }
+
+TBool CSimPhBkStore::FindIpcErrorMatch(TInt& aError)
+/**
+ * Determine whether the IPC counter has signalled that the current request should
+ * be errored, rather than executed.
+ *
+ * @param aError If the function returns ETrue, this parameter will pass back the
+ * number of the error to be propagated.
+ * @return TBool Returns ETrue if a match with the IPC count is found, EFalse if not.
+ */
+ {
+ TInt i;
+ for(i=0;i<iPhBkError->Count();i++)
+ {
+ TInt pi=iPhBkError->At(i).iCount;
+ if(pi==iIpcCnt)
+ {
+ aError=iPhBkError->At(i).iError;
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+const CTestConfigSection* CSimPhBkStore::CfgFile()
+/**
+* Returns a pointer to the config file section
+*
+* @return CTestConfigSection a pointer to the configuration file data section
+*/
+ {
+ LOGPHBK1(">>CSimPhBkStore::CfgFile");
+ return iPhone->CfgFile();
+ }