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