Home | History | Annotate | Download | only in uicc
      1 /*
      2  * Copyright (C) 2006 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.content.Context;
     20 import android.os.AsyncResult;
     21 import android.os.Handler;
     22 import android.os.Message;
     23 import android.os.Registrant;
     24 import android.os.RegistrantList;
     25 
     26 import android.telephony.Rlog;
     27 import android.telephony.TelephonyManager;
     28 import android.text.TextUtils;
     29 
     30 import com.android.internal.telephony.CommandsInterface;
     31 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
     32 
     33 import java.io.FileDescriptor;
     34 import java.io.PrintWriter;
     35 import java.io.UnsupportedEncodingException;
     36 import java.util.Arrays;
     37 import java.util.concurrent.atomic.AtomicBoolean;
     38 
     39 /**
     40  * {@hide}
     41  */
     42 public abstract class IccRecords extends Handler implements IccConstants {
     43     protected static final boolean DBG = true;
     44     protected static final boolean VDBG = false; // STOPSHIP if true
     45 
     46     // ***** Instance Variables
     47     protected AtomicBoolean mDestroyed = new AtomicBoolean(false);
     48     protected Context mContext;
     49     protected CommandsInterface mCi;
     50     protected IccFileHandler mFh;
     51     protected UiccCardApplication mParentApp;
     52     protected TelephonyManager mTelephonyManager;
     53 
     54     protected RegistrantList mRecordsLoadedRegistrants = new RegistrantList();
     55     protected RegistrantList mImsiReadyRegistrants = new RegistrantList();
     56     protected RegistrantList mRecordsEventsRegistrants = new RegistrantList();
     57     protected RegistrantList mNewSmsRegistrants = new RegistrantList();
     58     protected RegistrantList mNetworkSelectionModeAutomaticRegistrants = new RegistrantList();
     59 
     60     protected int mRecordsToLoad;  // number of pending load requests
     61 
     62     protected AdnRecordCache mAdnCache;
     63 
     64     // ***** Cached SIM State; cleared on channel close
     65 
     66     protected boolean mRecordsRequested = false; // true if we've made requests for the sim records
     67 
     68     protected String mIccId;
     69     protected String mMsisdn = null;  // My mobile number
     70     protected String mMsisdnTag = null;
     71     protected String mNewMsisdn = null;
     72     protected String mNewMsisdnTag = null;
     73     protected String mVoiceMailNum = null;
     74     protected String mVoiceMailTag = null;
     75     protected String mNewVoiceMailNum = null;
     76     protected String mNewVoiceMailTag = null;
     77     protected boolean mIsVoiceMailFixed = false;
     78     protected String mImsi;
     79     private IccIoResult auth_rsp;
     80 
     81     protected int mMncLength = UNINITIALIZED;
     82     protected int mMailboxIndex = 0; // 0 is no mailbox dailing number associated
     83 
     84     private String mSpn;
     85 
     86     protected String mGid1;
     87     protected String mGid2;
     88     protected String mPrefLang;
     89 
     90     private final Object mLock = new Object();
     91 
     92     // ***** Constants
     93 
     94     // Markers for mncLength
     95     protected static final int UNINITIALIZED = -1;
     96     protected static final int UNKNOWN = 0;
     97 
     98     // Bitmasks for SPN display rules.
     99     public static final int SPN_RULE_SHOW_SPN  = 0x01;
    100     public static final int SPN_RULE_SHOW_PLMN = 0x02;
    101 
    102     // ***** Event Constants
    103     protected static final int EVENT_SET_MSISDN_DONE = 30;
    104     public static final int EVENT_MWI = 0; // Message Waiting indication
    105     public static final int EVENT_CFI = 1; // Call Forwarding indication
    106     public static final int EVENT_SPN = 2; // Service Provider Name
    107 
    108     public static final int EVENT_GET_ICC_RECORD_DONE = 100;
    109     protected static final int EVENT_APP_READY = 1;
    110     private static final int EVENT_AKA_AUTHENTICATE_DONE          = 90;
    111 
    112     @Override
    113     public String toString() {
    114         return "mDestroyed=" + mDestroyed
    115                 + " mContext=" + mContext
    116                 + " mCi=" + mCi
    117                 + " mFh=" + mFh
    118                 + " mParentApp=" + mParentApp
    119                 + " recordsLoadedRegistrants=" + mRecordsLoadedRegistrants
    120                 + " mImsiReadyRegistrants=" + mImsiReadyRegistrants
    121                 + " mRecordsEventsRegistrants=" + mRecordsEventsRegistrants
    122                 + " mNewSmsRegistrants=" + mNewSmsRegistrants
    123                 + " mNetworkSelectionModeAutomaticRegistrants="
    124                         + mNetworkSelectionModeAutomaticRegistrants
    125                 + " recordsToLoad=" + mRecordsToLoad
    126                 + " adnCache=" + mAdnCache
    127                 + " recordsRequested=" + mRecordsRequested
    128                 + " iccid=" + mIccId
    129                 + " msisdnTag=" + mMsisdnTag
    130                 + " voiceMailNum=" + mVoiceMailNum
    131                 + " voiceMailTag=" + mVoiceMailTag
    132                 + " newVoiceMailNum=" + mNewVoiceMailNum
    133                 + " newVoiceMailTag=" + mNewVoiceMailTag
    134                 + " isVoiceMailFixed=" + mIsVoiceMailFixed
    135                 + (VDBG ? (" mImsi=" + mImsi) : "")
    136                 + " mncLength=" + mMncLength
    137                 + " mailboxIndex=" + mMailboxIndex
    138                 + " spn=" + mSpn;
    139 
    140     }
    141 
    142     /**
    143      * Generic ICC record loaded callback. Subclasses can call EF load methods on
    144      * {@link IccFileHandler} passing a Message for onLoaded with the what field set to
    145      * {@link #EVENT_GET_ICC_RECORD_DONE} and the obj field set to an instance
    146      * of this interface. The {@link #handleMessage} method in this class will print a
    147      * log message using {@link #getEfName()} and decrement {@link #mRecordsToLoad}.
    148      *
    149      * If the record load was successful, {@link #onRecordLoaded} will be called with the result.
    150      * Otherwise, an error log message will be output by {@link #handleMessage} and
    151      * {@link #onRecordLoaded} will not be called.
    152      */
    153     public interface IccRecordLoaded {
    154         String getEfName();
    155         void onRecordLoaded(AsyncResult ar);
    156     }
    157 
    158     // ***** Constructor
    159     public IccRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
    160         mContext = c;
    161         mCi = ci;
    162         mFh = app.getIccFileHandler();
    163         mParentApp = app;
    164         mTelephonyManager = (TelephonyManager) mContext.getSystemService(
    165                 Context.TELEPHONY_SERVICE);
    166     }
    167 
    168     /**
    169      * Call when the IccRecords object is no longer going to be used.
    170      */
    171     public void dispose() {
    172         mDestroyed.set(true);
    173         mParentApp = null;
    174         mFh = null;
    175         mCi = null;
    176         mContext = null;
    177     }
    178 
    179     public abstract void onReady();
    180 
    181     //***** Public Methods
    182     public AdnRecordCache getAdnCache() {
    183         return mAdnCache;
    184     }
    185 
    186     public String getIccId() {
    187         return mIccId;
    188     }
    189 
    190     public void registerForRecordsLoaded(Handler h, int what, Object obj) {
    191         if (mDestroyed.get()) {
    192             return;
    193         }
    194 
    195         Registrant r = new Registrant(h, what, obj);
    196         mRecordsLoadedRegistrants.add(r);
    197 
    198         if (mRecordsToLoad == 0 && mRecordsRequested == true) {
    199             r.notifyRegistrant(new AsyncResult(null, null, null));
    200         }
    201     }
    202     public void unregisterForRecordsLoaded(Handler h) {
    203         mRecordsLoadedRegistrants.remove(h);
    204     }
    205 
    206     public void registerForImsiReady(Handler h, int what, Object obj) {
    207         if (mDestroyed.get()) {
    208             return;
    209         }
    210 
    211         Registrant r = new Registrant(h, what, obj);
    212         mImsiReadyRegistrants.add(r);
    213 
    214         if (mImsi != null) {
    215             r.notifyRegistrant(new AsyncResult(null, null, null));
    216         }
    217     }
    218     public void unregisterForImsiReady(Handler h) {
    219         mImsiReadyRegistrants.remove(h);
    220     }
    221 
    222     public void registerForRecordsEvents(Handler h, int what, Object obj) {
    223         Registrant r = new Registrant (h, what, obj);
    224         mRecordsEventsRegistrants.add(r);
    225 
    226         /* Notify registrant of all the possible events. This is to make sure registrant is
    227         notified even if event occurred in the past. */
    228         r.notifyResult(EVENT_MWI);
    229         r.notifyResult(EVENT_CFI);
    230     }
    231     public void unregisterForRecordsEvents(Handler h) {
    232         mRecordsEventsRegistrants.remove(h);
    233     }
    234 
    235     public void registerForNewSms(Handler h, int what, Object obj) {
    236         Registrant r = new Registrant (h, what, obj);
    237         mNewSmsRegistrants.add(r);
    238     }
    239     public void unregisterForNewSms(Handler h) {
    240         mNewSmsRegistrants.remove(h);
    241     }
    242 
    243     public void registerForNetworkSelectionModeAutomatic(
    244             Handler h, int what, Object obj) {
    245         Registrant r = new Registrant (h, what, obj);
    246         mNetworkSelectionModeAutomaticRegistrants.add(r);
    247     }
    248     public void unregisterForNetworkSelectionModeAutomatic(Handler h) {
    249         mNetworkSelectionModeAutomaticRegistrants.remove(h);
    250     }
    251 
    252     /**
    253      * Get the International Mobile Subscriber ID (IMSI) on a SIM
    254      * for GSM, UMTS and like networks. Default is null if IMSI is
    255      * not supported or unavailable.
    256      *
    257      * @return null if SIM is not yet ready or unavailable
    258      */
    259     public String getIMSI() {
    260         return null;
    261     }
    262 
    263     /**
    264      * Imsi could be set by ServiceStateTrackers in case of cdma
    265      * @param imsi
    266      */
    267     public void setImsi(String imsi) {
    268         mImsi = imsi;
    269         mImsiReadyRegistrants.notifyRegistrants();
    270     }
    271 
    272     /**
    273      * Get the Network Access ID (NAI) on a CSIM for CDMA like networks. Default is null if IMSI is
    274      * not supported or unavailable.
    275      *
    276      * @return null if NAI is not yet ready or unavailable
    277      */
    278     public String getNAI() {
    279         return null;
    280     }
    281 
    282     public String getMsisdnNumber() {
    283         return mMsisdn;
    284     }
    285 
    286     /**
    287      * Get the Group Identifier Level 1 (GID1) on a SIM for GSM.
    288      * @return null if SIM is not yet ready
    289      */
    290     public String getGid1() {
    291         return null;
    292     }
    293 
    294     /**
    295      * Get the Group Identifier Level 2 (GID2) on a SIM.
    296      * @return null if SIM is not yet ready
    297      */
    298     public String getGid2() {
    299         return null;
    300     }
    301 
    302     /**
    303      * Set subscriber number to SIM record
    304      *
    305      * The subscriber number is stored in EF_MSISDN (TS 51.011)
    306      *
    307      * When the operation is complete, onComplete will be sent to its handler
    308      *
    309      * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
    310      * @param number dailing nubmer (up to 20 digits)
    311      *        if the number starts with '+', then set to international TOA
    312      * @param onComplete
    313      *        onComplete.obj will be an AsyncResult
    314      *        ((AsyncResult)onComplete.obj).exception == null on success
    315      *        ((AsyncResult)onComplete.obj).exception != null on fail
    316      */
    317     public void setMsisdnNumber(String alphaTag, String number,
    318             Message onComplete) {
    319 
    320         mMsisdn = number;
    321         mMsisdnTag = alphaTag;
    322 
    323         if (DBG) log("Set MSISDN: " + mMsisdnTag +" " + mMsisdn);
    324 
    325 
    326         AdnRecord adn = new AdnRecord(mMsisdnTag, mMsisdn);
    327 
    328         new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
    329                 obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
    330     }
    331 
    332     public String getMsisdnAlphaTag() {
    333         return mMsisdnTag;
    334     }
    335 
    336     public String getVoiceMailNumber() {
    337         return mVoiceMailNum;
    338     }
    339 
    340     /**
    341      * Return Service Provider Name stored in SIM (EF_SPN=0x6F46) or in RUIM (EF_RUIM_SPN=0x6F41).
    342      *
    343      * @return null if SIM is not yet ready or no RUIM entry
    344      */
    345     public String getServiceProviderName() {
    346         String providerName = mSpn;
    347 
    348         // Check for null pointers, mParentApp can be null after dispose,
    349         // which did occur after removing a SIM.
    350         UiccCardApplication parentApp = mParentApp;
    351         if (parentApp != null) {
    352             UiccCard card = parentApp.getUiccCard();
    353             if (card != null) {
    354                 String brandOverride = card.getOperatorBrandOverride();
    355                 if (brandOverride != null) {
    356                     log("getServiceProviderName: override");
    357                     providerName = brandOverride;
    358                 } else {
    359                     log("getServiceProviderName: no brandOverride");
    360                 }
    361             } else {
    362                 log("getServiceProviderName: card is null");
    363             }
    364         } else {
    365             log("getServiceProviderName: mParentApp is null");
    366         }
    367         log("getServiceProviderName: providerName=" + providerName);
    368         return providerName;
    369     }
    370 
    371     protected void setServiceProviderName(String spn) {
    372         mSpn = spn;
    373     }
    374 
    375     /**
    376      * Set voice mail number to SIM record
    377      *
    378      * The voice mail number can be stored either in EF_MBDN (TS 51.011) or
    379      * EF_MAILBOX_CPHS (CPHS 4.2)
    380      *
    381      * If EF_MBDN is available, store the voice mail number to EF_MBDN
    382      *
    383      * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
    384      *
    385      * So the voice mail number will be stored in both EFs if both are available
    386      *
    387      * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
    388      *
    389      * When the operation is complete, onComplete will be sent to its handler
    390      *
    391      * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
    392      * @param voiceNumber dailing nubmer (upto 20 digits)
    393      *        if the number is start with '+', then set to international TOA
    394      * @param onComplete
    395      *        onComplete.obj will be an AsyncResult
    396      *        ((AsyncResult)onComplete.obj).exception == null on success
    397      *        ((AsyncResult)onComplete.obj).exception != null on fail
    398      */
    399     public abstract void setVoiceMailNumber(String alphaTag, String voiceNumber,
    400             Message onComplete);
    401 
    402     public String getVoiceMailAlphaTag() {
    403         return mVoiceMailTag;
    404     }
    405 
    406     /**
    407      * Sets the SIM voice message waiting indicator records
    408      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
    409      * @param countWaiting The number of messages waiting, if known. Use
    410      *                     -1 to indicate that an unknown number of
    411      *                      messages are waiting
    412      */
    413     public abstract void setVoiceMessageWaiting(int line, int countWaiting);
    414 
    415     /**
    416      * Called by GsmPhone to update VoiceMail count
    417      */
    418     public abstract int getVoiceMessageCount();
    419 
    420     /**
    421      * Called by STK Service when REFRESH is received.
    422      * @param fileChanged indicates whether any files changed
    423      * @param fileList if non-null, a list of EF files that changed
    424      */
    425     public abstract void onRefresh(boolean fileChanged, int[] fileList);
    426 
    427     /**
    428      * Called by subclasses (SimRecords and RuimRecords) whenever
    429      * IccRefreshResponse.REFRESH_RESULT_INIT event received
    430      */
    431     protected void onIccRefreshInit() {
    432         mAdnCache.reset();
    433         UiccCardApplication parentApp = mParentApp;
    434         if ((parentApp != null) &&
    435                 (parentApp.getState() == AppState.APPSTATE_READY)) {
    436             // This will cause files to be reread
    437             sendMessage(obtainMessage(EVENT_APP_READY));
    438         }
    439     }
    440 
    441     public boolean getRecordsLoaded() {
    442         if (mRecordsToLoad == 0 && mRecordsRequested == true) {
    443             return true;
    444         } else {
    445             return false;
    446         }
    447     }
    448 
    449     //***** Overridden from Handler
    450     @Override
    451     public void handleMessage(Message msg) {
    452         AsyncResult ar;
    453 
    454         switch (msg.what) {
    455             case EVENT_GET_ICC_RECORD_DONE:
    456                 try {
    457                     ar = (AsyncResult) msg.obj;
    458                     IccRecordLoaded recordLoaded = (IccRecordLoaded) ar.userObj;
    459                     if (DBG) log(recordLoaded.getEfName() + " LOADED");
    460 
    461                     if (ar.exception != null) {
    462                         loge("Record Load Exception: " + ar.exception);
    463                     } else {
    464                         recordLoaded.onRecordLoaded(ar);
    465                     }
    466                 }catch (RuntimeException exc) {
    467                     // I don't want these exceptions to be fatal
    468                     loge("Exception parsing SIM record: " + exc);
    469                 } finally {
    470                     // Count up record load responses even if they are fails
    471                     onRecordLoaded();
    472                 }
    473                 break;
    474 
    475             case EVENT_AKA_AUTHENTICATE_DONE:
    476                 ar = (AsyncResult)msg.obj;
    477                 auth_rsp = null;
    478                 if (DBG) log("EVENT_AKA_AUTHENTICATE_DONE");
    479                 if (ar.exception != null) {
    480                     loge("Exception ICC SIM AKA: " + ar.exception);
    481                 } else {
    482                     try {
    483                         auth_rsp = (IccIoResult)ar.result;
    484                         if (DBG) log("ICC SIM AKA: auth_rsp = " + auth_rsp);
    485                     } catch (Exception e) {
    486                         loge("Failed to parse ICC SIM AKA contents: " + e);
    487                     }
    488                 }
    489                 synchronized (mLock) {
    490                     mLock.notifyAll();
    491                 }
    492 
    493                 break;
    494 
    495             default:
    496                 super.handleMessage(msg);
    497         }
    498     }
    499 
    500     /**
    501      * Returns the SIM language derived from the EF-LI and EF-PL sim records.
    502      */
    503     public String getSimLanguage() {
    504         return mPrefLang;
    505     }
    506 
    507     protected void setSimLanguage(byte[] efLi, byte[] efPl) {
    508         String[] locales = mContext.getAssets().getLocales();
    509         try {
    510             mPrefLang = findBestLanguage(efLi, locales);
    511         } catch (UnsupportedEncodingException uee) {
    512             log("Unable to parse EF-LI: " + Arrays.toString(efLi));
    513         }
    514 
    515         if (mPrefLang == null) {
    516             try {
    517                 mPrefLang = findBestLanguage(efPl, locales);
    518             } catch (UnsupportedEncodingException uee) {
    519                 log("Unable to parse EF-PL: " + Arrays.toString(efLi));
    520             }
    521         }
    522     }
    523 
    524     protected static String findBestLanguage(byte[] languages, String[] locales)
    525             throws UnsupportedEncodingException {
    526         if ((languages == null) || (locales == null)) return null;
    527 
    528         // Each 2-bytes consists of one language
    529         for (int i = 0; (i + 1) < languages.length; i += 2) {
    530             String lang = new String(languages, i, 2, "ISO-8859-1");
    531             for (int j = 0; j < locales.length; j++) {
    532                 if (locales[j] != null && locales[j].length() >= 2 &&
    533                         locales[j].substring(0, 2).equalsIgnoreCase(lang)) {
    534                     return lang;
    535                 }
    536             }
    537         }
    538 
    539         // no match found. return null
    540         return null;
    541     }
    542 
    543     protected abstract void onRecordLoaded();
    544 
    545     protected abstract void onAllRecordsLoaded();
    546 
    547     /**
    548      * Returns the SpnDisplayRule based on settings on the SIM and the
    549      * specified plmn (currently-registered PLMN).  See TS 22.101 Annex A
    550      * and TS 51.011 10.3.11 for details.
    551      *
    552      * If the SPN is not found on the SIM, the rule is always PLMN_ONLY.
    553      * Generally used for GSM/UMTS and the like SIMs.
    554      */
    555     public abstract int getDisplayRule(String plmn);
    556 
    557     /**
    558      * Return true if "Restriction of menu options for manual PLMN selection"
    559      * bit is set or EF_CSP data is unavailable, return false otherwise.
    560      * Generally used for GSM/UMTS and the like SIMs.
    561      */
    562     public boolean isCspPlmnEnabled() {
    563         return false;
    564     }
    565 
    566     /**
    567      * Returns the 5 or 6 digit MCC/MNC of the operator that
    568      * provided the SIM card. Returns null of SIM is not yet ready
    569      * or is not valid for the type of IccCard. Generally used for
    570      * GSM/UMTS and the like SIMS
    571      */
    572     public String getOperatorNumeric() {
    573         return null;
    574     }
    575 
    576     /**
    577      * Get the current Voice call forwarding flag for GSM/UMTS and the like SIMs
    578      *
    579      * @return true if enabled
    580      */
    581     public boolean getVoiceCallForwardingFlag() {
    582         return false;
    583     }
    584 
    585     /**
    586      * Set the voice call forwarding flag for GSM/UMTS and the like SIMs
    587      *
    588      * @param line to enable/disable
    589      * @param enable
    590      * @param number to which CFU is enabled
    591      */
    592     public void setVoiceCallForwardingFlag(int line, boolean enable, String number) {
    593     }
    594 
    595     /**
    596      * Indicates wether SIM is in provisioned state or not.
    597      * Overridden only if SIM can be dynamically provisioned via OTA.
    598      *
    599      * @return true if provisioned
    600      */
    601     public boolean isProvisioned () {
    602         return true;
    603     }
    604 
    605     /**
    606      * Write string to log file
    607      *
    608      * @param s is the string to write
    609      */
    610     protected abstract void log(String s);
    611 
    612     /**
    613      * Write error string to log file.
    614      *
    615      * @param s is the string to write
    616      */
    617     protected abstract void loge(String s);
    618 
    619     /**
    620      * Return an interface to retrieve the ISIM records for IMS, if available.
    621      * @return the interface to retrieve the ISIM records, or null if not supported
    622      */
    623     public IsimRecords getIsimRecords() {
    624         return null;
    625     }
    626 
    627     public UsimServiceTable getUsimServiceTable() {
    628         return null;
    629     }
    630 
    631     protected void setSystemProperty(String key, String val) {
    632         TelephonyManager.getDefault().setTelephonyProperty(mParentApp.getPhoneId(), key, val);
    633 
    634         log("[key, value]=" + key + ", " +  val);
    635     }
    636 
    637     /**
    638      * Returns the response of the SIM application on the UICC to authentication
    639      * challenge/response algorithm. The data string and challenge response are
    640      * Base64 encoded Strings.
    641      * Can support EAP-SIM, EAP-AKA with results encoded per 3GPP TS 31.102.
    642      *
    643      * @param authContext parameter P2 that specifies the authentication context per 3GPP TS 31.102 (Section 7.1.2)
    644      * @param data authentication challenge data
    645      * @return challenge response
    646      */
    647     public String getIccSimChallengeResponse(int authContext, String data) {
    648         if (DBG) log("getIccSimChallengeResponse:");
    649 
    650         try {
    651             synchronized(mLock) {
    652                 CommandsInterface ci = mCi;
    653                 UiccCardApplication parentApp = mParentApp;
    654                 if (ci != null && parentApp != null) {
    655                     ci.requestIccSimAuthentication(authContext, data,
    656                             parentApp.getAid(),
    657                             obtainMessage(EVENT_AKA_AUTHENTICATE_DONE));
    658                     try {
    659                         mLock.wait();
    660                     } catch (InterruptedException e) {
    661                         loge("getIccSimChallengeResponse: Fail, interrupted"
    662                                 + " while trying to request Icc Sim Auth");
    663                         return null;
    664                     }
    665                 } else {
    666                     loge( "getIccSimChallengeResponse: "
    667                             + "Fail, ci or parentApp is null");
    668                     return null;
    669                 }
    670             }
    671         } catch(Exception e) {
    672             loge( "getIccSimChallengeResponse: "
    673                     + "Fail while trying to request Icc Sim Auth");
    674             return null;
    675         }
    676 
    677         if (DBG) log("getIccSimChallengeResponse: return auth_rsp");
    678 
    679         return android.util.Base64.encodeToString(auth_rsp.payload, android.util.Base64.NO_WRAP);
    680     }
    681 
    682     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    683         pw.println("IccRecords: " + this);
    684         pw.println(" mDestroyed=" + mDestroyed);
    685         pw.println(" mCi=" + mCi);
    686         pw.println(" mFh=" + mFh);
    687         pw.println(" mParentApp=" + mParentApp);
    688         pw.println(" recordsLoadedRegistrants: size=" + mRecordsLoadedRegistrants.size());
    689         for (int i = 0; i < mRecordsLoadedRegistrants.size(); i++) {
    690             pw.println("  recordsLoadedRegistrants[" + i + "]="
    691                     + ((Registrant)mRecordsLoadedRegistrants.get(i)).getHandler());
    692         }
    693         pw.println(" mImsiReadyRegistrants: size=" + mImsiReadyRegistrants.size());
    694         for (int i = 0; i < mImsiReadyRegistrants.size(); i++) {
    695             pw.println("  mImsiReadyRegistrants[" + i + "]="
    696                     + ((Registrant)mImsiReadyRegistrants.get(i)).getHandler());
    697         }
    698         pw.println(" mRecordsEventsRegistrants: size=" + mRecordsEventsRegistrants.size());
    699         for (int i = 0; i < mRecordsEventsRegistrants.size(); i++) {
    700             pw.println("  mRecordsEventsRegistrants[" + i + "]="
    701                     + ((Registrant)mRecordsEventsRegistrants.get(i)).getHandler());
    702         }
    703         pw.println(" mNewSmsRegistrants: size=" + mNewSmsRegistrants.size());
    704         for (int i = 0; i < mNewSmsRegistrants.size(); i++) {
    705             pw.println("  mNewSmsRegistrants[" + i + "]="
    706                     + ((Registrant)mNewSmsRegistrants.get(i)).getHandler());
    707         }
    708         pw.println(" mNetworkSelectionModeAutomaticRegistrants: size="
    709                 + mNetworkSelectionModeAutomaticRegistrants.size());
    710         for (int i = 0; i < mNetworkSelectionModeAutomaticRegistrants.size(); i++) {
    711             pw.println("  mNetworkSelectionModeAutomaticRegistrants[" + i + "]="
    712                     + ((Registrant)mNetworkSelectionModeAutomaticRegistrants.get(i)).getHandler());
    713         }
    714         pw.println(" mRecordsRequested=" + mRecordsRequested);
    715         pw.println(" mRecordsToLoad=" + mRecordsToLoad);
    716         pw.println(" mRdnCache=" + mAdnCache);
    717         pw.println(" iccid=" + mIccId);
    718         if (TextUtils.isEmpty(mMsisdn)) {
    719             pw.println(" mMsisdn=null");
    720         } else {
    721             pw.println(" mMsisdn=" + (VDBG ? mMsisdn : "XXX"));
    722         }
    723         pw.println(" mMsisdnTag=" + mMsisdnTag);
    724         pw.println(" mVoiceMailNum=" + mVoiceMailNum);
    725         pw.println(" mVoiceMailTag=" + mVoiceMailTag);
    726         pw.println(" mNewVoiceMailNum=" + mNewVoiceMailNum);
    727         pw.println(" mNewVoiceMailTag=" + mNewVoiceMailTag);
    728         pw.println(" mIsVoiceMailFixed=" + mIsVoiceMailFixed);
    729         if (VDBG) pw.println(" mImsi=" + mImsi);
    730         pw.println(" mMncLength=" + mMncLength);
    731         pw.println(" mMailboxIndex=" + mMailboxIndex);
    732         pw.println(" mSpn=" + mSpn);
    733         pw.flush();
    734     }
    735 }
    736