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