SIMRecords.java revision 68515b655255005f653aec29e9f152412514982a
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;
26a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.TelephonyManager;
2731ae682ff511ddde4073c3f94eff15da2f7fade6Wink Savilleimport android.telephony.PhoneNumberUtils;
28a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hambyimport android.telephony.SmsMessage;
292bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapatiimport android.text.TextUtils;
3099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.CommandsInterface;
33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.MccTable;
34a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hambyimport com.android.internal.telephony.SmsConstants;
35d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.gsm.SimTlv;
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
3705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.FileDescriptor;
3805ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.io.PrintWriter;
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
4005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenkaimport java.util.Arrays;
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic class SIMRecords extends IccRecords {
46cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    protected static final String LOG_TAG = "SIMRecords";
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final boolean CRASH_RIL = false;
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Instance Variables
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    VoiceMailConstants mVmConfig;
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    SpnOverride mSpnOverride;
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Cached SIM State; cleared on channel close
58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
5922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mCallForwardingEnabled;
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * States only used by getSpnFsm FSM
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
6522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private GetSpnFsmState mSpnState;
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** CPHS service information (See CPHS 4.2 B.3.1.1)
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  It will be set in onSimReady if reading GET_CPHS_INFO successfully
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  mCphsInfo[0] is CPHS Phase
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private byte[] mCphsInfo = null;
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    boolean mCspPlmnEnabled = true;
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
7522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    byte[] mEfMWIS = null;
7622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    byte[] mEfCPHS_MWI =null;
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    byte[] mEfCff = null;
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    byte[] mEfCfis = null;
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
8122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mSpnDisplayCondition;
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Numeric network codes listed in TS 51.011 EF[SPDI]
8322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    ArrayList<String> mSpdiNetworks = null;
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
8522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPnnHomeName = null;
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    UsimServiceTable mUsimServiceTable;
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
89f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
90f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    public String toString() {
91f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return "SimRecords: " + super.toString()
92f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mVmConfig" + mVmConfig
93f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mSpnOverride=" + "mSpnOverride"
9422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " callForwardingEnabled=" + mCallForwardingEnabled
9522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " spnState=" + mSpnState
96f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mCphsInfo=" + mCphsInfo
97f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mCspPlmnEnabled=" + mCspPlmnEnabled
9822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " efMWIS=" + mEfMWIS
9922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                + " efCPHS_MWI=" + mEfCPHS_MWI
100f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mEfCff=" + mEfCff
101f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mEfCfis=" + mEfCfis
102f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " getOperatorNumeric=" + getOperatorNumeric();
103f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    }
104f92cb4bd5519427a0db673709d94683a8baf203aWink Saville
105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Constants
106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // From TS 51.011 EF[SPDI] section
108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SPDI = 0xA3;
109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SPDI_PLMN_LIST = 0x80;
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Full Name IEI from TS 24.008
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_FULL_NETWORK_NAME = 0x43;
113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Short Name IEI from TS 24.008
115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SHORT_NETWORK_NAME = 0x45;
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // active CFF from CPHS 4.2 B.4.5
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_LINE1_MASK = 0x0f;
121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_LINE1_RESET = 0xf0;
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // CPHS Service Table (See CPHS 4.2 B.3.1)
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int CPHS_SST_MBN_MASK = 0x30;
125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int CPHS_SST_MBN_ENABLED = 0x30;
126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
12731ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    // EF_CFIS related constants
12831ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    // Spec reference TS 51.011 section 10.3.46.
12931ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    private static final int CFIS_BCD_NUMBER_LENGTH_OFFSET = 2;
13031ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    private static final int CFIS_TON_NPI_OFFSET = 3;
13131ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    private static final int CFIS_ADN_CAPABILITY_ID_OFFSET = 14;
13231ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    private static final int CFIS_ADN_EXTENSION_ID_OFFSET = 15;
13331ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Event Constants
135e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_GET_IMSI_DONE = 3;
136e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_GET_ICCID_DONE = 4;
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MBI_DONE = 5;
138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MBDN_DONE = 6;
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MWIS_DONE = 7;
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8;
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_MSISDN_DONE = 10;
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11;
144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SPN_DONE = 12;
145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SPDI_DONE = 13;
146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_UPDATE_DONE = 14;
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_PNN_DONE = 15;
148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_SST_DONE = 17;
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_ALL_SMS_DONE = 18;
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_MARK_SMS_READ_DONE = 19;
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SET_MBDN_DONE = 20;
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SMS_ON_SIM = 21;
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SMS_DONE = 22;
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CFF_DONE = 24;
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25;
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_INFO_CPHS_DONE = 26;
157cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    // private static final int EVENT_SET_MSISDN_DONE = 30; Defined in IccRecords as 30
158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SIM_REFRESH = 31;
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CFIS_DONE = 32;
160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CSP_CPHS_DONE = 33;
1612f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim    private static final int EVENT_GET_GID1_DONE = 34;
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
1660530f592d89c1eceea7ee5bccb2359061a04f968duho.ro        "302370", "302720", "310260",
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914",
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922",
181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930",
1820530f592d89c1eceea7ee5bccb2359061a04f968duho.ro        "405931", "405932", "502142", "502143", "502145", "502146", "502147", "502148"
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Constructor
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
187e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
188e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        super(app, c, ci);
189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mAdnCache = new AdnRecordCache(mFh);
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mVmConfig = new VoiceMailConstants();
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mSpnOverride = new SpnOverride();
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsRequested = false;  // No load request is made till SIM ready
196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // recordsToLoad is set to 0 because no requests are made yet
19822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad = 0;
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Start off by setting empty state
204e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        resetRecords();
205e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mParentApp.registerForReady(this, EVENT_APP_READY, null);
206f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (DBG) log("SIMRecords X ctor this=" + this);
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dispose() {
211f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (DBG) log("Disposing SIMRecords this=" + this);
212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        //Unregister for all events
213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.unregisterForIccRefresh(this);
214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.unSetOnSmsOnSim(this);
215e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mParentApp.unregisterForReady(this);
216e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        resetRecords();
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        super.dispose();
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
220cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void finalize() {
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if(DBG) log("finalized");
223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
225e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    protected void resetRecords() {
226e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mImsi = null;
22722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMsisdn = null;
22822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mVoiceMailNum = null;
22922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCountVoiceMessages = 0;
23022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMncLength = UNINITIALIZED;
231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("setting0 mMncLength" + mMncLength);
232b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville        mIccId = null;
233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // -1 means no EF_SPN found; treat accordingly.
23422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mSpnDisplayCondition = -1;
23522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mEfMWIS = null;
23622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mEfCPHS_MWI = null;
23722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mSpdiNetworks = null;
23822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPnnHomeName = null;
239620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt        mGid1 = null;
240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
24122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mAdnCache.reset();
242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("SIMRecords: onRadioOffOrNotAvailable set 'gsm.sim.operator.numeric' to operator=null");
244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("update icc_operator_numeric=" + null);
245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null);
246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, null);
247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // recordsRequested is set to false indicating that the SIM
250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // read requests made so far are not valid. This is set to
251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // true only when fresh set of read requests are made.
25222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsRequested = false;
253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //***** Public Methods
257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getIMSI() {
263e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mImsi;
264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
266cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getMsisdnNumber() {
26822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mMsisdn;
269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
2722f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim    public String getGid1() {
273620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt        return mGid1;
2742f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim    }
2752f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
2762f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim    @Override
277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public UsimServiceTable getUsimServiceTable() {
278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mUsimServiceTable;
279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set subscriber number to SIM record
283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The subscriber number is stored in EF_MSISDN (TS 51.011)
285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * When the operation is complete, onComplete will be sent to its handler
287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param number dailing nubmer (up to 20 digits)
290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        if the number starts with '+', then set to international TOA
291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param onComplete
292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        onComplete.obj will be an AsyncResult
293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception == null on success
294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception != null on fail
295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setMsisdnNumber(String alphaTag, String number,
298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message onComplete) {
299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMsisdn = number;
30122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMsisdnTag = alphaTag;
302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if(DBG) log("Set MSISDN: " + mMsisdnTag + " " + /*mMsisdn*/ "xxxxxxx");
304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        AdnRecord adn = new AdnRecord(mMsisdnTag, mMsisdn);
307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
312cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getMsisdnAlphaTag() {
31422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mMsisdnTag;
315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
317cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getVoiceMailNumber() {
31922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mVoiceMailNum;
320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set voice mail number to SIM record
324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The voice mail number can be stored either in EF_MBDN (TS 51.011) or
326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * EF_MAILBOX_CPHS (CPHS 4.2)
327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If EF_MBDN is available, store the voice mail number to EF_MBDN
329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * So the voice mail number will be stored in both EFs if both are available
333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * When the operation is complete, onComplete will be sent to its handler
337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param voiceNumber dailing nubmer (upto 20 digits)
340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        if the number is start with '+', then set to international TOA
341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param onComplete
342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        onComplete.obj will be an AsyncResult
343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception == null on success
344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception != null on fail
345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
346cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setVoiceMailNumber(String alphaTag, String voiceNumber,
348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message onComplete) {
34922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mIsVoiceMailFixed) {
350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AsyncResult.forMessage((onComplete)).exception =
351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new IccVmFixedException("Voicemail number is fixed by operator");
352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onComplete.sendToTarget();
353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
35622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewVoiceMailNum = voiceNumber;
35722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNewVoiceMailTag = alphaTag;
358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
35922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        AdnRecord adn = new AdnRecord(mNewVoiceMailTag, mNewVoiceMailNum);
360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
36122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mMailboxIndex != 0 && mMailboxIndex != 0xff) {
362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AdnRecordLoader(mFh).updateEF(adn, EF_MBDN, EF_EXT6,
36422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mMailboxIndex, null,
365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_SET_MBDN_DONE, onComplete));
366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (isCphsMailboxEnabled()) {
368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS,
370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    EF_EXT1, 1, null,
371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete));
372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AsyncResult.forMessage((onComplete)).exception =
375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new IccVmNotSupportedException("Update SIM voice mailbox error");
376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onComplete.sendToTarget();
377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
380cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getVoiceMailAlphaTag()
382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    {
38322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mVoiceMailTag;
384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Sets the SIM voice message waiting indicator records
388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param countWaiting The number of messages waiting, if known. Use
390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *                     -1 to indicate that an unknown number of
391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *                      messages are waiting
392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
393cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void
395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    setVoiceMessageWaiting(int line, int countWaiting) {
396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (line != 1) {
397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // only profile 1 is supported
398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // range check
402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (countWaiting < 0) {
403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            countWaiting = -1;
404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (countWaiting > 0xff) {
405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // TS 23.040 9.2.3.24.2
406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // "The value 255 shall be taken to mean 255 or greater"
407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            countWaiting = 0xff;
408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
41022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCountVoiceMessages = countWaiting;
411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
41522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mEfMWIS != null) {
416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // TS 51.011 10.3.45
417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // lsb of byte 0 is 'voicemail' status
41922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mEfMWIS[0] = (byte)((mEfMWIS[0] & 0xfe)
42022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                    | (mCountVoiceMessages == 0 ? 0 : 1));
421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // byte 1 is the number of voice messages waiting
423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (countWaiting < 0) {
424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // The spec does not define what this should be
425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // if we don't know the count
42622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mEfMWIS[1] = 0;
427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
42822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mEfMWIS[1] = (byte) countWaiting;
429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFLinearFixed(
43222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    EF_MWIS, 1, mEfMWIS, null,
433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage (EVENT_UPDATE_DONE, EF_MWIS));
434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
43622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mEfCPHS_MWI != null) {
437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer CPHS4_2.WW6 B4.2.3
43822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mEfCPHS_MWI[0] = (byte)((mEfCPHS_MWI[0] & 0xf0)
43922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            | (mCountVoiceMessages == 0 ? 0x5 : 0xa));
440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFTransparent(
44222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    EF_VOICE_MAIL_INDICATOR_CPHS, mEfCPHS_MWI,
443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS));
444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (ArrayIndexOutOfBoundsException ex) {
446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            logw("Error saving voice mail state to SIM. Probably malformed SIM record", ex);
447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
450a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    // Validate data is !null and the MSP (Multiple Subscriber Profile)
451a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    // byte is between 1 and 4. See ETSI TS 131 102 v11.3.0 section 4.2.64.
452a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    private boolean validEfCfis(byte[] data) {
453a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville        return ((data != null) && (data[0] >= 1) && (data[0] <= 4));
454a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    }
455a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville
456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean getVoiceCallForwardingFlag() {
46122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mCallForwardingEnabled;
462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
46831ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville    public void setVoiceCallForwardingFlag(int line, boolean enable, String dialNumber) {
469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (line != 1) return; // only line 1 is supported
471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
47222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCallForwardingEnabled = enable;
473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
477a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville            if (validEfCfis(mEfCfis)) {
478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // lsb is of byte 1 is voice status
479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (enable) {
480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCfis[1] |= 1;
481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCfis[1] &= 0xfe;
483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
485a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                log("setVoiceCallForwardingFlag: enable=" + enable
486a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                        + " mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));
487a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville
48831ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                // Update dialNumber if not empty and CFU is enabled.
48931ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                // Spec reference for EF_CFIS contents, TS 51.011 section 10.3.46.
49031ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                if (enable && !TextUtils.isEmpty(dialNumber)) {
49131ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    log("EF_CFIS: updating cf number, " + dialNumber);
49231ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    byte[] bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(dialNumber);
49331ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville
49431ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    System.arraycopy(bcdNumber, 0, mEfCfis, CFIS_TON_NPI_OFFSET, bcdNumber.length);
49531ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville
49631ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    mEfCfis[CFIS_BCD_NUMBER_LENGTH_OFFSET] = (byte) (bcdNumber.length);
49731ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    mEfCfis[CFIS_ADN_CAPABILITY_ID_OFFSET] = (byte) 0xFF;
49831ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                    mEfCfis[CFIS_ADN_EXTENSION_ID_OFFSET] = (byte) 0xFF;
49931ae682ff511ddde4073c3f94eff15da2f7fade6Wink Saville                }
500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFLinearFixed(
502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EF_CFIS, 1, mEfCfis, null,
503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage (EVENT_UPDATE_DONE, EF_CFIS));
504a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville            } else {
505a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                log("setVoiceCallForwardingFlag: ignoring enable=" + enable
506a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                        + " invalid mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));
507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (mEfCff != null) {
510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (enable) {
511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            | CFF_UNCONDITIONAL_ACTIVE);
513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            | CFF_UNCONDITIONAL_DEACTIVE);
516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFTransparent(
519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EF_CFF_CPHS, mEfCff,
520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (ArrayIndexOutOfBoundsException ex) {
523e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby            logw("Error saving call forwarding flag to SIM. "
524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + "Probably malformed SIM record", ex);
525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Called by STK Service when REFRESH is received.
531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param fileChanged indicates whether any files changed
532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param fileList if non-null, a list of EF files that changed
533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
534cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void onRefresh(boolean fileChanged, int[] fileList) {
536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (fileChanged) {
537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // A future optimization would be to inspect fileList and
538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // only reload those files that we care about.  For now,
539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // just re-fetch all SIM records that we cache.
540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            fetchSimRecords();
541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getOperatorNumeric() {
549e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mImsi == null) {
550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("getOperatorNumeric: IMSI == null");
551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return null;
552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
55322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mMncLength == UNINITIALIZED || mMncLength == UNKNOWN) {
554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("getSIMOperatorNumeric: bad mncLength");
555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return null;
556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Length = length of MCC + length of MNC
559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // length of mcc = 3 (TS 23.003 Section 2.2)
56022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mImsi.substring(0, 3 + mMncLength);
561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Overridden from Handler
564cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void handleMessage(Message msg) {
566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AsyncResult ar;
567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AdnRecord adn;
568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte data[];
570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean isRecordLoadResponse = false;
572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
573bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (mDestroyed.get()) {
574c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("Received message " + msg + "[" + msg.what + "] " +
575c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    " while being destroyed. Ignoring.");
576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try { switch (msg.what) {
580e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_APP_READY:
581e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onReady();
582e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            /* IO events */
585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_IMSI_DONE:
586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Exception querying IMSI, Exception:" + ar.exception);
592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
595e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mImsi = (String) ar.result;
596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // than 15 (and usually 15).
599e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
600e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    loge("invalid IMSI " + mImsi);
601e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    mImsi = null;
602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
604a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("IMSI: mMncLength=" + mMncLength);
605a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxx");
606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
60722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (((mMncLength == UNKNOWN) || (mMncLength == 2)) &&
608e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        ((mImsi != null) && (mImsi.length() >= 6))) {
609e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    String mccmncCode = mImsi.substring(0, 6);
610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (mccmnc.equals(mccmncCode)) {
61222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mMncLength = 3;
613a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            log("IMSI: setting1 mMncLength=" + mMncLength);
614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            break;
615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
61922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mMncLength == UNKNOWN) {
620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // the SIM has told us all it knows, but it didn't know the mnc length.
621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // guess using the mcc
622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    try {
623e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        int mcc = Integer.parseInt(mImsi.substring(0,3));
62422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mMncLength = MccTable.smallestDigitsMccForMnc(mcc);
625a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        log("setting2 mMncLength=" + mMncLength);
626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } catch (NumberFormatException e) {
62722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mMncLength = UNKNOWN;
628a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        loge("Corrupt IMSI! setting3 mMncLength=" + mMncLength);
629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
63222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mMncLength != UNKNOWN && mMncLength != UNINITIALIZED) {
633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("update mccmnc=" + mImsi.substring(0, 3 + mMncLength));
634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // finally have both the imsi and the mncLength and can parse the imsi properly
635b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    MccTable.updateMccMncConfiguration(mContext,
636b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                            mImsi.substring(0, 3 + mMncLength), false);
637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
638e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mImsiReadyRegistrants.notifyRegistrants();
639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MBI_DONE:
642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean isValidMbdn;
643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[]) ar.result;
647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isValidMbdn = false;
649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer TS 51.011 Section 10.3.44 for content details
651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("EF_MBI: " + IccUtils.bytesToHexString(data));
652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Voice mail record number stored first
65422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mMailboxIndex = data[0] & 0xff;
655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // check if dailing numbe id valid
65722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mMailboxIndex != 0 && mMailboxIndex != 0xff) {
658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("Got valid mailbox number for MBDN");
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        isValidMbdn = true;
660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // one more record to load
66422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad += 1;
665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (isValidMbdn) {
667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Note: MBDN was not included in NUM_OF_SIM_RECORDS_LOADED
668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
66922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mMailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // If this EF not present, try mailbox as in CPHS standard
672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // CPHS (CPHS4_2.WW6) is a european standard.
673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS,
674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_EXT1, 1,
675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CPHS_MAILBOX_DONE:
680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MBDN_DONE:
681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //Resetting the voice mail number and voice mail tag to null
682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //as these should be updated from the data read from EF_MBDN.
683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //If they are not reset, incase of invalid data/exception these
684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //variables are retaining their previous values and are
685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //causing invalid voice mailbox info display to user.
68622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mVoiceMailNum = null;
68722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mVoiceMailTag = null;
688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Invalid or missing EF"
695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]"));
696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Bug #645770 fall back to CPHS
698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME should use SST to decide
699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (msg.what == EVENT_GET_MBDN_DONE) {
701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        //load CPHS on fail...
702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // FIXME right now, only load line1's CPHS voice mail entry
703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
70422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mRecordsToLoad += 1;
705c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        new AdnRecordLoader(mFh).loadFromEF(
706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                EF_MAILBOX_CPHS, EF_EXT1, 1,
707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                adn = (AdnRecord)ar.result;
713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("VM: " + adn +
715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) {
718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Bug #645770 fall back to CPHS
719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME should use SST to decide
720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME right now, only load line1's CPHS voice mail entry
72122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mRecordsToLoad += 1;
722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(
723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_MAILBOX_CPHS, EF_EXT1, 1,
724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
72922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mVoiceMailNum = adn.getNumber();
73022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mVoiceMailTag = adn.getAlphaTag();
731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
733c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MSISDN_DONE:
734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
735c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
737c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Invalid or missing EF[MSISDN]");
740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                adn = (AdnRecord)ar.result;
744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
74522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mMsisdn = adn.getNumber();
74622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mMsisdnTag = adn.getAlphaTag();
747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
74822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                log("MSISDN: " + /*mMsisdn*/ "xxxxxxx");
749c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_MSISDN_DONE:
752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
753c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.userObj != null) {
756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
757c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = ar.exception;
758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((Message) ar.userObj).sendToTarget();
759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
762c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MWIS_DONE:
763c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
764c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
769c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
770c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
771c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_MWIS: " + IccUtils.bytesToHexString(data));
773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
77422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mEfMWIS = data;
775c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
776c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if ((data[0] & 0xff) == 0xff) {
777c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Uninitialized record MWIS");
778c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
779c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
780c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Refer TS 51.011 Section 10.3.45 for the content description
782c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean voiceMailWaiting = ((data[0] & 0x01) != 0);
78322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCountVoiceMessages = data[1] & 0xff;
784c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
78522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (voiceMailWaiting && mCountVoiceMessages == 0) {
786c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Unknown count = -1
78722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCountVoiceMessages = -1;
788c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
789c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
790c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
791c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
792c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
793c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE:
794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
795c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
797c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
798c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
799c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
800c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
801c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
802c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
80322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mEfCPHS_MWI = data;
804c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Use this data if the EF[MWIS] exists and
806c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // has been loaded
807c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
80822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mEfMWIS == null) {
809cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    int indicator = data[0] & 0xf;
810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
811c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer CPHS4_2.WW6 B4.2.3
812c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (indicator == 0xA) {
813c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // Unknown count = -1
81422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mCountVoiceMessages = -1;
815c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else if (indicator == 0x5) {
81622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mCountVoiceMessages = 0;
817c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
818c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
819c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
820c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
821c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
823c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_ICCID_DONE:
824c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
825c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
826c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
827c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
828c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
829c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
833b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville                mIccId = IccUtils.bcdToString(data, 0, data.length);
834c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
835b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville                log("iccid: " + mIccId);
836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
837c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
840c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_AD_DONE:
841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                try {
842c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    isRecordLoadResponse = true;
843c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
844c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult)msg.obj;
845c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[])ar.result;
846c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
847c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.exception != null) {
848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
850c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
851c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("EF_AD: " + IccUtils.bytesToHexString(data));
852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
853c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (data.length < 3) {
854c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("Corrupt AD data on SIM");
855c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
856c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
857c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
858c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (data.length == 3) {
859c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("MNC length not present in EF_AD");
860c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
861c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
862c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
86322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mMncLength = data[3] & 0xf;
864a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("setting4 mMncLength=" + mMncLength);
865c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
86622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mMncLength == 0xf) {
86722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mMncLength = UNKNOWN;
868a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        log("setting5 mMncLength=" + mMncLength);
869c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } finally {
87122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (((mMncLength == UNINITIALIZED) || (mMncLength == UNKNOWN) ||
87222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            (mMncLength == 2)) && ((mImsi != null) && (mImsi.length() >= 6))) {
873e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        String mccmncCode = mImsi.substring(0, 6);
874a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        log("mccmncCode=" + mccmncCode);
875c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
876c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (mccmnc.equals(mccmncCode)) {
87722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mMncLength = 3;
878a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                                log("setting6 mMncLength=" + mMncLength);
879c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                break;
880c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
881c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
882c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
883c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
88422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mMncLength == UNKNOWN || mMncLength == UNINITIALIZED) {
885e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        if (mImsi != null) {
886c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            try {
887e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                                int mcc = Integer.parseInt(mImsi.substring(0,3));
888c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
88922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mMncLength = MccTable.smallestDigitsMccForMnc(mcc);
890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                                log("setting7 mMncLength=" + mMncLength);
891c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            } catch (NumberFormatException e) {
89222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mMncLength = UNKNOWN;
893a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                                loge("Corrupt IMSI! setting8 mMncLength=" + mMncLength);
894c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
895c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } else {
896c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // Indicate we got this info, but it didn't contain the length.
89722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mMncLength = UNKNOWN;
898a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            log("MNC length not present in EF_AD setting9 mMncLength=" + mMncLength);
899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
900c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
90122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mImsi != null && mMncLength != UNKNOWN) {
902c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // finally have both imsi and the length of the mnc and can parse
903c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // the imsi properly
904a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        log("update mccmnc=" + mImsi.substring(0, 3 + mMncLength));
905c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        MccTable.updateMccMncConfiguration(mContext,
906b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                                mImsi.substring(0, 3 + mMncLength), false);
907c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
908c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
909c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
910c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
911c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SPN_DONE:
912c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
914c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                getSpnFsm(false, ar);
915c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
916c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
917c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CFF_DONE:
918c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
919c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
920c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
921c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[]) ar.result;
922c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
923c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
924c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
927c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
928c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mEfCff = data;
929c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
930e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby                // if EF_CFIS is valid, prefer it to EF_CFF_CPHS
931e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby                if (!validEfCfis(mEfCfis)) {
93222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCallForwardingEnabled =
933c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE);
934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
936a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                } else {
937e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby                    log("EVENT_GET_CFF_DONE: EF_CFIS is valid, ignoring EF_CFF_CPHS");
938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SPDI_DONE:
942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
943c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
944c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
947c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
948c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
949c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                parseEfSpdi(data);
952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_UPDATE_DONE:
955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    logw("update failed. ", ar.exception);
958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
960c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
961c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_PNN_DONE:
962c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
963c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
964c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
965c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
966c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
967c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
971c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                SimTlv tlv = new SimTlv(data, 0, data.length);
972c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                for ( ; tlv.isValidObject() ; tlv.nextObject()) {
974c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (tlv.getTag() == TAG_FULL_NETWORK_NAME) {
97522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mPnnHomeName
976c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = IccUtils.networkNameToString(
977c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                tlv.getData(), 0, tlv.getData().length);
978c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
979c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
980c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
981c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
983c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_ALL_SMS_DONE:
984c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
985c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
986c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
987c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null)
988c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
989c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
990cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                handleSmses((ArrayList<byte []>) ar.result);
991c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
992c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
993c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_MARK_SMS_READ_DONE:
99499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.i("ENF", "marked read: sms " + msg.arg1);
995c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
996c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
997c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
998c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SMS_ON_SIM:
999c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1000c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1001c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1002c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1003c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int[] index = (int[])ar.result;
1004c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null || index.length != 1) {
1006c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Error on SMS_ON_SIM with exp "
1007c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + ar.exception + " length " + index.length);
1008c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1009c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("READ EF_SMS RECORD index=" + index[0]);
1010c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFLinearFixed(EF_SMS,index[0],
1011c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_SMS_DONE));
1012c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1013c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1014c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SMS_DONE:
1016c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1018c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
1019c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    handleSms((byte[])ar.result);
1020c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1021c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Error on GET_SMS with exp " + ar.exception);
1022c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1023c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1024c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SST_DONE:
1025c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1026c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1027c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1028c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
1029c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1030c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1031c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1032c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1033c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1034c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mUsimServiceTable = new UsimServiceTable(data);
1035c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("SST: " + mUsimServiceTable);
1036c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1038c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_INFO_CPHS_DONE:
1039c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1040c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1041c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1042c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1043c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1044c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1045c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1046c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1047c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mCphsInfo = (byte[])ar.result;
1048c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1049c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("iCPHS: " + IccUtils.bytesToHexString(mCphsInfo));
1050c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1051c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1052c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_MBDN_DONE:
1053c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1055c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1056c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
105722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mVoiceMailNum = mNewVoiceMailNum;
105822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mVoiceMailTag = mNewVoiceMailTag;
1059c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1060c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1061c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (isCphsMailboxEnabled()) {
106222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    adn = new AdnRecord(mVoiceMailTag, mVoiceMailNum);
1063c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    Message onCphsCompleted = (Message) ar.userObj;
1064c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1065c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    /* write to cphs mailbox whenever it is available but
1066c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * we only need notify caller once if both updating are
1067c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * successful.
1068c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    *
1069c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * so if set_mbdn successful, notify caller here and set
1070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * onCphsCompleted to null
1071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    */
1072c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.exception == null && ar.userObj != null) {
1073c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        AsyncResult.forMessage(((Message) ar.userObj)).exception
1074c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                = null;
1075c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((Message) ar.userObj).sendToTarget();
1076c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1077c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) log("Callback with MBDN successful.");
1078c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1079c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        onCphsCompleted = null;
1080c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1081c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1082c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).
1083c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null,
1084c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE,
1085c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    onCphsCompleted));
1086c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1087c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.userObj != null) {
1088c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        AsyncResult.forMessage(((Message) ar.userObj)).exception
1089c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                = ar.exception;
1090c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((Message) ar.userObj).sendToTarget();
1091c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1093c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1094c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_CPHS_MAILBOX_DONE:
1095c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1096c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1097c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if(ar.exception == null) {
109822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mVoiceMailNum = mNewVoiceMailNum;
109922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mVoiceMailTag = mNewVoiceMailTag;
1100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1101c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Set CPHS MailBox with exception: "
1102c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + ar.exception);
1103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1104c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.userObj != null) {
1105c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Callback with CPHS MB successful.");
1106c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
1107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = ar.exception;
1108c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((Message) ar.userObj).sendToTarget();
1109c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SIM_REFRESH:
1112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("Sim REFRESH with exception: " + ar.exception);
1115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
1116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    handleSimRefresh((IccRefreshResponse)ar.result);
1117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CFIS_DONE:
1120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
1124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CFIS: " + IccUtils.bytesToHexString(data));
1130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1131a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                if (validEfCfis(data)) {
1132a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    mEfCfis = data;
1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1134a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    // Refer TS 51.011 Section 10.3.46 for the content description
113522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCallForwardingEnabled = ((data[1] & 0x01) != 0);
1136e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby                    log("EF_CFIS: callForwardingEnabled=" + mCallForwardingEnabled);
1137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1138a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
1139a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                } else {
1140a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    log("EF_CFIS: invalid data=" + IccUtils.bytesToHexString(data));
1141a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                }
1142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CSP_CPHS_DONE:
1145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Exception in fetching EF_CSP data " + ar.exception);
1151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
1155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CSP: " + IccUtils.bytesToHexString(data));
1157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                handleEfCspData(data);
1158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
11602f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim            case EVENT_GET_GID1_DONE:
11612f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                isRecordLoadResponse = true;
11622f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
11632f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                ar = (AsyncResult)msg.obj;
11642f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                data =(byte[])ar.result;
11652f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
11662f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                if (ar.exception != null) {
11672f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                    loge("Exception in get GID1 " + ar.exception);
1168620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt                    mGid1 = null;
11692f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                    break;
11702f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                }
1171620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt                mGid1 = IccUtils.bytesToHexString(data);
1172620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt                log("GID1: " + mGid1);
11732f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
11742f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim                break;
11752f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim
1176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                super.handleMessage(msg);   // IccRecords handles generic record load responses
1178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }}catch (RuntimeException exc) {
1180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // I don't want these exceptions to be fatal
1181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            logw("Exception parsing SIM record", exc);
1182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } finally {
1183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Count up record load responses even if they are fails
1184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (isRecordLoadResponse) {
1185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRecordLoaded();
1186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleFileUpdate(int efid) {
1191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch(efid) {
1192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_MBDN:
119322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad++;
1194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
119522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mMailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
1196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_MAILBOX_CPHS:
119822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad++;
1199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
1200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
1201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_CSP_CPHS:
120322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad++;
1204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("[CSP] SIM Refresh for EF_CSP_CPHS");
1205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.loadEFTransparent(EF_CSP_CPHS,
1206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage(EVENT_GET_CSP_CPHS_DONE));
1207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
120867aacea4e6b0199579a71b3a6a2f5d6778b8a002Kevin Li            case EF_FDN:
120967aacea4e6b0199579a71b3a6a2f5d6778b8a002Kevin Li                if (DBG) log("SIM Refresh called for EF_FDN");
121067aacea4e6b0199579a71b3a6a2f5d6778b8a002Kevin Li                mParentApp.queryFdn();
121167aacea4e6b0199579a71b3a6a2f5d6778b8a002Kevin Li                break;
1212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // For now, fetch all records if this is not a
1214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // voicemail number.
1215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // TODO: Handle other cases, instead of fetching all.
121622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mAdnCache.reset();
1217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                fetchSimRecords();
1218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleSimRefresh(IccRefreshResponse refreshResponse){
1223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (refreshResponse == null) {
1224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("handleSimRefresh received without input");
1225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (refreshResponse.aid != null &&
1229e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                !refreshResponse.aid.equals(mParentApp.getAid())) {
1230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // This is for different app. Ignore.
1231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (refreshResponse.refreshResult) {
1235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
1236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_FILE_UPDATED");
1237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                handleFileUpdate(refreshResponse.efId);
1238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_INIT:
1240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_REFRESH_INIT");
1241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // need to reload all files (that we care about)
124264bfd98578babdd437f1a83d2d5e1fc92c76e729Alex Yakavenka                onIccRefreshInit();
1243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_RESET:
1245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET");
1246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mCi.setRadioPower(false, null);
1247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                /* Note: no need to call setRadioPower(true).  Assuming the desired
1248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * radio power state is still ON (as tracked by ServiceStateTracker),
1249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * ServiceStateTracker will call setRadioPower when it receives the
1250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * RADIO_STATE_CHANGED notification for the power off.  And if the
1251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * desired power state has changed in the interim, we don't want to
1252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * override it with an unconditional power on.
1253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                */
12547af882af5b1195e03881a61f177adf86e44ab76fduho.ro                mAdnCache.reset();
1255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // unknown refresh operation
1258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with unknown operation");
1259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1264e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby     * Dispatch 3GPP format message to registrant ({@code GSMPhone} or {@code CDMALTEPhone})
1265e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby     * to pass to the 3GPP SMS dispatcher for delivery.
1266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1267a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hamby    private int dispatchGsmMessage(SmsMessage message) {
1268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNewSmsRegistrants.notifyResult(message);
1269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return 0;
1270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleSms(byte[] ba) {
1273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ba[0] != 0)
127499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.d("ENF", "status : " + ba[0]);
1275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 3 == "received by MS from network; message to be read"
1278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ba[0] == 3) {
1279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int n = ba.length;
1280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Note: Data may include trailing FF's.  That's OK; message
1282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // should still parse correctly.
1283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] pdu = new byte[n - 1];
1284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            System.arraycopy(ba, 1, pdu, 0, n - 1);
1285a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hamby            SmsMessage message = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP);
1286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            dispatchGsmMessage(message);
1288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1292cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    private void handleSmses(ArrayList<byte[]> messages) {
1293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int count = messages.size();
1294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0; i < count; i++) {
1296cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville            byte[] ba = messages.get(i);
1297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ba[0] != 0)
129999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.i("ENF", "status " + i + ": " + ba[0]);
1300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // 3 == "received by MS from network; message to be read"
1303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ba[0] == 3) {
1305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int n = ba.length;
1306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Note: Data may include trailing FF's.  That's OK; message
1308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // should still parse correctly.
1309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                byte[] pdu = new byte[n - 1];
1310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                System.arraycopy(ba, 1, pdu, 0, n - 1);
1311a0d02d50aa0fd7cf1c2d9f4d811efd2e4bfb7d4aJake Hamby                SmsMessage message = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP);
1312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                dispatchGsmMessage(message);
1314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // 1 == "received by MS from network; message read"
1317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ba[0] = 1;
1319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1320cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                if (false) { // FIXME: writing seems to crash RdoServD
1321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.updateEFLinearFixed(EF_SMS,
1322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            i, ba, null, obtainMessage(EVENT_MARK_SMS_READ_DONE, i));
1323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1328cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onRecordLoaded() {
1330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // One record loaded successfully or failed, In either case
1331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // we need to update the recordsToLoad count
133222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad -= 1;
133322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("onRecordLoaded " + mRecordsToLoad + " requested: " + mRecordsRequested);
1334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
133522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mRecordsToLoad == 0 && mRecordsRequested == true) {
1336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onAllRecordsLoaded();
133722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mRecordsToLoad < 0) {
1338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("recordsToLoad <0, programmer error suspected");
133922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mRecordsToLoad = 0;
1340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1343cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onAllRecordsLoaded() {
1345e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        if (DBG) log("record load complete");
1346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Some fields require more than one SIM record to set
1348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1349e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        String operator = getOperatorNumeric();
1350e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        if (!TextUtils.isEmpty(operator)) {
1351e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            log("onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
1352e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville                    operator + "'");
1353a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("update icc_operator_numeric=" + operator);
1354a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
1355e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        } else {
1356e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            log("onAllRecordsLoaded empty 'gsm.sim.operator.numeric' skipping");
1357e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        }
1358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1359e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        if (!TextUtils.isEmpty(mImsi)) {
1360e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            log("onAllRecordsLoaded set mcc imsi=" + mImsi);
1361a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
1362e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3))));
1363e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville        } else {
1364e9070e6d48d1389987650fa2c3e1f90aab860684Wink Saville            log("onAllRecordsLoaded empty imsi skipping setting mcc");
1365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        setVoiceMailByCountry(operator);
1368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        setSpnFromConfig(operator);
1369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1370b7881d6e7e4e79491376bedf151c3412dfdc4121Wink Saville        mRecordsLoadedRegistrants.notifyRegistrants(
1371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AsyncResult(null, null, null));
1372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //***** Private methods
1375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setSpnFromConfig(String carrier) {
1377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mSpnOverride.containsCarrier(carrier)) {
1378b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal            setServiceProviderName(mSpnOverride.getSpn(carrier));
1379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1380c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setVoiceMailByCountry (String spn) {
1384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mVmConfig.containsCarrier(spn)) {
138522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mIsVoiceMailFixed = true;
138622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceMailNum = mVmConfig.getVoiceMailNumber(spn);
138722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mVoiceMailTag = mVmConfig.getVoiceMailTag(spn);
1388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void onReady() {
1393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        fetchSimRecords();
1394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void fetchSimRecords() {
139722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsRequested = true;
1398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
139922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("fetchSimRecords " + mRecordsToLoad);
1400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1401e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
140222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
140522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // FIXME should examine EF[MSISDN]'s capability configuration
1408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // to determine which is the voice/data/fax line
1409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1,
1410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_GET_MSISDN_DONE));
141122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Record number is subscriber profile
1414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE));
141522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
141822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Record number is subscriber profile
1421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE));
142222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Also load CPHS-style voice mail indicator, which stores
1426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // the same info as EF[MWIS]. If both exist, both are updated
1427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // but the EF[MWIS] data is preferred
1428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Please note this must be loaded after EF[MWIS]
1429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(
1430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                EF_VOICE_MAIL_INDICATOR_CPHS,
1431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));
143222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Same goes for Call Forward Status indicator: fetch both
1435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
1436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
143722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
143922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        getSpnFsm(true, null);
1443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE));
144522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE));
144822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
145122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
145422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
145722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordsToLoad++;
1458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
14592f837b8058eba0bc59e983c67efbc00cd9a80eeeHyejin Kim        mFh.loadEFTransparent(EF_GID1, obtainMessage(EVENT_GET_GID1_DONE));
1460620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt        mRecordsToLoad++;
1461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // XXX should seek instead of examining them all
1463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (false) { // XXX
1464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
146522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mRecordsToLoad++;
1466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (CRASH_RIL) {
1469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String sms = "0107912160130310f20404d0110041007030208054832b0120"
1470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "ffffffffffffffffffffffffffffff";
1475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] ba = IccUtils.hexStringToBytes(sms);
1476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
1478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
1479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
148022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (DBG) log("fetchSimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested);
1481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Returns the SpnDisplayRule based on settings on the SIM and the
1485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * specified plmn (currently-registered PLMN).  See TS 22.101 Annex A
1486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * and TS 51.011 10.3.11 for details.
1487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
14882bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati     * If the SPN is not found on the SIM or is empty, the rule is
14892bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati     * always PLMN_ONLY.
1490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public int getDisplayRule(String plmn) {
1493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int rule;
1494be6c87905a15d1e36e87189ad7df5d5a72a52f69Shishir Agrawal
149568515b655255005f653aec29e9f152412514982aShishir Agrawal        if (mParentApp.getUiccCard() != null &&
149668515b655255005f653aec29e9f152412514982aShishir Agrawal            mParentApp.getUiccCard().getOperatorBrandOverride() != null) {
1497be6c87905a15d1e36e87189ad7df5d5a72a52f69Shishir Agrawal        // If the operator has been overridden, treat it as the SPN file on the SIM did not exist.
1498be6c87905a15d1e36e87189ad7df5d5a72a52f69Shishir Agrawal            rule = SPN_RULE_SHOW_PLMN;
1499be6c87905a15d1e36e87189ad7df5d5a72a52f69Shishir Agrawal        } else if (TextUtils.isEmpty(getServiceProviderName()) || mSpnDisplayCondition == -1) {
15002bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati            // No EF_SPN content was found on the SIM, or not yet loaded.  Just show ONS.
1501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_PLMN;
1502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (isOnMatchingPlmn(plmn)) {
1503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_SPN;
150422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if ((mSpnDisplayCondition & 0x01) == 0x01) {
1505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // ONS required when registered to HPLMN or PLMN in EF_SPDI
1506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                rule |= SPN_RULE_SHOW_PLMN;
1507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_PLMN;
151022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if ((mSpnDisplayCondition & 0x02) == 0x00) {
1511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // SPN required if not registered to HPLMN or PLMN in EF_SPDI
1512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                rule |= SPN_RULE_SHOW_SPN;
1513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return rule;
1516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Checks if plmn is HPLMN or on the spdiNetworks list.
1520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean isOnMatchingPlmn(String plmn) {
1522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmn == null) return false;
1523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmn.equals(getOperatorNumeric())) {
1525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return true;
1526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
152822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSpdiNetworks != null) {
152922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (String spdiNet : mSpdiNetworks) {
1530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (plmn.equals(spdiNet)) {
1531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    return true;
1532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return false;
1536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * States of Get SPN Finite State Machine which only used by getSpnFsm()
1540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
154122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private enum GetSpnFsmState {
1542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        IDLE,               // No initialized
1543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        INIT,               // Start FSM
1544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_3GPP,      // Load EF_SPN firstly
1545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_CPHS,      // Load EF_SPN_CPHS secondly
1546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last
1547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Finite State Machine to load Service Provider Name , which can be stored
1551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2)
1552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * After starting, FSM will search SPN EFs in order and stop after finding
1554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the first valid SPN
1555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If the FSM gets restart while waiting for one of
1557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * SPN EFs results (i.e. a SIM refresh occurs after issuing
1558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * read EF_CPHS_SPN), it will re-initialize only after
1559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * receiving and discarding the unfinished SPN EF result.
1560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param start set true only for initialize loading
1562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param ar the AsyncResult from loadEFTransparent
1563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ar.exception holds exception in error
1564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ar.result is byte[] for data in success
1565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void getSpnFsm(boolean start, AsyncResult ar) {
1567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte[] data;
1568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (start) {
1570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Check previous state to see if there is outstanding
1571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // SPN read
157222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if(mSpnState == GetSpnFsmState.READ_SPN_3GPP ||
157322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville               mSpnState == GetSpnFsmState.READ_SPN_CPHS ||
157422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville               mSpnState == GetSpnFsmState.READ_SPN_SHORT_CPHS ||
157522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville               mSpnState == GetSpnFsmState.INIT) {
1576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Set INIT then return so the INIT code
1577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // will run when the outstanding read done.
157822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.INIT;
1579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return;
1580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
158122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.INIT;
1582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
158522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        switch(mSpnState){
1586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case INIT:
1587b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                setServiceProviderName(null);
1588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.loadEFTransparent(EF_SPN,
1590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage(EVENT_GET_SPN_DONE));
159122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mRecordsToLoad++;
1592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
159322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.READ_SPN_3GPP;
1594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_3GPP:
1596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
159822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnDisplayCondition = 0xff & data[0];
1599b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setServiceProviderName(IccUtils.adnStringFieldToString(
1600b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                            data, 1, data.length - 1));
1601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1602b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    if (DBG) log("Load EF_SPN: " + getServiceProviderName()
160322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            + " spnDisplayCondition: " + mSpnDisplayCondition);
1604b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, getServiceProviderName());
1605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
160622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnState = GetSpnFsmState.IDLE;
1607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFTransparent( EF_SPN_CPHS,
1609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_SPN_DONE));
161022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mRecordsToLoad++;
1611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
161222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnState = GetSpnFsmState.READ_SPN_CPHS;
1613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // See TS 51.011 10.3.11.  Basically, default to
1615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // show PLMN always, and SPN also if roaming.
161622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnDisplayCondition = -1;
1617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_CPHS:
1620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
1622b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setServiceProviderName(IccUtils.adnStringFieldToString(data, 0, data.length));
1623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1624b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    if (DBG) log("Load EF_SPN_CPHS: " + getServiceProviderName());
1625b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, getServiceProviderName());
1626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
162722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnState = GetSpnFsmState.IDLE;
1628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFTransparent(
1630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE));
163122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mRecordsToLoad++;
1632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
163322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mSpnState = GetSpnFsmState.READ_SPN_SHORT_CPHS;
1634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1636c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_SHORT_CPHS:
1637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
1639b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setServiceProviderName(IccUtils.adnStringFieldToString(data, 0, data.length));
1640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1641b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    if (DBG) log("Load EF_SPN_SHORT_CPHS: " + getServiceProviderName());
1642b93bb3538c55f173f94a4ee7510d9d1521d8f731Shishir Agrawal                    setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, getServiceProviderName());
1643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }else {
1644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("No SPN loaded in either CHPS or 3GPP");
1645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
164722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.IDLE;
1648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
165022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpnState = GetSpnFsmState.IDLE;
1651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Parse TS 51.011 EF[SPDI] record
1656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * This record contains the list of numeric network IDs that
1657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * are treated specially when determining SPN display
1658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void
1660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    parseEfSpdi(byte[] data) {
1661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SimTlv tlv = new SimTlv(data, 0, data.length);
1662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte[] plmnEntries = null;
1664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for ( ; tlv.isValidObject() ; tlv.nextObject()) {
1666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Skip SPDI tag, if existant
1667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (tlv.getTag() == TAG_SPDI) {
1668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville              tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
1669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // There should only be one TAG_SPDI_PLMN_LIST
1671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
1672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                plmnEntries = tlv.getData();
1673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmnEntries == null) {
1678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
168122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mSpdiNetworks = new ArrayList<String>(plmnEntries.length / 3);
1682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0 ; i + 2 < plmnEntries.length ; i += 3) {
1684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String plmnCode;
1685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            plmnCode = IccUtils.bcdToString(plmnEntries, i, 3);
1686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Valid operator codes are 5 or 6 digits
1688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (plmnCode.length() >= 5) {
1689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_SPDI network: " + plmnCode);
169022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mSpdiNetworks.add(plmnCode);
1691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * check to see if Mailbox Number is allocated and activated in CPHS SST
1697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean isCphsMailboxEnabled() {
1699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mCphsInfo == null)  return false;
1700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED );
1701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1703cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1704c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void log(String s) {
170599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d(LOG_TAG, "[SIMRecords] " + s);
1706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1708cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void loge(String s) {
171099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.e(LOG_TAG, "[SIMRecords] " + s);
1711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void logw(String s, Throwable tr) {
171499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.w(LOG_TAG, "[SIMRecords] " + s, tr);
1715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void logv(String s) {
171899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.v(LOG_TAG, "[SIMRecords] " + s);
1719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1721c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Return true if "Restriction of menu options for manual PLMN selection"
1723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * bit is set or EF_CSP data is unavailable, return false otherwise.
1724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1725cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean isCspPlmnEnabled() {
1727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mCspPlmnEnabled;
1728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1729c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Parse EF_CSP data and check if
1732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * "Restriction of menu options for manual PLMN selection" is
1733c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Enabled/Disabled
1734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1735c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param data EF_CSP hex data.
1736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1737c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleEfCspData(byte[] data) {
1738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
1739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 18 bytes (i.e 9 service groups info) and additional data specific to
1740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // operator. The valueAddedServicesGroup is not part of standard
1741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // services. This is operator specific and can be programmed any where.
1742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Normally this is programmed as 10th service after the standard
1743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // services.
1744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int usedCspGroups = data.length / 2;
1745e17fb5a149610484b4bcda31cde04abfd4e5d4ecJake Hamby        // This is the "Service Group Number" of "Value Added Services Group".
1746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte valueAddedServicesGroup = (byte)0xC0;
1747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1748c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCspPlmnEnabled = true;
1749c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0; i < usedCspGroups; i++) {
1750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             if (data[2 * i] == valueAddedServicesGroup) {
1751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 log("[CSP] found ValueAddedServicesGroup, value " + data[(2 * i) + 1]);
1752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 if ((data[(2 * i) + 1] & 0x80) == 0x80) {
1753c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Bit 8 is for
1754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // "Restriction of menu options for manual PLMN selection".
1755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection menu should be enabled.
1756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mCspPlmnEnabled = true;
1757c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 } else {
1758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mCspPlmnEnabled = false;
1759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection menu should be disabled.
1760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection Mode should be set to Automatic.
1761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     log("[CSP] Set Automatic Network Selection");
1762c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mNetworkSelectionModeAutomaticRegistrants.notifyRegistrants();
1763c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 }
1764c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 return;
1765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             }
1766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("[CSP] Value Added Service Group (0xC0), not found!");
1769c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
177005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka
177105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    @Override
177205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
177305ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println("SIMRecords: " + this);
177405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" extends:");
177505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        super.dump(fd, pw, args);
177605ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mVmConfig=" + mVmConfig);
177705ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mSpnOverride=" + mSpnOverride);
177822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mCallForwardingEnabled=" + mCallForwardingEnabled);
177922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSpnState=" + mSpnState);
178005ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mCphsInfo=" + mCphsInfo);
178105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mCspPlmnEnabled=" + mCspPlmnEnabled);
178222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mEfMWIS[]=" + Arrays.toString(mEfMWIS));
178322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mEfCPHS_MWI[]=" + Arrays.toString(mEfCPHS_MWI));
178405ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mEfCff[]=" + Arrays.toString(mEfCff));
178505ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mEfCfis[]=" + Arrays.toString(mEfCfis));
178622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSpnDisplayCondition=" + mSpnDisplayCondition);
178722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mSpdiNetworks[]=" + mSpdiNetworks);
178822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        pw.println(" mPnnHomeName=" + mPnnHomeName);
178905ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.println(" mUsimServiceTable=" + mUsimServiceTable);
1790620c8855bcaa3fe8d492e93811b0ed6e8b4f59fcRobert Greenwalt        pw.println(" mGid1=" + mGid1);
179105ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka        pw.flush();
179205ef3b65972826780859b9acbd1fa9580d099832Alex Yakavenka    }
1793a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1794a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void setSystemProperty(String key, String val) {
1795a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Update the system properties only in case NON-DSDS.
1796a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // TODO: Shall have a better approach!
1797a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!TelephonyManager.getDefault().isMultiSimEnabled()) {
1798a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            SystemProperties.set(key, val);
1799a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1800a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1801c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
1802