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