|
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 Own Number store manipulation code. |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include "CSimONStore.h" |
|
23 #include "CSimPhone.h" |
|
24 #include "Simlog.h" |
|
25 #include <testconfigfileparser.h> |
|
26 |
|
27 // |
|
28 // CSimONStore |
|
29 // |
|
30 void CSimONStore::ClosePhone(TAny* aObj) |
|
31 /** |
|
32 * A utility function for cleaning up the stack. |
|
33 */ |
|
34 { |
|
35 ((CObject*)aObj)->Close(); |
|
36 } |
|
37 |
|
38 CSimONStore* CSimONStore::NewL(CSimPhone* aPhone, TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen) |
|
39 /** |
|
40 * Standard two phase constructor. |
|
41 * @param aPhone The phone object from which this Own Number store was opened. |
|
42 * @param aName The name of the created Own Number store. |
|
43 * @param aMaxNumSlots The maximum number of slots in the Own Number store. |
|
44 * @return CSimONStore* The newly created object. |
|
45 */ |
|
46 { |
|
47 CSimONStore* store=new(ELeave) CSimONStore(aPhone); |
|
48 TCleanupItem newObjClose(ClosePhone,store); |
|
49 CleanupStack::PushL(newObjClose); |
|
50 store->ConstructL(aMaxNumSlots,aMaxNumLen,aMaxTextLen); |
|
51 CleanupStack::Pop(); |
|
52 return store; |
|
53 } |
|
54 |
|
55 CSimONStore::CSimONStore(CSimPhone* aPhone) |
|
56 : CSimPhone(iDummyPhoneBaseRef), iPhone(aPhone) |
|
57 /** |
|
58 * Trivial first phase constructor. |
|
59 * @param aPhone The phone object from which this Own Number store was opened. |
|
60 */ |
|
61 {} |
|
62 |
|
63 void CSimONStore::ConstructL(TInt aMaxNumSlots, TInt aMaxNumLen, TInt aMaxTextLen) |
|
64 /** |
|
65 * Second phase constructor that allocates memory for the Own Number store, batch read buffer and |
|
66 * a delayed completion timer. The constructor also reads the individual and batch read |
|
67 * delays from the configuration file. |
|
68 * |
|
69 * @param aMaxNumLen The maximum length of a telephone number. |
|
70 * @param aMaxTextLen The maximum length of an alpha tag. |
|
71 */ |
|
72 { |
|
73 LOGPHBK1("Starting to parse Own Number store additional config parameters..."); |
|
74 __ASSERT_ALWAYS(aMaxNumLen<=KONMaxTelNumSize,SimPanic(EOwnNumberNameOrNumberTooLarge)); |
|
75 __ASSERT_ALWAYS(aMaxTextLen<=KONMaxTextSize,SimPanic(EOwnNumberNameOrNumberTooLarge)); |
|
76 |
|
77 iONStoreEntries=new(ELeave) TONStoreEntry[aMaxNumSlots+1]; //slot 0 is unused |
|
78 iONMaxNumSlots=aMaxNumSlots; |
|
79 iONMaxTelNumLen=aMaxNumLen; |
|
80 iONMaxTextLen=aMaxTextLen; |
|
81 |
|
82 iReqTimer=CSimTimer::NewL(iPhone); |
|
83 iONRwBuffer=new(ELeave) CPhoneBookBuffer(); |
|
84 |
|
85 const CTestConfigItem* item=NULL; |
|
86 item=CfgFile()->Item(KONPhoneStoreCaps,0); |
|
87 if (item) |
|
88 { |
|
89 TPtrC8 value; |
|
90 TInt ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,value); |
|
91 if(ret!=KErrNone) |
|
92 { |
|
93 iONStoreCaps=KDefaultONPhoneStoreCaps; |
|
94 LOGPARSERR("value",ret,0,&KONPhoneStoreCaps); |
|
95 } |
|
96 else |
|
97 { |
|
98 TUint32 intValue; |
|
99 TInt ret = AsciiToNum(value, intValue); |
|
100 if(ret!=KErrNone) |
|
101 iONStoreCaps=KDefaultONPhoneStoreCaps; |
|
102 else |
|
103 iONStoreCaps = intValue; |
|
104 } |
|
105 } |
|
106 else |
|
107 iONStoreCaps=KDefaultONPhoneStoreCaps; |
|
108 |
|
109 |
|
110 LOGPHBK1("...Finished parsing Own Number store additional config parameters..."); |
|
111 } |
|
112 |
|
113 void CSimONStore::PopulateStoreFromConfigFileL() |
|
114 /** |
|
115 * Populate the Own Number store from information in the configuration file. This is performed |
|
116 * after the standard Own Number store construction in order to prevent reseting the configuation |
|
117 * file accessor class' pointers while possibly multiple Own Number stores are created. |
|
118 * |
|
119 * The store entries comply to the following format: |
|
120 * "PhBkStoreEntry = <store name>, <slot number>, <telephone number>, <alphatag>" |
|
121 */ |
|
122 { |
|
123 LOGPHBK1("Starting to read Own Number store entries..."); |
|
124 iONIndividualPause=CfgFile()->ItemValue(KONStoreIndividualReqPause,KDefaultONStoreIndividualReqPause); |
|
125 |
|
126 TInt count=CfgFile()->ItemCount(KONStoreEntry); |
|
127 const CTestConfigItem* item=NULL; |
|
128 TInt ret=KErrNone; |
|
129 |
|
130 TInt i; |
|
131 for(i=0;i<count;i++) |
|
132 { |
|
133 item=CfgFile()->Item(KONStoreEntry,i); |
|
134 if(!item) |
|
135 break; |
|
136 |
|
137 TPtrC8 telNum, name; |
|
138 TInt index; |
|
139 RMobilePhone::TMobileTON typeOfNumber; |
|
140 RMobilePhone::TMobileService service; |
|
141 RMobilePhone::TMobilePhoneNetworkMode mode; |
|
142 RMobilePhone::TMobileNPI numberPlan; |
|
143 ret=GetONEntry(item,0,index,telNum,name,typeOfNumber,service,mode,numberPlan); |
|
144 if(ret!=KErrNone) |
|
145 { |
|
146 LOGPARSERR("Own Number Entry",ret,index,&KONStoreEntry); |
|
147 continue; |
|
148 } |
|
149 |
|
150 iONStoreEntries[index].iMode=mode; |
|
151 iONStoreEntries[index].iService=service; |
|
152 iONStoreEntries[index].iTelNum.Copy(telNum); |
|
153 iONStoreEntries[index].iText.Copy(name); |
|
154 iONStoreEntries[index].iTypeOfNumber=typeOfNumber; |
|
155 iONStoreEntries[index].iNumberPlan=numberPlan; |
|
156 } |
|
157 |
|
158 LOGPHBK1("...Finished reading Own Number store entries..."); |
|
159 |
|
160 } |
|
161 |
|
162 TInt CSimONStore::GetONEntry(const CTestConfigItem* aItem, TInt aItemIndex, TInt& aIndex, |
|
163 TPtrC8& aTelNum, TPtrC8& aText, |
|
164 RMobilePhone::TMobileTON& aTypeOfNumber, |
|
165 RMobilePhone::TMobileService& aService, |
|
166 RMobilePhone::TMobilePhoneNetworkMode& aMode, |
|
167 RMobilePhone::TMobileNPI& aNumberPlan) |
|
168 /** |
|
169 * Retrieve a Own Number entry from the configuration file, starting at a given item index |
|
170 * value. |
|
171 * @param aItem Pointer to the config file item from which the Own Number entry will be read. |
|
172 * @param aItemIndex The index number within the item from which the Own Number entry will be read. |
|
173 * @param aIndex The returned index number |
|
174 * @param aTelNum The returned telephone number |
|
175 * @param aTypeOfNumber The returned Type of Number information |
|
176 * @param aService The returned service |
|
177 * @param aMode The returned Network Mode |
|
178 * @return TInt Standard error value. |
|
179 */ |
|
180 { |
|
181 TInt ret; |
|
182 ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aIndex); |
|
183 if(ret!=KErrNone) |
|
184 return ret; |
|
185 |
|
186 if(aIndex>iONMaxNumSlots) //the max number of slot is a valid slot |
|
187 return KErrArgument; |
|
188 |
|
189 ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aTelNum); |
|
190 if(ret!=KErrNone) |
|
191 return ret; |
|
192 if(aTelNum.Length()>iONMaxTelNumLen) |
|
193 return KErrArgument; |
|
194 |
|
195 TInt typeOfNumber; |
|
196 ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,typeOfNumber); |
|
197 if(ret!=KErrNone) |
|
198 return ret; |
|
199 |
|
200 aTypeOfNumber = (RMobilePhone::TMobileTON) typeOfNumber; |
|
201 if ( (TInt) RMobilePhone::EAbbreviatedNumber < typeOfNumber ) |
|
202 return KErrArgument; |
|
203 |
|
204 TInt service; |
|
205 ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,service); |
|
206 if(ret!=KErrNone) |
|
207 return ret; |
|
208 |
|
209 aService = (RMobilePhone::TMobileService) service; |
|
210 |
|
211 aMode = RMobilePhone::ENetworkModeGsm; |
|
212 |
|
213 TInt numberPlan; |
|
214 ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,numberPlan); |
|
215 if(ret!=KErrNone) |
|
216 return ret; |
|
217 |
|
218 aNumberPlan = (RMobilePhone::TMobileNPI) numberPlan; |
|
219 switch (aNumberPlan) |
|
220 { |
|
221 case RMobilePhone::EUnknownNumberingPlan: |
|
222 case RMobilePhone::EIsdnNumberPlan: |
|
223 case RMobilePhone::EDataNumberPlan: |
|
224 case RMobilePhone::ETelexNumberPlan: |
|
225 case RMobilePhone::EServiceCentreSpecificPlan1: |
|
226 case RMobilePhone::EServiceCentreSpecificPlan2: |
|
227 case RMobilePhone::ENationalNumberPlan: |
|
228 case RMobilePhone::EPrivateNumberPlan: |
|
229 case RMobilePhone::EERMESNumberPlan: |
|
230 break; |
|
231 default: |
|
232 return KErrArgument; |
|
233 } |
|
234 |
|
235 ret=CTestConfig::GetElement(aItem->Value(),KStdDelimiter,aItemIndex++,aText); |
|
236 if(ret!=KErrNone) |
|
237 return ret; |
|
238 if(aText.Length()>iONMaxTextLen) |
|
239 return KErrArgument; |
|
240 |
|
241 return ret; |
|
242 } |
|
243 |
|
244 CSimONStore::~CSimONStore() |
|
245 /** |
|
246 * Standard destructor. Any objects created by the ::ConstructL() function |
|
247 * will be destroyed here. |
|
248 */ |
|
249 { |
|
250 delete[] iONStoreEntries; |
|
251 delete iONRwBuffer; |
|
252 delete iReqTimer; |
|
253 } |
|
254 |
|
255 TInt CSimONStore::ExtFunc(const TTsyReqHandle aReqHandle,const TInt aIpc, const TDataPackage& aPckg) |
|
256 /** |
|
257 * Dispatch function for all Own Number store requests. |
|
258 * @param aReqHandle The TSY request handle for this request. |
|
259 * @param aIpc The IPC number of this request. |
|
260 * @param aPckg The parameter package related to this request. |
|
261 * @return TInt The return error condition. |
|
262 */ |
|
263 { |
|
264 TInt error; |
|
265 |
|
266 // The following requests can be completed even if the completion of another request is pending. |
|
267 switch(aIpc) |
|
268 { |
|
269 case EMobilePhoneStoreGetInfo: |
|
270 error = GetInfo(aReqHandle,aPckg.Des1n()); |
|
271 return error; |
|
272 |
|
273 default: |
|
274 break; |
|
275 } |
|
276 |
|
277 |
|
278 // The TSY can only process one of the following requests at a time. If a second is received |
|
279 // while processing the first, then it will be errored with KErrInUse. This restriction will |
|
280 // be removed later, by inserting a request queuing mechanism. Note that the standard TSY |
|
281 // "flow control" mechanism works phone-wide and so is not suitable. |
|
282 |
|
283 if(iReqTimer->IsActive()) |
|
284 { |
|
285 ReqCompleted(aReqHandle,KErrInUse); |
|
286 return KErrNone; |
|
287 } |
|
288 |
|
289 switch(aIpc) |
|
290 { |
|
291 case EMobilePhoneStoreRead: |
|
292 error = Read(aReqHandle,aPckg.Des1n()); |
|
293 return error; |
|
294 |
|
295 default: |
|
296 break; |
|
297 } |
|
298 |
|
299 return KErrNotSupported; |
|
300 } |
|
301 |
|
302 CTelObject* CSimONStore::OpenNewObjectByNameL(const TDesC& /*aName*/) |
|
303 /** |
|
304 * The API does not support any objects that could be opened from this one. |
|
305 */ |
|
306 { |
|
307 User::Leave(KErrNotSupported); |
|
308 return NULL; |
|
309 } |
|
310 |
|
311 CTelObject* CSimONStore::OpenNewObjectL(TDes&) |
|
312 /** |
|
313 * The API does not support any objects that could be opened from this one. |
|
314 */ |
|
315 { |
|
316 User::Leave(KErrNotSupported); |
|
317 return NULL; |
|
318 } |
|
319 |
|
320 CTelObject::TReqMode CSimONStore::ReqModeL(const TInt aIpc) |
|
321 /** |
|
322 * This function returns the Request Mode for the request with the passed IPC value. |
|
323 * @param aIpc The IPC number of the request. |
|
324 * @return TReqMode The request mode. |
|
325 */ |
|
326 { |
|
327 CTelObject::TReqMode ret=0; |
|
328 |
|
329 switch(aIpc) |
|
330 { |
|
331 case EMobilePhoneStoreGetInfo: |
|
332 case EMobilePhoneStoreRead: |
|
333 break; |
|
334 default: |
|
335 User::Leave(KErrNotSupported); |
|
336 break; |
|
337 } |
|
338 |
|
339 return ret; |
|
340 } |
|
341 |
|
342 TInt CSimONStore::RegisterNotification(const TInt /*aIpc*/) |
|
343 /** |
|
344 * The ETel Server calls this function when the first client makes a notification |
|
345 * request. If supported by the underlying protocol controlling the |
|
346 * signalling stack, this can be used to start requesting updates for the relevant |
|
347 * service. |
|
348 */ |
|
349 { |
|
350 return KErrNone; |
|
351 } |
|
352 |
|
353 TInt CSimONStore::DeregisterNotification(const TInt /*aIpc*/) |
|
354 /** |
|
355 * The ETel Server calls this function when the last client that had previously |
|
356 * made a notification request closes its ETel Server handle. If supported by |
|
357 * the underlying protocol controlling the signalling stack, this can be used |
|
358 * to stop requesting updates for the relevant service. |
|
359 */ |
|
360 { |
|
361 return KErrNone; |
|
362 } |
|
363 |
|
364 TInt CSimONStore::NumberOfSlotsL(const TInt /*aIpc*/) |
|
365 /** |
|
366 * Return the number of slots that the ETel Server should allocate for buffering requests |
|
367 * of the given IPC number. |
|
368 */ |
|
369 { |
|
370 return KDefaultNumberOfSlots; |
|
371 } |
|
372 |
|
373 TInt CSimONStore::CancelService(const TInt /*aIpc*/,const TTsyReqHandle /*aTsyReqHandle*/) |
|
374 /** |
|
375 * Cancel an outstanding request. |
|
376 * @param aIpc The IPC number of the request that is to be cancelled. |
|
377 * @param aTsyReqHandle The TSY request handle of the request that is to be cancelled. |
|
378 * @param TInt Standard return value. |
|
379 */ |
|
380 { |
|
381 return KErrNone; |
|
382 } |
|
383 |
|
384 void CSimONStore::Init() |
|
385 /** |
|
386 * This function can be used to perform any necessary synchronous initialisation. |
|
387 */ |
|
388 { |
|
389 } |
|
390 |
|
391 TInt CSimONStore::GetInfo(TTsyReqHandle aReqHandle, TDes8* aPckg) |
|
392 /** |
|
393 * Retrieve Own Number store information. This request is completed immediately, as it is assumed |
|
394 * that in a real TSY, all this data will be cached in the TSY. |
|
395 * |
|
396 * @param aReqHandle The TSY request handle associated with this request. |
|
397 * @param aPckg The parameter package associated with this request. |
|
398 */ |
|
399 { |
|
400 |
|
401 if(iPhone->IsICCLocked()!=EFalse) |
|
402 { |
|
403 ReqCompleted(aReqHandle, KErrAccessDenied); |
|
404 return KErrNone; |
|
405 } |
|
406 |
|
407 RMobileONStore::TMobileONStoreInfoV1Pckg* getInfoPckg=(RMobileONStore::TMobileONStoreInfoV1Pckg*)aPckg; |
|
408 RMobileONStore::TMobileONStoreInfoV1& getInfo=(*getInfoPckg)(); |
|
409 |
|
410 PopulateONStoreInfo(&getInfo); |
|
411 |
|
412 if(&getInfo!=NULL) // This will be the case if the version checking within PopulatePhBkStoreInfo has failed. |
|
413 { |
|
414 ReqCompleted(aReqHandle,KErrNone); |
|
415 } |
|
416 else |
|
417 { |
|
418 ReqCompleted(aReqHandle,KErrNotSupported); |
|
419 } |
|
420 |
|
421 return KErrNone; |
|
422 } |
|
423 |
|
424 void CSimONStore::PopulateONStoreInfo(RMobileONStore::TMobileONStoreInfoV1* aStoreInfo) |
|
425 /** |
|
426 * Populate the passed parameter with Own Number store information. |
|
427 * @param aStoreInfo Pointer to Own Number store information structure to be populated. |
|
428 */ |
|
429 { |
|
430 __ASSERT_ALWAYS(aStoreInfo, SimPanic(EIllegalNullPtrParameter)); |
|
431 |
|
432 aStoreInfo->iType=RMobilePhoneStore::EOwnNumberStore; |
|
433 aStoreInfo->iTotalEntries=iONMaxNumSlots; |
|
434 aStoreInfo->iCaps=iONStoreCaps; |
|
435 aStoreInfo->iName = KETelOwnNumberStore; |
|
436 aStoreInfo->iUsedEntries=UsedEntries(); |
|
437 |
|
438 aStoreInfo->iNumberLen = iONMaxTelNumLen; |
|
439 aStoreInfo->iTextLen = iONMaxTextLen; |
|
440 |
|
441 } |
|
442 |
|
443 TInt CSimONStore::Read(TTsyReqHandle aReqHandle, TDes8* aPckg1) |
|
444 /** |
|
445 * Read Own Number store entries. |
|
446 * |
|
447 * @param aReqHandle The TSY request handle associated with this request. |
|
448 * @param aPckg1 The first parameter package associated with this request. |
|
449 * It contains the index from which to read and value. |
|
450 * @return TInt Standard return value. |
|
451 */ |
|
452 { |
|
453 if(iPhone->IsICCLocked()!=EFalse) |
|
454 { |
|
455 ReqCompleted(aReqHandle, KErrAccessDenied); |
|
456 return KErrNone; |
|
457 } |
|
458 |
|
459 RMobileONStore::TMobileONEntryV1Pckg* ownNumberPckg = (RMobileONStore::TMobileONEntryV1Pckg*)aPckg1; |
|
460 RMobileONStore::TMobileONEntryV1& ownNumber = (*ownNumberPckg)(); |
|
461 |
|
462 if(ownNumber.iIndex>iONMaxNumSlots) |
|
463 { |
|
464 ReqCompleted(aReqHandle,KErrArgument); |
|
465 return KErrNone; |
|
466 } |
|
467 |
|
468 else if (!(iONStoreCaps & RMobilePhoneStore::KCapsIndividualEntry && iONStoreCaps & RMobilePhoneStore::KCapsReadAccess)) |
|
469 { |
|
470 ReqCompleted(aReqHandle, KErrAccessDenied); |
|
471 return KErrNone; |
|
472 } |
|
473 |
|
474 iONRwBuffer->Set(aPckg1); |
|
475 |
|
476 if(iONStoreEntries[ownNumber.iIndex].iTelNum.Length()!=0) |
|
477 { |
|
478 ownNumber.iMode = iONStoreEntries[ownNumber.iIndex].iMode; |
|
479 ownNumber.iService = iONStoreEntries[ownNumber.iIndex].iService; |
|
480 ownNumber.iNumber.iTelNumber.Copy(iONStoreEntries[ownNumber.iIndex].iTelNum); |
|
481 ownNumber.iNumber.iTypeOfNumber = iONStoreEntries[ownNumber.iIndex].iTypeOfNumber; |
|
482 ownNumber.iNumber.iNumberPlan = iONStoreEntries[ownNumber.iIndex].iNumberPlan; |
|
483 ownNumber.iText.Copy(iONStoreEntries[ownNumber.iIndex].iText); |
|
484 |
|
485 DelayCompletion(1, aReqHandle); |
|
486 } |
|
487 else |
|
488 { |
|
489 ReqCompleted(aReqHandle,KErrNotFound); // No entries found. |
|
490 } |
|
491 |
|
492 return KErrNone; |
|
493 } |
|
494 |
|
495 TInt CSimONStore::UsedEntries() |
|
496 /** |
|
497 * Count the number of used entries in the Own Number store. |
|
498 * @return TInt The number of used entries in the store. |
|
499 */ |
|
500 { |
|
501 TInt cnt=0; |
|
502 for(TInt i=1;i<=iONMaxNumSlots;i++) |
|
503 { |
|
504 if(iONStoreEntries[i].iTelNum.Length()!=0) |
|
505 cnt++; |
|
506 } |
|
507 return cnt; |
|
508 } |
|
509 |
|
510 void CSimONStore::DelayCompletion(TInt aDelayDuration,TTsyReqHandle aReqHandle) |
|
511 /** |
|
512 * A shell function for functions that wish to delay completion but do not trigger store |
|
513 * events. |
|
514 */ |
|
515 { |
|
516 iPendingReqCompletion=aReqHandle; |
|
517 iReqTimer->Start(aDelayDuration,this,ETimerIdONStorReq); |
|
518 } |
|
519 |
|
520 void CSimONStore::TimerCallBack(TInt aId) |
|
521 /** |
|
522 * Process a timer call back event. |
|
523 * |
|
524 * The "Request" timer is used to kick requests which have had their completions delayed. |
|
525 * |
|
526 * @param aId The Id of the timer to which this callback relates. |
|
527 */ |
|
528 { |
|
529 switch(aId) |
|
530 { |
|
531 case ETimerIdONStorReq: |
|
532 ReqCompleted(iPendingReqCompletion,KErrNone); |
|
533 break; |
|
534 |
|
535 default: |
|
536 break; |
|
537 } |
|
538 } |
|
539 |
|
540 const CTestConfigSection* CSimONStore::CfgFile() |
|
541 /** |
|
542 * Returns a pointer to the config file section |
|
543 * |
|
544 * @return CTestConfigSection a pointer to the configuration file data section |
|
545 */ |
|
546 { |
|
547 LOGPHBK1(">>CSimONStore::CfgFile"); |
|
548 return iPhone->CfgFile(); |
|
549 } |