|
1 // Copyright (c) 2002-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 Phone Smart Card application and file manipulation code. |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include <testconfigfileparser.h> |
|
23 #include <etelmmerr.h> |
|
24 #include "CSimPhone.h" |
|
25 #include "Simlog.h" |
|
26 |
|
27 // |
|
28 // CSimPhoneSmartCardApp |
|
29 // |
|
30 |
|
31 CSimPhoneSmartCardApp* CSimPhoneSmartCardApp::NewL(CSimPhone* aPhone) |
|
32 /** |
|
33 * Standard two phase constructor. |
|
34 * @param aPhone The phone object from which the Phone Smart Card applications will open |
|
35 */ |
|
36 { |
|
37 CSimPhoneSmartCardApp* obj=new(ELeave) CSimPhoneSmartCardApp(aPhone); |
|
38 CleanupStack::PushL(obj); |
|
39 obj->ConstructL(); |
|
40 CleanupStack::Pop(); |
|
41 return obj; |
|
42 } |
|
43 |
|
44 CSimPhoneSmartCardApp::CSimPhoneSmartCardApp(CSimPhone* aPhone) |
|
45 : iPhone(aPhone), iCurrentSelection(RMobilePhone::EUSimSelectionAutomatic), |
|
46 iFoundScAppTags(EFalse) |
|
47 /** |
|
48 * Trivial first phase constructor. |
|
49 * @param aPhone The phone object from which this Phone SmartCard App was opened. |
|
50 */ |
|
51 {} |
|
52 |
|
53 void CSimPhoneSmartCardApp::Init() |
|
54 {} |
|
55 |
|
56 void CSimPhoneSmartCardApp::ConstructL() |
|
57 /** |
|
58 * Second phase of the 2-phase constructor. |
|
59 * Constructs all the member data and retrieves all the data from the config file specific to this class. |
|
60 * |
|
61 * @leave Leaves due to not enough memory or if any data member does not construct for any reason. |
|
62 */ |
|
63 { |
|
64 LOGPHONE1("Starting to parse Phone Smart Card applications additional config parameters..."); |
|
65 ParseSmartCardApplicationInfoL(); |
|
66 ParseSmartCardFileInfoL(); |
|
67 MapUSimAppsL(); |
|
68 LOGPHONE1("Finished parsing Phone Smart Card applications additional config parameters..."); |
|
69 } |
|
70 |
|
71 |
|
72 CSimPhoneSmartCardApp::~CSimPhoneSmartCardApp() |
|
73 /** |
|
74 * Standard destructor. Any objects created by the ::ConstructL() function |
|
75 * will be destroyed here. |
|
76 */ |
|
77 { |
|
78 delete iTimer; |
|
79 if(iSmartCardAppEventList) |
|
80 { |
|
81 iSmartCardAppEventList->Delete(0, iSmartCardAppEventList->Count()); |
|
82 delete iSmartCardAppEventList; |
|
83 } |
|
84 if(iSmartCardAppList) |
|
85 { |
|
86 iSmartCardAppList->Delete(0, iSmartCardAppList->Count()); |
|
87 delete iSmartCardAppList; |
|
88 } |
|
89 if (iSmartCardFileList) |
|
90 { |
|
91 iSmartCardFileList->ResetAndDestroy(); |
|
92 delete iSmartCardFileList; |
|
93 } |
|
94 if(iUSimAppList) |
|
95 { |
|
96 iUSimAppList->Close(); |
|
97 delete iUSimAppList; |
|
98 } |
|
99 } |
|
100 |
|
101 |
|
102 TInt CSimPhoneSmartCardApp::ExtFunc(const TTsyReqHandle aTsyReqHandle,const TInt aIpc, const TDataPackage& aPckg) |
|
103 /** |
|
104 * ExtFunc is called by the server when it has an "extended", i.e. non-core ETel request |
|
105 * for the TSY to process. |
|
106 * A request handle, request type and request data are passed to the TSY |
|
107 * |
|
108 * @param aTsyReqHandle The request handle for completing the request |
|
109 * @param aIpc Ipc representing the request |
|
110 * @param aPackage any data associated with the request |
|
111 * @return err KErrNone if request completes ok |
|
112 */ |
|
113 { |
|
114 |
|
115 TAny* dataPtr = aPckg.Ptr1(); |
|
116 TAny* dataPtr2 = aPckg.Ptr2(); |
|
117 |
|
118 // The following requests can be completed even if the completion of another request is pending. |
|
119 switch(aIpc) |
|
120 { |
|
121 case EMobilePhoneGetCurrentActiveUSimApplication: |
|
122 return GetCurrentActiveUSimApplication(aTsyReqHandle, |
|
123 reinterpret_cast<RMobilePhone::TAID*>(dataPtr)); |
|
124 |
|
125 case EMobilePhoneEnumerateUSimApplications: |
|
126 return EnumerateUSimApplications(aTsyReqHandle, |
|
127 reinterpret_cast<TInt*> (dataPtr), |
|
128 reinterpret_cast<RMobilePhone::TAID*> (dataPtr2)); |
|
129 |
|
130 case EMobilePhoneSetUSimApplicationStatus: |
|
131 return SetUSimApplicationStatus(aTsyReqHandle, |
|
132 reinterpret_cast<RMobilePhone::TAID*> (dataPtr), |
|
133 reinterpret_cast<RMobilePhone::TUSimAppAction*> (dataPtr2)); |
|
134 |
|
135 case EMobilePhoneGetUSimApplicationsInfo: |
|
136 return GetUSimApplicationInfo(aTsyReqHandle, |
|
137 reinterpret_cast<TInt*> (dataPtr), |
|
138 aPckg.Des2n()); |
|
139 |
|
140 case EMobilePhoneNotifyUSimApplicationsInfoChange: |
|
141 return NotifyUSimApplicationsInfoChange(aTsyReqHandle, |
|
142 reinterpret_cast<TInt*> (dataPtr), |
|
143 reinterpret_cast<RMobilePhone::TAID*> (dataPtr2)); |
|
144 |
|
145 case EMobilePhoneEnumerateSmartCardApplications: |
|
146 return EnumerateScApplications(aTsyReqHandle, |
|
147 reinterpret_cast<TUint*>(dataPtr)); |
|
148 |
|
149 case EMobilePhoneGetSmartCardApplicationInfo: |
|
150 return GetScApplicationInfo(aTsyReqHandle, |
|
151 reinterpret_cast<TInt*>(dataPtr), |
|
152 aPckg.Des2n()); |
|
153 |
|
154 case EMobilePhoneSetSmartCardApplicationStatus: |
|
155 return SetScApplicationStatus(aTsyReqHandle, |
|
156 reinterpret_cast<RMobilePhone::TAID*>(dataPtr), |
|
157 reinterpret_cast<RMobilePhone::TSmartCardApplicationAction*>(dataPtr2)); |
|
158 |
|
159 case EMobilePhoneNotifySmartCardApplicationInfoChange: |
|
160 return NotifyScApplicationInfoChange(aTsyReqHandle, |
|
161 reinterpret_cast<RMobilePhone::TAID*>(dataPtr), |
|
162 reinterpret_cast<RMobilePhone::TSmartCardApplicationEvent*>(dataPtr2)); |
|
163 |
|
164 case EMobilePhoneGetUSimAppsSelectionMode: |
|
165 return GetUSimAppsSelectionMode(aTsyReqHandle, |
|
166 reinterpret_cast<RMobilePhone::TUSimSelectionMode*>(dataPtr)); |
|
167 |
|
168 case EMobilePhoneSetUSimAppsSelectionMode: |
|
169 return SetUSimAppsSelectionMode(aTsyReqHandle, |
|
170 reinterpret_cast<RMobilePhone::TUSimSelectionMode*>(dataPtr)); |
|
171 |
|
172 case EMobilePhoneNotifyUSimAppsSelectionModeChange: |
|
173 return NotifyUSIMAppsSelectionModeChange(aTsyReqHandle, |
|
174 reinterpret_cast<RMobilePhone::TUSimSelectionMode*>(dataPtr)); |
|
175 |
|
176 case EMobilePhoneGetScFileInfo: |
|
177 return GetScFileInfo(aTsyReqHandle, |
|
178 *reinterpret_cast<RMobilePhone::TScFilePath*>(dataPtr), |
|
179 aPckg.Des2n()); |
|
180 |
|
181 case EMobilePhoneReadScFile: |
|
182 return ReadScFile(aTsyReqHandle, |
|
183 *reinterpret_cast<RMobilePhone::TScFilePathWithAccessOffsets*>(dataPtr), |
|
184 aPckg.Des2n()); |
|
185 |
|
186 case EMobilePhoneUpdateScFile: |
|
187 return UpdateScFile(aTsyReqHandle, |
|
188 *reinterpret_cast<RMobilePhone::TScFilePathWithAccessOffsets*>(dataPtr), |
|
189 aPckg.Des2n()); |
|
190 |
|
191 default: |
|
192 break; |
|
193 } |
|
194 return KErrNotSupported; |
|
195 } |
|
196 |
|
197 |
|
198 CTelObject::TReqMode CSimPhoneSmartCardApp::ReqModeL(const TInt aIpc) |
|
199 /** |
|
200 * This function returns the Request Mode for the request with the passed IPC value. |
|
201 * The function leaves if the IPC is not found. |
|
202 * |
|
203 * @param aIpc The IPC number of the request. |
|
204 * @return TReqMode The request mode. |
|
205 */ |
|
206 { |
|
207 CTelObject::TReqMode ret=0; |
|
208 |
|
209 switch(aIpc) |
|
210 { |
|
211 case EMobilePhoneGetCurrentActiveUSimApplication: |
|
212 case EMobilePhoneEnumerateUSimApplications: |
|
213 case EMobilePhoneSetUSimApplicationStatus: |
|
214 case EMobilePhoneGetUSimApplicationsInfo: |
|
215 case EMobilePhoneEnumerateSmartCardApplications: |
|
216 case EMobilePhoneSetSmartCardApplicationStatus: |
|
217 case EMobilePhoneGetSmartCardApplicationInfo: |
|
218 case EMobilePhoneGetUSimAppsSelectionMode: |
|
219 case EMobilePhoneSetUSimAppsSelectionMode: |
|
220 case EMobilePhoneGetScFileInfo: |
|
221 case EMobilePhoneReadScFile: |
|
222 case EMobilePhoneUpdateScFile: |
|
223 break; |
|
224 |
|
225 case EMobilePhoneNotifyUSimAppsSelectionModeChange: |
|
226 case EMobilePhoneNotifyUSimApplicationsInfoChange: |
|
227 case EMobilePhoneNotifySmartCardApplicationInfoChange: |
|
228 ret=KReqModeMultipleCompletionEnabled | KReqModeRePostImmediately; |
|
229 break; |
|
230 |
|
231 default: |
|
232 User::Leave(KErrNotSupported); |
|
233 break; |
|
234 } |
|
235 |
|
236 return ret; |
|
237 } |
|
238 |
|
239 TInt CSimPhoneSmartCardApp::RegisterNotification(const TInt /*aIpc*/) |
|
240 /** |
|
241 * The ETel Server calls this function when the first client makes a notification |
|
242 * request. If supported by the underlying protocol controlling the |
|
243 * signalling stack, this can be used to start requesting updates for the relevant |
|
244 * service. |
|
245 */ |
|
246 { |
|
247 return KErrNone; |
|
248 } |
|
249 |
|
250 TInt CSimPhoneSmartCardApp::DeregisterNotification(const TInt /*aIpc*/) |
|
251 /** |
|
252 * The ETel Server calls this function when the last client that had previously |
|
253 * made a notification request closes its ETel Server handle. If supported by |
|
254 * the underlying protocol controlling the signalling stack, this can be used |
|
255 * to stop requesting updates for the relevant service. |
|
256 */ |
|
257 { |
|
258 return KErrNone; |
|
259 } |
|
260 |
|
261 CTelObject* CSimPhoneSmartCardApp::OpenNewObjectByNameL(const TDesC& /*aName*/) |
|
262 /** |
|
263 * The API does not support any objects that could be opened from this one. |
|
264 */ |
|
265 { |
|
266 User::Leave(KErrNotSupported); |
|
267 return NULL; |
|
268 } |
|
269 |
|
270 CTelObject* CSimPhoneSmartCardApp::OpenNewObjectL(TDes&) |
|
271 /** |
|
272 * The API does not support any objects that could be opened from this one. |
|
273 */ |
|
274 { |
|
275 User::Leave(KErrNotSupported); |
|
276 return NULL; |
|
277 } |
|
278 |
|
279 |
|
280 TInt CSimPhoneSmartCardApp::NumberOfSlotsL(const TInt aIpc) |
|
281 /** |
|
282 * Return the number of slots that the ETel Server should allocate for buffering requests |
|
283 * of the given IPC number. |
|
284 * |
|
285 * @param aIpc The IPC number of the request. |
|
286 */ |
|
287 { |
|
288 TInt numberOfSlots = 0; |
|
289 |
|
290 switch(aIpc) |
|
291 { |
|
292 case EMobilePhoneNotifyUSimAppsSelectionModeChange: |
|
293 case EMobilePhoneNotifyUSimApplicationsInfoChange: |
|
294 case EMobilePhoneNotifySmartCardApplicationInfoChange: |
|
295 numberOfSlots = KDefaultNumberOfSlots; |
|
296 break; |
|
297 default: |
|
298 LOGPHONE1("CSimPhoneSmartCardApp: Number of Slots error, unknown IPC"); |
|
299 User::Leave(KErrNotSupported); |
|
300 break; |
|
301 } |
|
302 return numberOfSlots; |
|
303 } |
|
304 |
|
305 |
|
306 TInt CSimPhoneSmartCardApp::CancelService(const TInt aIpc,const TTsyReqHandle aTsyReqHandle) |
|
307 /** |
|
308 * Cancel an outstanding request. |
|
309 * @param aIpc The IPC number of the request that is to be cancelled. |
|
310 * @param aTsyReqHandle The TSY request handle of the request that is to be cancelled. |
|
311 * @return Standard return value. |
|
312 */ |
|
313 { |
|
314 |
|
315 switch(aIpc) |
|
316 { |
|
317 case EMobilePhoneEnumerateSmartCardApplications: |
|
318 return EnumerateScApplicationsCancel(aTsyReqHandle); |
|
319 |
|
320 case EMobilePhoneEnumerateUSimApplications: |
|
321 return EnumerateUSimApplicationsCancel(aTsyReqHandle); |
|
322 |
|
323 case EMobilePhoneSetUSimApplicationStatus: |
|
324 return SetUSimApplicationStatusCancel(aTsyReqHandle); |
|
325 |
|
326 case EMobilePhoneGetUSimApplicationsInfo: |
|
327 return GetUSimApplicationInfoCancel(aTsyReqHandle); |
|
328 |
|
329 case EMobilePhoneNotifyUSimApplicationsInfoChange: |
|
330 return NotifyUSimApplicationsInfoChangeCancel(aTsyReqHandle); |
|
331 |
|
332 case EMobilePhoneSetSmartCardApplicationStatus: |
|
333 return SetScApplicationStatusCancel(aTsyReqHandle); |
|
334 |
|
335 case EMobilePhoneGetSmartCardApplicationInfo: |
|
336 return GetScApplicationInfoCancel(aTsyReqHandle); |
|
337 |
|
338 case EMobilePhoneGetCurrentActiveUSimApplication: |
|
339 return GetCurrentActiveUSimApplicationCancel(aTsyReqHandle); |
|
340 |
|
341 case EMobilePhoneNotifySmartCardApplicationInfoChange: |
|
342 return NotifyScApplicationInfoChangeCancel(aTsyReqHandle); |
|
343 |
|
344 case EMobilePhoneSetUSimAppsSelectionMode: |
|
345 return SetUSimAppsSelectionModeCancel(aTsyReqHandle); |
|
346 |
|
347 case EMobilePhoneGetUSimAppsSelectionMode: |
|
348 return GetUSimAppsSelectionModeCancel(aTsyReqHandle); |
|
349 |
|
350 case EMobilePhoneNotifyUSimAppsSelectionModeChange: |
|
351 return NotifyUSIMAppsSelectionModeChangeCancel(aTsyReqHandle); |
|
352 |
|
353 case EMobilePhoneGetScFileInfo: |
|
354 return GetScFileInfoCancel(aTsyReqHandle); |
|
355 |
|
356 case EMobilePhoneReadScFile: |
|
357 return ReadScFileCancel(aTsyReqHandle); |
|
358 |
|
359 case EMobilePhoneUpdateScFile: |
|
360 return UpdateScFileCancel(aTsyReqHandle); |
|
361 |
|
362 default: |
|
363 break; |
|
364 } |
|
365 return KErrNone; |
|
366 } |
|
367 |
|
368 |
|
369 const CTestConfigSection* CSimPhoneSmartCardApp::CfgFile() |
|
370 /** |
|
371 * Returns a pointer to the config file section |
|
372 * |
|
373 * @return CTestConfigSection a pointer to the configuration file data section |
|
374 */ |
|
375 { |
|
376 LOGPHONE1(">>CSimPhoneSmartCardApp::CfgFile"); |
|
377 return iPhone->CfgFile(); |
|
378 } |
|
379 |
|
380 void CSimPhoneSmartCardApp::TimerCallBack(TInt /*aId*/) |
|
381 /** |
|
382 * Timer callback function. When the timer goes off, it will call back into this |
|
383 * function for further processing. |
|
384 * |
|
385 * @param aId an id identifying which timer callback is being called |
|
386 */ |
|
387 { |
|
388 if(iNotifyScInfo.iNotifyPending || iNotifyUSimInfo.iNotifyPending) |
|
389 { |
|
390 TSmartCardAppEvent theEvent=iSmartCardAppEventList->At(iEventPointer); |
|
391 TInt ret; |
|
392 RMobilePhone::TSmartCardApplicationEvent occuredEvent; |
|
393 TBool isUSimAppAffected = EFalse; |
|
394 |
|
395 if(theEvent.iAction == RMobilePhone::EScApplicationActivate) |
|
396 { |
|
397 ret=ActivateSmartCardApp(theEvent.iAID, isUSimAppAffected); |
|
398 occuredEvent = RMobilePhone::EScApplicationActivated; |
|
399 } |
|
400 else |
|
401 { |
|
402 ret=TerminateSmartCardApp(theEvent.iAID, isUSimAppAffected); |
|
403 occuredEvent = RMobilePhone::EScApplicationTerminated; |
|
404 } |
|
405 |
|
406 if (ret == KErrNone) |
|
407 { |
|
408 iEventPointer++; |
|
409 |
|
410 //notify any ScApp client if such notify request is pending |
|
411 if(iNotifyScInfo.iNotifyPending) |
|
412 { |
|
413 iNotifyScInfo.iNotifyPending=EFalse; |
|
414 *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=theEvent.iAID; |
|
415 *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=occuredEvent; |
|
416 iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); |
|
417 } |
|
418 |
|
419 //notify any USimApp client if such notify request is pending |
|
420 if(isUSimAppAffected && iNotifyUSimInfo.iNotifyPending) |
|
421 { |
|
422 iNotifyUSimInfo.iNotifyPending=EFalse; |
|
423 |
|
424 if(occuredEvent == RMobilePhone::EScApplicationActivated) |
|
425 { |
|
426 *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=theEvent.iAID; |
|
427 } |
|
428 else |
|
429 { |
|
430 *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=_L8(""); |
|
431 } |
|
432 |
|
433 *(TInt*)iNotifyUSimInfo.iNotifyData2=iUSimAppList->Count(); |
|
434 iPhone->ReqCompleted(iNotifyUSimInfo.iNotifyHandle,KErrNone); |
|
435 } |
|
436 } |
|
437 }//end if(iNotifyScInfo.iNotifyPending... |
|
438 } |
|
439 |
|
440 TBool CSimPhoneSmartCardApp::FoundScAppTags() |
|
441 /** |
|
442 * Returns a value to indicate whether SCApp tags were found in the Config file |
|
443 * |
|
444 */ |
|
445 { |
|
446 return iFoundScAppTags; |
|
447 } |
|
448 |
|
449 |
|
450 void CSimPhoneSmartCardApp::TSmartCardFile::GetFileInfo(RMobilePhone::TScFileInfoV5& aScFileInfo) |
|
451 /** |
|
452 * Gets the SmartCard file's File info |
|
453 * |
|
454 * @param aScFileInfo The function passes back the file info through this reference |
|
455 */ |
|
456 { |
|
457 aScFileInfo.iFileID = iFileID; |
|
458 aScFileInfo.iType = iType; |
|
459 aScFileInfo.iTotalLength = iTotalLength; |
|
460 aScFileInfo.iRecordLength = iRecordLength; |
|
461 aScFileInfo.iNumberRecords = iNumberRecords; |
|
462 } |
|
463 |
|
464 CSimPhoneSmartCardApp::TCyclicSmartCardFile::TCyclicSmartCardFile() |
|
465 :iOldestRecord(0) |
|
466 {} |
|
467 |
|
468 TInt CSimPhoneSmartCardApp::TCyclicSmartCardFile::ReadFile( |
|
469 const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aReadBuffer) |
|
470 /** |
|
471 * Concrete implementation of the ReadFile() method for reading file data from a record based |
|
472 * cyclic smart card file. Reads precisely one record (iRecordLength bytes). |
|
473 * |
|
474 * Note: Records are numbered from 1 to n NOT 0 to n-1 |
|
475 * |
|
476 * @param aFilePathOffsets Information about which file to read (path) and where in the file to read data from (offsets) |
|
477 * @param aReadBuffer The requested data is read into this buffer |
|
478 */ |
|
479 { |
|
480 //check that the client has provided a buffer of sufficient size |
|
481 if(aReadBuffer->MaxSize() < iRecordLength) |
|
482 { |
|
483 return KErrOverflow; |
|
484 } |
|
485 |
|
486 //check that the client has specified a valid start offset |
|
487 else if(aFilePathOffsets.iStartOffset < 1 || aFilePathOffsets.iStartOffset > iNumberRecords) |
|
488 { |
|
489 LOGPHONE1("ERROR: File start offset information invalid."); |
|
490 return KErrMMEtelScRecordNotFound; |
|
491 } |
|
492 |
|
493 else |
|
494 { |
|
495 //Var filepointer initially holds a pointer to the beginning of the specified record |
|
496 //The record to read is specified as an offset from the oldest record. I.e. Record 1 is the |
|
497 //newest record. |
|
498 TInt filePointer = iOldestRecord + (aFilePathOffsets.iStartOffset * iRecordLength); |
|
499 if(filePointer >= iTotalLength) |
|
500 { |
|
501 filePointer = filePointer - iTotalLength; |
|
502 } |
|
503 |
|
504 aReadBuffer->SetLength(iRecordLength); |
|
505 aReadBuffer->FillZ(); |
|
506 |
|
507 TInt index; |
|
508 |
|
509 for(index = 0; index < iRecordLength; index++) |
|
510 { |
|
511 (*aReadBuffer)[index] = iFileData[filePointer]; |
|
512 filePointer++; |
|
513 } |
|
514 return KErrNone; |
|
515 } |
|
516 } |
|
517 |
|
518 TInt CSimPhoneSmartCardApp::TCyclicSmartCardFile::UpdateFile( |
|
519 const RMobilePhone::TScFilePathWithAccessOffsets& /*aFilePathOffsets*/, TDes8* aWriteBuffer) |
|
520 /** |
|
521 * Concrete implementation of the UpdateFile() method for updating file data in a record based |
|
522 * cyclic smart card file. Updates precisely one record (iRecordLength bytes). The record that is |
|
523 * updated is the oldest record. |
|
524 * |
|
525 * Note: Records are numbered from 1 to n NOT 0 to n-1 |
|
526 * |
|
527 * @param aReadBuffer The data with which the file should be updated. |
|
528 */ |
|
529 { |
|
530 //Check that the client has provided a buffer of sufficient size |
|
531 if(aWriteBuffer->Size() != iRecordLength) |
|
532 { |
|
533 return KErrMMEtelScWrongLength; |
|
534 } |
|
535 else |
|
536 { |
|
537 TInt filePointer = iOldestRecord ; |
|
538 |
|
539 TInt index; |
|
540 |
|
541 for(index = 0; index < iRecordLength; index++) |
|
542 { |
|
543 iFileData[filePointer] = (*aWriteBuffer)[index]; |
|
544 filePointer++; |
|
545 } |
|
546 UpdateOldestRecordPointer(); |
|
547 return KErrNone; |
|
548 } |
|
549 } |
|
550 |
|
551 void CSimPhoneSmartCardApp::TCyclicSmartCardFile::UpdateOldestRecordPointer() |
|
552 { |
|
553 //IF the OldestRecord pointer is set to point to the beginning of the buffer |
|
554 if(iOldestRecord==0) |
|
555 { |
|
556 //Set it to point to the beginning of the last record in the buffer |
|
557 iOldestRecord = iTotalLength - iRecordLength; |
|
558 } |
|
559 //ELSE set it to point to the beginning of previous record (the second oldest record) |
|
560 else |
|
561 { |
|
562 iOldestRecord = iOldestRecord - iRecordLength; |
|
563 } |
|
564 } |
|
565 |
|
566 |
|
567 TInt CSimPhoneSmartCardApp::TLinearSmartCardFile::ReadFile( |
|
568 const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aReadBuffer) |
|
569 /** |
|
570 * Concrete implementation of the ReadFile() method for reading file data from a record based |
|
571 * linear fixed smart card file. Reads precisely one record (iRecordLength bytes). |
|
572 * |
|
573 * Note: Records are numbered from 1 to n NOT 0 to n-1 |
|
574 * |
|
575 * @param aFilePathOffsets Information about which file to read (path) and where in the file to read data from (offsets) |
|
576 * @param aReadBuffer The requested data is read into this buffer |
|
577 */ |
|
578 { |
|
579 //check that the client has provided a buffer of sufficient size |
|
580 if(aReadBuffer->MaxSize() < iRecordLength) |
|
581 { |
|
582 return KErrOverflow; |
|
583 } |
|
584 |
|
585 //check that the client has specified a valid start offset |
|
586 else if(aFilePathOffsets.iStartOffset < 1 || aFilePathOffsets.iStartOffset > iNumberRecords) |
|
587 { |
|
588 LOGPHONE1("ERROR: File start offset information invalid."); |
|
589 return KErrMMEtelScRecordNotFound; |
|
590 } |
|
591 else |
|
592 { |
|
593 TInt filePointer = (aFilePathOffsets.iStartOffset - 1) * iRecordLength; |
|
594 TInt index; |
|
595 |
|
596 aReadBuffer->SetLength(iRecordLength); |
|
597 aReadBuffer->FillZ(); |
|
598 |
|
599 for(index = 0; index < iRecordLength; index++) |
|
600 { |
|
601 (*aReadBuffer)[index] = iFileData[filePointer]; |
|
602 filePointer++; |
|
603 } |
|
604 return KErrNone; |
|
605 } |
|
606 } |
|
607 |
|
608 TInt CSimPhoneSmartCardApp::TLinearSmartCardFile::UpdateFile( |
|
609 const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aWriteBuffer) |
|
610 /** |
|
611 * Concrete implementation of the UpdateFile() method for updating data in a record based |
|
612 * linear fixed smart card file. Updates precisely one record (iRecordLength bytes). |
|
613 * |
|
614 * Note: Records are numbered from 1 to n NOT 0 to n-1 |
|
615 * |
|
616 * @param aFilePathOffsets Information about which file to update (path) and where in the file to write data to (offsets) |
|
617 * @param aReadBuffer The data with which the file should be updated. |
|
618 */ |
|
619 { |
|
620 //check that the client has provided a buffer of sufficient size |
|
621 if(aWriteBuffer->Size() != iRecordLength) |
|
622 { |
|
623 return KErrMMEtelScWrongLength; |
|
624 } |
|
625 |
|
626 //check that the client has specified a valid start offset |
|
627 else if(aFilePathOffsets.iStartOffset < 1 || aFilePathOffsets.iStartOffset > iNumberRecords) |
|
628 { |
|
629 LOGPHONE1("ERROR: File start offset information invalid."); |
|
630 return KErrMMEtelScRecordNotFound; |
|
631 } |
|
632 else |
|
633 { |
|
634 TInt filePointer = (aFilePathOffsets.iStartOffset - 1) * iRecordLength; |
|
635 TInt index; |
|
636 |
|
637 for(index = 0; index < iRecordLength; index++) |
|
638 { |
|
639 iFileData[filePointer] = (*aWriteBuffer)[index]; |
|
640 filePointer++; |
|
641 } |
|
642 return KErrNone; |
|
643 } |
|
644 } |
|
645 |
|
646 TInt CSimPhoneSmartCardApp::TTransparentSmartCardFile::ReadFile( |
|
647 const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aReadBuffer) |
|
648 /** |
|
649 * Concrete implementation of the ReadFile() method for reading file data from a binary transparent |
|
650 * smart card file. |
|
651 * |
|
652 * @param aFilePathOffsets Information about which file to read (path) and where in the file to read data from (offsets) |
|
653 * @param aReadBuffer The requested data is read into this buffer |
|
654 */ |
|
655 { |
|
656 const TInt& bytesToRead = aFilePathOffsets.iCount; |
|
657 TInt filePointer = aFilePathOffsets.iStartOffset; |
|
658 |
|
659 //check that the client has provided a buffer of sufficient size |
|
660 if(aReadBuffer->MaxSize() < bytesToRead) |
|
661 { |
|
662 return KErrOverflow; |
|
663 } |
|
664 |
|
665 //check that the client has specified a valid start offset |
|
666 else if(aFilePathOffsets.iStartOffset >= (TUint)iTotalLength) |
|
667 { |
|
668 LOGPHONE1("ERROR: File start offset information invalid."); |
|
669 return KErrMMEtelScReferencedDataNotFound; |
|
670 } |
|
671 |
|
672 //check the client is not requesting to read too many bytes, resulting in reading |
|
673 //off the end of the file |
|
674 else if((bytesToRead + filePointer) > iTotalLength) |
|
675 { |
|
676 LOGPHONE1("ERROR: Path offset information results in reading off the end of the file"); |
|
677 return KErrMMEtelScEofReached; |
|
678 } |
|
679 else |
|
680 { |
|
681 aReadBuffer->SetLength(bytesToRead); |
|
682 aReadBuffer->FillZ(); |
|
683 |
|
684 TInt index; |
|
685 |
|
686 for(index = 0; index < bytesToRead; index++) |
|
687 { |
|
688 (*aReadBuffer)[index] = iFileData[filePointer]; |
|
689 filePointer++; |
|
690 } |
|
691 return KErrNone; |
|
692 } |
|
693 } |
|
694 |
|
695 TInt CSimPhoneSmartCardApp::TTransparentSmartCardFile::UpdateFile( |
|
696 const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aWriteBuffer) |
|
697 /** |
|
698 * Concrete implementation of the UpdateFile() method for updating data in a binary transparent |
|
699 * smart card file. |
|
700 * |
|
701 * @param aFilePathOffsets Information about which file to update (path) and where in the file to write data to (offsets) |
|
702 * @param aReadBuffer The data with which the file should be updated. |
|
703 */ |
|
704 { |
|
705 const TInt& bytesToWrite = aFilePathOffsets.iCount; |
|
706 TInt filePointer = aFilePathOffsets.iStartOffset; |
|
707 TInt index; |
|
708 |
|
709 //check that the client has provided a buffer of sufficient size |
|
710 if(aWriteBuffer->Size() != bytesToWrite) |
|
711 { |
|
712 //The length of the provided buffer does not match the number of bytes that client has requested |
|
713 //should be updated in the file. |
|
714 return KErrArgument; |
|
715 } |
|
716 |
|
717 //check that the client has specified a valid start offset |
|
718 else if(aFilePathOffsets.iStartOffset >= (TUint)iTotalLength) |
|
719 { |
|
720 LOGPHONE1("ERROR: File start offset information invalid."); |
|
721 return KErrMMEtelScReferencedDataNotFound; |
|
722 } |
|
723 |
|
724 //check the client is not requesting to write too many bytes, resulting in writing |
|
725 //off the end of the file |
|
726 else if((bytesToWrite + filePointer) > iTotalLength) |
|
727 { |
|
728 LOGPHONE1("ERROR: Path offset information results in reading off the end of the file"); |
|
729 return KErrMMEtelScEofReached; |
|
730 } |
|
731 else |
|
732 { |
|
733 for(index = 0; index < bytesToWrite; index++) |
|
734 { |
|
735 iFileData[filePointer] = (*aWriteBuffer)[index]; |
|
736 filePointer++; |
|
737 } |
|
738 |
|
739 return KErrNone; |
|
740 } |
|
741 } |
|
742 |
|
743 RMobilePhone::TAID CSimPhoneSmartCardApp::GetActiveUSim() |
|
744 /** |
|
745 * Returns the active aid (internally) |
|
746 * |
|
747 */ |
|
748 { |
|
749 return iActiveUSimApp; |
|
750 } |
|
751 |
|
752 TInt CSimPhoneSmartCardApp::GetCurrentActiveUSimApplication(const TTsyReqHandle aTsyReqHandle, RMobilePhone::TAID* aAID) |
|
753 /** |
|
754 * Returns the active aid |
|
755 * |
|
756 * @param aReqHandle The TSY request handle for this request. |
|
757 * @param aAID Returns the AID of the Active USim Application |
|
758 * @return KErrNone |
|
759 */ |
|
760 { |
|
761 if(iActiveUSimApp.Size() == 0) |
|
762 { |
|
763 iPhone->ReqCompleted(aTsyReqHandle, KErrMMEtelScApplicationNotActive); |
|
764 } |
|
765 else |
|
766 { |
|
767 *aAID=iActiveUSimApp; |
|
768 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
769 } |
|
770 return KErrNone; |
|
771 } |
|
772 |
|
773 TInt CSimPhoneSmartCardApp::GetCurrentActiveUSimApplicationCancel(const TTsyReqHandle aTsyReqHandle) |
|
774 /** |
|
775 * Attempts to cancel a pending GetActiveUSimApplication request (unsuccessfully) |
|
776 * |
|
777 */ |
|
778 { |
|
779 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
780 return KErrNone; |
|
781 } |
|
782 |
|
783 |
|
784 TInt CSimPhoneSmartCardApp::EnumerateUSimApplications(TTsyReqHandle aTsyReqHandle, TInt* aCount, RMobilePhone::TAID* aActiveAID) |
|
785 /** |
|
786 * Enumerates the number of USim applications in the UICC and returns the |
|
787 * AID of the active application. |
|
788 * |
|
789 * @param aTsyReqHandle A handle belonging to the client that created the |
|
790 * session with this TSY server. |
|
791 * @param aCount Returns the number of USim applications. |
|
792 * @param aActiveAID Returns the AID of the currently active application. |
|
793 * @return KErrNone. |
|
794 */ |
|
795 { |
|
796 *aCount=iUSimAppList->Count(); |
|
797 aActiveAID->Copy(iActiveUSimApp); |
|
798 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
799 return KErrNone; |
|
800 } |
|
801 |
|
802 |
|
803 TInt CSimPhoneSmartCardApp::EnumerateUSimApplicationsCancel(TTsyReqHandle aTsyReqHandle) |
|
804 /** |
|
805 *Attempts to cancel a pending EnumerateUSimApplications request (unsuccesfully). |
|
806 * |
|
807 *@param aTsyReqHandle A handle belonging to the client that created the |
|
808 * session with this TSY server. |
|
809 */ |
|
810 { |
|
811 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
812 return KErrNone; |
|
813 } |
|
814 |
|
815 |
|
816 TInt CSimPhoneSmartCardApp::GetUSimApplicationInfo(TTsyReqHandle aTsyReqHandle, TInt* aUSimAppIndex, TDes8* aInfo) |
|
817 /** |
|
818 * Retrieves information for a specified USim application |
|
819 * |
|
820 * @param aTsyReqHandle A handle belonging to the client that created the |
|
821 * session with this TSY server. |
|
822 * @param aUSimAppIndex Used to specify the index of the application. |
|
823 * @param aInfo Returns the information of the specified appplication. |
|
824 * @return KErrNone. |
|
825 */ |
|
826 { |
|
827 if(*aUSimAppIndex>=iUSimAppList->Count()) |
|
828 { |
|
829 iPhone->ReqCompleted(aTsyReqHandle, KErrNotFound); |
|
830 return KErrNone; |
|
831 } |
|
832 else |
|
833 { |
|
834 TPckg<RMobilePhone::TUSimApplicationInfoV2>* infoPckg = |
|
835 (TPckg<RMobilePhone::TUSimApplicationInfoV2>*)aInfo; |
|
836 |
|
837 RMobilePhone::TUSimApplicationInfoV2& info = (*infoPckg)(); |
|
838 |
|
839 // Check that the data structure is supported by the simulated TSY version |
|
840 TInt err = iPhone->CheckSimTsyVersion(info); |
|
841 if(err != KErrNone) |
|
842 { |
|
843 iPhone->ReqCompleted(aTsyReqHandle, err); |
|
844 return KErrNone; |
|
845 } |
|
846 |
|
847 info.iAID = (*iUSimAppList)[*aUSimAppIndex]->iAID; |
|
848 info.iLabel = (*iUSimAppList)[*aUSimAppIndex]->iLabel; |
|
849 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
850 } |
|
851 |
|
852 return KErrNone; |
|
853 } |
|
854 |
|
855 /** |
|
856 Attempts to cancel a pending GetUSimApplicationInfo request |
|
857 (unsuccesfully). |
|
858 |
|
859 @param aTsyReqHandle A handle belonging to the client that created the |
|
860 session with this TSY server. |
|
861 */ |
|
862 TInt CSimPhoneSmartCardApp::GetUSimApplicationInfoCancel(TTsyReqHandle aTsyReqHandle) |
|
863 { |
|
864 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
865 return KErrNone; |
|
866 } |
|
867 |
|
868 |
|
869 TInt CSimPhoneSmartCardApp::SetUSimApplicationStatus(TTsyReqHandle aTsyReqHandle, RMobilePhone::TAID* aAID, RMobilePhone::TUSimAppAction* aUsimAppAction) |
|
870 /** |
|
871 * Attempts to set the status of a specific USim application. |
|
872 * |
|
873 * @param aTsyReqHandle A handle belonging to the client that created the |
|
874 * session with this TSY server. |
|
875 * @param aAID The specific application's ID whose status is to be set. |
|
876 * @param aUsimAppAction The status to apply to the application identified |
|
877 * by aAID. |
|
878 * @return KErrNone on completion of request, unless the aAID given is not |
|
879 * identifiable, in which case KErrArgument is returned. |
|
880 */ |
|
881 { |
|
882 TInt ret; |
|
883 RMobilePhone::TAID aAidToAction; |
|
884 RMobilePhone::TSmartCardApplicationEvent aScEvent; |
|
885 TBool isUSimAppAffected = EFalse; |
|
886 |
|
887 //if the request is to activate a USimApp |
|
888 if(*aUsimAppAction == RMobilePhone::EUSimActivate) |
|
889 { |
|
890 //if another USimApp is active. |
|
891 if(iActiveUSimApp.Size() != 0) |
|
892 { |
|
893 //terminate active USimApp |
|
894 aAidToAction = iActiveUSimApp; |
|
895 aScEvent = RMobilePhone::EScApplicationTerminated; |
|
896 isUSimAppAffected = EFalse; |
|
897 ret = TerminateSmartCardApp(aAidToAction, isUSimAppAffected); |
|
898 |
|
899 //if No error terminating |
|
900 if (ret == KErrNone) |
|
901 { |
|
902 //notify ScApp client if notify request is pending |
|
903 if(iNotifyScInfo.iNotifyPending) |
|
904 { |
|
905 *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=aAidToAction; |
|
906 *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=aScEvent; |
|
907 iNotifyScInfo.iNotifyPending=EFalse; |
|
908 iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); |
|
909 } |
|
910 } |
|
911 }//end if(iActiveUSimApp.Size() != 0) |
|
912 |
|
913 //activate the requested application |
|
914 aAidToAction = *aAID; |
|
915 aScEvent = RMobilePhone::EScApplicationActivated; |
|
916 isUSimAppAffected = EFalse; |
|
917 ret=ActivateSmartCardApp(*aAID, isUSimAppAffected); |
|
918 |
|
919 //if no error activating |
|
920 if (ret == KErrNone) |
|
921 { |
|
922 //notify any ScApp client if such notify request is pending |
|
923 if(iNotifyScInfo.iNotifyPending) |
|
924 { |
|
925 iNotifyScInfo.iNotifyPending=EFalse; |
|
926 *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=aAidToAction; |
|
927 *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=aScEvent; |
|
928 iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); |
|
929 } |
|
930 //notify any USimApp client if such notify request is pending |
|
931 if(iNotifyUSimInfo.iNotifyPending) |
|
932 { |
|
933 iNotifyUSimInfo.iNotifyPending=EFalse; |
|
934 *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=aAidToAction; |
|
935 *(TInt*)iNotifyUSimInfo.iNotifyData2=iUSimAppList->Count(); |
|
936 iPhone->ReqCompleted(iNotifyUSimInfo.iNotifyHandle,KErrNone); |
|
937 } |
|
938 } |
|
939 |
|
940 //complete requests and return |
|
941 iPhone->ReqCompleted(aTsyReqHandle,ret); |
|
942 return KErrNone; |
|
943 |
|
944 } |
|
945 |
|
946 else |
|
947 { |
|
948 //the request is to terminate a USimApp |
|
949 aAidToAction = *aAID; |
|
950 aScEvent = RMobilePhone::EScApplicationTerminated; |
|
951 |
|
952 //terminate active USimApp |
|
953 isUSimAppAffected = EFalse; |
|
954 ret = TerminateSmartCardApp(aAidToAction, isUSimAppAffected); |
|
955 |
|
956 //if No error terminating |
|
957 if (ret == KErrNone) |
|
958 { |
|
959 //notify ScApp client if such notify request is pending |
|
960 if(iNotifyScInfo.iNotifyPending) |
|
961 { |
|
962 *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=aAidToAction; |
|
963 *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=aScEvent; |
|
964 iNotifyScInfo.iNotifyPending=EFalse; |
|
965 iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); |
|
966 } |
|
967 //notify any USimApp client if such notify request is pending |
|
968 if(iNotifyUSimInfo.iNotifyPending) |
|
969 { |
|
970 *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=_L8(""); |
|
971 *(TInt*)iNotifyUSimInfo.iNotifyData2=iUSimAppList->Count(); |
|
972 iNotifyUSimInfo.iNotifyPending=EFalse; |
|
973 iPhone->ReqCompleted(iNotifyUSimInfo.iNotifyHandle,KErrNone); |
|
974 } |
|
975 } |
|
976 //complete requests and return |
|
977 iPhone->ReqCompleted(aTsyReqHandle,ret); |
|
978 return KErrNone; |
|
979 } |
|
980 } |
|
981 |
|
982 |
|
983 TInt CSimPhoneSmartCardApp::SetUSimApplicationStatusCancel(TTsyReqHandle aTsyReqHandle) |
|
984 /** |
|
985 * Attempts to cancel a pending SetUSimApplicationStatus request (unsuccesfully). |
|
986 * |
|
987 * @param aTsyReqHandle A handle belonging to the client that created the |
|
988 * session with this TSY server. |
|
989 * @return KErrNone. |
|
990 */ |
|
991 { |
|
992 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
993 return KErrNone; |
|
994 } |
|
995 |
|
996 |
|
997 TInt CSimPhoneSmartCardApp::NotifyUSimApplicationsInfoChange(const TTsyReqHandle aTsyReqHandle, TInt* aCount, RMobilePhone::TAID* aActiveAID) |
|
998 /** |
|
999 * Notifies the client when the specified USim application's information |
|
1000 * changes. |
|
1001 * |
|
1002 * @param aTsyReqHandle A handle belonging to the client that created the |
|
1003 * session with this TSY server. |
|
1004 * @param aCount Returns the total number of USim applications when the |
|
1005 * request completes. |
|
1006 * @param aActiveAID The application's AID whose infromation change will |
|
1007 * be notified to the client. |
|
1008 * @return KErrNone. |
|
1009 */ |
|
1010 { |
|
1011 __ASSERT_ALWAYS(!iNotifyUSimInfo.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding)); |
|
1012 |
|
1013 TInt count=iSmartCardAppEventList->Count(); |
|
1014 |
|
1015 if(iEventPointer<count) |
|
1016 { |
|
1017 if(iTimerStarted) |
|
1018 { |
|
1019 delete iTimer; |
|
1020 iTimer = NULL; |
|
1021 TRAP_IGNORE(iTimer=CSimTimer::NewL(iPhone)); |
|
1022 } |
|
1023 |
|
1024 TSmartCardAppEvent event=iSmartCardAppEventList->At(iEventPointer); |
|
1025 |
|
1026 if (iTimer != NULL) |
|
1027 { |
|
1028 iTimer->Start(event.iDuration,this); |
|
1029 iTimerStarted = ETrue; |
|
1030 } |
|
1031 } |
|
1032 |
|
1033 iNotifyUSimInfo.iNotifyPending=ETrue; |
|
1034 iNotifyUSimInfo.iNotifyHandle=aTsyReqHandle; |
|
1035 iNotifyUSimInfo.iNotifyData1=aActiveAID; |
|
1036 iNotifyUSimInfo.iNotifyData2=aCount; |
|
1037 return KErrNone; |
|
1038 } |
|
1039 |
|
1040 |
|
1041 /** |
|
1042 *Attempts to cancel a pending NotifyUSimApplicationsInfoChange request. |
|
1043 * |
|
1044 *@param aTsyReqHandle A handle belonging to the client that created the |
|
1045 * session with this TSY server. |
|
1046 *@param KErrNone |
|
1047 */ |
|
1048 TInt CSimPhoneSmartCardApp::NotifyUSimApplicationsInfoChangeCancel(TTsyReqHandle aTsyReqHandle) |
|
1049 { |
|
1050 if(iNotifyUSimInfo.iNotifyPending) |
|
1051 { |
|
1052 iNotifyUSimInfo.iNotifyPending=EFalse; |
|
1053 iPhone->ReqCompleted(aTsyReqHandle,KErrCancel); |
|
1054 } |
|
1055 return KErrNone; |
|
1056 } |
|
1057 |
|
1058 |
|
1059 TInt CSimPhoneSmartCardApp::EnumerateScApplications(const TTsyReqHandle aTsyReqHandle, TUint* aCount) |
|
1060 /** |
|
1061 * Enumerates the number of Smart Card applications on the UICC |
|
1062 * |
|
1063 * @param aReqHandle The TSY request handle for this request |
|
1064 * @param aCount Returns the number of Smart Card applications |
|
1065 * @return KErrNone |
|
1066 */ |
|
1067 |
|
1068 { |
|
1069 *aCount=iSmartCardAppList->Count(); |
|
1070 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1071 return KErrNone; |
|
1072 } |
|
1073 |
|
1074 TInt CSimPhoneSmartCardApp::EnumerateScApplicationsCancel(const TTsyReqHandle aTsyReqHandle) |
|
1075 /** |
|
1076 * Attempts to cancel a pending EnumerateUSimApplications request (unsuccessfully) |
|
1077 * |
|
1078 * @param aReqHandle The TSY request handle for this request |
|
1079 */ |
|
1080 { |
|
1081 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1082 return KErrNone; |
|
1083 } |
|
1084 |
|
1085 TInt CSimPhoneSmartCardApp::GetScApplicationInfo(const TTsyReqHandle aTsyReqHandle, TInt* aAppIndex, TDes8* aInfo) |
|
1086 /** |
|
1087 * Retrieves information for a specified Smart Card application |
|
1088 * |
|
1089 * @param aReqHandle The TSY request handle for this request |
|
1090 * @param aAppIndex is used to specify the index of the application |
|
1091 * @param aInfo Returns the information of the specified appplication |
|
1092 * @return KErrNone |
|
1093 */ |
|
1094 { |
|
1095 if(*aAppIndex>=iSmartCardAppList->Count()) |
|
1096 { |
|
1097 iPhone->ReqCompleted(aTsyReqHandle, KErrNotFound); |
|
1098 } |
|
1099 else |
|
1100 { |
|
1101 TPckg<RMobilePhone::TSmartCardApplicationInfoV5>* infoPckg = |
|
1102 (TPckg<RMobilePhone::TSmartCardApplicationInfoV5>*)aInfo; |
|
1103 |
|
1104 RMobilePhone::TSmartCardApplicationInfoV5& info = (*infoPckg)(); |
|
1105 |
|
1106 // Check that the data structure is supported by the simulated TSY version |
|
1107 TInt err = iPhone->CheckSimTsyVersion(info); |
|
1108 if(err != KErrNone) |
|
1109 { |
|
1110 iPhone->ReqCompleted(aTsyReqHandle, err); |
|
1111 return KErrNone; |
|
1112 } |
|
1113 |
|
1114 info.iAID=iSmartCardAppList->At(*aAppIndex).iAID; |
|
1115 info.iLabel=iSmartCardAppList->At(*aAppIndex).iLabel; |
|
1116 if (info.ExtensionId() == KEtelExtMultimodeV6) |
|
1117 { |
|
1118 RMobilePhone::TUiccApplicationEapInfoV6& withEapInfo = static_cast<RMobilePhone::TUiccApplicationEapInfoV6&>(info); |
|
1119 withEapInfo.iEapTypeList = iSmartCardAppList->At(*aAppIndex).iEapList; |
|
1120 } |
|
1121 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1122 } |
|
1123 |
|
1124 return KErrNone; |
|
1125 } |
|
1126 |
|
1127 TInt CSimPhoneSmartCardApp::GetScApplicationInfoCancel(const TTsyReqHandle aTsyReqHandle) |
|
1128 /** |
|
1129 * Attempts to cancel a pending GetScApplicationInfo request (unsuccessfully) |
|
1130 * |
|
1131 */ |
|
1132 { |
|
1133 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1134 return KErrNone; |
|
1135 } |
|
1136 |
|
1137 TInt CSimPhoneSmartCardApp::NotifyScApplicationInfoChange(const TTsyReqHandle aTsyReqHandle, |
|
1138 RMobilePhone::TAID* aAID, RMobilePhone::TSmartCardApplicationEvent* aEvent) |
|
1139 /** |
|
1140 * Notifies of any Smart Card application information changes |
|
1141 * |
|
1142 * @param aReqHandle The TSY request handle for this request |
|
1143 * @param aAID Return the AID of the application whose status has changed |
|
1144 * @param aEvent Return the event that took place on application aAID |
|
1145 * @return KErrNone |
|
1146 */ |
|
1147 |
|
1148 { |
|
1149 __ASSERT_ALWAYS(!iNotifyScInfo.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding)); |
|
1150 |
|
1151 TInt count=iSmartCardAppEventList->Count(); |
|
1152 |
|
1153 if(iEventPointer<count) |
|
1154 { |
|
1155 if(iTimerStarted) |
|
1156 { |
|
1157 delete iTimer; |
|
1158 iTimer = NULL; |
|
1159 TRAP_IGNORE(iTimer=CSimTimer::NewL(iPhone)); |
|
1160 } |
|
1161 |
|
1162 TSmartCardAppEvent event=iSmartCardAppEventList->At(iEventPointer); |
|
1163 |
|
1164 if (iTimer != NULL) |
|
1165 { |
|
1166 iTimer->Start(event.iDuration,this); |
|
1167 iTimerStarted = ETrue; |
|
1168 } |
|
1169 } |
|
1170 iNotifyScInfo.iNotifyPending=ETrue; |
|
1171 iNotifyScInfo.iNotifyHandle=aTsyReqHandle; |
|
1172 iNotifyScInfo.iNotifyData1=aAID; |
|
1173 iNotifyScInfo.iNotifyData2=aEvent; |
|
1174 return KErrNone; |
|
1175 } |
|
1176 |
|
1177 TInt CSimPhoneSmartCardApp::NotifyScApplicationInfoChangeCancel(const TTsyReqHandle aTsyReqHandle) |
|
1178 /** |
|
1179 * Attempts to cancel a pending NotifyUSimApplicationsInfoChange request |
|
1180 * |
|
1181 */ |
|
1182 { |
|
1183 if(iNotifyScInfo.iNotifyPending) |
|
1184 { |
|
1185 iNotifyScInfo.iNotifyPending=EFalse; |
|
1186 iPhone->ReqCompleted(aTsyReqHandle,KErrCancel); |
|
1187 } |
|
1188 return KErrNone; |
|
1189 } |
|
1190 |
|
1191 |
|
1192 TInt CSimPhoneSmartCardApp::SetScApplicationStatus(const TTsyReqHandle aTsyReqHandle, RMobilePhone::TAID* aAID, RMobilePhone::TSmartCardApplicationAction* aAction) |
|
1193 /** |
|
1194 * Sets the Application Status for specified smart card application |
|
1195 * |
|
1196 * @param aReqHandle The TSY request handle for this request |
|
1197 * @param aAID The AID of the application whose status should be changed |
|
1198 * @param aAction The action that should take place on the specified application |
|
1199 * @return KErrNone |
|
1200 */ |
|
1201 { |
|
1202 TInt ret; |
|
1203 RMobilePhone::TSmartCardApplicationEvent event; |
|
1204 TBool isUSimAppAffected = EFalse; |
|
1205 |
|
1206 if(*aAction==RMobilePhone::EScApplicationActivate) |
|
1207 { |
|
1208 event=RMobilePhone::EScApplicationActivated; |
|
1209 ret=ActivateSmartCardApp(*aAID, isUSimAppAffected); |
|
1210 } |
|
1211 else |
|
1212 { |
|
1213 event=RMobilePhone::EScApplicationTerminated; |
|
1214 ret=TerminateSmartCardApp(*aAID, isUSimAppAffected); |
|
1215 } |
|
1216 |
|
1217 if(ret==KErrNone) |
|
1218 { |
|
1219 if(iNotifyScInfo.iNotifyPending) |
|
1220 { |
|
1221 iNotifyScInfo.iNotifyPending=EFalse; |
|
1222 *(RMobilePhone::TAID*)iNotifyScInfo.iNotifyData1=*aAID; |
|
1223 *(RMobilePhone::TSmartCardApplicationEvent*)iNotifyScInfo.iNotifyData2=event; |
|
1224 iPhone->ReqCompleted(iNotifyScInfo.iNotifyHandle,KErrNone); |
|
1225 } |
|
1226 |
|
1227 //If the affected ScApp is a USimApp... |
|
1228 //notify any USimApp client if such notify request is pending |
|
1229 if(isUSimAppAffected && iNotifyUSimInfo.iNotifyPending) |
|
1230 { |
|
1231 iNotifyUSimInfo.iNotifyPending=EFalse; |
|
1232 |
|
1233 if(event == RMobilePhone::EScApplicationActivated) |
|
1234 { |
|
1235 *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=*aAID; |
|
1236 } |
|
1237 else |
|
1238 { |
|
1239 *(RMobilePhone::TAID*)iNotifyUSimInfo.iNotifyData1=_L8(""); |
|
1240 } |
|
1241 |
|
1242 *(TInt*)iNotifyUSimInfo.iNotifyData2=iUSimAppList->Count(); |
|
1243 iPhone->ReqCompleted(iNotifyUSimInfo.iNotifyHandle,KErrNone); |
|
1244 } |
|
1245 } |
|
1246 |
|
1247 iPhone->ReqCompleted(aTsyReqHandle,ret); |
|
1248 return KErrNone; |
|
1249 } |
|
1250 |
|
1251 TInt CSimPhoneSmartCardApp::SetScApplicationStatusCancel(const TTsyReqHandle aTsyReqHandle) |
|
1252 /** |
|
1253 * Attempts to cancel a pending SetScApplicationStatus request (unsuccessfully) |
|
1254 * |
|
1255 */ |
|
1256 { |
|
1257 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1258 return KErrNone; |
|
1259 } |
|
1260 |
|
1261 TInt CSimPhoneSmartCardApp::SetUSimAppsSelectionMode(TTsyReqHandle aTsyReqHandle, RMobilePhone::TUSimSelectionMode* aUSimSelectionMode) |
|
1262 /** |
|
1263 * Sets the Selection mode for USim applications |
|
1264 * |
|
1265 * @param aReqHandle The TSY request handle for this request |
|
1266 * @param aUSimSelectionMode is used to specify the new selection mode for applications |
|
1267 * @return KErrNone |
|
1268 */ |
|
1269 { |
|
1270 iCurrentSelection=*aUSimSelectionMode; |
|
1271 if(iNotifyMode.iNotifyPending) |
|
1272 { |
|
1273 iNotifyMode.iNotifyPending=EFalse; |
|
1274 *(RMobilePhone::TUSimSelectionMode*)iNotifyMode.iNotifyData=iCurrentSelection; |
|
1275 iPhone->ReqCompleted(iNotifyMode.iNotifyHandle,KErrNone); |
|
1276 } |
|
1277 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1278 return KErrNone; |
|
1279 } |
|
1280 |
|
1281 TInt CSimPhoneSmartCardApp::SetUSimAppsSelectionModeCancel(const TTsyReqHandle aTsyReqHandle) |
|
1282 /** |
|
1283 * Attempts to cancel a pending SetUSimAppsSelectionMode request (unsuccessfully) |
|
1284 * |
|
1285 */ |
|
1286 { |
|
1287 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1288 return KErrNone; |
|
1289 } |
|
1290 |
|
1291 TInt CSimPhoneSmartCardApp::GetUSimAppsSelectionMode(TTsyReqHandle aTsyReqHandle, RMobilePhone::TUSimSelectionMode* aUSimSelectionMode) |
|
1292 /** |
|
1293 * Gets the Selection mode for USim applications |
|
1294 * |
|
1295 * @param aReqHandle The TSY request handle for this request |
|
1296 * @param aUSimSelectionMode Returns the selection mode for applications |
|
1297 * @return KErrNone |
|
1298 */ |
|
1299 { |
|
1300 *aUSimSelectionMode=iCurrentSelection; |
|
1301 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1302 return KErrNone; |
|
1303 } |
|
1304 |
|
1305 TInt CSimPhoneSmartCardApp::GetUSimAppsSelectionModeCancel(const TTsyReqHandle aTsyReqHandle) |
|
1306 /** |
|
1307 * Attempts to cancel a pending GetUSimAppsSelectionMode request (unsuccessfully) |
|
1308 * |
|
1309 */ |
|
1310 { |
|
1311 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1312 return KErrNone; |
|
1313 } |
|
1314 |
|
1315 TInt CSimPhoneSmartCardApp::NotifyUSIMAppsSelectionModeChange(TTsyReqHandle aTsyReqHandle, RMobilePhone::TUSimSelectionMode* aUSimSelectionMode) |
|
1316 /** |
|
1317 * Notifies for any Selection mode changes for USim applications |
|
1318 * |
|
1319 * @param aReqHandle The TSY request handle for this request |
|
1320 * @param aUSimSelectionMode Returns the new selection mode for applications |
|
1321 * @return KErrNone |
|
1322 */ |
|
1323 { |
|
1324 __ASSERT_ALWAYS(!iNotifyMode.iNotifyPending,SimPanic(ENotificationReqAlreadyOutstanding)); |
|
1325 iNotifyMode.iNotifyPending=ETrue; |
|
1326 iNotifyMode.iNotifyHandle=aTsyReqHandle; |
|
1327 iNotifyMode.iNotifyData=aUSimSelectionMode; |
|
1328 return KErrNone; |
|
1329 } |
|
1330 |
|
1331 TInt CSimPhoneSmartCardApp::NotifyUSIMAppsSelectionModeChangeCancel(TTsyReqHandle aTsyReqHandle) |
|
1332 /** |
|
1333 * Attempts to cancel a pending NotifyUSIMAppsSelectionModeChange request |
|
1334 * |
|
1335 */ |
|
1336 { |
|
1337 if(iNotifyMode.iNotifyPending) |
|
1338 { |
|
1339 iNotifyMode.iNotifyPending=EFalse; |
|
1340 iPhone->ReqCompleted(aTsyReqHandle,KErrCancel); |
|
1341 } |
|
1342 return KErrNone; |
|
1343 } |
|
1344 |
|
1345 |
|
1346 TInt CSimPhoneSmartCardApp::GetScFileInfo(const TTsyReqHandle aTsyReqHandle, |
|
1347 const RMobilePhone::TScFilePath& aFilePathId, TDes8* aInfo) |
|
1348 /** |
|
1349 * Gets information about the specified smart card file |
|
1350 * |
|
1351 * @param aReqHandle The TSY request handle for this request |
|
1352 * @param aFilePathId Used to specify path of the file for which information should be retrieved |
|
1353 * @param aInfo Used to return the retrieved file information |
|
1354 */ |
|
1355 { |
|
1356 |
|
1357 LOGPHONE1("CSimPhoneSmartCardApp::GetScFileInfo called"); |
|
1358 |
|
1359 RMobilePhone::TScFileInfoV5Pckg *scFileInfoPckg = reinterpret_cast<RMobilePhone::TScFileInfoV5Pckg*>(aInfo); |
|
1360 RMobilePhone::TScFileInfoV5 &scFileInfo = (*scFileInfoPckg)(); |
|
1361 |
|
1362 // Check that the data structure is supported by the simulated TSY version |
|
1363 TInt err = iPhone->CheckSimTsyVersion(scFileInfo); |
|
1364 if(err != KErrNone) |
|
1365 { |
|
1366 iPhone->ReqCompleted(aTsyReqHandle, err); |
|
1367 return KErrNone; |
|
1368 } |
|
1369 |
|
1370 if(scFileInfo.ExtensionId() == KEtelExtMultimodeV5) |
|
1371 { |
|
1372 TSmartCardFile* scFile = NULL; |
|
1373 TInt ret = FindScFile(aFilePathId, scFile); |
|
1374 if(ret==KErrNone) |
|
1375 { |
|
1376 scFile->GetFileInfo(scFileInfo); |
|
1377 iPhone->ReqCompleted(aTsyReqHandle,KErrNone); |
|
1378 } |
|
1379 else |
|
1380 { |
|
1381 iPhone->ReqCompleted(aTsyReqHandle,ret); |
|
1382 } |
|
1383 } |
|
1384 |
|
1385 else |
|
1386 { |
|
1387 iPhone->ReqCompleted(aTsyReqHandle,KErrCorrupt); |
|
1388 } |
|
1389 |
|
1390 return KErrNone; |
|
1391 } |
|
1392 |
|
1393 |
|
1394 TInt CSimPhoneSmartCardApp::GetScFileInfoCancel(const TTsyReqHandle aTsyReqHandle) |
|
1395 /** |
|
1396 * Attempts to cancel a pending GetScFileInfo request (unsuccessfully) |
|
1397 * |
|
1398 */ |
|
1399 { |
|
1400 LOGPHONE1("CSimPhoneSmartCardApp::GetScFileInfoCancel called"); |
|
1401 |
|
1402 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1403 return KErrNone; |
|
1404 } |
|
1405 |
|
1406 |
|
1407 TInt CSimPhoneSmartCardApp::ReadScFile(const TTsyReqHandle aTsyReqHandle, |
|
1408 const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aReadBuffer) |
|
1409 /** |
|
1410 * Reads a specified amount of data from a specified smart card file |
|
1411 * |
|
1412 * @param aReqHandle The TSY request handle for this request |
|
1413 * @param aFilePathOffsets Used to specify which file to read (path) and where in the file to read data from (offsets) |
|
1414 * @param aReadBuffer Used to return the read file data |
|
1415 */ |
|
1416 { |
|
1417 TSmartCardFile* scFile = NULL; |
|
1418 TInt ret = FindScFile((RMobilePhone::TScFilePath)aFilePathOffsets, scFile); |
|
1419 if(ret==KErrNone) |
|
1420 { |
|
1421 ret = scFile->ReadFile(aFilePathOffsets, aReadBuffer); |
|
1422 } |
|
1423 |
|
1424 iPhone->ReqCompleted(aTsyReqHandle,ret); |
|
1425 return KErrNone; |
|
1426 } |
|
1427 |
|
1428 |
|
1429 TInt CSimPhoneSmartCardApp::ReadScFileCancel(const TTsyReqHandle aTsyReqHandle) |
|
1430 /** |
|
1431 * Attempts to cancel a pending ReadScFileInfo request (unsuccessfully) |
|
1432 * |
|
1433 */ |
|
1434 { |
|
1435 LOGPHONE1("CSimPhoneSmartCardApp::ReadScFileInfoCancel called"); |
|
1436 |
|
1437 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1438 return KErrNone; |
|
1439 } |
|
1440 |
|
1441 |
|
1442 TInt CSimPhoneSmartCardApp::UpdateScFile(const TTsyReqHandle aTsyReqHandle, |
|
1443 const RMobilePhone::TScFilePathWithAccessOffsets& aFilePathOffsets, TDes8* aWriteBuffer) |
|
1444 /** |
|
1445 * Writes a specified amount of data to a specified smart card file |
|
1446 * |
|
1447 * @param aReqHandle The TSY request handle for this request |
|
1448 * @param aFilePathOffsets Used to specify which file to update (path) and where in the file to write data to (offsets) |
|
1449 * @param aReadBuffer Used to return the read file data |
|
1450 */ |
|
1451 { |
|
1452 TSmartCardFile* scFile = NULL; |
|
1453 TInt ret = FindScFile((RMobilePhone::TScFilePath)aFilePathOffsets, scFile); |
|
1454 if(ret==KErrNone) |
|
1455 { |
|
1456 ret = scFile->UpdateFile(aFilePathOffsets, aWriteBuffer); |
|
1457 } |
|
1458 |
|
1459 iPhone->ReqCompleted(aTsyReqHandle,ret); |
|
1460 return KErrNone; |
|
1461 } |
|
1462 |
|
1463 |
|
1464 TInt CSimPhoneSmartCardApp::UpdateScFileCancel(const TTsyReqHandle aTsyReqHandle) |
|
1465 /** |
|
1466 * Attempts to cancel a pending UpdateScFileInfo request (unsuccessfully) |
|
1467 * |
|
1468 */ |
|
1469 { |
|
1470 LOGPHONE1("CSimPhoneSmartCardApp::UpdateScFileInfoCancel called"); |
|
1471 |
|
1472 iPhone->ReqCompleted(aTsyReqHandle, KErrNone); |
|
1473 return KErrNone; |
|
1474 } |
|
1475 |
|
1476 |
|
1477 void CSimPhoneSmartCardApp::ParseSmartCardApplicationInfoL() |
|
1478 /** |
|
1479 * Parses all Smart Card Application related tags from the config file |
|
1480 * |
|
1481 */ |
|
1482 { |
|
1483 const CTestConfigItem* item=NULL; |
|
1484 TInt ret=KErrNone; |
|
1485 TInt index; |
|
1486 TPtrC8 activeUSimApp, aid, label, eap; |
|
1487 TInt type; |
|
1488 |
|
1489 TSmartCardApplication appInfo; |
|
1490 |
|
1491 TRAP_IGNORE(iTimer=CSimTimer::NewL(iPhone)); |
|
1492 |
|
1493 |
|
1494 LOGPHONE1("Starting to Parse MaxActiveSmartCardApp Info"); |
|
1495 iMaxActiveSmartCardApps = CfgFile()->ItemValue(KMaxActiveSmartCardApps ,KDefaultMaxActiveSmartCardApps); |
|
1496 |
|
1497 |
|
1498 LOGPHONE1("Starting to Parse ActiveUSIMApp Info"); |
|
1499 activeUSimApp.Set(CfgFile()->ItemValue(KActiveUSIMApp, KEmptyString)); |
|
1500 if(activeUSimApp.Length() == 0) |
|
1501 { |
|
1502 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: ACTIVE USIM APP NOT SPECIFIED!"); |
|
1503 } |
|
1504 |
|
1505 |
|
1506 TInt count = CfgFile()->ItemCount(KSmartCardAppInfo); |
|
1507 iSmartCardAppList=new(ELeave) CArrayFixFlat<TSmartCardApplication>(count+1); |
|
1508 |
|
1509 LOGPHONE1("Starting to Load and Parse Smart Card Application Info"); |
|
1510 for(index=0;index<count;index++) |
|
1511 { |
|
1512 item=CfgFile()->Item(KSmartCardAppInfo,index); |
|
1513 if(!item) |
|
1514 { |
|
1515 break; |
|
1516 } |
|
1517 |
|
1518 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,aid); |
|
1519 if(ret!=KErrNone) |
|
1520 { |
|
1521 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD APP INFO TAG"); |
|
1522 continue; |
|
1523 } |
|
1524 else |
|
1525 { |
|
1526 appInfo.iAID.Copy(aid); |
|
1527 } |
|
1528 |
|
1529 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,label); |
|
1530 if(ret!=KErrNone) |
|
1531 { |
|
1532 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD APP INFO TAG"); |
|
1533 continue; |
|
1534 } |
|
1535 else |
|
1536 { |
|
1537 appInfo.iLabel.Copy(label); |
|
1538 } |
|
1539 |
|
1540 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,type); |
|
1541 if(ret!=KErrNone) |
|
1542 { |
|
1543 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD APP INFO TAG"); |
|
1544 continue; |
|
1545 } |
|
1546 else |
|
1547 { |
|
1548 appInfo.iAppType = (TSmartCardAppType)type; |
|
1549 } |
|
1550 |
|
1551 if((appInfo.iAppType == EUSimApp) && (appInfo.iAID == activeUSimApp)) |
|
1552 { |
|
1553 //Make this the active USim App |
|
1554 iActiveUSimApp = appInfo.iAID; |
|
1555 appInfo.iAppStatus = EActive; |
|
1556 iNumActiveSmartCardApps++; |
|
1557 } |
|
1558 else |
|
1559 { |
|
1560 appInfo.iAppStatus = EInactive; |
|
1561 } |
|
1562 |
|
1563 ret = CTestConfig::GetElement(item->Value(), KStdDelimiter, 3, eap); |
|
1564 if (ret != KErrNone) |
|
1565 { |
|
1566 LOGPHONE2("CONFIGURATION FILE PARSING: BAD OR NO (OPTIONAL) EAP LIST @ SMARTCARD APP INFO TAG [%d]", index); |
|
1567 _LIT8(emptyEapList, ""); |
|
1568 eap.Set(emptyEapList); |
|
1569 } |
|
1570 // Append empty string if no info is given |
|
1571 appInfo.iEapList.Copy(eap); |
|
1572 |
|
1573 iSmartCardAppList->AppendL(appInfo); |
|
1574 iFoundScAppTags = ETrue; |
|
1575 }//end of FOR loop |
|
1576 |
|
1577 if(iActiveUSimApp.Length() == 0) |
|
1578 { |
|
1579 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: AID FOR ACTIVE USIM APP NOT FOUND!"); |
|
1580 } |
|
1581 |
|
1582 |
|
1583 count=CfgFile()->ItemCount(KSmartCardAppEvent); |
|
1584 iSmartCardAppEventList=new(ELeave) CArrayFixFlat<TSmartCardAppEvent>(count+1); |
|
1585 TSmartCardAppEvent appEvent; |
|
1586 TInt duration, action; |
|
1587 |
|
1588 LOGPHONE1("Starting to Load and Parse Smart Card Application Event Info"); |
|
1589 |
|
1590 for(index=0;index<count;index++) |
|
1591 { |
|
1592 item=CfgFile()->Item(KSmartCardAppEvent,index); |
|
1593 if(!item) |
|
1594 { |
|
1595 break; |
|
1596 } |
|
1597 |
|
1598 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0, duration); |
|
1599 if(ret!=KErrNone) |
|
1600 { |
|
1601 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMART CARD APP EVENT TAG"); |
|
1602 continue; |
|
1603 } |
|
1604 else |
|
1605 { |
|
1606 appEvent.iDuration=duration; |
|
1607 } |
|
1608 |
|
1609 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1, aid); |
|
1610 if(ret!=KErrNone) |
|
1611 { |
|
1612 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING; BAD SMART CARD APP EVENT TAG"); |
|
1613 continue; |
|
1614 } |
|
1615 else |
|
1616 { |
|
1617 appEvent.iAID.Copy(aid); |
|
1618 } |
|
1619 |
|
1620 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2, action); |
|
1621 if(ret!=KErrNone) |
|
1622 { |
|
1623 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING; BAD SMART CARD APP EVENT TAG"); |
|
1624 continue; |
|
1625 } |
|
1626 else |
|
1627 { |
|
1628 appEvent.iAction = (RMobilePhone::TSmartCardApplicationAction)action; |
|
1629 } |
|
1630 |
|
1631 iSmartCardAppEventList->AppendL(appEvent); |
|
1632 }//end FOR loop |
|
1633 } |
|
1634 |
|
1635 |
|
1636 void CSimPhoneSmartCardApp::ParseSmartCardFileInfoL() |
|
1637 /** |
|
1638 * Parses all Smart Card File related tags from the config file |
|
1639 * |
|
1640 */ |
|
1641 { |
|
1642 const CTestConfigItem* item=NULL; |
|
1643 TInt ret=KErrNone; |
|
1644 TPtrC8 fileId, filePath, fileData; |
|
1645 TInt aidIndex, fileType, fileLength, recordLength, numRecords, index; |
|
1646 TSmartCardFile* file = NULL; |
|
1647 |
|
1648 LOGPHONE1("Starting to Parse Smart Card File Info"); |
|
1649 TInt count = CfgFile()->ItemCount(KSmartCardFile); |
|
1650 iSmartCardFileList = new(ELeave) CArrayPtrFlat<TSmartCardFile>(count+1); |
|
1651 |
|
1652 for(index=0;index<count;index++) |
|
1653 { |
|
1654 item=CfgFile()->Item(KSmartCardFile,index); |
|
1655 if(!item) |
|
1656 { |
|
1657 break; |
|
1658 } |
|
1659 |
|
1660 //Get the file's type information |
|
1661 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,0,fileType); |
|
1662 if(ret!=KErrNone) |
|
1663 { |
|
1664 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); |
|
1665 continue; |
|
1666 } |
|
1667 else |
|
1668 { |
|
1669 switch ((RMobilePhone::TScFileType)fileType) |
|
1670 { |
|
1671 case RMobilePhone::ELinearFixed: |
|
1672 file = new(ELeave) TLinearSmartCardFile; |
|
1673 break; |
|
1674 case RMobilePhone::ECyclic: |
|
1675 file = new(ELeave) TCyclicSmartCardFile; |
|
1676 break; |
|
1677 case RMobilePhone::ETransparent: |
|
1678 file = new(ELeave) TTransparentSmartCardFile; |
|
1679 break; |
|
1680 default: |
|
1681 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING:"); |
|
1682 LOGPHONE1("ENCOUNTERED UNKNOWN SMART CARD FILE TYPE."); |
|
1683 continue; |
|
1684 } |
|
1685 file->iType = (RMobilePhone::TScFileType)fileType; |
|
1686 } |
|
1687 |
|
1688 //Get the FID of the file |
|
1689 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,1,fileId); |
|
1690 if(ret!=KErrNone) |
|
1691 { |
|
1692 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); |
|
1693 delete file; |
|
1694 continue; |
|
1695 } |
|
1696 //check that the FID is precisely 4 bytes long |
|
1697 else if(fileId.Length() != KMaxHexFIDLen) |
|
1698 { |
|
1699 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE FID"); |
|
1700 delete file; |
|
1701 continue; |
|
1702 } |
|
1703 else |
|
1704 { |
|
1705 TBuf8<KMaxBinFIDLen> fileIdBuffer; |
|
1706 TextToBin(fileId, fileIdBuffer); |
|
1707 file->iFileID = (RMobilePhone::TScFileID)((fileIdBuffer[0] <<8) + (fileIdBuffer[1])); |
|
1708 } |
|
1709 |
|
1710 //Get the Index of the AID of the application the file belongs to |
|
1711 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,2,aidIndex); |
|
1712 if(ret!=KErrNone) |
|
1713 { |
|
1714 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); |
|
1715 delete file; |
|
1716 continue; |
|
1717 } |
|
1718 else |
|
1719 { |
|
1720 file->iAIDIndex = aidIndex; |
|
1721 } |
|
1722 |
|
1723 //Get the file's path information |
|
1724 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,3,filePath); |
|
1725 if(ret!=KErrNone) |
|
1726 { |
|
1727 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); |
|
1728 delete file; |
|
1729 continue; |
|
1730 } |
|
1731 else |
|
1732 { |
|
1733 file->iPath = filePath; |
|
1734 } |
|
1735 |
|
1736 //Get the information about the total length of the file |
|
1737 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,4,fileLength); |
|
1738 if(ret!=KErrNone) |
|
1739 { |
|
1740 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); |
|
1741 delete file; |
|
1742 continue; |
|
1743 } |
|
1744 else |
|
1745 { |
|
1746 file->iTotalLength = fileLength; |
|
1747 } |
|
1748 |
|
1749 //Get information about the length of each record in the file |
|
1750 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,5,recordLength); |
|
1751 if(ret!=KErrNone) |
|
1752 { |
|
1753 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); |
|
1754 delete file; |
|
1755 continue; |
|
1756 } |
|
1757 else |
|
1758 { |
|
1759 file->iRecordLength = recordLength; |
|
1760 } |
|
1761 |
|
1762 //Get information about the number of records in the file |
|
1763 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,6,numRecords); |
|
1764 if(ret!=KErrNone) |
|
1765 { |
|
1766 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); |
|
1767 delete file; |
|
1768 continue; |
|
1769 } |
|
1770 else |
|
1771 { |
|
1772 file->iNumberRecords = numRecords; |
|
1773 } |
|
1774 |
|
1775 //If the file is Cyclic or Linear record based file... |
|
1776 //Check that record Length * number of records = Total length of file |
|
1777 if((fileType != RMobilePhone::ETransparent) && ((recordLength*numRecords) != fileLength)) |
|
1778 { |
|
1779 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING:..."); |
|
1780 LOGPHONE1("...Record Length * Number of Records != File Length"); |
|
1781 delete file; |
|
1782 continue; |
|
1783 } |
|
1784 |
|
1785 //Get file data |
|
1786 ret=CTestConfig::GetElement(item->Value(),KStdDelimiter,7,fileData); |
|
1787 if(ret!=KErrNone) |
|
1788 { |
|
1789 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE TAG"); |
|
1790 delete file; |
|
1791 continue; |
|
1792 } |
|
1793 else if((fileData.Length() % 2 ) != 0) |
|
1794 { |
|
1795 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING: BAD SMARTCARD FILE DATA"); |
|
1796 continue; |
|
1797 } |
|
1798 else |
|
1799 { |
|
1800 TBuf8<KMaxFileSize> fileDataBuffer; |
|
1801 TextToBin(fileData, fileDataBuffer); |
|
1802 if(fileDataBuffer.Length() != fileLength) |
|
1803 { |
|
1804 LOGPHONE1("ERROR IN CONFIGURATION FILE PARSING:INCONSISTANT DATA FILE LENGTH"); |
|
1805 delete file; |
|
1806 continue; |
|
1807 } |
|
1808 file->iFileData = fileDataBuffer; |
|
1809 } |
|
1810 |
|
1811 iSmartCardFileList->AppendL(file); |
|
1812 }//end FOR Loop |
|
1813 } |
|
1814 |
|
1815 void CSimPhoneSmartCardApp::MapUSimAppsL() |
|
1816 { |
|
1817 iUSimAppList=new(ELeave) RPointerArray<TSmartCardApplication>(iSmartCardAppList->Count() + 1); |
|
1818 TInt index; |
|
1819 TSmartCardApplication* SmartCardApp = NULL; |
|
1820 |
|
1821 //iterate through the list of smart card applications |
|
1822 for(index=0; index < iSmartCardAppList->Count(); index++) |
|
1823 { |
|
1824 SmartCardApp = &(iSmartCardAppList->At(index)); |
|
1825 |
|
1826 //if the smart card application is a USim App |
|
1827 if(SmartCardApp->iAppType == EUSimApp) |
|
1828 { |
|
1829 //add a pointer to it in the list of USim Apps |
|
1830 iUSimAppList->AppendL(SmartCardApp); |
|
1831 } |
|
1832 }//end FOR loop |
|
1833 |
|
1834 } |
|
1835 |
|
1836 |
|
1837 TInt CSimPhoneSmartCardApp::FindScFile(const RMobilePhone::TScFilePath& aFilePathInfo, TSmartCardFile*& aSmartCardFile) |
|
1838 /** |
|
1839 * Helper function |
|
1840 * |
|
1841 * Searches through the SimTSYs internal list of Smart Card files and returns a pointer |
|
1842 * to the requested file. If the file is under an application a check is done to ensure |
|
1843 * the application is active. |
|
1844 * |
|
1845 * @param aFilePathInfo Some information about the file that the client is looking for |
|
1846 * @param aSmartCardFile A pointer to the Smart Card File the client was looking for |
|
1847 */ |
|
1848 { |
|
1849 TInt index; |
|
1850 TInt aidIndex = KNoAID; |
|
1851 |
|
1852 //If the user has specified a file that is under an application |
|
1853 if(aFilePathInfo.iAID.Size() != 0) |
|
1854 { |
|
1855 //search the list of Smart Card Applications and get an index for the specifed AID |
|
1856 for(index=0; index < iSmartCardAppList->Count(); index++) |
|
1857 { |
|
1858 if(iSmartCardAppList->At(index).iAID == aFilePathInfo.iAID) |
|
1859 { |
|
1860 aidIndex = index; |
|
1861 break; |
|
1862 } |
|
1863 } |
|
1864 |
|
1865 //if the AID is not found |
|
1866 if(aidIndex == KNoAID) |
|
1867 { |
|
1868 return KErrNotFound; |
|
1869 } |
|
1870 else |
|
1871 { |
|
1872 //return an error if the specified application is inactive |
|
1873 if(iSmartCardAppList->At(aidIndex).iAppStatus == EInactive) |
|
1874 { |
|
1875 return KErrMMEtelScApplicationNotActive; |
|
1876 } |
|
1877 } |
|
1878 }//end if(aFilePathInfo.iAID.Size() != 0) |
|
1879 |
|
1880 //Find the specified file |
|
1881 TSmartCardFile* scFile=NULL; |
|
1882 |
|
1883 for(index = 0; index < iSmartCardFileList->Count(); index++) |
|
1884 { |
|
1885 scFile = iSmartCardFileList->At(index); |
|
1886 if((scFile->iAIDIndex == aidIndex) && (scFile->iPath == aFilePathInfo.iPath)) |
|
1887 { |
|
1888 aSmartCardFile = scFile; |
|
1889 return KErrNone; |
|
1890 } |
|
1891 } |
|
1892 |
|
1893 return KErrMMEtelScFileNotFound; |
|
1894 } |
|
1895 |
|
1896 |
|
1897 TInt CSimPhoneSmartCardApp::ActivateSmartCardApp(const RMobilePhone::TAID aAID, TBool& aActivatedUSimApp) |
|
1898 /** |
|
1899 * Performs the logic for Activating a Smart Card application |
|
1900 * |
|
1901 * @param aAID The AID of the application that should be activated |
|
1902 */ |
|
1903 { |
|
1904 TInt index; |
|
1905 TSmartCardApplication* smartCardApp = NULL; |
|
1906 |
|
1907 for(index=0; index < iSmartCardAppList->Count(); index++) |
|
1908 { |
|
1909 smartCardApp = &(iSmartCardAppList->At(index)); |
|
1910 if(smartCardApp->iAID == aAID) |
|
1911 { |
|
1912 //Check that 1)iMaxActiveSmartCardApps will not be exceeded by activating |
|
1913 //a new smart card application; 2)The application is not already active |
|
1914 if((iNumActiveSmartCardApps<iMaxActiveSmartCardApps) && |
|
1915 (smartCardApp->iAppStatus != CSimPhoneSmartCardApp::EActive)) |
|
1916 { |
|
1917 //if we are activating a USIM and another USIM app is already active, |
|
1918 //fail with KErrAlreadyExists |
|
1919 if((smartCardApp->iAppType == CSimPhoneSmartCardApp::EUSimApp) && |
|
1920 (iActiveUSimApp.Length() != 0)) |
|
1921 { |
|
1922 return KErrAlreadyExists; |
|
1923 } |
|
1924 else |
|
1925 { |
|
1926 smartCardApp->iAppStatus = CSimPhoneSmartCardApp::EActive; |
|
1927 iNumActiveSmartCardApps++; |
|
1928 |
|
1929 if(smartCardApp->iAppType == CSimPhoneSmartCardApp::EUSimApp) |
|
1930 { |
|
1931 iActiveUSimApp = smartCardApp->iAID; |
|
1932 aActivatedUSimApp = ETrue; |
|
1933 } |
|
1934 |
|
1935 return KErrNone; |
|
1936 } |
|
1937 } |
|
1938 |
|
1939 else |
|
1940 { |
|
1941 if(smartCardApp->iAppStatus == CSimPhoneSmartCardApp::EActive) |
|
1942 { |
|
1943 LOGPHONE1("REACTIVATING AN ALREADY ACTIVE APPLICATION"); |
|
1944 return KErrNone; |
|
1945 } |
|
1946 else |
|
1947 { |
|
1948 //iMaxActiveSmartCardApps will be exceeded |
|
1949 LOGPHONE1("WARNING: CANNOT PROCESS ACTIVATING APPLICATION"); |
|
1950 return KErrMMEtelScMaxApplicationsActive; |
|
1951 } |
|
1952 } |
|
1953 |
|
1954 } |
|
1955 }//end for loop |
|
1956 |
|
1957 LOGPHONE1("WARNING: AID NOT FOUND. CANNOT PROCESS EVENT"); |
|
1958 return KErrNotFound; |
|
1959 } |
|
1960 |
|
1961 |
|
1962 TInt CSimPhoneSmartCardApp::TerminateSmartCardApp(const RMobilePhone::TAID aAID, TBool& aTerminatedUSimApp) |
|
1963 /** |
|
1964 * Performs the logic for terminating a Smart Card application |
|
1965 * |
|
1966 * @param aAID The AID of the application that should be terminated |
|
1967 */ |
|
1968 { |
|
1969 TInt index; |
|
1970 TSmartCardApplication* smartCardApp = NULL; |
|
1971 for(index=0; index < iSmartCardAppList->Count(); index++) |
|
1972 { |
|
1973 smartCardApp = &(iSmartCardAppList->At(index)); |
|
1974 if(smartCardApp->iAID == aAID) |
|
1975 { |
|
1976 if(smartCardApp->iAppStatus == CSimPhoneSmartCardApp::EActive) |
|
1977 { |
|
1978 smartCardApp->iAppStatus = CSimPhoneSmartCardApp::EInactive; |
|
1979 iNumActiveSmartCardApps--; |
|
1980 |
|
1981 if(smartCardApp->iAppType == CSimPhoneSmartCardApp::EUSimApp) |
|
1982 { |
|
1983 iActiveUSimApp.Zero(); |
|
1984 aTerminatedUSimApp = ETrue; |
|
1985 } |
|
1986 |
|
1987 return KErrNone; |
|
1988 } |
|
1989 else |
|
1990 { |
|
1991 LOGPHONE1("ATTEMPTED TO TERMINATE NON-ACTIVE APPLICATION"); |
|
1992 return KErrMMEtelScApplicationNotActive; |
|
1993 } |
|
1994 } |
|
1995 |
|
1996 }//end for loop |
|
1997 LOGPHONE1("WARNING: AID NOT FOUND. CANNOT PROCESS EVENT"); |
|
1998 return KErrNotFound; |
|
1999 } |
|
2000 |
|
2001 |
|
2002 void CSimPhoneSmartCardApp::TextToBin(const TDesC8& aSrc, TDes8& aDst) |
|
2003 /** |
|
2004 * Helper function |
|
2005 * |
|
2006 * Converts a text descriptor containing Hex information to binary. |
|
2007 * |
|
2008 * @param aSrc The input buffer |
|
2009 * @param aDst The output buffer |
|
2010 */ |
|
2011 { |
|
2012 //LOG_ASSERT((aSrc.Length() % 2) == 0, "Not passed in an even-length string?"); |
|
2013 |
|
2014 aDst.SetLength(aSrc.Length() / 2); |
|
2015 |
|
2016 for (TInt i = 0; i < aSrc.Length(); i += 2) |
|
2017 { |
|
2018 TInt val = 0; |
|
2019 if ((aSrc[i] >= '0') && (aSrc[i] <= '9')) |
|
2020 { |
|
2021 val = ((aSrc[i] - '0') << 4); |
|
2022 } |
|
2023 else if ((aSrc[i] >= 'A') && (aSrc[i] <= 'F')) |
|
2024 { |
|
2025 val = ((aSrc[i] - 'A' + 10) << 4); |
|
2026 } |
|
2027 else |
|
2028 { |
|
2029 __DEBUGGER(); |
|
2030 } |
|
2031 |
|
2032 if ((aSrc[i+1] >= '0') && (aSrc[i+1] <= '9')) |
|
2033 { |
|
2034 val += (aSrc[i+1] - '0'); |
|
2035 } |
|
2036 else if ((aSrc[i+1] >= 'A') && (aSrc[i+1] <= 'F')) |
|
2037 { |
|
2038 val += (aSrc[i+1] - 'A' + 10); |
|
2039 } |
|
2040 else |
|
2041 { |
|
2042 __DEBUGGER(); |
|
2043 } |
|
2044 |
|
2045 aDst[i/2] = (TUint8) val; |
|
2046 } |
|
2047 } |