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