diff -r 6b1d113cdff3 -r 6638e7f4bd8f telephonyserverplugins/simtsy/src/CSimPhBkUsimStore.cpp --- a/telephonyserverplugins/simtsy/src/CSimPhBkUsimStore.cpp Mon May 03 13:37:20 2010 +0300 +++ b/telephonyserverplugins/simtsy/src/CSimPhBkUsimStore.cpp Thu May 06 15:10:38 2010 +0100 @@ -1,2297 +1,2297 @@ -// 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 "CSimPhBkUsimStore.h" -#include "CSimPhone.h" -#include "Simlog.h" -#include - -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 KMaxGroups = 10; // < The maximum allowed number of groups associated with a phonebook entry -const TInt KMaxSecondNames = 1; // < The maximum allowed number of Second Names associated with a phonebook entry -const TInt KPhonebookErrorGranularity=3; // < Granularity of phonebook error list array. -const TUint DELETED=0xdededede; -// -// CSimPhBkUSimStore -// -void CSimPhBkUSimStore::ClosePhone(TAny* aObj) -/** - * A utility function for cleaning up the stack. - */ - { - ((CObject*)aObj)->Close(); - } - -CSimPhBkUSimStore* CSimPhBkUSimStore::NewL(CSimPhone* aPhone, const TDesC8& aStore, const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen, TInt aAdditional, TInt aMaxEmail, TInt aMaxAdditionalTelNumLen, TInt aMaxAdditionalTextLen) -/** - * 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. - * @param aMaxNumLen The maximum length of the telephone number (<100) - * @param aMaxTextLen The maximum length of the alpha text strings (<100) - * @param aAdditional The maximum number of additional numbers associated with an entry - * @param aMaxEmail The maximum number of email addresses associated with an entry - * @param aMaxAdditionalTelNumLen The maximum length of the an additional telephone number. - * @param aMaxAdditionalTextLen The maximum length of the alpha tag in an additional telephone number. - * @return CSimPhBkUSimStore* The newly created object. - */ - { - CSimPhBkUSimStore* store=new(ELeave) CSimPhBkUSimStore(aPhone); - TCleanupItem newObjClose(ClosePhone,store); - CleanupStack::PushL(newObjClose); - store->ConstructL(aStore,aName,aMaxNumSlots,aMaxNumLen,aMaxTextLen,aAdditional,aMaxEmail, aMaxAdditionalTelNumLen, aMaxAdditionalTextLen); - CleanupStack::Pop(); - return store; - } - -CSimPhBkUSimStore::CSimPhBkUSimStore(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 CSimPhBkUSimStore::ConstructL(const TDesC8& aStore, const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen, TInt aAdditional, TInt aMaxEmail, TInt aMaxAdditionalTelNumLen, TInt aMaxAdditionalTextLen) -/** - * 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. - * @param aMaxNumLen The maximum length of the telephone number (<100). - * @param aMaxTextLen The maximum length of the alpha text strings (<100). - * @param aAdditional The maximum number of additional numbers associated with an entry. - * @param aMaxEmail The maximum number of email addresses associated with an entry. - * @param aMaxAdditionalTelNumLen The maximum length of the an additional telephone number. - * @param aMaxAdditionalTextLen The maximum length of the alpha tag in an additional telephone number. - */ - { - LOGPHBK1("Starting to parse Phonebook store additional config parameters..."); - __ASSERT_ALWAYS(aMaxNumLen<=KPhBkMaxTelNumSize,SimPanic(EPhonebookNameOrNumberTooLarge)); - __ASSERT_ALWAYS(aMaxTextLen<=KPhBkMaxAlphaTagSize,SimPanic(EPhonebookNameOrNumberTooLarge)); - - iPhBkMaxNumSlots=aMaxNumSlots; - iPhBkMaxTelNumLen=aMaxNumLen; - iPhBkMaxTextLen=aMaxTextLen; - iPhBkStoreName.Copy(aName); - iPhBkStore.Copy(aStore); - iPhBkAdditional=aAdditional; - iPhBkMaxEmail=aMaxEmail; - iPhBkMaxAdditionalTelNumLen = aMaxAdditionalTelNumLen; - iPhBkMaxAdditionalTextLen = aMaxAdditionalTextLen; - - iPhBkAid.Zero(); - iPhBkAidUSim1.Zero(); - iPhBkAidUSim2.Zero(); - - if(iPhBkStore.Compare(KUSimPhoneBook)==KErrNone) - { - iPhBkUSim1StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused - iPhBkUSim2StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused - } - else - { - iPhBkUSim1StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused - iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries; - } - - iReqTimer=CSimTimer::NewL(iPhone); - iOOBWriteTimer=CSimTimer::NewL(iPhone); - iOOBDeleteTimer=CSimTimer::NewL(iPhone); - iPhBkRwBuffer=new(ELeave) CPhoneBookBuffer(); - iPhBkError=new(ELeave) CArrayFixFlat(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; - TInt count=CfgFile()->ItemCount(KPhBkPhoneUSimStoreCaps); - - if(count==0) - iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; - else - { - TBool capsFound=EFalse; - for(TInt i=0;(iItem(KPhBkPhoneUSimStoreCaps,i); - - if (item0) - { - TPtrC8 value0,phonebookStore, phonebookName; - TInt ret0; - - ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,0,phonebookStore); - if(ret0!=KErrNone) - { - iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; - LOGPARSERR("Caps:PhonebookStore",ret,0,&KPhBkPhoneUSimStoreCaps); - } - - if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type - continue; - - ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,1,phonebookName); - if(ret0!=KErrNone) - { - iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; - LOGPARSERR("phonebookName",ret,1,&KPhBkPhoneUSimStoreCaps); - } - - if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this PhBkStoreName type - continue; - - ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,2,value0); - if(ret0!=KErrNone) - { - iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; - LOGPARSERR("caps",ret,2,&KPhBkPhoneUSimStoreCaps); - } - else - { - TUint32 intValue; - TInt ret = AsciiToNum(value0, intValue); - if(ret!=KErrNone) - iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; - else - { - iPhBkStoreCaps = intValue; - capsFound=ETrue; - } - } - - } - } - } - LOGPHBK1("...Finished parsing Phonebook store additional config parameters..."); - } - -void CSimPhBkUSimStore::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. -//alex - * - * The store entries comply to the following format: - * "PhBkStoreEntry = , , , " - */ - { - LOGPHBK1("Starting to read Phonebook store entries..."); - iPhBkIndividualPause=CfgFile()->ItemValue(KPhBkStoreIndividualReqPause,KDefaultPhBkStoreIndividualReqPause); - iPhBkBatchPause=CfgFile()->ItemValue(KPhBkStoreBatchReqPause,KDefaultPhBkStoreBatchReqPause); - - const CTestConfigItem* item=NULL; - TInt ret=KErrNone; - - TInt i; - - // Get Phonebook entries - TInt count=CfgFile()->ItemCount(KPhBkUSimStoreEntry); - for(i=0;iItem(KPhBkUSimStoreEntry,i); - if(!item) - break; - - TPtrC8 phonebookStore,aid, phonebookName,alphaTag,telNum,alphaTag2,emails, groups, additional; - TInt index; - TUint8 npiTon; - ret=GetPhBkUSimEntry(item,parseIndex,phonebookStore,phonebookName,aid,index,telNum,alphaTag,npiTon,alphaTag2); - if(ret!=KErrNone) - { - LOGPARSERR("Phonebook Entry",ret,index,&KPhBkUSimStoreEntry); - continue; - } - - if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type - continue; - else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook - continue; - - if(phonebookStore.MatchF(KUSimPhoneBook)==0 && - iPhBkAid.Length()==0) //starting up - { - iPhBkAid.Copy(aid); - iPhBkAidUSim1.Copy(aid); - iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries; - } - - else if(phonebookStore.MatchF(KUSimPhoneBook)==0 && - iPhBkAid.Length()!=0 && iPhBkAid.Compare(aid)!=KErrNone) - { - if(iPhBkAidUSim2.Length()==0) - { - iPhBkAid.Copy(aid); - iPhBkAidUSim2.Copy(aid); - iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries; - } - else if(iPhBkAidUSim2.Compare(aid)==KErrNone) - { - iPhBkAid.Copy(aid); - iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries; - } - else if(iPhBkAidUSim2.Compare(aid)!=KErrNone) - //Currently there is support for only 2 USim phonebooks - {continue;} //...so, a possible third one will be ignored!!! - } - - iPhBkUSimStoreEntries[index].iAlphaTag.Copy(alphaTag); - iPhBkUSimStoreEntries[index].iTelNum.Copy(telNum); - iPhBkUSimStoreEntries[index].iTonNpi=npiTon; - iPhBkUSimStoreEntries[index].iAlphaTag2.Copy(alphaTag2); - - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,additional); - if(ret!=KErrNone) - { - LOGPARSERR("additional",ret,parseIndex,&KPhBkUSimStoreEntry); - } - else - { - TPtrC8 myName,myNum; - TUint8 myTon; - TInt myindex=0,pIndex=0; - iPhBkUSimStoreEntries[index].iAdditional=new(ELeave) CArrayFixFlat(iPhBkAdditional+1); - - while((GetPhBkAdditionalEntry(additional,pIndex,myNum,myName,myTon)==KErrNone) - && (myindex < iPhBkAdditional)) - { - TPhBkStoreEntry entry; - - entry.iAlphaTag.Copy(myName); - entry.iTelNum.Copy(myNum); - entry.iTonNpi=myTon; - TRAP_IGNORE(iPhBkUSimStoreEntries[index].iAdditional->AppendL(entry)); - - myindex++; - } - - } - - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,emails); - if(ret!=KErrNone) - { - LOGPARSERR("emails",ret,parseIndex,&KPhBkUSimStoreEntry); - } - else - { - TPtrC8 myemail; - TInt myindex=0; - iPhBkUSimStoreEntries[index].iEmails=new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1); - - while((CTestConfig::GetElement(emails,';',myindex,myemail)==KErrNone) && - (myindex < iPhBkMaxEmail)) - { - TPhBkUSimEmail entry; - entry.Copy(myemail); - TRAP_IGNORE(iPhBkUSimStoreEntries[index].iEmails->AppendL(entry)); - myindex++; - } - } - - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,groups); - if(ret!=KErrNone) - { - LOGPARSERR("groups",ret,parseIndex,&KPhBkUSimStoreEntry); - } - else - { - - TPtrC8 mygroup; - TInt myindex=0; - iPhBkUSimStoreEntries[index].iGroups=new(ELeave) CArrayFixFlat(KMaxGroups+1); - - - while((CTestConfig::GetElement(groups,';',myindex,mygroup)==KErrNone) && - (myindex < KMaxGroups)) - { - TPhBkUSimGroup entry; - entry.Copy(mygroup); - TRAP_IGNORE(iPhBkUSimStoreEntries[index].iGroups->AppendL(entry)); - myindex++; - } - } - - TBool hidden; - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,hidden); - if(ret!=KErrNone) - { - LOGPARSERR("emails",ret,parseIndex,&KPhBkUSimStoreEntry); - } - else - iPhBkUSimStoreEntries[index].iHiddenEntry=hidden; - - } - - count=CfgFile()->ItemCount(KPhBkError); - item=NULL; - - for(i=0;iItem(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); - //global phonebook error - continue; - } - - if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook - continue; - else if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this phonebook - continue; - - TPhBkError entry; - entry.iCount=count; - entry.iError=error; - TRAP_IGNORE(iPhBkError->AppendL(entry)); - } - PopulateOOBWrite(); - PopulateOOBDelete(); - LOGPHBK1("...Finished reading Phonebook store entries..."); - - if(iPhBkOOBWriteDuration!=-1) - iOOBWriteTimer->Start(iPhBkOOBWriteDuration,this,ETimerIdPhBkUSimStorOOBWrite); - if(iPhBkOOBDeleteDuration!=-1) - iOOBDeleteTimer->Start(iPhBkOOBDeleteDuration,this,ETimerIdPhBkUSimStorOOBDelete); - } - -void CSimPhBkUSimStore::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= , , , , " - */ - { - TInt parseIndex=0; - iPhBkOOBWriteDuration=KErrNotFound; - const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkUSimWrite); - if(!item) - return; - - TInt count; - TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,count); - if(ret!=KErrNone) - { - LOGPARSERR("count",ret,parseIndex,&KOOBPhBkUSimWrite); - return; - } - - TPtrC8 phonebookStore,aid, phonebookName,alphaTag,telNum,alphaTag2,emails, groups, additional; - TInt index; - TUint8 npiTon; - ret=GetPhBkUSimEntry(item,parseIndex,phonebookStore,phonebookName,aid,index,telNum,alphaTag,npiTon,alphaTag2); - if(ret!=KErrNone) - { - LOGPARSERR("Phonebook Entry",ret,parseIndex,&KOOBPhBkUSimWrite); - return; - } - - if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type - return; - else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook - return; - - iPhBkOOBWriteDuration=count; - iPhBkOOBWriteIndex=index; - iPhBkOOBWrite.iAlphaTag.Copy(alphaTag); - iPhBkOOBWrite.iTelNum.Copy(telNum); - iPhBkOOBWrite.iTonNpi=npiTon; - iPhBkOOBWrite.iAlphaTag2.Copy(alphaTag2); - - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,additional); - if(ret!=KErrNone) - { - LOGPARSERR("additional",ret,parseIndex,&KOOBPhBkUSimWrite); - } - else - { - TPtrC8 myName,myNum; - TUint8 myTon; - TInt myindex=0,pIndex=0; - - TRAPD(err,iPhBkOOBWrite.iAdditional=new(ELeave) CArrayFixFlat(iPhBkAdditional+1)); - if (err!=KErrNone) - return; - while((GetPhBkAdditionalEntry(additional,pIndex,myNum,myName,myTon)==KErrNone) - && (myindex < iPhBkAdditional)) - { - TPhBkStoreEntry entry; - - entry.iAlphaTag.Copy(myName); - entry.iTelNum.Copy(myNum); - entry.iTonNpi=myTon; - TRAP_IGNORE(iPhBkOOBWrite.iAdditional->AppendL(entry)); - myindex++; - } - } - - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,groups); - if(ret!=KErrNone) - { - LOGPARSERR("groups",ret,parseIndex,&KOOBPhBkUSimWrite); - } - else - { - TPtrC8 mygroup; - TInt myindex=0; - - TRAPD(err,iPhBkOOBWrite.iGroups=new(ELeave) CArrayFixFlat(KMaxGroups+1)); - if (err!=KErrNone) - return; - while((CTestConfig::GetElement(groups,';',myindex,mygroup)==KErrNone) && - (myindex < KMaxGroups)) - { - TPhBkUSimGroup entry; - entry.Copy(mygroup); - TRAP_IGNORE(iPhBkOOBWrite.iGroups->AppendL(entry)); - myindex++; - } - } - - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,emails); - if(ret!=KErrNone) - { - LOGPARSERR("emails",ret,parseIndex,&KOOBPhBkUSimWrite); - } - else - { - TPtrC8 myemail; - TInt myindex=0; - - TRAPD(err,iPhBkOOBWrite.iEmails=new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1)); - if (err!=KErrNone) - return; - - while((CTestConfig::GetElement(emails,';',myindex,myemail)==KErrNone) && - (myindex < iPhBkMaxEmail)) - { - TPhBkUSimEmail entry; - entry.Copy(myemail); - TRAP_IGNORE(iPhBkOOBWrite.iEmails->AppendL(entry)); - myindex++; - } - } - - } - -void CSimPhBkUSimStore::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= , , - */ - { - iPhBkOOBDeleteDuration=KErrNotFound; - const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkUSimDelete); - if(!item) - return; - - TInt count; - TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count); - if(ret!=KErrNone) - { - LOGPARSERR("count",ret,0,&KOOBPhBkUSimDelete); - return; - } - - TPtrC8 phonebookName, phonebookStore; - - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,phonebookStore); - if(ret!=KErrNone) - { - LOGPARSERR("phonebookStore",ret,1,&KOOBPhBkUSimDelete); - return; - } - - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,phonebookName); - if(ret!=KErrNone) - { - LOGPARSERR("phonebookName",ret,2,&KOOBPhBkUSimDelete); - return; - } - - if(phonebookStore.MatchF(iPhBkStore)!=0) - return; // Not this store - else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook - return; - - TInt index; - ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,index); - if(ret!=KErrNone) - { - LOGPARSERR("index",ret,3,&KOOBPhBkUSimDelete); - return; - } - - iPhBkOOBDeleteDuration=count; - iPhBkOOBDeleteIndex=index; - } - - -TInt CSimPhBkUSimStore::GetPhBkUSimEntry(const CTestConfigItem* aItem, TInt& aItemIndex, - TPtrC8& aPhonebookStore, - TPtrC8& aPhonebookName, - TPtrC8& aAid,TInt& aIndex, - TPtrC8& aTelNum, TPtrC8& aAlphaTag, TUint8& aNpiTon, - TPtrC8& aAlphaTag2) -/** - * 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++,aPhonebookStore); - if(ret!=KErrNone) - return ret; - - ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aPhonebookName); - if(ret!=KErrNone) - return ret; - - ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAid); - 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 EXTENDEDERROR(KErrArgument, KErrPhonebookNumberOverflow); - - ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag); - if(ret!=KErrNone) - return ret; - if(aAlphaTag.Length()>iPhBkMaxTextLen) - return EXTENDEDERROR(KErrArgument, KErrPhonebookTextOverflow); - - if((aTelNum.Length()>0) && (aTelNum[0]=='+')) - { - aTelNum.Set(aTelNum.Mid(1)); - aNpiTon=KNpiTonInternational; - } - else - aNpiTon=KNpiTonNational; - - ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag2); - if(ret!=KErrNone) - return ret; - if(aAlphaTag.Length()>iPhBkMaxTextLen) - return EXTENDEDERROR(KErrArgument, KErrPhonebookTextOverflow); - - return ret; - } - -TInt CSimPhBkUSimStore::GetPhBkAdditionalEntry(TPtrC8& aEntry, TInt& aItemIndex, - 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 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(aEntry,';',aItemIndex++,aAlphaTag); - if(ret!=KErrNone) - return ret; - - if(aAlphaTag.Length()>iPhBkMaxAdditionalTextLen) - return EXTENDEDERROR(KErrArgument, KErrPhonebookAdditionalNumberAlphaTextOverflow); - - ret=CTestConfig::GetElement(aEntry,';',aItemIndex++,aTelNum); - if(ret!=KErrNone) - return ret; - if(aTelNum.Length()>iPhBkMaxAdditionalTelNumLen) - return EXTENDEDERROR(KErrArgument, KErrPhonebookAdditionalNumberNumberOverflow); - - - if((aTelNum.Length()>0) && (aTelNum[0]=='+')) - { - aTelNum.Set(aTelNum.Mid(1)); - aNpiTon=KNpiTonInternational; - } - else - { - aNpiTon=KNpiTonNational; - } - - return ret; - } - -CSimPhBkUSimStore::~CSimPhBkUSimStore() -/** - * Standard destructor. Any objects created by the ::ConstructL() function - * will be destroyed here. - */ - { - - for(TInt i=1;i<=iPhBkMaxNumSlots;i++) - { - if(iPhBkUSim1StoreEntries[i].iTelNum.Length()>0 || - iPhBkUSim1StoreEntries[i].iAlphaTag.Length()>0) - { - iPhBkUSim1StoreEntries[i].iTelNum.Zero(); - if((iPhBkUSim1StoreEntries[i].iAdditional!=NULL) - && ((TUint)iPhBkUSim1StoreEntries[i].iAdditional!=DELETED)) - { - if(iPhBkUSim1StoreEntries[i].iAdditional->Count()>=0) - { - iPhBkUSim1StoreEntries[i].iAdditional->Delete(0,iPhBkUSim1StoreEntries[i].iAdditional->Count()); - delete iPhBkUSim1StoreEntries[i].iAdditional; - } - } - if((iPhBkUSim1StoreEntries[i].iGroups!=NULL) - && ((TUint)iPhBkUSim1StoreEntries[i].iGroups!=DELETED)) - { - if(iPhBkUSim1StoreEntries[i].iGroups->Count()>=0) - { - iPhBkUSim1StoreEntries[i].iGroups->Delete(0,iPhBkUSim1StoreEntries[i].iGroups->Count()); - delete iPhBkUSim1StoreEntries[i].iGroups; - } - } - if((iPhBkUSim1StoreEntries[i].iEmails!=NULL) - && ((TUint)iPhBkUSim1StoreEntries[i].iEmails!=DELETED)) - { - if(iPhBkUSim1StoreEntries[i].iEmails->Count()>=0) - { - iPhBkUSim1StoreEntries[i].iEmails->Delete(0,iPhBkUSim1StoreEntries[i].iEmails->Count()); - delete iPhBkUSim1StoreEntries[i].iEmails; - } - } - } - if(iPhBkUSim2StoreEntries!=NULL && - (iPhBkUSim2StoreEntries[i].iTelNum.Length()>0 || - iPhBkUSim2StoreEntries[i].iAlphaTag.Length()>0)) - { - iPhBkUSim2StoreEntries[i].iTelNum.Zero(); - if((iPhBkUSim2StoreEntries[i].iAdditional!=NULL) - && ((TUint)iPhBkUSim2StoreEntries[i].iAdditional!=DELETED)) - { - if(iPhBkUSim2StoreEntries[i].iAdditional->Count()>=0) - { - iPhBkUSim2StoreEntries[i].iAdditional->Delete(0,iPhBkUSim2StoreEntries[i].iAdditional->Count()); - delete iPhBkUSim2StoreEntries[i].iAdditional; - } - } - if((iPhBkUSim2StoreEntries[i].iGroups!=NULL) - && ((TUint)iPhBkUSim2StoreEntries[i].iGroups!=DELETED)) - { - if(iPhBkUSim2StoreEntries[i].iGroups->Count()>=0) - { - iPhBkUSim2StoreEntries[i].iGroups->Delete(0,iPhBkUSim2StoreEntries[i].iGroups->Count()); - delete iPhBkUSim2StoreEntries[i].iGroups; - } - } - if((iPhBkUSim2StoreEntries[i].iEmails!=NULL) - && ((TUint)iPhBkUSim2StoreEntries[i].iEmails!=DELETED)) - { - if(iPhBkUSim2StoreEntries[i].iEmails->Count()>=0) - { - iPhBkUSim2StoreEntries[i].iEmails->Delete(0,iPhBkUSim2StoreEntries[i].iEmails->Count()); - delete iPhBkUSim2StoreEntries[i].iEmails; - } - } - } - } - - if((iPhBkOOBWrite.iAdditional!=NULL) - && ((TUint)iPhBkOOBWrite.iAdditional!=DELETED)) - { - iPhBkOOBWrite.iAdditional->Delete(0,iPhBkOOBWrite.iAdditional->Count()); - delete iPhBkOOBWrite.iAdditional; - } - if((iPhBkOOBWrite.iGroups!=NULL) - && ((TUint)iPhBkOOBWrite.iGroups!=DELETED)) - { - iPhBkOOBWrite.iGroups->Delete(0,iPhBkOOBWrite.iGroups->Count()); - delete iPhBkOOBWrite.iGroups; - } - if((iPhBkOOBWrite.iEmails!=NULL) - && ((TUint)iPhBkOOBWrite.iEmails!=DELETED)) - { - iPhBkOOBWrite.iEmails->Delete(0,iPhBkOOBWrite.iEmails->Count()); - delete iPhBkOOBWrite.iEmails; - } - delete[] iPhBkUSim1StoreEntries; - delete[] iPhBkUSim2StoreEntries; - delete iPhBkError; - delete iPhBkRwBuffer; - delete iOOBWriteTimer; - delete iOOBDeleteTimer; - delete iReqTimer; - - } - -TInt CSimPhBkUSimStore::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* CSimPhBkUSimStore::OpenNewObjectByNameL(const TDesC& /*aName*/) -/** - * The API does not support any objects that could be opened from this one. - */ - { - User::Leave(KErrNotSupported); - return NULL; - } - -CTelObject* CSimPhBkUSimStore::OpenNewObjectL(TDes&) -/** - * The API does not support any objects that could be opened from this one. - */ - { - User::Leave(KErrNotSupported); - return NULL; - } - -CTelObject::TReqMode CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::Init() -/** - * This function can be used to perform any necessary synchronous initialisation. - */ - { - } - -TInt CSimPhBkUSimStore::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; - } - - if(CheckAndSwitchUSimApps()!=KErrNone) - { - ReqCompleted(aReqHandle, KErrNotFound); - return KErrNone; - } - - RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg* getInfoPckg=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg*)aPckg; - RMobilePhoneBookStore::TMobilePhoneBookInfoV1& getInfo=(*getInfoPckg)(); - - PopulatePhBkStoreInfo(&getInfo); - - if(&getInfo!=NULL) // NULL will have been assigned by PopulatePhBkStoreInfo if the version checking failed. - { - ReqCompleted(aReqHandle,KErrNone); - } - else - { - ReqCompleted(aReqHandle,KErrNotSupported); - } - - return KErrNone; - } - -void CSimPhBkUSimStore::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.Zero(); - - getExtraInfo->iPhBkMode.Copy(PhBkStore()); - - if(PhBkStore().Compare(KUSimPhoneBook)!=KErrNone) - { - getExtraInfo->iIdentity.Copy(iPhone->GetImsi()); - } - else - { - TPtrC8 USimId(iPhone->GetActiveUSim().Right(1)); - getExtraInfo->iIdentity.Copy(USimId); - getExtraInfo->iIdentity.Append(iPhone->GetImsi()); - } - } - 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.Zero(); - - getExtraInfo->iPhBkMode.Copy(PhBkStore()); - - getExtraInfo->iMaxSecondNames = KMaxSecondNames; - getExtraInfo->iMaxTextLengthSecondName = iPhBkMaxTextLen; - getExtraInfo->iMaxAdditionalNumbers = iPhBkAdditional; - getExtraInfo->iMaxTextLengthAdditionalNumber = iPhBkMaxAdditionalTextLen; - getExtraInfo->iMaxNumLengthAdditionalNumber = iPhBkMaxAdditionalTelNumLen; - getExtraInfo->iMaxGroupNames = KMaxGroups; - getExtraInfo->iMaxTextLengthGroupName = iPhBkMaxTextLen; - getExtraInfo->iMaxEmailAddr = iPhBkMaxEmail; - getExtraInfo->iMaxTextLengthEmailAddr = iPhBkMaxTextLen; - - if(PhBkStore().Compare(KUSimPhoneBook)!=KErrNone) - { - getExtraInfo->iIdentity.Copy(iPhone->GetImsi()); - } - else - { - TPtrC8 USimId(iPhone->GetActiveUSim().Right(1)); - getExtraInfo->iIdentity.Copy(USimId); - getExtraInfo->iIdentity.Append(iPhone->GetImsi()); - } - } - } - -TInt CSimPhBkUSimStore::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(CheckAndSwitchUSimApps()!=KErrNone) - { - ReqCompleted(aReqHandle, KErrNotFound); - return KErrNone; - } - - if(iPhone->IsICCLocked()!=EFalse) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - TPckg* indexNumPckg=(TPckg*)aPckg1; - RMobilePhoneBookStore::TPBIndexAndNumEntries& indexNum=(*indexNumPckg)(); - - if(indexNum.iNumSlots==iPhBkMaxNumSlots) - { - if (!(iPhBkStoreCaps & static_cast(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; - TBool onlyHidden=EFalse; - - for(TInt i=indexNum.iIndex;i<=iPhBkMaxNumSlots;i++) - { - if((iPhBkUSimStoreEntries[i].iTelNum.Length()!=0)||(iPhBkUSimStoreEntries[i].iAlphaTag.Length()!=0)) - { - ret=iPhBkRwBuffer->AddNewEntryTag(); - if(ret!=KErrNone) - break; - - if((iPhone->IsHiddenEnabled()!=EFalse) && - iPhBkUSimStoreEntries[i].iHiddenEntry==1) - { - //This is a hidden entry, the key is required and is currently locked - //Therefore, the client should be notified that the slot has been occupied by a hidden entry - - partial=ETrue; - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i); - if(ret!=KErrNone) - break; - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBHiddenInfo,(TUint8) iPhBkUSimStoreEntries[i].iHiddenEntry); - if(ret!=KErrNone) - break; - partial=EFalse; - onlyHidden=ETrue; - break; - } - - partial=ETrue; - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i); - if(ret!=KErrNone) - break; - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,iPhBkUSimStoreEntries[i].iAlphaTag); - if(ret!=KErrNone) - break; - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,iPhBkUSimStoreEntries[i].iTonNpi); - if(ret!=KErrNone) - break; - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,iPhBkUSimStoreEntries[i].iTelNum); - if(ret!=KErrNone) - break; - - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBSecondName,iPhBkUSimStoreEntries[i].iAlphaTag2); - if(ret!=KErrNone) - break; - - TInt EmailCount = iPhBkUSimStoreEntries[i].iEmails->Count(); - TInt GroupCount = iPhBkUSimStoreEntries[i].iGroups->Count(); - TInt AnrCount = iPhBkUSimStoreEntries[i].iAdditional->Count(); - TInt j; - - TBool corrupt=EFalse; - - for(j=0; jAt(j); - - corrupt=ETrue; - - ret=iPhBkRwBuffer->AddNewNumberTag(); - if(ret!=KErrNone) - break; - - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,entry.iAlphaTag); - if(ret!=KErrNone) - break; - - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,entry.iTelNum); - if(ret!=KErrNone) - break; - - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,entry.iTonNpi); - if(ret!=KErrNone) - break; - - corrupt=EFalse; - } - if(corrupt) - break; - - for(j=0; jAt(j); - - corrupt=ETrue; - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBEmailAddress,entry); - if(ret!=KErrNone) - break; - corrupt=EFalse; - } - if(corrupt) - break; - - for(j=0; jAt(j); - - corrupt=ETrue; - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBGroupName,entry); - if(ret!=KErrNone) - break; - corrupt=EFalse; - } - if(corrupt) - break; - - ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBHiddenInfo,(TUint8) iPhBkUSimStoreEntries[i].iHiddenEntry); - if(ret!=KErrNone) - break; - - partial=EFalse; - onlyHidden=ETrue; - 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)&&(!onlyHidden)) - ReqCompleted(aReqHandle,KErrNotFound); // No entries found. - else if((cnt==0)&&(!partial)&&(onlyHidden)) - ReqCompleted(aReqHandle,KErrAccessDenied); - else - ReqCompleted(aReqHandle,KErrNone); - - return KErrNone; - } - -TInt CSimPhBkUSimStore::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(CheckAndSwitchUSimApps()!=KErrNone) - { - ReqCompleted(aReqHandle, KErrNotFound); - return KErrNone; - } - - if(iPhone->IsICCLocked()!=EFalse) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess)) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - TPckg* indexPckg=(TPckg*)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((iPhBkUSimStoreEntries[i].iTelNum.Length()==0)&&(iPhBkUSimStoreEntries[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(iPhBkUSimStoreEntries[index].iTelNum.Length()!=0) - { - if((iPhone->IsHiddenEnabled()!=EFalse) && - iPhBkUSimStoreEntries[index].iHiddenEntry==1) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - isSlotAlreadyUsed=ETrue; - TInt idx,count; - - count=iPhBkUSimStoreEntries[index].iAdditional->Count(); - for(idx=0;idxAt(idx); - entry.iTelNum.Zero(); - entry.iAlphaTag.Zero(); - entry.iTonNpi=0; - } - iPhBkUSimStoreEntries[index].iAdditional->Delete(0,count); - delete iPhBkUSimStoreEntries[index].iAdditional; - count=iPhBkUSimStoreEntries[index].iGroups->Count(); - iPhBkUSimStoreEntries[index].iGroups->Delete(0,count); - delete iPhBkUSimStoreEntries[index].iGroups; - count=iPhBkUSimStoreEntries[index].iEmails->Count(); - iPhBkUSimStoreEntries[index].iEmails->Delete(0,count); - delete iPhBkUSimStoreEntries[index].iEmails; - - TRAPD(err,iPhBkUSimStoreEntries[index].iAdditional= - new(ELeave) CArrayFixFlat(iPhBkAdditional+1)); - if (err!=KErrNone) - return (err); - - TRAP(err,iPhBkUSimStoreEntries[index].iGroups= - new(ELeave) CArrayFixFlat(KMaxGroups)); - if (err!=KErrNone) - return (err); - - TRAP(err,iPhBkUSimStoreEntries[index].iEmails= - new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1)); - if (err!=KErrNone) - return (err); - } - else - { - TRAPD(err,iPhBkUSimStoreEntries[index].iAdditional= - new(ELeave) CArrayFixFlat(iPhBkAdditional+1)); - if (err!=KErrNone) - return (err); - - TRAP(err,iPhBkUSimStoreEntries[index].iGroups= - new(ELeave) CArrayFixFlat(KMaxGroups)); - if (err!=KErrNone) - return (err); - - TRAP(err,iPhBkUSimStoreEntries[index].iEmails= - new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1)); - if (err!=KErrNone) - return (err); - } -// Unpick the phonebook entry. - iPhBkRwBuffer->Set(aPckg1); - iPhBkRwBuffer->StartRead(); - - TUint8 tagVal; - TUint8 npiTon=0; - TUint8 hidden; - TPtrC alphaTag,alphaTag2; - TPtrC telNum; - TPtrC bufPtr; - TBool additional=EFalse; - TInt additionalCount=0; - - CPhoneBookBuffer::TPhBkTagType tagType; - TInt ret=KErrNone; - - TPhBkStoreEntry additionalEntry; - - while(ret==KErrNone) - { - ret=iPhBkRwBuffer->GetTagAndType(tagVal,tagType); - if(ret==KErrNotFound) - { - ret=KErrNone; - break; - } - else if(ret!=KErrNone) - break; - switch(tagVal) - { - case RMobilePhoneBookStore::ETagPBNewEntry: - break; - - case RMobilePhoneBookStore::ETagPBText: - ret=iPhBkRwBuffer->GetValue(alphaTag); - - LOGPHBK2("alphaTag (ETagPBText) Length = (%d)",alphaTag.Length()); - LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen); - - if(!additional && ret==KErrNone && (alphaTag.Length()<=iPhBkMaxTextLen)) - iPhBkUSimStoreEntries[index].iAlphaTag.Copy(alphaTag); - else if(additional && ret==KErrNone && (alphaTag.Length()<=iPhBkMaxAdditionalTextLen) - && (additionalCountGetValue(alphaTag2); - - LOGPHBK2("alphaTag2 (ETagPBSecondName) Length = (%d)",alphaTag2.Length()); - LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen); - - if(ret==KErrNone && (alphaTag2.Length()<=iPhBkMaxTextLen)) - iPhBkUSimStoreEntries[index].iAlphaTag2.Copy(alphaTag2); - else - ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookSecondNameTextOverflow); - break; - - case RMobilePhoneBookStore::ETagPBNumber: - ret=iPhBkRwBuffer->GetValue(telNum); - - LOGPHBK2("telNum (ETagPBNumber) Length = (%d)",telNum.Length()); - LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTelNumLen); - - if(!additional && ret==KErrNone && (telNum.Length()<=iPhBkMaxTelNumLen)) - iPhBkUSimStoreEntries[index].iTelNum.Copy(telNum); - else if(additional && ret==KErrNone && (telNum.Length()<=iPhBkMaxAdditionalTelNumLen) - && (additionalCountGetValue(npiTon); - if(!additional && ret==KErrNone) - iPhBkUSimStoreEntries[index].iTonNpi=npiTon; - else if (additional && ret==KErrNone) - { - additionalEntry.iTonNpi=npiTon; - TRAP_IGNORE(iPhBkUSimStoreEntries[index].iAdditional->AppendL(additionalEntry)); - additional=EFalse; - additionalCount++; - additionalEntry.iAlphaTag.Zero(); - additionalEntry.iTelNum.Zero(); - additionalEntry.iTonNpi=0; - } - break; - - case RMobilePhoneBookStore::ETagPBAnrStart: - if(!additional) - additional=ETrue; - else - ret=KErrArgument; - break; - - case RMobilePhoneBookStore::ETagPBGroupName: - ret=iPhBkRwBuffer->GetValue(bufPtr); - - LOGPHBK2("bufPtr (ETagPBGroupName) Length = (%d)",bufPtr.Length()); - LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen); - - if(ret==KErrNone && (bufPtr.Length()<=iPhBkMaxTextLen) - && (iPhBkUSimStoreEntries[index].iGroups->Count() < KMaxGroups)) - { - TRAP_IGNORE(iPhBkUSimStoreEntries[index].iGroups->AppendL(bufPtr)); - } - else - ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookGroupAlphaTextOverflow); - break; - - case RMobilePhoneBookStore::ETagPBEmailAddress: - ret=iPhBkRwBuffer->GetValue(bufPtr); - - LOGPHBK2("bufPtr (ETagPBEmailAddress) Length = (%d)",bufPtr.Length()); - LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen); - - if(ret==KErrNone && (bufPtr.Length()<=iPhBkMaxTextLen) - && (iPhBkUSimStoreEntries[index].iEmails->Count() < iPhBkMaxEmail)) - { - TRAP_IGNORE(iPhBkUSimStoreEntries[index].iEmails->AppendL(bufPtr)); - } - else - ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookEmailTextOverflow); - break; - - case RMobilePhoneBookStore::ETagPBHiddenInfo: - ret=iPhBkRwBuffer->GetValue(hidden); - if(ret==KErrNone) - iPhBkUSimStoreEntries[index].iHiddenEntry=hidden; - break; - - default: - ret=KErrNotSupported; - } - } - - if(ret!=KErrNone) - { - //Cleanup! - iPhBkUSimStoreEntries[index].iTelNum.Zero(); - iPhBkUSimStoreEntries[index].iAlphaTag.Zero(); - iPhBkUSimStoreEntries[index].iAlphaTag2.Zero(); - iPhBkUSimStoreEntries[index].iHiddenEntry=0; - iPhBkUSimStoreEntries[index].iTonNpi=npiTon; - - if(iPhBkUSimStoreEntries[index].iGroups!=NULL) - { - iPhBkUSimStoreEntries[index].iGroups->Delete(0,iPhBkUSimStoreEntries[index].iGroups->Count()); - delete iPhBkUSimStoreEntries[index].iGroups; - } - if(iPhBkUSimStoreEntries[index].iEmails!=NULL) - { - iPhBkUSimStoreEntries[index].iEmails->Delete(0,iPhBkUSimStoreEntries[index].iEmails->Count()); - delete iPhBkUSimStoreEntries[index].iEmails; - } - if(iPhBkUSimStoreEntries[index].iAdditional!=NULL) - { - iPhBkUSimStoreEntries[index].iAdditional->Delete(0,iPhBkUSimStoreEntries[index].iAdditional->Count()); - delete iPhBkUSimStoreEntries[index].iAdditional; - } - ReqCompleted(aReqHandle,ret); - return KErrNone; - } - -// if(alphaTag.Length()>iPhBkMaxTextLen) -// { -// ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookTextOverflow)); -// return KErrNone; -// } -// else if(telNum.Length()>iPhBkMaxTelNumLen) -// { -// ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookNumberOverflow)); -// return KErrNone; -// } - - if(isSlotAlreadyUsed) - DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventChanged,index); - else - DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventAdded,index); - return KErrNone; - } - -TInt CSimPhBkUSimStore::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(CheckAndSwitchUSimApps()!=KErrNone) - { - ReqCompleted(aReqHandle, KErrNotFound); - return KErrNone; - } - - if(iPhone->IsICCLocked()!=EFalse) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess)) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - - TPckg* intPckg=(TPckg*)aPckg; - TInt& index=(*intPckg)(); - - if((index<1)||(index>iPhBkMaxNumSlots)) - { - ReqCompleted(aReqHandle,KErrArgument); - return KErrNone; - } - - if((iPhone->IsHiddenEnabled()!=EFalse) && - iPhBkUSimStoreEntries[index].iHiddenEntry==1) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - iPhBkUSimStoreEntries[index].iTelNum.Zero(); - iPhBkUSimStoreEntries[index].iAlphaTag.Zero(); - iPhBkUSimStoreEntries[index].iAlphaTag2.Zero(); - - if((iPhBkUSimStoreEntries[index].iGroups!=NULL) && - ((TUint)iPhBkUSimStoreEntries[index].iGroups!=DELETED)) - { - iPhBkUSimStoreEntries[index].iGroups->Delete(0, - iPhBkUSimStoreEntries[index].iGroups->Count()); - delete iPhBkUSimStoreEntries[index].iGroups; - } - if((iPhBkUSimStoreEntries[index].iEmails!=NULL) && - ((TUint)iPhBkUSimStoreEntries[index].iEmails!=DELETED)) - { - iPhBkUSimStoreEntries[index].iEmails->Delete(0, - iPhBkUSimStoreEntries[index].iEmails->Count()); - delete iPhBkUSimStoreEntries[index].iEmails; - } - - if((iPhBkUSimStoreEntries[index].iAdditional!=NULL) && - ((TUint)iPhBkUSimStoreEntries[index].iAdditional!=DELETED)) - { - TInt count = iPhBkUSimStoreEntries[index].iAdditional->Count(); - for(TInt i=0;iAt(i); - entry.iTelNum.Zero(); - entry.iAlphaTag.Zero(); - entry.iTonNpi=0; - } - - iPhBkUSimStoreEntries[index].iAdditional->Delete(0,count); - delete iPhBkUSimStoreEntries[index].iAdditional; - } - - DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventDeleted,index); - return KErrNone; - } - -TInt CSimPhBkUSimStore::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(CheckAndSwitchUSimApps()!=KErrNone) - { - ReqCompleted(aReqHandle, KErrNotFound); - return KErrNone; - } - - if(iPhone->IsICCLocked()!=EFalse) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - if (!(iPhBkStoreCaps & static_cast(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess)) - { - ReqCompleted(aReqHandle, KErrAccessDenied); - return KErrNone; - } - - for(TInt i=1;i<=iPhBkMaxNumSlots;i++) - { - TBool entryUsed =EFalse; - - if((iPhone->IsHiddenEnabled()!=EFalse) && - iPhBkUSimStoreEntries[i].iHiddenEntry==1) - { - //Skip me because I am a hidden entry! - //The hidden key has to be verified to delete me! - continue; - } - if(iPhBkUSimStoreEntries[i].iTelNum.Length()>0) - entryUsed = ETrue; - - iPhBkUSimStoreEntries[i].iTelNum.Zero(); - iPhBkUSimStoreEntries[i].iAlphaTag.Zero(); - iPhBkUSimStoreEntries[i].iAlphaTag2.Zero(); - - if(entryUsed) - { - if((iPhBkUSimStoreEntries[i].iGroups!=NULL) && - ((TUint)iPhBkUSimStoreEntries[i].iGroups!=DELETED)) - { - iPhBkUSimStoreEntries[i].iGroups->Delete(0, - iPhBkUSimStoreEntries[i].iGroups->Count()); - delete iPhBkUSimStoreEntries[i].iGroups; - } - if((iPhBkUSimStoreEntries[i].iEmails!=NULL) && - ((TUint)iPhBkUSimStoreEntries[i].iEmails!=DELETED)) - { - iPhBkUSimStoreEntries[i].iEmails->Delete(0, - iPhBkUSimStoreEntries[i].iEmails->Count()); - delete iPhBkUSimStoreEntries[i].iEmails; - } - if((iPhBkUSimStoreEntries[i].iAdditional!=NULL) && - ((TUint)iPhBkUSimStoreEntries[i].iAdditional!=DELETED)) - { - TInt count = iPhBkUSimStoreEntries[i].iAdditional->Count(); - for(TInt index=0;indexAt(index); - entry.iTelNum.Zero(); - entry.iAlphaTag.Zero(); - entry.iTonNpi=0; - } - - iPhBkUSimStoreEntries[i].iAdditional->Delete(0,count); - delete iPhBkUSimStoreEntries[i].iAdditional; - } - } - } - DelayCompletion(iPhBkBatchPause,aReqHandle,EStoreEventDeleted,-1); - return KErrNone; - } - -TInt CSimPhBkUSimStore::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* eventPckg=(TPckg*)aPckg1; - TUint32& event=(*eventPckg)(); - TPckg* indexPckg=(TPckg*)aPckg2; - TInt& index=(*indexPckg)(); - - iEvOutstandingReq=ETrue; - iEvReqHandle=aReqHandle; - iEvEvent=&event; - iEvIndex=&index; - return KErrNone; - } - -void CSimPhBkUSimStore::NotifyStoreEventCancel() -/** - * Cancel an outstanding notify store request. - */ - { - if(iEvOutstandingReq) - { - iEvOutstandingReq=EFalse; - ReqCompleted(iEvReqHandle,KErrCancel); - } - } - -TPtrC8 CSimPhBkUSimStore::Name() -/** - * Accessor function fot the Phonebook Store name. - * - * @return TPtrC8 The name of this Phonebook Store. - */ - { - return iPhBkStoreName; - } - -TPtrC8 CSimPhBkUSimStore::PhBkStore() -/** - * Accessor function fot the Phonebook Store name. - * - * @return TPtrC8 The name of this Phonebook Store. - */ - { - return iPhBkStore; - } - -TPtrC8 CSimPhBkUSimStore::AID() -/** - * Accessor function fot the Phonebook Store name. - * - * @return TPtrC8 The name of this Phonebook Store. - */ - { - return iPhBkAid; - } - -TInt CSimPhBkUSimStore::UsedEntries() -/** - * Count the number of used entries in the Phonebook Store. - * @return TInt The number of used entries in the store. - */ - { - TInt cnt=0; - if(CheckAndSwitchUSimApps()!=KErrNone) - return KErrNotFound; - for(TInt i=1;i<=iPhBkMaxNumSlots;i++) - { - if((iPhBkUSimStoreEntries[i].iTelNum.Length()!=0)||(iPhBkUSimStoreEntries[i].iAlphaTag.Length()!=0)) - cnt++; - } - return cnt; - } - -TInt CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::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,ETimerIdPhBkUSimStorReq); - } - -void CSimPhBkUSimStore::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. - */ - { - TInt idx=0,count; - TBool isSlotAlreadyUsed=EFalse; - - switch(aId) - { - case ETimerIdPhBkUSimStorReq: - StoreEvent(iPendingEvent,iPendingIndex); - ReqCompleted(iPendingReqCompletion,KErrNone); - break; - - case ETimerIdPhBkUSimStorOOBWrite: - - if(CheckAndSwitchUSimApps()!=KErrNone) - if(iEvOutstandingReq) - { - ReqCompleted(iEvReqHandle,KErrNotFound); - return; - } - else - { - return; - } - - if(iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTelNum.Length()!=0) - isSlotAlreadyUsed=ETrue; - - iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAlphaTag.Copy(iPhBkOOBWrite.iAlphaTag); - iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTelNum.Copy(iPhBkOOBWrite.iTelNum); - iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTonNpi=iPhBkOOBWrite.iTonNpi; - iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAlphaTag2.Copy(iPhBkOOBWrite.iAlphaTag2); - - if(isSlotAlreadyUsed) - { - if((count=iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->Count())>0) - { - for(idx=0;idxAt(idx); - entry.iTelNum.Zero(); - entry.iAlphaTag.Zero(); - entry.iTonNpi=0; - } - iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->Delete(0,count); - delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional; - } - - if((count = iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups->Count())>0) - { - iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups->Delete(0,count); - delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups; - } - if((count = iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails->Count())>0) - { - iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails->Delete(0,count); - delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails; - } - } - - count = iPhBkOOBWrite.iAdditional->Count(); - - //sometimes because of a kernel bug on wins, iAdditional pointer gets filled up with - //bad address 0xdededede (investigating) - - TRAPD(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional=new(ELeave) CArrayFixFlat(iPhBkAdditional+1)); - if (err!=KErrNone) - { - LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure"); - return; - } - - for(idx=0;idxAt(idx); - TRAP_IGNORE(iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->AppendL(entry)); - } - - - TRAP(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups=new(ELeave) CArrayFixFlat(KMaxGroups)); - if (err!=KErrNone) - { - LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure"); - return; - } - - for(idx=0;idxAppendL(entry)); - } - - count = iPhBkOOBWrite.iEmails->Count(); - TRAP(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails=new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1)); - if (err!=KErrNone) - { - LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure"); - return; - } - - for(idx=0;idxAppendL(entry)); - } - - iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iHiddenEntry=iPhBkOOBWrite.iHiddenEntry; - - StoreEvent(EStoreEventAdded,iPhBkOOBWriteIndex); - break; - - case ETimerIdPhBkUSimStorOOBDelete: - - if(CheckAndSwitchUSimApps()!=KErrNone) - if(iEvOutstandingReq) - { - ReqCompleted(iEvReqHandle,KErrNotFound); - return; - } - else - { - return; - } - - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag.Zero(); - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iTelNum.Zero(); - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iTonNpi=0; - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag2.Zero(); - - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups->Delete(0, - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups->Count()); - delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups; - - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails->Delete(0, - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails->Count()); - delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails; - - count = iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional->Count(); - for(idx=0;idxAt(idx); - entry.iTelNum.Zero(); - entry.iAlphaTag.Zero(); - entry.iTonNpi=0; - } - - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional->Delete(0,count); - delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional; - iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iHiddenEntry=0; - - StoreEvent(EStoreEventDeleted,iPhBkOOBDeleteIndex); - break; - - default: - break; - } - } - -void CSimPhBkUSimStore::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 CSimPhBkUSimStore::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;iCount();i++) - { - if(iPhBkError->At(i).iCount==iIpcCnt) - { - aError=iPhBkError->At(i).iError; - return ETrue; - } - } - return EFalse; - } - - -/** - * Check that the USIM App phonebook in use is the same as the current - * USIM App, and if not then swap the phonebook over. - */ -TInt CSimPhBkUSimStore::CheckAndSwitchUSimApps() - { - TInt ret=KErrNone; - - if(iPhBkStore.Compare(KUSimPhoneBook)==KErrNone) - { - if(iPhone->GetActiveUSim().Compare(iPhBkAid)==KErrNone) - { - // - // The active USIM App is the same as last time, but ensure that - // we are using the right phonebook anyway. - // - if(iPhBkAid.Compare(iPhBkAidUSim2)==KErrNone) - { - iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries; - } - else if(iPhBkAid.Compare(iPhBkAidUSim1)==KErrNone) - { - iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries; - } - else - { - //messed up - return KErrUnknown; - } - } - else if((iPhone->GetActiveUSim().Compare(iPhBkAid)!=KErrNone) && - (iPhone->GetActiveUSim().Compare(iPhBkAidUSim2)==KErrNone)) - { - // - // The active USIM App is not the same as last time and it appears - // to be USIM App 2, so use USIM phonebook number 2. - // - iPhBkAid.Copy(iPhBkAidUSim2); - iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries; - } - else if((iPhone->GetActiveUSim().Compare(iPhBkAid)!=KErrNone) && - (iPhone->GetActiveUSim().Compare(iPhBkAidUSim1)==KErrNone)) - { - // - // The active USIM App is not the same as last time and it appears - // to be USIM App 1, so use USIM phonebook number 1. - // - iPhBkAid.Copy(iPhBkAidUSim1); - iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries; - } - else - { - //Unknown active application!! - ret=KErrNotFound; - } - } - return ret; -} - -const CTestConfigSection* CSimPhBkUSimStore::CfgFile() -/** -* Returns a pointer to the config file section -* -* @return CTestConfigSection a pointer to the configuration file data section -*/ - { - LOGPHBK1(">>CSimPhBkUSimStore::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 "CSimPhBkUsimStore.h" +#include "CSimPhone.h" +#include "Simlog.h" +#include + +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 KMaxGroups = 10; // < The maximum allowed number of groups associated with a phonebook entry +const TInt KMaxSecondNames = 1; // < The maximum allowed number of Second Names associated with a phonebook entry +const TInt KPhonebookErrorGranularity=3; // < Granularity of phonebook error list array. +const TUint DELETED=0xdededede; +// +// CSimPhBkUSimStore +// +void CSimPhBkUSimStore::ClosePhone(TAny* aObj) +/** + * A utility function for cleaning up the stack. + */ + { + ((CObject*)aObj)->Close(); + } + +CSimPhBkUSimStore* CSimPhBkUSimStore::NewL(CSimPhone* aPhone, const TDesC8& aStore, const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen, TInt aAdditional, TInt aMaxEmail, TInt aMaxAdditionalTelNumLen, TInt aMaxAdditionalTextLen) +/** + * 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. + * @param aMaxNumLen The maximum length of the telephone number (<100) + * @param aMaxTextLen The maximum length of the alpha text strings (<100) + * @param aAdditional The maximum number of additional numbers associated with an entry + * @param aMaxEmail The maximum number of email addresses associated with an entry + * @param aMaxAdditionalTelNumLen The maximum length of the an additional telephone number. + * @param aMaxAdditionalTextLen The maximum length of the alpha tag in an additional telephone number. + * @return CSimPhBkUSimStore* The newly created object. + */ + { + CSimPhBkUSimStore* store=new(ELeave) CSimPhBkUSimStore(aPhone); + TCleanupItem newObjClose(ClosePhone,store); + CleanupStack::PushL(newObjClose); + store->ConstructL(aStore,aName,aMaxNumSlots,aMaxNumLen,aMaxTextLen,aAdditional,aMaxEmail, aMaxAdditionalTelNumLen, aMaxAdditionalTextLen); + CleanupStack::Pop(); + return store; + } + +CSimPhBkUSimStore::CSimPhBkUSimStore(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 CSimPhBkUSimStore::ConstructL(const TDesC8& aStore, const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen, TInt aAdditional, TInt aMaxEmail, TInt aMaxAdditionalTelNumLen, TInt aMaxAdditionalTextLen) +/** + * 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. + * @param aMaxNumLen The maximum length of the telephone number (<100). + * @param aMaxTextLen The maximum length of the alpha text strings (<100). + * @param aAdditional The maximum number of additional numbers associated with an entry. + * @param aMaxEmail The maximum number of email addresses associated with an entry. + * @param aMaxAdditionalTelNumLen The maximum length of the an additional telephone number. + * @param aMaxAdditionalTextLen The maximum length of the alpha tag in an additional telephone number. + */ + { + LOGPHBK1("Starting to parse Phonebook store additional config parameters..."); + __ASSERT_ALWAYS(aMaxNumLen<=KPhBkMaxTelNumSize,SimPanic(EPhonebookNameOrNumberTooLarge)); + __ASSERT_ALWAYS(aMaxTextLen<=KPhBkMaxAlphaTagSize,SimPanic(EPhonebookNameOrNumberTooLarge)); + + iPhBkMaxNumSlots=aMaxNumSlots; + iPhBkMaxTelNumLen=aMaxNumLen; + iPhBkMaxTextLen=aMaxTextLen; + iPhBkStoreName.Copy(aName); + iPhBkStore.Copy(aStore); + iPhBkAdditional=aAdditional; + iPhBkMaxEmail=aMaxEmail; + iPhBkMaxAdditionalTelNumLen = aMaxAdditionalTelNumLen; + iPhBkMaxAdditionalTextLen = aMaxAdditionalTextLen; + + iPhBkAid.Zero(); + iPhBkAidUSim1.Zero(); + iPhBkAidUSim2.Zero(); + + if(iPhBkStore.Compare(KUSimPhoneBook)==KErrNone) + { + iPhBkUSim1StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused + iPhBkUSim2StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused + } + else + { + iPhBkUSim1StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused + iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries; + } + + iReqTimer=CSimTimer::NewL(iPhone); + iOOBWriteTimer=CSimTimer::NewL(iPhone); + iOOBDeleteTimer=CSimTimer::NewL(iPhone); + iPhBkRwBuffer=new(ELeave) CPhoneBookBuffer(); + iPhBkError=new(ELeave) CArrayFixFlat(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; + TInt count=CfgFile()->ItemCount(KPhBkPhoneUSimStoreCaps); + + if(count==0) + iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; + else + { + TBool capsFound=EFalse; + for(TInt i=0;(iItem(KPhBkPhoneUSimStoreCaps,i); + + if (item0) + { + TPtrC8 value0,phonebookStore, phonebookName; + TInt ret0; + + ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,0,phonebookStore); + if(ret0!=KErrNone) + { + iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; + LOGPARSERR("Caps:PhonebookStore",ret,0,&KPhBkPhoneUSimStoreCaps); + } + + if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type + continue; + + ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,1,phonebookName); + if(ret0!=KErrNone) + { + iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; + LOGPARSERR("phonebookName",ret,1,&KPhBkPhoneUSimStoreCaps); + } + + if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this PhBkStoreName type + continue; + + ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,2,value0); + if(ret0!=KErrNone) + { + iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; + LOGPARSERR("caps",ret,2,&KPhBkPhoneUSimStoreCaps); + } + else + { + TUint32 intValue; + TInt ret = AsciiToNum(value0, intValue); + if(ret!=KErrNone) + iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps; + else + { + iPhBkStoreCaps = intValue; + capsFound=ETrue; + } + } + + } + } + } + LOGPHBK1("...Finished parsing Phonebook store additional config parameters..."); + } + +void CSimPhBkUSimStore::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. +//alex + * + * The store entries comply to the following format: + * "PhBkStoreEntry = , , , " + */ + { + LOGPHBK1("Starting to read Phonebook store entries..."); + iPhBkIndividualPause=CfgFile()->ItemValue(KPhBkStoreIndividualReqPause,KDefaultPhBkStoreIndividualReqPause); + iPhBkBatchPause=CfgFile()->ItemValue(KPhBkStoreBatchReqPause,KDefaultPhBkStoreBatchReqPause); + + const CTestConfigItem* item=NULL; + TInt ret=KErrNone; + + TInt i; + + // Get Phonebook entries + TInt count=CfgFile()->ItemCount(KPhBkUSimStoreEntry); + for(i=0;iItem(KPhBkUSimStoreEntry,i); + if(!item) + break; + + TPtrC8 phonebookStore,aid, phonebookName,alphaTag,telNum,alphaTag2,emails, groups, additional; + TInt index; + TUint8 npiTon; + ret=GetPhBkUSimEntry(item,parseIndex,phonebookStore,phonebookName,aid,index,telNum,alphaTag,npiTon,alphaTag2); + if(ret!=KErrNone) + { + LOGPARSERR("Phonebook Entry",ret,index,&KPhBkUSimStoreEntry); + continue; + } + + if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type + continue; + else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook + continue; + + if(phonebookStore.MatchF(KUSimPhoneBook)==0 && + iPhBkAid.Length()==0) //starting up + { + iPhBkAid.Copy(aid); + iPhBkAidUSim1.Copy(aid); + iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries; + } + + else if(phonebookStore.MatchF(KUSimPhoneBook)==0 && + iPhBkAid.Length()!=0 && iPhBkAid.Compare(aid)!=KErrNone) + { + if(iPhBkAidUSim2.Length()==0) + { + iPhBkAid.Copy(aid); + iPhBkAidUSim2.Copy(aid); + iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries; + } + else if(iPhBkAidUSim2.Compare(aid)==KErrNone) + { + iPhBkAid.Copy(aid); + iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries; + } + else if(iPhBkAidUSim2.Compare(aid)!=KErrNone) + //Currently there is support for only 2 USim phonebooks + {continue;} //...so, a possible third one will be ignored!!! + } + + iPhBkUSimStoreEntries[index].iAlphaTag.Copy(alphaTag); + iPhBkUSimStoreEntries[index].iTelNum.Copy(telNum); + iPhBkUSimStoreEntries[index].iTonNpi=npiTon; + iPhBkUSimStoreEntries[index].iAlphaTag2.Copy(alphaTag2); + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,additional); + if(ret!=KErrNone) + { + LOGPARSERR("additional",ret,parseIndex,&KPhBkUSimStoreEntry); + } + else + { + TPtrC8 myName,myNum; + TUint8 myTon; + TInt myindex=0,pIndex=0; + iPhBkUSimStoreEntries[index].iAdditional=new(ELeave) CArrayFixFlat(iPhBkAdditional+1); + + while((GetPhBkAdditionalEntry(additional,pIndex,myNum,myName,myTon)==KErrNone) + && (myindex < iPhBkAdditional)) + { + TPhBkStoreEntry entry; + + entry.iAlphaTag.Copy(myName); + entry.iTelNum.Copy(myNum); + entry.iTonNpi=myTon; + TRAP_IGNORE(iPhBkUSimStoreEntries[index].iAdditional->AppendL(entry)); + + myindex++; + } + + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,emails); + if(ret!=KErrNone) + { + LOGPARSERR("emails",ret,parseIndex,&KPhBkUSimStoreEntry); + } + else + { + TPtrC8 myemail; + TInt myindex=0; + iPhBkUSimStoreEntries[index].iEmails=new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1); + + while((CTestConfig::GetElement(emails,';',myindex,myemail)==KErrNone) && + (myindex < iPhBkMaxEmail)) + { + TPhBkUSimEmail entry; + entry.Copy(myemail); + TRAP_IGNORE(iPhBkUSimStoreEntries[index].iEmails->AppendL(entry)); + myindex++; + } + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,groups); + if(ret!=KErrNone) + { + LOGPARSERR("groups",ret,parseIndex,&KPhBkUSimStoreEntry); + } + else + { + + TPtrC8 mygroup; + TInt myindex=0; + iPhBkUSimStoreEntries[index].iGroups=new(ELeave) CArrayFixFlat(KMaxGroups+1); + + + while((CTestConfig::GetElement(groups,';',myindex,mygroup)==KErrNone) && + (myindex < KMaxGroups)) + { + TPhBkUSimGroup entry; + entry.Copy(mygroup); + TRAP_IGNORE(iPhBkUSimStoreEntries[index].iGroups->AppendL(entry)); + myindex++; + } + } + + TBool hidden; + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,hidden); + if(ret!=KErrNone) + { + LOGPARSERR("emails",ret,parseIndex,&KPhBkUSimStoreEntry); + } + else + iPhBkUSimStoreEntries[index].iHiddenEntry=hidden; + + } + + count=CfgFile()->ItemCount(KPhBkError); + item=NULL; + + for(i=0;iItem(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); + //global phonebook error + continue; + } + + if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook + continue; + else if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this phonebook + continue; + + TPhBkError entry; + entry.iCount=count; + entry.iError=error; + TRAP_IGNORE(iPhBkError->AppendL(entry)); + } + PopulateOOBWrite(); + PopulateOOBDelete(); + LOGPHBK1("...Finished reading Phonebook store entries..."); + + if(iPhBkOOBWriteDuration!=-1) + iOOBWriteTimer->Start(iPhBkOOBWriteDuration,this,ETimerIdPhBkUSimStorOOBWrite); + if(iPhBkOOBDeleteDuration!=-1) + iOOBDeleteTimer->Start(iPhBkOOBDeleteDuration,this,ETimerIdPhBkUSimStorOOBDelete); + } + +void CSimPhBkUSimStore::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= , , , , " + */ + { + TInt parseIndex=0; + iPhBkOOBWriteDuration=KErrNotFound; + const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkUSimWrite); + if(!item) + return; + + TInt count; + TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,count); + if(ret!=KErrNone) + { + LOGPARSERR("count",ret,parseIndex,&KOOBPhBkUSimWrite); + return; + } + + TPtrC8 phonebookStore,aid, phonebookName,alphaTag,telNum,alphaTag2,emails, groups, additional; + TInt index; + TUint8 npiTon; + ret=GetPhBkUSimEntry(item,parseIndex,phonebookStore,phonebookName,aid,index,telNum,alphaTag,npiTon,alphaTag2); + if(ret!=KErrNone) + { + LOGPARSERR("Phonebook Entry",ret,parseIndex,&KOOBPhBkUSimWrite); + return; + } + + if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type + return; + else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook + return; + + iPhBkOOBWriteDuration=count; + iPhBkOOBWriteIndex=index; + iPhBkOOBWrite.iAlphaTag.Copy(alphaTag); + iPhBkOOBWrite.iTelNum.Copy(telNum); + iPhBkOOBWrite.iTonNpi=npiTon; + iPhBkOOBWrite.iAlphaTag2.Copy(alphaTag2); + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,additional); + if(ret!=KErrNone) + { + LOGPARSERR("additional",ret,parseIndex,&KOOBPhBkUSimWrite); + } + else + { + TPtrC8 myName,myNum; + TUint8 myTon; + TInt myindex=0,pIndex=0; + + TRAPD(err,iPhBkOOBWrite.iAdditional=new(ELeave) CArrayFixFlat(iPhBkAdditional+1)); + if (err!=KErrNone) + return; + while((GetPhBkAdditionalEntry(additional,pIndex,myNum,myName,myTon)==KErrNone) + && (myindex < iPhBkAdditional)) + { + TPhBkStoreEntry entry; + + entry.iAlphaTag.Copy(myName); + entry.iTelNum.Copy(myNum); + entry.iTonNpi=myTon; + TRAP_IGNORE(iPhBkOOBWrite.iAdditional->AppendL(entry)); + myindex++; + } + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,groups); + if(ret!=KErrNone) + { + LOGPARSERR("groups",ret,parseIndex,&KOOBPhBkUSimWrite); + } + else + { + TPtrC8 mygroup; + TInt myindex=0; + + TRAPD(err,iPhBkOOBWrite.iGroups=new(ELeave) CArrayFixFlat(KMaxGroups+1)); + if (err!=KErrNone) + return; + while((CTestConfig::GetElement(groups,';',myindex,mygroup)==KErrNone) && + (myindex < KMaxGroups)) + { + TPhBkUSimGroup entry; + entry.Copy(mygroup); + TRAP_IGNORE(iPhBkOOBWrite.iGroups->AppendL(entry)); + myindex++; + } + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,emails); + if(ret!=KErrNone) + { + LOGPARSERR("emails",ret,parseIndex,&KOOBPhBkUSimWrite); + } + else + { + TPtrC8 myemail; + TInt myindex=0; + + TRAPD(err,iPhBkOOBWrite.iEmails=new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1)); + if (err!=KErrNone) + return; + + while((CTestConfig::GetElement(emails,';',myindex,myemail)==KErrNone) && + (myindex < iPhBkMaxEmail)) + { + TPhBkUSimEmail entry; + entry.Copy(myemail); + TRAP_IGNORE(iPhBkOOBWrite.iEmails->AppendL(entry)); + myindex++; + } + } + + } + +void CSimPhBkUSimStore::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= , , + */ + { + iPhBkOOBDeleteDuration=KErrNotFound; + const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkUSimDelete); + if(!item) + return; + + TInt count; + TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count); + if(ret!=KErrNone) + { + LOGPARSERR("count",ret,0,&KOOBPhBkUSimDelete); + return; + } + + TPtrC8 phonebookName, phonebookStore; + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,phonebookStore); + if(ret!=KErrNone) + { + LOGPARSERR("phonebookStore",ret,1,&KOOBPhBkUSimDelete); + return; + } + + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,phonebookName); + if(ret!=KErrNone) + { + LOGPARSERR("phonebookName",ret,2,&KOOBPhBkUSimDelete); + return; + } + + if(phonebookStore.MatchF(iPhBkStore)!=0) + return; // Not this store + else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook + return; + + TInt index; + ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,index); + if(ret!=KErrNone) + { + LOGPARSERR("index",ret,3,&KOOBPhBkUSimDelete); + return; + } + + iPhBkOOBDeleteDuration=count; + iPhBkOOBDeleteIndex=index; + } + + +TInt CSimPhBkUSimStore::GetPhBkUSimEntry(const CTestConfigItem* aItem, TInt& aItemIndex, + TPtrC8& aPhonebookStore, + TPtrC8& aPhonebookName, + TPtrC8& aAid,TInt& aIndex, + TPtrC8& aTelNum, TPtrC8& aAlphaTag, TUint8& aNpiTon, + TPtrC8& aAlphaTag2) +/** + * 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++,aPhonebookStore); + if(ret!=KErrNone) + return ret; + + ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aPhonebookName); + if(ret!=KErrNone) + return ret; + + ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAid); + 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 EXTENDEDERROR(KErrArgument, KErrPhonebookNumberOverflow); + + ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag); + if(ret!=KErrNone) + return ret; + if(aAlphaTag.Length()>iPhBkMaxTextLen) + return EXTENDEDERROR(KErrArgument, KErrPhonebookTextOverflow); + + if((aTelNum.Length()>0) && (aTelNum[0]=='+')) + { + aTelNum.Set(aTelNum.Mid(1)); + aNpiTon=KNpiTonInternational; + } + else + aNpiTon=KNpiTonNational; + + ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag2); + if(ret!=KErrNone) + return ret; + if(aAlphaTag.Length()>iPhBkMaxTextLen) + return EXTENDEDERROR(KErrArgument, KErrPhonebookTextOverflow); + + return ret; + } + +TInt CSimPhBkUSimStore::GetPhBkAdditionalEntry(TPtrC8& aEntry, TInt& aItemIndex, + 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 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(aEntry,';',aItemIndex++,aAlphaTag); + if(ret!=KErrNone) + return ret; + + if(aAlphaTag.Length()>iPhBkMaxAdditionalTextLen) + return EXTENDEDERROR(KErrArgument, KErrPhonebookAdditionalNumberAlphaTextOverflow); + + ret=CTestConfig::GetElement(aEntry,';',aItemIndex++,aTelNum); + if(ret!=KErrNone) + return ret; + if(aTelNum.Length()>iPhBkMaxAdditionalTelNumLen) + return EXTENDEDERROR(KErrArgument, KErrPhonebookAdditionalNumberNumberOverflow); + + + if((aTelNum.Length()>0) && (aTelNum[0]=='+')) + { + aTelNum.Set(aTelNum.Mid(1)); + aNpiTon=KNpiTonInternational; + } + else + { + aNpiTon=KNpiTonNational; + } + + return ret; + } + +CSimPhBkUSimStore::~CSimPhBkUSimStore() +/** + * Standard destructor. Any objects created by the ::ConstructL() function + * will be destroyed here. + */ + { + + for(TInt i=1;i<=iPhBkMaxNumSlots;i++) + { + if(iPhBkUSim1StoreEntries[i].iTelNum.Length()>0 || + iPhBkUSim1StoreEntries[i].iAlphaTag.Length()>0) + { + iPhBkUSim1StoreEntries[i].iTelNum.Zero(); + if((iPhBkUSim1StoreEntries[i].iAdditional!=NULL) + && ((TUint)iPhBkUSim1StoreEntries[i].iAdditional!=DELETED)) + { + if(iPhBkUSim1StoreEntries[i].iAdditional->Count()>=0) + { + iPhBkUSim1StoreEntries[i].iAdditional->Delete(0,iPhBkUSim1StoreEntries[i].iAdditional->Count()); + delete iPhBkUSim1StoreEntries[i].iAdditional; + } + } + if((iPhBkUSim1StoreEntries[i].iGroups!=NULL) + && ((TUint)iPhBkUSim1StoreEntries[i].iGroups!=DELETED)) + { + if(iPhBkUSim1StoreEntries[i].iGroups->Count()>=0) + { + iPhBkUSim1StoreEntries[i].iGroups->Delete(0,iPhBkUSim1StoreEntries[i].iGroups->Count()); + delete iPhBkUSim1StoreEntries[i].iGroups; + } + } + if((iPhBkUSim1StoreEntries[i].iEmails!=NULL) + && ((TUint)iPhBkUSim1StoreEntries[i].iEmails!=DELETED)) + { + if(iPhBkUSim1StoreEntries[i].iEmails->Count()>=0) + { + iPhBkUSim1StoreEntries[i].iEmails->Delete(0,iPhBkUSim1StoreEntries[i].iEmails->Count()); + delete iPhBkUSim1StoreEntries[i].iEmails; + } + } + } + if(iPhBkUSim2StoreEntries!=NULL && + (iPhBkUSim2StoreEntries[i].iTelNum.Length()>0 || + iPhBkUSim2StoreEntries[i].iAlphaTag.Length()>0)) + { + iPhBkUSim2StoreEntries[i].iTelNum.Zero(); + if((iPhBkUSim2StoreEntries[i].iAdditional!=NULL) + && ((TUint)iPhBkUSim2StoreEntries[i].iAdditional!=DELETED)) + { + if(iPhBkUSim2StoreEntries[i].iAdditional->Count()>=0) + { + iPhBkUSim2StoreEntries[i].iAdditional->Delete(0,iPhBkUSim2StoreEntries[i].iAdditional->Count()); + delete iPhBkUSim2StoreEntries[i].iAdditional; + } + } + if((iPhBkUSim2StoreEntries[i].iGroups!=NULL) + && ((TUint)iPhBkUSim2StoreEntries[i].iGroups!=DELETED)) + { + if(iPhBkUSim2StoreEntries[i].iGroups->Count()>=0) + { + iPhBkUSim2StoreEntries[i].iGroups->Delete(0,iPhBkUSim2StoreEntries[i].iGroups->Count()); + delete iPhBkUSim2StoreEntries[i].iGroups; + } + } + if((iPhBkUSim2StoreEntries[i].iEmails!=NULL) + && ((TUint)iPhBkUSim2StoreEntries[i].iEmails!=DELETED)) + { + if(iPhBkUSim2StoreEntries[i].iEmails->Count()>=0) + { + iPhBkUSim2StoreEntries[i].iEmails->Delete(0,iPhBkUSim2StoreEntries[i].iEmails->Count()); + delete iPhBkUSim2StoreEntries[i].iEmails; + } + } + } + } + + if((iPhBkOOBWrite.iAdditional!=NULL) + && ((TUint)iPhBkOOBWrite.iAdditional!=DELETED)) + { + iPhBkOOBWrite.iAdditional->Delete(0,iPhBkOOBWrite.iAdditional->Count()); + delete iPhBkOOBWrite.iAdditional; + } + if((iPhBkOOBWrite.iGroups!=NULL) + && ((TUint)iPhBkOOBWrite.iGroups!=DELETED)) + { + iPhBkOOBWrite.iGroups->Delete(0,iPhBkOOBWrite.iGroups->Count()); + delete iPhBkOOBWrite.iGroups; + } + if((iPhBkOOBWrite.iEmails!=NULL) + && ((TUint)iPhBkOOBWrite.iEmails!=DELETED)) + { + iPhBkOOBWrite.iEmails->Delete(0,iPhBkOOBWrite.iEmails->Count()); + delete iPhBkOOBWrite.iEmails; + } + delete[] iPhBkUSim1StoreEntries; + delete[] iPhBkUSim2StoreEntries; + delete iPhBkError; + delete iPhBkRwBuffer; + delete iOOBWriteTimer; + delete iOOBDeleteTimer; + delete iReqTimer; + + } + +TInt CSimPhBkUSimStore::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* CSimPhBkUSimStore::OpenNewObjectByNameL(const TDesC& /*aName*/) +/** + * The API does not support any objects that could be opened from this one. + */ + { + User::Leave(KErrNotSupported); + return NULL; + } + +CTelObject* CSimPhBkUSimStore::OpenNewObjectL(TDes&) +/** + * The API does not support any objects that could be opened from this one. + */ + { + User::Leave(KErrNotSupported); + return NULL; + } + +CTelObject::TReqMode CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::Init() +/** + * This function can be used to perform any necessary synchronous initialisation. + */ + { + } + +TInt CSimPhBkUSimStore::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; + } + + if(CheckAndSwitchUSimApps()!=KErrNone) + { + ReqCompleted(aReqHandle, KErrNotFound); + return KErrNone; + } + + RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg* getInfoPckg=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg*)aPckg; + RMobilePhoneBookStore::TMobilePhoneBookInfoV1& getInfo=(*getInfoPckg)(); + + PopulatePhBkStoreInfo(&getInfo); + + if(&getInfo!=NULL) // NULL will have been assigned by PopulatePhBkStoreInfo if the version checking failed. + { + ReqCompleted(aReqHandle,KErrNone); + } + else + { + ReqCompleted(aReqHandle,KErrNotSupported); + } + + return KErrNone; + } + +void CSimPhBkUSimStore::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.Zero(); + + getExtraInfo->iPhBkMode.Copy(PhBkStore()); + + if(PhBkStore().Compare(KUSimPhoneBook)!=KErrNone) + { + getExtraInfo->iIdentity.Copy(iPhone->GetImsi()); + } + else + { + TPtrC8 USimId(iPhone->GetActiveUSim().Right(1)); + getExtraInfo->iIdentity.Copy(USimId); + getExtraInfo->iIdentity.Append(iPhone->GetImsi()); + } + } + 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.Zero(); + + getExtraInfo->iPhBkMode.Copy(PhBkStore()); + + getExtraInfo->iMaxSecondNames = KMaxSecondNames; + getExtraInfo->iMaxTextLengthSecondName = iPhBkMaxTextLen; + getExtraInfo->iMaxAdditionalNumbers = iPhBkAdditional; + getExtraInfo->iMaxTextLengthAdditionalNumber = iPhBkMaxAdditionalTextLen; + getExtraInfo->iMaxNumLengthAdditionalNumber = iPhBkMaxAdditionalTelNumLen; + getExtraInfo->iMaxGroupNames = KMaxGroups; + getExtraInfo->iMaxTextLengthGroupName = iPhBkMaxTextLen; + getExtraInfo->iMaxEmailAddr = iPhBkMaxEmail; + getExtraInfo->iMaxTextLengthEmailAddr = iPhBkMaxTextLen; + + if(PhBkStore().Compare(KUSimPhoneBook)!=KErrNone) + { + getExtraInfo->iIdentity.Copy(iPhone->GetImsi()); + } + else + { + TPtrC8 USimId(iPhone->GetActiveUSim().Right(1)); + getExtraInfo->iIdentity.Copy(USimId); + getExtraInfo->iIdentity.Append(iPhone->GetImsi()); + } + } + } + +TInt CSimPhBkUSimStore::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(CheckAndSwitchUSimApps()!=KErrNone) + { + ReqCompleted(aReqHandle, KErrNotFound); + return KErrNone; + } + + if(iPhone->IsICCLocked()!=EFalse) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + TPckg* indexNumPckg=(TPckg*)aPckg1; + RMobilePhoneBookStore::TPBIndexAndNumEntries& indexNum=(*indexNumPckg)(); + + if(indexNum.iNumSlots==iPhBkMaxNumSlots) + { + if (!(iPhBkStoreCaps & static_cast(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; + TBool onlyHidden=EFalse; + + for(TInt i=indexNum.iIndex;i<=iPhBkMaxNumSlots;i++) + { + if((iPhBkUSimStoreEntries[i].iTelNum.Length()!=0)||(iPhBkUSimStoreEntries[i].iAlphaTag.Length()!=0)) + { + ret=iPhBkRwBuffer->AddNewEntryTag(); + if(ret!=KErrNone) + break; + + if((iPhone->IsHiddenEnabled()!=EFalse) && + iPhBkUSimStoreEntries[i].iHiddenEntry==1) + { + //This is a hidden entry, the key is required and is currently locked + //Therefore, the client should be notified that the slot has been occupied by a hidden entry + + partial=ETrue; + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i); + if(ret!=KErrNone) + break; + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBHiddenInfo,(TUint8) iPhBkUSimStoreEntries[i].iHiddenEntry); + if(ret!=KErrNone) + break; + partial=EFalse; + onlyHidden=ETrue; + break; + } + + partial=ETrue; + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i); + if(ret!=KErrNone) + break; + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,iPhBkUSimStoreEntries[i].iAlphaTag); + if(ret!=KErrNone) + break; + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,iPhBkUSimStoreEntries[i].iTonNpi); + if(ret!=KErrNone) + break; + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,iPhBkUSimStoreEntries[i].iTelNum); + if(ret!=KErrNone) + break; + + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBSecondName,iPhBkUSimStoreEntries[i].iAlphaTag2); + if(ret!=KErrNone) + break; + + TInt EmailCount = iPhBkUSimStoreEntries[i].iEmails->Count(); + TInt GroupCount = iPhBkUSimStoreEntries[i].iGroups->Count(); + TInt AnrCount = iPhBkUSimStoreEntries[i].iAdditional->Count(); + TInt j; + + TBool corrupt=EFalse; + + for(j=0; jAt(j); + + corrupt=ETrue; + + ret=iPhBkRwBuffer->AddNewNumberTag(); + if(ret!=KErrNone) + break; + + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,entry.iAlphaTag); + if(ret!=KErrNone) + break; + + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,entry.iTelNum); + if(ret!=KErrNone) + break; + + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,entry.iTonNpi); + if(ret!=KErrNone) + break; + + corrupt=EFalse; + } + if(corrupt) + break; + + for(j=0; jAt(j); + + corrupt=ETrue; + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBEmailAddress,entry); + if(ret!=KErrNone) + break; + corrupt=EFalse; + } + if(corrupt) + break; + + for(j=0; jAt(j); + + corrupt=ETrue; + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBGroupName,entry); + if(ret!=KErrNone) + break; + corrupt=EFalse; + } + if(corrupt) + break; + + ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBHiddenInfo,(TUint8) iPhBkUSimStoreEntries[i].iHiddenEntry); + if(ret!=KErrNone) + break; + + partial=EFalse; + onlyHidden=ETrue; + 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)&&(!onlyHidden)) + ReqCompleted(aReqHandle,KErrNotFound); // No entries found. + else if((cnt==0)&&(!partial)&&(onlyHidden)) + ReqCompleted(aReqHandle,KErrAccessDenied); + else + ReqCompleted(aReqHandle,KErrNone); + + return KErrNone; + } + +TInt CSimPhBkUSimStore::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(CheckAndSwitchUSimApps()!=KErrNone) + { + ReqCompleted(aReqHandle, KErrNotFound); + return KErrNone; + } + + if(iPhone->IsICCLocked()!=EFalse) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess)) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + TPckg* indexPckg=(TPckg*)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((iPhBkUSimStoreEntries[i].iTelNum.Length()==0)&&(iPhBkUSimStoreEntries[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(iPhBkUSimStoreEntries[index].iTelNum.Length()!=0) + { + if((iPhone->IsHiddenEnabled()!=EFalse) && + iPhBkUSimStoreEntries[index].iHiddenEntry==1) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + isSlotAlreadyUsed=ETrue; + TInt idx,count; + + count=iPhBkUSimStoreEntries[index].iAdditional->Count(); + for(idx=0;idxAt(idx); + entry.iTelNum.Zero(); + entry.iAlphaTag.Zero(); + entry.iTonNpi=0; + } + iPhBkUSimStoreEntries[index].iAdditional->Delete(0,count); + delete iPhBkUSimStoreEntries[index].iAdditional; + count=iPhBkUSimStoreEntries[index].iGroups->Count(); + iPhBkUSimStoreEntries[index].iGroups->Delete(0,count); + delete iPhBkUSimStoreEntries[index].iGroups; + count=iPhBkUSimStoreEntries[index].iEmails->Count(); + iPhBkUSimStoreEntries[index].iEmails->Delete(0,count); + delete iPhBkUSimStoreEntries[index].iEmails; + + TRAPD(err,iPhBkUSimStoreEntries[index].iAdditional= + new(ELeave) CArrayFixFlat(iPhBkAdditional+1)); + if (err!=KErrNone) + return (err); + + TRAP(err,iPhBkUSimStoreEntries[index].iGroups= + new(ELeave) CArrayFixFlat(KMaxGroups)); + if (err!=KErrNone) + return (err); + + TRAP(err,iPhBkUSimStoreEntries[index].iEmails= + new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1)); + if (err!=KErrNone) + return (err); + } + else + { + TRAPD(err,iPhBkUSimStoreEntries[index].iAdditional= + new(ELeave) CArrayFixFlat(iPhBkAdditional+1)); + if (err!=KErrNone) + return (err); + + TRAP(err,iPhBkUSimStoreEntries[index].iGroups= + new(ELeave) CArrayFixFlat(KMaxGroups)); + if (err!=KErrNone) + return (err); + + TRAP(err,iPhBkUSimStoreEntries[index].iEmails= + new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1)); + if (err!=KErrNone) + return (err); + } +// Unpick the phonebook entry. + iPhBkRwBuffer->Set(aPckg1); + iPhBkRwBuffer->StartRead(); + + TUint8 tagVal; + TUint8 npiTon=0; + TUint8 hidden; + TPtrC alphaTag,alphaTag2; + TPtrC telNum; + TPtrC bufPtr; + TBool additional=EFalse; + TInt additionalCount=0; + + CPhoneBookBuffer::TPhBkTagType tagType; + TInt ret=KErrNone; + + TPhBkStoreEntry additionalEntry; + + while(ret==KErrNone) + { + ret=iPhBkRwBuffer->GetTagAndType(tagVal,tagType); + if(ret==KErrNotFound) + { + ret=KErrNone; + break; + } + else if(ret!=KErrNone) + break; + switch(tagVal) + { + case RMobilePhoneBookStore::ETagPBNewEntry: + break; + + case RMobilePhoneBookStore::ETagPBText: + ret=iPhBkRwBuffer->GetValue(alphaTag); + + LOGPHBK2("alphaTag (ETagPBText) Length = (%d)",alphaTag.Length()); + LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen); + + if(!additional && ret==KErrNone && (alphaTag.Length()<=iPhBkMaxTextLen)) + iPhBkUSimStoreEntries[index].iAlphaTag.Copy(alphaTag); + else if(additional && ret==KErrNone && (alphaTag.Length()<=iPhBkMaxAdditionalTextLen) + && (additionalCountGetValue(alphaTag2); + + LOGPHBK2("alphaTag2 (ETagPBSecondName) Length = (%d)",alphaTag2.Length()); + LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen); + + if(ret==KErrNone && (alphaTag2.Length()<=iPhBkMaxTextLen)) + iPhBkUSimStoreEntries[index].iAlphaTag2.Copy(alphaTag2); + else + ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookSecondNameTextOverflow); + break; + + case RMobilePhoneBookStore::ETagPBNumber: + ret=iPhBkRwBuffer->GetValue(telNum); + + LOGPHBK2("telNum (ETagPBNumber) Length = (%d)",telNum.Length()); + LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTelNumLen); + + if(!additional && ret==KErrNone && (telNum.Length()<=iPhBkMaxTelNumLen)) + iPhBkUSimStoreEntries[index].iTelNum.Copy(telNum); + else if(additional && ret==KErrNone && (telNum.Length()<=iPhBkMaxAdditionalTelNumLen) + && (additionalCountGetValue(npiTon); + if(!additional && ret==KErrNone) + iPhBkUSimStoreEntries[index].iTonNpi=npiTon; + else if (additional && ret==KErrNone) + { + additionalEntry.iTonNpi=npiTon; + TRAP_IGNORE(iPhBkUSimStoreEntries[index].iAdditional->AppendL(additionalEntry)); + additional=EFalse; + additionalCount++; + additionalEntry.iAlphaTag.Zero(); + additionalEntry.iTelNum.Zero(); + additionalEntry.iTonNpi=0; + } + break; + + case RMobilePhoneBookStore::ETagPBAnrStart: + if(!additional) + additional=ETrue; + else + ret=KErrArgument; + break; + + case RMobilePhoneBookStore::ETagPBGroupName: + ret=iPhBkRwBuffer->GetValue(bufPtr); + + LOGPHBK2("bufPtr (ETagPBGroupName) Length = (%d)",bufPtr.Length()); + LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen); + + if(ret==KErrNone && (bufPtr.Length()<=iPhBkMaxTextLen) + && (iPhBkUSimStoreEntries[index].iGroups->Count() < KMaxGroups)) + { + TRAP_IGNORE(iPhBkUSimStoreEntries[index].iGroups->AppendL(bufPtr)); + } + else + ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookGroupAlphaTextOverflow); + break; + + case RMobilePhoneBookStore::ETagPBEmailAddress: + ret=iPhBkRwBuffer->GetValue(bufPtr); + + LOGPHBK2("bufPtr (ETagPBEmailAddress) Length = (%d)",bufPtr.Length()); + LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen); + + if(ret==KErrNone && (bufPtr.Length()<=iPhBkMaxTextLen) + && (iPhBkUSimStoreEntries[index].iEmails->Count() < iPhBkMaxEmail)) + { + TRAP_IGNORE(iPhBkUSimStoreEntries[index].iEmails->AppendL(bufPtr)); + } + else + ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookEmailTextOverflow); + break; + + case RMobilePhoneBookStore::ETagPBHiddenInfo: + ret=iPhBkRwBuffer->GetValue(hidden); + if(ret==KErrNone) + iPhBkUSimStoreEntries[index].iHiddenEntry=hidden; + break; + + default: + ret=KErrNotSupported; + } + } + + if(ret!=KErrNone) + { + //Cleanup! + iPhBkUSimStoreEntries[index].iTelNum.Zero(); + iPhBkUSimStoreEntries[index].iAlphaTag.Zero(); + iPhBkUSimStoreEntries[index].iAlphaTag2.Zero(); + iPhBkUSimStoreEntries[index].iHiddenEntry=0; + iPhBkUSimStoreEntries[index].iTonNpi=npiTon; + + if(iPhBkUSimStoreEntries[index].iGroups!=NULL) + { + iPhBkUSimStoreEntries[index].iGroups->Delete(0,iPhBkUSimStoreEntries[index].iGroups->Count()); + delete iPhBkUSimStoreEntries[index].iGroups; + } + if(iPhBkUSimStoreEntries[index].iEmails!=NULL) + { + iPhBkUSimStoreEntries[index].iEmails->Delete(0,iPhBkUSimStoreEntries[index].iEmails->Count()); + delete iPhBkUSimStoreEntries[index].iEmails; + } + if(iPhBkUSimStoreEntries[index].iAdditional!=NULL) + { + iPhBkUSimStoreEntries[index].iAdditional->Delete(0,iPhBkUSimStoreEntries[index].iAdditional->Count()); + delete iPhBkUSimStoreEntries[index].iAdditional; + } + ReqCompleted(aReqHandle,ret); + return KErrNone; + } + +// if(alphaTag.Length()>iPhBkMaxTextLen) +// { +// ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookTextOverflow)); +// return KErrNone; +// } +// else if(telNum.Length()>iPhBkMaxTelNumLen) +// { +// ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookNumberOverflow)); +// return KErrNone; +// } + + if(isSlotAlreadyUsed) + DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventChanged,index); + else + DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventAdded,index); + return KErrNone; + } + +TInt CSimPhBkUSimStore::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(CheckAndSwitchUSimApps()!=KErrNone) + { + ReqCompleted(aReqHandle, KErrNotFound); + return KErrNone; + } + + if(iPhone->IsICCLocked()!=EFalse) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess)) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + + TPckg* intPckg=(TPckg*)aPckg; + TInt& index=(*intPckg)(); + + if((index<1)||(index>iPhBkMaxNumSlots)) + { + ReqCompleted(aReqHandle,KErrArgument); + return KErrNone; + } + + if((iPhone->IsHiddenEnabled()!=EFalse) && + iPhBkUSimStoreEntries[index].iHiddenEntry==1) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + iPhBkUSimStoreEntries[index].iTelNum.Zero(); + iPhBkUSimStoreEntries[index].iAlphaTag.Zero(); + iPhBkUSimStoreEntries[index].iAlphaTag2.Zero(); + + if((iPhBkUSimStoreEntries[index].iGroups!=NULL) && + ((TUint)iPhBkUSimStoreEntries[index].iGroups!=DELETED)) + { + iPhBkUSimStoreEntries[index].iGroups->Delete(0, + iPhBkUSimStoreEntries[index].iGroups->Count()); + delete iPhBkUSimStoreEntries[index].iGroups; + } + if((iPhBkUSimStoreEntries[index].iEmails!=NULL) && + ((TUint)iPhBkUSimStoreEntries[index].iEmails!=DELETED)) + { + iPhBkUSimStoreEntries[index].iEmails->Delete(0, + iPhBkUSimStoreEntries[index].iEmails->Count()); + delete iPhBkUSimStoreEntries[index].iEmails; + } + + if((iPhBkUSimStoreEntries[index].iAdditional!=NULL) && + ((TUint)iPhBkUSimStoreEntries[index].iAdditional!=DELETED)) + { + TInt count = iPhBkUSimStoreEntries[index].iAdditional->Count(); + for(TInt i=0;iAt(i); + entry.iTelNum.Zero(); + entry.iAlphaTag.Zero(); + entry.iTonNpi=0; + } + + iPhBkUSimStoreEntries[index].iAdditional->Delete(0,count); + delete iPhBkUSimStoreEntries[index].iAdditional; + } + + DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventDeleted,index); + return KErrNone; + } + +TInt CSimPhBkUSimStore::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(CheckAndSwitchUSimApps()!=KErrNone) + { + ReqCompleted(aReqHandle, KErrNotFound); + return KErrNone; + } + + if(iPhone->IsICCLocked()!=EFalse) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + if (!(iPhBkStoreCaps & static_cast(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess)) + { + ReqCompleted(aReqHandle, KErrAccessDenied); + return KErrNone; + } + + for(TInt i=1;i<=iPhBkMaxNumSlots;i++) + { + TBool entryUsed =EFalse; + + if((iPhone->IsHiddenEnabled()!=EFalse) && + iPhBkUSimStoreEntries[i].iHiddenEntry==1) + { + //Skip me because I am a hidden entry! + //The hidden key has to be verified to delete me! + continue; + } + if(iPhBkUSimStoreEntries[i].iTelNum.Length()>0) + entryUsed = ETrue; + + iPhBkUSimStoreEntries[i].iTelNum.Zero(); + iPhBkUSimStoreEntries[i].iAlphaTag.Zero(); + iPhBkUSimStoreEntries[i].iAlphaTag2.Zero(); + + if(entryUsed) + { + if((iPhBkUSimStoreEntries[i].iGroups!=NULL) && + ((TUint)iPhBkUSimStoreEntries[i].iGroups!=DELETED)) + { + iPhBkUSimStoreEntries[i].iGroups->Delete(0, + iPhBkUSimStoreEntries[i].iGroups->Count()); + delete iPhBkUSimStoreEntries[i].iGroups; + } + if((iPhBkUSimStoreEntries[i].iEmails!=NULL) && + ((TUint)iPhBkUSimStoreEntries[i].iEmails!=DELETED)) + { + iPhBkUSimStoreEntries[i].iEmails->Delete(0, + iPhBkUSimStoreEntries[i].iEmails->Count()); + delete iPhBkUSimStoreEntries[i].iEmails; + } + if((iPhBkUSimStoreEntries[i].iAdditional!=NULL) && + ((TUint)iPhBkUSimStoreEntries[i].iAdditional!=DELETED)) + { + TInt count = iPhBkUSimStoreEntries[i].iAdditional->Count(); + for(TInt index=0;indexAt(index); + entry.iTelNum.Zero(); + entry.iAlphaTag.Zero(); + entry.iTonNpi=0; + } + + iPhBkUSimStoreEntries[i].iAdditional->Delete(0,count); + delete iPhBkUSimStoreEntries[i].iAdditional; + } + } + } + DelayCompletion(iPhBkBatchPause,aReqHandle,EStoreEventDeleted,-1); + return KErrNone; + } + +TInt CSimPhBkUSimStore::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* eventPckg=(TPckg*)aPckg1; + TUint32& event=(*eventPckg)(); + TPckg* indexPckg=(TPckg*)aPckg2; + TInt& index=(*indexPckg)(); + + iEvOutstandingReq=ETrue; + iEvReqHandle=aReqHandle; + iEvEvent=&event; + iEvIndex=&index; + return KErrNone; + } + +void CSimPhBkUSimStore::NotifyStoreEventCancel() +/** + * Cancel an outstanding notify store request. + */ + { + if(iEvOutstandingReq) + { + iEvOutstandingReq=EFalse; + ReqCompleted(iEvReqHandle,KErrCancel); + } + } + +TPtrC8 CSimPhBkUSimStore::Name() +/** + * Accessor function fot the Phonebook Store name. + * + * @return TPtrC8 The name of this Phonebook Store. + */ + { + return iPhBkStoreName; + } + +TPtrC8 CSimPhBkUSimStore::PhBkStore() +/** + * Accessor function fot the Phonebook Store name. + * + * @return TPtrC8 The name of this Phonebook Store. + */ + { + return iPhBkStore; + } + +TPtrC8 CSimPhBkUSimStore::AID() +/** + * Accessor function fot the Phonebook Store name. + * + * @return TPtrC8 The name of this Phonebook Store. + */ + { + return iPhBkAid; + } + +TInt CSimPhBkUSimStore::UsedEntries() +/** + * Count the number of used entries in the Phonebook Store. + * @return TInt The number of used entries in the store. + */ + { + TInt cnt=0; + if(CheckAndSwitchUSimApps()!=KErrNone) + return KErrNotFound; + for(TInt i=1;i<=iPhBkMaxNumSlots;i++) + { + if((iPhBkUSimStoreEntries[i].iTelNum.Length()!=0)||(iPhBkUSimStoreEntries[i].iAlphaTag.Length()!=0)) + cnt++; + } + return cnt; + } + +TInt CSimPhBkUSimStore::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 CSimPhBkUSimStore::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 CSimPhBkUSimStore::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,ETimerIdPhBkUSimStorReq); + } + +void CSimPhBkUSimStore::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. + */ + { + TInt idx=0,count; + TBool isSlotAlreadyUsed=EFalse; + + switch(aId) + { + case ETimerIdPhBkUSimStorReq: + StoreEvent(iPendingEvent,iPendingIndex); + ReqCompleted(iPendingReqCompletion,KErrNone); + break; + + case ETimerIdPhBkUSimStorOOBWrite: + + if(CheckAndSwitchUSimApps()!=KErrNone) + if(iEvOutstandingReq) + { + ReqCompleted(iEvReqHandle,KErrNotFound); + return; + } + else + { + return; + } + + if(iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTelNum.Length()!=0) + isSlotAlreadyUsed=ETrue; + + iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAlphaTag.Copy(iPhBkOOBWrite.iAlphaTag); + iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTelNum.Copy(iPhBkOOBWrite.iTelNum); + iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTonNpi=iPhBkOOBWrite.iTonNpi; + iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAlphaTag2.Copy(iPhBkOOBWrite.iAlphaTag2); + + if(isSlotAlreadyUsed) + { + if((count=iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->Count())>0) + { + for(idx=0;idxAt(idx); + entry.iTelNum.Zero(); + entry.iAlphaTag.Zero(); + entry.iTonNpi=0; + } + iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->Delete(0,count); + delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional; + } + + if((count = iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups->Count())>0) + { + iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups->Delete(0,count); + delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups; + } + if((count = iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails->Count())>0) + { + iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails->Delete(0,count); + delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails; + } + } + + count = iPhBkOOBWrite.iAdditional->Count(); + + //sometimes because of a kernel bug on wins, iAdditional pointer gets filled up with + //bad address 0xdededede (investigating) + + TRAPD(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional=new(ELeave) CArrayFixFlat(iPhBkAdditional+1)); + if (err!=KErrNone) + { + LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure"); + return; + } + + for(idx=0;idxAt(idx); + TRAP_IGNORE(iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->AppendL(entry)); + } + + + TRAP(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups=new(ELeave) CArrayFixFlat(KMaxGroups)); + if (err!=KErrNone) + { + LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure"); + return; + } + + for(idx=0;idxAppendL(entry)); + } + + count = iPhBkOOBWrite.iEmails->Count(); + TRAP(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails=new(ELeave) CArrayFixFlat(iPhBkMaxEmail+1)); + if (err!=KErrNone) + { + LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure"); + return; + } + + for(idx=0;idxAppendL(entry)); + } + + iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iHiddenEntry=iPhBkOOBWrite.iHiddenEntry; + + StoreEvent(EStoreEventAdded,iPhBkOOBWriteIndex); + break; + + case ETimerIdPhBkUSimStorOOBDelete: + + if(CheckAndSwitchUSimApps()!=KErrNone) + if(iEvOutstandingReq) + { + ReqCompleted(iEvReqHandle,KErrNotFound); + return; + } + else + { + return; + } + + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag.Zero(); + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iTelNum.Zero(); + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iTonNpi=0; + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag2.Zero(); + + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups->Delete(0, + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups->Count()); + delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups; + + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails->Delete(0, + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails->Count()); + delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails; + + count = iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional->Count(); + for(idx=0;idxAt(idx); + entry.iTelNum.Zero(); + entry.iAlphaTag.Zero(); + entry.iTonNpi=0; + } + + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional->Delete(0,count); + delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional; + iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iHiddenEntry=0; + + StoreEvent(EStoreEventDeleted,iPhBkOOBDeleteIndex); + break; + + default: + break; + } + } + +void CSimPhBkUSimStore::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 CSimPhBkUSimStore::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;iCount();i++) + { + if(iPhBkError->At(i).iCount==iIpcCnt) + { + aError=iPhBkError->At(i).iError; + return ETrue; + } + } + return EFalse; + } + + +/** + * Check that the USIM App phonebook in use is the same as the current + * USIM App, and if not then swap the phonebook over. + */ +TInt CSimPhBkUSimStore::CheckAndSwitchUSimApps() + { + TInt ret=KErrNone; + + if(iPhBkStore.Compare(KUSimPhoneBook)==KErrNone) + { + if(iPhone->GetActiveUSim().Compare(iPhBkAid)==KErrNone) + { + // + // The active USIM App is the same as last time, but ensure that + // we are using the right phonebook anyway. + // + if(iPhBkAid.Compare(iPhBkAidUSim2)==KErrNone) + { + iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries; + } + else if(iPhBkAid.Compare(iPhBkAidUSim1)==KErrNone) + { + iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries; + } + else + { + //messed up + return KErrUnknown; + } + } + else if((iPhone->GetActiveUSim().Compare(iPhBkAid)!=KErrNone) && + (iPhone->GetActiveUSim().Compare(iPhBkAidUSim2)==KErrNone)) + { + // + // The active USIM App is not the same as last time and it appears + // to be USIM App 2, so use USIM phonebook number 2. + // + iPhBkAid.Copy(iPhBkAidUSim2); + iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries; + } + else if((iPhone->GetActiveUSim().Compare(iPhBkAid)!=KErrNone) && + (iPhone->GetActiveUSim().Compare(iPhBkAidUSim1)==KErrNone)) + { + // + // The active USIM App is not the same as last time and it appears + // to be USIM App 1, so use USIM phonebook number 1. + // + iPhBkAid.Copy(iPhBkAidUSim1); + iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries; + } + else + { + //Unknown active application!! + ret=KErrNotFound; + } + } + return ret; +} + +const CTestConfigSection* CSimPhBkUSimStore::CfgFile() +/** +* Returns a pointer to the config file section +* +* @return CTestConfigSection a pointer to the configuration file data section +*/ + { + LOGPHBK1(">>CSimPhBkUSimStore::CfgFile"); + return iPhone->CfgFile(); + }