SIMRecords.java revision 31ae682ff511ddde4073c3f94eff15da2f7fade6
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/*
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * Copyright (C) 2006 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
19c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
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;
22c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.content.Context;
23c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.AsyncResult;
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
2631ae682ff511ddde4073c3f94eff15da2f7fade6Wink Savilleimport android.telephony.PhoneNumberUtils;
27a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hambyimport android.telephony.SmsMessage;
282bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapatiimport android.text.TextUtils;
2999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.CommandsInterface;
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.MccTable;
33a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hambyimport com.android.internal.telephony.SmsConstants;
34d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.gsm.SimTlv;
35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.FileDescriptor;
3705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.PrintWriter;
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
3905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.util.Arrays;
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic class SIMRecords extends IccRecords {
45cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String LOG_TAG = "SIMRecords";
46c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final boolean CRASH_RIL = false;
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Instance Variables
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    VoiceMailConstants mVmConfig;
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    SpnOverride mSpnOverride;
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Cached SIM State; cleared on channel close
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
5822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mCallForwardingEnabled;
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * States only used by getSpnFsm FSM
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
6422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private GetSpnFsmState mSpnState;
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** CPHS service information (See CPHS 4.2 B.3.1.1)
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  It will be set in onSimReady if reading GET_CPHS_INFO successfully
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  mCphsInfo[0] is CPHS Phase
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private byte[] mCphsInfo = null;
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    boolean mCspPlmnEnabled = true;
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
7422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    byte[] mEfMWIS = null;
7522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    byte[] mEfCPHS_MWI =null;
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    byte[] mEfCff = null;
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    byte[] mEfCfis = null;
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
8022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mSpnDisplayCondition;
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Numeric network codes listed in TS 51.011 EF[SPDI]
8222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    ArrayList<String> mSpdiNetworks = null;
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
8422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPnnHomeName = null;
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    UsimServiceTable mUsimServiceTable;
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
88f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
89f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    public String toString() {
90f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return "SimRecords: " + super.toString()
91f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mVmConfig" + mVmConfig
92f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mSpnOverride=" + "mSpnOverride"
9322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " callForwardingEnabled=" + mCallForwardingEnabled
9422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " spnState=" + mSpnState
95f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mCphsInfo=" + mCphsInfo
96f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mCspPlmnEnabled=" + mCspPlmnEnabled
9722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " efMWIS=" + mEfMWIS
9822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " efCPHS_MWI=" + mEfCPHS_MWI
99f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mEfCff=" + mEfCff
100f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mEfCfis=" + mEfCfis
101f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " getOperatorNumeric=" + getOperatorNumeric();
102f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    }
103f92cb4bd5519427a0db673709d94683a8baf203aWink Saville
104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Constants
105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // From TS 51.011 EF[SPDI] section
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SPDI = 0xA3;
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SPDI_PLMN_LIST = 0x80;
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Full Name IEI from TS 24.008
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_FULL_NETWORK_NAME = 0x43;
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Short Name IEI from TS 24.008
114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SHORT_NETWORK_NAME = 0x45;
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // active CFF from CPHS 4.2 B.4.5
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_LINE1_MASK = 0x0f;
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_LINE1_RESET = 0xf0;
121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // CPHS Service Table (See CPHS 4.2 B.3.1)
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int CPHS_SST_MBN_MASK = 0x30;
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int CPHS_SST_MBN_ENABLED = 0x30;
125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
12631ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    // EF_CFIS related constants
12731ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    // Spec reference TS 51.011 section 10.3.46.
12831ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    private static final int CFIS_BCD_NUMBER_LENGTH_OFFSET = 2;
12931ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    private static final int CFIS_TON_NPI_OFFSET = 3;
13031ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    private static final int CFIS_ADN_CAPABILITY_ID_OFFSET = 14;
13131ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    private static final int CFIS_ADN_EXTENSION_ID_OFFSET = 15;
13231ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville
133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Event Constants
134e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_GET_IMSI_DONE = 3;
135e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_GET_ICCID_DONE = 4;
136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MBI_DONE = 5;
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MBDN_DONE = 6;
138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MWIS_DONE = 7;
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8;
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_MSISDN_DONE = 10;
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11;
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SPN_DONE = 12;
144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SPDI_DONE = 13;
145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_UPDATE_DONE = 14;
146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_PNN_DONE = 15;
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_SST_DONE = 17;
148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_ALL_SMS_DONE = 18;
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_MARK_SMS_READ_DONE = 19;
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SET_MBDN_DONE = 20;
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SMS_ON_SIM = 21;
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SMS_DONE = 22;
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CFF_DONE = 24;
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25;
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_INFO_CPHS_DONE = 26;
156cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // private static final int EVENT_SET_MSISDN_DONE = 30; Defined in IccRecords as 30
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SIM_REFRESH = 31;
158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CFIS_DONE = 32;
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CSP_CPHS_DONE = 33;
1602f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim    private static final int EVENT_GET_GID1_DONE = 34;
161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
1650530f592d89c1eceea7ee5bccb2359061a04f968duho.ro        "302370", "302720", "310260",
166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914",
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922",
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930",
1810530f592d89c1eceea7ee5bccb2359061a04f968duho.ro        "405931", "405932", "502142", "502143", "502145", "502146", "502147", "502148"
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Constructor
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
186e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
187e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        super(app, c, ci);
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
18922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mAdnCache = new AdnRecordCache(mFh);
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mVmConfig = new VoiceMailConstants();
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mSpnOverride = new SpnOverride();
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsRequested = false;  // No load request is made till SIM ready
195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // recordsToLoad is set to 0 because no requests are made yet
19722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad = 0;
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Start off by setting empty state
203e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        resetRecords();
204e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mParentApp.registerForReady(this, EVENT_APP_READY, null);
205f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (DBG) log("SIMRecords X ctor this=" + this);
206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dispose() {
210f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (DBG) log("Disposing SIMRecords this=" + this);
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        //Unregister for all events
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.unregisterForIccRefresh(this);
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.unSetOnSmsOnSim(this);
214e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mParentApp.unregisterForReady(this);
215e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        resetRecords();
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        super.dispose();
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
219cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void finalize() {
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if(DBG) log("finalized");
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
224e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    protected void resetRecords() {
225e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mImsi = null;
22622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMsisdn = null;
22722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceMailNum = null;
22822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCountVoiceMessages = 0;
22922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMncLength = UNINITIALIZED;
230b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville        mIccId = null;
231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // -1 means no EF_SPN found; treat accordingly.
23222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mSpnDisplayCondition = -1;
23322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mEfMWIS = null;
23422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mEfCPHS_MWI = null;
23522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mSpdiNetworks = null;
23622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPnnHomeName = null;
237620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt        mGid1 = null;
238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
23922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mAdnCache.reset();
240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("SIMRecords: onRadioOffOrNotAvailable set 'gsm.sim.operator.numeric' to operator=null");
242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, null);
243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, null);
244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // recordsRequested is set to false indicating that the SIM
247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // read requests made so far are not valid. This is set to
248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // true only when fresh set of read requests are made.
24922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsRequested = false;
250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //***** Public Methods
254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getIMSI() {
260e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mImsi;
261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
263cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getMsisdnNumber() {
26522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mMsisdn;
266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
2692f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim    public String getGid1() {
270620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt        return mGid1;
2712f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim    }
2722f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
2732f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim    @Override
274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public UsimServiceTable getUsimServiceTable() {
275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mUsimServiceTable;
276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set subscriber number to SIM record
280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The subscriber number is stored in EF_MSISDN (TS 51.011)
282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * When the operation is complete, onComplete will be sent to its handler
284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param number dailing nubmer (up to 20 digits)
287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        if the number starts with '+', then set to international TOA
288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param onComplete
289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        onComplete.obj will be an AsyncResult
290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception == null on success
291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception != null on fail
292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
293cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setMsisdnNumber(String alphaTag, String number,
295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message onComplete) {
296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
29722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMsisdn = number;
29822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMsisdnTag = alphaTag;
299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if(DBG) log("Set MSISDN: " + mMsisdnTag + " " + /*mMsisdn*/ "xxxxxxx");
301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        AdnRecord adn = new AdnRecord(mMsisdnTag, mMsisdn);
304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
309cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getMsisdnAlphaTag() {
31122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mMsisdnTag;
312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
314cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getVoiceMailNumber() {
31622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mVoiceMailNum;
317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set voice mail number to SIM record
321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The voice mail number can be stored either in EF_MBDN (TS 51.011) or
323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * EF_MAILBOX_CPHS (CPHS 4.2)
324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If EF_MBDN is available, store the voice mail number to EF_MBDN
326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * So the voice mail number will be stored in both EFs if both are available
330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * When the operation is complete, onComplete will be sent to its handler
334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param voiceNumber dailing nubmer (upto 20 digits)
337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        if the number is start with '+', then set to international TOA
338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param onComplete
339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        onComplete.obj will be an AsyncResult
340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception == null on success
341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception != null on fail
342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setVoiceMailNumber(String alphaTag, String voiceNumber,
345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message onComplete) {
34622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mIsVoiceMailFixed) {
347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AsyncResult.forMessage((onComplete)).exception =
348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new IccVmFixedException("Voicemail number is fixed by operator");
349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onComplete.sendToTarget();
350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
35322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewVoiceMailNum = voiceNumber;
35422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewVoiceMailTag = alphaTag;
355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
35622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        AdnRecord adn = new AdnRecord(mNewVoiceMailTag, mNewVoiceMailNum);
357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
35822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mMailboxIndex != 0 && mMailboxIndex != 0xff) {
359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AdnRecordLoader(mFh).updateEF(adn, EF_MBDN, EF_EXT6,
36122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mMailboxIndex, null,
362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_SET_MBDN_DONE, onComplete));
363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (isCphsMailboxEnabled()) {
365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS,
367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    EF_EXT1, 1, null,
368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete));
369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AsyncResult.forMessage((onComplete)).exception =
372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new IccVmNotSupportedException("Update SIM voice mailbox error");
373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onComplete.sendToTarget();
374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
377cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getVoiceMailAlphaTag()
379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    {
38022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mVoiceMailTag;
381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Sets the SIM voice message waiting indicator records
385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param countWaiting The number of messages waiting, if known. Use
387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *                     -1 to indicate that an unknown number of
388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *                      messages are waiting
389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
390cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void
392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    setVoiceMessageWaiting(int line, int countWaiting) {
393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (line != 1) {
394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // only profile 1 is supported
395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // range check
399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (countWaiting < 0) {
400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            countWaiting = -1;
401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (countWaiting > 0xff) {
402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // TS 23.040 9.2.3.24.2
403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // "The value 255 shall be taken to mean 255 or greater"
404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            countWaiting = 0xff;
405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
40722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCountVoiceMessages = countWaiting;
408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
41222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mEfMWIS != null) {
413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // TS 51.011 10.3.45
414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // lsb of byte 0 is 'voicemail' status
41622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mEfMWIS[0] = (byte)((mEfMWIS[0] & 0xfe)
41722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                    | (mCountVoiceMessages == 0 ? 0 : 1));
418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // byte 1 is the number of voice messages waiting
420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (countWaiting < 0) {
421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // The spec does not define what this should be
422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // if we don't know the count
42322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mEfMWIS[1] = 0;
424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
42522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mEfMWIS[1] = (byte) countWaiting;
426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFLinearFixed(
42922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    EF_MWIS, 1, mEfMWIS, null,
430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage (EVENT_UPDATE_DONE, EF_MWIS));
431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
432c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
43322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mEfCPHS_MWI != null) {
434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer CPHS4_2.WW6 B4.2.3
43522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mEfCPHS_MWI[0] = (byte)((mEfCPHS_MWI[0] & 0xf0)
43622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            | (mCountVoiceMessages == 0 ? 0x5 : 0xa));
437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFTransparent(
43922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    EF_VOICE_MAIL_INDICATOR_CPHS, mEfCPHS_MWI,
440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS));
441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (ArrayIndexOutOfBoundsException ex) {
443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            logw("Error saving voice mail state to SIM. Probably malformed SIM record", ex);
444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
447a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    // Validate data is !null and the MSP (Multiple Subscriber Profile)
448a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    // byte is between 1 and 4. See ETSI TS 131 102 v11.3.0 section 4.2.64.
449a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    private boolean validEfCfis(byte[] data) {
450a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville        return ((data != null) && (data[0] >= 1) && (data[0] <= 4));
451a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    }
452a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville
453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean getVoiceCallForwardingFlag() {
45822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mCallForwardingEnabled;
459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
46531ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    public void setVoiceCallForwardingFlag(int line, boolean enable, String dialNumber) {
466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (line != 1) return; // only line 1 is supported
468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
46922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCallForwardingEnabled = enable;
470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
474a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville            if (validEfCfis(mEfCfis)) {
475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // lsb is of byte 1 is voice status
476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (enable) {
477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCfis[1] |= 1;
478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCfis[1] &= 0xfe;
480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
482a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                log("setVoiceCallForwardingFlag: enable=" + enable
483a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                        + " mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));
484a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville
48531ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                // Update dialNumber if not empty and CFU is enabled.
48631ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                // Spec reference for EF_CFIS contents, TS 51.011 section 10.3.46.
48731ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                if (enable && !TextUtils.isEmpty(dialNumber)) {
48831ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    log("EF_CFIS: updating cf number, " + dialNumber);
48931ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    byte[] bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(dialNumber);
49031ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville
49131ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    System.arraycopy(bcdNumber, 0, mEfCfis, CFIS_TON_NPI_OFFSET, bcdNumber.length);
49231ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville
49331ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    mEfCfis[CFIS_BCD_NUMBER_LENGTH_OFFSET] = (byte) (bcdNumber.length);
49431ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    mEfCfis[CFIS_ADN_CAPABILITY_ID_OFFSET] = (byte) 0xFF;
49531ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    mEfCfis[CFIS_ADN_EXTENSION_ID_OFFSET] = (byte) 0xFF;
49631ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                }
497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFLinearFixed(
499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EF_CFIS, 1, mEfCfis, null,
500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage (EVENT_UPDATE_DONE, EF_CFIS));
501a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville            } else {
502a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                log("setVoiceCallForwardingFlag: ignoring enable=" + enable
503a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                        + " invalid mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));
504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (mEfCff != null) {
507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (enable) {
508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            | CFF_UNCONDITIONAL_ACTIVE);
510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            | CFF_UNCONDITIONAL_DEACTIVE);
513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFTransparent(
516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EF_CFF_CPHS, mEfCff,
517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (ArrayIndexOutOfBoundsException ex) {
520e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby            logw("Error saving call forwarding flag to SIM. "
521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + "Probably malformed SIM record", ex);
522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Called by STK Service when REFRESH is received.
528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param fileChanged indicates whether any files changed
529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param fileList if non-null, a list of EF files that changed
530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
531cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void onRefresh(boolean fileChanged, int[] fileList) {
533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (fileChanged) {
534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // A future optimization would be to inspect fileList and
535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // only reload those files that we care about.  For now,
536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // just re-fetch all SIM records that we cache.
537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            fetchSimRecords();
538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getOperatorNumeric() {
546e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mImsi == null) {
547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("getOperatorNumeric: IMSI == null");
548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return null;
549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
55022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mMncLength == UNINITIALIZED || mMncLength == UNKNOWN) {
551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("getSIMOperatorNumeric: bad mncLength");
552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return null;
553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Length = length of MCC + length of MNC
556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // length of mcc = 3 (TS 23.003 Section 2.2)
55722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mImsi.substring(0, 3 + mMncLength);
558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Overridden from Handler
561cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void handleMessage(Message msg) {
563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AsyncResult ar;
564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AdnRecord adn;
565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte data[];
567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean isRecordLoadResponse = false;
569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
570bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (mDestroyed.get()) {
571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("Received message " + msg + "[" + msg.what + "] " +
572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    " while being destroyed. Ignoring.");
573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
574c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
575c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try { switch (msg.what) {
577e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_APP_READY:
578e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onReady();
579e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
581c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            /* IO events */
582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_IMSI_DONE:
583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Exception querying IMSI, Exception:" + ar.exception);
589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
592e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mImsi = (String) ar.result;
593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // than 15 (and usually 15).
596e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
597e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    loge("invalid IMSI " + mImsi);
598e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    mImsi = null;
599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("IMSI: " + /* imsi.substring(0, 6) +*/ "xxxxxxx");
602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
60322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (((mMncLength == UNKNOWN) || (mMncLength == 2)) &&
604e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        ((mImsi != null) && (mImsi.length() >= 6))) {
605e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    String mccmncCode = mImsi.substring(0, 6);
606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (mccmnc.equals(mccmncCode)) {
60822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mMncLength = 3;
609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            break;
610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
61422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mMncLength == UNKNOWN) {
615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // the SIM has told us all it knows, but it didn't know the mnc length.
616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // guess using the mcc
617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    try {
618e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        int mcc = Integer.parseInt(mImsi.substring(0,3));
61922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mMncLength = MccTable.smallestDigitsMccForMnc(mcc);
620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } catch (NumberFormatException e) {
62122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mMncLength = UNKNOWN;
622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        loge("Corrupt IMSI!");
623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
62622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mMncLength != UNKNOWN && mMncLength != UNINITIALIZED) {
627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // finally have both the imsi and the mncLength and can parse the imsi properly
62822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    MccTable.updateMccMncConfiguration(mContext, mImsi.substring(0, 3 + mMncLength));
629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
630e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mImsiReadyRegistrants.notifyRegistrants();
631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MBI_DONE:
634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean isValidMbdn;
635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
636c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[]) ar.result;
639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isValidMbdn = false;
641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer TS 51.011 Section 10.3.44 for content details
643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("EF_MBI: " + IccUtils.bytesToHexString(data));
644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Voice mail record number stored first
64622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mMailboxIndex = data[0] & 0xff;
647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // check if dailing numbe id valid
64922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mMailboxIndex != 0 && mMailboxIndex != 0xff) {
650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("Got valid mailbox number for MBDN");
651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        isValidMbdn = true;
652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // one more record to load
65622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad += 1;
657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (isValidMbdn) {
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Note: MBDN was not included in NUM_OF_SIM_RECORDS_LOADED
660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
66122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mMailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // If this EF not present, try mailbox as in CPHS standard
664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // CPHS (CPHS4_2.WW6) is a european standard.
665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS,
666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_EXT1, 1,
667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CPHS_MAILBOX_DONE:
672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MBDN_DONE:
673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //Resetting the voice mail number and voice mail tag to null
674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //as these should be updated from the data read from EF_MBDN.
675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //If they are not reset, incase of invalid data/exception these
676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //variables are retaining their previous values and are
677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //causing invalid voice mailbox info display to user.
67822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mVoiceMailNum = null;
67922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mVoiceMailTag = null;
680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Invalid or missing EF"
687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]"));
688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Bug #645770 fall back to CPHS
690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME should use SST to decide
691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (msg.what == EVENT_GET_MBDN_DONE) {
693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        //load CPHS on fail...
694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // FIXME right now, only load line1's CPHS voice mail entry
695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
69622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mRecordsToLoad += 1;
697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        new AdnRecordLoader(mFh).loadFromEF(
698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                EF_MAILBOX_CPHS, EF_EXT1, 1,
699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
704c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                adn = (AdnRecord)ar.result;
705c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("VM: " + adn +
707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) {
710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Bug #645770 fall back to CPHS
711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME should use SST to decide
712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME right now, only load line1's CPHS voice mail entry
71322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mRecordsToLoad += 1;
714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(
715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_MAILBOX_CPHS, EF_EXT1, 1,
716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
72122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mVoiceMailNum = adn.getNumber();
72222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mVoiceMailTag = adn.getAlphaTag();
723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MSISDN_DONE:
726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
729c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Invalid or missing EF[MSISDN]");
732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
733c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
735c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                adn = (AdnRecord)ar.result;
736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
73722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mMsisdn = adn.getNumber();
73822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mMsisdnTag = adn.getAlphaTag();
739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
74022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                log("MSISDN: " + /*mMsisdn*/ "xxxxxxx");
741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_MSISDN_DONE:
744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
745c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.userObj != null) {
748c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
749c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = ar.exception;
750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((Message) ar.userObj).sendToTarget();
751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
753c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MWIS_DONE:
755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
757c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
762c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
763c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
764c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_MWIS: " + IccUtils.bytesToHexString(data));
765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
76622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mEfMWIS = data;
767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if ((data[0] & 0xff) == 0xff) {
769c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Uninitialized record MWIS");
770c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
771c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Refer TS 51.011 Section 10.3.45 for the content description
774c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean voiceMailWaiting = ((data[0] & 0x01) != 0);
77522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCountVoiceMessages = data[1] & 0xff;
776c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
77722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (voiceMailWaiting && mCountVoiceMessages == 0) {
778c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Unknown count = -1
77922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCountVoiceMessages = -1;
780c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
782c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
783c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
784c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
785c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE:
786c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
787c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
788c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
789c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
790c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
791c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
792c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
793c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
79522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mEfCPHS_MWI = data;
796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
797c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Use this data if the EF[MWIS] exists and
798c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // has been loaded
799c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
80022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mEfMWIS == null) {
801cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    int indicator = data[0] & 0xf;
802c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer CPHS4_2.WW6 B4.2.3
804c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (indicator == 0xA) {
805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // Unknown count = -1
80622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mCountVoiceMessages = -1;
807c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else if (indicator == 0x5) {
80822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mCountVoiceMessages = 0;
809c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
811c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
812c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
813c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
814c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
815c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_ICCID_DONE:
816c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
817c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
818c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
819c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
820c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
821c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
823c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
824c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
825b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville                mIccId = IccUtils.bcdToString(data, 0, data.length);
826c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
827b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville                log("iccid: " + mIccId);
828c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
829c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_AD_DONE:
833c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                try {
834c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    isRecordLoadResponse = true;
835c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult)msg.obj;
837c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[])ar.result;
838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.exception != null) {
840c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
842c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
843c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("EF_AD: " + IccUtils.bytesToHexString(data));
844c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
845c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (data.length < 3) {
846c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("Corrupt AD data on SIM");
847c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
850c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (data.length == 3) {
851c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("MNC length not present in EF_AD");
852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
853c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
854c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
85522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mMncLength = data[3] & 0xf;
856c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
85722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mMncLength == 0xf) {
85822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mMncLength = UNKNOWN;
859c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
860c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } finally {
86122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (((mMncLength == UNINITIALIZED) || (mMncLength == UNKNOWN) ||
86222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            (mMncLength == 2)) && ((mImsi != null) && (mImsi.length() >= 6))) {
863e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        String mccmncCode = mImsi.substring(0, 6);
864c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
865c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (mccmnc.equals(mccmncCode)) {
86622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mMncLength = 3;
867c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                break;
868c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
869c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
871c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
87222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mMncLength == UNKNOWN || mMncLength == UNINITIALIZED) {
873e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        if (mImsi != null) {
874c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            try {
875e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                                int mcc = Integer.parseInt(mImsi.substring(0,3));
876c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
87722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mMncLength = MccTable.smallestDigitsMccForMnc(mcc);
878c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            } catch (NumberFormatException e) {
87922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mMncLength = UNKNOWN;
880c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                loge("Corrupt IMSI!");
881c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
882c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } else {
883c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // Indicate we got this info, but it didn't contain the length.
88422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mMncLength = UNKNOWN;
885c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
886c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            log("MNC length not present in EF_AD");
887c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
888c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
88922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mImsi != null && mMncLength != UNKNOWN) {
890c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // finally have both imsi and the length of the mnc and can parse
891c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // the imsi properly
892c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        MccTable.updateMccMncConfiguration(mContext,
89322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mImsi.substring(0, 3 + mMncLength));
894c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
895c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
896c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
897c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
898c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SPN_DONE:
899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
900c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
901c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                getSpnFsm(false, ar);
902c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
903c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
904c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CFF_DONE:
905c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
906c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
907c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
908c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[]) ar.result;
909c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
910c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
911c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
912c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
914c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
915c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mEfCff = data;
916c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
917e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby                // if EF_CFIS is valid, prefer it to EF_CFF_CPHS
918e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby                if (!validEfCfis(mEfCfis)) {
91922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCallForwardingEnabled =
920c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE);
921c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
922c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
923a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                } else {
924e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby                    log("EVENT_GET_CFF_DONE: EF_CFIS is valid, ignoring EF_CFF_CPHS");
925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
927c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
928c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SPDI_DONE:
929c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
930c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
933c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
936c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
937c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                parseEfSpdi(data);
939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_UPDATE_DONE:
942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
943c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
944c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    logw("update failed. ", ar.exception);
945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
947c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
948c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_PNN_DONE:
949c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                SimTlv tlv = new SimTlv(data, 0, data.length);
959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
960c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                for ( ; tlv.isValidObject() ; tlv.nextObject()) {
961c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (tlv.getTag() == TAG_FULL_NETWORK_NAME) {
96222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mPnnHomeName
963c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = IccUtils.networkNameToString(
964c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                tlv.getData(), 0, tlv.getData().length);
965c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
966c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
967c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_ALL_SMS_DONE:
971c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
972c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
974c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null)
975c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
976c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
977cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleSmses((ArrayList<byte []>) ar.result);
978c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
979c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
980c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_MARK_SMS_READ_DONE:
98199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.i("ENF", "marked read: sms " + msg.arg1);
982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
983c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
984c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
985c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SMS_ON_SIM:
986c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
987c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
988c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
989c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
990c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int[] index = (int[])ar.result;
991c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
992c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null || index.length != 1) {
993c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Error on SMS_ON_SIM with exp "
994c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + ar.exception + " length " + index.length);
995c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
996c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("READ EF_SMS RECORD index=" + index[0]);
997c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFLinearFixed(EF_SMS,index[0],
998c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_SMS_DONE));
999c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1000c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1001c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1002c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SMS_DONE:
1003c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1004c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
1006c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    handleSms((byte[])ar.result);
1007c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1008c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Error on GET_SMS with exp " + ar.exception);
1009c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1010c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1011c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SST_DONE:
1012c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1013c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1014c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
1016c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1018c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1019c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1020c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1021c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mUsimServiceTable = new UsimServiceTable(data);
1022c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("SST: " + mUsimServiceTable);
1023c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1024c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1025c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_INFO_CPHS_DONE:
1026c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1027c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1028c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1029c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1030c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1031c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1032c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1033c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1034c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mCphsInfo = (byte[])ar.result;
1035c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1036c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("iCPHS: " + IccUtils.bytesToHexString(mCphsInfo));
1037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1038c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1039c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_MBDN_DONE:
1040c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1041c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1042c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1043c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
104422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mVoiceMailNum = mNewVoiceMailNum;
104522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mVoiceMailTag = mNewVoiceMailTag;
1046c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1047c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1048c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (isCphsMailboxEnabled()) {
104922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    adn = new AdnRecord(mVoiceMailTag, mVoiceMailNum);
1050c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    Message onCphsCompleted = (Message) ar.userObj;
1051c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1052c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    /* write to cphs mailbox whenever it is available but
1053c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * we only need notify caller once if both updating are
1054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * successful.
1055c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    *
1056c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * so if set_mbdn successful, notify caller here and set
1057c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * onCphsCompleted to null
1058c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    */
1059c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.exception == null && ar.userObj != null) {
1060c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        AsyncResult.forMessage(((Message) ar.userObj)).exception
1061c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                = null;
1062c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((Message) ar.userObj).sendToTarget();
1063c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1064c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) log("Callback with MBDN successful.");
1065c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1066c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        onCphsCompleted = null;
1067c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1068c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1069c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).
1070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null,
1071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE,
1072c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    onCphsCompleted));
1073c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1074c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.userObj != null) {
1075c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        AsyncResult.forMessage(((Message) ar.userObj)).exception
1076c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                = ar.exception;
1077c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((Message) ar.userObj).sendToTarget();
1078c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1079c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1080c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1081c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_CPHS_MAILBOX_DONE:
1082c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1083c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1084c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if(ar.exception == null) {
108522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mVoiceMailNum = mNewVoiceMailNum;
108622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mVoiceMailTag = mNewVoiceMailTag;
1087c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1088c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Set CPHS MailBox with exception: "
1089c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + ar.exception);
1090c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1091c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.userObj != null) {
1092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Callback with CPHS MB successful.");
1093c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
1094c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = ar.exception;
1095c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((Message) ar.userObj).sendToTarget();
1096c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1097c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1098c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SIM_REFRESH:
1099c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("Sim REFRESH with exception: " + ar.exception);
1102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
1103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    handleSimRefresh((IccRefreshResponse)ar.result);
1104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CFIS_DONE:
1107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
1111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CFIS: " + IccUtils.bytesToHexString(data));
1117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1118a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                if (validEfCfis(data)) {
1119a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    mEfCfis = data;
1120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1121a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    // Refer TS 51.011 Section 10.3.46 for the content description
112222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCallForwardingEnabled = ((data[1] & 0x01) != 0);
1123e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby                    log("EF_CFIS: callForwardingEnabled=" + mCallForwardingEnabled);
1124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1125a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
1126a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                } else {
1127a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    log("EF_CFIS: invalid data=" + IccUtils.bytesToHexString(data));
1128a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                }
1129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CSP_CPHS_DONE:
1132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Exception in fetching EF_CSP data " + ar.exception);
1138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
1142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CSP: " + IccUtils.bytesToHexString(data));
1144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                handleEfCspData(data);
1145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
11472f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim            case EVENT_GET_GID1_DONE:
11482f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                isRecordLoadResponse = true;
11492f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
11502f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                ar = (AsyncResult)msg.obj;
11512f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                data =(byte[])ar.result;
11522f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
11532f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                if (ar.exception != null) {
11542f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                    loge("Exception in get GID1 " + ar.exception);
1155620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt                    mGid1 = null;
11562f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                    break;
11572f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                }
1158620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt                mGid1 = IccUtils.bytesToHexString(data);
1159620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt                log("GID1: " + mGid1);
11602f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
11612f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                break;
11622f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
1163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                super.handleMessage(msg);   // IccRecords handles generic record load responses
1165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }}catch (RuntimeException exc) {
1167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // I don't want these exceptions to be fatal
1168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            logw("Exception parsing SIM record", exc);
1169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } finally {
1170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Count up record load responses even if they are fails
1171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (isRecordLoadResponse) {
1172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRecordLoaded();
1173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleFileUpdate(int efid) {
1178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch(efid) {
1179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_MBDN:
118022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad++;
1181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
118222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mMailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
1183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_MAILBOX_CPHS:
118522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad++;
1186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
1187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
1188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_CSP_CPHS:
119022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad++;
1191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("[CSP] SIM Refresh for EF_CSP_CPHS");
1192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.loadEFTransparent(EF_CSP_CPHS,
1193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage(EVENT_GET_CSP_CPHS_DONE));
1194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // For now, fetch all records if this is not a
1197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // voicemail number.
1198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // TODO: Handle other cases, instead of fetching all.
119922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mAdnCache.reset();
1200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                fetchSimRecords();
1201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleSimRefresh(IccRefreshResponse refreshResponse){
1206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (refreshResponse == null) {
1207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("handleSimRefresh received without input");
1208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (refreshResponse.aid != null &&
1212e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                !refreshResponse.aid.equals(mParentApp.getAid())) {
1213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // This is for different app. Ignore.
1214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (refreshResponse.refreshResult) {
1218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
1219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_FILE_UPDATED");
1220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                handleFileUpdate(refreshResponse.efId);
1221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_INIT:
1223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_REFRESH_INIT");
1224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // need to reload all files (that we care about)
122564bfd98578babdd437f1a83d2d5e1fc92c76e729Alex Yakavenka                onIccRefreshInit();
1226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_RESET:
1228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET");
1229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mCi.setRadioPower(false, null);
1230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                /* Note: no need to call setRadioPower(true).  Assuming the desired
1231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * radio power state is still ON (as tracked by ServiceStateTracker),
1232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * ServiceStateTracker will call setRadioPower when it receives the
1233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * RADIO_STATE_CHANGED notification for the power off.  And if the
1234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * desired power state has changed in the interim, we don't want to
1235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * override it with an unconditional power on.
1236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                */
1237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // unknown refresh operation
1240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with unknown operation");
1241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1246e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby     * Dispatch 3GPP format message to registrant ({@code GSMPhone} or {@code CDMALTEPhone})
1247e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby     * to pass to the 3GPP SMS dispatcher for delivery.
1248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1249a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hamby    private int dispatchGsmMessage(SmsMessage message) {
1250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNewSmsRegistrants.notifyResult(message);
1251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return 0;
1252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleSms(byte[] ba) {
1255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ba[0] != 0)
125699c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.d("ENF", "status : " + ba[0]);
1257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 3 == "received by MS from network; message to be read"
1260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ba[0] == 3) {
1261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int n = ba.length;
1262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Note: Data may include trailing FF's.  That's OK; message
1264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // should still parse correctly.
1265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] pdu = new byte[n - 1];
1266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            System.arraycopy(ba, 1, pdu, 0, n - 1);
1267a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hamby            SmsMessage message = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP);
1268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            dispatchGsmMessage(message);
1270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1274cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void handleSmses(ArrayList<byte[]> messages) {
1275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int count = messages.size();
1276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0; i < count; i++) {
1278cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            byte[] ba = messages.get(i);
1279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ba[0] != 0)
128199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.i("ENF", "status " + i + ": " + ba[0]);
1282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // 3 == "received by MS from network; message to be read"
1285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ba[0] == 3) {
1287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int n = ba.length;
1288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Note: Data may include trailing FF's.  That's OK; message
1290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // should still parse correctly.
1291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                byte[] pdu = new byte[n - 1];
1292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                System.arraycopy(ba, 1, pdu, 0, n - 1);
1293a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hamby                SmsMessage message = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP);
1294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                dispatchGsmMessage(message);
1296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // 1 == "received by MS from network; message read"
1299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ba[0] = 1;
1301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1302cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (false) { // FIXME: writing seems to crash RdoServD
1303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.updateEFLinearFixed(EF_SMS,
1304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            i, ba, null, obtainMessage(EVENT_MARK_SMS_READ_DONE, i));
1305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1310cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onRecordLoaded() {
1312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // One record loaded successfully or failed, In either case
1313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // we need to update the recordsToLoad count
131422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad -= 1;
131522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("onRecordLoaded " + mRecordsToLoad + " requested: " + mRecordsRequested);
1316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
131722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRecordsToLoad == 0 && mRecordsRequested == true) {
1318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onAllRecordsLoaded();
131922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mRecordsToLoad < 0) {
1320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("recordsToLoad <0, programmer error suspected");
132122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mRecordsToLoad = 0;
1322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1325cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onAllRecordsLoaded() {
1327e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        if (DBG) log("record load complete");
1328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Some fields require more than one SIM record to set
1330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1331e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        String operator = getOperatorNumeric();
1332e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        if (!TextUtils.isEmpty(operator)) {
1333e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            log("onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
1334e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville                    operator + "'");
1335e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
1336e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        } else {
1337e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            log("onAllRecordsLoaded empty 'gsm.sim.operator.numeric' skipping");
1338e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        }
1339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1340e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        if (!TextUtils.isEmpty(mImsi)) {
1341e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            log("onAllRecordsLoaded set mcc imsi=" + mImsi);
1342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
1343e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3))));
1344e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        } else {
1345e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            log("onAllRecordsLoaded empty imsi skipping setting mcc");
1346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        setVoiceMailByCountry(operator);
1349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        setSpnFromConfig(operator);
1350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1351b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville        mRecordsLoadedRegistrants.notifyRegistrants(
1352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AsyncResult(null, null, null));
1353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //***** Private methods
1356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setSpnFromConfig(String carrier) {
1358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mSpnOverride.containsCarrier(carrier)) {
135922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSpn = mSpnOverride.getSpn(carrier);
1360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setVoiceMailByCountry (String spn) {
1365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mVmConfig.containsCarrier(spn)) {
136622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mIsVoiceMailFixed = true;
136722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceMailNum = mVmConfig.getVoiceMailNumber(spn);
136822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceMailTag = mVmConfig.getVoiceMailTag(spn);
1369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void onReady() {
1374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        fetchSimRecords();
1375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void fetchSimRecords() {
137822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsRequested = true;
1379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
138022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("fetchSimRecords " + mRecordsToLoad);
1381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1382e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
138322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
138622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // FIXME should examine EF[MSISDN]'s capability configuration
1389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // to determine which is the voice/data/fax line
1390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1,
1391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_GET_MSISDN_DONE));
139222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Record number is subscriber profile
1395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE));
139622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
139922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Record number is subscriber profile
1402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE));
140322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Also load CPHS-style voice mail indicator, which stores
1407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // the same info as EF[MWIS]. If both exist, both are updated
1408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // but the EF[MWIS] data is preferred
1409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Please note this must be loaded after EF[MWIS]
1410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(
1411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                EF_VOICE_MAIL_INDICATOR_CPHS,
1412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));
141322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Same goes for Call Forward Status indicator: fetch both
1416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
1417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
141822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
142022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        getSpnFsm(true, null);
1424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE));
142622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE));
142922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
143222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
143522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
143822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
14402f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim        mFh.loadEFTransparent(EF_GID1, obtainMessage(EVENT_GET_GID1_DONE));
1441620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt        mRecordsToLoad++;
1442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // XXX should seek instead of examining them all
1444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (false) { // XXX
1445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
144622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mRecordsToLoad++;
1447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (CRASH_RIL) {
1450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String sms = "0107912160130310f20404d0110041007030208054832b0120"
1451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "ffffffffffffffffffffffffffffff";
1456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] ba = IccUtils.hexStringToBytes(sms);
1457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
1459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
1460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
146122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("fetchSimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested);
1462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Returns the SpnDisplayRule based on settings on the SIM and the
1466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * specified plmn (currently-registered PLMN).  See TS 22.101 Annex A
1467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * and TS 51.011 10.3.11 for details.
1468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
14692bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati     * If the SPN is not found on the SIM or is empty, the rule is
14702bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati     * always PLMN_ONLY.
1471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public int getDisplayRule(String plmn) {
1474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int rule;
147522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (TextUtils.isEmpty(mSpn) || mSpnDisplayCondition == -1) {
14762bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati            // No EF_SPN content was found on the SIM, or not yet loaded.  Just show ONS.
1477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_PLMN;
1478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (isOnMatchingPlmn(plmn)) {
1479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_SPN;
148022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if ((mSpnDisplayCondition & 0x01) == 0x01) {
1481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // ONS required when registered to HPLMN or PLMN in EF_SPDI
1482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                rule |= SPN_RULE_SHOW_PLMN;
1483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_PLMN;
148622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if ((mSpnDisplayCondition & 0x02) == 0x00) {
1487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // SPN required if not registered to HPLMN or PLMN in EF_SPDI
1488c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                rule |= SPN_RULE_SHOW_SPN;
1489c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return rule;
1492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Checks if plmn is HPLMN or on the spdiNetworks list.
1496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean isOnMatchingPlmn(String plmn) {
1498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmn == null) return false;
1499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmn.equals(getOperatorNumeric())) {
1501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return true;
1502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
150422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSpdiNetworks != null) {
150522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (String spdiNet : mSpdiNetworks) {
1506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (plmn.equals(spdiNet)) {
1507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    return true;
1508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return false;
1512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * States of Get SPN Finite State Machine which only used by getSpnFsm()
1516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
151722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private enum GetSpnFsmState {
1518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        IDLE,               // No initialized
1519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        INIT,               // Start FSM
1520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_3GPP,      // Load EF_SPN firstly
1521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_CPHS,      // Load EF_SPN_CPHS secondly
1522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last
1523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Finite State Machine to load Service Provider Name , which can be stored
1527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2)
1528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * After starting, FSM will search SPN EFs in order and stop after finding
1530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the first valid SPN
1531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If the FSM gets restart while waiting for one of
1533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * SPN EFs results (i.e. a SIM refresh occurs after issuing
1534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * read EF_CPHS_SPN), it will re-initialize only after
1535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * receiving and discarding the unfinished SPN EF result.
1536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param start set true only for initialize loading
1538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param ar the AsyncResult from loadEFTransparent
1539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ar.exception holds exception in error
1540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ar.result is byte[] for data in success
1541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void getSpnFsm(boolean start, AsyncResult ar) {
1543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte[] data;
1544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (start) {
1546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Check previous state to see if there is outstanding
1547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // SPN read
154822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if(mSpnState == GetSpnFsmState.READ_SPN_3GPP ||
154922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville               mSpnState == GetSpnFsmState.READ_SPN_CPHS ||
155022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville               mSpnState == GetSpnFsmState.READ_SPN_SHORT_CPHS ||
155122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville               mSpnState == GetSpnFsmState.INIT) {
1552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Set INIT then return so the INIT code
1553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // will run when the outstanding read done.
155422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.INIT;
1555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return;
1556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
155722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.INIT;
1558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
156122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        switch(mSpnState){
1562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case INIT:
156322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpn = null;
1564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.loadEFTransparent(EF_SPN,
1566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage(EVENT_GET_SPN_DONE));
156722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad++;
1568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
156922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.READ_SPN_3GPP;
1570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_3GPP:
1572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
157422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnDisplayCondition = 0xff & data[0];
157522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpn = IccUtils.adnStringFieldToString(data, 1, data.length - 1);
1576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
157722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (DBG) log("Load EF_SPN: " + mSpn
157822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            + " spnDisplayCondition: " + mSpnDisplayCondition);
157922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, mSpn);
1580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
158122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnState = GetSpnFsmState.IDLE;
1582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFTransparent( EF_SPN_CPHS,
1584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_SPN_DONE));
158522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mRecordsToLoad++;
1586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
158722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnState = GetSpnFsmState.READ_SPN_CPHS;
1588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // See TS 51.011 10.3.11.  Basically, default to
1590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // show PLMN always, and SPN also if roaming.
159122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnDisplayCondition = -1;
1592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_CPHS:
1595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
159722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpn = IccUtils.adnStringFieldToString(data, 0, data.length);
1598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
159922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (DBG) log("Load EF_SPN_CPHS: " + mSpn);
160022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, mSpn);
1601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
160222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnState = GetSpnFsmState.IDLE;
1603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFTransparent(
1605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE));
160622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mRecordsToLoad++;
1607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
160822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnState = GetSpnFsmState.READ_SPN_SHORT_CPHS;
1609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_SHORT_CPHS:
1612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
161422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpn = IccUtils.adnStringFieldToString(data, 0, data.length);
1615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
161622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (DBG) log("Load EF_SPN_SHORT_CPHS: " + mSpn);
161722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, mSpn);
1618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }else {
1619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("No SPN loaded in either CHPS or 3GPP");
1620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
162222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.IDLE;
1623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
162522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.IDLE;
1626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Parse TS 51.011 EF[SPDI] record
1631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * This record contains the list of numeric network IDs that
1632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * are treated specially when determining SPN display
1633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void
1635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    parseEfSpdi(byte[] data) {
1636c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SimTlv tlv = new SimTlv(data, 0, data.length);
1637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte[] plmnEntries = null;
1639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for ( ; tlv.isValidObject() ; tlv.nextObject()) {
1641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Skip SPDI tag, if existant
1642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (tlv.getTag() == TAG_SPDI) {
1643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville              tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
1644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // There should only be one TAG_SPDI_PLMN_LIST
1646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
1647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                plmnEntries = tlv.getData();
1648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmnEntries == null) {
1653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
165622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mSpdiNetworks = new ArrayList<String>(plmnEntries.length / 3);
1657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0 ; i + 2 < plmnEntries.length ; i += 3) {
1659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String plmnCode;
1660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            plmnCode = IccUtils.bcdToString(plmnEntries, i, 3);
1661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Valid operator codes are 5 or 6 digits
1663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (plmnCode.length() >= 5) {
1664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_SPDI network: " + plmnCode);
166522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpdiNetworks.add(plmnCode);
1666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * check to see if Mailbox Number is allocated and activated in CPHS SST
1672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean isCphsMailboxEnabled() {
1674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mCphsInfo == null)  return false;
1675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED );
1676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1678cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void log(String s) {
168099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d(LOG_TAG, "[SIMRecords] " + s);
1681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1683cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void loge(String s) {
168599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.e(LOG_TAG, "[SIMRecords] " + s);
1686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void logw(String s, Throwable tr) {
168999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.w(LOG_TAG, "[SIMRecords] " + s, tr);
1690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void logv(String s) {
169399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.v(LOG_TAG, "[SIMRecords] " + s);
1694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Return true if "Restriction of menu options for manual PLMN selection"
1698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * bit is set or EF_CSP data is unavailable, return false otherwise.
1699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1700cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean isCspPlmnEnabled() {
1702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mCspPlmnEnabled;
1703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1704c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1705c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Parse EF_CSP data and check if
1707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * "Restriction of menu options for manual PLMN selection" is
1708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Enabled/Disabled
1709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param data EF_CSP hex data.
1711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleEfCspData(byte[] data) {
1713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
1714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 18 bytes (i.e 9 service groups info) and additional data specific to
1715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // operator. The valueAddedServicesGroup is not part of standard
1716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // services. This is operator specific and can be programmed any where.
1717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Normally this is programmed as 10th service after the standard
1718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // services.
1719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int usedCspGroups = data.length / 2;
1720e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby        // This is the "Service Group Number" of "Value Added Services Group".
1721c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte valueAddedServicesGroup = (byte)0xC0;
1722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCspPlmnEnabled = true;
1724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0; i < usedCspGroups; i++) {
1725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             if (data[2 * i] == valueAddedServicesGroup) {
1726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 log("[CSP] found ValueAddedServicesGroup, value " + data[(2 * i) + 1]);
1727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 if ((data[(2 * i) + 1] & 0x80) == 0x80) {
1728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Bit 8 is for
1729c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // "Restriction of menu options for manual PLMN selection".
1730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection menu should be enabled.
1731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mCspPlmnEnabled = true;
1732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 } else {
1733c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mCspPlmnEnabled = false;
1734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection menu should be disabled.
1735c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection Mode should be set to Automatic.
1736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     log("[CSP] Set Automatic Network Selection");
1737c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mNetworkSelectionModeAutomaticRegistrants.notifyRegistrants();
1738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 }
1739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 return;
1740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             }
1741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("[CSP] Value Added Service Group (0xC0), not found!");
1744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
174505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka
174605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    @Override
174705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
174805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println("SIMRecords: " + this);
174905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" extends:");
175005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        super.dump(fd, pw, args);
175105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mVmConfig=" + mVmConfig);
175205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mSpnOverride=" + mSpnOverride);
175322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCallForwardingEnabled=" + mCallForwardingEnabled);
175422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSpnState=" + mSpnState);
175505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mCphsInfo=" + mCphsInfo);
175605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mCspPlmnEnabled=" + mCspPlmnEnabled);
175722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mEfMWIS[]=" + Arrays.toString(mEfMWIS));
175822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mEfCPHS_MWI[]=" + Arrays.toString(mEfCPHS_MWI));
175905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mEfCff[]=" + Arrays.toString(mEfCff));
176005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mEfCfis[]=" + Arrays.toString(mEfCfis));
176122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSpnDisplayCondition=" + mSpnDisplayCondition);
176222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSpdiNetworks[]=" + mSpdiNetworks);
176322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPnnHomeName=" + mPnnHomeName);
176405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mUsimServiceTable=" + mUsimServiceTable);
1765620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt        pw.println(" mGid1=" + mGid1);
176605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.flush();
176705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    }
1768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
1769