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.annotation.IntDef; 20 import android.annotation.Nullable; 21 import android.content.Context; 22 import android.os.AsyncResult; 23 import android.os.Handler; 24 import android.os.Message; 25 import android.os.Registrant; 26 import android.os.RegistrantList; 27 import android.os.SystemClock; 28 import android.telephony.SubscriptionInfo; 29 import android.telephony.TelephonyManager; 30 import android.text.TextUtils; 31 import android.util.Pair; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.android.internal.telephony.CommandsInterface; 35 import com.android.internal.telephony.MccTable; 36 import com.android.internal.telephony.util.ArrayUtils; 37 import com.android.telephony.Rlog; 38 39 import java.io.FileDescriptor; 40 import java.io.PrintWriter; 41 import java.io.UnsupportedEncodingException; 42 import java.lang.annotation.Retention; 43 import java.lang.annotation.RetentionPolicy; 44 import java.util.Arrays; 45 import java.util.HashMap; 46 import java.util.Objects; 47 import java.util.concurrent.atomic.AtomicBoolean; 48 import java.util.concurrent.atomic.AtomicInteger; 49 50 /** 51 * {@hide} 52 */ 53 public abstract class IccRecords extends Handler implements IccConstants { 54 protected static final boolean DBG = true; 55 protected static final boolean VDBG = false; // STOPSHIP if true 56 57 // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length. 58 private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = { 59 "302370", "302720", "310260", 60 "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032", 61 "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040", 62 "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750", 63 "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800", 64 "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808", 65 "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816", 66 "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824", 67 "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832", 68 "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840", 69 "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848", 70 "405849", "405850", "405851", "405852", "405853", "405854", "405855", "405856", 71 "405857", "405858", "405859", "405860", "405861", "405862", "405863", "405864", 72 "405865", "405866", "405867", "405868", "405869", "405870", "405871", "405872", 73 "405873", "405874", "405875", "405876", "405877", "405878", "405879", "405880", 74 "405881", "405882", "405883", "405884", "405885", "405886", "405908", "405909", 75 "405910", "405911", "405912", "405913", "405914", "405915", "405916", "405917", 76 "405918", "405919", "405920", "405921", "405922", "405923", "405924", "405925", 77 "405926", "405927", "405928", "405929", "405930", "405931", "405932", "502142", 78 "502143", "502145", "502146", "502147", "502148" 79 }; 80 81 // ***** Instance Variables 82 protected AtomicBoolean mDestroyed = new AtomicBoolean(false); 83 protected AtomicBoolean mLoaded = new AtomicBoolean(false); 84 protected Context mContext; 85 protected CommandsInterface mCi; 86 protected IccFileHandler mFh; 87 protected UiccCardApplication mParentApp; 88 protected TelephonyManager mTelephonyManager; 89 90 protected RegistrantList mRecordsLoadedRegistrants = new RegistrantList(); 91 protected RegistrantList mLockedRecordsLoadedRegistrants = new RegistrantList(); 92 protected RegistrantList mNetworkLockedRecordsLoadedRegistrants = new RegistrantList(); 93 protected RegistrantList mImsiReadyRegistrants = new RegistrantList(); 94 protected RegistrantList mRecordsEventsRegistrants = new RegistrantList(); 95 protected RegistrantList mNewSmsRegistrants = new RegistrantList(); 96 protected RegistrantList mNetworkSelectionModeAutomaticRegistrants = new RegistrantList(); 97 protected RegistrantList mSpnUpdatedRegistrants = new RegistrantList(); 98 protected RegistrantList mRecordsOverrideRegistrants = new RegistrantList(); 99 100 protected int mRecordsToLoad; // number of pending load requests 101 102 protected AdnRecordCache mAdnCache; 103 104 // ***** Cached SIM State; cleared on channel close 105 106 // SIM is not locked 107 protected static final int LOCKED_RECORDS_REQ_REASON_NONE = 0; 108 // Records requested for PIN or PUK locked SIM 109 protected static final int LOCKED_RECORDS_REQ_REASON_LOCKED = 1; 110 // Records requested for network locked SIM 111 protected static final int LOCKED_RECORDS_REQ_REASON_NETWORK_LOCKED = 2; 112 113 protected boolean mRecordsRequested = false; // true if we've made requests for the sim records 114 protected int mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_NONE; 115 116 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) 117 public String mIccId; // Includes only decimals (no hex) 118 119 protected String mFullIccId; // Includes hex characters in ICCID 120 protected String mMsisdn = null; // My mobile number 121 protected String mMsisdnTag = null; 122 protected String mNewMsisdn = null; 123 protected String mNewMsisdnTag = null; 124 protected String mVoiceMailNum = null; 125 protected String mVoiceMailTag = null; 126 protected String mNewVoiceMailNum = null; 127 protected String mNewVoiceMailTag = null; 128 protected boolean mIsVoiceMailFixed = false; 129 protected String mImsi; // IMSI must be only valid numeric characters 0-9 without padding 'f's 130 131 protected int mMncLength = UNINITIALIZED; 132 protected int mMailboxIndex = 0; // 0 is no mailbox dailing number associated 133 134 protected int mSmsCountOnIcc = 0; 135 136 private String mSpn; 137 138 protected String mGid1; 139 protected String mGid2; 140 141 protected String mPnnHomeName; 142 143 protected String mPrefLang; 144 145 protected PlmnActRecord[] mHplmnActRecords; 146 protected PlmnActRecord[] mOplmnActRecords; 147 protected PlmnActRecord[] mPlmnActRecords; 148 149 // A list of PLMN in which the SPN shall be displayed. 150 // Reference: 3GPP TS 31.102 Section 4.2.66 151 protected String[] mSpdi; 152 153 154 // Carrier name display condition bitmask 155 // Reference: 3GPP TS 131.102 section 4.2.12 EF_SPN Display Condition 156 protected int mCarrierNameDisplayCondition; 157 158 protected String[] mEhplmns; 159 protected String[] mFplmns; 160 161 CarrierTestOverride mCarrierTestOverride; 162 163 //Arbitrary offset for the Handler 164 protected static final int HANDLER_ACTION_BASE = 0x12E500; 165 protected static final int HANDLER_ACTION_NONE = HANDLER_ACTION_BASE + 0; 166 protected static final int HANDLER_ACTION_SEND_RESPONSE = HANDLER_ACTION_BASE + 1; 167 protected static AtomicInteger sNextRequestId = new AtomicInteger(1); 168 protected final HashMap<Integer, Pair<Message, Object>> mPendingTransactions = new HashMap<>(); 169 // ***** Constants 170 171 // Markers for mncLength 172 protected static final int UNINITIALIZED = -1; 173 protected static final int UNKNOWN = 0; 174 175 // Bitmask for carrier name display condition. 176 @Retention(RetentionPolicy.SOURCE) 177 @IntDef(prefix = {"CARRIER_NAME_DISPLAY_CONDITION_BITMASK_"}, 178 value = {CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN, 179 CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN}, 180 flag = true) 181 public @interface CarrierNameDisplayConditionBitmask {} 182 public static final int CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN = 1; 183 public static final int CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN = 2; 184 185 186 // See {@link CarrierConfigManager#KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT}. 187 public static final int INVALID_CARRIER_NAME_DISPLAY_CONDITION_BITMASK = -1; 188 189 // Display SPN only and only if registered to Home PLMNs. 190 // Display PLMN only and only if registered to Non-Home PLMNs. 191 public static final int DEFAULT_CARRIER_NAME_DISPLAY_CONDITION = 0; 192 193 // ***** Event Constants 194 public static final int EVENT_MWI = 0; // Message Waiting indication 195 public static final int EVENT_CFI = 1; // Call Forwarding indication 196 public static final int EVENT_SPN = 2; // Service Provider Name 197 198 public static final int EVENT_GET_ICC_RECORD_DONE = 100; 199 public static final int EVENT_REFRESH = 31; // ICC refresh occurred 200 private static final int EVENT_AKA_AUTHENTICATE_DONE = 90; 201 protected static final int EVENT_GET_SMS_RECORD_SIZE_DONE = 28; 202 203 protected static final int SYSTEM_EVENT_BASE = 0x100; 204 protected static final int EVENT_APP_READY = 1 + SYSTEM_EVENT_BASE; 205 protected static final int EVENT_APP_LOCKED = 2 + SYSTEM_EVENT_BASE; 206 protected static final int EVENT_APP_NETWORK_LOCKED = 3 + SYSTEM_EVENT_BASE; 207 protected static final int EVENT_APP_DETECTED = 4 + SYSTEM_EVENT_BASE; 208 209 public static final int CALL_FORWARDING_STATUS_DISABLED = 0; 210 public static final int CALL_FORWARDING_STATUS_ENABLED = 1; 211 public static final int CALL_FORWARDING_STATUS_UNKNOWN = -1; 212 213 public static final int DEFAULT_VOICE_MESSAGE_COUNT = -2; 214 public static final int UNKNOWN_VOICE_MESSAGE_COUNT = -1; 215 216 // Maximum time in millisecond to wait for a IccSim Challenge before assuming it will not 217 // arrive and returning null to the callers. 218 private static final long ICC_SIM_CHALLENGE_TIMEOUT_MILLIS = 2500; 219 220 /** 221 * There are two purposes for this class. First, each instance of AuthAsyncResponse acts as a 222 * lock to for calling thead to wait in getIccSimChallengeResponse(). Second, pass the IMS 223 * authentication response to the getIccSimChallengeResponse(). 224 */ 225 private static class AuthAsyncResponse { 226 public IccIoResult authRsp; 227 public Throwable exception; 228 } 229 230 @Override toString()231 public String toString() { 232 String iccIdToPrint = SubscriptionInfo.givePrintableIccid(mFullIccId); 233 return "mDestroyed=" + mDestroyed 234 + " mContext=" + mContext 235 + " mCi=" + mCi 236 + " mFh=" + mFh 237 + " mParentApp=" + mParentApp 238 + " recordsToLoad=" + mRecordsToLoad 239 + " adnCache=" + mAdnCache 240 + " recordsRequested=" + mRecordsRequested 241 + " lockedRecordsReqReason=" + mLockedRecordsReqReason 242 + " iccid=" + iccIdToPrint 243 + (mCarrierTestOverride.isInTestMode() ? "mFakeIccid=" 244 + mCarrierTestOverride.getFakeIccid() : "") 245 + " msisdnTag=" + mMsisdnTag 246 + " voiceMailNum=" + Rlog.pii(VDBG, mVoiceMailNum) 247 + " voiceMailTag=" + mVoiceMailTag 248 + " voiceMailNum=" + Rlog.pii(VDBG, mNewVoiceMailNum) 249 + " newVoiceMailTag=" + mNewVoiceMailTag 250 + " isVoiceMailFixed=" + mIsVoiceMailFixed 251 + " mImsi=" + ((mImsi != null) ? 252 mImsi.substring(0, 6) + Rlog.pii(VDBG, mImsi.substring(6)) : "null") 253 + (mCarrierTestOverride.isInTestMode() ? " mFakeImsi=" 254 + mCarrierTestOverride.getFakeIMSI() : "") 255 + " mncLength=" + mMncLength 256 + " mailboxIndex=" + mMailboxIndex 257 + " spn=" + mSpn 258 + (mCarrierTestOverride.isInTestMode() ? " mFakeSpn=" 259 + mCarrierTestOverride.getFakeSpn() : ""); 260 } 261 262 /** 263 * Generic ICC record loaded callback. Subclasses can call EF load methods on 264 * {@link IccFileHandler} passing a Message for onLoaded with the what field set to 265 * {@link #EVENT_GET_ICC_RECORD_DONE} and the obj field set to an instance 266 * of this interface. The {@link #handleMessage} method in this class will print a 267 * log message using {@link #getEfName()} and decrement {@link #mRecordsToLoad}. 268 * 269 * If the record load was successful, {@link #onRecordLoaded} will be called with the result. 270 * Otherwise, an error log message will be output by {@link #handleMessage} and 271 * {@link #onRecordLoaded} will not be called. 272 */ 273 public interface IccRecordLoaded { getEfName()274 String getEfName(); onRecordLoaded(AsyncResult ar)275 void onRecordLoaded(AsyncResult ar); 276 } 277 278 // ***** Constructor IccRecords(UiccCardApplication app, Context c, CommandsInterface ci)279 public IccRecords(UiccCardApplication app, Context c, CommandsInterface ci) { 280 mContext = c; 281 mCi = ci; 282 mFh = app.getIccFileHandler(); 283 mParentApp = app; 284 mTelephonyManager = (TelephonyManager) mContext.getSystemService( 285 Context.TELEPHONY_SERVICE); 286 287 mCarrierTestOverride = new CarrierTestOverride(); 288 mCi.registerForIccRefresh(this, EVENT_REFRESH, null); 289 290 mParentApp.registerForReady(this, EVENT_APP_READY, null); 291 mParentApp.registerForDetected(this, EVENT_APP_DETECTED, null); 292 mParentApp.registerForLocked(this, EVENT_APP_LOCKED, null); 293 mParentApp.registerForNetworkLocked(this, EVENT_APP_NETWORK_LOCKED, null); 294 } 295 296 // Override IccRecords for testing setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1, String gid2, String pnn, String spn)297 public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1, 298 String gid2, String pnn, String spn) { 299 mCarrierTestOverride.override(mccmnc, imsi, iccid, gid1, gid2, pnn, spn); 300 mTelephonyManager.setSimOperatorNameForPhone(mParentApp.getPhoneId(), spn); 301 mTelephonyManager.setSimOperatorNumericForPhone(mParentApp.getPhoneId(), mccmnc); 302 mRecordsOverrideRegistrants.notifyRegistrants(); 303 } 304 305 /** 306 * Call when the IccRecords object is no longer going to be used. 307 */ dispose()308 public void dispose() { 309 mDestroyed.set(true); 310 311 mCi.unregisterForIccRefresh(this); 312 mParentApp.unregisterForReady(this); 313 mParentApp.unregisterForDetected(this); 314 mParentApp.unregisterForLocked(this); 315 mParentApp.unregisterForNetworkLocked(this); 316 317 mParentApp = null; 318 mFh = null; 319 mCi = null; 320 mContext = null; 321 if (mAdnCache != null) { 322 mAdnCache.reset(); 323 } 324 mLoaded.set(false); 325 } 326 onReady()327 protected abstract void onReady(); 328 onDetected()329 protected void onDetected() { 330 mRecordsRequested = false; 331 mLoaded.set(false); 332 } 333 onLocked()334 protected void onLocked() { 335 // The LOADED state should not be indicated while the lock is effective. 336 mRecordsRequested = false; 337 mLoaded.set(false); 338 } 339 340 //***** Public Methods getAdnCache()341 public AdnRecordCache getAdnCache() { 342 return mAdnCache; 343 } 344 345 /** 346 * Adds a message to the pending requests list by generating a unique (integer) 347 * hash key and returning it. The message should never be null. 348 * 349 * @param msg Message of the transaction to be stored 350 * @return the unique (integer) hash key to retrieve the pending transaction 351 */ storePendingTransaction(Message msg)352 public int storePendingTransaction(Message msg) { 353 return storePendingTransaction(msg, null); 354 } 355 356 /** 357 * Adds a message and obj pair to the pending requests list by generating a unique (integer) 358 * hash key and returning it. The message should never be null. 359 * 360 * @param msg Message of the transaction to be stored 361 * @param obj Object of the transaction to be stored 362 * @return the unique (integer) hash key to retrieve the pending transaction 363 */ storePendingTransaction(Message msg, Object obj)364 public int storePendingTransaction(Message msg, Object obj) { 365 int key = sNextRequestId.getAndIncrement(); 366 Pair<Message, Object> pair = new Pair<Message, Object>(msg, obj); 367 synchronized (mPendingTransactions) { 368 mPendingTransactions.put(key, pair); 369 } 370 return key; 371 } 372 373 /** 374 * Returns the pending transaction and free it from memory, if any or null 375 * 376 * @param key key of the entry to retrieve 377 * @return The pending transaction. 378 */ retrievePendingTransaction(Integer key)379 public Pair<Message, Object> retrievePendingTransaction(Integer key) { 380 synchronized (mPendingTransactions) { 381 return mPendingTransactions.remove(key); 382 } 383 } 384 385 /** 386 * Returns the ICC ID stripped at the first hex character. Some SIMs have ICC IDs 387 * containing hex digits; {@link #getFullIccId()} should be used to get the full ID including 388 * hex digits. 389 * @return ICC ID without hex digits 390 */ getIccId()391 public String getIccId() { 392 if (mCarrierTestOverride.isInTestMode()) { 393 String fakeIccId = mCarrierTestOverride.getFakeIccid(); 394 if (fakeIccId != null) { 395 return fakeIccId; 396 } 397 } 398 return mIccId; 399 } 400 401 /** 402 * Returns the full ICC ID including hex digits. 403 * @return full ICC ID including hex digits 404 */ getFullIccId()405 public String getFullIccId() { 406 return mFullIccId; 407 } 408 registerForRecordsLoaded(Handler h, int what, Object obj)409 public void registerForRecordsLoaded(Handler h, int what, Object obj) { 410 if (mDestroyed.get()) { 411 return; 412 } 413 414 Registrant r = new Registrant(h, what, obj); 415 mRecordsLoadedRegistrants.add(r); 416 417 if (getRecordsLoaded()) { 418 r.notifyRegistrant(new AsyncResult(null, null, null)); 419 } 420 } 421 unregisterForRecordsLoaded(Handler h)422 public void unregisterForRecordsLoaded(Handler h) { 423 mRecordsLoadedRegistrants.remove(h); 424 } 425 unregisterForRecordsOverride(Handler h)426 public void unregisterForRecordsOverride(Handler h) { 427 mRecordsOverrideRegistrants.remove(h); 428 } 429 registerForRecordsOverride(Handler h, int what, Object obj)430 public void registerForRecordsOverride(Handler h, int what, Object obj) { 431 if (mDestroyed.get()) { 432 return; 433 } 434 435 Registrant r = new Registrant(h, what, obj); 436 mRecordsOverrideRegistrants.add(r); 437 438 if (getRecordsLoaded()) { 439 r.notifyRegistrant(new AsyncResult(null, null, null)); 440 } 441 } 442 443 /** 444 * Register to be notified when records are loaded for a PIN or PUK locked SIM 445 */ registerForLockedRecordsLoaded(Handler h, int what, Object obj)446 public void registerForLockedRecordsLoaded(Handler h, int what, Object obj) { 447 if (mDestroyed.get()) { 448 return; 449 } 450 451 Registrant r = new Registrant(h, what, obj); 452 mLockedRecordsLoadedRegistrants.add(r); 453 454 if (getLockedRecordsLoaded()) { 455 r.notifyRegistrant(new AsyncResult(null, null, null)); 456 } 457 } 458 459 /** 460 * Unregister corresponding to registerForLockedRecordsLoaded() 461 */ unregisterForLockedRecordsLoaded(Handler h)462 public void unregisterForLockedRecordsLoaded(Handler h) { 463 mLockedRecordsLoadedRegistrants.remove(h); 464 } 465 466 /** 467 * Register to be notified when records are loaded for a network locked SIM 468 */ registerForNetworkLockedRecordsLoaded(Handler h, int what, Object obj)469 public void registerForNetworkLockedRecordsLoaded(Handler h, int what, Object obj) { 470 if (mDestroyed.get()) { 471 return; 472 } 473 474 Registrant r = new Registrant(h, what, obj); 475 mNetworkLockedRecordsLoadedRegistrants.add(r); 476 477 if (getNetworkLockedRecordsLoaded()) { 478 r.notifyRegistrant(new AsyncResult(null, null, null)); 479 } 480 } 481 482 /** 483 * Unregister corresponding to registerForLockedRecordsLoaded() 484 */ unregisterForNetworkLockedRecordsLoaded(Handler h)485 public void unregisterForNetworkLockedRecordsLoaded(Handler h) { 486 mNetworkLockedRecordsLoadedRegistrants.remove(h); 487 } 488 registerForImsiReady(Handler h, int what, Object obj)489 public void registerForImsiReady(Handler h, int what, Object obj) { 490 if (mDestroyed.get()) { 491 return; 492 } 493 494 Registrant r = new Registrant(h, what, obj); 495 mImsiReadyRegistrants.add(r); 496 497 if (getIMSI() != null) { 498 r.notifyRegistrant(new AsyncResult(null, null, null)); 499 } 500 } unregisterForImsiReady(Handler h)501 public void unregisterForImsiReady(Handler h) { 502 mImsiReadyRegistrants.remove(h); 503 } 504 registerForSpnUpdate(Handler h, int what, Object obj)505 public void registerForSpnUpdate(Handler h, int what, Object obj) { 506 if (mDestroyed.get()) { 507 return; 508 } 509 510 Registrant r = new Registrant(h, what, obj); 511 mSpnUpdatedRegistrants.add(r); 512 513 if (!TextUtils.isEmpty(mSpn)) { 514 r.notifyRegistrant(new AsyncResult(null, null, null)); 515 } 516 } unregisterForSpnUpdate(Handler h)517 public void unregisterForSpnUpdate(Handler h) { 518 mSpnUpdatedRegistrants.remove(h); 519 } 520 registerForRecordsEvents(Handler h, int what, Object obj)521 public void registerForRecordsEvents(Handler h, int what, Object obj) { 522 Registrant r = new Registrant (h, what, obj); 523 mRecordsEventsRegistrants.add(r); 524 525 /* Notify registrant of all the possible events. This is to make sure registrant is 526 notified even if event occurred in the past. */ 527 r.notifyResult(EVENT_MWI); 528 r.notifyResult(EVENT_CFI); 529 } 530 unregisterForRecordsEvents(Handler h)531 public void unregisterForRecordsEvents(Handler h) { 532 mRecordsEventsRegistrants.remove(h); 533 } 534 registerForNewSms(Handler h, int what, Object obj)535 public void registerForNewSms(Handler h, int what, Object obj) { 536 Registrant r = new Registrant (h, what, obj); 537 mNewSmsRegistrants.add(r); 538 } 539 unregisterForNewSms(Handler h)540 public void unregisterForNewSms(Handler h) { 541 mNewSmsRegistrants.remove(h); 542 } 543 registerForNetworkSelectionModeAutomatic( Handler h, int what, Object obj)544 public void registerForNetworkSelectionModeAutomatic( 545 Handler h, int what, Object obj) { 546 Registrant r = new Registrant (h, what, obj); 547 mNetworkSelectionModeAutomaticRegistrants.add(r); 548 } unregisterForNetworkSelectionModeAutomatic(Handler h)549 public void unregisterForNetworkSelectionModeAutomatic(Handler h) { 550 mNetworkSelectionModeAutomaticRegistrants.remove(h); 551 } 552 553 /** 554 * Get the International Mobile Subscriber ID (IMSI) on a SIM 555 * for GSM, UMTS and like networks. Default is null if IMSI is 556 * not supported or unavailable. 557 * 558 * @return null if SIM is not yet ready or unavailable 559 */ getIMSI()560 public String getIMSI() { 561 if (mCarrierTestOverride.isInTestMode()) { 562 String fakeImsi = mCarrierTestOverride.getFakeIMSI(); 563 if (fakeImsi != null) { 564 return fakeImsi; 565 } 566 } 567 return mImsi; 568 } 569 570 /** 571 * Update IMSI record and try to extract the PLMN information and notify registrants. 572 * @param inImsi the IMSI value 573 */ setImsi(String inImsi)574 public void setImsi(String inImsi) { 575 // Remove trailing F's if present in IMSI. 576 mImsi = IccUtils.stripTrailingFs(inImsi); 577 if (!Objects.equals(mImsi, inImsi)) { 578 loge("Invalid IMSI padding digits received."); 579 } 580 581 if (TextUtils.isEmpty(mImsi)) mImsi = null; 582 583 if (mImsi != null && !mImsi.matches("[0-9]+")) { 584 loge("Invalid non-numeric IMSI digits received."); 585 mImsi = null; 586 } 587 588 // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more 589 // than 15 (and usually 15). 590 // This will also handle un-set IMSI records (all Fs) 591 if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) { 592 loge("invalid IMSI " + mImsi); 593 mImsi = null; 594 } 595 596 log("IMSI: mMncLength=" + mMncLength); 597 598 if (mImsi != null && mImsi.length() >= 6) { 599 log("IMSI: " + mImsi.substring(0, 6) + Rlog.pii(VDBG, mImsi.substring(6))); 600 } 601 602 // IMSI has changed so the PLMN might have changed as well 603 updateOperatorPlmn(); 604 605 mImsiReadyRegistrants.notifyRegistrants(); 606 } 607 updateOperatorPlmn()608 protected void updateOperatorPlmn() { 609 // In case of a test override, use the test IMSI 610 String imsi = getIMSI(); 611 612 if (imsi != null) { 613 // First try to guess the length based on a table of known 3-digit MNCs. 614 if (((mMncLength == UNKNOWN) || (mMncLength == 2)) && imsi.length() >= 6) { 615 String mccmncCode = imsi.substring(0, 6); 616 for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) { 617 if (mccmnc.equals(mccmncCode)) { 618 mMncLength = 3; 619 log("IMSI: setting1 mMncLength=" + mMncLength); 620 break; 621 } 622 } 623 } 624 625 // If still unknown, guess using the MCC. 626 if (mMncLength == UNKNOWN) { 627 try { 628 int mcc = Integer.parseInt(imsi.substring(0, 3)); 629 mMncLength = MccTable.smallestDigitsMccForMnc(mcc); 630 log("setting2 mMncLength=" + mMncLength); 631 } catch (NumberFormatException e) { 632 loge("Corrupt IMSI! setting3 mMncLength=" + mMncLength); 633 } 634 } 635 636 if (mMncLength != UNKNOWN && mMncLength != UNINITIALIZED 637 && imsi.length() >= 3 + mMncLength) { 638 log("update mccmnc=" + imsi.substring(0, 3 + mMncLength)); 639 // finally have both the imsi and the mncLength and 640 // can parse the imsi properly 641 MccTable.updateMccMncConfiguration(mContext, imsi.substring(0, 3 + mMncLength)); 642 } 643 } 644 } 645 646 /** 647 * Get the Network Access ID (NAI) on a CSIM for CDMA like networks. Default is null if IMSI is 648 * not supported or unavailable. 649 * 650 * @return null if NAI is not yet ready or unavailable 651 */ getNAI()652 public String getNAI() { 653 return null; 654 } 655 getMsisdnNumber()656 public String getMsisdnNumber() { 657 return mMsisdn; 658 } 659 660 /** 661 * Get the Group Identifier Level 1 (GID1) on a SIM for GSM. 662 * @return null if SIM is not yet ready 663 */ getGid1()664 public String getGid1() { 665 if (mCarrierTestOverride.isInTestMode()) { 666 String fakeGid1 = mCarrierTestOverride.getFakeGid1(); 667 if (fakeGid1 != null) { 668 return fakeGid1; 669 } 670 } 671 return mGid1; 672 } 673 674 /** 675 * Get the Group Identifier Level 2 (GID2) on a SIM. 676 * @return null if SIM is not yet ready 677 */ getGid2()678 public String getGid2() { 679 if (mCarrierTestOverride.isInTestMode()) { 680 String fakeGid2 = mCarrierTestOverride.getFakeGid2(); 681 if (fakeGid2 != null) { 682 return fakeGid2; 683 } 684 } 685 return mGid2; 686 } 687 688 /** 689 * Get the PLMN network name on a SIM. 690 * @return null if SIM is not yet ready 691 */ getPnnHomeName()692 public String getPnnHomeName() { 693 if (mCarrierTestOverride.isInTestMode()) { 694 String fakePnnHomeName = mCarrierTestOverride.getFakePnnHomeName(); 695 if (fakePnnHomeName != null) { 696 return fakePnnHomeName; 697 } 698 } 699 return mPnnHomeName; 700 } 701 setMsisdnNumber(String alphaTag, String number, Message onComplete)702 public void setMsisdnNumber(String alphaTag, String number, 703 Message onComplete) { 704 loge("setMsisdn() should not be invoked on base IccRecords"); 705 // synthesize a "File Not Found" exception and return it 706 AsyncResult.forMessage(onComplete).exception = 707 (new IccIoResult(0x6A, 0x82, (byte[]) null)).getException(); 708 onComplete.sendToTarget(); 709 } 710 getMsisdnAlphaTag()711 public String getMsisdnAlphaTag() { 712 return mMsisdnTag; 713 } 714 getVoiceMailNumber()715 public String getVoiceMailNumber() { 716 return mVoiceMailNum; 717 } 718 719 /** 720 * Return Service Provider Name stored in SIM (EF_SPN=0x6F46) or in RUIM (EF_RUIM_SPN=0x6F41). 721 * 722 * @return null if SIM is not yet ready or no RUIM entry 723 */ getServiceProviderName()724 public String getServiceProviderName() { 725 if (mCarrierTestOverride.isInTestMode()) { 726 String fakeSpn = mCarrierTestOverride.getFakeSpn(); 727 if (fakeSpn != null) { 728 return fakeSpn; 729 } 730 } 731 return mSpn; 732 } 733 734 /** 735 * Return Service Provider Name stored in SIM (EF_SPN=0x6F46) or in RUIM (EF_RUIM_SPN=0x6F41) or 736 * the brand override. The brand override has higher priority than the SPN from SIM. 737 * 738 * @return service provider name. 739 */ 740 @Nullable getServiceProviderNameWithBrandOverride()741 public String getServiceProviderNameWithBrandOverride() { 742 if (mParentApp != null && mParentApp.getUiccProfile() != null) { 743 String brandOverride = mParentApp.getUiccProfile().getOperatorBrandOverride(); 744 if (!TextUtils.isEmpty(brandOverride)) { 745 return brandOverride; 746 } 747 } 748 return mSpn; 749 } 750 setServiceProviderName(String spn)751 protected void setServiceProviderName(String spn) { 752 if (!TextUtils.equals(mSpn, spn)) { 753 mSpn = spn != null ? spn.trim() : null; 754 mSpnUpdatedRegistrants.notifyRegistrants(); 755 } 756 } 757 758 /** 759 * Set voice mail number to SIM record 760 * 761 * The voice mail number can be stored either in EF_MBDN (TS 51.011) or 762 * EF_MAILBOX_CPHS (CPHS 4.2) 763 * 764 * If EF_MBDN is available, store the voice mail number to EF_MBDN 765 * 766 * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS 767 * 768 * So the voice mail number will be stored in both EFs if both are available 769 * 770 * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail. 771 * 772 * When the operation is complete, onComplete will be sent to its handler 773 * 774 * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters) 775 * @param voiceNumber dailing nubmer (upto 20 digits) 776 * if the number is start with '+', then set to international TOA 777 * @param onComplete 778 * onComplete.obj will be an AsyncResult 779 * ((AsyncResult)onComplete.obj).exception == null on success 780 * ((AsyncResult)onComplete.obj).exception != null on fail 781 */ setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete)782 public abstract void setVoiceMailNumber(String alphaTag, String voiceNumber, 783 Message onComplete); 784 getVoiceMailAlphaTag()785 public String getVoiceMailAlphaTag() { 786 return mVoiceMailTag; 787 } 788 789 /** 790 * Sets the SIM voice message waiting indicator records 791 * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported 792 * @param countWaiting The number of messages waiting, if known. Use 793 * -1 to indicate that an unknown number of 794 * messages are waiting 795 */ setVoiceMessageWaiting(int line, int countWaiting)796 public abstract void setVoiceMessageWaiting(int line, int countWaiting); 797 798 /** 799 * Called by GsmCdmaPhone to update VoiceMail count 800 */ getVoiceMessageCount()801 public abstract int getVoiceMessageCount(); 802 803 /** 804 * Called by STK Service when REFRESH is received. 805 * @param fileChanged indicates whether any files changed 806 * @param fileList if non-null, a list of EF files that changed 807 */ onRefresh(boolean fileChanged, int[] fileList)808 public abstract void onRefresh(boolean fileChanged, int[] fileList); 809 getRecordsLoaded()810 public boolean getRecordsLoaded() { 811 return mRecordsToLoad == 0 && mRecordsRequested; 812 } 813 getLockedRecordsLoaded()814 protected boolean getLockedRecordsLoaded() { 815 return mRecordsToLoad == 0 816 && mLockedRecordsReqReason == LOCKED_RECORDS_REQ_REASON_LOCKED; 817 } 818 getNetworkLockedRecordsLoaded()819 protected boolean getNetworkLockedRecordsLoaded() { 820 return mRecordsToLoad == 0 821 && mLockedRecordsReqReason == LOCKED_RECORDS_REQ_REASON_NETWORK_LOCKED; 822 } 823 824 //***** Overridden from Handler 825 @Override handleMessage(Message msg)826 public void handleMessage(Message msg) { 827 AsyncResult ar; 828 829 switch (msg.what) { 830 case EVENT_APP_READY: 831 mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_NONE; 832 onReady(); 833 break; 834 835 case EVENT_APP_DETECTED: 836 mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_NONE; 837 onDetected(); 838 break; 839 840 case EVENT_APP_LOCKED: 841 mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_LOCKED; 842 onLocked(); 843 break; 844 845 case EVENT_APP_NETWORK_LOCKED: 846 mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_NETWORK_LOCKED; 847 onLocked(); 848 break; 849 850 case EVENT_GET_ICC_RECORD_DONE: 851 try { 852 ar = (AsyncResult) msg.obj; 853 IccRecordLoaded recordLoaded = (IccRecordLoaded) ar.userObj; 854 if (DBG) log(recordLoaded.getEfName() + " LOADED"); 855 856 if (ar.exception != null) { 857 loge("Record Load Exception: " + ar.exception); 858 } else { 859 recordLoaded.onRecordLoaded(ar); 860 } 861 }catch (RuntimeException exc) { 862 // I don't want these exceptions to be fatal 863 loge("Exception parsing SIM record: " + exc); 864 } finally { 865 // Count up record load responses even if they are fails 866 onRecordLoaded(); 867 } 868 break; 869 870 case EVENT_REFRESH: 871 ar = (AsyncResult)msg.obj; 872 if (DBG) log("Card REFRESH occurred: "); 873 if (ar.exception == null) { 874 handleRefresh((IccRefreshResponse)ar.result); 875 } else { 876 loge("Icc refresh Exception: " + ar.exception); 877 } 878 break; 879 880 case EVENT_AKA_AUTHENTICATE_DONE: 881 ar = (AsyncResult) msg.obj; 882 AuthAsyncResponse rsp = (AuthAsyncResponse) ar.userObj; 883 if (DBG) log("EVENT_AKA_AUTHENTICATE_DONE"); 884 885 synchronized (rsp) { 886 if (ar.exception != null) { 887 rsp.exception = ar.exception; 888 loge("Exception ICC SIM AKA: " + ar.exception); 889 } else if (ar.result == null) { 890 rsp.exception = new NullPointerException( 891 "Null SIM authentication response"); 892 loge("EVENT_AKA_AUTHENTICATE_DONE: null response"); 893 } else { 894 try { 895 rsp.authRsp = (IccIoResult) ar.result; 896 if (VDBG) log("ICC SIM AKA: authRsp = " + rsp.authRsp); 897 } catch (ClassCastException e) { 898 rsp.exception = e; 899 loge("Failed to parse ICC SIM AKA contents: " + e); 900 } 901 } 902 rsp.notifyAll(); 903 } 904 905 break; 906 907 case EVENT_GET_SMS_RECORD_SIZE_DONE: 908 ar = (AsyncResult) msg.obj; 909 910 if (ar.exception != null) { 911 onRecordLoaded(); 912 loge("Exception in EVENT_GET_SMS_RECORD_SIZE_DONE " + ar.exception); 913 break; 914 } 915 916 int[] recordSize = (int[])ar.result; 917 try { 918 // recordSize[0] is the record length 919 // recordSize[1] is the total length of the EF file 920 // recordSize[2] is the number of records in the EF file 921 mSmsCountOnIcc = recordSize[2]; 922 log("EVENT_GET_SMS_RECORD_SIZE_DONE Size " + recordSize[0] 923 + " total " + recordSize[1] 924 + " record " + recordSize[2]); 925 } catch (ArrayIndexOutOfBoundsException exc) { 926 mSmsCountOnIcc = -1; 927 loge("ArrayIndexOutOfBoundsException in EVENT_GET_SMS_RECORD_SIZE_DONE: " 928 + exc.toString()); 929 } finally { 930 onRecordLoaded(); 931 } 932 break; 933 934 default: 935 super.handleMessage(msg); 936 } 937 } 938 939 /** 940 * Returns the SIM language derived from the EF-LI and EF-PL sim records. 941 */ getSimLanguage()942 public String getSimLanguage() { 943 return mPrefLang; 944 } 945 setSimLanguage(byte[] efLi, byte[] efPl)946 protected void setSimLanguage(byte[] efLi, byte[] efPl) { 947 String[] locales = mContext.getAssets().getLocales(); 948 try { 949 mPrefLang = findBestLanguage(efLi, locales); 950 } catch (UnsupportedEncodingException uee) { 951 log("Unable to parse EF-LI: " + Arrays.toString(efLi)); 952 } 953 954 if (mPrefLang == null) { 955 try { 956 mPrefLang = findBestLanguage(efPl, locales); 957 } catch (UnsupportedEncodingException uee) { 958 log("Unable to parse EF-PL: " + Arrays.toString(efLi)); 959 } 960 } 961 } 962 findBestLanguage(byte[] languages, String[] locales)963 protected static String findBestLanguage(byte[] languages, String[] locales) 964 throws UnsupportedEncodingException { 965 if ((languages == null) || (locales == null)) return null; 966 967 // Each 2-bytes consists of one language 968 for (int i = 0; (i + 1) < languages.length; i += 2) { 969 String lang = new String(languages, i, 2, "ISO-8859-1"); 970 for (int j = 0; j < locales.length; j++) { 971 if (locales[j] != null && locales[j].length() >= 2 && 972 locales[j].substring(0, 2).equalsIgnoreCase(lang)) { 973 return lang; 974 } 975 } 976 } 977 978 // no match found. return null 979 return null; 980 } 981 handleFileUpdate(int efid)982 protected abstract void handleFileUpdate(int efid); 983 handleRefresh(IccRefreshResponse refreshResponse)984 protected void handleRefresh(IccRefreshResponse refreshResponse){ 985 if (refreshResponse == null) { 986 if (DBG) log("handleRefresh received without input"); 987 return; 988 } 989 990 if (!TextUtils.isEmpty(refreshResponse.aid) && 991 !refreshResponse.aid.equals(mParentApp.getAid())) { 992 // This is for different app. Ignore. 993 return; 994 } 995 996 switch (refreshResponse.refreshResult) { 997 case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE: 998 if (DBG) log("handleRefresh with SIM_FILE_UPDATED"); 999 handleFileUpdate(refreshResponse.efId); 1000 break; 1001 default: 1002 // unknown refresh operation 1003 if (DBG) log("handleRefresh with unknown operation"); 1004 break; 1005 } 1006 } 1007 onRecordLoaded()1008 protected abstract void onRecordLoaded(); 1009 onAllRecordsLoaded()1010 protected abstract void onAllRecordsLoaded(); 1011 1012 /** 1013 * Retrieves the SPN/PLMN display condition from UICC. 1014 * 1015 * Display of service provider name is required when registered PLMN is neither HPLMN nor a PLMN 1016 * in the service provider PLMN list(EF_SPDI). 1017 * 1018 * Display of PLMN network name is required when registered PLMN is either HPLMN or a PLMN in 1019 * the service provider PLMN list(EF_SPDI). 1020 * 1021 * Reference: 3GPP TS 131.102 section 4.2.12 EF_SPN Display Condition 1022 * 1023 * @return a bitmask represent the carrier name display condition. 1024 */ 1025 @CarrierNameDisplayConditionBitmask getCarrierNameDisplayCondition()1026 public int getCarrierNameDisplayCondition() { 1027 return mCarrierNameDisplayCondition; 1028 } 1029 1030 /** 1031 * Retrieves the service provider display information. This is a list of PLMNs in which the 1032 * service provider name shall be displayed. 1033 * 1034 * Reference: 3GPP TS 131.102 section 4.2.66 EF_SPDI 1035 * 1036 * @return a list of PLMN(mcc+mnc) if EF_SPDI is existed, otherwise return null. 1037 */ getServiceProviderDisplayInformation()1038 public String[] getServiceProviderDisplayInformation() { 1039 return mSpdi; 1040 } 1041 1042 /** 1043 * Get home PLMN list. 1044 * 1045 * @see #getEhplmns() 1046 * @see #getServiceProviderDisplayInformation() 1047 * 1048 * @return a list of HPLMN if existed, otherwise return null. 1049 */ getHomePlmns()1050 public String[] getHomePlmns() { 1051 // hplmn from imsi. 1052 String hplmn = getOperatorNumeric(); 1053 1054 // hplmn from ehplmn list. 1055 String[] hplmns = getEhplmns(); 1056 1057 // plmn from ef_spdi. 1058 String[] spdi = getServiceProviderDisplayInformation(); 1059 1060 // Use the plmn from imsi as the hplmn if Ehplmn not present. 1061 if (ArrayUtils.isEmpty(hplmns)) { 1062 hplmns = new String[] {hplmn}; 1063 } 1064 1065 if (!ArrayUtils.isEmpty(spdi)) { 1066 hplmns = ArrayUtils.concatElements(String.class, hplmns, spdi); 1067 } 1068 // If hplmns don't contain hplmn, we need to add hplmn to hplmns 1069 hplmns = ArrayUtils.appendElement(String.class, hplmns, hplmn); 1070 return hplmns; 1071 } 1072 1073 /** 1074 * Return true if "Restriction of menu options for manual PLMN selection" 1075 * bit is set or EF_CSP data is unavailable, return false otherwise. 1076 * Generally used for GSM/UMTS and the like SIMs. 1077 */ isCspPlmnEnabled()1078 public boolean isCspPlmnEnabled() { 1079 return false; 1080 } 1081 1082 /** 1083 * Returns the 5 or 6 digit MCC/MNC of the operator that 1084 * provided the SIM card. Returns null of SIM is not yet ready 1085 * or is not valid for the type of IccCard. Generally used for 1086 * GSM/UMTS and the like SIMS 1087 */ getOperatorNumeric()1088 public String getOperatorNumeric() { 1089 return null; 1090 } 1091 1092 /** 1093 * Get the current Voice call forwarding flag for GSM/UMTS and the like SIMs 1094 * 1095 * @return CALL_FORWARDING_STATUS_XXX (DISABLED/ENABLED/UNKNOWN) 1096 */ getVoiceCallForwardingFlag()1097 public int getVoiceCallForwardingFlag() { 1098 return CALL_FORWARDING_STATUS_UNKNOWN; 1099 } 1100 1101 /** 1102 * Set the voice call forwarding flag for GSM/UMTS and the like SIMs 1103 * 1104 * @param line to enable/disable 1105 * @param enable 1106 * @param number to which CFU is enabled 1107 */ setVoiceCallForwardingFlag(int line, boolean enable, String number)1108 public void setVoiceCallForwardingFlag(int line, boolean enable, String number) { 1109 } 1110 1111 /** 1112 * Indicates wether the ICC records have been loaded or not 1113 * 1114 * @return true if the records have been loaded, false otherwise. 1115 */ isLoaded()1116 public boolean isLoaded() { 1117 return mLoaded.get(); 1118 } 1119 1120 /** 1121 * Indicates wether SIM is in provisioned state or not. 1122 * Overridden only if SIM can be dynamically provisioned via OTA. 1123 * 1124 * @return true if provisioned 1125 */ isProvisioned()1126 public boolean isProvisioned () { 1127 return true; 1128 } 1129 1130 /** 1131 * Write string to log file 1132 * 1133 * @param s is the string to write 1134 */ log(String s)1135 protected abstract void log(String s); 1136 1137 /** 1138 * Write error string to log file. 1139 * 1140 * @param s is the string to write 1141 */ loge(String s)1142 protected abstract void loge(String s); 1143 1144 /** 1145 * @return String array containing EHPLMNs associated with the card. 1146 */ getEhplmns()1147 public String[] getEhplmns() { 1148 return mEhplmns; 1149 } 1150 1151 /** 1152 * @return String array containing PLMN from HplmnActRecord. 1153 */ getPlmnsFromHplmnActRecord()1154 public String[] getPlmnsFromHplmnActRecord() { 1155 if (mHplmnActRecords == null) return null; 1156 String[] hplmns = new String[mHplmnActRecords.length]; 1157 for (int i = 0; i < mHplmnActRecords.length; i++) { 1158 hplmns[i] = mHplmnActRecords[i].plmn; 1159 } 1160 return hplmns; 1161 } 1162 1163 /** 1164 * Return an interface to retrieve the ISIM records for IMS, if available. 1165 * @return the interface to retrieve the ISIM records, or null if not supported 1166 */ getIsimRecords()1167 public IsimRecords getIsimRecords() { 1168 return null; 1169 } 1170 getUsimServiceTable()1171 public UsimServiceTable getUsimServiceTable() { 1172 return null; 1173 } 1174 1175 /** 1176 * Solve authentication leakage issue. See b/147463955. 1177 * Returns the response of the SIM application on the UICC to authentication 1178 * challenge/response algorithm. The data string and challenge response are 1179 * Base64 encoded Strings. 1180 * Can support EAP-SIM, EAP-AKA with results encoded per 3GPP TS 31.102. 1181 * 1182 * @param authContext parameter P2 that specifies the authentication context 1183 * per 3GPP TS 31.102 (Section 7.1.2) 1184 * @param data authentication challenge data 1185 * @return challenge response 1186 */ 1187 @Nullable getIccSimChallengeResponse(int authContext, String data)1188 public String getIccSimChallengeResponse(int authContext, String data) { 1189 if (VDBG) log("getIccSimChallengeResponse:"); 1190 1191 //final here is for defensive copy. 1192 final CommandsInterface ci = mCi; 1193 final UiccCardApplication parentApp = mParentApp; 1194 if (ci == null || parentApp == null) { 1195 loge("getIccSimChallengeResponse: Fail, ci or parentApp is null"); 1196 return null; 1197 } 1198 1199 AuthAsyncResponse rsp = new AuthAsyncResponse(); 1200 1201 synchronized (rsp) { 1202 ci.requestIccSimAuthentication(authContext, data, parentApp.getAid(), 1203 obtainMessage(EVENT_AKA_AUTHENTICATE_DONE, 0, 0, rsp)); 1204 //TODO: factor wait with timeout into a separate method 1205 final long startTime = SystemClock.elapsedRealtime(); 1206 do { 1207 try { 1208 long sleepTime = startTime + ICC_SIM_CHALLENGE_TIMEOUT_MILLIS 1209 - SystemClock.elapsedRealtime(); 1210 if (sleepTime > 0) rsp.wait(sleepTime); 1211 } catch (InterruptedException e) { 1212 Rlog.w("IccRecords", "getIccSimChallengeResponse: InterruptedException."); 1213 } 1214 } while (SystemClock.elapsedRealtime() - startTime < ICC_SIM_CHALLENGE_TIMEOUT_MILLIS 1215 && rsp.authRsp == null && rsp.exception == null); 1216 1217 if (SystemClock.elapsedRealtime() - startTime >= ICC_SIM_CHALLENGE_TIMEOUT_MILLIS 1218 && rsp.authRsp == null && rsp.exception == null) { 1219 loge("getIccSimChallengeResponse timeout!"); 1220 return null; 1221 } 1222 1223 if (rsp.exception != null) { 1224 loge("getIccSimChallengeResponse exception: " + rsp.exception); 1225 //TODO: propagate better exceptions up to the user now that we have them available 1226 //in the call stack. 1227 return null; 1228 } 1229 1230 if (rsp.authRsp == null) { 1231 loge("getIccSimChallengeResponse: No authentication response"); 1232 return null; 1233 } 1234 } 1235 if (VDBG) log("getIccSimChallengeResponse: return rsp.authRsp"); 1236 1237 return rsp.authRsp.payload != null ? new String(rsp.authRsp.payload) : null; 1238 } 1239 1240 /** 1241 * Convert the spn display condition to a bitmask 1242 * {@link com.android.internal.telephony.uicc.IccRecords.CarrierNameDisplayConditionBitmask}. 1243 * 1244 * b1 is the last bit of the display condition which is used to determine whether display of 1245 * PLMN network name is required when registered PLMN is **either** HPLMN or a PLMN in the 1246 * service provider PLMN list. 1247 * 1248 * b2 is the second last bit of the display condtion which is used to determine 1249 * whether display of Service Provider Name is required when registered PLMN is 1250 * **neither** HPLMN nor PLMN in the service provider PLMN list. 1251 * 1252 * Reference: 3GPP TS 31.102 section 4.2.12 EF_SPN 1253 * 1254 * @return a carrier name display condtion bitmask. 1255 */ 1256 @CarrierNameDisplayConditionBitmask convertSpnDisplayConditionToBitmask(int condition)1257 public static int convertSpnDisplayConditionToBitmask(int condition) { 1258 int carrierNameDisplayCondition = 0; 1259 // b1 = 0: display of registered PLMN name not required when registered PLMN is 1260 // either HPLMN or a PLMN in the service provider PLMN list. 1261 // b1 = 1: display of registered PLMN name required when registered PLMN is 1262 // either HPLMN or a PLMN in the service provider PLMN list. 1263 if ((condition & 0x1) == 0x1) { 1264 carrierNameDisplayCondition |= CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN; 1265 } 1266 1267 // b2 = 0: display of the service provider name is **required** when registered 1268 // PLMN is neither HPLMN nor a PLMN in the service provider PLMN list. 1269 // b2 = 1: display of the servier provider name is **not required** when 1270 // registered PLMN is neither HPLMN nor PLMN in the service provider PLMN list. 1271 if ((condition & 0x2) == 0) { 1272 carrierNameDisplayCondition |= CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN; 1273 } 1274 1275 return carrierNameDisplayCondition; 1276 } 1277 1278 /** 1279 * Get SMS capacity count on ICC card. 1280 */ getSmsCapacityOnIcc()1281 public int getSmsCapacityOnIcc() { 1282 if (DBG) log("getSmsCapacityOnIcc: " + mSmsCountOnIcc); 1283 return mSmsCountOnIcc; 1284 } 1285 dump(FileDescriptor fd, PrintWriter pw, String[] args)1286 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1287 pw.println("IccRecords: " + this); 1288 pw.println(" mDestroyed=" + mDestroyed); 1289 pw.println(" mCi=" + mCi); 1290 pw.println(" mFh=" + mFh); 1291 pw.println(" mParentApp=" + mParentApp); 1292 pw.println(" recordsLoadedRegistrants: size=" + mRecordsLoadedRegistrants.size()); 1293 for (int i = 0; i < mRecordsLoadedRegistrants.size(); i++) { 1294 pw.println(" recordsLoadedRegistrants[" + i + "]=" 1295 + ((Registrant)mRecordsLoadedRegistrants.get(i)).getHandler()); 1296 } 1297 pw.println(" mLockedRecordsLoadedRegistrants: size=" 1298 + mLockedRecordsLoadedRegistrants.size()); 1299 for (int i = 0; i < mLockedRecordsLoadedRegistrants.size(); i++) { 1300 pw.println(" mLockedRecordsLoadedRegistrants[" + i + "]=" 1301 + ((Registrant) mLockedRecordsLoadedRegistrants.get(i)).getHandler()); 1302 } 1303 pw.println(" mNetworkLockedRecordsLoadedRegistrants: size=" 1304 + mNetworkLockedRecordsLoadedRegistrants.size()); 1305 for (int i = 0; i < mNetworkLockedRecordsLoadedRegistrants.size(); i++) { 1306 pw.println(" mLockedRecordsLoadedRegistrants[" + i + "]=" 1307 + ((Registrant) mNetworkLockedRecordsLoadedRegistrants.get(i)).getHandler()); 1308 } 1309 pw.println(" mImsiReadyRegistrants: size=" + mImsiReadyRegistrants.size()); 1310 for (int i = 0; i < mImsiReadyRegistrants.size(); i++) { 1311 pw.println(" mImsiReadyRegistrants[" + i + "]=" 1312 + ((Registrant)mImsiReadyRegistrants.get(i)).getHandler()); 1313 } 1314 pw.println(" mRecordsEventsRegistrants: size=" + mRecordsEventsRegistrants.size()); 1315 for (int i = 0; i < mRecordsEventsRegistrants.size(); i++) { 1316 pw.println(" mRecordsEventsRegistrants[" + i + "]=" 1317 + ((Registrant)mRecordsEventsRegistrants.get(i)).getHandler()); 1318 } 1319 pw.println(" mNewSmsRegistrants: size=" + mNewSmsRegistrants.size()); 1320 for (int i = 0; i < mNewSmsRegistrants.size(); i++) { 1321 pw.println(" mNewSmsRegistrants[" + i + "]=" 1322 + ((Registrant)mNewSmsRegistrants.get(i)).getHandler()); 1323 } 1324 pw.println(" mNetworkSelectionModeAutomaticRegistrants: size=" 1325 + mNetworkSelectionModeAutomaticRegistrants.size()); 1326 for (int i = 0; i < mNetworkSelectionModeAutomaticRegistrants.size(); i++) { 1327 pw.println(" mNetworkSelectionModeAutomaticRegistrants[" + i + "]=" 1328 + ((Registrant)mNetworkSelectionModeAutomaticRegistrants.get(i)).getHandler()); 1329 } 1330 pw.println(" mRecordsRequested=" + mRecordsRequested); 1331 pw.println(" mLockedRecordsReqReason=" + mLockedRecordsReqReason); 1332 pw.println(" mRecordsToLoad=" + mRecordsToLoad); 1333 pw.println(" mRdnCache=" + mAdnCache); 1334 1335 String iccIdToPrint = SubscriptionInfo.givePrintableIccid(mFullIccId); 1336 pw.println(" iccid=" + iccIdToPrint); 1337 pw.println(" mMsisdn=" + Rlog.pii(VDBG, mMsisdn)); 1338 pw.println(" mMsisdnTag=" + mMsisdnTag); 1339 pw.println(" mVoiceMailNum=" + Rlog.pii(VDBG, mVoiceMailNum)); 1340 pw.println(" mVoiceMailTag=" + mVoiceMailTag); 1341 pw.println(" mNewVoiceMailNum=" + Rlog.pii(VDBG, mNewVoiceMailNum)); 1342 pw.println(" mNewVoiceMailTag=" + mNewVoiceMailTag); 1343 pw.println(" mIsVoiceMailFixed=" + mIsVoiceMailFixed); 1344 pw.println(" mImsi=" + ((mImsi != null) ? 1345 mImsi.substring(0, 6) + Rlog.pii(VDBG, mImsi.substring(6)) : "null")); 1346 if (mCarrierTestOverride.isInTestMode()) { 1347 pw.println(" mFakeImsi=" + mCarrierTestOverride.getFakeIMSI()); 1348 } 1349 pw.println(" mMncLength=" + mMncLength); 1350 pw.println(" mMailboxIndex=" + mMailboxIndex); 1351 pw.println(" mSpn=" + mSpn); 1352 if (mCarrierTestOverride.isInTestMode()) { 1353 pw.println(" mFakeSpn=" + mCarrierTestOverride.getFakeSpn()); 1354 } 1355 pw.flush(); 1356 } 1357 1358 /** 1359 * Operator PLMN information. This contains the location area information or tracking area 1360 * that are used to associate a specific name contained in EF_PNN. 1361 * 1362 * Reference: 3GPP TS 31.102 section 4.2.59 EF_OPL 1363 */ 1364 public static final class OperatorPlmnInfo { 1365 // PLMN numeric that may contains wildcard character ".". 1366 // For example, the pattern "123..." could match all PLMN which mcc is 123. 1367 public final String plmnNumericPattern; 1368 1369 public final int lacTacStart; 1370 public final int lacTacEnd; 1371 1372 public final int plmnNetworkNameIndex; OperatorPlmnInfo(String plmnNumericPattern, int lacTacStart, int lacTacEnd, int plmnNetworkNameIndex)1373 public OperatorPlmnInfo(String plmnNumericPattern, int lacTacStart, int lacTacEnd, 1374 int plmnNetworkNameIndex) { 1375 this.plmnNumericPattern = plmnNumericPattern; 1376 this.lacTacStart = lacTacStart; 1377 this.lacTacEnd = lacTacEnd; 1378 this.plmnNetworkNameIndex = plmnNetworkNameIndex; 1379 } 1380 1381 @Override toString()1382 public String toString() { 1383 return "{ plmnNumericPattern = " + plmnNumericPattern 1384 + "lacTacStart = " + lacTacStart 1385 + "lacTacEnd = " + lacTacEnd 1386 + "plmnNetworkNameIndex = " + plmnNetworkNameIndex 1387 + " }"; 1388 } 1389 } 1390 1391 /** 1392 * Full and short version of PLMN network name. 1393 */ 1394 public static final class PlmnNetworkName { 1395 public final String fullName; 1396 public final String shortName; 1397 PlmnNetworkName(String fullName, String shortName)1398 public PlmnNetworkName(String fullName, String shortName) { 1399 this.fullName = fullName; 1400 this.shortName = shortName; 1401 } 1402 1403 @Override toString()1404 public String toString() { 1405 return "{ fullName = " + fullName + " shortName = " + shortName + " }"; 1406 } 1407 } 1408 } 1409