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

IsimUiccRecords

public final class IsimUiccRecords extends IccRecords implements IsimRecords
{@hide}

Fields Summary
protected static final String
LOG_TAG
private static final boolean
DBG
private static final boolean
DUMP_RECORDS
public static final String
INTENT_ISIM_REFRESH
private static final int
EVENT_APP_READY
private static final int
EVENT_ISIM_REFRESH
private static final int
EVENT_AKA_AUTHENTICATE_DONE
private String
mIsimImpi
private String
mIsimDomain
private String[]
mIsimImpu
private String
mIsimIst
private String[]
mIsimPcscf
private String
auth_rsp
private final Object
mLock
private static final int
TAG_ISIM_VALUE
Constructors Summary
public IsimUiccRecords(UiccCardApplication app, android.content.Context c, com.android.internal.telephony.CommandsInterface ci)

        super(app, c, ci);

        mRecordsRequested = false;  // No load request is made till SIM ready

        // recordsToLoad is set to 0 because no requests are made yet
        mRecordsToLoad = 0;
        // Start off by setting empty state
        resetRecords();
        mCi.registerForIccRefresh(this, EVENT_ISIM_REFRESH, null);

        mParentApp.registerForReady(this, EVENT_APP_READY, null);
        if (DBG) log("IsimUiccRecords X ctor this=" + this);
    
Methods Summary
public voiddispose()

        log("Disposing " + this);
        //Unregister for all events
        mCi.unregisterForIccRefresh(this);
        mParentApp.unregisterForReady(this);
        resetRecords();
        super.dispose();
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        pw.println("IsimRecords: " + this);
        pw.println(" extends:");
        super.dump(fd, pw, args);
        pw.println(" mIsimImpi=" + mIsimImpi);
        pw.println(" mIsimDomain=" + mIsimDomain);
        pw.println(" mIsimImpu[]=" + Arrays.toString(mIsimImpu));
        pw.println(" mIsimIst" + mIsimIst);
        pw.println(" mIsimPcscf"+mIsimPcscf);
        pw.flush();
    
