FileDocCategorySizeDatePackage
SIMFileHandler.javaAPI DocAndroid 1.5 API17910Wed May 06 22:42:02 BST 2009com.android.internal.telephony.gsm

SIMFileHandler

public final class SIMFileHandler extends Handler
{@hide}

Fields Summary
static final String
LOG_TAG
private static final int
COMMAND_READ_BINARY
private static final int
COMMAND_UPDATE_BINARY
private static final int
COMMAND_READ_RECORD
private static final int
COMMAND_UPDATE_RECORD
private static final int
COMMAND_SEEK
private static final int
COMMAND_GET_RESPONSE
private static final int
READ_RECORD_MODE_ABSOLUTE
private static final int
EF_TYPE_TRANSPARENT
private static final int
EF_TYPE_LINEAR_FIXED
private static final int
EF_TYPE_CYCLIC
private static final int
TYPE_RFU
private static final int
TYPE_MF
private static final int
TYPE_DF
private static final int
TYPE_EF
private static final int
GET_RESPONSE_EF_SIZE_BYTES
private static final int
RESPONSE_DATA_RFU_1
private static final int
RESPONSE_DATA_RFU_2
private static final int
RESPONSE_DATA_FILE_SIZE_1
private static final int
RESPONSE_DATA_FILE_SIZE_2
private static final int
RESPONSE_DATA_FILE_ID_1
private static final int
RESPONSE_DATA_FILE_ID_2
private static final int
RESPONSE_DATA_FILE_TYPE
private static final int
RESPONSE_DATA_RFU_3
private static final int
RESPONSE_DATA_ACCESS_CONDITION_1
private static final int
RESPONSE_DATA_ACCESS_CONDITION_2
private static final int
RESPONSE_DATA_ACCESS_CONDITION_3
private static final int
RESPONSE_DATA_FILE_STATUS
private static final int
RESPONSE_DATA_LENGTH
private static final int
RESPONSE_DATA_STRUCTURE
private static final int
RESPONSE_DATA_RECORD_LENGTH
GSMPhone
phone
private static final int
EVENT_GET_BINARY_SIZE_DONE
Finished retrieving size of transparent EF; start loading.
private static final int
EVENT_READ_BINARY_DONE
Finished loading contents of transparent EF; post result.
private static final int
EVENT_GET_RECORD_SIZE_DONE
Finished retrieving size of records for linear-fixed EF; now load.
private static final int
EVENT_READ_RECORD_DONE
Finished loading single record from a linear-fixed EF; post result.
private static final int
EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE
Finished retrieving record size; post result.
private static final int
EVENT_READ_IMG_DONE
Finished retrieving image instance record; post result.
private static final int
EVENT_READ_ICON_DONE
Finished retrieving icon data; post result.
Constructors Summary
SIMFileHandler(GSMPhone phone)

        this.phone = phone;
    
