telephonyserverplugins/simtsy/src/CSimPhBkUsimStore.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 42 3adadc800673
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implements the Phonebook Store manipulation code.
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include "CSimPhBkUsimStore.h"
       
    23 #include "CSimPhone.h"
       
    24 #include "Simlog.h"
       
    25 #include <testconfigfileparser.h>
       
    26 
       
    27 const TUint16 KNpiTonInternational=145;		// < The Number Plan Identifier and Type of Number for an international telephone number.
       
    28 const TUint16 KNpiTonNational=129;			// < The Number Plan Identifier and Type of Number for a national telephone number.
       
    29 const TInt KMaxGroups = 10;					// < The maximum allowed number of groups associated with a phonebook entry
       
    30 const TInt KMaxSecondNames = 1;				// < The maximum allowed number of Second Names associated with a phonebook entry
       
    31 const TInt KPhonebookErrorGranularity=3;	// < Granularity of phonebook error list array.
       
    32 const TUint DELETED=0xdededede; 
       
    33 //
       
    34 // CSimPhBkUSimStore
       
    35 //
       
    36 void CSimPhBkUSimStore::ClosePhone(TAny* aObj)
       
    37 /**
       
    38  * A utility function for cleaning up the stack.
       
    39  */
       
    40 	{
       
    41 	((CObject*)aObj)->Close();
       
    42 	}
       
    43 
       
    44 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)
       
    45 /**
       
    46  * Standard two phase constructor.
       
    47  * @param aPhone			The phone object from which this Phonebook was opened.
       
    48  * @param aName				The name of the created Phonebook.
       
    49  * @param aMaxNumSlots		The maximum number of slots in the Phonebook.
       
    50  * @param aMaxNumLen		The maximum length of the telephone number (<100)
       
    51  * @param aMaxTextLen		The maximum length of the alpha text strings (<100)
       
    52  * @param aAdditional		The maximum number of additional numbers associated with an entry
       
    53  * @param aMaxEmail			The maximum number of email addresses associated with an entry
       
    54  * @param aMaxAdditionalTelNumLen	The maximum length of the an additional telephone number.
       
    55  * @param aMaxAdditionalTextLen		The maximum length of the alpha tag in an additional telephone number.
       
    56  * @return CSimPhBkUSimStore*			The newly created object.
       
    57  */
       
    58 	{
       
    59 	CSimPhBkUSimStore* store=new(ELeave) CSimPhBkUSimStore(aPhone);
       
    60 	TCleanupItem newObjClose(ClosePhone,store);
       
    61 	CleanupStack::PushL(newObjClose);
       
    62 	store->ConstructL(aStore,aName,aMaxNumSlots,aMaxNumLen,aMaxTextLen,aAdditional,aMaxEmail, aMaxAdditionalTelNumLen, aMaxAdditionalTextLen);	
       
    63 	CleanupStack::Pop();
       
    64 	return store;
       
    65 	}
       
    66 
       
    67 CSimPhBkUSimStore::CSimPhBkUSimStore(CSimPhone* aPhone)
       
    68 		: CSimPhone(iDummyPhoneBaseRef), iPhone(aPhone),iIpcCnt(0),iEvOutstandingReq(EFalse)
       
    69 /**
       
    70  * Trivial first phase constructor.
       
    71  * @param aPhone	The phone object from which this phonebook was opened.
       
    72  */
       
    73 	{}
       
    74 
       
    75 void CSimPhBkUSimStore::ConstructL(const TDesC8& aStore, const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen, TInt aAdditional, TInt aMaxEmail, TInt aMaxAdditionalTelNumLen, TInt aMaxAdditionalTextLen)
       
    76 /**
       
    77  * Second phase constructor that allocates memory for the phonebook, batch read buffer and
       
    78  * a delayed completion timer.  The constructor also reads the individual and batch read
       
    79  * delays from the configuration file.
       
    80  *
       
    81  * @param aName			The name of the created phonebook.
       
    82  * @param aMaxNumLen	The maximum length of a telephone number.
       
    83  * @param aMaxTextLen	The maximum length of an alpha tag.
       
    84  * @param aMaxNumLen	The maximum length of the telephone number (<100).
       
    85  * @param aMaxTextLen	The maximum length of the alpha text strings (<100).
       
    86  * @param aAdditional	The maximum number of additional numbers associated with an entry.
       
    87  * @param aMaxEmail		The maximum number of email addresses associated with an entry.
       
    88  * @param aMaxAdditionalTelNumLen	The maximum length of the an additional telephone number.
       
    89  * @param aMaxAdditionalTextLen		The maximum length of the alpha tag in an additional telephone number.
       
    90  */
       
    91 	{
       
    92 	LOGPHBK1("Starting to parse Phonebook store additional config parameters...");
       
    93 	__ASSERT_ALWAYS(aMaxNumLen<=KPhBkMaxTelNumSize,SimPanic(EPhonebookNameOrNumberTooLarge));
       
    94 	__ASSERT_ALWAYS(aMaxTextLen<=KPhBkMaxAlphaTagSize,SimPanic(EPhonebookNameOrNumberTooLarge));
       
    95 
       
    96 	iPhBkMaxNumSlots=aMaxNumSlots;
       
    97 	iPhBkMaxTelNumLen=aMaxNumLen;
       
    98 	iPhBkMaxTextLen=aMaxTextLen;
       
    99 	iPhBkStoreName.Copy(aName);
       
   100 	iPhBkStore.Copy(aStore);
       
   101 	iPhBkAdditional=aAdditional;
       
   102 	iPhBkMaxEmail=aMaxEmail;
       
   103 	iPhBkMaxAdditionalTelNumLen = aMaxAdditionalTelNumLen;
       
   104 	iPhBkMaxAdditionalTextLen = aMaxAdditionalTextLen;	
       
   105 	
       
   106 	iPhBkAid.Zero();
       
   107 	iPhBkAidUSim1.Zero();
       
   108 	iPhBkAidUSim2.Zero();
       
   109 
       
   110 	if(iPhBkStore.Compare(KUSimPhoneBook)==KErrNone)
       
   111 		{
       
   112 		iPhBkUSim1StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused
       
   113 		iPhBkUSim2StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused
       
   114 		}
       
   115 	else
       
   116 		{
       
   117 		iPhBkUSim1StoreEntries=new(ELeave) TPhBkUSimStoreEntry[aMaxNumSlots+1]; //slot 0 is unused
       
   118 		iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries;
       
   119 		}
       
   120 
       
   121 	iReqTimer=CSimTimer::NewL(iPhone);
       
   122 	iOOBWriteTimer=CSimTimer::NewL(iPhone);
       
   123 	iOOBDeleteTimer=CSimTimer::NewL(iPhone);
       
   124 	iPhBkRwBuffer=new(ELeave) CPhoneBookBuffer();
       
   125 	iPhBkError=new(ELeave) CArrayFixFlat<TPhBkError>(KPhonebookErrorGranularity);
       
   126 
       
   127 	const CTestConfigItem* item = NULL;
       
   128 	TInt ret = KErrNone;
       
   129 	
       
   130 	item=CfgFile()->Item(KTriggerEventIPC,0);
       
   131 	if(item)
       
   132 		{
       
   133 		TInt ipc, cnt, event;
       
   134 
       
   135 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,ipc);
       
   136 		if(ret!=KErrNone)
       
   137 			{
       
   138 			LOGPARSERR("ipc",ret,0,&KTriggerEventIPC);
       
   139 			}
       
   140 		else
       
   141 			iTriggerEventIPC.iIPC=ipc;
       
   142 
       
   143 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,cnt);
       
   144 		if(ret!=KErrNone)
       
   145 			{
       
   146 			LOGPARSERR("cnt",ret,1,&KTriggerEventIPC);
       
   147 			}
       
   148 		else
       
   149 			iTriggerEventIPC.iIPCCnt=cnt;
       
   150 		
       
   151 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,event);
       
   152 		if(ret!=KErrNone)
       
   153 			{
       
   154 			LOGPARSERR("event",ret,2,&KTriggerEventIPC);
       
   155 			}
       
   156 		else
       
   157 			iTriggerEventIPC.iEvent=RMobilePhone::TMobilePhoneSecurityEvent(event);
       
   158 
       
   159 		}
       
   160 
       
   161 	const CTestConfigItem* item0=NULL;
       
   162 	TInt count=CfgFile()->ItemCount(KPhBkPhoneUSimStoreCaps);
       
   163 	
       
   164 	if(count==0)
       
   165 		iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
       
   166 	else
       
   167 		{
       
   168 		TBool capsFound=EFalse;
       
   169 		for(TInt i=0;(i<count || !capsFound);i++)
       
   170 		{
       
   171 			item0=CfgFile()->Item(KPhBkPhoneUSimStoreCaps,i);
       
   172 			
       
   173 			if (item0)
       
   174 				{
       
   175 				TPtrC8 value0,phonebookStore, phonebookName;
       
   176 				TInt ret0;
       
   177 
       
   178 				ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,0,phonebookStore);
       
   179 				if(ret0!=KErrNone)
       
   180 					{
       
   181 					iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
       
   182 					LOGPARSERR("Caps:PhonebookStore",ret,0,&KPhBkPhoneUSimStoreCaps);
       
   183 					}	
       
   184 
       
   185 				if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type
       
   186 					continue;
       
   187 
       
   188 				ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,1,phonebookName);
       
   189 				if(ret0!=KErrNone)
       
   190 					{
       
   191 					iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
       
   192 					LOGPARSERR("phonebookName",ret,1,&KPhBkPhoneUSimStoreCaps);
       
   193 					}	
       
   194 				
       
   195 				if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this PhBkStoreName type
       
   196 					continue;
       
   197 				
       
   198 				ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,2,value0);
       
   199 				if(ret0!=KErrNone)
       
   200 					{
       
   201 					iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
       
   202 					LOGPARSERR("caps",ret,2,&KPhBkPhoneUSimStoreCaps);
       
   203 					}	
       
   204 				else
       
   205 					{
       
   206 					TUint32 intValue;
       
   207 					TInt ret = AsciiToNum(value0, intValue);
       
   208 					if(ret!=KErrNone)
       
   209 						iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
       
   210 					else
       
   211 						{
       
   212 						iPhBkStoreCaps = intValue;
       
   213 						capsFound=ETrue;
       
   214 						}
       
   215 					}
       
   216 				
       
   217 				}
       
   218 			}
       
   219 	}
       
   220 	LOGPHBK1("...Finished parsing Phonebook store additional config parameters...");
       
   221 	}
       
   222 
       
   223 void CSimPhBkUSimStore::PopulateStoreFromConfigFileL()
       
   224 /**
       
   225  * Populate the Phonebook Store from information in the configuration file.  This is performed
       
   226  * after the standard Phonebook Store construction in order to prevent reseting the configuation
       
   227  * file accessor class' pointers while possibly multiple Phonebook Stores are created.
       
   228 //alex
       
   229  *
       
   230  * The store entries comply to the following format:
       
   231  * "PhBkStoreEntry = <store name>, <slot number>, <telephone number>, <alphatag>"
       
   232  */
       
   233 	{
       
   234 	LOGPHBK1("Starting to read Phonebook store entries...");
       
   235 	iPhBkIndividualPause=CfgFile()->ItemValue(KPhBkStoreIndividualReqPause,KDefaultPhBkStoreIndividualReqPause);
       
   236 	iPhBkBatchPause=CfgFile()->ItemValue(KPhBkStoreBatchReqPause,KDefaultPhBkStoreBatchReqPause);
       
   237 
       
   238 	const CTestConfigItem* item=NULL;
       
   239 	TInt ret=KErrNone;
       
   240 
       
   241 	TInt i;
       
   242 
       
   243 	// Get Phonebook entries
       
   244 	TInt count=CfgFile()->ItemCount(KPhBkUSimStoreEntry);
       
   245 	for(i=0;i<count;i++)
       
   246 		{
       
   247 		TInt parseIndex=0;
       
   248 
       
   249 		item=CfgFile()->Item(KPhBkUSimStoreEntry,i);
       
   250 		if(!item)
       
   251 			break;
       
   252 
       
   253 		TPtrC8 phonebookStore,aid, phonebookName,alphaTag,telNum,alphaTag2,emails, groups, additional;
       
   254 		TInt index;
       
   255 		TUint8 npiTon;
       
   256 		ret=GetPhBkUSimEntry(item,parseIndex,phonebookStore,phonebookName,aid,index,telNum,alphaTag,npiTon,alphaTag2);
       
   257 		if(ret!=KErrNone)
       
   258 			{
       
   259 			LOGPARSERR("Phonebook Entry",ret,index,&KPhBkUSimStoreEntry);
       
   260 			continue;
       
   261 			}
       
   262 
       
   263 		if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type
       
   264 			continue;
       
   265 		else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
       
   266 			continue;
       
   267 
       
   268 		if(phonebookStore.MatchF(KUSimPhoneBook)==0 &&
       
   269 			iPhBkAid.Length()==0) //starting up
       
   270 			{
       
   271 			iPhBkAid.Copy(aid);
       
   272 			iPhBkAidUSim1.Copy(aid);
       
   273 			iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries;
       
   274 			}
       
   275 
       
   276 		else if(phonebookStore.MatchF(KUSimPhoneBook)==0 &&
       
   277 			iPhBkAid.Length()!=0 && iPhBkAid.Compare(aid)!=KErrNone)
       
   278 			{
       
   279 			if(iPhBkAidUSim2.Length()==0)
       
   280 				{
       
   281 				iPhBkAid.Copy(aid);
       
   282 				iPhBkAidUSim2.Copy(aid);
       
   283 				iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries;
       
   284 				}
       
   285 			else if(iPhBkAidUSim2.Compare(aid)==KErrNone)
       
   286 				{
       
   287 				iPhBkAid.Copy(aid);
       
   288 				iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries;	
       
   289 				}
       
   290 			else if(iPhBkAidUSim2.Compare(aid)!=KErrNone)
       
   291 				//Currently there is support for only 2 USim phonebooks
       
   292 				{continue;} //...so, a possible third one will be ignored!!!
       
   293 			}
       
   294 
       
   295 		iPhBkUSimStoreEntries[index].iAlphaTag.Copy(alphaTag);
       
   296 		iPhBkUSimStoreEntries[index].iTelNum.Copy(telNum);
       
   297 		iPhBkUSimStoreEntries[index].iTonNpi=npiTon;
       
   298 		iPhBkUSimStoreEntries[index].iAlphaTag2.Copy(alphaTag2);
       
   299 	
       
   300 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,additional);
       
   301 		if(ret!=KErrNone)
       
   302 			{
       
   303 			LOGPARSERR("additional",ret,parseIndex,&KPhBkUSimStoreEntry);
       
   304 			}
       
   305 		else
       
   306 			{	
       
   307 			TPtrC8 myName,myNum;
       
   308 			TUint8 myTon;
       
   309 			TInt myindex=0,pIndex=0;
       
   310 			iPhBkUSimStoreEntries[index].iAdditional=new(ELeave) CArrayFixFlat<TPhBkStoreEntry>(iPhBkAdditional+1);
       
   311 	
       
   312 			while((GetPhBkAdditionalEntry(additional,pIndex,myNum,myName,myTon)==KErrNone)
       
   313 					&& (myindex < iPhBkAdditional))
       
   314 				{
       
   315 				TPhBkStoreEntry entry;
       
   316 			
       
   317 				entry.iAlphaTag.Copy(myName);
       
   318 				entry.iTelNum.Copy(myNum);
       
   319 				entry.iTonNpi=myTon;
       
   320 				TRAP_IGNORE(iPhBkUSimStoreEntries[index].iAdditional->AppendL(entry));
       
   321 
       
   322 				myindex++;
       
   323 				}
       
   324 
       
   325 			}
       
   326 	
       
   327 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,emails);
       
   328 		if(ret!=KErrNone)
       
   329 			{
       
   330 			LOGPARSERR("emails",ret,parseIndex,&KPhBkUSimStoreEntry);
       
   331 			}
       
   332 		else
       
   333 		{	
       
   334 			TPtrC8 myemail;
       
   335 			TInt myindex=0;
       
   336 			iPhBkUSimStoreEntries[index].iEmails=new(ELeave) CArrayFixFlat<TPhBkUSimEmail>(iPhBkMaxEmail+1);
       
   337 			
       
   338 			while((CTestConfig::GetElement(emails,';',myindex,myemail)==KErrNone) &&
       
   339 					(myindex < iPhBkMaxEmail))
       
   340 			{
       
   341 			TPhBkUSimEmail entry;
       
   342 			entry.Copy(myemail);
       
   343 			TRAP_IGNORE(iPhBkUSimStoreEntries[index].iEmails->AppendL(entry));
       
   344 			myindex++;
       
   345 			}
       
   346 		}
       
   347 
       
   348 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,groups);
       
   349 		if(ret!=KErrNone)
       
   350 			{
       
   351 			LOGPARSERR("groups",ret,parseIndex,&KPhBkUSimStoreEntry);
       
   352 			}
       
   353 		else
       
   354 		{	
       
   355 
       
   356 			TPtrC8 mygroup;
       
   357 			TInt myindex=0;
       
   358 			iPhBkUSimStoreEntries[index].iGroups=new(ELeave) CArrayFixFlat<TPhBkUSimGroup>(KMaxGroups+1);
       
   359 
       
   360 		
       
   361 			while((CTestConfig::GetElement(groups,';',myindex,mygroup)==KErrNone) &&
       
   362 					(myindex < KMaxGroups))
       
   363 			{
       
   364 			TPhBkUSimGroup entry;
       
   365 			entry.Copy(mygroup);
       
   366 			TRAP_IGNORE(iPhBkUSimStoreEntries[index].iGroups->AppendL(entry));
       
   367 			myindex++;
       
   368 			}
       
   369 		}
       
   370 
       
   371 		TBool hidden;
       
   372 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,hidden);
       
   373 		if(ret!=KErrNone)
       
   374 			{
       
   375 			LOGPARSERR("emails",ret,parseIndex,&KPhBkUSimStoreEntry);
       
   376 			}
       
   377 		else
       
   378 			iPhBkUSimStoreEntries[index].iHiddenEntry=hidden;
       
   379 
       
   380 		}
       
   381 
       
   382 	count=CfgFile()->ItemCount(KPhBkError);
       
   383 	item=NULL;
       
   384 
       
   385 	for(i=0;i<count;i++)
       
   386 		{
       
   387 		item=CfgFile()->Item(KPhBkError,i);
       
   388 		if(!item)
       
   389 			break;
       
   390 
       
   391 		TInt count,error;
       
   392 		TPtrC8 phonebookName, phonebookStore;
       
   393 
       
   394 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
       
   395 		if(ret!=KErrNone)
       
   396 			{
       
   397 			LOGPARSERR("count",ret,0,&KPhBkError);
       
   398 			continue;
       
   399 			}
       
   400 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,error);
       
   401 		if(ret!=KErrNone)
       
   402 			{
       
   403 			LOGPARSERR("error",ret,1,&KPhBkError);
       
   404 			continue;
       
   405 			}
       
   406 		
       
   407 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,phonebookName);
       
   408 		if(ret!=KErrNone)
       
   409 			{
       
   410 			LOGPARSERR("phonebookName",ret,2,&KPhBkError);
       
   411 			continue;
       
   412 			}
       
   413 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,phonebookStore);
       
   414 		if(ret!=KErrNone)
       
   415 			{
       
   416 			LOGPARSERR("phonebookStore",ret,3,&KPhBkError);
       
   417 			//global phonebook error
       
   418 			continue;
       
   419 			}
       
   420 		
       
   421 		if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
       
   422 			continue;
       
   423 		else if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this phonebook
       
   424 			continue;
       
   425 
       
   426 		TPhBkError entry;
       
   427 		entry.iCount=count;
       
   428 		entry.iError=error;
       
   429 		TRAP_IGNORE(iPhBkError->AppendL(entry));
       
   430 		}
       
   431 	PopulateOOBWrite();
       
   432 	PopulateOOBDelete();
       
   433 	LOGPHBK1("...Finished reading Phonebook store entries...");
       
   434 
       
   435 	if(iPhBkOOBWriteDuration!=-1)
       
   436 		iOOBWriteTimer->Start(iPhBkOOBWriteDuration,this,ETimerIdPhBkUSimStorOOBWrite);
       
   437 	if(iPhBkOOBDeleteDuration!=-1)
       
   438 		iOOBDeleteTimer->Start(iPhBkOOBDeleteDuration,this,ETimerIdPhBkUSimStorOOBDelete);
       
   439 	}
       
   440 
       
   441 void CSimPhBkUSimStore::PopulateOOBWrite()
       
   442 /**
       
   443  * Populate the member variables required to operate the OOB Store functionality from
       
   444  * the configuration file.
       
   445  * The OOBPhBkStore configuration file tag should have the following format:
       
   446  * "OOBPhBkStore= <duration>, <phonebook name>, <index>, <telephone number>, <alpha tag>"
       
   447  */
       
   448 	{
       
   449 	TInt parseIndex=0;
       
   450 	iPhBkOOBWriteDuration=KErrNotFound;
       
   451 	const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkUSimWrite);
       
   452 	if(!item)
       
   453 		return;
       
   454 
       
   455 	TInt count;
       
   456 	TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,count);
       
   457 	if(ret!=KErrNone)
       
   458 		{
       
   459 		LOGPARSERR("count",ret,parseIndex,&KOOBPhBkUSimWrite);
       
   460 		return;
       
   461 		}
       
   462 
       
   463 	TPtrC8 phonebookStore,aid, phonebookName,alphaTag,telNum,alphaTag2,emails, groups, additional;
       
   464 	TInt index;
       
   465 	TUint8 npiTon;
       
   466 	ret=GetPhBkUSimEntry(item,parseIndex,phonebookStore,phonebookName,aid,index,telNum,alphaTag,npiTon,alphaTag2);
       
   467 	if(ret!=KErrNone)
       
   468 		{
       
   469 		LOGPARSERR("Phonebook Entry",ret,parseIndex,&KOOBPhBkUSimWrite);
       
   470 		return;
       
   471 		}
       
   472 
       
   473 	if(phonebookStore.MatchF(iPhBkStore)!=0)// Not this PhBkStore type
       
   474 		return;
       
   475 	else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
       
   476 		return;
       
   477 
       
   478 	iPhBkOOBWriteDuration=count;
       
   479 	iPhBkOOBWriteIndex=index;
       
   480 	iPhBkOOBWrite.iAlphaTag.Copy(alphaTag);
       
   481 	iPhBkOOBWrite.iTelNum.Copy(telNum);
       
   482 	iPhBkOOBWrite.iTonNpi=npiTon;
       
   483 	iPhBkOOBWrite.iAlphaTag2.Copy(alphaTag2);
       
   484 
       
   485 	ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,additional);
       
   486 	if(ret!=KErrNone)
       
   487 		{
       
   488 		LOGPARSERR("additional",ret,parseIndex,&KOOBPhBkUSimWrite);
       
   489 		}
       
   490 	else
       
   491 	{	
       
   492 		TPtrC8 myName,myNum;
       
   493 		TUint8 myTon;
       
   494 		TInt myindex=0,pIndex=0;
       
   495 		
       
   496 		TRAPD(err,iPhBkOOBWrite.iAdditional=new(ELeave) CArrayFixFlat<TPhBkStoreEntry>(iPhBkAdditional+1));
       
   497 		if (err!=KErrNone)
       
   498 			return;
       
   499 		while((GetPhBkAdditionalEntry(additional,pIndex,myNum,myName,myTon)==KErrNone)
       
   500 				&& (myindex < iPhBkAdditional))
       
   501 		{
       
   502 		TPhBkStoreEntry entry; 
       
   503 
       
   504 		entry.iAlphaTag.Copy(myName);
       
   505 		entry.iTelNum.Copy(myNum);
       
   506 		entry.iTonNpi=myTon;
       
   507 		TRAP_IGNORE(iPhBkOOBWrite.iAdditional->AppendL(entry));
       
   508 		myindex++;
       
   509 		}
       
   510 	}
       
   511 
       
   512 	ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,groups);
       
   513 	if(ret!=KErrNone)
       
   514 		{
       
   515 		LOGPARSERR("groups",ret,parseIndex,&KOOBPhBkUSimWrite);
       
   516 		}
       
   517 	else
       
   518 	{	
       
   519 		TPtrC8 mygroup;
       
   520 		TInt myindex=0;
       
   521 		
       
   522 		TRAPD(err,iPhBkOOBWrite.iGroups=new(ELeave) CArrayFixFlat<TPhBkUSimGroup>(KMaxGroups+1));
       
   523 		if (err!=KErrNone)
       
   524 			return;
       
   525 		while((CTestConfig::GetElement(groups,';',myindex,mygroup)==KErrNone) &&
       
   526 				(myindex < KMaxGroups))
       
   527 		{
       
   528 		TPhBkUSimGroup entry;
       
   529 		entry.Copy(mygroup);
       
   530 		TRAP_IGNORE(iPhBkOOBWrite.iGroups->AppendL(entry));
       
   531 		myindex++;
       
   532 		}
       
   533 	}
       
   534 
       
   535 	ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,parseIndex++,emails);
       
   536 	if(ret!=KErrNone)
       
   537 		{
       
   538 		LOGPARSERR("emails",ret,parseIndex,&KOOBPhBkUSimWrite);
       
   539 		}
       
   540 	else
       
   541 	{	
       
   542 		TPtrC8 myemail;
       
   543 		TInt myindex=0;
       
   544 		
       
   545 		TRAPD(err,iPhBkOOBWrite.iEmails=new(ELeave) CArrayFixFlat<TPhBkUSimEmail>(iPhBkMaxEmail+1));
       
   546 		if (err!=KErrNone)
       
   547 			return;
       
   548 	
       
   549 		while((CTestConfig::GetElement(emails,';',myindex,myemail)==KErrNone) &&
       
   550 				(myindex < iPhBkMaxEmail))
       
   551 		{
       
   552 		TPhBkUSimEmail entry;
       
   553 		entry.Copy(myemail);
       
   554 		TRAP_IGNORE(iPhBkOOBWrite.iEmails->AppendL(entry));
       
   555 		myindex++;
       
   556 		}
       
   557 	}
       
   558 
       
   559 	}
       
   560 
       
   561 void CSimPhBkUSimStore::PopulateOOBDelete()
       
   562 /**
       
   563  * Populate the member variables required to operate the OOB Delete functionality from
       
   564  * the configuration file.
       
   565  * The OOBPhBkDelete configuration file tag should have the following format:
       
   566  * "OOBPhBkDelete= <duration>, <phonebook name>, <index>
       
   567  */
       
   568 	{
       
   569 	iPhBkOOBDeleteDuration=KErrNotFound;
       
   570 	const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkUSimDelete);
       
   571 	if(!item)
       
   572 		return;
       
   573 
       
   574 	TInt count;
       
   575 	TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
       
   576 	if(ret!=KErrNone)
       
   577 		{
       
   578 		LOGPARSERR("count",ret,0,&KOOBPhBkUSimDelete);
       
   579 		return;
       
   580 		}
       
   581 
       
   582 	TPtrC8 phonebookName, phonebookStore;
       
   583 		
       
   584 	ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,phonebookStore);
       
   585 	if(ret!=KErrNone)
       
   586 		{
       
   587 		LOGPARSERR("phonebookStore",ret,1,&KOOBPhBkUSimDelete);
       
   588 		return;
       
   589 		}
       
   590 
       
   591 	ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,phonebookName);
       
   592 	if(ret!=KErrNone)
       
   593 		{
       
   594 		LOGPARSERR("phonebookName",ret,2,&KOOBPhBkUSimDelete);
       
   595 		return;
       
   596 		}
       
   597 
       
   598 	if(phonebookStore.MatchF(iPhBkStore)!=0)
       
   599 		return;						// Not this store
       
   600 	else if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
       
   601 		return;
       
   602 
       
   603 	TInt index;
       
   604 	ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,index);
       
   605 	if(ret!=KErrNone)
       
   606 		{
       
   607 		LOGPARSERR("index",ret,3,&KOOBPhBkUSimDelete);
       
   608 		return;
       
   609 		}
       
   610 
       
   611 	iPhBkOOBDeleteDuration=count;
       
   612 	iPhBkOOBDeleteIndex=index;
       
   613 	}
       
   614 
       
   615 
       
   616 TInt CSimPhBkUSimStore::GetPhBkUSimEntry(const CTestConfigItem* aItem, TInt& aItemIndex,
       
   617 								 TPtrC8& aPhonebookStore, 
       
   618 								 TPtrC8& aPhonebookName, 
       
   619 								 TPtrC8& aAid,TInt& aIndex,
       
   620 								 TPtrC8& aTelNum, TPtrC8& aAlphaTag, TUint8& aNpiTon,
       
   621 								 TPtrC8& aAlphaTag2)
       
   622 /**
       
   623  * Retrieve a phonebook entry from the configuration file, starting at a given item index
       
   624  * value.
       
   625  * @param aItem				Pointer to the config file item from which the phonebook entry will be read.
       
   626  * @param aItemIndex		The index number within the item from which the phonebook entry will be read.
       
   627  * @param aPhonebookName	The returned phonebook name
       
   628  * @param aIndex			The returned index number
       
   629  * @param aTelNum			The returned telephone number
       
   630  * @param aAlphaTag			The returned alpha tag
       
   631  * @param aNpiTon			The returned Number Plan Identifier and Type of Number information
       
   632  * @return TInt				Standard error value.
       
   633  */
       
   634 	{
       
   635 	TInt ret;
       
   636 	
       
   637 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aPhonebookStore);
       
   638 	if(ret!=KErrNone)
       
   639 		return ret;
       
   640 
       
   641 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aPhonebookName);
       
   642 	if(ret!=KErrNone)
       
   643 		return ret;
       
   644 
       
   645 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAid);
       
   646 	if(ret!=KErrNone)
       
   647 		return ret;
       
   648 
       
   649 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aIndex);
       
   650 	if(ret!=KErrNone)
       
   651 		return ret;
       
   652 
       
   653 	if(aIndex>iPhBkMaxNumSlots) //the max number of slot is a valid slot
       
   654 		return KErrArgument;
       
   655 
       
   656 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aTelNum);
       
   657 	if(ret!=KErrNone)
       
   658 		return ret;
       
   659 	if(aTelNum.Length()>iPhBkMaxTelNumLen)
       
   660 		return EXTENDEDERROR(KErrArgument, KErrPhonebookNumberOverflow);
       
   661 
       
   662 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag);
       
   663 	if(ret!=KErrNone)
       
   664 		return ret;
       
   665 	if(aAlphaTag.Length()>iPhBkMaxTextLen)
       
   666 		return EXTENDEDERROR(KErrArgument, KErrPhonebookTextOverflow);
       
   667 
       
   668 	if((aTelNum.Length()>0) && (aTelNum[0]=='+'))
       
   669 		{
       
   670 		aTelNum.Set(aTelNum.Mid(1));
       
   671 		aNpiTon=KNpiTonInternational;
       
   672 		}
       
   673 	else
       
   674 		aNpiTon=KNpiTonNational;
       
   675 
       
   676 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag2);
       
   677 	if(ret!=KErrNone)
       
   678 		return ret;
       
   679 	if(aAlphaTag.Length()>iPhBkMaxTextLen)
       
   680 		return EXTENDEDERROR(KErrArgument, KErrPhonebookTextOverflow);
       
   681 
       
   682 	return ret;
       
   683 	}
       
   684 
       
   685 TInt CSimPhBkUSimStore::GetPhBkAdditionalEntry(TPtrC8& aEntry, TInt& aItemIndex,
       
   686 								 TPtrC8& aTelNum, TPtrC8& aAlphaTag, TUint8& aNpiTon)
       
   687 /**
       
   688  * Retrieve a phonebook entry from the configuration file, starting at a given item index
       
   689  * value.
       
   690  * @param aItem				Pointer to the config file item from which the phonebook entry will be read.
       
   691  * @param aItemIndex		The index number within the item from which the phonebook entry will be read.
       
   692  * @param aTelNum			The returned telephone number
       
   693  * @param aAlphaTag			The returned alpha tag
       
   694  * @param aNpiTon			The returned Number Plan Identifier and Type of Number information
       
   695  * @return TInt				Standard error value.
       
   696  */
       
   697 	{
       
   698 	TInt ret;
       
   699 
       
   700 	ret=CTestConfig::GetElement(aEntry,';',aItemIndex++,aAlphaTag);
       
   701 	if(ret!=KErrNone)
       
   702 		return ret;
       
   703 	
       
   704 	if(aAlphaTag.Length()>iPhBkMaxAdditionalTextLen)
       
   705 		return EXTENDEDERROR(KErrArgument, KErrPhonebookAdditionalNumberAlphaTextOverflow);
       
   706 
       
   707 	ret=CTestConfig::GetElement(aEntry,';',aItemIndex++,aTelNum);
       
   708 	if(ret!=KErrNone)
       
   709 		return ret;
       
   710 	if(aTelNum.Length()>iPhBkMaxAdditionalTelNumLen)
       
   711 		return EXTENDEDERROR(KErrArgument, KErrPhonebookAdditionalNumberNumberOverflow);
       
   712 
       
   713 		
       
   714 	if((aTelNum.Length()>0) && (aTelNum[0]=='+'))
       
   715 		{
       
   716 		aTelNum.Set(aTelNum.Mid(1));
       
   717 		aNpiTon=KNpiTonInternational;
       
   718 		}
       
   719 	else
       
   720 		{
       
   721 		aNpiTon=KNpiTonNational;
       
   722 		}
       
   723 		
       
   724 	return ret;
       
   725 	}
       
   726 
       
   727 CSimPhBkUSimStore::~CSimPhBkUSimStore()
       
   728 /**
       
   729  * Standard destructor.  Any objects created by the ::ConstructL() function
       
   730  * will be destroyed here.
       
   731  */
       
   732 	{
       
   733 
       
   734 	for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
       
   735 		{
       
   736 			if(iPhBkUSim1StoreEntries[i].iTelNum.Length()>0 ||
       
   737 				iPhBkUSim1StoreEntries[i].iAlphaTag.Length()>0)
       
   738 			{
       
   739 				iPhBkUSim1StoreEntries[i].iTelNum.Zero();
       
   740 				if((iPhBkUSim1StoreEntries[i].iAdditional!=NULL)
       
   741 					&& ((TUint)iPhBkUSim1StoreEntries[i].iAdditional!=DELETED))
       
   742 				{
       
   743 					if(iPhBkUSim1StoreEntries[i].iAdditional->Count()>=0)
       
   744 					{
       
   745 						iPhBkUSim1StoreEntries[i].iAdditional->Delete(0,iPhBkUSim1StoreEntries[i].iAdditional->Count());
       
   746 						delete iPhBkUSim1StoreEntries[i].iAdditional;
       
   747 					}
       
   748 				}
       
   749 				if((iPhBkUSim1StoreEntries[i].iGroups!=NULL)
       
   750 					&& ((TUint)iPhBkUSim1StoreEntries[i].iGroups!=DELETED))
       
   751 				{
       
   752 					if(iPhBkUSim1StoreEntries[i].iGroups->Count()>=0)
       
   753 					{
       
   754 						iPhBkUSim1StoreEntries[i].iGroups->Delete(0,iPhBkUSim1StoreEntries[i].iGroups->Count());
       
   755 						delete iPhBkUSim1StoreEntries[i].iGroups;
       
   756 					}
       
   757 				}
       
   758 				if((iPhBkUSim1StoreEntries[i].iEmails!=NULL)	
       
   759 					&& ((TUint)iPhBkUSim1StoreEntries[i].iEmails!=DELETED))
       
   760 				{
       
   761 					if(iPhBkUSim1StoreEntries[i].iEmails->Count()>=0)
       
   762 					{
       
   763 						iPhBkUSim1StoreEntries[i].iEmails->Delete(0,iPhBkUSim1StoreEntries[i].iEmails->Count());
       
   764 						delete iPhBkUSim1StoreEntries[i].iEmails;
       
   765 					}
       
   766 				}
       
   767 			}
       
   768 		if(iPhBkUSim2StoreEntries!=NULL &&
       
   769 			(iPhBkUSim2StoreEntries[i].iTelNum.Length()>0 ||
       
   770 				iPhBkUSim2StoreEntries[i].iAlphaTag.Length()>0))
       
   771 		{
       
   772 			iPhBkUSim2StoreEntries[i].iTelNum.Zero();
       
   773 			if((iPhBkUSim2StoreEntries[i].iAdditional!=NULL)	
       
   774 				&& ((TUint)iPhBkUSim2StoreEntries[i].iAdditional!=DELETED))
       
   775 			{
       
   776 				if(iPhBkUSim2StoreEntries[i].iAdditional->Count()>=0)
       
   777 				{
       
   778 					iPhBkUSim2StoreEntries[i].iAdditional->Delete(0,iPhBkUSim2StoreEntries[i].iAdditional->Count());
       
   779 					delete iPhBkUSim2StoreEntries[i].iAdditional;
       
   780 				}
       
   781 			}
       
   782 			if((iPhBkUSim2StoreEntries[i].iGroups!=NULL)
       
   783 				&& ((TUint)iPhBkUSim2StoreEntries[i].iGroups!=DELETED))
       
   784 			{
       
   785 				if(iPhBkUSim2StoreEntries[i].iGroups->Count()>=0)
       
   786 				{
       
   787 					iPhBkUSim2StoreEntries[i].iGroups->Delete(0,iPhBkUSim2StoreEntries[i].iGroups->Count());
       
   788 					delete iPhBkUSim2StoreEntries[i].iGroups;
       
   789 				}
       
   790 			}
       
   791 			if((iPhBkUSim2StoreEntries[i].iEmails!=NULL)
       
   792 				&& ((TUint)iPhBkUSim2StoreEntries[i].iEmails!=DELETED))
       
   793 			{
       
   794 				if(iPhBkUSim2StoreEntries[i].iEmails->Count()>=0)
       
   795 				{
       
   796 					iPhBkUSim2StoreEntries[i].iEmails->Delete(0,iPhBkUSim2StoreEntries[i].iEmails->Count());
       
   797 					delete iPhBkUSim2StoreEntries[i].iEmails;	
       
   798 				}
       
   799 			}
       
   800 		}
       
   801 	}	
       
   802 	
       
   803 	if((iPhBkOOBWrite.iAdditional!=NULL)
       
   804 		&& ((TUint)iPhBkOOBWrite.iAdditional!=DELETED))
       
   805 	{
       
   806 		iPhBkOOBWrite.iAdditional->Delete(0,iPhBkOOBWrite.iAdditional->Count());
       
   807 		delete iPhBkOOBWrite.iAdditional;
       
   808 	}
       
   809 	if((iPhBkOOBWrite.iGroups!=NULL)
       
   810 		&& ((TUint)iPhBkOOBWrite.iGroups!=DELETED))
       
   811 	{
       
   812 		iPhBkOOBWrite.iGroups->Delete(0,iPhBkOOBWrite.iGroups->Count());
       
   813 		delete iPhBkOOBWrite.iGroups;
       
   814 	}
       
   815 	if((iPhBkOOBWrite.iEmails!=NULL)
       
   816 		&& ((TUint)iPhBkOOBWrite.iEmails!=DELETED))
       
   817 	{
       
   818 		iPhBkOOBWrite.iEmails->Delete(0,iPhBkOOBWrite.iEmails->Count());
       
   819 		delete iPhBkOOBWrite.iEmails;
       
   820 	}
       
   821 	delete[] iPhBkUSim1StoreEntries;
       
   822 	delete[] iPhBkUSim2StoreEntries;
       
   823 	delete iPhBkError;
       
   824 	delete iPhBkRwBuffer;
       
   825 	delete iOOBWriteTimer;
       
   826 	delete iOOBDeleteTimer;
       
   827 	delete iReqTimer;
       
   828 
       
   829 	}
       
   830 
       
   831 TInt CSimPhBkUSimStore::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
       
   832 /**
       
   833  * Dispatch function for all Phonebook Store requests.
       
   834  * @param aReqHandle	The TSY request handle for this request.
       
   835  * @param aIpc			The IPC number of this request.
       
   836  * @param aPckg			The parameter package related to this request.
       
   837  * @return TInt			The return error condition.
       
   838  */
       
   839 	{
       
   840 	iIpcCnt++;
       
   841 	TInt error=KErrNone;
       
   842 	if(FindIpcErrorMatch(error))
       
   843 		{
       
   844 		ReqCompleted(aReqHandle,error);
       
   845 		return KErrNone;
       
   846 		}
       
   847 
       
   848 // The following requests can be completed even if the completion of another request is pending.
       
   849 	switch(aIpc)
       
   850 		{
       
   851 	case EMobilePhoneStoreGetInfo:
       
   852 		error = GetInfo(aReqHandle,aPckg.Des1n());
       
   853 		if(iTriggerEventIPC.iIPC==aIpc)
       
   854 			{
       
   855 			iTriggerCnt++;
       
   856 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   857 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   858 			}
       
   859 		return error;
       
   860 
       
   861 	case EMobilePhoneStoreNotifyStoreEvent:
       
   862 		error = NotifyStoreEvent(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
       
   863 		if(iTriggerEventIPC.iIPC==aIpc)
       
   864 			{
       
   865 			iTriggerCnt++;
       
   866 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   867 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   868 			}
       
   869 		return error;
       
   870 
       
   871 	default:
       
   872 		break;
       
   873 		}
       
   874 
       
   875 
       
   876 // The TSY can only process one of the following requests at a time.  If a second is received
       
   877 // while processing the first, then it will be errored with KErrInUse.  This restriction will
       
   878 // be removed later, by inserting a request queuing mechanism.  Note that the standard TSY
       
   879 // "flow control" mechanism works phone-wide and so is not suitable.
       
   880 
       
   881 	if(iReqTimer->IsActive())
       
   882 		{
       
   883 		ReqCompleted(aReqHandle,KErrInUse);
       
   884 		return KErrNone;
       
   885 		}
       
   886 
       
   887 	switch(aIpc)
       
   888 		{
       
   889 // The standard multimode store read and write are not supported.
       
   890 	case EMobilePhoneStoreRead:
       
   891 	case EMobilePhoneStoreWrite:
       
   892 	case EMobilePhoneStoreReadAllPhase1:
       
   893 	case EMobilePhoneStoreReadAllPhase2:
       
   894 		ReqCompleted(aReqHandle,KErrNotSupported);
       
   895 		return KErrNone;
       
   896 
       
   897 	case EMobilePhoneBookStoreRead:
       
   898 		 error = Read(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
       
   899 		 if(iTriggerEventIPC.iIPC==aIpc)
       
   900 			{
       
   901 			iTriggerCnt++;
       
   902 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   903 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   904 			}
       
   905 		 return error;
       
   906 			
       
   907 	case EMobilePhoneBookStoreWrite:
       
   908 		error = Write(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
       
   909 		if(iTriggerEventIPC.iIPC==aIpc)
       
   910 			{
       
   911 			iTriggerCnt++;
       
   912 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   913 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   914 			}
       
   915 		 return error;
       
   916 
       
   917 	case EMobilePhoneStoreDelete:
       
   918 		error =  Delete(aReqHandle,aPckg.Des1n());
       
   919 		if(iTriggerEventIPC.iIPC==aIpc)
       
   920 			{
       
   921 			iTriggerCnt++;
       
   922 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   923 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   924 			}
       
   925 		 return error;
       
   926 
       
   927 	case EMobilePhoneStoreDeleteAll:
       
   928 		error =  DeleteAll(aReqHandle);
       
   929 		if(iTriggerEventIPC.iIPC==aIpc)
       
   930 			{
       
   931 			iTriggerCnt++;
       
   932 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   933 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   934 			}
       
   935 		 return error;
       
   936 
       
   937 	default:
       
   938 		break;
       
   939 		}
       
   940 
       
   941 	return KErrNotSupported;
       
   942 	}
       
   943 
       
   944 CTelObject* CSimPhBkUSimStore::OpenNewObjectByNameL(const TDesC& /*aName*/)
       
   945 /**
       
   946  * The API does not support any objects that could be opened from this one.
       
   947  */
       
   948 	{
       
   949 	User::Leave(KErrNotSupported);
       
   950 	return NULL;
       
   951 	}
       
   952 
       
   953 CTelObject* CSimPhBkUSimStore::OpenNewObjectL(TDes&)
       
   954 /**
       
   955  * The API does not support any objects that could be opened from this one.
       
   956  */
       
   957 	{
       
   958 	User::Leave(KErrNotSupported);
       
   959 	return NULL;
       
   960 	}
       
   961 
       
   962 CTelObject::TReqMode CSimPhBkUSimStore::ReqModeL(const TInt aIpc)
       
   963 /**
       
   964  * This function returns the Request Mode for the request with the passed IPC value.
       
   965  * @param aIpc		The IPC number of the request.
       
   966  * @return TReqMode	The request mode.
       
   967  */
       
   968 	{
       
   969 	CTelObject::TReqMode ret=0;	
       
   970 
       
   971 	switch(aIpc)
       
   972 		{
       
   973 	case EMobilePhoneStoreGetInfo:
       
   974 	case EMobilePhoneStoreDelete:
       
   975 	case EMobilePhoneStoreDeleteAll:
       
   976 	case EMobilePhoneBookStoreRead:
       
   977 	case EMobilePhoneBookStoreWrite:
       
   978 		break;
       
   979 
       
   980 	case EMobilePhoneStoreNotifyStoreEvent:
       
   981 		ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
       
   982 		break;
       
   983 
       
   984 	default:
       
   985 		User::Leave(KErrNotSupported);
       
   986 		break;
       
   987 		}
       
   988 
       
   989 	return ret;
       
   990 	}
       
   991 
       
   992 TInt CSimPhBkUSimStore::RegisterNotification(const TInt /*aIpc*/)
       
   993 /**
       
   994  * The ETel Server calls this function when the first client makes a notification
       
   995  * request.  If supported by the underlying protocol controlling the
       
   996  * signalling stack, this can be used to start requesting updates for the relevant
       
   997  * service.
       
   998  */
       
   999 	{
       
  1000 	return KErrNone;
       
  1001 	}
       
  1002 
       
  1003 TInt CSimPhBkUSimStore::DeregisterNotification(const TInt /*aIpc*/)
       
  1004 /**
       
  1005  * The ETel Server calls this function when the last client that had previously
       
  1006  * made a notification request closes its ETel Server handle.  If supported by
       
  1007  * the underlying protocol controlling the	signalling stack, this can be used
       
  1008  * to stop requesting updates for the relevant service.
       
  1009  */
       
  1010 	{
       
  1011 	return KErrNone;
       
  1012 	}
       
  1013 
       
  1014 TInt CSimPhBkUSimStore::NumberOfSlotsL(const TInt /*aIpc*/)
       
  1015 /**
       
  1016  * Return the number of slots that the ETel Server should allocate for buffering requests
       
  1017  * of the given IPC number.
       
  1018  */
       
  1019 	{
       
  1020 	return KDefaultNumberOfSlots;
       
  1021 	}
       
  1022 
       
  1023 TInt CSimPhBkUSimStore::CancelService(const TInt aIpc,const TTsyReqHandle /*aTsyReqHandle*/)
       
  1024 /**
       
  1025  * Cancel an outstanding request.
       
  1026  * @param aIpc			The IPC number of the request that is to be cancelled.
       
  1027  * @param aTsyReqHandle	The TSY request handle of the request that is to be cancelled.
       
  1028  * @param TInt			Standard return value.
       
  1029  */
       
  1030 	{
       
  1031 	switch(aIpc)
       
  1032 		{
       
  1033 	case EMobilePhoneStoreGetInfo:
       
  1034 	case EMobilePhoneStoreDelete:
       
  1035 	case EMobilePhoneStoreDeleteAll:
       
  1036 	case EMobilePhoneBookStoreRead:
       
  1037 	case EMobilePhoneBookStoreWrite:
       
  1038 		break;
       
  1039 
       
  1040 	case EMobilePhoneStoreNotifyStoreEvent:
       
  1041 		NotifyStoreEventCancel();
       
  1042 		break;
       
  1043 
       
  1044 	default:
       
  1045 		break;
       
  1046 		}
       
  1047 	return KErrNone;
       
  1048 	}
       
  1049 
       
  1050 void CSimPhBkUSimStore::Init()
       
  1051 /**
       
  1052  *	This function can be used to perform any necessary synchronous initialisation.
       
  1053  */
       
  1054 	{
       
  1055 	}
       
  1056 
       
  1057 TInt CSimPhBkUSimStore::GetInfo(TTsyReqHandle aReqHandle, TDes8* aPckg)
       
  1058 /**
       
  1059  * Retrieve Phonebook Store information. This request is completed immediately, as it is assumed
       
  1060  * that in a real TSY, all this data will be cached in the TSY.
       
  1061  *
       
  1062  * @param aReqHandle	The TSY request handle associated with this request.
       
  1063  * @param aPckg			The parameter package associated with this request.
       
  1064  */
       
  1065 	{
       
  1066 	if(iPhone->IsICCLocked()!=EFalse)
       
  1067 		{
       
  1068 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1069 		return KErrNone;
       
  1070 		}
       
  1071 
       
  1072 	if(CheckAndSwitchUSimApps()!=KErrNone)
       
  1073 		{
       
  1074 		ReqCompleted(aReqHandle, KErrNotFound);
       
  1075 		return KErrNone;
       
  1076 		}
       
  1077 
       
  1078 	RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg* getInfoPckg=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg*)aPckg;
       
  1079 	RMobilePhoneBookStore::TMobilePhoneBookInfoV1& getInfo=(*getInfoPckg)();
       
  1080 
       
  1081 	PopulatePhBkStoreInfo(&getInfo);
       
  1082 
       
  1083 	if(&getInfo!=NULL) // NULL will have been assigned by PopulatePhBkStoreInfo if the version checking failed.
       
  1084 		{
       
  1085 		ReqCompleted(aReqHandle,KErrNone);
       
  1086 		}
       
  1087 	else
       
  1088 		{
       
  1089 		ReqCompleted(aReqHandle,KErrNotSupported);
       
  1090 		}
       
  1091 	
       
  1092 	return KErrNone;
       
  1093 	}
       
  1094 
       
  1095 void CSimPhBkUSimStore::PopulatePhBkStoreInfo(RMobilePhoneStore::TMobilePhoneStoreInfoV1* aStoreInfo)
       
  1096 /**
       
  1097  * Populate the passed parameter with Phonebook Store information.
       
  1098  * @param aStoreInfo	Pointer to phonebook store information structure to be populated.
       
  1099  */
       
  1100 	{
       
  1101 	__ASSERT_ALWAYS(aStoreInfo, SimPanic(EIllegalNullPtrParameter));
       
  1102 	
       
  1103 	aStoreInfo->iType=RMobilePhoneStore::EPhoneBookStore;
       
  1104 	aStoreInfo->iTotalEntries=MaxSlots();
       
  1105 	aStoreInfo->iCaps=iPhBkStoreCaps;
       
  1106 	aStoreInfo->iName.Copy(iPhBkStoreName);
       
  1107 	aStoreInfo->iUsedEntries=UsedEntries();
       
  1108 	
       
  1109 	if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV1)
       
  1110 		{
       
  1111 		RMobilePhoneBookStore::TMobilePhoneBookInfoV1* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1*)aStoreInfo;
       
  1112 
       
  1113 		// Check that the data structure is supported by the simulated TSY version
       
  1114 		TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
       
  1115 		if(err != KErrNone)
       
  1116 			{
       
  1117 			getExtraInfo = NULL;
       
  1118 			return;
       
  1119 			}
       
  1120 
       
  1121 		getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
       
  1122 		getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
       
  1123 		getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
       
  1124 		getExtraInfo->iChangeCounter=0;
       
  1125 		getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
       
  1126 		}
       
  1127 	else if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV2)
       
  1128 		{
       
  1129 		RMobilePhoneBookStore::TMobilePhoneBookInfoV2* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV2*)aStoreInfo;
       
  1130 
       
  1131 		// Check that the data structure is supported by the simulated TSY version
       
  1132 		TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
       
  1133 		if(err != KErrNone)
       
  1134 			{
       
  1135 			getExtraInfo = NULL;
       
  1136 			return;
       
  1137 			}
       
  1138 
       
  1139 		getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
       
  1140 		getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
       
  1141 		getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
       
  1142 		getExtraInfo->iChangeCounter=0;
       
  1143 		getExtraInfo->iIdentity.Zero();		
       
  1144 
       
  1145 		getExtraInfo->iPhBkMode.Copy(PhBkStore());		
       
  1146 	
       
  1147 		if(PhBkStore().Compare(KUSimPhoneBook)!=KErrNone)
       
  1148 			{
       
  1149 			getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
       
  1150 			}
       
  1151 		else
       
  1152 			{
       
  1153 			TPtrC8 USimId(iPhone->GetActiveUSim().Right(1));
       
  1154 			getExtraInfo->iIdentity.Copy(USimId);
       
  1155 			getExtraInfo->iIdentity.Append(iPhone->GetImsi());
       
  1156 			}
       
  1157 		}
       
  1158 	else if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV5)
       
  1159 		{
       
  1160 		RMobilePhoneBookStore::TMobilePhoneBookInfoV5* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV5*)aStoreInfo;
       
  1161 
       
  1162 		// Check that the data structure is supported by the simulated TSY version
       
  1163 		TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
       
  1164 		if(err != KErrNone)
       
  1165 			{
       
  1166 			getExtraInfo = NULL;
       
  1167 			return;
       
  1168 			}
       
  1169 
       
  1170 		getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
       
  1171 		getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
       
  1172 		getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
       
  1173 		getExtraInfo->iChangeCounter=0;
       
  1174 		getExtraInfo->iIdentity.Zero();		
       
  1175 
       
  1176 		getExtraInfo->iPhBkMode.Copy(PhBkStore());
       
  1177 
       
  1178 		getExtraInfo->iMaxSecondNames = KMaxSecondNames;
       
  1179 		getExtraInfo->iMaxTextLengthSecondName = iPhBkMaxTextLen;
       
  1180 		getExtraInfo->iMaxAdditionalNumbers = iPhBkAdditional;
       
  1181 		getExtraInfo->iMaxTextLengthAdditionalNumber = iPhBkMaxAdditionalTextLen;
       
  1182 		getExtraInfo->iMaxNumLengthAdditionalNumber = iPhBkMaxAdditionalTelNumLen;
       
  1183 		getExtraInfo->iMaxGroupNames = KMaxGroups;
       
  1184 		getExtraInfo->iMaxTextLengthGroupName = iPhBkMaxTextLen;
       
  1185 		getExtraInfo->iMaxEmailAddr = iPhBkMaxEmail;
       
  1186 		getExtraInfo->iMaxTextLengthEmailAddr = iPhBkMaxTextLen;
       
  1187 	
       
  1188 		if(PhBkStore().Compare(KUSimPhoneBook)!=KErrNone)
       
  1189 			{
       
  1190 			getExtraInfo->iIdentity.Copy(iPhone->GetImsi());			
       
  1191 			}
       
  1192 		else
       
  1193 			{
       
  1194 			TPtrC8 USimId(iPhone->GetActiveUSim().Right(1));
       
  1195 			getExtraInfo->iIdentity.Copy(USimId);
       
  1196 			getExtraInfo->iIdentity.Append(iPhone->GetImsi());
       
  1197 			}
       
  1198 		}	
       
  1199 	}
       
  1200 
       
  1201 TInt CSimPhBkUSimStore::Read(TTsyReqHandle aReqHandle, TDes8* aPckg1,TDes8* aPckg2)
       
  1202 /**
       
  1203  * Read Phonebook store entries.  The completion of this request is delayed in order to
       
  1204  * simulate a real TSY that would have to go and get the information from a SIM card.
       
  1205  *
       
  1206  * @param aReqHandle	The TSY request handle associated with this request.
       
  1207  * @param aPckg1		The first parameter package associated with this request.
       
  1208  *						It contains the index from which the read should start and
       
  1209  *						the number of entries which should be read.
       
  1210  * @param aPckg2		The second parameter package associated with this request.
       
  1211  *						It contains the buffer, which will be populated with the retrieved
       
  1212  *						values.
       
  1213  * @return TInt			Standard return value.
       
  1214  */
       
  1215 	{
       
  1216 	if(CheckAndSwitchUSimApps()!=KErrNone)
       
  1217 		{
       
  1218 		ReqCompleted(aReqHandle, KErrNotFound);
       
  1219 		return KErrNone;
       
  1220 		}
       
  1221 
       
  1222 	if(iPhone->IsICCLocked()!=EFalse)
       
  1223 		{
       
  1224 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1225 		return KErrNone;
       
  1226 		}
       
  1227 
       
  1228 	TPckg<RMobilePhoneBookStore::TPBIndexAndNumEntries>* indexNumPckg=(TPckg<RMobilePhoneBookStore::TPBIndexAndNumEntries>*)aPckg1;
       
  1229 	RMobilePhoneBookStore::TPBIndexAndNumEntries& indexNum=(*indexNumPckg)();
       
  1230 
       
  1231 	if(indexNum.iNumSlots==iPhBkMaxNumSlots)
       
  1232 		{
       
  1233 		if (!(iPhBkStoreCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsReadAccess))
       
  1234 			{
       
  1235 			ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1236 			return KErrNone;
       
  1237 			}
       
  1238 		}
       
  1239 	else if((indexNum.iIndex+indexNum.iNumSlots-1)>iPhBkMaxNumSlots)
       
  1240 			{
       
  1241 			ReqCompleted(aReqHandle,KErrArgument);
       
  1242 			return KErrNone;
       
  1243 			}
       
  1244 	else if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsReadAccess))
       
  1245 			{
       
  1246 			ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1247 			return KErrNone;
       
  1248 			}
       
  1249 
       
  1250 	iPhBkRwBuffer->Set(aPckg2);
       
  1251 
       
  1252 	TInt cnt=0;
       
  1253 	TInt ret=0;
       
  1254 	TBool partial=EFalse;
       
  1255 	TBool onlyHidden=EFalse;
       
  1256 
       
  1257 	for(TInt i=indexNum.iIndex;i<=iPhBkMaxNumSlots;i++)
       
  1258 		{
       
  1259 		if((iPhBkUSimStoreEntries[i].iTelNum.Length()!=0)||(iPhBkUSimStoreEntries[i].iAlphaTag.Length()!=0))
       
  1260 			{				
       
  1261 			ret=iPhBkRwBuffer->AddNewEntryTag();
       
  1262 			if(ret!=KErrNone)
       
  1263 				break;
       
  1264 			
       
  1265 			if((iPhone->IsHiddenEnabled()!=EFalse) &&
       
  1266 				iPhBkUSimStoreEntries[i].iHiddenEntry==1)
       
  1267 				{
       
  1268 				//This is a hidden entry, the key is required and is currently locked
       
  1269 				//Therefore, the client should be notified that the slot has been occupied by a hidden entry
       
  1270 
       
  1271 				partial=ETrue;
       
  1272 				ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i);
       
  1273 				if(ret!=KErrNone)
       
  1274 					break;
       
  1275 				ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBHiddenInfo,(TUint8) iPhBkUSimStoreEntries[i].iHiddenEntry);
       
  1276 				if(ret!=KErrNone)
       
  1277 					break;
       
  1278 				partial=EFalse;
       
  1279 				onlyHidden=ETrue;
       
  1280 				break;
       
  1281 				}
       
  1282 
       
  1283 			partial=ETrue;
       
  1284 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i);
       
  1285 			if(ret!=KErrNone)
       
  1286 				break;
       
  1287 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,iPhBkUSimStoreEntries[i].iAlphaTag);
       
  1288 			if(ret!=KErrNone)
       
  1289 				break;
       
  1290 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,iPhBkUSimStoreEntries[i].iTonNpi);
       
  1291 			if(ret!=KErrNone)
       
  1292 				break;
       
  1293 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,iPhBkUSimStoreEntries[i].iTelNum);
       
  1294 			if(ret!=KErrNone)
       
  1295 				break;
       
  1296 	
       
  1297 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBSecondName,iPhBkUSimStoreEntries[i].iAlphaTag2);
       
  1298 			if(ret!=KErrNone)
       
  1299 				break;
       
  1300 
       
  1301 			TInt EmailCount = iPhBkUSimStoreEntries[i].iEmails->Count();
       
  1302 			TInt GroupCount = iPhBkUSimStoreEntries[i].iGroups->Count();
       
  1303 			TInt AnrCount = iPhBkUSimStoreEntries[i].iAdditional->Count();
       
  1304 			TInt j;
       
  1305 
       
  1306 			TBool corrupt=EFalse;
       
  1307 
       
  1308 			for(j=0; j<AnrCount; j++)
       
  1309 				{
       
  1310 				TPhBkStoreEntry entry = iPhBkUSimStoreEntries[i].iAdditional->At(j);
       
  1311 				
       
  1312 				corrupt=ETrue;
       
  1313 
       
  1314 				ret=iPhBkRwBuffer->AddNewNumberTag();
       
  1315 				if(ret!=KErrNone)
       
  1316 					break;
       
  1317 				
       
  1318 				ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,entry.iAlphaTag);
       
  1319 				if(ret!=KErrNone)
       
  1320 					break;
       
  1321 						
       
  1322 				ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,entry.iTelNum);
       
  1323 				if(ret!=KErrNone)
       
  1324 					break;
       
  1325 
       
  1326 				ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,entry.iTonNpi);
       
  1327 				if(ret!=KErrNone)
       
  1328 					break;
       
  1329 
       
  1330 				corrupt=EFalse;
       
  1331 				}			
       
  1332 			if(corrupt)
       
  1333 				break;
       
  1334 
       
  1335 			for(j=0; j<EmailCount; j++)
       
  1336 				{
       
  1337 				TPhBkUSimEmail entry = iPhBkUSimStoreEntries[i].iEmails->At(j);
       
  1338 				
       
  1339 				corrupt=ETrue;
       
  1340 				ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBEmailAddress,entry);
       
  1341 				if(ret!=KErrNone)
       
  1342 					break;
       
  1343 				corrupt=EFalse;
       
  1344 				}			
       
  1345 			if(corrupt)
       
  1346 				break;
       
  1347 			
       
  1348 			for(j=0; j<GroupCount; j++)
       
  1349 				{
       
  1350 				TPhBkUSimGroup entry = iPhBkUSimStoreEntries[i].iGroups->At(j);
       
  1351 				
       
  1352 				corrupt=ETrue;
       
  1353 				ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBGroupName,entry);
       
  1354 				if(ret!=KErrNone)
       
  1355 					break;
       
  1356 				corrupt=EFalse;
       
  1357 				}			
       
  1358 			if(corrupt)
       
  1359 				break;
       
  1360 
       
  1361 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBHiddenInfo,(TUint8) iPhBkUSimStoreEntries[i].iHiddenEntry);
       
  1362 			if(ret!=KErrNone)
       
  1363 				break;
       
  1364 
       
  1365 			partial=EFalse;
       
  1366 			onlyHidden=ETrue;
       
  1367 			if(++cnt>=indexNum.iNumSlots)
       
  1368 				break;
       
  1369 			}
       
  1370 		}
       
  1371 	if(partial)
       
  1372 		// EXPORT - but return value not relevant
       
  1373 		(void)iPhBkRwBuffer->RemovePartialEntry();
       
  1374 
       
  1375 	indexNum.iNumSlots=cnt;
       
  1376 	
       
  1377 	if((cnt==0)&&(partial))
       
  1378 		ReqCompleted(aReqHandle,KErrArgument);		// An entry was found, but the buffer was too small to return it.
       
  1379 	else if((cnt==0)&&(!partial)&&(!onlyHidden))
       
  1380 		ReqCompleted(aReqHandle,KErrNotFound);		// No entries found.
       
  1381 	else if((cnt==0)&&(!partial)&&(onlyHidden))
       
  1382 		ReqCompleted(aReqHandle,KErrAccessDenied);
       
  1383 	else
       
  1384 		ReqCompleted(aReqHandle,KErrNone);
       
  1385 
       
  1386 	return KErrNone;
       
  1387 	}
       
  1388 
       
  1389 TInt CSimPhBkUSimStore::Write(TTsyReqHandle aReqHandle,TDes8* aPckg1,TDes8* aPckg2)
       
  1390 /**
       
  1391  * Write a phonebook store entries.  The completion of this request is delayed in order to
       
  1392  * simulate a real TSY that would have to write the information to a SIM card. A store
       
  1393  * event may be triggered by this request.
       
  1394  *
       
  1395  * @param aReqHandle	The TSY request handle associated with this request.
       
  1396  * @param aPckg1		The first parameter package associated with this request.
       
  1397  *						This contains the TLV phonebook entry to be written.
       
  1398  * @param aPckg2		The second parameter package associated with this request.
       
  1399  *						This contains the slot index number to which the entry must be written.
       
  1400  */
       
  1401 	{
       
  1402 	if(CheckAndSwitchUSimApps()!=KErrNone)
       
  1403 		{
       
  1404 		ReqCompleted(aReqHandle, KErrNotFound);
       
  1405 		return KErrNone;
       
  1406 		}
       
  1407 
       
  1408 	if(iPhone->IsICCLocked()!=EFalse)
       
  1409 		{
       
  1410 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1411 		return KErrNone;
       
  1412 		}
       
  1413 	
       
  1414 	if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
       
  1415 		{
       
  1416 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1417 		return KErrNone;
       
  1418 		}
       
  1419 
       
  1420 	TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg2;
       
  1421 	TInt& index=(*indexPckg)();
       
  1422 
       
  1423 // If the index is -1, then use the first available free slot.
       
  1424 	if(index==-1)
       
  1425 		{
       
  1426 		for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
       
  1427 			{
       
  1428 			if((iPhBkUSimStoreEntries[i].iTelNum.Length()==0)&&(iPhBkUSimStoreEntries[i].iAlphaTag.Length()==0))
       
  1429 				{
       
  1430 				index=i;
       
  1431 				break;
       
  1432 				}
       
  1433 			}
       
  1434 		}
       
  1435 
       
  1436 	if(index==-1)
       
  1437 		{
       
  1438 		ReqCompleted(aReqHandle, EXTENDEDERROR(KErrNoMemory, KErrPhonebookNoMemory));
       
  1439 		return KErrNone;
       
  1440 		}
       
  1441 
       
  1442 	if((index<1)||(index>iPhBkMaxNumSlots))
       
  1443 		{
       
  1444 		ReqCompleted(aReqHandle,KErrArgument);
       
  1445 		return KErrNone;
       
  1446 		}
       
  1447 
       
  1448 	TBool isSlotAlreadyUsed=EFalse;
       
  1449 	if(iPhBkUSimStoreEntries[index].iTelNum.Length()!=0)
       
  1450 		{
       
  1451 		if((iPhone->IsHiddenEnabled()!=EFalse) &&
       
  1452 			iPhBkUSimStoreEntries[index].iHiddenEntry==1)
       
  1453 			{
       
  1454 			ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1455 			return KErrNone;
       
  1456 			}
       
  1457 
       
  1458 		isSlotAlreadyUsed=ETrue;
       
  1459 		TInt idx,count;
       
  1460 		
       
  1461 		count=iPhBkUSimStoreEntries[index].iAdditional->Count();
       
  1462 		for(idx=0;idx<count;idx++)
       
  1463 			{
       
  1464 			TPhBkStoreEntry entry=
       
  1465 				iPhBkUSimStoreEntries[index].iAdditional->At(idx);
       
  1466 			entry.iTelNum.Zero();
       
  1467 			entry.iAlphaTag.Zero();	
       
  1468 			entry.iTonNpi=0;
       
  1469 			}
       
  1470 		iPhBkUSimStoreEntries[index].iAdditional->Delete(0,count);
       
  1471 		delete iPhBkUSimStoreEntries[index].iAdditional;
       
  1472 		count=iPhBkUSimStoreEntries[index].iGroups->Count();
       
  1473 		iPhBkUSimStoreEntries[index].iGroups->Delete(0,count);
       
  1474 		delete iPhBkUSimStoreEntries[index].iGroups;
       
  1475 		count=iPhBkUSimStoreEntries[index].iEmails->Count();
       
  1476 		iPhBkUSimStoreEntries[index].iEmails->Delete(0,count);
       
  1477 		delete iPhBkUSimStoreEntries[index].iEmails;
       
  1478 
       
  1479 		TRAPD(err,iPhBkUSimStoreEntries[index].iAdditional=
       
  1480 				new(ELeave) CArrayFixFlat<TPhBkStoreEntry>(iPhBkAdditional+1));
       
  1481 		if (err!=KErrNone)
       
  1482 			return (err);
       
  1483 
       
  1484 		TRAP(err,iPhBkUSimStoreEntries[index].iGroups=
       
  1485 				new(ELeave) CArrayFixFlat<TPhBkUSimGroup>(KMaxGroups));
       
  1486 		if (err!=KErrNone)
       
  1487 			return (err);
       
  1488 
       
  1489 		TRAP(err,iPhBkUSimStoreEntries[index].iEmails=
       
  1490 				new(ELeave) CArrayFixFlat<TPhBkUSimEmail>(iPhBkMaxEmail+1));
       
  1491 		if (err!=KErrNone)
       
  1492 			return (err);
       
  1493 	}
       
  1494 	else 
       
  1495 		{
       
  1496 		TRAPD(err,iPhBkUSimStoreEntries[index].iAdditional=
       
  1497 				new(ELeave) CArrayFixFlat<TPhBkStoreEntry>(iPhBkAdditional+1));
       
  1498 		if (err!=KErrNone)
       
  1499 			return (err);
       
  1500 
       
  1501 		TRAP(err,iPhBkUSimStoreEntries[index].iGroups=
       
  1502 				new(ELeave) CArrayFixFlat<TPhBkUSimGroup>(KMaxGroups));
       
  1503 		if (err!=KErrNone)
       
  1504 			return (err);
       
  1505 
       
  1506 		TRAP(err,iPhBkUSimStoreEntries[index].iEmails=
       
  1507 				new(ELeave) CArrayFixFlat<TPhBkUSimEmail>(iPhBkMaxEmail+1));
       
  1508 		if (err!=KErrNone)
       
  1509 			return (err);
       
  1510 	}
       
  1511 // Unpick the phonebook entry.
       
  1512 	iPhBkRwBuffer->Set(aPckg1);
       
  1513 	iPhBkRwBuffer->StartRead();
       
  1514 
       
  1515 	TUint8 tagVal;
       
  1516 	TUint8 npiTon=0;
       
  1517 	TUint8 hidden;
       
  1518 	TPtrC alphaTag,alphaTag2;
       
  1519 	TPtrC telNum;
       
  1520 	TPtrC bufPtr;
       
  1521 	TBool additional=EFalse;
       
  1522 	TInt additionalCount=0;
       
  1523 	
       
  1524 	CPhoneBookBuffer::TPhBkTagType tagType;
       
  1525 	TInt ret=KErrNone;
       
  1526 
       
  1527 	TPhBkStoreEntry additionalEntry;
       
  1528 
       
  1529 	while(ret==KErrNone)
       
  1530 		{
       
  1531 		ret=iPhBkRwBuffer->GetTagAndType(tagVal,tagType);
       
  1532 		if(ret==KErrNotFound)
       
  1533 			{
       
  1534 			ret=KErrNone;
       
  1535 			break;
       
  1536 			}
       
  1537 		else if(ret!=KErrNone)
       
  1538 			break;
       
  1539 		switch(tagVal)
       
  1540 			{
       
  1541 		case RMobilePhoneBookStore::ETagPBNewEntry:
       
  1542 			break;
       
  1543 
       
  1544 		case RMobilePhoneBookStore::ETagPBText:
       
  1545 			ret=iPhBkRwBuffer->GetValue(alphaTag);
       
  1546 
       
  1547 			LOGPHBK2("alphaTag (ETagPBText) Length = (%d)",alphaTag.Length());
       
  1548 			LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen);
       
  1549 
       
  1550 			if(!additional && ret==KErrNone && (alphaTag.Length()<=iPhBkMaxTextLen))
       
  1551 				iPhBkUSimStoreEntries[index].iAlphaTag.Copy(alphaTag);
       
  1552 			else if(additional && ret==KErrNone && (alphaTag.Length()<=iPhBkMaxAdditionalTextLen)
       
  1553 					&& (additionalCount<iPhBkAdditional))
       
  1554 				additionalEntry.iAlphaTag.Copy(alphaTag);
       
  1555 			else if(additional)
       
  1556 				ret=EXTENDEDERROR(KErrArgument, KErrPhonebookAdditionalNumberAlphaTextOverflow);
       
  1557 			else
       
  1558 				ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookTextOverflow);
       
  1559 			break;
       
  1560 
       
  1561 		case RMobilePhoneBookStore::ETagPBSecondName:
       
  1562 			ret=iPhBkRwBuffer->GetValue(alphaTag2);
       
  1563 
       
  1564 			LOGPHBK2("alphaTag2 (ETagPBSecondName) Length = (%d)",alphaTag2.Length());
       
  1565 			LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen);
       
  1566 
       
  1567 			if(ret==KErrNone && (alphaTag2.Length()<=iPhBkMaxTextLen))
       
  1568 				iPhBkUSimStoreEntries[index].iAlphaTag2.Copy(alphaTag2);
       
  1569 			else
       
  1570 				ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookSecondNameTextOverflow);
       
  1571 			break;
       
  1572 
       
  1573 		case RMobilePhoneBookStore::ETagPBNumber:
       
  1574 			ret=iPhBkRwBuffer->GetValue(telNum);
       
  1575 
       
  1576 			LOGPHBK2("telNum (ETagPBNumber) Length = (%d)",telNum.Length());
       
  1577 			LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTelNumLen);
       
  1578 
       
  1579 			if(!additional && ret==KErrNone && (telNum.Length()<=iPhBkMaxTelNumLen))
       
  1580 				iPhBkUSimStoreEntries[index].iTelNum.Copy(telNum);
       
  1581 			else if(additional && ret==KErrNone && (telNum.Length()<=iPhBkMaxAdditionalTelNumLen)
       
  1582 					&& (additionalCount<iPhBkAdditional))
       
  1583 				additionalEntry.iTelNum.Copy(telNum);
       
  1584 			else if(additional)
       
  1585 				ret=EXTENDEDERROR(KErrArgument, KErrPhonebookAdditionalNumberNumberOverflow);
       
  1586 			else 
       
  1587 				ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookNumberOverflow);
       
  1588 			break;
       
  1589 
       
  1590 		case RMobilePhoneBookStore::ETagPBTonNpi:
       
  1591 			ret=iPhBkRwBuffer->GetValue(npiTon);
       
  1592 			if(!additional && ret==KErrNone)
       
  1593 				iPhBkUSimStoreEntries[index].iTonNpi=npiTon;
       
  1594 			else if (additional && ret==KErrNone)
       
  1595 				{
       
  1596 				additionalEntry.iTonNpi=npiTon;
       
  1597 				TRAP_IGNORE(iPhBkUSimStoreEntries[index].iAdditional->AppendL(additionalEntry));
       
  1598 				additional=EFalse;
       
  1599 				additionalCount++;
       
  1600 				additionalEntry.iAlphaTag.Zero();
       
  1601 				additionalEntry.iTelNum.Zero();
       
  1602 				additionalEntry.iTonNpi=0;
       
  1603 				}
       
  1604 			break;
       
  1605 
       
  1606 		case RMobilePhoneBookStore::ETagPBAnrStart:
       
  1607 			if(!additional)
       
  1608 				additional=ETrue;
       
  1609 			else
       
  1610 				ret=KErrArgument;
       
  1611 			break;
       
  1612 
       
  1613 		case RMobilePhoneBookStore::ETagPBGroupName:
       
  1614 			ret=iPhBkRwBuffer->GetValue(bufPtr);
       
  1615 
       
  1616 			LOGPHBK2("bufPtr (ETagPBGroupName) Length = (%d)",bufPtr.Length());
       
  1617 			LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen);
       
  1618 
       
  1619 			if(ret==KErrNone && (bufPtr.Length()<=iPhBkMaxTextLen)
       
  1620 				&& (iPhBkUSimStoreEntries[index].iGroups->Count() < KMaxGroups))
       
  1621 			{
       
  1622 				TRAP_IGNORE(iPhBkUSimStoreEntries[index].iGroups->AppendL(bufPtr));
       
  1623 			}
       
  1624 			else 
       
  1625 				ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookGroupAlphaTextOverflow);
       
  1626 			break;
       
  1627 
       
  1628 		case RMobilePhoneBookStore::ETagPBEmailAddress:
       
  1629 			ret=iPhBkRwBuffer->GetValue(bufPtr);
       
  1630 
       
  1631 			LOGPHBK2("bufPtr (ETagPBEmailAddress) Length = (%d)",bufPtr.Length());
       
  1632 			LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen);
       
  1633 
       
  1634 			if(ret==KErrNone && (bufPtr.Length()<=iPhBkMaxTextLen)
       
  1635 				&& (iPhBkUSimStoreEntries[index].iEmails->Count() < iPhBkMaxEmail))
       
  1636 			{
       
  1637 				TRAP_IGNORE(iPhBkUSimStoreEntries[index].iEmails->AppendL(bufPtr));
       
  1638 			}
       
  1639 			else
       
  1640 				ret=EXTENDEDERROR(KErrOverflow, KErrPhonebookEmailTextOverflow);		
       
  1641 			break;
       
  1642 
       
  1643 		case RMobilePhoneBookStore::ETagPBHiddenInfo:
       
  1644 			ret=iPhBkRwBuffer->GetValue(hidden);	
       
  1645 			if(ret==KErrNone)
       
  1646 				iPhBkUSimStoreEntries[index].iHiddenEntry=hidden;
       
  1647 			break;
       
  1648 
       
  1649 		default:
       
  1650 			ret=KErrNotSupported;
       
  1651 			}
       
  1652 		}
       
  1653 
       
  1654 	if(ret!=KErrNone)
       
  1655 		{
       
  1656 		//Cleanup!
       
  1657 		iPhBkUSimStoreEntries[index].iTelNum.Zero();
       
  1658 		iPhBkUSimStoreEntries[index].iAlphaTag.Zero();
       
  1659 		iPhBkUSimStoreEntries[index].iAlphaTag2.Zero();
       
  1660 		iPhBkUSimStoreEntries[index].iHiddenEntry=0;
       
  1661 		iPhBkUSimStoreEntries[index].iTonNpi=npiTon;
       
  1662 
       
  1663 		if(iPhBkUSimStoreEntries[index].iGroups!=NULL) 
       
  1664 		{
       
  1665 			iPhBkUSimStoreEntries[index].iGroups->Delete(0,iPhBkUSimStoreEntries[index].iGroups->Count());
       
  1666 			delete iPhBkUSimStoreEntries[index].iGroups;
       
  1667 		}
       
  1668 		if(iPhBkUSimStoreEntries[index].iEmails!=NULL)
       
  1669 		{
       
  1670 			iPhBkUSimStoreEntries[index].iEmails->Delete(0,iPhBkUSimStoreEntries[index].iEmails->Count());
       
  1671 			delete iPhBkUSimStoreEntries[index].iEmails;
       
  1672 		}
       
  1673 		if(iPhBkUSimStoreEntries[index].iAdditional!=NULL)
       
  1674 		{
       
  1675 			iPhBkUSimStoreEntries[index].iAdditional->Delete(0,iPhBkUSimStoreEntries[index].iAdditional->Count());
       
  1676 			delete iPhBkUSimStoreEntries[index].iAdditional;
       
  1677 		}
       
  1678 		ReqCompleted(aReqHandle,ret);
       
  1679 		return KErrNone;
       
  1680 		}
       
  1681 
       
  1682 //	if(alphaTag.Length()>iPhBkMaxTextLen)
       
  1683 //		{
       
  1684 //		ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookTextOverflow));
       
  1685 //		return KErrNone;
       
  1686 //		}
       
  1687 //	else if(telNum.Length()>iPhBkMaxTelNumLen)
       
  1688 //		{
       
  1689 //		ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookNumberOverflow));
       
  1690 //		return KErrNone;
       
  1691 //		}
       
  1692 	
       
  1693 	if(isSlotAlreadyUsed)
       
  1694 		DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventChanged,index);
       
  1695 	else
       
  1696 		DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventAdded,index);
       
  1697 	return KErrNone;
       
  1698 	}
       
  1699 
       
  1700 TInt CSimPhBkUSimStore::Delete(TTsyReqHandle aReqHandle,TDes8* aPckg)
       
  1701 /**
       
  1702  * Delete a single Phonebook store entry.  The completion of this request is delayed in order to
       
  1703  * simulate a real TSY that would have to write the information to a SIM card. A store
       
  1704  * event may be triggered by this request.
       
  1705  *
       
  1706  * @param aReqHandle	The TSY request handle associated with this request.
       
  1707  * @param aPckg			The parameter package associated with this request.
       
  1708  * @return				Standard return value.
       
  1709  */
       
  1710 	{
       
  1711 	if(CheckAndSwitchUSimApps()!=KErrNone)
       
  1712 		{
       
  1713 		ReqCompleted(aReqHandle, KErrNotFound);
       
  1714 		return KErrNone;
       
  1715 		}
       
  1716 
       
  1717 	if(iPhone->IsICCLocked()!=EFalse)
       
  1718 		{
       
  1719 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1720 		return KErrNone;
       
  1721 		}
       
  1722 	
       
  1723 	if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
       
  1724 		{
       
  1725 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1726 		return KErrNone;
       
  1727 		}
       
  1728 
       
  1729 
       
  1730 	TPckg<TInt>* intPckg=(TPckg<TInt>*)aPckg;
       
  1731 	TInt& index=(*intPckg)();
       
  1732 
       
  1733 	if((index<1)||(index>iPhBkMaxNumSlots))
       
  1734 		{
       
  1735 		ReqCompleted(aReqHandle,KErrArgument);
       
  1736 		return KErrNone;
       
  1737 		}
       
  1738 	
       
  1739 	if((iPhone->IsHiddenEnabled()!=EFalse) &&
       
  1740 		iPhBkUSimStoreEntries[index].iHiddenEntry==1)
       
  1741 		{
       
  1742 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1743 		return KErrNone;
       
  1744 		}
       
  1745 	
       
  1746 	iPhBkUSimStoreEntries[index].iTelNum.Zero();
       
  1747 	iPhBkUSimStoreEntries[index].iAlphaTag.Zero();
       
  1748 	iPhBkUSimStoreEntries[index].iAlphaTag2.Zero();
       
  1749 	
       
  1750 	if((iPhBkUSimStoreEntries[index].iGroups!=NULL) &&
       
  1751 		((TUint)iPhBkUSimStoreEntries[index].iGroups!=DELETED))
       
  1752 	{
       
  1753 		iPhBkUSimStoreEntries[index].iGroups->Delete(0,
       
  1754 			iPhBkUSimStoreEntries[index].iGroups->Count());
       
  1755 		delete iPhBkUSimStoreEntries[index].iGroups;
       
  1756 	}
       
  1757 	if((iPhBkUSimStoreEntries[index].iEmails!=NULL) &&
       
  1758 		((TUint)iPhBkUSimStoreEntries[index].iEmails!=DELETED))
       
  1759 	{
       
  1760 		iPhBkUSimStoreEntries[index].iEmails->Delete(0,
       
  1761 			iPhBkUSimStoreEntries[index].iEmails->Count());
       
  1762 		delete iPhBkUSimStoreEntries[index].iEmails;
       
  1763 	}
       
  1764 
       
  1765 	if((iPhBkUSimStoreEntries[index].iAdditional!=NULL) &&
       
  1766 		((TUint)iPhBkUSimStoreEntries[index].iAdditional!=DELETED))
       
  1767 		{
       
  1768 		TInt count = iPhBkUSimStoreEntries[index].iAdditional->Count();
       
  1769 		for(TInt i=0;i<count;i++)
       
  1770 			{
       
  1771 			TPhBkStoreEntry entry=iPhBkUSimStoreEntries[index].iAdditional->At(i);
       
  1772 			entry.iTelNum.Zero();
       
  1773 			entry.iAlphaTag.Zero();
       
  1774 			entry.iTonNpi=0;
       
  1775 			}
       
  1776 
       
  1777 		iPhBkUSimStoreEntries[index].iAdditional->Delete(0,count);
       
  1778 		delete iPhBkUSimStoreEntries[index].iAdditional;
       
  1779 		}
       
  1780 
       
  1781 	DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventDeleted,index);
       
  1782 	return KErrNone;
       
  1783 	}
       
  1784 
       
  1785 TInt CSimPhBkUSimStore::DeleteAll(TTsyReqHandle aReqHandle)
       
  1786 /**
       
  1787  * Delete all entries in the Phonebook Store.  The completion of this function is delayed in
       
  1788  * order to simulate the SIM operations a real TSY would have to carry out.  This function
       
  1789  * may trigger an Phonebook Store notification.
       
  1790  *
       
  1791  * @param aReqHandle	The TSY request handle associated with this request.
       
  1792  * @return				Standard return value.
       
  1793  */
       
  1794 	{
       
  1795 	if(CheckAndSwitchUSimApps()!=KErrNone)
       
  1796 		{
       
  1797 		ReqCompleted(aReqHandle, KErrNotFound);
       
  1798 		return KErrNone;
       
  1799 		}
       
  1800 
       
  1801 	if(iPhone->IsICCLocked()!=EFalse)
       
  1802 		{
       
  1803 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1804 		return KErrNone;
       
  1805 		}
       
  1806 
       
  1807 	if (!(iPhBkStoreCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
       
  1808 		{
       
  1809 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1810 		return KErrNone;
       
  1811 		}
       
  1812 
       
  1813 	for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
       
  1814 		{
       
  1815 		TBool entryUsed =EFalse;
       
  1816 
       
  1817 		if((iPhone->IsHiddenEnabled()!=EFalse) &&
       
  1818 		iPhBkUSimStoreEntries[i].iHiddenEntry==1)
       
  1819 			{
       
  1820 			//Skip me because I am a hidden entry!
       
  1821 			//The hidden key has to be verified to delete me!
       
  1822 			continue;
       
  1823 			}
       
  1824 		if(iPhBkUSimStoreEntries[i].iTelNum.Length()>0)
       
  1825 			entryUsed = ETrue;
       
  1826 			
       
  1827 		iPhBkUSimStoreEntries[i].iTelNum.Zero();
       
  1828 		iPhBkUSimStoreEntries[i].iAlphaTag.Zero();
       
  1829 		iPhBkUSimStoreEntries[i].iAlphaTag2.Zero();
       
  1830 		
       
  1831 		if(entryUsed)
       
  1832 			{
       
  1833 			if((iPhBkUSimStoreEntries[i].iGroups!=NULL) &&
       
  1834 				((TUint)iPhBkUSimStoreEntries[i].iGroups!=DELETED))
       
  1835 			{
       
  1836 				iPhBkUSimStoreEntries[i].iGroups->Delete(0,
       
  1837 					iPhBkUSimStoreEntries[i].iGroups->Count());
       
  1838 				delete iPhBkUSimStoreEntries[i].iGroups;
       
  1839 			}
       
  1840 			if((iPhBkUSimStoreEntries[i].iEmails!=NULL) &&
       
  1841 				((TUint)iPhBkUSimStoreEntries[i].iEmails!=DELETED))
       
  1842 			{
       
  1843 				iPhBkUSimStoreEntries[i].iEmails->Delete(0,
       
  1844 					iPhBkUSimStoreEntries[i].iEmails->Count());
       
  1845 				delete iPhBkUSimStoreEntries[i].iEmails;
       
  1846 			}
       
  1847 			if((iPhBkUSimStoreEntries[i].iAdditional!=NULL) &&
       
  1848 				((TUint)iPhBkUSimStoreEntries[i].iAdditional!=DELETED))
       
  1849 				{
       
  1850 				TInt count = iPhBkUSimStoreEntries[i].iAdditional->Count();
       
  1851 	            for(TInt index=0;index<count;index++)
       
  1852 					{
       
  1853 					TPhBkStoreEntry entry=iPhBkUSimStoreEntries[i].iAdditional->At(index);
       
  1854 					entry.iTelNum.Zero();
       
  1855 					entry.iAlphaTag.Zero();
       
  1856 					entry.iTonNpi=0;
       
  1857 					}
       
  1858 
       
  1859 				iPhBkUSimStoreEntries[i].iAdditional->Delete(0,count);
       
  1860 				delete iPhBkUSimStoreEntries[i].iAdditional;
       
  1861 				}
       
  1862 			}
       
  1863 	}
       
  1864 	DelayCompletion(iPhBkBatchPause,aReqHandle,EStoreEventDeleted,-1);
       
  1865 	return KErrNone;
       
  1866 	}
       
  1867 
       
  1868 TInt CSimPhBkUSimStore::NotifyStoreEvent(TTsyReqHandle aReqHandle,TDes8* aPckg1,TDes8* aPckg2)
       
  1869 /**
       
  1870  * Register a client's interest in Phonebook Store events.
       
  1871  *
       
  1872  * @param aReqHandle	The TSY request handle associated with this request.
       
  1873  * @param aPckg1		The first parameter package associated with this request.
       
  1874  *						It contains the event flags that will be returned to the client.
       
  1875  * @param aPckg2		The second parameter package associated with this request.
       
  1876  *						It contains the index value associated with the event
       
  1877  *						that will be returned to the client.
       
  1878  * @return				Standard return value.
       
  1879  */
       
  1880 	{
       
  1881 	TPckg<TUint32>* eventPckg=(TPckg<TUint32>*)aPckg1;
       
  1882 	TUint32& event=(*eventPckg)();
       
  1883 	TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg2;
       
  1884 	TInt& index=(*indexPckg)();
       
  1885 
       
  1886 	iEvOutstandingReq=ETrue;
       
  1887 	iEvReqHandle=aReqHandle;
       
  1888 	iEvEvent=&event;
       
  1889 	iEvIndex=&index;
       
  1890 	return KErrNone;
       
  1891 	}
       
  1892 
       
  1893 void CSimPhBkUSimStore::NotifyStoreEventCancel()
       
  1894 /**
       
  1895  * Cancel an outstanding notify store request.
       
  1896  */
       
  1897 	{
       
  1898 	if(iEvOutstandingReq)
       
  1899 		{
       
  1900 		iEvOutstandingReq=EFalse;
       
  1901 		ReqCompleted(iEvReqHandle,KErrCancel);
       
  1902 		}
       
  1903 	}
       
  1904 
       
  1905 TPtrC8 CSimPhBkUSimStore::Name()
       
  1906 /**
       
  1907  * Accessor function fot the Phonebook Store name.
       
  1908  *
       
  1909  * @return TPtrC8	The name of this Phonebook Store.
       
  1910  */
       
  1911 	{
       
  1912 	return iPhBkStoreName;
       
  1913 	}
       
  1914 
       
  1915 TPtrC8 CSimPhBkUSimStore::PhBkStore()
       
  1916 /**
       
  1917  * Accessor function fot the Phonebook Store name.
       
  1918  *
       
  1919  * @return TPtrC8	The name of this Phonebook Store.
       
  1920  */
       
  1921 	{
       
  1922 	return iPhBkStore;
       
  1923 	}
       
  1924 
       
  1925 TPtrC8 CSimPhBkUSimStore::AID()
       
  1926 /**
       
  1927  * Accessor function fot the Phonebook Store name.
       
  1928  *
       
  1929  * @return TPtrC8	The name of this Phonebook Store.
       
  1930  */
       
  1931 	{
       
  1932 	return iPhBkAid;
       
  1933 	}
       
  1934 
       
  1935 TInt CSimPhBkUSimStore::UsedEntries()
       
  1936 /**
       
  1937  * Count the number of used entries in the Phonebook Store.
       
  1938  * @return TInt	The number of used entries in the store.
       
  1939  */
       
  1940 	{
       
  1941 	TInt cnt=0;
       
  1942 	if(CheckAndSwitchUSimApps()!=KErrNone)
       
  1943   		return KErrNotFound;
       
  1944 	for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
       
  1945 		{
       
  1946 		if((iPhBkUSimStoreEntries[i].iTelNum.Length()!=0)||(iPhBkUSimStoreEntries[i].iAlphaTag.Length()!=0))
       
  1947 			cnt++;
       
  1948 		}
       
  1949 	return cnt;
       
  1950 	}
       
  1951 
       
  1952 TInt CSimPhBkUSimStore::MaxSlots()
       
  1953 /**
       
  1954  * Retrieve the maximum number of slots in this Phonebook Store.
       
  1955  * @return TInt	The maximum number of slots in this Phonebook Store.
       
  1956  */
       
  1957 	{
       
  1958 	return iPhBkMaxNumSlots;
       
  1959 	}
       
  1960 
       
  1961 void CSimPhBkUSimStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle)
       
  1962 /**
       
  1963  * A shell function for functions that wish to delay completion but do not trigger store
       
  1964  * events.
       
  1965  */
       
  1966 	{
       
  1967 	DelayCompletion(aDelayDuration,aReqHandle,EStoreEventNoEvent,0);
       
  1968 	}
       
  1969 
       
  1970 void CSimPhBkUSimStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle,TStoreEvent aEvent,TInt aIndex)
       
  1971 /**
       
  1972  * Delay the completion of a TSY request.  It is assumed that the member variable
       
  1973  * manipulation associated with the request has already taken place, and so all that is
       
  1974  * left to do is call the ETel server's request completion function when the timer expires.
       
  1975  * So, just record the parameters and kick off the timer.
       
  1976  *
       
  1977  * @param aDelayDuration	The time (in seconds) for which the request completion is to be delayed.
       
  1978  * @param aReqHandle		The TSY request handle related to the delayed completion.
       
  1979  * @param aEvent			The store event related to the delayed completion.
       
  1980  * @param aIndex			The index related to the event passed in aEvent.
       
  1981  */
       
  1982 	{
       
  1983 	iPendingReqCompletion=aReqHandle;
       
  1984 	iPendingEvent=aEvent;
       
  1985 	iPendingIndex=aIndex;
       
  1986 	iReqTimer->Start(aDelayDuration,this,ETimerIdPhBkUSimStorReq);
       
  1987 	}
       
  1988 
       
  1989 void CSimPhBkUSimStore::TimerCallBack(TInt aId)
       
  1990 /**
       
  1991  * Process a timer call back event.  There are three timers associated with this class
       
  1992  * and this callback will be used for all of them.  The timers can be identified from the
       
  1993  * aId parameter passed with the callback.
       
  1994  *
       
  1995  * The "Request" timer is used to kick requests which have had their completions delayed.
       
  1996  * The "Out of Band Write" timer is used to schedule a non-client phonebook write.
       
  1997  * The "Out of Band Delete" timer is used to schedule a non-client phonebook delete.
       
  1998  *
       
  1999  * @param aId	The Id of the timer to which this callback relates.
       
  2000  */
       
  2001 	{
       
  2002 	TInt idx=0,count;
       
  2003 	TBool isSlotAlreadyUsed=EFalse;
       
  2004 
       
  2005 	switch(aId)
       
  2006 		{
       
  2007 	case ETimerIdPhBkUSimStorReq:
       
  2008 		StoreEvent(iPendingEvent,iPendingIndex);
       
  2009 		ReqCompleted(iPendingReqCompletion,KErrNone);
       
  2010 		break;
       
  2011 
       
  2012 	case ETimerIdPhBkUSimStorOOBWrite:
       
  2013 
       
  2014 		if(CheckAndSwitchUSimApps()!=KErrNone)
       
  2015 			if(iEvOutstandingReq)
       
  2016 				{
       
  2017 				ReqCompleted(iEvReqHandle,KErrNotFound);
       
  2018 				return;
       
  2019 				}
       
  2020 			else
       
  2021 				{
       
  2022 				return;
       
  2023 				}
       
  2024 
       
  2025 		if(iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTelNum.Length()!=0)
       
  2026 			isSlotAlreadyUsed=ETrue;
       
  2027 		
       
  2028 		iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAlphaTag.Copy(iPhBkOOBWrite.iAlphaTag);
       
  2029 		iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTelNum.Copy(iPhBkOOBWrite.iTelNum);
       
  2030 		iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iTonNpi=iPhBkOOBWrite.iTonNpi;
       
  2031 		iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAlphaTag2.Copy(iPhBkOOBWrite.iAlphaTag2);
       
  2032 
       
  2033 		if(isSlotAlreadyUsed)
       
  2034 			{
       
  2035 			if((count=iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->Count())>0)
       
  2036 				{
       
  2037 				for(idx=0;idx<count;idx++)
       
  2038 						{
       
  2039 						TPhBkStoreEntry entry=
       
  2040 							iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->At(idx);
       
  2041 						entry.iTelNum.Zero();
       
  2042 						entry.iAlphaTag.Zero();	
       
  2043 						entry.iTonNpi=0;
       
  2044 						}
       
  2045 				iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->Delete(0,count);
       
  2046 				delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional;
       
  2047 				}
       
  2048 			
       
  2049 			if((count = iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups->Count())>0)
       
  2050 				{
       
  2051 					iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups->Delete(0,count);
       
  2052 					delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups;
       
  2053 				}
       
  2054 			if((count = iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails->Count())>0)
       
  2055 				{
       
  2056 					iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails->Delete(0,count);
       
  2057 					delete iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails;
       
  2058 				}
       
  2059 			}
       
  2060 	
       
  2061 		count = iPhBkOOBWrite.iAdditional->Count();
       
  2062 
       
  2063 		//sometimes because of a kernel bug on wins, iAdditional pointer gets filled up with
       
  2064 		//bad address 0xdededede (investigating)
       
  2065 	
       
  2066 		TRAPD(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional=new(ELeave) CArrayFixFlat<TPhBkStoreEntry>(iPhBkAdditional+1));
       
  2067 		if (err!=KErrNone)
       
  2068 			{
       
  2069 			LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure");
       
  2070 			return;
       
  2071 			}
       
  2072 
       
  2073 		for(idx=0;idx<count;idx++)
       
  2074 			{
       
  2075 			TPhBkStoreEntry entry=iPhBkOOBWrite.iAdditional->At(idx);
       
  2076 			TRAP_IGNORE(iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iAdditional->AppendL(entry));
       
  2077 			}
       
  2078 
       
  2079 		
       
  2080 		TRAP(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups=new(ELeave) CArrayFixFlat<TPhBkUSimGroup>(KMaxGroups));
       
  2081 		if (err!=KErrNone)
       
  2082 			{
       
  2083 			LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure");
       
  2084 			return;
       
  2085 			}
       
  2086 
       
  2087 		for(idx=0;idx<count;idx++)
       
  2088 			{
       
  2089 			TPhBkUSimGroup entry;
       
  2090 			TRAP_IGNORE(iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iGroups->AppendL(entry));
       
  2091 			}
       
  2092 		
       
  2093 		count = iPhBkOOBWrite.iEmails->Count();
       
  2094 		TRAP(err,iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails=new(ELeave) CArrayFixFlat<TPhBkUSimEmail>(iPhBkMaxEmail+1));	
       
  2095 		if (err!=KErrNone)
       
  2096 			{
       
  2097 			LOGPHBK1("CSimPhBkUSimStore::TimerCallBack - Memory Allocation Failure");
       
  2098 			return;
       
  2099 			}
       
  2100 
       
  2101 		for(idx=0;idx<count;idx++)
       
  2102 			{
       
  2103 			TPhBkUSimEmail entry;
       
  2104 			TRAP_IGNORE(iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iEmails->AppendL(entry));
       
  2105 			}
       
  2106 		
       
  2107 		iPhBkUSimStoreEntries[iPhBkOOBWriteIndex].iHiddenEntry=iPhBkOOBWrite.iHiddenEntry;
       
  2108 	
       
  2109 		StoreEvent(EStoreEventAdded,iPhBkOOBWriteIndex);
       
  2110 		break;
       
  2111 
       
  2112 	case ETimerIdPhBkUSimStorOOBDelete:
       
  2113 		
       
  2114 		if(CheckAndSwitchUSimApps()!=KErrNone)
       
  2115 			if(iEvOutstandingReq)
       
  2116 				{
       
  2117 				ReqCompleted(iEvReqHandle,KErrNotFound);
       
  2118 				return;
       
  2119 				}
       
  2120 			else
       
  2121 				{
       
  2122 				return;
       
  2123 				}
       
  2124 
       
  2125 		iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag.Zero();
       
  2126 		iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iTelNum.Zero();
       
  2127 		iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iTonNpi=0;
       
  2128 		iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag2.Zero();
       
  2129 
       
  2130 		iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups->Delete(0,
       
  2131 			iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups->Count());
       
  2132 		delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iGroups;
       
  2133 
       
  2134 		iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails->Delete(0,
       
  2135 			iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails->Count());
       
  2136 		delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iEmails;
       
  2137 
       
  2138 		count = iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional->Count();
       
  2139 		for(idx=0;idx<count;idx++)
       
  2140 			{
       
  2141 			TPhBkStoreEntry entry=iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional->At(idx);
       
  2142 			entry.iTelNum.Zero();
       
  2143 			entry.iAlphaTag.Zero();	
       
  2144 			entry.iTonNpi=0;
       
  2145 			}
       
  2146 
       
  2147 		iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional->Delete(0,count);
       
  2148 		delete iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iAdditional;
       
  2149 		iPhBkUSimStoreEntries[iPhBkOOBDeleteIndex].iHiddenEntry=0;
       
  2150 
       
  2151 		StoreEvent(EStoreEventDeleted,iPhBkOOBDeleteIndex);
       
  2152 		break;
       
  2153 
       
  2154 	default:
       
  2155 		break;
       
  2156 		}
       
  2157 	}
       
  2158 
       
  2159 void CSimPhBkUSimStore::StoreEvent(TStoreEvent aEvent,TInt aIndex)
       
  2160 /**
       
  2161  * Determine if a store event notification should be completed.
       
  2162  * @param aEvent	The store event.
       
  2163  * @param aIndex	The index related to the store event.
       
  2164  */
       
  2165 	{
       
  2166 	if(iEvOutstandingReq)
       
  2167 		{
       
  2168 		TUint event=0;
       
  2169 		switch(aEvent)
       
  2170 			{
       
  2171 		case EStoreEventNoEvent:
       
  2172 			return;
       
  2173 
       
  2174 		case EStoreEventAdded:
       
  2175 			event|=RMobilePhoneStore::KStoreEntryAdded;
       
  2176 			break;
       
  2177 
       
  2178 		case EStoreEventDeleted:
       
  2179 			event|=RMobilePhoneStore::KStoreEntryDeleted;
       
  2180 			break;
       
  2181 
       
  2182 		case EStoreEventChanged:
       
  2183 			event|=RMobilePhoneStore::KStoreEntryChanged;
       
  2184 			break;
       
  2185 
       
  2186 		default:
       
  2187 			break;
       
  2188 			}
       
  2189 
       
  2190 		TInt cnt=UsedEntries();
       
  2191 		if(cnt==0)
       
  2192 			event|=RMobilePhoneStore::KStoreEmpty;
       
  2193 
       
  2194 		if(cnt==iPhBkMaxNumSlots)
       
  2195 			event|=RMobilePhoneStore::KStoreFull;
       
  2196 		else
       
  2197 			event|=RMobilePhoneStore::KStoreHasSpace;
       
  2198 
       
  2199 		*iEvEvent=event;
       
  2200 		*iEvIndex=aIndex;
       
  2201 		iEvOutstandingReq=EFalse;
       
  2202 		ReqCompleted(iEvReqHandle,KErrNone);
       
  2203 		}
       
  2204 	}
       
  2205 
       
  2206 TBool CSimPhBkUSimStore::FindIpcErrorMatch(TInt& aError)
       
  2207 /**
       
  2208  * Determine whether the IPC counter has signalled that the current request should
       
  2209  * be errored, rather than executed.
       
  2210  *
       
  2211  * @param aError	If the function returns ETrue, this parameter will pass back the
       
  2212  *					number of the error to be propagated.
       
  2213  * @return TBool	Returns ETrue if a match with the IPC count is found, EFalse if not.
       
  2214  */
       
  2215 	{
       
  2216 	TInt i;
       
  2217 	for(i=0;i<iPhBkError->Count();i++)
       
  2218 		{
       
  2219 		if(iPhBkError->At(i).iCount==iIpcCnt)
       
  2220 			{
       
  2221 			aError=iPhBkError->At(i).iError;
       
  2222 			return ETrue;
       
  2223 			}
       
  2224 		}
       
  2225 	return EFalse;
       
  2226 	}
       
  2227 
       
  2228 
       
  2229 /**
       
  2230  *  Check that the USIM App phonebook in use is the same as the current
       
  2231  *  USIM App, and if not then swap the phonebook over.
       
  2232  */
       
  2233 TInt CSimPhBkUSimStore::CheckAndSwitchUSimApps()
       
  2234 	{	
       
  2235 	TInt ret=KErrNone;
       
  2236 
       
  2237 	if(iPhBkStore.Compare(KUSimPhoneBook)==KErrNone)
       
  2238 		{
       
  2239 		if(iPhone->GetActiveUSim().Compare(iPhBkAid)==KErrNone) 
       
  2240 			{
       
  2241 			//
       
  2242 			// The active USIM App is the same as last time, but ensure that
       
  2243 			// we are using the right phonebook anyway.
       
  2244 			//
       
  2245 			if(iPhBkAid.Compare(iPhBkAidUSim2)==KErrNone)
       
  2246 				{
       
  2247 				iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries;
       
  2248 				}
       
  2249 			else if(iPhBkAid.Compare(iPhBkAidUSim1)==KErrNone)
       
  2250 				{
       
  2251 				iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries;
       
  2252 				}
       
  2253 			else 
       
  2254 				{
       
  2255 				//messed up
       
  2256 				return KErrUnknown;
       
  2257 				}
       
  2258 			}
       
  2259 		else if((iPhone->GetActiveUSim().Compare(iPhBkAid)!=KErrNone) &&
       
  2260 			(iPhone->GetActiveUSim().Compare(iPhBkAidUSim2)==KErrNone)) 
       
  2261 			{
       
  2262 			//
       
  2263 			// The active USIM App is not the same as last time and it appears
       
  2264 			// to be USIM App 2, so use USIM phonebook number 2.
       
  2265 			//
       
  2266 			iPhBkAid.Copy(iPhBkAidUSim2);
       
  2267 			iPhBkUSimStoreEntries=iPhBkUSim2StoreEntries;
       
  2268 			}
       
  2269 		else if((iPhone->GetActiveUSim().Compare(iPhBkAid)!=KErrNone) &&
       
  2270 			(iPhone->GetActiveUSim().Compare(iPhBkAidUSim1)==KErrNone)) 
       
  2271 			{
       
  2272 			//
       
  2273 			// The active USIM App is not the same as last time and it appears
       
  2274 			// to be USIM App 1, so use USIM phonebook number 1.
       
  2275 			//
       
  2276 			iPhBkAid.Copy(iPhBkAidUSim1);
       
  2277 			iPhBkUSimStoreEntries=iPhBkUSim1StoreEntries;
       
  2278 			}
       
  2279 		else
       
  2280 			{
       
  2281 			//Unknown active application!!
       
  2282 			ret=KErrNotFound;
       
  2283 			}
       
  2284 		}	
       
  2285 	return ret;
       
  2286 }
       
  2287 
       
  2288 const CTestConfigSection* CSimPhBkUSimStore::CfgFile()
       
  2289 /**
       
  2290 * Returns a pointer to the config file section
       
  2291 *
       
  2292 * @return CTestConfigSection a pointer to the configuration file data section
       
  2293 */
       
  2294 	{
       
  2295 	LOGPHBK1(">>CSimPhBkUSimStore::CfgFile");
       
  2296 	return iPhone->CfgFile();
       
  2297 	}