protected voidfetchIsimRecords()

        mRecordsRequested = true;

        mFh.loadEFTransparent(EF_IMPI, obtainMessage(
                IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpiLoaded()));
        mRecordsToLoad++;

        mFh.loadEFLinearFixedAll(EF_IMPU, obtainMessage(
                IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpuLoaded()));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_DOMAIN, obtainMessage(
                IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimDomainLoaded()));
        mRecordsToLoad++;
        mFh.loadEFTransparent(EF_IST, obtainMessage(
                    IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimIstLoaded()));
        mRecordsToLoad++;
        mFh.loadEFLinearFixedAll(EF_PCSCF, obtainMessage(
                    IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimPcscfLoaded()));
        mRecordsToLoad++;

        if (DBG) log("fetchIsimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested);
    
public intgetDisplayRule(java.lang.String plmn)

        // Not applicable to Isim
        return 0;
    
public java.lang.StringgetIsimChallengeResponse(java.lang.String nonce)
Returns the response of ISIM Authetification through RIL. Returns null if the Authentification hasn't been successed or isn't present iphonesubinfo.

return
the response of ISIM Authetification, or null if not available

        if (DBG) log("getIsimChallengeResponse-nonce:"+nonce);
        try {
            synchronized(mLock) {
                mCi.requestIsimAuthentication(nonce,obtainMessage(EVENT_AKA_AUTHENTICATE_DONE));
                try {
                    mLock.wait();
                } catch (InterruptedException e) {
                    log("interrupted while trying to request Isim Auth");
                }
            }
        } catch(Exception e) {
            if (DBG) log( "Fail while trying to request Isim Auth");
            return null;
        }

        if (DBG) log("getIsimChallengeResponse-auth_rsp"+auth_rsp);

        return auth_rsp;
    
public java.lang.StringgetIsimDomain()
Return the IMS home network domain name. Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM.

return
the IMS home network domain name, or null if not available

        return mIsimDomain;
    
public java.lang.StringgetIsimImpi()
Return the IMS private user identity (IMPI). Returns null if the IMPI hasn't been loaded or isn't present on the ISIM.

return
the IMS private user identity string, or null if not available

        return mIsimImpi;
    
public java.lang.String[]getIsimImpu()
Return an array of IMS public user identities (IMPU). Returns null if the IMPU hasn't been loaded or isn't present on the ISIM.

return
an array of IMS public user identity strings, or null if not available

        return (mIsimImpu != null) ? mIsimImpu.clone() : null;
    
public java.lang.StringgetIsimIst()
Returns the IMS Service Table (IST) that was loaded from the ISIM.

return
IMS Service Table or null if not present or not loaded

        return mIsimIst;
    
public java.lang.String[]getIsimPcscf()
Returns the IMS Proxy Call Session Control Function(PCSCF) that were loaded from the ISIM.

return
an array of PCSCF strings with one PCSCF per string, or null if not present or not loaded

        return (mIsimPcscf != null) ? mIsimPcscf.clone() : null;
    
public intgetVoiceMessageCount()

        return 0; // Not applicable to Isim
    
private voidhandleFileUpdate(int efid)

        switch (efid) {
            case EF_IMPI:
                mFh.loadEFTransparent(EF_IMPI, obtainMessage(
                            IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpiLoaded()));
                mRecordsToLoad++;
                break;

            case EF_IMPU:
                mFh.loadEFLinearFixedAll(EF_IMPU, obtainMessage(
                            IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpuLoaded()));
                mRecordsToLoad++;
            break;

            case EF_DOMAIN:
                mFh.loadEFTransparent(EF_DOMAIN, obtainMessage(
                            IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimDomainLoaded()));
                mRecordsToLoad++;
            break;

            case EF_IST:
                mFh.loadEFTransparent(EF_IST, obtainMessage(
                            IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimIstLoaded()));
                mRecordsToLoad++;
            break;

            case EF_PCSCF:
                mFh.loadEFLinearFixedAll(EF_PCSCF, obtainMessage(
                            IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimPcscfLoaded()));
                mRecordsToLoad++;

            default:
                fetchIsimRecords();
                break;
        }
    
private voidhandleIsimRefresh(IccRefreshResponse refreshResponse)

        if (refreshResponse == null) {
            if (DBG) log("handleIsimRefresh received without input");
            return;
        }

        if (refreshResponse.aid != null &&
                !refreshResponse.aid.equals(mParentApp.getAid())) {
            // This is for different app. Ignore.
            if (DBG) log("handleIsimRefresh received different app");
            return;
        }

        switch (refreshResponse.refreshResult) {
            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
                if (DBG) log("handleIsimRefresh with REFRESH_RESULT_FILE_UPDATE");
                handleFileUpdate(refreshResponse.efId);
                break;

            case IccRefreshResponse.REFRESH_RESULT_INIT:
                if (DBG) log("handleIsimRefresh with REFRESH_RESULT_INIT");
                // need to reload all files (that we care about)
                // onIccRefreshInit();
                fetchIsimRecords();
                break;

            case IccRefreshResponse.REFRESH_RESULT_RESET:
                // Refresh reset is handled by the UiccCard object.
                if (DBG) log("handleIsimRefresh with REFRESH_RESULT_RESET");
                break;

            default:
                // unknown refresh operation
                if (DBG) log("handleIsimRefresh with unknown operation");
                break;
        }
    
public voidhandleMessage(android.os.Message msg)

        AsyncResult ar;

        if (mDestroyed.get()) {
            Rlog.e(LOG_TAG, "Received message " + msg +
                    "[" + msg.what + "] while being destroyed. Ignoring.");
            return;
        }
        loge("IsimUiccRecords: handleMessage " + msg + "[" + msg.what + "] ");

        try {
            switch (msg.what) {
                case EVENT_APP_READY:
                    onReady();
                    break;

                case EVENT_ISIM_REFRESH:
                    ar = (AsyncResult)msg.obj;
                    loge("ISim REFRESH(EVENT_ISIM_REFRESH) with exception: " + ar.exception);
                    if (ar.exception == null) {
                        Intent intent = new Intent(INTENT_ISIM_REFRESH);
                        loge("send ISim REFRESH: " + INTENT_ISIM_REFRESH);
                        mContext.sendBroadcast(intent);
                        handleIsimRefresh((IccRefreshResponse)ar.result);
                    }
                    break;

                case EVENT_AKA_AUTHENTICATE_DONE:
                    ar = (AsyncResult)msg.obj;
                    log("EVENT_AKA_AUTHENTICATE_DONE");
                    if (ar.exception != null) {
                        log("Exception ISIM AKA: " + ar.exception);
                    } else {
                        try {
                            auth_rsp = (String)ar.result;
                            log("ISIM AKA: auth_rsp = " + auth_rsp);
                        } catch (Exception e) {
                            log("Failed to parse ISIM AKA contents: " + e);
                        }
                    }
                    synchronized (mLock) {
                        mLock.notifyAll();
                    }

                    break;

                default:
                    super.handleMessage(msg);   // IccRecords handles generic record load responses

            }
        } catch (RuntimeException exc) {
            // I don't want these exceptions to be fatal
            Rlog.w(LOG_TAG, "Exception parsing SIM record", exc);
        }
    
private static java.lang.StringisimTlvToString(byte[] record)
ISIM records for IMS are stored inside a Tag-Length-Value record as a UTF-8 string with tag value 0x80.

param
record the byte array containing the IMS data string
return
the decoded String value, or null if the record can't be decoded

        SimTlv tlv = new SimTlv(record, 0, record.length);
        do {
            if (tlv.getTag() == TAG_ISIM_VALUE) {
                return new String(tlv.getData(), Charset.forName("UTF-8"));
            }
        } while (tlv.nextObject());

        Rlog.e(LOG_TAG, "[ISIM] can't find TLV tag in ISIM record, returning null");
        return null;
    
protected voidlog(java.lang.String s)

        if (DBG) Rlog.d(LOG_TAG, "[ISIM] " + s);
    
protected voidloge(java.lang.String s)

        if (DBG) Rlog.e(LOG_TAG, "[ISIM] " + s);
    
protected voidonAllRecordsLoaded()

       if (DBG) log("record load complete");
        mRecordsLoadedRegistrants.notifyRegistrants(
                new AsyncResult(null, null, null));
    
public voidonReady()

        fetchIsimRecords();
    
protected voidonRecordLoaded()

        // One record loaded successfully or failed, In either case
        // we need to update the recordsToLoad count
        mRecordsToLoad -= 1;
        if (DBG) log("onRecordLoaded " + mRecordsToLoad + " requested: " + mRecordsRequested);

        if (mRecordsToLoad == 0 && mRecordsRequested == true) {
            onAllRecordsLoaded();
        } else if (mRecordsToLoad < 0) {
            loge("recordsToLoad <0, programmer error suspected");
            mRecordsToLoad = 0;
        }
    
public voidonRefresh(boolean fileChanged, int[] fileList)

        if (fileChanged) {
            // A future optimization would be to inspect fileList and
            // only reload those files that we care about.  For now,
            // just re-fetch all SIM records that we cache.
            fetchIsimRecords();
        }
    
protected voidresetRecords()

        // recordsRequested is set to false indicating that the SIM
        // read requests made so far are not valid. This is set to
        // true only when fresh set of read requests are made.
        mIsimImpi = null;
        mIsimDomain = null;
        mIsimImpu = null;
        mIsimIst = null;
        mIsimPcscf = null;
        auth_rsp = null;

        mRecordsRequested = false;
    
public voidsetVoiceMailNumber(java.lang.String alphaTag, java.lang.String voiceNumber, android.os.Message onComplete)

        // Not applicable to Isim
    
public voidsetVoiceMessageWaiting(int line, int countWaiting)

        // Not applicable to Isim
    
public java.lang.StringtoString()

     // From 3GPP TS 31.103

    
       
        return "IsimUiccRecords: " + super.toString()
                + " mIsimImpi=" + mIsimImpi
                + " mIsimDomain=" + mIsimDomain
                + " mIsimImpu=" + mIsimImpu
                + " mIsimIst=" + mIsimIst
                + " mIsimPcscf=" + mIsimPcscf;