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 Yakavenkaimport static com.android.internal.telephony.TelephonyProperties.PROPERTY_TEST_CSIM;
20e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
2105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.FileDescriptor;
2205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.PrintWriter;
23e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport java.util.ArrayList;
2405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.util.Arrays;
25e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport java.util.Locale;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
305866914ae9798adebcb84cd710bca660b797bff0Amit Mahajanimport android.telephony.SubscriptionManager;
3199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
32e9070e6d48d1389987650fa2c3e1f90aab860684Wink Savilleimport android.text.TextUtils;
332351b17aba5350004fc76707f3b3d2859ce773c8xinheimport android.util.Log;
34e409b02a691d5bb0515aab41cfa597c725eb9174duho.roimport android.content.res.Resources;
35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.CommandsInterface;
37e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.GsmAlphabet;
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.MccTable;
39062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawalimport com.android.internal.telephony.SubscriptionController;
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
41e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.cdma.sms.UserData;
42d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
432351b17aba5350004fc76707f3b3d2859ce773c8xinheimport com.android.internal.util.BitwiseInputStream;
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;
672351b17aba5350004fc76707f3b3d2859ce773c8xinhe    private String mNai;
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
69f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
70f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    public String toString() {
71f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return "RuimRecords: " + super.toString()
7222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " m_ota_commited" + mOtaCommited
73f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mMyMobileNumber=" + "xxxx"
74f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mMin2Min1=" + mMin2Min1
75f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mPrlVersion=" + mPrlVersion
76f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mEFpl=" + mEFpl
77f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mEFli=" + mEFli
78f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mCsimSpnDisplayCondition=" + mCsimSpnDisplayCondition
79f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mMdn=" + mMdn
80f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mMin=" + mMin
81f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mHomeSystemId=" + mHomeSystemId
82f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mHomeNetworkId=" + mHomeNetworkId;
83f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    }
84f92cb4bd5519427a0db673709d94683a8baf203aWink Saville
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Event Constants
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        mMncLength = UNINITIALIZED;
137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("setting0 mMncLength" + mMncLength);
138b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville        mIccId = 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
1732351b17aba5350004fc76707f3b3d2859ce773c8xinhe    /** Returns null if RUIM is not yet ready */
1742351b17aba5350004fc76707f3b3d2859ce773c8xinhe    public String getNAI() {
1752351b17aba5350004fc76707f3b3d2859ce773c8xinhe        return mNai;
1762351b17aba5350004fc76707f3b3d2859ce773c8xinhe    }
1772351b17aba5350004fc76707f3b3d2859ce773c8xinhe
1782351b17aba5350004fc76707f3b3d2859ce773c8xinhe    @Override
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // In CDMA this is Operator/OEM dependent
181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AsyncResult.forMessage((onComplete)).exception =
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                new IccException("setVoiceMailNumber not implemented");
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        onComplete.sendToTarget();
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        loge("method setVoiceMailNumber is not implemented");
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Called by CCAT Service when REFRESH is received.
189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param fileChanged indicates whether any files changed
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param fileList if non-null, a list of EF files that changed
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void onRefresh(boolean fileChanged, int[] fileList) {
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (fileChanged) {
195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // A future optimization would be to inspect fileList and
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // only reload those files that we care about.  For now,
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // just re-fetch all RUIM records that we cache.
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            fetchRuimRecords();
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
202e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private int adjstMinDigits (int digits) {
203e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // Per C.S0005 section 2.3.1.
204e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        digits += 111;
205e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        digits = (digits % 10 == 0)?(digits - 10):digits;
206e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        digits = ((digits / 10) % 10 == 0)?(digits - 100):digits;
207e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        digits = ((digits / 100) % 10 == 0)?(digits - 1000):digits;
208e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return digits;
209e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
210e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Returns the 5 or 6 digit MCC/MNC of the operator that
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  provided the RUIM card. Returns null of RUIM is not yet ready
214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getRUIMOperatorNumeric() {
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mImsi == null) {
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return null;
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
22022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mMncLength != UNINITIALIZED && mMncLength != UNKNOWN) {
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Length = length of MCC + length of MNC
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3)
22322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return mImsi.substring(0, 3 + mMncLength);
224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Guess the MNC length based on the MCC if we don't
227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // have a valid value in ef[ad]
228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int mcc = Integer.parseInt(mImsi.substring(0,3));
230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
233e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    // Refer to ETSI TS 102.221
234e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private class EfPlLoaded implements IccRecordLoaded {
235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
236e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public String getEfName() {
237e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return "EF_PL";
238e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
239e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
240cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
241e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public void onRecordLoaded(AsyncResult ar) {
242e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mEFpl = (byte[]) ar.result;
243e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl));
244e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
245e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
246e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
247e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    // Refer to C.S0065 5.2.26
248e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private class EfCsimLiLoaded implements IccRecordLoaded {
249cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
250e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public String getEfName() {
251e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return "EF_CSIM_LI";
252e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
253e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
254cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
255e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public void onRecordLoaded(AsyncResult ar) {
256e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mEFli = (byte[]) ar.result;
257e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            // convert csim efli data to iso 639 format
258e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            for (int i = 0; i < mEFli.length; i+=2) {
259e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                switch(mEFli[i+1]) {
260e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case 0x01: mEFli[i] = 'e'; mEFli[i+1] = 'n';break;
261e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case 0x02: mEFli[i] = 'f'; mEFli[i+1] = 'r';break;
262e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case 0x03: mEFli[i] = 'e'; mEFli[i+1] = 's';break;
263e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case 0x04: mEFli[i] = 'j'; mEFli[i+1] = 'a';break;
264e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case 0x05: mEFli[i] = 'k'; mEFli[i+1] = 'o';break;
265e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case 0x06: mEFli[i] = 'z'; mEFli[i+1] = 'h';break;
266e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case 0x07: mEFli[i] = 'h'; mEFli[i+1] = 'e';break;
267e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                default: mEFli[i] = ' '; mEFli[i+1] = ' ';
268e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                }
269e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
270e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
271e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli));
272e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
273e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
274e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
275e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    // Refer to C.S0065 5.2.32
276e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private class EfCsimSpnLoaded implements IccRecordLoaded {
277cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
278e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public String getEfName() {
279e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return "EF_CSIM_SPN";
280e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
281e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
282cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
283e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public void onRecordLoaded(AsyncResult ar) {
284e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            byte[] data = (byte[]) ar.result;
285e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) log("CSIM_SPN=" +
286e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                         IccUtils.bytesToHexString(data));
287e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
288e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            // C.S0065 for EF_SPN decoding
289e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0);
290e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
291e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            int encoding = data[1];
292e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            int language = data[2];
293e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            byte[] spnData = new byte[32];
294e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            int len = ((data.length - 3) < 32) ? (data.length - 3) : 32;
295e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            System.arraycopy(data, 3, spnData, 0, len);
296e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
297e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            int numBytes;
298e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            for (numBytes = 0; numBytes < spnData.length; numBytes++) {
299e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if ((spnData[numBytes] & 0xFF) == 0xFF) break;
300e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
301e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
302e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (numBytes == 0) {
303b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                setServiceProviderName("");
304e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
305e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
306e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            try {
307e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                switch (encoding) {
308e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case UserData.ENCODING_OCTET:
309e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case UserData.ENCODING_LATIN:
310b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setServiceProviderName(new String(spnData, 0, numBytes, "ISO-8859-1"));
311e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    break;
312e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case UserData.ENCODING_IA5:
313e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case UserData.ENCODING_GSM_7BIT_ALPHABET:
314b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setServiceProviderName(
315b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                            GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes*8)/7));
316e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    break;
31760e3a52dad667a094af0c269176ee30da739ee84Sandeep Gutta                case UserData.ENCODING_7BIT_ASCII:
318b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    String spn = new String(spnData, 0, numBytes, "US-ASCII");
319b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    // To address issues with incorrect encoding scheme
320b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    // programmed in some commercial CSIM cards, the decoded
321b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    // SPN is checked to have characters in printable ASCII
322b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    // range. If not, they are decoded with
323b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    // ENCODING_GSM_7BIT_ALPHABET scheme.
324b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    if (TextUtils.isPrintableAsciiOnly(spn)) {
325b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                        setServiceProviderName(spn);
326b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    } else {
327b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                        if (DBG) log("Some corruption in SPN decoding = " + spn);
328b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                        if (DBG) log("Using ENCODING_GSM_7BIT_ALPHABET scheme...");
329b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                        setServiceProviderName(
330b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                                GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes * 8) / 7));
331b5d27d8e567ef835e961548b144cdad95d2361deJing Zhao                    }
33260e3a52dad667a094af0c269176ee30da739ee84Sandeep Gutta                break;
333e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                case UserData.ENCODING_UNICODE_16:
334b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setServiceProviderName(new String(spnData, 0, numBytes, "utf-16"));
335e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    break;
336e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                default:
337e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    log("SPN encoding not supported");
338e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                }
339e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } catch(Exception e) {
340e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                log("spn decode error: " + e);
341e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
342b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal            if (DBG) log("spn=" + getServiceProviderName());
343e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition);
344e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu            mTelephonyManager.setSimOperatorNameForPhone(
345e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                    mParentApp.getPhoneId(), getServiceProviderName());
346e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
347e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
348e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
349e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private class EfCsimMdnLoaded implements IccRecordLoaded {
350cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
351e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public String getEfName() {
352e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return "EF_CSIM_MDN";
353e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
354e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
355cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
356e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public void onRecordLoaded(AsyncResult ar) {
357e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            byte[] data = (byte[]) ar.result;
358e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data));
359e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            // Refer to C.S0065 5.2.35
360e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            int mdnDigitsNum = 0x0F & data[0];
361e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum);
362e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) log("CSIM MDN=" + mMdn);
363e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
364e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
365e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
366e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private class EfCsimImsimLoaded implements IccRecordLoaded {
367cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
368e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public String getEfName() {
369e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return "EF_CSIM_IMSIM";
370e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
371e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
373e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public void onRecordLoaded(AsyncResult ar) {
374e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            byte[] data = (byte[]) ar.result;
375f9f73e5f5125df262b8c2bec21de5600dc4d1801Etan Cohen            if (VDBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data));
376e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            // C.S0065 section 5.2.2 for IMSI_M encoding
377e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            // C.S0005 section 2.3.1 for MIN encoding in IMSI_M.
378e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            boolean provisioned = ((data[7] & 0x80) == 0x80);
379e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
380e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (provisioned) {
381e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]);
382e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6;
383e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                int digit7 = 0x0F & (data[4] >> 2);
384e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (digit7 > 0x09) digit7 = 0;
385e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]);
386e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                first3digits = adjstMinDigits(first3digits);
387e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                second3digits = adjstMinDigits(second3digits);
388e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                last3digits = adjstMinDigits(last3digits);
389e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
390e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                StringBuilder builder = new StringBuilder();
391e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                builder.append(String.format(Locale.US, "%03d", first3digits));
392e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                builder.append(String.format(Locale.US, "%03d", second3digits));
393e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                builder.append(String.format(Locale.US, "%d", digit7));
394e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                builder.append(String.format(Locale.US, "%03d", last3digits));
395e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mMin = builder.toString();
396e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (DBG) log("min present=" + mMin);
397e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            } else {
398e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (DBG) log("min not present");
399e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
400e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
401e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
402e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
403e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private class EfCsimCdmaHomeLoaded implements IccRecordLoaded {
404cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
405e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public String getEfName() {
406e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return "EF_CSIM_CDMAHOME";
407e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
408e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
410e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public void onRecordLoaded(AsyncResult ar) {
411e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            // Per C.S0065 section 5.2.8
412e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result;
413e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size());
414e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            if (dataList.isEmpty()) {
415e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                return;
416e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
417e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            StringBuilder sidBuf = new StringBuilder();
418e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            StringBuilder nidBuf = new StringBuilder();
419e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
420e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            for (byte[] data : dataList) {
421e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (data.length == 5) {
422e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
423e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
424e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    sidBuf.append(sid).append(',');
425e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    nidBuf.append(nid).append(',');
426e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                }
427e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            }
428e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            // remove trailing ","
429e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            sidBuf.setLength(sidBuf.length()-1);
430e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            nidBuf.setLength(nidBuf.length()-1);
431e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
432e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mHomeSystemId = sidBuf.toString();
433e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mHomeNetworkId = nidBuf.toString();
434e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
435e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
436e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
437e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private class EfCsimEprlLoaded implements IccRecordLoaded {
438cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
439e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public String getEfName() {
440e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return "EF_CSIM_EPRL";
441e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
442cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
443e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        public void onRecordLoaded(AsyncResult ar) {
444e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            onGetCSimEprlDone(ar);
445e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
446e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
447e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
448e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private void onGetCSimEprlDone(AsyncResult ar) {
449e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // C.S0065 section 5.2.57 for EFeprl encoding
450e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // C.S0016 section 3.5.5 for PRL format.
451e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        byte[] data = (byte[]) ar.result;
452e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (DBG) log("CSIM_EPRL=" + IccUtils.bytesToHexString(data));
453e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
454e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // Only need the first 4 bytes of record
455e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (data.length > 3) {
456e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            int prlId = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
457e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            mPrlVersion = Integer.toString(prlId);
458e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
459e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (DBG) log("CSIM PRL version=" + mPrlVersion);
460e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
461e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
4622351b17aba5350004fc76707f3b3d2859ce773c8xinhe    private class EfCsimMipUppLoaded implements IccRecordLoaded {
4632351b17aba5350004fc76707f3b3d2859ce773c8xinhe        @Override
4642351b17aba5350004fc76707f3b3d2859ce773c8xinhe        public String getEfName() {
4652351b17aba5350004fc76707f3b3d2859ce773c8xinhe            return "EF_CSIM_MIPUPP";
4662351b17aba5350004fc76707f3b3d2859ce773c8xinhe        }
4672351b17aba5350004fc76707f3b3d2859ce773c8xinhe
4682351b17aba5350004fc76707f3b3d2859ce773c8xinhe        boolean checkLengthLegal(int length, int expectLength) {
4692351b17aba5350004fc76707f3b3d2859ce773c8xinhe            if(length < expectLength) {
4702351b17aba5350004fc76707f3b3d2859ce773c8xinhe                Log.e(LOG_TAG, "CSIM MIPUPP format error, length = " + length  +
4712351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        "expected length at least =" + expectLength);
4722351b17aba5350004fc76707f3b3d2859ce773c8xinhe                return false;
4732351b17aba5350004fc76707f3b3d2859ce773c8xinhe            } else {
4742351b17aba5350004fc76707f3b3d2859ce773c8xinhe                return true;
4752351b17aba5350004fc76707f3b3d2859ce773c8xinhe            }
4762351b17aba5350004fc76707f3b3d2859ce773c8xinhe        }
4772351b17aba5350004fc76707f3b3d2859ce773c8xinhe
4782351b17aba5350004fc76707f3b3d2859ce773c8xinhe        @Override
4792351b17aba5350004fc76707f3b3d2859ce773c8xinhe        public void onRecordLoaded(AsyncResult ar) {
4802351b17aba5350004fc76707f3b3d2859ce773c8xinhe            // 3GPP2 C.S0065 section 5.2.24
4812351b17aba5350004fc76707f3b3d2859ce773c8xinhe            byte[] data = (byte[]) ar.result;
4822351b17aba5350004fc76707f3b3d2859ce773c8xinhe
4832351b17aba5350004fc76707f3b3d2859ce773c8xinhe            if(data.length < 1) {
4842351b17aba5350004fc76707f3b3d2859ce773c8xinhe                Log.e(LOG_TAG,"MIPUPP read error");
4852351b17aba5350004fc76707f3b3d2859ce773c8xinhe                return;
4862351b17aba5350004fc76707f3b3d2859ce773c8xinhe            }
4872351b17aba5350004fc76707f3b3d2859ce773c8xinhe
4882351b17aba5350004fc76707f3b3d2859ce773c8xinhe            BitwiseInputStream bitStream = new BitwiseInputStream(data);
4892351b17aba5350004fc76707f3b3d2859ce773c8xinhe            try {
4902351b17aba5350004fc76707f3b3d2859ce773c8xinhe                int  mipUppLength = bitStream.read(8);
4912351b17aba5350004fc76707f3b3d2859ce773c8xinhe                //transfer length from byte to bit
4922351b17aba5350004fc76707f3b3d2859ce773c8xinhe                mipUppLength = (mipUppLength << 3);
4932351b17aba5350004fc76707f3b3d2859ce773c8xinhe
4942351b17aba5350004fc76707f3b3d2859ce773c8xinhe                if (!checkLengthLegal(mipUppLength, 1)) {
4952351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    return;
4962351b17aba5350004fc76707f3b3d2859ce773c8xinhe                }
4972351b17aba5350004fc76707f3b3d2859ce773c8xinhe                //parse the MIPUPP body 3GPP2 C.S0016-C 3.5.8.6
4982351b17aba5350004fc76707f3b3d2859ce773c8xinhe                int retryInfoInclude = bitStream.read(1);
4992351b17aba5350004fc76707f3b3d2859ce773c8xinhe                mipUppLength--;
5002351b17aba5350004fc76707f3b3d2859ce773c8xinhe
5012351b17aba5350004fc76707f3b3d2859ce773c8xinhe                if(retryInfoInclude == 1) {
5022351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    if (!checkLengthLegal(mipUppLength, 11)) {
5032351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        return;
5042351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    }
5052351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    bitStream.skip(11); //not used now
5062351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    //transfer length from byte to bit
5072351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    mipUppLength -= 11;
5082351b17aba5350004fc76707f3b3d2859ce773c8xinhe                }
5092351b17aba5350004fc76707f3b3d2859ce773c8xinhe
5102351b17aba5350004fc76707f3b3d2859ce773c8xinhe                if (!checkLengthLegal(mipUppLength, 4)) {
5112351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    return;
5122351b17aba5350004fc76707f3b3d2859ce773c8xinhe                }
5132351b17aba5350004fc76707f3b3d2859ce773c8xinhe                int numNai = bitStream.read(4);
5142351b17aba5350004fc76707f3b3d2859ce773c8xinhe                mipUppLength -= 4;
5152351b17aba5350004fc76707f3b3d2859ce773c8xinhe
5162351b17aba5350004fc76707f3b3d2859ce773c8xinhe                //start parse NAI body
5172351b17aba5350004fc76707f3b3d2859ce773c8xinhe                for(int index = 0; index < numNai; index++) {
5182351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    if (!checkLengthLegal(mipUppLength, 4)) {
5192351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        return;
5202351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    }
5212351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    int naiEntryIndex = bitStream.read(4);
5222351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    mipUppLength -= 4;
5232351b17aba5350004fc76707f3b3d2859ce773c8xinhe
5242351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    if (!checkLengthLegal(mipUppLength, 8)) {
5252351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        return;
5262351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    }
5272351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    int naiLength = bitStream.read(8);
5282351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    mipUppLength -= 8;
5292351b17aba5350004fc76707f3b3d2859ce773c8xinhe
5302351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    if(naiEntryIndex == 0) {
5312351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        //we find the one!
5322351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        if (!checkLengthLegal(mipUppLength, naiLength << 3)) {
5332351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            return;
5342351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        }
5352351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        char naiCharArray[] = new char[naiLength];
5362351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        for(int index1 = 0; index1 < naiLength; index1++) {
5372351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            naiCharArray[index1] = (char)(bitStream.read(8) & 0xFF);
5382351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        }
5392351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        mNai =  new String(naiCharArray);
540e9fdc85df2111a0a0d7d240bbc11ed5b14b01376xinhe                        if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) {
541e9fdc85df2111a0a0d7d240bbc11ed5b14b01376xinhe                            Log.v(LOG_TAG,"MIPUPP Nai = " + mNai);
542e9fdc85df2111a0a0d7d240bbc11ed5b14b01376xinhe                        }
5432351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        return; //need not parsing further
5442351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    } else {
5452351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        //ignore this NAI body
5462351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        if (!checkLengthLegal(mipUppLength, (naiLength << 3) + 102)) {
5472351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            return;
5482351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        }
5492351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        bitStream.skip((naiLength << 3) + 101);//not used
5502351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        int mnAaaSpiIndicator = bitStream.read(1);
5512351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        mipUppLength -= ((naiLength << 3) + 102);
5522351b17aba5350004fc76707f3b3d2859ce773c8xinhe
5532351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        if(mnAaaSpiIndicator == 1) {
5542351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            if (!checkLengthLegal(mipUppLength, 32)) {
5552351b17aba5350004fc76707f3b3d2859ce773c8xinhe                                return;
5562351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            }
5572351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            bitStream.skip(32); //not used
5582351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            mipUppLength -= 32;
5592351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        }
5602351b17aba5350004fc76707f3b3d2859ce773c8xinhe
5612351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        //MN-HA_AUTH_ALGORITHM
5622351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        if (!checkLengthLegal(mipUppLength, 5)) {
5632351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            return;
5642351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        }
5652351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        bitStream.skip(4);
5662351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        mipUppLength -= 4;
5672351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        int mnHaSpiIndicator = bitStream.read(1);
5682351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        mipUppLength--;
5692351b17aba5350004fc76707f3b3d2859ce773c8xinhe
5702351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        if(mnHaSpiIndicator == 1) {
5712351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            if (!checkLengthLegal(mipUppLength, 32)) {
5722351b17aba5350004fc76707f3b3d2859ce773c8xinhe                                return;
5732351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            }
5742351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            bitStream.skip(32);
5752351b17aba5350004fc76707f3b3d2859ce773c8xinhe                            mipUppLength -= 32;
5762351b17aba5350004fc76707f3b3d2859ce773c8xinhe                        }
5772351b17aba5350004fc76707f3b3d2859ce773c8xinhe                    }
5782351b17aba5350004fc76707f3b3d2859ce773c8xinhe                }
5792351b17aba5350004fc76707f3b3d2859ce773c8xinhe            } catch(Exception e) {
5802351b17aba5350004fc76707f3b3d2859ce773c8xinhe              Log.e(LOG_TAG,"MIPUPP read Exception error!");
5812351b17aba5350004fc76707f3b3d2859ce773c8xinhe                return;
5822351b17aba5350004fc76707f3b3d2859ce773c8xinhe            }
5832351b17aba5350004fc76707f3b3d2859ce773c8xinhe        }
5842351b17aba5350004fc76707f3b3d2859ce773c8xinhe    }
5852351b17aba5350004fc76707f3b3d2859ce773c8xinhe
586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void handleMessage(Message msg) {
588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AsyncResult ar;
589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte data[];
591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean isRecordLoadResponse = false;
593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
594bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (mDestroyed.get()) {
595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("Received message " + msg +
596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    "[" + msg.what + "] while being destroyed. Ignoring.");
597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try { switch (msg.what) {
601e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_APP_READY:
602e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onReady();
603e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_DEVICE_IDENTITY_DONE:
606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("Event EVENT_GET_DEVICE_IDENTITY_DONE Received");
607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            /* IO events */
610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_IMSI_DONE:
611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Exception querying IMSI, Exception:" + ar.exception);
616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mImsi = (String) ar.result;
620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // than 15 (and usually 15).
623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("invalid IMSI " + mImsi);
625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mImsi = null;
626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
628f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                // FIXME: CSIM IMSI may not contain the MNC.
629f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                if (false) {
630f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                    log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx");
631f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby
632f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                    String operatorNumeric = getRUIMOperatorNumeric();
633f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                    if (operatorNumeric != null) {
634f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                        if (operatorNumeric.length() <= 6) {
635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            log("update mccmnc=" + operatorNumeric);
636f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                            MccTable.updateMccMncConfiguration(mContext, operatorNumeric, false);
637f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                        }
638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } else {
640a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    String operatorNumeric = getRUIMOperatorNumeric();
641a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("NO update mccmnc=" + operatorNumeric);
642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
643f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby
644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CDMA_SUBSCRIPTION_DONE:
647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                String localTemp[] = (String[])ar.result;
649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mMyMobileNumber = localTemp[0];
654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mMin2Min1 = localTemp[3];
655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mPrlVersion = localTemp[4];
656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);
658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_ICCID_DONE:
662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
671b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville                mIccId = IccUtils.bcdToString(data, 0, data.length);
672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
673b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville                log("iccid: " + mIccId);
674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_UPDATE_DONE:
678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
68099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                    Rlog.i(LOG_TAG, "RuimRecords update failed", ar.exception);
681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_ALL_SMS_DONE:
685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_MARK_SMS_READ_DONE:
686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SMS_ON_RUIM:
687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SMS_DONE:
68899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.w(LOG_TAG, "Event not supported: " + msg.what);
689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // TODO: probably EF_CST should be read instead
692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SST_DONE:
693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("Event EVENT_GET_SST_DONE Received");
694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_RUIM_REFRESH:
697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    handleRuimRefresh((IccRefreshResponse)ar.result);
701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
704e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            default:
705e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                super.handleMessage(msg);   // IccRecords handles generic record load responses
706e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }}catch (RuntimeException exc) {
708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // I don't want these exceptions to be fatal
70999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.w(LOG_TAG, "Exception parsing RUIM record", exc);
710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } finally {
711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Count up record load responses even if they are fails
712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (isRecordLoadResponse) {
713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRecordLoaded();
714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
7180cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath    /**
7190cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath     * Returns an array of languages we have assets for.
7200cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath     *
7210cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath     * NOTE: This array will have duplicates. If this method will be caused
7220cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath     * frequently or in a tight loop, it can be rewritten for efficiency.
7230cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath     */
7240cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath    private static String[] getAssetLanguages(Context ctx) {
7250cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath        final String[] locales = ctx.getAssets().getLocales();
7260cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath        final String[] localeLangs = new String[locales.length];
7270cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath        for (int i = 0; i < locales.length; ++i) {
7280cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath            final String localeStr = locales[i];
7290cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath            final int separator = localeStr.indexOf('-');
7300cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath            if (separator < 0) {
7310cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath                localeLangs[i] = localeStr;
7320cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath            } else {
7330cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath                localeLangs[i] = localeStr.substring(0, separator);
7340cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath            }
7350cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath        }
7360cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath
7370cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath        return localeLangs;
7380cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath    }
7390cdae27a3afaf241764dc3a03bfff6ed012656dbNarayan Kamath
740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onRecordLoaded() {
742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // One record loaded successfully or failed, In either case
743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // we need to update the recordsToLoad count
74422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad -= 1;
74522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("onRecordLoaded " + mRecordsToLoad + " requested: " + mRecordsRequested);
746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
74722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRecordsToLoad == 0 && mRecordsRequested == true) {
748c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onAllRecordsLoaded();
74922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mRecordsToLoad < 0) {
750bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka            loge("recordsToLoad <0, programmer error suspected");
75122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mRecordsToLoad = 0;
752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
753c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onAllRecordsLoaded() {
757bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (DBG) log("record load complete");
758bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka
759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Further records that can be inserted are Operator/OEM dependent
760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
761f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby        // FIXME: CSIM IMSI may not contain the MNC.
762f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby        if (false) {
763f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby            String operator = getRUIMOperatorNumeric();
764f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby            if (!TextUtils.isEmpty(operator)) {
765f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                log("onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
766f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                        operator + "'");
767a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("update icc_operator_numeric=" + operator);
768e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                mTelephonyManager.setSimOperatorNumericForPhone(
769e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                        mParentApp.getPhoneId(), operator);
770f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby            } else {
771f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                log("onAllRecordsLoaded empty 'gsm.sim.operator.numeric' skipping");
772f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby            }
773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
774f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby            if (!TextUtils.isEmpty(mImsi)) {
775a1421a82e8d4f711ba13a86d40889868ead492d4Amit Mahajan                log("onAllRecordsLoaded set mcc imsi=" + (VDBG ? ("=" + mImsi) : ""));
776e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                mTelephonyManager.setSimCountryIsoForPhone(
777e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                        mParentApp.getPhoneId(),
778e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                        MccTable.countryCodeForMcc(
779e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu                        Integer.parseInt(mImsi.substring(0,3))));
780f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby            } else {
781f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby                log("onAllRecordsLoaded empty imsi skipping setting mcc");
782f93def879c5225379e1542eedf50bfd6aca17779Jake Hamby            }
783c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
784e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
785c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan        Resources resource = Resources.getSystem();
786c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan        if (resource.getBoolean(com.android.internal.R.bool.config_use_sim_language_file)) {
787c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan            setSimLanguage(mEFli, mEFpl);
788c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan        }
789c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan
790b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville        mRecordsLoadedRegistrants.notifyRegistrants(
791c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AsyncResult(null, null, null));
7925866914ae9798adebcb84cd710bca660b797bff0Amit Mahajan
793062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal        // TODO: The below is hacky since the SubscriptionController may not be ready at this time.
7945866914ae9798adebcb84cd710bca660b797bff0Amit Mahajan        if (!TextUtils.isEmpty(mMdn)) {
795062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal            int phoneId = mParentApp.getUiccCard().getPhoneId();
796062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal            int[] subIds = SubscriptionController.getInstance().getSubId(phoneId);
797062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal            if (subIds != null) {
798062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal                SubscriptionManager.from(mContext).setDisplayNumber(mMdn, subIds[0]);
799062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal            } else {
800062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal                log("Cannot call setDisplayNumber: invalid subId");
801062a2a3838c8d8adf16f4d9fbde8d52450da0336Shishir Agrawal            }
8025866914ae9798adebcb84cd710bca660b797bff0Amit Mahajan        }
803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
804c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
806c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void onReady() {
807c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        fetchRuimRecords();
808c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
809c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
811c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
812c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
813c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void fetchRuimRecords() {
81422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsRequested = true;
815c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
81622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("fetchRuimRecords " + mRecordsToLoad);
817c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
818e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
81922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
820c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
821c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_ICCID,
822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                obtainMessage(EVENT_GET_ICCID_DONE));
82322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
824c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
825c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan        mFh.loadEFTransparent(EF_PL,
826c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded()));
827c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan        mRecordsToLoad++;
828e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
829c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan        mFh.loadEFTransparent(EF_CSIM_LI,
830c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded()));
831c9a55d1e545ab7bc92e14c2ca1123ac71b18f7feAmit Mahajan        mRecordsToLoad++;
832e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
833e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mFh.loadEFTransparent(EF_CSIM_SPN,
834e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimSpnLoaded()));
83522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
836e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
837e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mFh.loadEFLinearFixed(EF_CSIM_MDN, 1,
838e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMdnLoaded()));
83922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
840e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
841e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mFh.loadEFTransparent(EF_CSIM_IMSIM,
842e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimImsimLoaded()));
84322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
844e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
845e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME,
846e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimCdmaHomeLoaded()));
84722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
848e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
849e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // Entire PRL could be huge. We are only interested in
850e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // the first 4 bytes of the record.
851e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mFh.loadEFTransparent(EF_CSIM_EPRL, 4,
852e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimEprlLoaded()));
85322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
854e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
8552351b17aba5350004fc76707f3b3d2859ce773c8xinhe        mFh.loadEFTransparent(EF_CSIM_MIPUPP,
8562351b17aba5350004fc76707f3b3d2859ce773c8xinhe                obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMipUppLoaded()));
8572351b17aba5350004fc76707f3b3d2859ce773c8xinhe        mRecordsToLoad++;
8582351b17aba5350004fc76707f3b3d2859ce773c8xinhe
85922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("fetchRuimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested);
860c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Further records that can be inserted are Operator/OEM dependent
861c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
862c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
863c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
864c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
865c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
866c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * No Display rule for RUIMs yet.
867c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
868c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
869c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public int getDisplayRule(String plmn) {
870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // TODO together with spn
871c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return 0;
872c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
873c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
874c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
875e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public boolean isProvisioned() {
876e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // If UICC card has CSIM app, look for MDN and MIN field
877e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // to determine if the SIM is provisioned.  Otherwise,
878e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // consider the SIM is provisioned. (for case of ordinal
879e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // USIM only UICC.)
880e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // If PROPERTY_TEST_CSIM is defined, bypess provision check
881e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        // and consider the SIM is provisioned.
882e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (SystemProperties.getBoolean(PROPERTY_TEST_CSIM, false)) {
883e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return true;
884e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
885e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
886e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mParentApp == null) {
887e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return false;
888e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
889e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
890e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mParentApp.getType() == AppType.APPTYPE_CSIM &&
891e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            ((mMdn == null) || (mMin == null))) {
892e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            return false;
893e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        }
894e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return true;
895e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
896e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
897e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    @Override
898c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setVoiceMessageWaiting(int line, int countWaiting) {
89926a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa        // Will be used in future to store voice mail count in UIM
90026a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa        // C.S0023-D_v1.0 does not have a file id in UIM for MWI
90126a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa        log("RuimRecords:setVoiceMessageWaiting - NOP for CDMA");
90226a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa    }
903c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
90426a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa    @Override
90526a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa    public int getVoiceMessageCount() {
90626a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa        // Will be used in future to retrieve voice mail count for UIM
90726a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa        // C.S0023-D_v1.0 does not have a file id in UIM for MWI
90826a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa        log("RuimRecords:getVoiceMessageCount - NOP for CDMA");
90926a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa        return 0;
910c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
911c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
912c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleRuimRefresh(IccRefreshResponse refreshResponse) {
913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (refreshResponse == null) {
914c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("handleRuimRefresh received without input");
915c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
916c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
917c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
918c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (refreshResponse.aid != null &&
919e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                !refreshResponse.aid.equals(mParentApp.getAid())) {
920c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // This is for different app. Ignore.
921c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
922c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
923c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
924c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (refreshResponse.refreshResult) {
925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED");
92722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mAdnCache.reset();
928c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                fetchRuimRecords();
929c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
930c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_INIT:
931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT");
932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // need to reload all files (that we care about)
93364bfd98578babdd437f1a83d2d5e1fc92c76e729Alex Yakavenka                onIccRefreshInit();
934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_RESET:
93662648296ee1514d871d7d779d6f33da5e55babcaShishir Agrawal                // Refresh reset is handled by the UiccCard object.
937c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET");
938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // unknown refresh operation
941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleRuimRefresh with unknown operation");
942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
943c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
944c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
946e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public String getMdn() {
947e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mMdn;
948e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
949e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
950e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public String getMin() {
951e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mMin;
952e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
953e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
954e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public String getSid() {
955e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mHomeSystemId;
956e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
957e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
958e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public String getNid() {
959e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mHomeNetworkId;
960e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
961e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka
962e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public boolean getCsimSpnDisplayCondition() {
963e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mCsimSpnDisplayCondition;
964e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    }
965c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
966c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void log(String s) {
96799c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d(LOG_TAG, "[RuimRecords] " + s);
968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
971c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void loge(String s) {
97299c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.e(LOG_TAG, "[RuimRecords] " + s);
973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
97405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka
97505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    @Override
97605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
97705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println("RuimRecords: " + this);
97805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" extends:");
97905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        super.dump(fd, pw, args);
98022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mOtaCommited=" + mOtaCommited);
98105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mMyMobileNumber=" + mMyMobileNumber);
98205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mMin2Min1=" + mMin2Min1);
98305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mPrlVersion=" + mPrlVersion);
98405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mEFpl[]=" + Arrays.toString(mEFpl));
98505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mEFli[]=" + Arrays.toString(mEFli));
98605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mCsimSpnDisplayCondition=" + mCsimSpnDisplayCondition);
98705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mMdn=" + mMdn);
98805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mMin=" + mMin);
98905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mHomeSystemId=" + mHomeSystemId);
99005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mHomeNetworkId=" + mHomeNetworkId);
99105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.flush();
99205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    }
993c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
994