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