• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony.uicc;
18 
19 import android.annotation.UnsupportedAppUsage;
20 import android.os.*;
21 
22 import com.android.internal.telephony.CommandsInterface;
23 
24 import java.util.ArrayList;
25 
26 /**
27  * {@hide}
28  */
29 public abstract class IccFileHandler extends Handler implements IccConstants {
30     private static final boolean VDBG = false;
31 
32     //from TS 11.11 9.1 or elsewhere
33     static protected final int COMMAND_READ_BINARY = 0xb0;
34     static protected final int COMMAND_UPDATE_BINARY = 0xd6;
35     static protected final int COMMAND_READ_RECORD = 0xb2;
36     static protected final int COMMAND_UPDATE_RECORD = 0xdc;
37     static protected final int COMMAND_SEEK = 0xa2;
38     static protected final int COMMAND_GET_RESPONSE = 0xc0;
39 
40     // from TS 11.11 9.2.5
41     static protected final int READ_RECORD_MODE_ABSOLUTE = 4;
42 
43     //***** types of files  TS 11.11 9.3
44     static protected final int EF_TYPE_TRANSPARENT = 0;
45     static protected final int EF_TYPE_LINEAR_FIXED = 1;
46     static protected final int EF_TYPE_CYCLIC = 3;
47 
48     //***** types of files  TS 11.11 9.3
49     static protected final int TYPE_RFU = 0;
50     static protected final int TYPE_MF  = 1;
51     static protected final int TYPE_DF  = 2;
52     static protected final int TYPE_EF  = 4;
53 
54     // size of GET_RESPONSE for EF's
55     static protected final int GET_RESPONSE_EF_SIZE_BYTES = 15;
56     static protected final int GET_RESPONSE_EF_IMG_SIZE_BYTES = 10;
57 
58     // Byte order received in response to COMMAND_GET_RESPONSE
59     // Refer TS 51.011 Section 9.2.1
60     static protected final int RESPONSE_DATA_RFU_1 = 0;
61     static protected final int RESPONSE_DATA_RFU_2 = 1;
62 
63     static protected final int RESPONSE_DATA_FILE_SIZE_1 = 2;
64     static protected final int RESPONSE_DATA_FILE_SIZE_2 = 3;
65 
66     static protected final int RESPONSE_DATA_FILE_ID_1 = 4;
67     static protected final int RESPONSE_DATA_FILE_ID_2 = 5;
68     static protected final int RESPONSE_DATA_FILE_TYPE = 6;
69     static protected final int RESPONSE_DATA_RFU_3 = 7;
70     static protected final int RESPONSE_DATA_ACCESS_CONDITION_1 = 8;
71     static protected final int RESPONSE_DATA_ACCESS_CONDITION_2 = 9;
72     static protected final int RESPONSE_DATA_ACCESS_CONDITION_3 = 10;
73     static protected final int RESPONSE_DATA_FILE_STATUS = 11;
74     static protected final int RESPONSE_DATA_LENGTH = 12;
75     static protected final int RESPONSE_DATA_STRUCTURE = 13;
76     static protected final int RESPONSE_DATA_RECORD_LENGTH = 14;
77 
78 
79     //***** Events
80 
81     /** Finished retrieving size of transparent EF; start loading. */
82     static protected final int EVENT_GET_BINARY_SIZE_DONE = 4;
83     /** Finished loading contents of transparent EF; post result. */
84     static protected final int EVENT_READ_BINARY_DONE = 5;
85     /** Finished retrieving size of records for linear-fixed EF; now load. */
86     static protected final int EVENT_GET_RECORD_SIZE_DONE = 6;
87     /** Finished loading single record from a linear-fixed EF; post result. */
88     static protected final int EVENT_READ_RECORD_DONE = 7;
89     /** Finished retrieving record size; post result. */
90     static protected final int EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE = 8;
91     /** Finished retrieving image instance record; post result. */
92     static protected final int EVENT_READ_IMG_DONE = 9;
93     /** Finished retrieving icon data; post result. */
94     static protected final int EVENT_READ_ICON_DONE = 10;
95     /** Finished retrieving size of record for EFimg now. */
96     static protected final int EVENT_GET_RECORD_SIZE_IMG_DONE = 11;
97 
98      // member variables
99     @UnsupportedAppUsage
100     protected final CommandsInterface mCi;
101     @UnsupportedAppUsage
102     protected final UiccCardApplication mParentApp;
103     @UnsupportedAppUsage
104     protected final String mAid;
105 
106     static class LoadLinearFixedContext {
107 
108         int mEfid;
109         @UnsupportedAppUsage
110         int mRecordNum, mRecordSize, mCountRecords;
111         boolean mLoadAll;
112         String mPath;
113 
114         Message mOnLoaded;
115 
116         @UnsupportedAppUsage
117         ArrayList<byte[]> results;
118 
119         @UnsupportedAppUsage
LoadLinearFixedContext(int efid, int recordNum, Message onLoaded)120         LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) {
121             mEfid = efid;
122             mRecordNum = recordNum;
123             mOnLoaded = onLoaded;
124             mLoadAll = false;
125             mPath = null;
126         }
127 
LoadLinearFixedContext(int efid, int recordNum, String path, Message onLoaded)128         LoadLinearFixedContext(int efid, int recordNum, String path, Message onLoaded) {
129             mEfid = efid;
130             mRecordNum = recordNum;
131             mOnLoaded = onLoaded;
132             mLoadAll = false;
133             mPath = path;
134         }
135 
LoadLinearFixedContext(int efid, String path, Message onLoaded)136         LoadLinearFixedContext(int efid, String path, Message onLoaded) {
137             mEfid = efid;
138             mRecordNum = 1;
139             mLoadAll = true;
140             mOnLoaded = onLoaded;
141             mPath = path;
142         }
143 
LoadLinearFixedContext(int efid, Message onLoaded)144         LoadLinearFixedContext(int efid, Message onLoaded) {
145             mEfid = efid;
146             mRecordNum = 1;
147             mLoadAll = true;
148             mOnLoaded = onLoaded;
149             mPath = null;
150         }
151     }
152 
153     /**
154      * Default constructor
155      */
IccFileHandler(UiccCardApplication app, String aid, CommandsInterface ci)156     protected IccFileHandler(UiccCardApplication app, String aid, CommandsInterface ci) {
157         mParentApp = app;
158         mAid = aid;
159         mCi = ci;
160     }
161 
dispose()162     public void dispose() {
163     }
164 
165     //***** Public Methods
166 
167     /**
168      * Load a record from a SIM Linear Fixed EF
169      *
170      * @param fileid EF id
171      * @param path Path of the EF on the card
172      * @param recordNum 1-based (not 0-based) record number
173      * @param onLoaded
174      *
175      * ((AsyncResult)(onLoaded.obj)).result is the byte[]
176      *
177      */
178     @UnsupportedAppUsage
loadEFLinearFixed(int fileid, String path, int recordNum, Message onLoaded)179     public void loadEFLinearFixed(int fileid, String path, int recordNum, Message onLoaded) {
180         String efPath = (path == null) ? getEFPath(fileid) : path;
181         Message response
182                 = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
183                         new LoadLinearFixedContext(fileid, recordNum, efPath, onLoaded));
184 
185         mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, efPath,
186                         0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
187     }
188 
189     /**
190      * Load a record from a SIM Linear Fixed EF
191      *
192      * @param fileid EF id
193      * @param recordNum 1-based (not 0-based) record number
194      * @param onLoaded
195      *
196      * ((AsyncResult)(onLoaded.obj)).result is the byte[]
197      *
198      */
199     @UnsupportedAppUsage
loadEFLinearFixed(int fileid, int recordNum, Message onLoaded)200     public void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) {
201         loadEFLinearFixed(fileid, getEFPath(fileid), recordNum, onLoaded);
202     }
203 
204     /**
205      * Load a image instance record from a SIM Linear Fixed EF-IMG
206      *
207      * @param recordNum 1-based (not 0-based) record number
208      * @param onLoaded
209      *
210      * ((AsyncResult)(onLoaded.obj)).result is the byte[]
211      *
212      */
loadEFImgLinearFixed(int recordNum, Message onLoaded)213     public void loadEFImgLinearFixed(int recordNum, Message onLoaded) {
214         Message response = obtainMessage(EVENT_GET_RECORD_SIZE_IMG_DONE,
215                 new LoadLinearFixedContext(IccConstants.EF_IMG, recordNum,
216                         onLoaded));
217 
218         mCi.iccIOForApp(COMMAND_GET_RESPONSE, IccConstants.EF_IMG,
219                     getEFPath(IccConstants.EF_IMG), recordNum,
220                     READ_RECORD_MODE_ABSOLUTE, GET_RESPONSE_EF_IMG_SIZE_BYTES,
221                     null, null, mAid, response);
222     }
223 
224     /**
225      * get record size for a linear fixed EF
226      *
227      * @param fileid EF id
228      * @param path Path of the EF on the card
229      * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
230      *        int[0] is the record length int[1] is the total length of the EF
231      *        file int[3] is the number of records in the EF file So int[0] *
232      *        int[3] = int[1]
233      */
234     @UnsupportedAppUsage
getEFLinearRecordSize(int fileid, String path, Message onLoaded)235     public void getEFLinearRecordSize(int fileid, String path, Message onLoaded) {
236         String efPath = (path == null) ? getEFPath(fileid) : path;
237         Message response
238                 = obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE,
239                         new LoadLinearFixedContext(fileid, efPath, onLoaded));
240         mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, efPath,
241                     0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
242     }
243 
244     /**
245      * get record size for a linear fixed EF
246      *
247      * @param fileid EF id
248      * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
249      *        int[0] is the record length int[1] is the total length of the EF
250      *        file int[3] is the number of records in the EF file So int[0] *
251      *        int[3] = int[1]
252      */
253     @UnsupportedAppUsage
getEFLinearRecordSize(int fileid, Message onLoaded)254     public void getEFLinearRecordSize(int fileid, Message onLoaded) {
255         getEFLinearRecordSize(fileid, getEFPath(fileid), onLoaded);
256     }
257 
258     /**
259      * Load all records from a SIM Linear Fixed EF
260      *
261      * @param fileid EF id
262      * @param path Path of the EF on the card
263      * @param onLoaded
264      *
265      * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
266      *
267      */
268     @UnsupportedAppUsage
loadEFLinearFixedAll(int fileid, String path, Message onLoaded)269     public void loadEFLinearFixedAll(int fileid, String path, Message onLoaded) {
270         String efPath = (path == null) ? getEFPath(fileid) : path;
271         Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
272                         new LoadLinearFixedContext(fileid, efPath, onLoaded));
273 
274         mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, efPath,
275                         0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
276     }
277 
278     /**
279      * Load all records from a SIM Linear Fixed EF
280      *
281      * @param fileid EF id
282      * @param onLoaded
283      *
284      * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
285      *
286      */
287     @UnsupportedAppUsage
loadEFLinearFixedAll(int fileid, Message onLoaded)288     public void loadEFLinearFixedAll(int fileid, Message onLoaded) {
289         loadEFLinearFixedAll(fileid, getEFPath(fileid), onLoaded);
290     }
291 
292     /**
293      * Load a SIM Transparent EF
294      *
295      * @param fileid EF id
296      * @param onLoaded
297      *
298      * ((AsyncResult)(onLoaded.obj)).result is the byte[]
299      *
300      */
301 
302     @UnsupportedAppUsage
loadEFTransparent(int fileid, Message onLoaded)303     public void loadEFTransparent(int fileid, Message onLoaded) {
304         Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
305                         fileid, 0, onLoaded);
306 
307         mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
308                         0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
309     }
310 
311     /**
312      * Load first @size bytes from SIM Transparent EF
313      *
314      * @param fileid EF id
315      * @param size
316      * @param onLoaded
317      *
318      * ((AsyncResult)(onLoaded.obj)).result is the byte[]
319      *
320      */
loadEFTransparent(int fileid, int size, Message onLoaded)321     public void loadEFTransparent(int fileid, int size, Message onLoaded) {
322         Message response = obtainMessage(EVENT_READ_BINARY_DONE,
323                         fileid, 0, onLoaded);
324 
325         mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
326                         0, 0, size, null, null, mAid, response);
327     }
328 
329     /**
330      * Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to
331      * retrive STK's icon data.
332      *
333      * @param fileid EF id
334      * @param onLoaded
335      *
336      * ((AsyncResult)(onLoaded.obj)).result is the byte[]
337      *
338      */
loadEFImgTransparent(int fileid, int highOffset, int lowOffset, int length, Message onLoaded)339     public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
340             int length, Message onLoaded) {
341         Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
342                 onLoaded);
343 
344         logd("IccFileHandler: loadEFImgTransparent fileid = " + fileid
345                 + " filePath = " + getEFPath(EF_IMG) + " highOffset = " + highOffset
346                 + " lowOffset = " + lowOffset + " length = " + length);
347 
348         /* Per TS 31.102, for displaying of Icon, under
349          * DF Telecom and DF Graphics , EF instance(s) (4FXX,transparent files)
350          * are present. The possible image file identifiers (EF instance) for
351          * EF img ( 4F20, linear fixed file) are : 4F01 ... 4F05.
352          * It should be MF_SIM + DF_TELECOM + DF_GRAPHICS, same path as EF IMG
353          */
354         mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(EF_IMG),
355                 highOffset, lowOffset, length, null, null, mAid, response);
356     }
357 
358     /**
359      * Update a record in a linear fixed EF
360      * @param fileid EF id
361      * @param path Path of the EF on the card
362      * @param recordNum 1-based (not 0-based) record number
363      * @param data must be exactly as long as the record in the EF
364      * @param pin2 for CHV2 operations, otherwist must be null
365      * @param onComplete onComplete.obj will be an AsyncResult
366      *                   onComplete.obj.userObj will be a IccIoResult on success
367      */
368     @UnsupportedAppUsage
updateEFLinearFixed(int fileid, String path, int recordNum, byte[] data, String pin2, Message onComplete)369     public void updateEFLinearFixed(int fileid, String path, int recordNum, byte[] data,
370             String pin2, Message onComplete) {
371         String efPath = (path == null) ? getEFPath(fileid) : path;
372         mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, efPath,
373                         recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
374                         IccUtils.bytesToHexString(data), pin2, mAid, onComplete);
375     }
376 
377     /**
378      * Update a record in a linear fixed EF
379      * @param fileid EF id
380      * @param recordNum 1-based (not 0-based) record number
381      * @param data must be exactly as long as the record in the EF
382      * @param pin2 for CHV2 operations, otherwist must be null
383      * @param onComplete onComplete.obj will be an AsyncResult
384      *                   onComplete.obj.userObj will be a IccIoResult on success
385      */
386     @UnsupportedAppUsage
updateEFLinearFixed(int fileid, int recordNum, byte[] data, String pin2, Message onComplete)387     public void updateEFLinearFixed(int fileid, int recordNum, byte[] data,
388             String pin2, Message onComplete) {
389         mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, getEFPath(fileid),
390                         recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
391                         IccUtils.bytesToHexString(data), pin2, mAid, onComplete);
392     }
393 
394     /**
395      * Update a transparent EF
396      * @param fileid EF id
397      * @param data must be exactly as long as the EF
398      */
399     @UnsupportedAppUsage
updateEFTransparent(int fileid, byte[] data, Message onComplete)400     public void updateEFTransparent(int fileid, byte[] data, Message onComplete) {
401         mCi.iccIOForApp(COMMAND_UPDATE_BINARY, fileid, getEFPath(fileid),
402                         0, 0, data.length,
403                         IccUtils.bytesToHexString(data), null, mAid, onComplete);
404     }
405 
406 
407     //***** Abstract Methods
408 
409 
410     //***** Private Methods
411 
sendResult(Message response, Object result, Throwable ex)412     private void sendResult(Message response, Object result, Throwable ex) {
413         if (response == null) {
414             return;
415         }
416 
417         AsyncResult.forMessage(response, result, ex);
418 
419         response.sendToTarget();
420     }
421 
processException(Message response, AsyncResult ar)422     private boolean processException(Message response, AsyncResult ar) {
423         IccException iccException;
424         boolean flag = false;
425         IccIoResult result = (IccIoResult) ar.result;
426         if (ar.exception != null) {
427             sendResult(response, null, ar.exception);
428             flag = true;
429         } else {
430             iccException = result.getException();
431             if (iccException != null) {
432                 sendResult(response, null, iccException);
433                 flag = true;
434             }
435         }
436         return flag;
437     }
438 
439     //***** Overridden from Handler
440 
441     @Override
handleMessage(Message msg)442     public void handleMessage(Message msg) {
443         AsyncResult ar;
444         IccIoResult result;
445         Message response = null;
446         String str;
447         LoadLinearFixedContext lc;
448 
449         byte data[];
450         int size;
451         int fileid;
452         int recordSize[];
453         String path = null;
454 
455         try {
456             switch (msg.what) {
457             case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE:
458                 ar = (AsyncResult)msg.obj;
459                 lc = (LoadLinearFixedContext) ar.userObj;
460                 result = (IccIoResult) ar.result;
461                 response = lc.mOnLoaded;
462 
463                 if (processException(response, (AsyncResult) msg.obj)) {
464                     break;
465                 }
466 
467                 data = result.payload;
468 
469                 if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] ||
470                     EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
471                     throw new IccFileTypeMismatch();
472                 }
473 
474                 recordSize = new int[3];
475                 recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
476                 recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
477                        + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
478                 recordSize[2] = recordSize[1] / recordSize[0];
479 
480                 sendResult(response, recordSize, null);
481                 break;
482 
483              case EVENT_GET_RECORD_SIZE_IMG_DONE:
484              case EVENT_GET_RECORD_SIZE_DONE:
485                 ar = (AsyncResult)msg.obj;
486                 lc = (LoadLinearFixedContext) ar.userObj;
487                 result = (IccIoResult) ar.result;
488                 response = lc.mOnLoaded;
489 
490                 if (processException(response, (AsyncResult) msg.obj)) {
491                     loge("exception caught from EVENT_GET_RECORD_SIZE");
492                     break;
493                 }
494 
495                 data = result.payload;
496                 path = lc.mPath;
497 
498                 if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
499                     throw new IccFileTypeMismatch();
500                 }
501 
502                 if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
503                     throw new IccFileTypeMismatch();
504                 }
505 
506                 lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
507 
508                 size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
509                        + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
510 
511                 lc.mCountRecords = size / lc.mRecordSize;
512 
513                  if (lc.mLoadAll) {
514                      lc.results = new ArrayList<byte[]>(lc.mCountRecords);
515                  }
516 
517                  if (path == null) {
518                      path = getEFPath(lc.mEfid);
519                  }
520                  mCi.iccIOForApp(COMMAND_READ_RECORD, lc.mEfid, path,
521                          lc.mRecordNum,
522                          READ_RECORD_MODE_ABSOLUTE,
523                          lc.mRecordSize, null, null, mAid,
524                          obtainMessage(EVENT_READ_RECORD_DONE, lc));
525                  break;
526             case EVENT_GET_BINARY_SIZE_DONE:
527                 ar = (AsyncResult)msg.obj;
528                 response = (Message) ar.userObj;
529                 result = (IccIoResult) ar.result;
530 
531                 if (processException(response, (AsyncResult) msg.obj)) {
532                     break;
533                 }
534 
535                 data = result.payload;
536 
537                 fileid = msg.arg1;
538 
539                 if (VDBG) {
540                     logd(String.format("Contents of the Select Response for command %x: ", fileid)
541                             + IccUtils.bytesToHexString(data));
542                 }
543 
544                 if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
545                     throw new IccFileTypeMismatch();
546                 }
547 
548                 if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) {
549                     throw new IccFileTypeMismatch();
550                 }
551 
552                 size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
553                        + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
554 
555                 mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
556                                 0, 0, size, null, null, mAid,
557                                 obtainMessage(EVENT_READ_BINARY_DONE,
558                                               fileid, 0, response));
559             break;
560 
561             case EVENT_READ_IMG_DONE:
562             case EVENT_READ_RECORD_DONE:
563 
564                 ar = (AsyncResult)msg.obj;
565                 lc = (LoadLinearFixedContext) ar.userObj;
566                 result = (IccIoResult) ar.result;
567                 response = lc.mOnLoaded;
568                 path = lc.mPath;
569 
570                 if (processException(response, (AsyncResult) msg.obj)) {
571                     break;
572                 }
573 
574                 if (!lc.mLoadAll) {
575                     sendResult(response, result.payload, null);
576                 } else {
577                     lc.results.add(result.payload);
578 
579                     lc.mRecordNum++;
580 
581                     if (lc.mRecordNum > lc.mCountRecords) {
582                         sendResult(response, lc.results, null);
583                     } else {
584                         if (path == null) {
585                             path = getEFPath(lc.mEfid);
586                         }
587 
588                         mCi.iccIOForApp(COMMAND_READ_RECORD, lc.mEfid, path,
589                                     lc.mRecordNum,
590                                     READ_RECORD_MODE_ABSOLUTE,
591                                     lc.mRecordSize, null, null, mAid,
592                                     obtainMessage(EVENT_READ_RECORD_DONE, lc));
593                     }
594                 }
595 
596             break;
597 
598             case EVENT_READ_BINARY_DONE:
599             case EVENT_READ_ICON_DONE:
600                 ar = (AsyncResult)msg.obj;
601                 response = (Message) ar.userObj;
602                 result = (IccIoResult) ar.result;
603 
604                 if (processException(response, (AsyncResult) msg.obj)) {
605                     break;
606                 }
607 
608                 sendResult(response, result.payload, null);
609             break;
610 
611         }} catch (Exception exc) {
612             if (response != null) {
613                 sendResult(response, null, exc);
614             } else {
615                 loge("uncaught exception" + exc);
616             }
617         }
618     }
619 
620     /**
621      * Returns the root path of the EF file.
622      * i.e returns MasterFile + DFfile as a string.
623      * Ex: For EF_ADN on a SIM, it will return "3F007F10"
624      * This function handles only EFids that are common to
625      * RUIM, SIM, USIM and other types of Icc cards.
626      *
627      * @param efid of path to retrieve
628      * @return root path of the file.
629      */
getCommonIccEFPath(int efid)630     protected String getCommonIccEFPath(int efid) {
631         switch(efid) {
632         case EF_ADN:
633         case EF_FDN:
634         case EF_MSISDN:
635         case EF_SDN:
636         case EF_EXT1:
637         case EF_EXT2:
638         case EF_EXT3:
639         case EF_PSI:
640             return MF_SIM + DF_TELECOM;
641 
642         case EF_ICCID:
643         case EF_PL:
644             return MF_SIM;
645         case EF_PBR:
646             // we only support global phonebook.
647             return MF_SIM + DF_TELECOM + DF_PHONEBOOK;
648         case EF_IMG:
649             return MF_SIM + DF_TELECOM + DF_GRAPHICS;
650         }
651         return null;
652     }
653 
654     @UnsupportedAppUsage
getEFPath(int efid)655     protected abstract String getEFPath(int efid);
logd(String s)656     protected abstract void logd(String s);
loge(String s)657     protected abstract void loge(String s);
658 
659 }
660