FileDocCategorySizeDatePackage
IccFileHandler.javaAPI DocAndroid 5.1 API19110Thu Mar 12 22:22:54 GMT 2015com.android.internal.telephony.uicc

IccFileHandler

public abstract class IccFileHandler extends Handler implements IccConstants
{@hide}

Fields Summary
protected static final int
COMMAND_READ_BINARY
protected static final int
COMMAND_UPDATE_BINARY
protected static final int
COMMAND_READ_RECORD
protected static final int
COMMAND_UPDATE_RECORD
protected static final int
COMMAND_SEEK
protected static final int
COMMAND_GET_RESPONSE
protected static final int
READ_RECORD_MODE_ABSOLUTE
protected static final int
EF_TYPE_TRANSPARENT
protected static final int
EF_TYPE_LINEAR_FIXED
protected static final int
EF_TYPE_CYCLIC
protected static final int
TYPE_RFU
protected static final int
TYPE_MF
protected static final int
TYPE_DF
protected static final int
TYPE_EF
protected static final int
GET_RESPONSE_EF_SIZE_BYTES
protected static final int
GET_RESPONSE_EF_IMG_SIZE_BYTES
protected static final int
RESPONSE_DATA_RFU_1
protected static final int
RESPONSE_DATA_RFU_2
protected static final int
RESPONSE_DATA_FILE_SIZE_1
protected static final int
RESPONSE_DATA_FILE_SIZE_2
protected static final int
RESPONSE_DATA_FILE_ID_1
protected static final int
RESPONSE_DATA_FILE_ID_2
protected static final int
RESPONSE_DATA_FILE_TYPE
protected static final int
RESPONSE_DATA_RFU_3
protected static final int
RESPONSE_DATA_ACCESS_CONDITION_1
protected static final int
RESPONSE_DATA_ACCESS_CONDITION_2
protected static final int
RESPONSE_DATA_ACCESS_CONDITION_3
protected static final int
RESPONSE_DATA_FILE_STATUS
protected static final int
RESPONSE_DATA_LENGTH
protected static final int
RESPONSE_DATA_STRUCTURE
protected static final int
RESPONSE_DATA_RECORD_LENGTH
protected static final int
EVENT_GET_BINARY_SIZE_DONE
Finished retrieving size of transparent EF; start loading.
protected static final int
EVENT_READ_BINARY_DONE
Finished loading contents of transparent EF; post result.
protected static final int
EVENT_GET_RECORD_SIZE_DONE
Finished retrieving size of records for linear-fixed EF; now load.
protected static final int
EVENT_READ_RECORD_DONE
Finished loading single record from a linear-fixed EF; post result.
protected static final int
EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE
Finished retrieving record size; post result.
protected static final int
EVENT_READ_IMG_DONE
Finished retrieving image instance record; post result.
protected static final int
EVENT_READ_ICON_DONE
Finished retrieving icon data; post result.
protected static final int
EVENT_GET_RECORD_SIZE_IMG_DONE
Finished retrieving size of record for EFimg now.
protected final com.android.internal.telephony.CommandsInterface
mCi
protected final UiccCardApplication
mParentApp
protected final String
mAid
Constructors Summary
protected IccFileHandler(UiccCardApplication app, String aid, com.android.internal.telephony.CommandsInterface ci)
Default constructor

        mParentApp = app;
        mAid = aid;
        mCi = ci;
    
Methods Summary
public voiddispose()

    
protected java.lang.StringgetCommonIccEFPath(int efid)
Returns the root path of the EF file. i.e returns MasterFile + DFfile as a string. Ex: For EF_ADN on a SIM, it will return "3F007F10" This function handles only EFids that are common to RUIM, SIM, USIM and other types of Icc cards.

param
efid of path to retrieve
return
root path of the file.

        switch(efid) {
        case EF_ADN:
        case EF_FDN:
        case EF_MSISDN:
        case EF_SDN:
        case EF_EXT1:
        case EF_EXT2:
        case EF_EXT3:
        case EF_PSI:
            return MF_SIM + DF_TELECOM;

        case EF_ICCID:
        case EF_PL:
            return MF_SIM;
        case EF_PBR:
            // we only support global phonebook.
            return MF_SIM + DF_TELECOM + DF_PHONEBOOK;
        case EF_IMG:
            return MF_SIM + DF_TELECOM + DF_GRAPHICS;
        }
        return null;
    
public voidgetEFLinearRecordSize(int fileid, Message onLoaded)
get record size for a linear fixed EF

param
fileid EF id
param
onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] int[0] is the record length int[1] is the total length of the EF file int[3] is the number of records in the EF file So int[0] * int[3] = int[1]

        Message response
                = obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE,
                        new LoadLinearFixedContext(fileid, onLoaded));
        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
                    0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
    
