RuimRecords.java revision 64bfd98578babdd437f1a83d2d5e1fc92c76e729
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.Handler; 34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message; 35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Registrant; 36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties; 37ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.CommandsInterface; 40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccCardConstants; 41e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.GsmAlphabet; 42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.PhoneBase; 43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.TelephonyProperties; 44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.MccTable; 45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville// can't be used since VoiceMailConstants is not public 47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville//import com.android.internal.telephony.gsm.VoiceMailConstants; 48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.PhoneProxy; 49e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.cdma.sms.UserData; 50d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/** 54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide} 55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic final class RuimRecords extends IccRecords { 57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville static final String LOG_TAG = "CDMA"; 58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final boolean DBG = true; 60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private boolean m_ota_commited=false; 61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // ***** Instance Variables 63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private String mMyMobileNumber; 65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private String mMin2Min1; 66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private String mPrlVersion; 68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // From CSIM application 69e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private byte[] mEFpl = null; 70e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private byte[] mEFli = null; 71e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka boolean mCsimSpnDisplayCondition = false; 72e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String mMdn; 73e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String mMin; 74e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String mHomeSystemId; 75e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String mHomeNetworkId; 76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // ***** Event Constants 78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_IMSI_DONE = 3; 79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4; 80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_ICCID_DONE = 5; 81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10; 82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_UPDATE_DONE = 14; 83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_SST_DONE = 17; 84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_ALL_SMS_DONE = 18; 85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_MARK_SMS_READ_DONE = 19; 86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_SMS_ON_RUIM = 21; 88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_GET_SMS_DONE = 22; 89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private static final int EVENT_RUIM_REFRESH = 31; 91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 92e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public RuimRecords(UiccCardApplication app, Context c, CommandsInterface ci) { 93e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka super(app, c, ci); 94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville adnCache = new AdnRecordCache(mFh); 96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsRequested = false; // No load request is made till SIM ready 98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // recordsToLoad is set to 0 because no requests are made yet 100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsToLoad = 0; 101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // NOTE the EVENT_SMS_ON_RUIM is not registered 103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mCi.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null); 104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Start off by setting empty state 106e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka resetRecords(); 107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 108e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mParentApp.registerForReady(this, EVENT_APP_READY, null); 109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void dispose() { 113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("Disposing RuimRecords " + this); 114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville //Unregister for all events 115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mCi.unregisterForIccRefresh(this); 116e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mParentApp.unregisterForReady(this); 117e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka resetRecords(); 118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville super.dispose(); 119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void finalize() { 123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if(DBG) log("RuimRecords finalized"); 124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 126e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka protected void resetRecords() { 127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville countVoiceMessages = 0; 128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mncLength = UNINITIALIZED; 129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville iccid = null; 130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville adnCache.reset(); 132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Don't clean up PROPERTY_ICC_OPERATOR_ISO_COUNTRY and 134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // PROPERTY_ICC_OPERATOR_NUMERIC here. Since not all CDMA 135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // devices have RUIM, these properties should keep the original 136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // values, e.g. build time settings, when there is no RUIM but 137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // set new values when RUIM is available and loaded. 138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // recordsRequested is set to false indicating that the SIM 140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // read requests made so far are not valid. This is set to 141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // true only when fresh set of read requests are made. 142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsRequested = false; 143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 145e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka @Override 146e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getIMSI() { 147e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mImsi; 148e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 149e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String getMdnNumber() { 151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mMyMobileNumber; 152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String getCdmaMin() { 155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mMin2Min1; 156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** Returns null if RUIM is not yet ready */ 159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String getPrlVersion() { 160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mPrlVersion; 161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){ 165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // In CDMA this is Operator/OEM dependent 166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville AsyncResult.forMessage((onComplete)).exception = 167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville new IccException("setVoiceMailNumber not implemented"); 168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onComplete.sendToTarget(); 169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville loge("method setVoiceMailNumber is not implemented"); 170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Called by CCAT Service when REFRESH is received. 174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param fileChanged indicates whether any files changed 175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * @param fileList if non-null, a list of EF files that changed 176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void onRefresh(boolean fileChanged, int[] fileList) { 179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (fileChanged) { 180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // A future optimization would be to inspect fileList and 181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // only reload those files that we care about. For now, 182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // just re-fetch all RUIM records that we cache. 183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fetchRuimRecords(); 184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 187e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private int adjstMinDigits (int digits) { 188e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Per C.S0005 section 2.3.1. 189e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka digits += 111; 190e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka digits = (digits % 10 == 0)?(digits - 10):digits; 191e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka digits = ((digits / 10) % 10 == 0)?(digits - 100):digits; 192e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka digits = ((digits / 100) % 10 == 0)?(digits - 1000):digits; 193e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return digits; 194e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 195e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Returns the 5 or 6 digit MCC/MNC of the operator that 198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * provided the RUIM card. Returns null of RUIM is not yet ready 199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public String getRUIMOperatorNumeric() { 201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (mImsi == null) { 202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return null; 203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (mncLength != UNINITIALIZED && mncLength != UNKNOWN) { 206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Length = length of MCC + length of MNC 207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3) 208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mImsi.substring(0, 3 + mncLength); 209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Guess the MNC length based on the MCC if we don't 212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // have a valid value in ef[ad] 213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville int mcc = Integer.parseInt(mImsi.substring(0,3)); 215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc)); 216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 218e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Refer to ETSI TS 102.221 219e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfPlLoaded implements IccRecordLoaded { 220e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 221e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_PL"; 222e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 223e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 224e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 225e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mEFpl = (byte[]) ar.result; 226e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl)); 227e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 228e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 229e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 230e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Refer to C.S0065 5.2.26 231e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimLiLoaded implements IccRecordLoaded { 232e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 233e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_LI"; 234e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 235e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 236e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 237e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mEFli = (byte[]) ar.result; 238e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // convert csim efli data to iso 639 format 239e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (int i = 0; i < mEFli.length; i+=2) { 240e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch(mEFli[i+1]) { 241e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x01: mEFli[i] = 'e'; mEFli[i+1] = 'n';break; 242e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x02: mEFli[i] = 'f'; mEFli[i+1] = 'r';break; 243e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x03: mEFli[i] = 'e'; mEFli[i+1] = 's';break; 244e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x04: mEFli[i] = 'j'; mEFli[i+1] = 'a';break; 245e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x05: mEFli[i] = 'k'; mEFli[i+1] = 'o';break; 246e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x06: mEFli[i] = 'z'; mEFli[i+1] = 'h';break; 247e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case 0x07: mEFli[i] = 'h'; mEFli[i+1] = 'e';break; 248e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: mEFli[i] = ' '; mEFli[i+1] = ' '; 249e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 250e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 251e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 252e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli)); 253e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 254e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 255e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 256e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Refer to C.S0065 5.2.32 257e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimSpnLoaded implements IccRecordLoaded { 258e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 259e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_SPN"; 260e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 261e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 262e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 263e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] data = (byte[]) ar.result; 264e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_SPN=" + 265e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka IccUtils.bytesToHexString(data)); 266e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 267e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0065 for EF_SPN decoding 268e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0); 269e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 270e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int encoding = data[1]; 271e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int language = data[2]; 272e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] spnData = new byte[32]; 273e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int len = ((data.length - 3) < 32) ? (data.length - 3) : 32; 274e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka System.arraycopy(data, 3, spnData, 0, len); 275e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 276e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int numBytes; 277e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (numBytes = 0; numBytes < spnData.length; numBytes++) { 278e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if ((spnData[numBytes] & 0xFF) == 0xFF) break; 279e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 280e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 281e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (numBytes == 0) { 282e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka spn = ""; 283e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return; 284e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 285e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka try { 286e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka switch (encoding) { 287e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_OCTET: 288e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_LATIN: 289e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka spn = new String(spnData, 0, numBytes, "ISO-8859-1"); 290e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 291e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_IA5: 292e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_GSM_7BIT_ALPHABET: 293e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_7BIT_ASCII: 294e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka spn = GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes*8)/7); 295e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 296e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case UserData.ENCODING_UNICODE_16: 297e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka spn = new String(spnData, 0, numBytes, "utf-16"); 298e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 299e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: 300e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log("SPN encoding not supported"); 301e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 302e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } catch(Exception e) { 303e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log("spn decode error: " + e); 304e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 305e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("spn=" + spn); 306e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition); 307e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn); 308e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 309e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 310e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 311e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimMdnLoaded implements IccRecordLoaded { 312e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 313e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_MDN"; 314e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 315e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 316e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 317e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] data = (byte[]) ar.result; 318e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data)); 319e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Refer to C.S0065 5.2.35 320e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int mdnDigitsNum = 0x0F & data[0]; 321e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum); 322e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM MDN=" + mMdn); 323e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 324e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 325e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 326e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimImsimLoaded implements IccRecordLoaded { 327e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 328e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_IMSIM"; 329e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 330e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 331e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 332e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] data = (byte[]) ar.result; 333e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data)); 334e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0065 section 5.2.2 for IMSI_M encoding 335e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0005 section 2.3.1 for MIN encoding in IMSI_M. 336e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka boolean provisioned = ((data[7] & 0x80) == 0x80); 337e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 338e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (provisioned) { 339e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]); 340e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6; 341e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int digit7 = 0x0F & (data[4] >> 2); 342e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (digit7 > 0x09) digit7 = 0; 343e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]); 344e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka first3digits = adjstMinDigits(first3digits); 345e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka second3digits = adjstMinDigits(second3digits); 346e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka last3digits = adjstMinDigits(last3digits); 347e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 348e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka StringBuilder builder = new StringBuilder(); 349e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka builder.append(String.format(Locale.US, "%03d", first3digits)); 350e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka builder.append(String.format(Locale.US, "%03d", second3digits)); 351e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka builder.append(String.format(Locale.US, "%d", digit7)); 352e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka builder.append(String.format(Locale.US, "%03d", last3digits)); 353e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mMin = builder.toString(); 354e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("min present=" + mMin); 355e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 356e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("min not present"); 357e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 358e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 359e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 360e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 361e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimCdmaHomeLoaded implements IccRecordLoaded { 362e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 363e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_CDMAHOME"; 364e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 365e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 366e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 367e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Per C.S0065 section 5.2.8 368e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result; 369e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size()); 370e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (dataList.isEmpty()) { 371e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return; 372e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 373e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka StringBuilder sidBuf = new StringBuilder(); 374e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka StringBuilder nidBuf = new StringBuilder(); 375e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 376e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (byte[] data : dataList) { 377e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (data.length == 5) { 378e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF); 379e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF); 380e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka sidBuf.append(sid).append(','); 381e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka nidBuf.append(nid).append(','); 382e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 383e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 384e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // remove trailing "," 385e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka sidBuf.setLength(sidBuf.length()-1); 386e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka nidBuf.setLength(nidBuf.length()-1); 387e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 388e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mHomeSystemId = sidBuf.toString(); 389e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mHomeNetworkId = nidBuf.toString(); 390e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 391e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 392e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 393e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private class EfCsimEprlLoaded implements IccRecordLoaded { 394e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getEfName() { 395e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return "EF_CSIM_EPRL"; 396e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 397e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public void onRecordLoaded(AsyncResult ar) { 398e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka onGetCSimEprlDone(ar); 399e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 400e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 401e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 402e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void onGetCSimEprlDone(AsyncResult ar) { 403e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0065 section 5.2.57 for EFeprl encoding 404e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // C.S0016 section 3.5.5 for PRL format. 405e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka byte[] data = (byte[]) ar.result; 406e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM_EPRL=" + IccUtils.bytesToHexString(data)); 407e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 408e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Only need the first 4 bytes of record 409e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (data.length > 3) { 410e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka int prlId = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF); 411e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mPrlVersion = Integer.toString(prlId); 412e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 413e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (DBG) log("CSIM PRL version=" + mPrlVersion); 414e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 415e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void handleMessage(Message msg) { 418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville AsyncResult ar; 419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville byte data[]; 421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville boolean isRecordLoadResponse = false; 423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 424bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (mDestroyed.get()) { 425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville loge("Received message " + msg + 426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville "[" + msg.what + "] while being destroyed. Ignoring."); 427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville try { switch (msg.what) { 431e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka case EVENT_APP_READY: 432e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka onReady(); 433e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka break; 434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_DEVICE_IDENTITY_DONE: 436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("Event EVENT_GET_DEVICE_IDENTITY_DONE Received"); 437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /* IO events */ 440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_IMSI_DONE: 441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isRecordLoadResponse = true; 442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville loge("Exception querying IMSI, Exception:" + ar.exception); 446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mImsi = (String) ar.result; 450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more 452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // than 15 (and usually 15). 453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) { 454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville loge("invalid IMSI " + mImsi); 455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mImsi = null; 456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx"); 459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String operatorNumeric = getRUIMOperatorNumeric(); 461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (operatorNumeric != null) { 462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if(operatorNumeric.length() <= 6){ 463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville MccTable.updateMccMncConfiguration(mContext, operatorNumeric); 464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_CDMA_SUBSCRIPTION_DONE: 469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String localTemp[] = (String[])ar.result; 471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mMyMobileNumber = localTemp[0]; 476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mMin2Min1 = localTemp[3]; 477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mPrlVersion = localTemp[4]; 478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1); 480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_ICCID_DONE: 484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isRecordLoadResponse = true; 485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville data = (byte[])ar.result; 488c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 489c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville iccid = IccUtils.bcdToString(data, 0, data.length); 494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("iccid: " + iccid); 496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_UPDATE_DONE: 500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception != null) { 502ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.i(LOG_TAG, "RuimRecords update failed", ar.exception); 503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_ALL_SMS_DONE: 507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_MARK_SMS_READ_DONE: 508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_SMS_ON_RUIM: 509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_SMS_DONE: 510ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "Event not supported: " + msg.what); 511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // TODO: probably EF_CST should be read instead 514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_GET_SST_DONE: 515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("Event EVENT_GET_SST_DONE Received"); 516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case EVENT_RUIM_REFRESH: 519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville isRecordLoadResponse = false; 520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville ar = (AsyncResult)msg.obj; 521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (ar.exception == null) { 522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville handleRuimRefresh((IccRefreshResponse)ar.result); 523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 526e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka default: 527e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka super.handleMessage(msg); // IccRecords handles generic record load responses 528e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville }}catch (RuntimeException exc) { 530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // I don't want these exceptions to be fatal 531ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "Exception parsing RUIM record", exc); 532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } finally { 533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Count up record load responses even if they are fails 534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (isRecordLoadResponse) { 535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onRecordLoaded(); 536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 540e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private String findBestLanguage(byte[] languages) { 541e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String bestMatch = null; 542e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String[] locales = mContext.getAssets().getLocales(); 543e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 544e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if ((languages == null) || (locales == null)) return null; 545e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 546e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Each 2-bytes consists of one language 547e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (int i = 0; (i + 1) < languages.length; i += 2) { 548e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka try { 549e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String lang = new String(languages, i, 2, "ISO-8859-1"); 550e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka for (int j = 0; j < locales.length; j++) { 551e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (locales[j] != null && locales[j].length() >= 2 && 552e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka locales[j].substring(0, 2).equals(lang)) { 553e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return lang; 554e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 555e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 556e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (bestMatch != null) break; 557e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } catch(java.io.UnsupportedEncodingException e) { 558e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log ("Failed to parse SIM language records"); 559e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 560e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 561e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // no match found. return null 562e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return null; 563e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 564e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 565e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private void setLocaleFromCsim() { 566e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String prefLang = null; 567e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // check EFli then EFpl 568e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka prefLang = findBestLanguage(mEFli); 569e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 570e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (prefLang == null) { 571e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka prefLang = findBestLanguage(mEFpl); 572e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 573e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 574e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (prefLang != null) { 575e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // check country code from SIM 576e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String imsi = getIMSI(); 577e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka String country = null; 578e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (imsi != null) { 579e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka country = MccTable.countryCodeForMcc( 580e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Integer.parseInt(imsi.substring(0,3))); 581e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 582e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log("Setting locale to " + prefLang + "_" + country); 583e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka MccTable.setSystemLocale(mContext, prefLang, country); 584e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } else { 585e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka log ("No suitable CSIM selected locale"); 586e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 587e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 588e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void onRecordLoaded() { 591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // One record loaded successfully or failed, In either case 592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // we need to update the recordsToLoad count 593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsToLoad -= 1; 594bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (DBG) log("onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested); 595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (recordsToLoad == 0 && recordsRequested == true) { 597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville onAllRecordsLoaded(); 598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (recordsToLoad < 0) { 599bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka loge("recordsToLoad <0, programmer error suspected"); 600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsToLoad = 0; 601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void onAllRecordsLoaded() { 606bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (DBG) log("record load complete"); 607bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka 608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Further records that can be inserted are Operator/OEM dependent 609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville String operator = getRUIMOperatorNumeric(); 611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville log("RuimRecords: onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" + 612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville operator + "'"); 613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator); 614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (mImsi != null) { 616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, 617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3)))); 618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 619e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 620e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka setLocaleFromCsim(); 621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsLoadedRegistrants.notifyRegistrants( 622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville new AsyncResult(null, null, null)); 623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void onReady() { 627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fetchRuimRecords(); 628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mCi.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE)); 630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void fetchRuimRecords() { 634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsRequested = true; 635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 636bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (DBG) log("fetchRuimRecords " + recordsToLoad); 637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 638e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE)); 639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsToLoad++; 640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mFh.loadEFTransparent(EF_ICCID, 642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville obtainMessage(EVENT_GET_ICCID_DONE)); 643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville recordsToLoad++; 644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 645e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_PL, 646e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded())); 647e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka recordsToLoad++; 648e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 649e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_CSIM_LI, 650e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded())); 651e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka recordsToLoad++; 652e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 653e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_CSIM_SPN, 654e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimSpnLoaded())); 655e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka recordsToLoad++; 656e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 657e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFLinearFixed(EF_CSIM_MDN, 1, 658e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMdnLoaded())); 659e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka recordsToLoad++; 660e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 661e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_CSIM_IMSIM, 662e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimImsimLoaded())); 663e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka recordsToLoad++; 664e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 665e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME, 666e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimCdmaHomeLoaded())); 667e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka recordsToLoad++; 668e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 669e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // Entire PRL could be huge. We are only interested in 670e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // the first 4 bytes of the record. 671e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mFh.loadEFTransparent(EF_CSIM_EPRL, 4, 672e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimEprlLoaded())); 673e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka recordsToLoad++; 674e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 675bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka if (DBG) log("fetchRuimRecords " + recordsToLoad + " requested: " + recordsRequested); 676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // Further records that can be inserted are Operator/OEM dependent 677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /** 680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@inheritDoc} 681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * 682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * No Display rule for RUIMs yet. 683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public int getDisplayRule(String plmn) { 686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // TODO together with spn 687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return 0; 688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 691e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public boolean isProvisioned() { 692e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // If UICC card has CSIM app, look for MDN and MIN field 693e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // to determine if the SIM is provisioned. Otherwise, 694e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // consider the SIM is provisioned. (for case of ordinal 695e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // USIM only UICC.) 696e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // If PROPERTY_TEST_CSIM is defined, bypess provision check 697e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka // and consider the SIM is provisioned. 698e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (SystemProperties.getBoolean(PROPERTY_TEST_CSIM, false)) { 699e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return true; 700e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 701e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 702e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mParentApp == null) { 703e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return false; 704e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 705e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 706e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mParentApp.getType() == AppType.APPTYPE_CSIM && 707e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ((mMdn == null) || (mMin == null))) { 708e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return false; 709e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 710e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return true; 711e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 712e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 713e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka @Override 714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville public void setVoiceMessageWaiting(int line, int countWaiting) { 715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (line != 1) { 716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // only profile 1 is supported 717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // range check 721c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (countWaiting < 0) { 722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville countWaiting = -1; 723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } else if (countWaiting > 0xff) { 724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // C.S0015-B v2, 4.5.12 725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // range: 0-99 726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville countWaiting = 0xff; 727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville countVoiceMessages = countWaiting; 729c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mRecordsEventsRegistrants.notifyResult(EVENT_MWI); 731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 733c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville private void handleRuimRefresh(IccRefreshResponse refreshResponse) { 734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (refreshResponse == null) { 735c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh received without input"); 736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 737c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (refreshResponse.aid != null && 740e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka !refreshResponse.aid.equals(mParentApp.getAid())) { 741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // This is for different app. Ignore. 742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville return; 743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 745c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville switch (refreshResponse.refreshResult) { 746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE: 747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED"); 748c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville adnCache.reset(); 749c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville fetchRuimRecords(); 750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case IccRefreshResponse.REFRESH_RESULT_INIT: 752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT"); 753c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // need to reload all files (that we care about) 75464bfd98578babdd437f1a83d2d5e1fc92c76e729Alex Yakavenka onIccRefreshInit(); 755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville case IccRefreshResponse.REFRESH_RESULT_RESET: 757c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET"); 758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville mCi.setRadioPower(false, null); 759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville /* Note: no need to call setRadioPower(true). Assuming the desired 760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * radio power state is still ON (as tracked by ServiceStateTracker), 761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * ServiceStateTracker will call setRadioPower when it receives the 762c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * RADIO_STATE_CHANGED notification for the power off. And if the 763c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * desired power state has changed in the interim, we don't want to 764c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * override it with an unconditional power on. 765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */ 766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville default: 768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville // unknown refresh operation 769c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville if (DBG) log("handleRuimRefresh with unknown operation"); 770c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville break; 771c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 774e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getMdn() { 775e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mMdn; 776e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 777e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 778e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getMin() { 779e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mMin; 780e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 781e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 782e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getSid() { 783e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mHomeSystemId; 784e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 785e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 786e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public String getNid() { 787e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mHomeNetworkId; 788e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 789e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 790e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public boolean getCsimSpnDisplayCondition() { 791e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return mCsimSpnDisplayCondition; 792e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 793c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void log(String s) { 795ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "[RuimRecords] " + s); 796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 797c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville 798c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville @Override 799c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville protected void loge(String s) { 800ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "[RuimRecords] " + s); 801c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville } 80205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka 80305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka @Override 80405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 80505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println("RuimRecords: " + this); 80605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" extends:"); 80705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka super.dump(fd, pw, args); 80805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" m_ota_commited=" + m_ota_commited); 80905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mMyMobileNumber=" + mMyMobileNumber); 81005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mMin2Min1=" + mMin2Min1); 81105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mPrlVersion=" + mPrlVersion); 81205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mEFpl[]=" + Arrays.toString(mEFpl)); 81305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mEFli[]=" + Arrays.toString(mEFli)); 81405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mCsimSpnDisplayCondition=" + mCsimSpnDisplayCondition); 81505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mMdn=" + mMdn); 81605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mMin=" + mMin); 81705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mHomeSystemId=" + mHomeSystemId); 81805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.println(" mHomeNetworkId=" + mHomeNetworkId); 81905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka pw.flush(); 82005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka } 821c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville} 822