RuimRecords.java revision 2351b17aba5350004fc76707f3b3d2859ce773c8
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/* 2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2008 The Android Open Source Project 3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * you may not use this file except in compliance with the License. 6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * You may obtain a copy of the License at 7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * http://www.apache.org/licenses/LICENSE-2.0 9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Unless required by applicable law or agreed to in writing, software 11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * See the License for the specific language governing permissions and 14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * limitations under the License. 15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 17d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkapackage com.android.internal.telephony.uicc; 18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 19e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY; 21c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC; 22e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 23e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA; 24e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport static com.android.internal.telephony.TelephonyProperties.PROPERTY_TEST_CSIM; 25e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 2605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.FileDescriptor; 2705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.PrintWriter; 28e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport java.util.ArrayList; 2905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.util.Arrays; 30e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport java.util.Locale; 31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context; 32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult; 33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message; 34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties; 35a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.TelephonyManager; 3699c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog; 37e9070e6d48d1389987650fa2c3e1f90aab860684Wink Savilleimport android.text.TextUtils; 382351b17aba5350004fc76707f3b3d2859ce773c8xinheimport android.util.Log; 39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.CommandsInterface; 41e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.GsmAlphabet; 42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.MccTable; 43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 44e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.cdma.sms.UserData; 45d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 462351b17aba5350004fc76707f3b3d2859ce773c8xinheimport com.android.internal.util.BitwiseInputStream; 47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/** 49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide} 50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic final class RuimRecords extends IccRecords { 52cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville static final String LOG_TAG = "RuimRecords"; 53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 5422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville private boolean mOtaCommited=false; 55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // ***** Instance Variables 57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private String mMyMobileNumber; 59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private String mMin2Min1; 60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private String mPrlVersion; 62e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // From CSIM application 63e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private byte[] mEFpl = null; 64e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private byte[] mEFli = null; 65e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka boolean mCsimSpnDisplayCondition = false; 66e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String mMdn; 67e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String mMin; 68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String mHomeSystemId; 69e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String mHomeNetworkId; 702351b17aba5350004fc76707f3b3d2859ce773c8xinhe private String mNai; 71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 72f92cb4bd5519427a0db673709d94683a8baf203aWink Saville @Override 73f92cb4bd5519427a0db673709d94683a8baf203aWink Saville public String toString() { 74f92cb4bd5519427a0db673709d94683a8baf203aWink Saville return "RuimRecords: " + super.toString() 7522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville + " m_ota_commited" + mOtaCommited 76f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mMyMobileNumber=" + "xxxx" 77f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mMin2Min1=" + mMin2Min1 78f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mPrlVersion=" + mPrlVersion 79f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mEFpl=" + mEFpl 80f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mEFli=" + mEFli 81f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mCsimSpnDisplayCondition=" + mCsimSpnDisplayCondition 82f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mMdn=" + mMdn 83f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mMin=" + mMin 84f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mHomeSystemId=" + mHomeSystemId 85f92cb4bd5519427a0db673709d94683a8baf203aWink Saville + " mHomeNetworkId=" + mHomeNetworkId; 86f92cb4bd5519427a0db673709d94683a8baf203aWink Saville } 87f92cb4bd5519427a0db673709d94683a8baf203aWink Saville 88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // ***** Event Constants 89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_IMSI_DONE = 3; 90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4; 91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_ICCID_DONE = 5; 92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10; 93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_UPDATE_DONE = 14; 94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_SST_DONE = 17; 95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_ALL_SMS_DONE = 18; 96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_MARK_SMS_READ_DONE = 19; 97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_SMS_ON_RUIM = 21; 99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_SMS_DONE = 22; 100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_RUIM_REFRESH = 31; 102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 103e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public RuimRecords(UiccCardApplication app, Context c, CommandsInterface ci) { 104e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka super(app, c, ci); 105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 10622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mAdnCache = new AdnRecordCache(mFh); 107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 10822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsRequested = false; // No load request is made till SIM ready 109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // recordsToLoad is set to 0 because no requests are made yet 11122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad = 0; 112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // NOTE the EVENT_SMS_ON_RUIM is not registered 114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mCi.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null); 115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Start off by setting empty state 117e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka resetRecords(); 118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 119e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mParentApp.registerForReady(this, EVENT_APP_READY, null); 120f92cb4bd5519427a0db673709d94683a8baf203aWink Saville if (DBG) log("RuimRecords X ctor this=" + this); 121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void dispose() { 125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("Disposing RuimRecords " + this); 126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //Unregister for all events 127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mCi.unregisterForIccRefresh(this); 128e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mParentApp.unregisterForReady(this); 129e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka resetRecords(); 130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville super.dispose(); 131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void finalize() { 135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if(DBG) log("RuimRecords finalized"); 136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 138e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected void resetRecords() { 13922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCountVoiceMessages = 0; 14022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMncLength = UNINITIALIZED; 141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville log("setting0 mMncLength" + mMncLength); 142b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville mIccId = null; 143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 14422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mAdnCache.reset(); 145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Don't clean up PROPERTY_ICC_OPERATOR_ISO_COUNTRY and 147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // PROPERTY_ICC_OPERATOR_NUMERIC here. Since not all CDMA 148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // devices have RUIM, these properties should keep the original 149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // values, e.g. build time settings, when there is no RUIM but 150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // set new values when RUIM is available and loaded. 151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // recordsRequested is set to false indicating that the SIM 153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // read requests made so far are not valid. This is set to 154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // true only when fresh set of read requests are made. 15522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsRequested = false; 156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 158e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka @Override 159e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getIMSI() { 160e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mImsi; 161e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 162e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String getMdnNumber() { 164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mMyMobileNumber; 165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String getCdmaMin() { 168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mMin2Min1; 169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** Returns null if RUIM is not yet ready */ 172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String getPrlVersion() { 173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mPrlVersion; 174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 1772351b17aba5350004fc76707f3b3d2859ce773c8xinhe /** Returns null if RUIM is not yet ready */ 1782351b17aba5350004fc76707f3b3d2859ce773c8xinhe public String getNAI() { 1792351b17aba5350004fc76707f3b3d2859ce773c8xinhe return mNai; 1802351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 1812351b17aba5350004fc76707f3b3d2859ce773c8xinhe 1822351b17aba5350004fc76707f3b3d2859ce773c8xinhe @Override 183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){ 184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // In CDMA this is Operator/OEM dependent 185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville AsyncResult.forMessage((onComplete)).exception = 186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville new IccException("setVoiceMailNumber not implemented"); 187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onComplete.sendToTarget(); 188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville loge("method setVoiceMailNumber is not implemented"); 189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Called by CCAT Service when REFRESH is received. 193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param fileChanged indicates whether any files changed 194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param fileList if non-null, a list of EF files that changed 195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void onRefresh(boolean fileChanged, int[] fileList) { 198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (fileChanged) { 199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // A future optimization would be to inspect fileList and 200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // only reload those files that we care about. For now, 201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // just re-fetch all RUIM records that we cache. 202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fetchRuimRecords(); 203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 206e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int adjstMinDigits (int digits) { 207e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Per C.S0005 section 2.3.1. 208e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka digits += 111; 209e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka digits = (digits % 10 == 0)?(digits - 10):digits; 210e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka digits = ((digits / 10) % 10 == 0)?(digits - 100):digits; 211e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka digits = ((digits / 100) % 10 == 0)?(digits - 1000):digits; 212e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return digits; 213e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 214e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Returns the 5 or 6 digit MCC/MNC of the operator that 217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * provided the RUIM card. Returns null of RUIM is not yet ready 218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String getRUIMOperatorNumeric() { 220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (mImsi == null) { 221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return null; 222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 22422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mMncLength != UNINITIALIZED && mMncLength != UNKNOWN) { 225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Length = length of MCC + length of MNC 226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3) 22722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mImsi.substring(0, 3 + mMncLength); 228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Guess the MNC length based on the MCC if we don't 231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // have a valid value in ef[ad] 232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int mcc = Integer.parseInt(mImsi.substring(0,3)); 234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc)); 235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 237e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Refer to ETSI TS 102.221 238e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfPlLoaded implements IccRecordLoaded { 239cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 240e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 241e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_PL"; 242e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 243e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 244cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 245e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 246e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mEFpl = (byte[]) ar.result; 247e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl)); 248e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 249e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 250e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 251e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Refer to C.S0065 5.2.26 252e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimLiLoaded implements IccRecordLoaded { 253cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 254e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 255e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_LI"; 256e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 257e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 258cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 259e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 260e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mEFli = (byte[]) ar.result; 261e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // convert csim efli data to iso 639 format 262e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (int i = 0; i < mEFli.length; i+=2) { 263e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch(mEFli[i+1]) { 264e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x01: mEFli[i] = 'e'; mEFli[i+1] = 'n';break; 265e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x02: mEFli[i] = 'f'; mEFli[i+1] = 'r';break; 266e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x03: mEFli[i] = 'e'; mEFli[i+1] = 's';break; 267e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x04: mEFli[i] = 'j'; mEFli[i+1] = 'a';break; 268e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x05: mEFli[i] = 'k'; mEFli[i+1] = 'o';break; 269e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x06: mEFli[i] = 'z'; mEFli[i+1] = 'h';break; 270e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x07: mEFli[i] = 'h'; mEFli[i+1] = 'e';break; 271e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: mEFli[i] = ' '; mEFli[i+1] = ' '; 272e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 273e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 274e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 275e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli)); 276e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 277e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 278e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 279e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Refer to C.S0065 5.2.32 280e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimSpnLoaded implements IccRecordLoaded { 281cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 282e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 283e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_SPN"; 284e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 285e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 286cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 287e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 288e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] data = (byte[]) ar.result; 289e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_SPN=" + 290e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka IccUtils.bytesToHexString(data)); 291e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 292e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0065 for EF_SPN decoding 293e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0); 294e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 295e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int encoding = data[1]; 296e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int language = data[2]; 297e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] spnData = new byte[32]; 298e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int len = ((data.length - 3) < 32) ? (data.length - 3) : 32; 299e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka System.arraycopy(data, 3, spnData, 0, len); 300e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 301e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int numBytes; 302e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (numBytes = 0; numBytes < spnData.length; numBytes++) { 303e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if ((spnData[numBytes] & 0xFF) == 0xFF) break; 304e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 305e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 306e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (numBytes == 0) { 307b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal setServiceProviderName(""); 308e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return; 309e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 310e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka try { 311e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch (encoding) { 312e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_OCTET: 313e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_LATIN: 314b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal setServiceProviderName(new String(spnData, 0, numBytes, "ISO-8859-1")); 315e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 316e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_IA5: 317e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_GSM_7BIT_ALPHABET: 318b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal setServiceProviderName( 319b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes*8)/7)); 320e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 32160e3a52dad667a094af0c269176ee30da739ee84Sandeep Gutta case UserData.ENCODING_7BIT_ASCII: 322b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao String spn = new String(spnData, 0, numBytes, "US-ASCII"); 323b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao // To address issues with incorrect encoding scheme 324b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao // programmed in some commercial CSIM cards, the decoded 325b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao // SPN is checked to have characters in printable ASCII 326b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao // range. If not, they are decoded with 327b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao // ENCODING_GSM_7BIT_ALPHABET scheme. 328b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao if (TextUtils.isPrintableAsciiOnly(spn)) { 329b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao setServiceProviderName(spn); 330b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao } else { 331b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao if (DBG) log("Some corruption in SPN decoding = " + spn); 332b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao if (DBG) log("Using ENCODING_GSM_7BIT_ALPHABET scheme..."); 333b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao setServiceProviderName( 334b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes * 8) / 7)); 335b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao } 33660e3a52dad667a094af0c269176ee30da739ee84Sandeep Gutta break; 337e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_UNICODE_16: 338b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal setServiceProviderName(new String(spnData, 0, numBytes, "utf-16")); 339e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 340e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: 341e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log("SPN encoding not supported"); 342e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 343e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } catch(Exception e) { 344e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log("spn decode error: " + e); 345e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 346b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal if (DBG) log("spn=" + getServiceProviderName()); 347e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition); 348b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, getServiceProviderName()); 349e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 350e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 351e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 352e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimMdnLoaded implements IccRecordLoaded { 353cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 354e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 355e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_MDN"; 356e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 357e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 358cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 359e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 360e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] data = (byte[]) ar.result; 361e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data)); 362e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Refer to C.S0065 5.2.35 363e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int mdnDigitsNum = 0x0F & data[0]; 364e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum); 365e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM MDN=" + mMdn); 366e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 367e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 368e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 369e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimImsimLoaded implements IccRecordLoaded { 370cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 371e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 372e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_IMSIM"; 373e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 374e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 375cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 376e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 377e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] data = (byte[]) ar.result; 378e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data)); 379e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0065 section 5.2.2 for IMSI_M encoding 380e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0005 section 2.3.1 for MIN encoding in IMSI_M. 381e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka boolean provisioned = ((data[7] & 0x80) == 0x80); 382e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 383e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (provisioned) { 384e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]); 385e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6; 386e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int digit7 = 0x0F & (data[4] >> 2); 387e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (digit7 > 0x09) digit7 = 0; 388e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]); 389e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka first3digits = adjstMinDigits(first3digits); 390e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka second3digits = adjstMinDigits(second3digits); 391e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka last3digits = adjstMinDigits(last3digits); 392e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 393e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka StringBuilder builder = new StringBuilder(); 394e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka builder.append(String.format(Locale.US, "%03d", first3digits)); 395e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka builder.append(String.format(Locale.US, "%03d", second3digits)); 396e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka builder.append(String.format(Locale.US, "%d", digit7)); 397e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka builder.append(String.format(Locale.US, "%03d", last3digits)); 398e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mMin = builder.toString(); 399e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("min present=" + mMin); 400e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 401e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("min not present"); 402e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 403e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 404e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 405e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 406e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimCdmaHomeLoaded implements IccRecordLoaded { 407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 408e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 409e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_CDMAHOME"; 410e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 411e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 412cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 413e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 414e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Per C.S0065 section 5.2.8 415e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result; 416e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size()); 417e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (dataList.isEmpty()) { 418e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return; 419e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 420e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka StringBuilder sidBuf = new StringBuilder(); 421e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka StringBuilder nidBuf = new StringBuilder(); 422e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 423e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (byte[] data : dataList) { 424e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (data.length == 5) { 425e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF); 426e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF); 427e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka sidBuf.append(sid).append(','); 428e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka nidBuf.append(nid).append(','); 429e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 430e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 431e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // remove trailing "," 432e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka sidBuf.setLength(sidBuf.length()-1); 433e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka nidBuf.setLength(nidBuf.length()-1); 434e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 435e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mHomeSystemId = sidBuf.toString(); 436e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mHomeNetworkId = nidBuf.toString(); 437e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 438e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 439e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 440e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimEprlLoaded implements IccRecordLoaded { 441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 442e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 443e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_EPRL"; 444e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 445cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 446e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 447e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka onGetCSimEprlDone(ar); 448e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 449e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 450e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 451e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void onGetCSimEprlDone(AsyncResult ar) { 452e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0065 section 5.2.57 for EFeprl encoding 453e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0016 section 3.5.5 for PRL format. 454e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] data = (byte[]) ar.result; 455e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_EPRL=" + IccUtils.bytesToHexString(data)); 456e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 457e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Only need the first 4 bytes of record 458e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (data.length > 3) { 459e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int prlId = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF); 460e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mPrlVersion = Integer.toString(prlId); 461e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 462e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM PRL version=" + mPrlVersion); 463e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 464e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 4652351b17aba5350004fc76707f3b3d2859ce773c8xinhe private class EfCsimMipUppLoaded implements IccRecordLoaded { 4662351b17aba5350004fc76707f3b3d2859ce773c8xinhe @Override 4672351b17aba5350004fc76707f3b3d2859ce773c8xinhe public String getEfName() { 4682351b17aba5350004fc76707f3b3d2859ce773c8xinhe return "EF_CSIM_MIPUPP"; 4692351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 4702351b17aba5350004fc76707f3b3d2859ce773c8xinhe 4712351b17aba5350004fc76707f3b3d2859ce773c8xinhe boolean checkLengthLegal(int length, int expectLength) { 4722351b17aba5350004fc76707f3b3d2859ce773c8xinhe if(length < expectLength) { 4732351b17aba5350004fc76707f3b3d2859ce773c8xinhe Log.e(LOG_TAG, "CSIM MIPUPP format error, length = " + length + 4742351b17aba5350004fc76707f3b3d2859ce773c8xinhe "expected length at least =" + expectLength); 4752351b17aba5350004fc76707f3b3d2859ce773c8xinhe return false; 4762351b17aba5350004fc76707f3b3d2859ce773c8xinhe } else { 4772351b17aba5350004fc76707f3b3d2859ce773c8xinhe return true; 4782351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 4792351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 4802351b17aba5350004fc76707f3b3d2859ce773c8xinhe 4812351b17aba5350004fc76707f3b3d2859ce773c8xinhe @Override 4822351b17aba5350004fc76707f3b3d2859ce773c8xinhe public void onRecordLoaded(AsyncResult ar) { 4832351b17aba5350004fc76707f3b3d2859ce773c8xinhe // 3GPP2 C.S0065 section 5.2.24 4842351b17aba5350004fc76707f3b3d2859ce773c8xinhe byte[] data = (byte[]) ar.result; 4852351b17aba5350004fc76707f3b3d2859ce773c8xinhe 4862351b17aba5350004fc76707f3b3d2859ce773c8xinhe if(data.length < 1) { 4872351b17aba5350004fc76707f3b3d2859ce773c8xinhe Log.e(LOG_TAG,"MIPUPP read error"); 4882351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 4892351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 4902351b17aba5350004fc76707f3b3d2859ce773c8xinhe 4912351b17aba5350004fc76707f3b3d2859ce773c8xinhe BitwiseInputStream bitStream = new BitwiseInputStream(data); 4922351b17aba5350004fc76707f3b3d2859ce773c8xinhe try { 4932351b17aba5350004fc76707f3b3d2859ce773c8xinhe int mipUppLength = bitStream.read(8); 4942351b17aba5350004fc76707f3b3d2859ce773c8xinhe //transfer length from byte to bit 4952351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength = (mipUppLength << 3); 4962351b17aba5350004fc76707f3b3d2859ce773c8xinhe 4972351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, 1)) { 4982351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 4992351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5002351b17aba5350004fc76707f3b3d2859ce773c8xinhe //parse the MIPUPP body 3GPP2 C.S0016-C 3.5.8.6 5012351b17aba5350004fc76707f3b3d2859ce773c8xinhe int retryInfoInclude = bitStream.read(1); 5022351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength--; 5032351b17aba5350004fc76707f3b3d2859ce773c8xinhe 5042351b17aba5350004fc76707f3b3d2859ce773c8xinhe if(retryInfoInclude == 1) { 5052351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, 11)) { 5062351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5072351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5082351b17aba5350004fc76707f3b3d2859ce773c8xinhe bitStream.skip(11); //not used now 5092351b17aba5350004fc76707f3b3d2859ce773c8xinhe //transfer length from byte to bit 5102351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength -= 11; 5112351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5122351b17aba5350004fc76707f3b3d2859ce773c8xinhe 5132351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, 4)) { 5142351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5152351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5162351b17aba5350004fc76707f3b3d2859ce773c8xinhe int numNai = bitStream.read(4); 5172351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength -= 4; 5182351b17aba5350004fc76707f3b3d2859ce773c8xinhe 5192351b17aba5350004fc76707f3b3d2859ce773c8xinhe //start parse NAI body 5202351b17aba5350004fc76707f3b3d2859ce773c8xinhe for(int index = 0; index < numNai; index++) { 5212351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, 4)) { 5222351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5232351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5242351b17aba5350004fc76707f3b3d2859ce773c8xinhe int naiEntryIndex = bitStream.read(4); 5252351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength -= 4; 5262351b17aba5350004fc76707f3b3d2859ce773c8xinhe 5272351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, 8)) { 5282351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5292351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5302351b17aba5350004fc76707f3b3d2859ce773c8xinhe int naiLength = bitStream.read(8); 5312351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength -= 8; 5322351b17aba5350004fc76707f3b3d2859ce773c8xinhe 5332351b17aba5350004fc76707f3b3d2859ce773c8xinhe if(naiEntryIndex == 0) { 5342351b17aba5350004fc76707f3b3d2859ce773c8xinhe //we find the one! 5352351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, naiLength << 3)) { 5362351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5372351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5382351b17aba5350004fc76707f3b3d2859ce773c8xinhe char naiCharArray[] = new char[naiLength]; 5392351b17aba5350004fc76707f3b3d2859ce773c8xinhe for(int index1 = 0; index1 < naiLength; index1++) { 5402351b17aba5350004fc76707f3b3d2859ce773c8xinhe naiCharArray[index1] = (char)(bitStream.read(8) & 0xFF); 5412351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5422351b17aba5350004fc76707f3b3d2859ce773c8xinhe mNai = new String(naiCharArray); 5432351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; //need not parsing further 5442351b17aba5350004fc76707f3b3d2859ce773c8xinhe } else { 5452351b17aba5350004fc76707f3b3d2859ce773c8xinhe //ignore this NAI body 5462351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, (naiLength << 3) + 102)) { 5472351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5482351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5492351b17aba5350004fc76707f3b3d2859ce773c8xinhe bitStream.skip((naiLength << 3) + 101);//not used 5502351b17aba5350004fc76707f3b3d2859ce773c8xinhe int mnAaaSpiIndicator = bitStream.read(1); 5512351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength -= ((naiLength << 3) + 102); 5522351b17aba5350004fc76707f3b3d2859ce773c8xinhe 5532351b17aba5350004fc76707f3b3d2859ce773c8xinhe if(mnAaaSpiIndicator == 1) { 5542351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, 32)) { 5552351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5562351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5572351b17aba5350004fc76707f3b3d2859ce773c8xinhe bitStream.skip(32); //not used 5582351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength -= 32; 5592351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5602351b17aba5350004fc76707f3b3d2859ce773c8xinhe 5612351b17aba5350004fc76707f3b3d2859ce773c8xinhe //MN-HA_AUTH_ALGORITHM 5622351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, 5)) { 5632351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5642351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5652351b17aba5350004fc76707f3b3d2859ce773c8xinhe bitStream.skip(4); 5662351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength -= 4; 5672351b17aba5350004fc76707f3b3d2859ce773c8xinhe int mnHaSpiIndicator = bitStream.read(1); 5682351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength--; 5692351b17aba5350004fc76707f3b3d2859ce773c8xinhe 5702351b17aba5350004fc76707f3b3d2859ce773c8xinhe if(mnHaSpiIndicator == 1) { 5712351b17aba5350004fc76707f3b3d2859ce773c8xinhe if (!checkLengthLegal(mipUppLength, 32)) { 5722351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5732351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5742351b17aba5350004fc76707f3b3d2859ce773c8xinhe bitStream.skip(32); 5752351b17aba5350004fc76707f3b3d2859ce773c8xinhe mipUppLength -= 32; 5762351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5772351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5782351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5792351b17aba5350004fc76707f3b3d2859ce773c8xinhe } catch(Exception e) { 5802351b17aba5350004fc76707f3b3d2859ce773c8xinhe Log.e(LOG_TAG,"MIPUPP read Exception error!"); 5812351b17aba5350004fc76707f3b3d2859ce773c8xinhe return; 5822351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5832351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5842351b17aba5350004fc76707f3b3d2859ce773c8xinhe } 5852351b17aba5350004fc76707f3b3d2859ce773c8xinhe 586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void handleMessage(Message msg) { 588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville AsyncResult ar; 589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville byte data[]; 591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean isRecordLoadResponse = false; 593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 594bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (mDestroyed.get()) { 595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville loge("Received message " + msg + 596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville "[" + msg.what + "] while being destroyed. Ignoring."); 597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville try { switch (msg.what) { 601e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_APP_READY: 602e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka onReady(); 603e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_DEVICE_IDENTITY_DONE: 606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("Event EVENT_GET_DEVICE_IDENTITY_DONE Received"); 607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /* IO events */ 610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_IMSI_DONE: 611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isRecordLoadResponse = true; 612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville loge("Exception querying IMSI, Exception:" + ar.exception); 616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mImsi = (String) ar.result; 620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more 622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // than 15 (and usually 15). 623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) { 624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville loge("invalid IMSI " + mImsi); 625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mImsi = null; 626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 628f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby // FIXME: CSIM IMSI may not contain the MNC. 629f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby if (false) { 630f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx"); 631f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby 632f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby String operatorNumeric = getRUIMOperatorNumeric(); 633f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby if (operatorNumeric != null) { 634f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby if (operatorNumeric.length() <= 6) { 635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville log("update mccmnc=" + operatorNumeric); 636f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby MccTable.updateMccMncConfiguration(mContext, operatorNumeric, false); 637f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby } 638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 640a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville String operatorNumeric = getRUIMOperatorNumeric(); 641a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville log("NO update mccmnc=" + operatorNumeric); 642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 643f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby 644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_CDMA_SUBSCRIPTION_DONE: 647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String localTemp[] = (String[])ar.result; 649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mMyMobileNumber = localTemp[0]; 654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mMin2Min1 = localTemp[3]; 655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mPrlVersion = localTemp[4]; 656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1); 658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_ICCID_DONE: 662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isRecordLoadResponse = true; 663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville data = (byte[])ar.result; 666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 671b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville mIccId = IccUtils.bcdToString(data, 0, data.length); 672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 673b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville log("iccid: " + mIccId); 674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_UPDATE_DONE: 678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 68099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.i(LOG_TAG, "RuimRecords update failed", ar.exception); 681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_ALL_SMS_DONE: 685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_MARK_SMS_READ_DONE: 686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_SMS_ON_RUIM: 687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_SMS_DONE: 68899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.w(LOG_TAG, "Event not supported: " + msg.what); 689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // TODO: probably EF_CST should be read instead 692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_SST_DONE: 693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("Event EVENT_GET_SST_DONE Received"); 694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_RUIM_REFRESH: 697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isRecordLoadResponse = false; 698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception == null) { 700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handleRuimRefresh((IccRefreshResponse)ar.result); 701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 704e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: 705e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka super.handleMessage(msg); // IccRecords handles generic record load responses 706e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville }}catch (RuntimeException exc) { 708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // I don't want these exceptions to be fatal 70999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.w(LOG_TAG, "Exception parsing RUIM record", exc); 710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } finally { 711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Count up record load responses even if they are fails 712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isRecordLoadResponse) { 713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onRecordLoaded(); 714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 7180cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath /** 7190cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath * Returns an array of languages we have assets for. 7200cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath * 7210cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath * NOTE: This array will have duplicates. If this method will be caused 7220cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath * frequently or in a tight loop, it can be rewritten for efficiency. 7230cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath */ 7240cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath private static String[] getAssetLanguages(Context ctx) { 7250cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath final String[] locales = ctx.getAssets().getLocales(); 7260cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath final String[] localeLangs = new String[locales.length]; 7270cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath for (int i = 0; i < locales.length; ++i) { 7280cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath final String localeStr = locales[i]; 7290cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath final int separator = localeStr.indexOf('-'); 7300cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath if (separator < 0) { 7310cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath localeLangs[i] = localeStr; 7320cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath } else { 7330cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath localeLangs[i] = localeStr.substring(0, separator); 7340cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath } 7350cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath } 7360cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath 7370cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath return localeLangs; 7380cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath } 7390cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath 740e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String findBestLanguage(byte[] languages) { 7410cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath final String[] assetLanguages = getAssetLanguages(mContext); 742e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 7430cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath if ((languages == null) || (assetLanguages == null)) return null; 744e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 745e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Each 2-bytes consists of one language 746e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (int i = 0; (i + 1) < languages.length; i += 2) { 7470cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath final String lang; 748e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka try { 7490cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath lang = new String(languages, i, 2, "ISO-8859-1"); 750e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } catch(java.io.UnsupportedEncodingException e) { 7510cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath log("Failed to parse SIM language records"); 7520cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath continue; 7530cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath } 7540cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath 7550cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath for (int j = 0; j < assetLanguages.length; j++) { 7560cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath if (assetLanguages[j].equals(lang)) { 7570cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath return lang; 7580cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath } 759e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 760e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 7610cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath 762e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // no match found. return null 763e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 764e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 765e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 766e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void setLocaleFromCsim() { 767e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String prefLang = null; 768e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // check EFli then EFpl 769e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka prefLang = findBestLanguage(mEFli); 770e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 771e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (prefLang == null) { 772e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka prefLang = findBestLanguage(mEFpl); 773e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 774e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 775e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (prefLang != null) { 776e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // check country code from SIM 777e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String imsi = getIMSI(); 778e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String country = null; 779e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (imsi != null) { 780e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka country = MccTable.countryCodeForMcc( 781e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Integer.parseInt(imsi.substring(0,3))); 782e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 783e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log("Setting locale to " + prefLang + "_" + country); 784e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka MccTable.setSystemLocale(mContext, prefLang, country); 785e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 786e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log ("No suitable CSIM selected locale"); 787e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 788e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 789e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 790c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 791c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void onRecordLoaded() { 792c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // One record loaded successfully or failed, In either case 793c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // we need to update the recordsToLoad count 79422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad -= 1; 79522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (DBG) log("onRecordLoaded " + mRecordsToLoad + " requested: " + mRecordsRequested); 796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 79722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mRecordsToLoad == 0 && mRecordsRequested == true) { 798c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onAllRecordsLoaded(); 79922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mRecordsToLoad < 0) { 800bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka loge("recordsToLoad <0, programmer error suspected"); 80122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad = 0; 802c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 804c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 806c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void onAllRecordsLoaded() { 807bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (DBG) log("record load complete"); 808bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 809c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Further records that can be inserted are Operator/OEM dependent 810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 811f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby // FIXME: CSIM IMSI may not contain the MNC. 812f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby if (false) { 813f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby String operator = getRUIMOperatorNumeric(); 814f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby if (!TextUtils.isEmpty(operator)) { 815f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby log("onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" + 816f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby operator + "'"); 817a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville log("update icc_operator_numeric=" + operator); 818f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator); 819f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby } else { 820f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby log("onAllRecordsLoaded empty 'gsm.sim.operator.numeric' skipping"); 821f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby } 822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 823f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby if (!TextUtils.isEmpty(mImsi)) { 824f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby log("onAllRecordsLoaded set mcc imsi=" + mImsi); 825f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, 826f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3)))); 827f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby } else { 828f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby log("onAllRecordsLoaded empty imsi skipping setting mcc"); 829f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby } 830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 831e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 832e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka setLocaleFromCsim(); 833b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville mRecordsLoadedRegistrants.notifyRegistrants( 834c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville new AsyncResult(null, null, null)); 835c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 837c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void onReady() { 839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fetchRuimRecords(); 840c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mCi.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); 842c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 843c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 844c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 845c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void fetchRuimRecords() { 84622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsRequested = true; 847c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 84822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (DBG) log("fetchRuimRecords " + mRecordsToLoad); 849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 850e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE)); 85122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 853c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mFh.loadEFTransparent(EF_ICCID, 854c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_GET_ICCID_DONE)); 85522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 856c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 857e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_PL, 858e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded())); 85922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 860e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 861e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_CSIM_LI, 862e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded())); 86322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 864e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 865e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_CSIM_SPN, 866e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimSpnLoaded())); 86722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 868e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 869e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFLinearFixed(EF_CSIM_MDN, 1, 870e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMdnLoaded())); 87122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 872e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 873e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_CSIM_IMSIM, 874e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimImsimLoaded())); 87522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 876e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 877e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME, 878e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimCdmaHomeLoaded())); 87922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 880e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 881e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Entire PRL could be huge. We are only interested in 882e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // the first 4 bytes of the record. 883e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_CSIM_EPRL, 4, 884e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimEprlLoaded())); 88522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mRecordsToLoad++; 886e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 8872351b17aba5350004fc76707f3b3d2859ce773c8xinhe mFh.loadEFTransparent(EF_CSIM_MIPUPP, 8882351b17aba5350004fc76707f3b3d2859ce773c8xinhe obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMipUppLoaded())); 8892351b17aba5350004fc76707f3b3d2859ce773c8xinhe mRecordsToLoad++; 8902351b17aba5350004fc76707f3b3d2859ce773c8xinhe 89122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (DBG) log("fetchRuimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested); 892c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Further records that can be inserted are Operator/OEM dependent 893c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 894c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 895c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 896c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@inheritDoc} 897c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 898c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * No Display rule for RUIMs yet. 899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 900c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 901c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public int getDisplayRule(String plmn) { 902c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // TODO together with spn 903c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return 0; 904c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 905c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 906c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 907e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public boolean isProvisioned() { 908e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // If UICC card has CSIM app, look for MDN and MIN field 909e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // to determine if the SIM is provisioned. Otherwise, 910e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // consider the SIM is provisioned. (for case of ordinal 911e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // USIM only UICC.) 912e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // If PROPERTY_TEST_CSIM is defined, bypess provision check 913e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // and consider the SIM is provisioned. 914e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (SystemProperties.getBoolean(PROPERTY_TEST_CSIM, false)) { 915e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return true; 916e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 917e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 918e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mParentApp == null) { 919e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return false; 920e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 921e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 922e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mParentApp.getType() == AppType.APPTYPE_CSIM && 923e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ((mMdn == null) || (mMin == null))) { 924e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return false; 925e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 926e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return true; 927e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 928e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 929e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka @Override 930c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void setVoiceMessageWaiting(int line, int countWaiting) { 931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (line != 1) { 932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // only profile 1 is supported 933c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 936c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // range check 937c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (countWaiting < 0) { 938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville countWaiting = -1; 939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (countWaiting > 0xff) { 940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // C.S0015-B v2, 4.5.12 941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // range: 0-99 942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville countWaiting = 0xff; 943c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 94422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCountVoiceMessages = countWaiting; 945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mRecordsEventsRegistrants.notifyResult(EVENT_MWI); 947c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 948c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 949c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void handleRuimRefresh(IccRefreshResponse refreshResponse) { 950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (refreshResponse == null) { 951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh received without input"); 952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (refreshResponse.aid != null && 956e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka !refreshResponse.aid.equals(mParentApp.getAid())) { 957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // This is for different app. Ignore. 958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 960c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 961c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (refreshResponse.refreshResult) { 962c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE: 963c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED"); 96422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mAdnCache.reset(); 965c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fetchRuimRecords(); 966c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 967c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case IccRefreshResponse.REFRESH_RESULT_INIT: 968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT"); 969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // need to reload all files (that we care about) 97064bfd98578babdd437f1a83d2d5e1fc92c76e729Alex Yakavenka onIccRefreshInit(); 971c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 972c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case IccRefreshResponse.REFRESH_RESULT_RESET: 973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET"); 974c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal if (requirePowerOffOnSimRefreshReset()) { 975c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal mCi.setRadioPower(false, null); 976c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal /* Note: no need to call setRadioPower(true). Assuming the desired 977c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal * radio power state is still ON (as tracked by ServiceStateTracker), 978c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal * ServiceStateTracker will call setRadioPower when it receives the 979c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal * RADIO_STATE_CHANGED notification for the power off. And if the 980c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal * desired power state has changed in the interim, we don't want to 981c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal * override it with an unconditional power on. 982c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal */ 983c3e37a01b74d28ebf10572bb0811c8a01916d941Shishir Agrawal } 984c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 985c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville default: 986c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // unknown refresh operation 987c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh with unknown operation"); 988c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 989c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 990c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 991c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 992e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getMdn() { 993e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mMdn; 994e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 995e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 996e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getMin() { 997e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mMin; 998e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 999e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 1000e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getSid() { 1001e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mHomeSystemId; 1002e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 1003e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 1004e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getNid() { 1005e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mHomeNetworkId; 1006e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 1007e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 1008e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public boolean getCsimSpnDisplayCondition() { 1009e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mCsimSpnDisplayCondition; 1010e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 1011c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 1012c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void log(String s) { 101399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.d(LOG_TAG, "[RuimRecords] " + s); 1014c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 1015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 1016c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 1017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void loge(String s) { 101899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(LOG_TAG, "[RuimRecords] " + s); 1019c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 102005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka 102105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka @Override 102205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 102305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println("RuimRecords: " + this); 102405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" extends:"); 102505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka super.dump(fd, pw, args); 102622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville pw.println(" mOtaCommited=" + mOtaCommited); 102705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mMyMobileNumber=" + mMyMobileNumber); 102805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mMin2Min1=" + mMin2Min1); 102905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mPrlVersion=" + mPrlVersion); 103005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mEFpl[]=" + Arrays.toString(mEFpl)); 103105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mEFli[]=" + Arrays.toString(mEFli)); 103205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mCsimSpnDisplayCondition=" + mCsimSpnDisplayCondition); 103305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mMdn=" + mMdn); 103405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mMin=" + mMin); 103505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mHomeSystemId=" + mHomeSystemId); 103605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mHomeNetworkId=" + mHomeNetworkId); 103705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.flush(); 103805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 1039c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville} 1040