protected abstract java.lang.StringgetEFPath(int efid)

public voidhandleMessage(Message msg)

        AsyncResult ar;
        IccIoResult result;
        Message response = null;
        String str;
        LoadLinearFixedContext lc;

        byte data[];
        int size;
        int fileid;
        int recordSize[];

        try {
            switch (msg.what) {
            case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE:
                ar = (AsyncResult)msg.obj;
                lc = (LoadLinearFixedContext) ar.userObj;
                result = (IccIoResult) ar.result;
                response = lc.mOnLoaded;

                if (processException(response, (AsyncResult) msg.obj)) {
                    break;
                }

                data = result.payload;

                if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] ||
                    EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
                    throw new IccFileTypeMismatch();
                }

                recordSize = new int[3];
                recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
                recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
                recordSize[2] = recordSize[1] / recordSize[0];

                sendResult(response, recordSize, null);
                break;

             case EVENT_GET_RECORD_SIZE_IMG_DONE:
             case EVENT_GET_RECORD_SIZE_DONE:
                ar = (AsyncResult)msg.obj;
                lc = (LoadLinearFixedContext) ar.userObj;
                result = (IccIoResult) ar.result;
                response = lc.mOnLoaded;

                if (processException(response, (AsyncResult) msg.obj)) {
                    break;
                }

                data = result.payload;

                if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
                    throw new IccFileTypeMismatch();
                }

                if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
                    throw new IccFileTypeMismatch();
                }

                lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;

                size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);

                lc.mCountRecords = size / lc.mRecordSize;

                 if (lc.mLoadAll) {
                     lc.results = new ArrayList<byte[]>(lc.mCountRecords);
                 }

                 mCi.iccIOForApp(COMMAND_READ_RECORD, lc.mEfid, getEFPath(lc.mEfid),
                         lc.mRecordNum,
                         READ_RECORD_MODE_ABSOLUTE,
                         lc.mRecordSize, null, null, mAid,
                         obtainMessage(EVENT_READ_RECORD_DONE, lc));
                 break;
            case EVENT_GET_BINARY_SIZE_DONE:
                ar = (AsyncResult)msg.obj;
                response = (Message) ar.userObj;
                result = (IccIoResult) ar.result;

                if (processException(response, (AsyncResult) msg.obj)) {
                    break;
                }

                data = result.payload;

                fileid = msg.arg1;

                if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
                    throw new IccFileTypeMismatch();
                }

                if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) {
                    throw new IccFileTypeMismatch();
                }

                size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);

                mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
                                0, 0, size, null, null, mAid,
                                obtainMessage(EVENT_READ_BINARY_DONE,
                                              fileid, 0, response));
            break;

            case EVENT_READ_IMG_DONE:
            case EVENT_READ_RECORD_DONE:

                ar = (AsyncResult)msg.obj;
                lc = (LoadLinearFixedContext) ar.userObj;
                result = (IccIoResult) ar.result;
                response = lc.mOnLoaded;

                if (processException(response, (AsyncResult) msg.obj)) {
                    break;
                }

                if (!lc.mLoadAll) {
                    sendResult(response, result.payload, null);
                } else {
                    lc.results.add(result.payload);

                    lc.mRecordNum++;

                    if (lc.mRecordNum > lc.mCountRecords) {
                        sendResult(response, lc.results, null);
                    } else {
                        mCi.iccIOForApp(COMMAND_READ_RECORD, lc.mEfid, getEFPath(lc.mEfid),
                                    lc.mRecordNum,
                                    READ_RECORD_MODE_ABSOLUTE,
                                    lc.mRecordSize, null, null, mAid,
                                    obtainMessage(EVENT_READ_RECORD_DONE, lc));
                    }
                }

            break;

            case EVENT_READ_BINARY_DONE:
            case EVENT_READ_ICON_DONE:
                ar = (AsyncResult)msg.obj;
                response = (Message) ar.userObj;
                result = (IccIoResult) ar.result;

                if (processException(response, (AsyncResult) msg.obj)) {
                    break;
                }

                sendResult(response, result.payload, null);
            break;

        }} catch (Exception exc) {
            if (response != null) {
                sendResult(response, null, exc);
            } else {
                loge("uncaught exception" + exc);
            }
        }
    
public voidloadEFImgLinearFixed(int recordNum, Message onLoaded)
Load a image instance record from a SIM Linear Fixed EF-IMG

