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