Methods Summary
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));
        phone.mCM.simIO(COMMAND_GET_RESPONSE, fileid, null,
                    0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
    
public voidhandleMessage(Message msg)

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

        SimException simException;
        byte data[];
        int size;
        int fileid;
        int recordNum;
        int recordSize[];

        try {
            switch (msg.what) {
            case EVENT_READ_IMG_DONE:
                ar = (AsyncResult) msg.obj;
                lc = (LoadLinearFixedContext) ar.userObj;
                result = (SimIoResult) ar.result;
                response = lc.onLoaded;

                simException = result.getException();
                if (simException != null) {
                    sendResult(response, result.payload, ar.exception);
                }
                break;
            case EVENT_READ_ICON_DONE:
                ar = (AsyncResult) msg.obj;
                response = (Message) ar.userObj;
                result = (SimIoResult) ar.result;

                simException = result.getException();
                if (simException != null) {
                    sendResult(response, result.payload, ar.exception);
                }
                break;
            case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE:
                ar = (AsyncResult)msg.obj;
                lc = (LoadLinearFixedContext) ar.userObj;
                result = (SimIoResult) ar.result;
                response = lc.onLoaded;

                if (ar.exception != null) {
                    sendResult(response, null, ar.exception);
                    break;
                }

                simException = result.getException();
                if (simException != null) {
                    sendResult(response, null, simException);
                    break;
                }

                data = result.payload;

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

                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_DONE:
                ar = (AsyncResult)msg.obj;
                lc = (LoadLinearFixedContext) ar.userObj;
                result = (SimIoResult) ar.result;
                response = lc.onLoaded;

                if (ar.exception != null) {
                    sendResult(response, null, ar.exception);
                    break;
                }

                simException = result.getException();
                
                if (simException != null) {
                    sendResult(response, null, simException);
                    break;
                }

                data = result.payload;
                fileid = lc.efid;
                recordNum = lc.recordNum;

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

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

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

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

                lc.countRecords = size / lc.recordSize;

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

                 phone.mCM.simIO(COMMAND_READ_RECORD, lc.efid, null,
                         lc.recordNum,
                         READ_RECORD_MODE_ABSOLUTE,
                         lc.recordSize, null, null,
                         obtainMessage(EVENT_READ_RECORD_DONE, lc));
                 break;
            case EVENT_GET_BINARY_SIZE_DONE:
                ar = (AsyncResult)msg.obj;
                response = (Message) ar.userObj;
                result = (SimIoResult) ar.result;

                if (ar.exception != null) {
                    sendResult(response, null, ar.exception);
                    break;
                }

                simException = result.getException();
                
                if (simException != null) {
                    sendResult(response, null, simException);
                    break;
                }

                data = result.payload;

                fileid = msg.arg1;

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

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

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

                phone.mCM.simIO(COMMAND_READ_BINARY, fileid, null,
                                0, 0, size, null, null, 
                                obtainMessage(EVENT_READ_BINARY_DONE,
                                              fileid, 0, response));
            break;

            case EVENT_READ_RECORD_DONE:

                ar = (AsyncResult)msg.obj;
                lc = (LoadLinearFixedContext) ar.userObj;
                result = (SimIoResult) ar.result;
                response = lc.onLoaded;

                if (ar.exception != null) {
                    sendResult(response, null, ar.exception);
                    break;
                }

                simException = result.getException();
                
                if (simException != null) {
                    sendResult(response, null, simException);
                    break;
                }

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

                    lc.recordNum++;

                    if (lc.recordNum > lc.countRecords) {
                        sendResult(response, lc.results, null);
                    } else {                   
                        phone.mCM.simIO(COMMAND_READ_RECORD, lc.efid, null,
                                    lc.recordNum,
                                    READ_RECORD_MODE_ABSOLUTE,
                                    lc.recordSize, null, null,
                                    obtainMessage(EVENT_READ_RECORD_DONE, lc));
                    }
                }                

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

                if (ar.exception != null) {
                    sendResult(response, null, ar.exception);
                    break;
                }

                simException = result.getException();
                
                if (simException != null) {
                    sendResult(response, null, simException);
                    break;
                }

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

        }} catch (Exception exc) {
            if (response != null) {
                sendResult(response, null, exc);
            } else {
                Log.e(LOG_TAG, "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_READ_IMG_DONE,
                new LoadLinearFixedContext(SimConstants.EF_IMG, recordNum,
                        onLoaded));

        phone.mCM.simIO(COMMAND_GET_RESPONSE, SimConstants.EF_IMG, "img",
                recordNum, READ_RECORD_MODE_ABSOLUTE,
                ImageDescriptor.ID_LENGTH, null, null, 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);

        phone.mCM.simIO(COMMAND_READ_BINARY, fileid, "img", highOffset, lowOffset,
                length, null, null, response);
    
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));

        phone.mCM.simIO(COMMAND_GET_RESPONSE, fileid, null,
                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
    
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));

        phone.mCM.simIO(COMMAND_GET_RESPONSE, fileid, null,
                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
    
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);

        phone.mCM.simIO(COMMAND_GET_RESPONSE, fileid, null,
                        0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
    
private voidsendResult(Message response, java.lang.Object result, java.lang.Throwable ex)

        if (response == null) {
            return;
        }

        AsyncResult.forMessage(response, result, ex);

        response.sendToTarget();
    
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 SimIoResult on success

        phone.mCM.simIO(COMMAND_UPDATE_RECORD, fileid, null,
                        recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
                        SimUtils.bytesToHexString(data), pin2, onComplete);
    
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

        phone.mCM.simIO(COMMAND_UPDATE_BINARY, fileid, null,
                        0, 0, data.length,
                        SimUtils.bytesToHexString(data), null, onComplete);