telephonyserverplugins/simtsy/src/CSimPhBkStore.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
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 "CSimPhBkStore.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 KPhonebookErrorGranularity=3;	// < Granularity of phonebook error list array.
       
    30 //
       
    31 // CSimPhBkStore
       
    32 //
       
    33 void CSimPhBkStore::ClosePhone(TAny* aObj)
       
    34 /**
       
    35  * A utility function for cleaning up the stack.
       
    36  */
       
    37 	{
       
    38 	((CObject*)aObj)->Close();
       
    39 	}
       
    40 
       
    41 CSimPhBkStore* CSimPhBkStore::NewL(CSimPhone* aPhone, const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen)
       
    42 /**
       
    43  * Standard two phase constructor.
       
    44  * @param aPhone			The phone object from which this Phonebook was opened.
       
    45  * @param aName				The name of the created Phonebook.
       
    46  * @param aMaxNumSlots		The maximum number of slots in the Phonebook.
       
    47  * @return CSimPhBkStore*	The newly created object.
       
    48  */
       
    49 	{
       
    50 	CSimPhBkStore* store=new(ELeave) CSimPhBkStore(aPhone);
       
    51 	TCleanupItem newObjClose(ClosePhone,store);
       
    52 	CleanupStack::PushL(newObjClose);
       
    53 	store->ConstructL(aName,aMaxNumSlots,aMaxNumLen,aMaxTextLen);
       
    54 	CleanupStack::Pop();
       
    55 	return store;
       
    56 	}
       
    57 
       
    58 CSimPhBkStore::CSimPhBkStore(CSimPhone* aPhone)
       
    59 		: CSimPhone(iDummyPhoneBaseRef), iPhone(aPhone),iIpcCnt(0),iEvOutstandingReq(EFalse)
       
    60 /**
       
    61  * Trivial first phase constructor.
       
    62  * @param aPhone	The phone object from which this phonebook was opened.
       
    63  */
       
    64 	{}
       
    65 
       
    66 void CSimPhBkStore::ConstructL(const TDesC8& aName, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen)
       
    67 /**
       
    68  * Second phase constructor that allocates memory for the phonebook, batch read buffer and
       
    69  * a delayed completion timer.  The constructor also reads the individual and batch read
       
    70  * delays from the configuration file.
       
    71  * 
       
    72  * @param aName			The name of the created phonebook.
       
    73  * @param aMaxNumLen	The maximum length of a telephone number.
       
    74  * @param aMaxTextLen	The maximum length of an alpha tag.
       
    75  */
       
    76 	{
       
    77 	LOGPHBK1("Starting to parse Phonebook store additional config parameters...");
       
    78 	__ASSERT_ALWAYS(aMaxNumLen<=KPhBkMaxTelNumSize,SimPanic(EPhonebookNameOrNumberTooLarge));
       
    79 	__ASSERT_ALWAYS(aMaxTextLen<=KPhBkMaxAlphaTagSize,SimPanic(EPhonebookNameOrNumberTooLarge));
       
    80 
       
    81 	iPhBkStoreEntries=new(ELeave) TPhBkStoreEntry[aMaxNumSlots+1]; //slot 0 is unused
       
    82 	iPhBkMaxNumSlots=aMaxNumSlots;
       
    83 	iPhBkMaxTelNumLen=aMaxNumLen;
       
    84 	iPhBkMaxTextLen=aMaxTextLen;
       
    85 	iPhBkStoreName.Copy(aName);
       
    86 
       
    87 	iReqTimer=CSimTimer::NewL(iPhone);
       
    88 	iOOBWriteTimer=CSimTimer::NewL(iPhone);
       
    89 	iOOBDeleteTimer=CSimTimer::NewL(iPhone);
       
    90 	iPhBkRwBuffer=new(ELeave) CPhoneBookBuffer();
       
    91 	iPhBkError=new(ELeave) CArrayFixFlat<TPhBkError>(KPhonebookErrorGranularity);
       
    92 
       
    93 	const CTestConfigItem* item=NULL;
       
    94 	TInt ret=KErrNone;
       
    95 	item=CfgFile()->Item(KTriggerEventIPC,0);
       
    96 	if(item)
       
    97 		{
       
    98 		TInt ipc, cnt, event;
       
    99 
       
   100 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,ipc);
       
   101 		if(ret!=KErrNone)
       
   102 			{
       
   103 			LOGPARSERR("ipc",ret,0,&KTriggerEventIPC);
       
   104 			}
       
   105 		else
       
   106 			iTriggerEventIPC.iIPC=ipc;
       
   107 
       
   108 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,cnt);
       
   109 		if(ret!=KErrNone)
       
   110 			{
       
   111 			LOGPARSERR("cnt",ret,1,&KTriggerEventIPC);
       
   112 			}
       
   113 		else
       
   114 			iTriggerEventIPC.iIPCCnt=cnt;
       
   115 		
       
   116 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,event);
       
   117 		if(ret!=KErrNone)
       
   118 			{
       
   119 			LOGPARSERR("event",ret,2,&KTriggerEventIPC);
       
   120 			}
       
   121 		else
       
   122 			iTriggerEventIPC.iEvent=RMobilePhone::TMobilePhoneSecurityEvent(event);
       
   123 
       
   124 		
       
   125 		}
       
   126 
       
   127 	const CTestConfigItem* item0=NULL;
       
   128 	item0=CfgFile()->Item(KPhBkPhoneStoreCaps,0);
       
   129 	if (item0)
       
   130 		{
       
   131 		TPtrC8 value0;
       
   132 		TInt ret0=CTestConfig::GetElement(item0->Value(),KStdDelimiter,0,value0);
       
   133 		if(ret0!=KErrNone)
       
   134 			{
       
   135 			iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
       
   136 			LOGPARSERR("value0",ret0,0,&KPhBkPhoneStoreCaps);
       
   137 			}	
       
   138 		else
       
   139 			{
       
   140 			TUint32 intValue;
       
   141 			TInt ret = AsciiToNum(value0, intValue);
       
   142 			if(ret!=KErrNone)
       
   143 				iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
       
   144 			else
       
   145 				iPhBkStoreCaps = intValue;
       
   146 			}
       
   147 		}
       
   148 	else
       
   149 		iPhBkStoreCaps=KDefaultPhBkPhoneStoreCaps;
       
   150 
       
   151 
       
   152 	LOGPHBK1("...Finished parsing Phonebook store additional config parameters...");
       
   153 	}
       
   154 
       
   155 void CSimPhBkStore::PopulateStoreFromConfigFileL()
       
   156 /**
       
   157  * Populate the Phonebook Store from information in the configuration file.  This is performed
       
   158  * after the standard Phonebook Store construction in order to prevent reseting the configuation
       
   159  * file accessor class' pointers while possibly multiple Phonebook Stores are created.
       
   160  *
       
   161  * The store entries comply to the following format:
       
   162  * "PhBkStoreEntry = <store name>, <slot number>, <telephone number>, <alphatag>"
       
   163  */
       
   164 	{
       
   165 	LOGPHBK1("Starting to read Phonebook store entries...");
       
   166 	iPhBkIndividualPause=CfgFile()->ItemValue(KPhBkStoreIndividualReqPause,KDefaultPhBkStoreIndividualReqPause);
       
   167 	iPhBkBatchPause=CfgFile()->ItemValue(KPhBkStoreBatchReqPause,KDefaultPhBkStoreBatchReqPause);
       
   168 
       
   169 	TInt count=CfgFile()->ItemCount(KPhBkStoreEntry);
       
   170 	const CTestConfigItem* item=NULL;
       
   171 	TInt ret=KErrNone;
       
   172 
       
   173 	TInt i;
       
   174 	for(i=0;i<count;i++)
       
   175 		{
       
   176 		item=CfgFile()->Item(KPhBkStoreEntry,i);
       
   177 		if(!item)
       
   178 			break;
       
   179 
       
   180 		TPtrC8 phonebookName,alphaTag,telNum;
       
   181 		TInt index;
       
   182 		TUint8 npiTon;
       
   183 		ret=GetPhBkEntry(item,0,phonebookName,index,telNum,alphaTag,npiTon);
       
   184 		if(ret!=KErrNone)
       
   185 			{
       
   186 			LOGPARSERR("Phonebook Entry",ret,index,&KPhBkStoreEntry);
       
   187 			continue;
       
   188 			}
       
   189 		if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
       
   190 			continue;
       
   191 
       
   192 		iPhBkStoreEntries[index].iAlphaTag.Copy(alphaTag);
       
   193 		iPhBkStoreEntries[index].iTelNum.Copy(telNum);
       
   194 		iPhBkStoreEntries[index].iTonNpi=npiTon;
       
   195 		}
       
   196 
       
   197 	count=CfgFile()->ItemCount(KPhBkError);
       
   198 	item=NULL;
       
   199 
       
   200 	for(i=0;i<count;i++)
       
   201 		{
       
   202 		item=CfgFile()->Item(KPhBkError,i);
       
   203 		if(!item)
       
   204 			break;
       
   205 
       
   206 		TInt count,error;
       
   207 		TPtrC8 phonebookName, phonebookStore;
       
   208 		
       
   209 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
       
   210 		if(ret!=KErrNone)
       
   211 			{
       
   212 			LOGPARSERR("count",ret,0,&KPhBkError);
       
   213 			continue;
       
   214 			}
       
   215 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,error);
       
   216 		if(ret!=KErrNone)
       
   217 			{
       
   218 			LOGPARSERR("error",ret,1,&KPhBkError);
       
   219 			continue;
       
   220 			}	
       
   221 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,phonebookName);
       
   222 		if(ret!=KErrNone)
       
   223 			{
       
   224 			LOGPARSERR("phonebookName",ret,2,&KPhBkError);
       
   225 			continue;
       
   226 			}
       
   227 		ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,phonebookStore);
       
   228 		if(ret!=KErrNone)
       
   229 			{
       
   230 			LOGPARSERR("phonebookStore",ret,3,&KPhBkError);
       
   231 			}
       
   232 		else  //not for the global phonebook
       
   233 			continue;
       
   234 
       
   235 		if(phonebookName.MatchF(iPhBkStoreName)!=0)// Not this phonebook
       
   236 			continue;
       
   237 
       
   238 
       
   239 		TPhBkError entry;
       
   240 		entry.iCount=count;
       
   241 		entry.iError=error;
       
   242 		iPhBkError->AppendL(entry);
       
   243 		}
       
   244 	PopulateOOBWrite();
       
   245 	PopulateOOBDelete();
       
   246 	LOGPHBK1("...Finished reading Phonebook store entries...");
       
   247 
       
   248 	if(iPhBkOOBWriteDuration!=-1)
       
   249 		iOOBWriteTimer->Start(iPhBkOOBWriteDuration,this,ETimerIdPhBkStorOOBWrite);
       
   250 	if(iPhBkOOBDeleteDuration!=-1)
       
   251 		iOOBDeleteTimer->Start(iPhBkOOBDeleteDuration,this,ETimerIdPhBkStorOOBDelete);
       
   252 	}
       
   253 
       
   254 void CSimPhBkStore::PopulateOOBWrite()
       
   255 /**
       
   256  * Populate the member variables required to operate the OOB Store functionality from
       
   257  * the configuration file.
       
   258  * The OOBPhBkStore configuration file tag should have the following format:
       
   259  * "OOBPhBkStore= <duration>, <phonebook name>, <index>, <telephone number>, <alpha tag>"
       
   260  */
       
   261 	{
       
   262 	iPhBkOOBWriteDuration=KErrNotFound;
       
   263 	const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkWrite);
       
   264 	if(!item)
       
   265 		return;
       
   266 
       
   267 	TInt count;
       
   268 	TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
       
   269 	if(ret!=KErrNone)
       
   270 		{
       
   271 		LOGPARSERR("count",ret,0,&KOOBPhBkWrite);
       
   272 		return;
       
   273 		}
       
   274 
       
   275 	TPtrC8 phonebookName,alphaTag,telNum;
       
   276 	TInt index;
       
   277 	TUint8 npiTon;
       
   278 	ret=GetPhBkEntry(item,1,phonebookName,index,telNum,alphaTag,npiTon);
       
   279 	if(ret!=KErrNone)
       
   280 		{
       
   281 		LOGPARSERR("npiTon",ret,index,&KOOBPhBkWrite);
       
   282 		return;
       
   283 		}
       
   284 	if(phonebookName.MatchF(iPhBkStoreName)!=0)
       
   285 		return;						// Not this phonebook
       
   286 
       
   287 	iPhBkOOBWriteDuration=count;
       
   288 	iPhBkOOBWriteIndex=index;
       
   289 	iPhBkOOBWrite.iAlphaTag.Copy(alphaTag);
       
   290 	iPhBkOOBWrite.iTelNum.Copy(telNum);
       
   291 	iPhBkOOBWrite.iTonNpi=npiTon;
       
   292 	}
       
   293 
       
   294 void CSimPhBkStore::PopulateOOBDelete()
       
   295 /**
       
   296  * Populate the member variables required to operate the OOB Delete functionality from
       
   297  * the configuration file.
       
   298  * The OOBPhBkDelete configuration file tag should have the following format:
       
   299  * "OOBPhBkDelete= <duration>, <phonebook name>, <index>
       
   300  */
       
   301 	{
       
   302 	iPhBkOOBDeleteDuration=KErrNotFound;
       
   303 	const CTestConfigItem* item=CfgFile()->Item(KOOBPhBkDelete);
       
   304 	if(!item)
       
   305 		return;
       
   306 
       
   307 	TInt count;
       
   308 	TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,count);
       
   309 	if(ret!=KErrNone)
       
   310 		{
       
   311 		LOGPARSERR("count",ret,0,&KOOBPhBkDelete);
       
   312 		return;
       
   313 		}
       
   314 
       
   315 	TPtrC8 phonebookName;
       
   316 	ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,phonebookName);
       
   317 	if(ret!=KErrNone)
       
   318 		{
       
   319 		LOGPARSERR("phonebookName",ret,1,&KOOBPhBkDelete);
       
   320 		return;
       
   321 		}
       
   322 	if(phonebookName.MatchF(iPhBkStoreName)!=0)
       
   323 		return;						// Not this phonebook
       
   324 
       
   325 	TInt index;
       
   326 	ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,index);
       
   327 	if(ret!=KErrNone)
       
   328 		{
       
   329 		LOGPARSERR("index",ret,2,&KOOBPhBkDelete);
       
   330 		return;
       
   331 		}
       
   332 
       
   333 	iPhBkOOBDeleteDuration=count;
       
   334 	iPhBkOOBDeleteIndex=index;
       
   335 	}
       
   336 
       
   337 TInt CSimPhBkStore::GetPhBkEntry(const CTestConfigItem* aItem, TInt aItemIndex,
       
   338 								 TPtrC8& aPhonebookName, TInt& aIndex,
       
   339 								 TPtrC8& aTelNum, TPtrC8& aAlphaTag, TUint8& aNpiTon)
       
   340 /**
       
   341  * Retrieve a phonebook entry from the configuration file, starting at a given item index
       
   342  * value.
       
   343  * @param aItem				Pointer to the config file item from which the phonebook entry will be read.
       
   344  * @param aItemIndex		The index number within the item from which the phonebook entry will be read.
       
   345  * @param aPhonebookName	The returned phonebook name
       
   346  * @param aIndex			The returned index number
       
   347  * @param aTelNum			The returned telephone number
       
   348  * @param aAlphaTag			The returned alpha tag
       
   349  * @param aNpiTon			The returned Number Plan Identifier and Type of Number information
       
   350  * @return TInt				Standard error value.
       
   351  */
       
   352 	{
       
   353 	TInt ret;
       
   354 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aPhonebookName);
       
   355 	if(ret!=KErrNone)
       
   356 		return ret;
       
   357 
       
   358 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aIndex);
       
   359 	if(ret!=KErrNone)
       
   360 		return ret;
       
   361 
       
   362 	if(aIndex>iPhBkMaxNumSlots) //the max number of slot is a valid slot
       
   363 		return KErrArgument;
       
   364 
       
   365 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aTelNum);
       
   366 	if(ret!=KErrNone)
       
   367 		return ret;
       
   368 	if(aTelNum.Length()>iPhBkMaxTelNumLen)
       
   369 		return KErrArgument;
       
   370 
       
   371 	ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aAlphaTag);
       
   372 	if(ret!=KErrNone)
       
   373 		return ret;
       
   374 	if(aAlphaTag.Length()>iPhBkMaxTextLen)
       
   375 		return KErrArgument;
       
   376 
       
   377 	if((aTelNum.Length()>0) && (aTelNum[0]=='+'))
       
   378 		{
       
   379 		aTelNum.Set(aTelNum.Mid(1));
       
   380 		aNpiTon=KNpiTonInternational;
       
   381 		}
       
   382 	else
       
   383 		aNpiTon=KNpiTonNational;
       
   384 	return ret;
       
   385 	}
       
   386 
       
   387 CSimPhBkStore::~CSimPhBkStore()
       
   388 /**
       
   389  * Standard destructor.  Any objects created by the ::ConstructL() function
       
   390  * will be destroyed here.
       
   391  */
       
   392 	{
       
   393 	delete[] iPhBkStoreEntries;
       
   394 	delete iPhBkError;
       
   395 	delete iPhBkRwBuffer;
       
   396 	delete iOOBWriteTimer;
       
   397 	delete iOOBDeleteTimer;
       
   398 	delete iReqTimer;
       
   399 	}
       
   400 
       
   401 TInt CSimPhBkStore::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg)
       
   402 /**
       
   403  * Dispatch function for all Phonebook Store requests.
       
   404  * @param aReqHandle	The TSY request handle for this request.
       
   405  * @param aIpc			The IPC number of this request.
       
   406  * @param aPckg			The parameter package related to this request.
       
   407  * @return TInt			The return error condition.
       
   408  */
       
   409 	{
       
   410 	iIpcCnt++;
       
   411 	TInt error=KErrNone;
       
   412 	if(FindIpcErrorMatch(error))
       
   413 		{
       
   414 		ReqCompleted(aReqHandle,error);
       
   415 		return KErrNone;
       
   416 		}
       
   417 
       
   418 // The following requests can be completed even if the completion of another request is pending.
       
   419 	switch(aIpc)
       
   420 		{
       
   421 	case EMobilePhoneStoreGetInfo:
       
   422 		error = GetInfo(aReqHandle,aPckg.Des1n());
       
   423 		if(iTriggerEventIPC.iIPC==aIpc)
       
   424 			{
       
   425 			iTriggerCnt++;
       
   426 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   427 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   428 			}
       
   429 		return error;
       
   430 
       
   431 	case EMobilePhoneStoreNotifyStoreEvent:
       
   432 		error = NotifyStoreEvent(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
       
   433 		if(iTriggerEventIPC.iIPC==aIpc)
       
   434 			{
       
   435 			iTriggerCnt++;
       
   436 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   437 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   438 			}
       
   439 		return error;
       
   440 
       
   441 	default:
       
   442 		break;
       
   443 		}
       
   444 
       
   445 
       
   446 // The TSY can only process one of the following requests at a time.  If a second is received
       
   447 // while processing the first, then it will be errored with KErrInUse.  This restriction will
       
   448 // be removed later, by inserting a request queuing mechanism.  Note that the standard TSY
       
   449 // "flow control" mechanism works phone-wide and so is not suitable.
       
   450 
       
   451 	if(iReqTimer->IsActive())
       
   452 		{
       
   453 		ReqCompleted(aReqHandle,KErrInUse);
       
   454 		return KErrNone;
       
   455 		}
       
   456 
       
   457 	switch(aIpc)
       
   458 		{
       
   459 // The standard multimode store read and write are not supported.
       
   460 	case EMobilePhoneStoreRead:
       
   461 	case EMobilePhoneStoreWrite:
       
   462 	case EMobilePhoneStoreReadAllPhase1:
       
   463 	case EMobilePhoneStoreReadAllPhase2:
       
   464 		ReqCompleted(aReqHandle,KErrNotSupported);
       
   465 		return KErrNone;
       
   466 
       
   467 	case EMobilePhoneBookStoreRead:
       
   468 		 error = Read(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
       
   469 		 if(iTriggerEventIPC.iIPC==aIpc)
       
   470 			{
       
   471 			iTriggerCnt++;
       
   472 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   473 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   474 			}
       
   475 		 return error;
       
   476 			
       
   477 	case EMobilePhoneBookStoreWrite:
       
   478 		error = Write(aReqHandle,aPckg.Des1n(),aPckg.Des2n());
       
   479 		if(iTriggerEventIPC.iIPC==aIpc)
       
   480 			{
       
   481 			iTriggerCnt++;
       
   482 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   483 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   484 			}
       
   485 		 return error;
       
   486 
       
   487 	case EMobilePhoneStoreDelete:
       
   488 		error =  Delete(aReqHandle,aPckg.Des1n());
       
   489 		if(iTriggerEventIPC.iIPC==aIpc)
       
   490 			{
       
   491 			iTriggerCnt++;
       
   492 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   493 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   494 			}
       
   495 		 return error;
       
   496 
       
   497 	case EMobilePhoneStoreDeleteAll:
       
   498 		error =  DeleteAll(aReqHandle);
       
   499 		if(iTriggerEventIPC.iIPC==aIpc)
       
   500 			{
       
   501 			iTriggerCnt++;
       
   502 			if(iTriggerEventIPC.iIPCCnt==iTriggerCnt)
       
   503 				iPhone->SecurityEvent(iTriggerEventIPC.iEvent);
       
   504 			}
       
   505 		 return error;
       
   506 
       
   507 	default:
       
   508 		break;
       
   509 		}
       
   510 
       
   511 	return KErrNotSupported;
       
   512 	}
       
   513 
       
   514 CTelObject* CSimPhBkStore::OpenNewObjectByNameL(const TDesC& /*aName*/)
       
   515 /**
       
   516  * The API does not support any objects that could be opened from this one.
       
   517  */
       
   518 	{
       
   519 	User::Leave(KErrNotSupported);
       
   520 	return NULL;
       
   521 	}
       
   522 
       
   523 CTelObject* CSimPhBkStore::OpenNewObjectL(TDes&)
       
   524 /**
       
   525  * The API does not support any objects that could be opened from this one.
       
   526  */
       
   527 	{
       
   528 	User::Leave(KErrNotSupported);
       
   529 	return NULL;
       
   530 	}
       
   531 
       
   532 CTelObject::TReqMode CSimPhBkStore::ReqModeL(const TInt aIpc)
       
   533 /**
       
   534  * This function returns the Request Mode for the request with the passed IPC value.
       
   535  * @param aIpc		The IPC number of the request.
       
   536  * @return TReqMode	The request mode.
       
   537  */
       
   538 	{
       
   539 	CTelObject::TReqMode ret=0;	
       
   540 
       
   541 	switch(aIpc)
       
   542 		{
       
   543 	case EMobilePhoneStoreGetInfo:
       
   544 	case EMobilePhoneStoreDelete:
       
   545 	case EMobilePhoneStoreDeleteAll:
       
   546 	case EMobilePhoneBookStoreRead:
       
   547 	case EMobilePhoneBookStoreWrite:
       
   548 		break;
       
   549 
       
   550 	case EMobilePhoneStoreNotifyStoreEvent:
       
   551 		ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately;
       
   552 		break;
       
   553 
       
   554 	default:
       
   555 		User::Leave(KErrNotSupported);
       
   556 		break;
       
   557 		}
       
   558 
       
   559 	return ret;
       
   560 	}
       
   561 
       
   562 TInt CSimPhBkStore::RegisterNotification(const TInt /*aIpc*/)
       
   563 /**
       
   564  * The ETel Server calls this function when the first client makes a notification
       
   565  * request.  If supported by the underlying protocol controlling the
       
   566  * signalling stack, this can be used to start requesting updates for the relevant
       
   567  * service.
       
   568  */
       
   569 	{
       
   570 	return KErrNone;
       
   571 	}
       
   572 
       
   573 TInt CSimPhBkStore::DeregisterNotification(const TInt /*aIpc*/)
       
   574 /**
       
   575  * The ETel Server calls this function when the last client that had previously
       
   576  * made a notification request closes its ETel Server handle.  If supported by
       
   577  * the underlying protocol controlling the	signalling stack, this can be used
       
   578  * to stop requesting updates for the relevant service.
       
   579  */
       
   580 	{
       
   581 	return KErrNone;
       
   582 	}
       
   583 
       
   584 TInt CSimPhBkStore::NumberOfSlotsL(const TInt /*aIpc*/)
       
   585 /**
       
   586  * Return the number of slots that the ETel Server should allocate for buffering requests
       
   587  * of the given IPC number.
       
   588  */
       
   589 	{
       
   590 	return KDefaultNumberOfSlots;
       
   591 	}
       
   592 
       
   593 TInt CSimPhBkStore::CancelService(const TInt aIpc,const TTsyReqHandle /*aTsyReqHandle*/)
       
   594 /**
       
   595  * Cancel an outstanding request.
       
   596  * @param aIpc			The IPC number of the request that is to be cancelled.
       
   597  * @param aTsyReqHandle	The TSY request handle of the request that is to be cancelled.
       
   598  * @param TInt			Standard return value.
       
   599  */
       
   600 	{
       
   601 	switch(aIpc)
       
   602 		{
       
   603 	case EMobilePhoneStoreGetInfo:
       
   604 	case EMobilePhoneStoreDelete:
       
   605 	case EMobilePhoneStoreDeleteAll:
       
   606 	case EMobilePhoneBookStoreRead:
       
   607 	case EMobilePhoneBookStoreWrite:
       
   608 		break;
       
   609 
       
   610 	case EMobilePhoneStoreNotifyStoreEvent:
       
   611 		NotifyStoreEventCancel();
       
   612 		break;
       
   613 
       
   614 	default:
       
   615 		break;
       
   616 		}
       
   617 	return KErrNone;
       
   618 	}
       
   619 
       
   620 void CSimPhBkStore::Init()
       
   621 /**
       
   622  *	This function can be used to perform any necessary synchronous initialisation.
       
   623  */
       
   624 	{
       
   625 	}
       
   626 
       
   627 TInt CSimPhBkStore::GetInfo(TTsyReqHandle aReqHandle, TDes8* aPckg)
       
   628 /**
       
   629  * Retrieve Phonebook Store information. This request is completed immediately, as it is assumed
       
   630  * that in a real TSY, all this data will be cached in the TSY.
       
   631  *
       
   632  * @param aReqHandle	The TSY request handle associated with this request.
       
   633  * @param aPckg			The parameter package associated with this request.
       
   634  */
       
   635 	{
       
   636 
       
   637 	if(iPhone->IsICCLocked()!=EFalse)
       
   638 		{
       
   639 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
   640 		return KErrNone;
       
   641 		}
       
   642 
       
   643 	RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg* getInfoPckg=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg*)aPckg;
       
   644 	RMobilePhoneBookStore::TMobilePhoneBookInfoV1& getInfo=(*getInfoPckg)();
       
   645 
       
   646 	PopulatePhBkStoreInfo(&getInfo);
       
   647 
       
   648 	if(&getInfo!=NULL) // This will be the case if the version checking within PopulatePhBkStoreInfo has failed.
       
   649 		{
       
   650 		ReqCompleted(aReqHandle,KErrNone);
       
   651 		}
       
   652 	else
       
   653 		{
       
   654 		ReqCompleted(aReqHandle,KErrNotSupported);
       
   655 		}
       
   656 
       
   657 	return KErrNone;
       
   658 	}
       
   659 
       
   660 void CSimPhBkStore::PopulatePhBkStoreInfo(RMobilePhoneStore::TMobilePhoneStoreInfoV1* aStoreInfo)
       
   661 /**
       
   662  * Populate the passed parameter with Phonebook Store information.
       
   663  * @param aStoreInfo	Pointer to phonebook store information structure to be populated.
       
   664  */
       
   665 	{
       
   666 	__ASSERT_ALWAYS(aStoreInfo, SimPanic(EIllegalNullPtrParameter));
       
   667 	
       
   668 	aStoreInfo->iType=RMobilePhoneStore::EPhoneBookStore;
       
   669 	aStoreInfo->iTotalEntries=MaxSlots();
       
   670 	aStoreInfo->iCaps=iPhBkStoreCaps;
       
   671 	aStoreInfo->iName.Copy(iPhBkStoreName);
       
   672 	aStoreInfo->iUsedEntries=UsedEntries();
       
   673 
       
   674 	if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV1)
       
   675 		{
       
   676 		RMobilePhoneBookStore::TMobilePhoneBookInfoV1* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV1*)aStoreInfo;
       
   677 
       
   678 		// Check that the data structure is supported by the simulated TSY version
       
   679 		TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
       
   680 		if(err != KErrNone)
       
   681 			{
       
   682 			getExtraInfo = NULL;
       
   683 			return;
       
   684 			}
       
   685 
       
   686 		getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
       
   687 		getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
       
   688 		getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
       
   689 		getExtraInfo->iChangeCounter=0;
       
   690 		getExtraInfo->iIdentity.Copy(iPhone->GetImsi());		
       
   691 		}
       
   692 	else if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV2)
       
   693 		{
       
   694 		RMobilePhoneBookStore::TMobilePhoneBookInfoV2* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV2*)aStoreInfo;
       
   695 
       
   696 		// Check that the data structure is supported by the simulated TSY version
       
   697 		TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
       
   698 		if(err != KErrNone)
       
   699 			{
       
   700 			getExtraInfo = NULL;
       
   701 			return;
       
   702 			}
       
   703 
       
   704 		getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
       
   705 		getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
       
   706 		getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
       
   707 		getExtraInfo->iChangeCounter=0;
       
   708 		getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
       
   709 
       
   710 		getExtraInfo->iPhBkMode.Zero();		
       
   711 		}
       
   712 	else if(aStoreInfo->ExtensionId()==RMobilePhoneStore::KETelMobilePhonebookStoreV5)
       
   713 		{
       
   714 		RMobilePhoneBookStore::TMobilePhoneBookInfoV5* getExtraInfo=(RMobilePhoneBookStore::TMobilePhoneBookInfoV5*)aStoreInfo;
       
   715 
       
   716 		// Check that the data structure is supported by the simulated TSY version
       
   717 		TInt err = iPhone->CheckSimTsyVersion(*getExtraInfo);
       
   718 		if(err != KErrNone)
       
   719 			{
       
   720 			getExtraInfo = NULL;
       
   721 			return;
       
   722 			}
       
   723 
       
   724 		getExtraInfo->iMaxNumLength=iPhBkMaxTelNumLen;
       
   725 		getExtraInfo->iMaxTextLength=iPhBkMaxTextLen;
       
   726 		getExtraInfo->iLocation=RMobilePhoneBookStore::ELocationIccMemory;
       
   727 		getExtraInfo->iChangeCounter=0;
       
   728 		getExtraInfo->iIdentity.Copy(iPhone->GetImsi());
       
   729 
       
   730 		getExtraInfo->iPhBkMode.Zero();
       
   731 
       
   732 		getExtraInfo->iMaxSecondNames = 0;
       
   733 		getExtraInfo->iMaxTextLengthSecondName = 0;
       
   734 		getExtraInfo->iMaxAdditionalNumbers = 0;
       
   735 		getExtraInfo->iMaxTextLengthAdditionalNumber = 0;
       
   736 		getExtraInfo->iMaxNumLengthAdditionalNumber = 0;
       
   737 		getExtraInfo->iMaxGroupNames = 0;
       
   738 		getExtraInfo->iMaxTextLengthGroupName = 0;
       
   739 		getExtraInfo->iMaxEmailAddr = 0;
       
   740 		getExtraInfo->iMaxTextLengthEmailAddr = 0;
       
   741 		}	
       
   742 	}
       
   743 
       
   744 TInt CSimPhBkStore::Read(TTsyReqHandle aReqHandle, TDes8* aPckg1,TDes8* aPckg2)
       
   745 /**
       
   746  * Read Phonebook store entries.  The completion of this request is delayed in order to
       
   747  * simulate a real TSY that would have to go and get the information from a SIM card.
       
   748  *
       
   749  * @param aReqHandle	The TSY request handle associated with this request.
       
   750  * @param aPckg1		The first parameter package associated with this request.
       
   751  *						It contains the index from which the read should start and
       
   752  *						the number of entries which should be read.
       
   753  * @param aPckg2		The second parameter package associated with this request.
       
   754  *						It contains the buffer, which will be populated with the retrieved
       
   755  *						values.
       
   756  * @return TInt			Standard return value.
       
   757  */
       
   758 	{
       
   759 	if(iPhone->IsICCLocked()!=EFalse)
       
   760 		{
       
   761 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
   762 		return KErrNone;
       
   763 		}
       
   764 
       
   765 	TPckg<RMobilePhoneBookStore::TPBIndexAndNumEntries>* indexNumPckg=(TPckg<RMobilePhoneBookStore::TPBIndexAndNumEntries>*)aPckg1;
       
   766 	RMobilePhoneBookStore::TPBIndexAndNumEntries& indexNum=(*indexNumPckg)();
       
   767 
       
   768 	if(indexNum.iNumSlots==iPhBkMaxNumSlots)
       
   769 		{
       
   770 		if (!(iPhBkStoreCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsReadAccess))
       
   771 			{
       
   772 			ReqCompleted(aReqHandle, KErrAccessDenied);
       
   773 			return KErrNone;
       
   774 			}
       
   775 		}
       
   776 	else if((indexNum.iIndex+indexNum.iNumSlots - 1)>iPhBkMaxNumSlots)
       
   777 			{
       
   778 			ReqCompleted(aReqHandle,KErrArgument);
       
   779 			return KErrNone;
       
   780 			}
       
   781 
       
   782 	else if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsReadAccess))
       
   783 			{
       
   784 			ReqCompleted(aReqHandle, KErrAccessDenied);
       
   785 			return KErrNone;
       
   786 			}
       
   787 		
       
   788 	iPhBkRwBuffer->Set(aPckg2);
       
   789 
       
   790 	TInt cnt=0;
       
   791 	TInt ret=0;
       
   792 	TBool partial=EFalse;
       
   793 	for(TInt i=indexNum.iIndex;i<=iPhBkMaxNumSlots;i++)
       
   794 		{
       
   795 		if((iPhBkStoreEntries[i].iTelNum.Length()!=0)||(iPhBkStoreEntries[i].iAlphaTag.Length()!=0))
       
   796 			{
       
   797 			ret=iPhBkRwBuffer->AddNewEntryTag();
       
   798 			if(ret!=KErrNone)
       
   799 				break;
       
   800 
       
   801 			partial=ETrue;
       
   802 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)i);
       
   803 			if(ret!=KErrNone)
       
   804 				break;
       
   805 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText,iPhBkStoreEntries[i].iAlphaTag);
       
   806 			if(ret!=KErrNone)
       
   807 				break;
       
   808 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi,iPhBkStoreEntries[i].iTonNpi);
       
   809 			if(ret!=KErrNone)
       
   810 				break;
       
   811 			ret=iPhBkRwBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber,iPhBkStoreEntries[i].iTelNum);
       
   812 			if(ret!=KErrNone)
       
   813 				break;
       
   814 
       
   815 			partial=EFalse;
       
   816 			if(++cnt>=indexNum.iNumSlots)
       
   817 				break;
       
   818 			}
       
   819 		}
       
   820 	if(partial)
       
   821 		// EXPORT - but return value not relevant
       
   822 		(void)iPhBkRwBuffer->RemovePartialEntry();
       
   823 
       
   824 	indexNum.iNumSlots=cnt;
       
   825 
       
   826 	if((cnt==0)&&(partial))
       
   827 		ReqCompleted(aReqHandle,KErrArgument);		// An entry was found, but the buffer was too small to return it.
       
   828 	else if((cnt==0)&&(!partial))
       
   829 		ReqCompleted(aReqHandle,KErrNotFound);		// No entries found.
       
   830 	else
       
   831 		ReqCompleted(aReqHandle,KErrNone);
       
   832 
       
   833 	return KErrNone;
       
   834 	}
       
   835 
       
   836 TInt CSimPhBkStore::Write(TTsyReqHandle aReqHandle,TDes8* aPckg1,TDes8* aPckg2)
       
   837 /**
       
   838  * Write a phonebook store entries.  The completion of this request is delayed in order to
       
   839  * simulate a real TSY that would have to write the information to a SIM card. A store
       
   840  * event may be triggered by this request.
       
   841  *
       
   842  * @param aReqHandle	The TSY request handle associated with this request.
       
   843  * @param aPckg1		The first parameter package associated with this request.
       
   844  *						This contains the TLV phonebook entry to be written.
       
   845  * @param aPckg2		The second parameter package associated with this request.
       
   846  *						This contains the slot index number to which the entry must be written.
       
   847  */
       
   848 	{
       
   849 	if(iPhone->IsICCLocked()!=EFalse)
       
   850 		{
       
   851 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
   852 		return KErrNone;
       
   853 		}
       
   854 	
       
   855 	if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
       
   856 		{
       
   857 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
   858 		return KErrNone;
       
   859 		}
       
   860 
       
   861 	TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg2;
       
   862 	TInt& index=(*indexPckg)();
       
   863 
       
   864 // If the index is -1, then use the first available free slot.
       
   865 	if(index==-1)
       
   866 		{
       
   867 		for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
       
   868 			{
       
   869 			if((iPhBkStoreEntries[i].iTelNum.Length()==0)&&(iPhBkStoreEntries[i].iAlphaTag.Length()==0))
       
   870 				{
       
   871 				index=i;
       
   872 				break;
       
   873 				}
       
   874 			}
       
   875 		}
       
   876 
       
   877 	if(index==-1)
       
   878 		{
       
   879 		ReqCompleted(aReqHandle,EXTENDEDERROR(KErrNoMemory, KErrPhonebookNoMemory));
       
   880 		return KErrNone;
       
   881 		}
       
   882 
       
   883 	if((index<1)||(index>iPhBkMaxNumSlots))
       
   884 		{
       
   885 		ReqCompleted(aReqHandle,KErrArgument);
       
   886 		return KErrNone;
       
   887 		}
       
   888 
       
   889 	TBool isSlotAlreadyUsed=EFalse;
       
   890 	if(iPhBkStoreEntries[index].iTelNum.Length()!=0)
       
   891 		isSlotAlreadyUsed=ETrue;
       
   892 
       
   893 // Unpick the phonebook entry.
       
   894 	iPhBkRwBuffer->Set(aPckg1);
       
   895 	iPhBkRwBuffer->StartRead();
       
   896 
       
   897 	TUint8 tagVal;
       
   898 	TUint8 npiTon=0;
       
   899 	TPtrC alphaTag;
       
   900 	TPtrC telNum;
       
   901 	TPtrC alphaTag2;
       
   902 	TBool skipToNextEntry=EFalse;		
       
   903 	CPhoneBookBuffer::TPhBkTagType tagType;
       
   904 	TInt ret=KErrNone;
       
   905 
       
   906 	while(ret==KErrNone)
       
   907 		{	
       
   908 		ret=iPhBkRwBuffer->GetTagAndType(tagVal,tagType);
       
   909 		if(ret==KErrNotFound)
       
   910 			{
       
   911 			ret=KErrNone;
       
   912 			break;
       
   913 			}
       
   914 		else if(ret!=KErrNone)
       
   915 			break;
       
   916 
       
   917 	
       
   918 		switch(tagVal)
       
   919 			{
       
   920 		case RMobilePhoneBookStore::ETagPBNewEntry:
       
   921 			skipToNextEntry=EFalse;
       
   922 			break;
       
   923 
       
   924 		case RMobilePhoneBookStore::ETagPBText:
       
   925 			if(!skipToNextEntry)
       
   926 				ret=iPhBkRwBuffer->GetValue(alphaTag);
       
   927 			else
       
   928 				{
       
   929 				TPtrC throwAway;
       
   930 				ret=iPhBkRwBuffer->GetValue(throwAway);
       
   931 				}
       
   932 			break;
       
   933 
       
   934 		case RMobilePhoneBookStore::ETagPBNumber:
       
   935 			if(!skipToNextEntry)
       
   936 				ret=iPhBkRwBuffer->GetValue(telNum);
       
   937 			else
       
   938 				{
       
   939 				TPtrC throwAway;
       
   940 				ret=iPhBkRwBuffer->GetValue(throwAway);
       
   941 				}
       
   942 			break;
       
   943 
       
   944 		case RMobilePhoneBookStore::ETagPBTonNpi:
       
   945 			if(!skipToNextEntry)
       
   946 				ret=iPhBkRwBuffer->GetValue(npiTon);
       
   947 			else
       
   948 				{
       
   949 				TUint8 throwAway;
       
   950 				ret=iPhBkRwBuffer->GetValue(throwAway);
       
   951 				}
       
   952 			break;
       
   953 		
       
   954 		// Alexandros - phbksync "shortcut" should be discussed and removed
       
   955 		case RMobilePhoneBookStore::ETagPBAnrStart:
       
   956 			skipToNextEntry=ETrue;
       
   957 			break;
       
   958 
       
   959 		case RMobilePhoneBookStore::ETagPBEmailAddress:
       
   960 		case RMobilePhoneBookStore::ETagPBGroupName:
       
   961 		case RMobilePhoneBookStore::ETagPBSecondName:
       
   962 			ret=iPhBkRwBuffer->GetValue(alphaTag2);
       
   963 			break;
       
   964 		case RMobilePhoneBookStore::ETagPBHiddenInfo:
       
   965 			TUint8 throwAway;
       
   966 			ret=iPhBkRwBuffer->GetValue(throwAway);
       
   967 			break;
       
   968 		
       
   969 		default:
       
   970 			//DEF001769 - SIM TSY should ignore extra fields in short entries
       
   971 			//ret=KErrNotSupported;
       
   972 			break;
       
   973 			}
       
   974 		}
       
   975 
       
   976 	if(ret!=KErrNone)
       
   977 		{
       
   978 		ReqCompleted(aReqHandle,ret);
       
   979 		return KErrNone;
       
   980 		}
       
   981 
       
   982 	LOGPHBK2("alphaTag Length = (%d)",alphaTag.Length());
       
   983 	LOGPHBK2("Phonebook Max Text Length = (%d)",iPhBkMaxTextLen);
       
   984 	LOGPHBK2("TelNum Length = (%d)",telNum.Length());
       
   985 	LOGPHBK2("TelNum Max Length = (%d)",iPhBkMaxTelNumLen);
       
   986 
       
   987 	if(alphaTag.Length()>iPhBkMaxTextLen)
       
   988 		{
       
   989 		ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookTextOverflow));
       
   990 		return KErrNone;
       
   991 		}
       
   992 	else if(telNum.Length()>iPhBkMaxTelNumLen)
       
   993 		{
       
   994 		ReqCompleted(aReqHandle, EXTENDEDERROR(KErrOverflow, KErrPhonebookNumberOverflow));
       
   995 		return KErrNone;
       
   996 		}
       
   997 
       
   998 	iPhBkStoreEntries[index].iAlphaTag.Copy(alphaTag);
       
   999 	iPhBkStoreEntries[index].iTelNum.Copy(telNum);
       
  1000 	iPhBkStoreEntries[index].iTonNpi=npiTon;
       
  1001 	if(isSlotAlreadyUsed)
       
  1002 		DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventChanged,index);
       
  1003 	else
       
  1004 		DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventAdded,index);
       
  1005 	return KErrNone;
       
  1006 	}
       
  1007 
       
  1008 TInt CSimPhBkStore::Delete(TTsyReqHandle aReqHandle,TDes8* aPckg)
       
  1009 /**
       
  1010  * Delete a single Phonebook store entry.  The completion of this request is delayed in order to
       
  1011  * simulate a real TSY that would have to write the information to a SIM card. A store
       
  1012  * event may be triggered by this request.
       
  1013  *
       
  1014  * @param aReqHandle	The TSY request handle associated with this request.
       
  1015  * @param aPckg			The parameter package associated with this request.
       
  1016  * @return				Standard return value.
       
  1017  */
       
  1018 	{
       
  1019 	if(iPhone->IsICCLocked()!=EFalse)
       
  1020 		{
       
  1021 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1022 		return KErrNone;
       
  1023 		}
       
  1024 	
       
  1025 	if (!(iPhBkStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
       
  1026 		{
       
  1027 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1028 		return KErrNone;
       
  1029 		}
       
  1030 
       
  1031 
       
  1032 	TPckg<TInt>* intPckg=(TPckg<TInt>*)aPckg;
       
  1033 	TInt& index=(*intPckg)();
       
  1034 
       
  1035 	if((index<1)||(index>iPhBkMaxNumSlots))
       
  1036 		{
       
  1037 		ReqCompleted(aReqHandle,KErrArgument);
       
  1038 		return KErrNone;
       
  1039 		}
       
  1040 
       
  1041 	iPhBkStoreEntries[index].iTelNum.Zero();
       
  1042 	iPhBkStoreEntries[index].iAlphaTag.Zero();
       
  1043 	DelayCompletion(iPhBkIndividualPause,aReqHandle,EStoreEventDeleted,index);
       
  1044 	return KErrNone;
       
  1045 	}
       
  1046 
       
  1047 TInt CSimPhBkStore::DeleteAll(TTsyReqHandle aReqHandle)
       
  1048 /**
       
  1049  * Delete all entries in the Phonebook Store.  The completion of this function is delayed in
       
  1050  * order to simulate the SIM operations a real TSY would have to carry out.  This function
       
  1051  * may trigger an Phonebook Store notification.
       
  1052  *
       
  1053  * @param aReqHandle	The TSY request handle associated with this request.
       
  1054  * @return				Standard return value.
       
  1055  */
       
  1056 	{
       
  1057 	if(iPhone->IsICCLocked()!=EFalse)
       
  1058 		{
       
  1059 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1060 		return KErrNone;
       
  1061 		}
       
  1062 
       
  1063 	if (!(iPhBkStoreCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) && iPhBkStoreCaps & RMobilePhoneStore::KCapsWriteAccess))
       
  1064 		{
       
  1065 		ReqCompleted(aReqHandle, KErrAccessDenied);
       
  1066 		return KErrNone;
       
  1067 		}
       
  1068 
       
  1069 	for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
       
  1070 		{
       
  1071 		iPhBkStoreEntries[i].iTelNum.Zero();
       
  1072 		iPhBkStoreEntries[i].iAlphaTag.Zero();
       
  1073 		}
       
  1074 	DelayCompletion(iPhBkBatchPause,aReqHandle,EStoreEventDeleted,-1);
       
  1075 	return KErrNone;
       
  1076 	}
       
  1077 
       
  1078 TInt CSimPhBkStore::NotifyStoreEvent(TTsyReqHandle aReqHandle,TDes8* aPckg1,TDes8* aPckg2)
       
  1079 /**
       
  1080  * Register a client's interest in Phonebook Store events.
       
  1081  *
       
  1082  * @param aReqHandle	The TSY request handle associated with this request.
       
  1083  * @param aPckg1		The first parameter package associated with this request.
       
  1084  *						It contains the event flags that will be returned to the client.
       
  1085  * @param aPckg2		The second parameter package associated with this request.
       
  1086  *						It contains the index value associated with the event
       
  1087  *						that will be returned to the client.
       
  1088  * @return				Standard return value.
       
  1089  */
       
  1090 	{
       
  1091 	TPckg<TUint32>* eventPckg=(TPckg<TUint32>*)aPckg1;
       
  1092 	TUint32& event=(*eventPckg)();
       
  1093 	TPckg<TInt>* indexPckg=(TPckg<TInt>*)aPckg2;
       
  1094 	TInt& index=(*indexPckg)();
       
  1095 
       
  1096 	iEvOutstandingReq=ETrue;
       
  1097 	iEvReqHandle=aReqHandle;
       
  1098 	iEvEvent=&event;
       
  1099 	iEvIndex=&index;
       
  1100 	return KErrNone;
       
  1101 	}
       
  1102 
       
  1103 void CSimPhBkStore::NotifyStoreEventCancel()
       
  1104 /**
       
  1105  * Cancel an outstanding notify store request.
       
  1106  */
       
  1107 	{
       
  1108 	if(iEvOutstandingReq)
       
  1109 		{
       
  1110 		iEvOutstandingReq=EFalse;
       
  1111 		ReqCompleted(iEvReqHandle,KErrCancel);
       
  1112 		}
       
  1113 	}
       
  1114 
       
  1115 TPtrC8 CSimPhBkStore::Name()
       
  1116 /**
       
  1117  * Accessor function fot the Phonebook Store name.
       
  1118  *
       
  1119  * @return TPtrC8	The name of this Phonebook Store.
       
  1120  */
       
  1121 	{
       
  1122 	return iPhBkStoreName;
       
  1123 	}
       
  1124 
       
  1125 TInt CSimPhBkStore::UsedEntries()
       
  1126 /**
       
  1127  * Count the number of used entries in the Phonebook Store.
       
  1128  * @return TInt	The number of used entries in the store.
       
  1129  */
       
  1130 	{
       
  1131 	TInt cnt=0;
       
  1132 	for(TInt i=1;i<=iPhBkMaxNumSlots;i++)
       
  1133 		{
       
  1134 		if((iPhBkStoreEntries[i].iTelNum.Length()!=0)||(iPhBkStoreEntries[i].iAlphaTag.Length()!=0))
       
  1135 			cnt++;
       
  1136 		}
       
  1137 	return cnt;
       
  1138 	}
       
  1139 
       
  1140 TInt CSimPhBkStore::MaxSlots()
       
  1141 /**
       
  1142  * Retrieve the maximum number of slots in this Phonebook Store.
       
  1143  * @return TInt	The maximum number of slots in this Phonebook Store.
       
  1144  */
       
  1145 	{
       
  1146 	return iPhBkMaxNumSlots;
       
  1147 	}
       
  1148 
       
  1149 void CSimPhBkStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle)
       
  1150 /**
       
  1151  * A shell function for functions that wish to delay completion but do not trigger store
       
  1152  * events.
       
  1153  */
       
  1154 	{
       
  1155 	DelayCompletion(aDelayDuration,aReqHandle,EStoreEventNoEvent,0);
       
  1156 	}
       
  1157 
       
  1158 void CSimPhBkStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle,TStoreEvent aEvent,TInt aIndex)
       
  1159 /**
       
  1160  * Delay the completion of a TSY request.  It is assumed that the member variable
       
  1161  * manipulation associated with the request has already taken place, and so all that is
       
  1162  * left to do is call the ETel server's request completion function when the timer expires.
       
  1163  * So, just record the parameters and kick off the timer.
       
  1164  *
       
  1165  * @param aDelayDuration	The time (in seconds) for which the request completion is to be delayed.
       
  1166  * @param aReqHandle		The TSY request handle related to the delayed completion.
       
  1167  * @param aEvent			The store event related to the delayed completion.
       
  1168  * @param aIndex			The index related to the event passed in aEvent.
       
  1169  */
       
  1170 	{
       
  1171 	iPendingReqCompletion=aReqHandle;
       
  1172 	iPendingEvent=aEvent;
       
  1173 	iPendingIndex=aIndex;
       
  1174 	iReqTimer->Start(aDelayDuration,this,ETimerIdPhBkStorReq);
       
  1175 	}
       
  1176 
       
  1177 void CSimPhBkStore::TimerCallBack(TInt aId)
       
  1178 /**
       
  1179  * Process a timer call back event.  There are three timers associated with this class
       
  1180  * and this callback will be used for all of them.  The timers can be identified from the
       
  1181  * aId parameter passed with the callback.
       
  1182  *
       
  1183  * The "Request" timer is used to kick requests which have had their completions delayed.
       
  1184  * The "Out of Band Write" timer is used to schedule a non-client phonebook write.
       
  1185  * The "Out of Band Delete" timer is used to schedule a non-client phonebook delete.
       
  1186  *
       
  1187  * @param aId	The Id of the timer to which this callback relates.
       
  1188  */
       
  1189 	{
       
  1190 	switch(aId)
       
  1191 		{
       
  1192 	case ETimerIdPhBkStorReq:
       
  1193 		StoreEvent(iPendingEvent,iPendingIndex);
       
  1194 		ReqCompleted(iPendingReqCompletion,KErrNone);
       
  1195 		break;
       
  1196 
       
  1197 	case ETimerIdPhBkStorOOBWrite:
       
  1198 		iPhBkStoreEntries[iPhBkOOBWriteIndex].iAlphaTag.Copy(iPhBkOOBWrite.iAlphaTag);
       
  1199 		iPhBkStoreEntries[iPhBkOOBWriteIndex].iTelNum.Copy(iPhBkOOBWrite.iTelNum);
       
  1200 		iPhBkStoreEntries[iPhBkOOBWriteIndex].iTonNpi=iPhBkOOBWrite.iTonNpi;
       
  1201 		StoreEvent(EStoreEventAdded,iPhBkOOBWriteIndex);
       
  1202 		break;
       
  1203 
       
  1204 	case ETimerIdPhBkStorOOBDelete:
       
  1205 		iPhBkStoreEntries[iPhBkOOBDeleteIndex].iAlphaTag.Zero();
       
  1206 		iPhBkStoreEntries[iPhBkOOBDeleteIndex].iTelNum.Zero();
       
  1207 		iPhBkStoreEntries[iPhBkOOBDeleteIndex].iTonNpi=0;
       
  1208 		StoreEvent(EStoreEventDeleted,iPhBkOOBDeleteIndex);
       
  1209 		break;
       
  1210 
       
  1211 	default:
       
  1212 		break;
       
  1213 		}
       
  1214 	}
       
  1215 
       
  1216 void CSimPhBkStore::StoreEvent(TStoreEvent aEvent,TInt aIndex)
       
  1217 /**
       
  1218  * Determine if a store event notification should be completed.
       
  1219  * @param aEvent	The store event.
       
  1220  * @param aIndex	The index related to the store event.
       
  1221  */
       
  1222 	{
       
  1223 	if(iEvOutstandingReq)
       
  1224 		{
       
  1225 		TUint event=0;
       
  1226 		switch(aEvent)
       
  1227 			{
       
  1228 		case EStoreEventNoEvent:
       
  1229 			return;
       
  1230 
       
  1231 		case EStoreEventAdded:
       
  1232 			event|=RMobilePhoneStore::KStoreEntryAdded;
       
  1233 			break;
       
  1234 
       
  1235 		case EStoreEventDeleted:
       
  1236 			event|=RMobilePhoneStore::KStoreEntryDeleted;
       
  1237 			break;
       
  1238 
       
  1239 		case EStoreEventChanged:
       
  1240 			event|=RMobilePhoneStore::KStoreEntryChanged;
       
  1241 			break;
       
  1242 
       
  1243 		default:
       
  1244 			break;
       
  1245 			}
       
  1246 
       
  1247 		TInt cnt=UsedEntries();
       
  1248 		if(cnt==0)
       
  1249 			event|=RMobilePhoneStore::KStoreEmpty;
       
  1250 
       
  1251 		if(cnt==iPhBkMaxNumSlots)
       
  1252 			event|=RMobilePhoneStore::KStoreFull;
       
  1253 		else
       
  1254 			event|=RMobilePhoneStore::KStoreHasSpace;
       
  1255 
       
  1256 		*iEvEvent=event;
       
  1257 		*iEvIndex=aIndex;
       
  1258 		iEvOutstandingReq=EFalse;
       
  1259 		ReqCompleted(iEvReqHandle,KErrNone);
       
  1260 		}
       
  1261 	}
       
  1262 
       
  1263 TBool CSimPhBkStore::FindIpcErrorMatch(TInt& aError)
       
  1264 /**
       
  1265  * Determine whether the IPC counter has signalled that the current request should
       
  1266  * be errored, rather than executed.
       
  1267  *
       
  1268  * @param aError	If the function returns ETrue, this parameter will pass back the
       
  1269  *					number of the error to be propagated.
       
  1270  * @return TBool	Returns ETrue if a match with the IPC count is found, EFalse if not.
       
  1271  */
       
  1272 	{
       
  1273 	TInt i;
       
  1274 	for(i=0;i<iPhBkError->Count();i++)
       
  1275 		{
       
  1276 		TInt pi=iPhBkError->At(i).iCount;
       
  1277 		if(pi==iIpcCnt)
       
  1278 			{
       
  1279 			aError=iPhBkError->At(i).iError;
       
  1280 			return ETrue;
       
  1281 			}
       
  1282 		}
       
  1283 	return EFalse;
       
  1284 	}
       
  1285 
       
  1286 const CTestConfigSection* CSimPhBkStore::CfgFile()
       
  1287 /**
       
  1288 * Returns a pointer to the config file section
       
  1289 *
       
  1290 * @return CTestConfigSection a pointer to the configuration file data section
       
  1291 */
       
  1292 	{
       
  1293 	LOGPHBK1(">>CSimPhBkStore::CfgFile");
       
  1294 	return iPhone->CfgFile();
       
  1295 	}