param
recordNum 1-based (not 0-based) record number
param
onLoaded ((AsyncResult)(onLoaded.obj)).result is the byte[]

        Message response = obtainMessage(EVENT_GET_RECORD_SIZE_IMG_DONE,
                new LoadLinearFixedContext(IccConstants.EF_IMG, recordNum,
                        onLoaded));

        mCi.iccIOForApp(COMMAND_GET_RESPONSE, IccConstants.EF_IMG,
                    getEFPath(IccConstants.EF_IMG), recordNum,
                    READ_RECORD_MODE_ABSOLUTE, GET_RESPONSE_EF_IMG_SIZE_BYTES,
                    null, null, mAid, response);
    
public voidloadEFImgTransparent(int fileid, int highOffset, int lowOffset, int length, Message onLoaded)
Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to retrive STK's icon data.

param
fileid EF id
param
onLoaded ((AsyncResult)(onLoaded.obj)).result is the byte[]

        Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
                onLoaded);

        logd("IccFileHandler: loadEFImgTransparent fileid = " + fileid
                + " filePath = " + getEFPath(EF_IMG) + " highOffset = " + highOffset
                + " lowOffset = " + lowOffset + " length = " + length);

        /* Per TS 31.102, for displaying of Icon, under
         * DF Telecom and DF Graphics , EF instance(s) (4FXX,transparent files)
         * are present. The possible image file identifiers (EF instance) for
         * EF img ( 4F20, linear fixed file) are : 4F01 ... 4F05.
         * It should be MF_SIM + DF_TELECOM + DF_GRAPHICS, same path as EF IMG
         */
        mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(EF_IMG),
                highOffset, lowOffset, length, null, null, mAid, response);
    
public voidloadEFLinearFixed(int fileid, int recordNum, Message onLoaded)
Load a record from a SIM Linear Fixed EF

param
fileid EF id
param
recordNum 1-based (not 0-based) record number
param
onLoaded ((AsyncResult)(onLoaded.obj)).result is the byte[]

        Message response
            = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
                        new LoadLinearFixedContext(fileid, recordNum, onLoaded));

        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
    
public voidloadEFLinearFixedAll(int fileid, Message onLoaded)
Load all records from a SIM Linear Fixed EF

param
fileid EF id
param
onLoaded ((AsyncResult)(onLoaded.obj)).result is an ArrayList

        Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
                        new LoadLinearFixedContext(fileid,onLoaded));

        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
    
public voidloadEFTransparent(int fileid, Message onLoaded)
Load a SIM Transparent EF

param
fileid EF id
param
onLoaded ((AsyncResult)(onLoaded.obj)).result is the byte[]

        Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
                        fileid, 0, onLoaded);

        mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
    
public voidloadEFTransparent(int fileid, int size, Message onLoaded)
Load first @size bytes from SIM Transparent EF

param
fileid EF id
param
size
param
onLoaded ((AsyncResult)(onLoaded.obj)).result is the byte[]

        Message response = obtainMessage(EVENT_READ_BINARY_DONE,
                        fileid, 0, onLoaded);

        mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
                        0, 0, size, null, null, mAid, response);
    
protected abstract voidlogd(java.lang.String s)

protected abstract voidloge(java.lang.String s)

private booleanprocessException(Message response, AsyncResult ar)

        IccException iccException;
        boolean flag = false;
        IccIoResult result = (IccIoResult) ar.result;
        if (ar.exception != null) {
            sendResult(response, null, ar.exception);
            flag = true;
        } else {
            iccException = result.getException();
            if (iccException != null) {
                sendResult(response, null, iccException);
                flag = true;
            }
        }
        return flag;
    
private voidsendResult(Message response, java.lang.Object result, java.lang.Throwable ex)

        if (response == null) {
            return;
        }

        AsyncResult.forMessage(response, result, ex);

        response.sendToTarget();
    
public voidupdateEFLinearFixed(int fileid, int recordNum, byte[] data, java.lang.String pin2, Message onComplete)
Update a record in a linear fixed EF

param
fileid EF id
param
recordNum 1-based (not 0-based) record number
param
data must be exactly as long as the record in the EF
param
pin2 for CHV2 operations, otherwist must be null
param
onComplete onComplete.obj will be an AsyncResult onComplete.obj.userObj will be a IccIoResult on success

        mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, getEFPath(fileid),
                        recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
                        IccUtils.bytesToHexString(data), pin2, mAid, onComplete);
    
public voidupdateEFTransparent(int fileid, byte[] data, Message onComplete)
Update a transparent EF

param
fileid EF id
param
data must be exactly as long as the EF

        mCi.iccIOForApp(COMMAND_UPDATE_BINARY, fileid, getEFPath(fileid),
                        0, 0, data.length,
                        IccUtils.bytesToHexString(data), null, mAid, onComplete);