SIMRecords.java revision f92cb4bd5519427a0db673709d94683a8baf203a
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
17c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepackage com.android.internal.telephony.gsm;
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.Handler;
25c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.Message;
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.os.SystemProperties;
272bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapatiimport android.text.TextUtils;
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport android.util.Log;
29c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
30c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.AdnRecord;
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.AdnRecordCache;
32c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.AdnRecordLoader;
33c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.BaseCommands;
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.CommandsInterface;
35c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccCardConstants;
36c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccFileHandler;
37c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccRecords;
38c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccUtils;
39c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccVmFixedException;
40c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccVmNotSupportedException;
41c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.MccTable;
42c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.Phone;
43c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.PhoneBase;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.SmsMessageBase;
45c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport com.android.internal.telephony.IccRefreshResponse;
46e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.UiccCardApplication;
47c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
48c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savilleimport java.util.ArrayList;
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
50c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
51c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/**
52c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville * {@hide}
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville */
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillepublic class SIMRecords extends IccRecords {
55c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final String LOG_TAG = "GSM";
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
57c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final boolean CRASH_RIL = false;
58c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
59c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final boolean DBG = true;
60c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
61c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Instance Variables
62c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
63c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    VoiceMailConstants mVmConfig;
64c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
65c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
66c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    SpnOverride mSpnOverride;
67c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
68c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Cached SIM State; cleared on channel close
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
70c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean callForwardingEnabled;
71c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
72c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
73c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
74c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * States only used by getSpnFsm FSM
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
76c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private Get_Spn_Fsm_State spnState;
77c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
78c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /** CPHS service information (See CPHS 4.2 B.3.1.1)
79c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  It will be set in onSimReady if reading GET_CPHS_INFO successfully
80c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  mCphsInfo[0] is CPHS Phase
81c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *  mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
82c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
83c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private byte[] mCphsInfo = null;
84c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    boolean mCspPlmnEnabled = true;
85c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
86c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    byte[] efMWIS = null;
87c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    byte[] efCPHS_MWI =null;
88c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    byte[] mEfCff = null;
89c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    byte[] mEfCfis = null;
90c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
91c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
92c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    int spnDisplayCondition;
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Numeric network codes listed in TS 51.011 EF[SPDI]
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    ArrayList<String> spdiNetworks = null;
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    String pnnHomeName = null;
97c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
98c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    UsimServiceTable mUsimServiceTable;
99c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
100f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    @Override
101f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    public String toString() {
102f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        return "SimRecords: " + super.toString()
103f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mVmConfig" + mVmConfig
104f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mSpnOverride=" + "mSpnOverride"
105f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " callForwardingEnabled=" + callForwardingEnabled
106f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " spnState=" + spnState
107f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mCphsInfo=" + mCphsInfo
108f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mCspPlmnEnabled=" + mCspPlmnEnabled
109f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " efMWIS=" + efMWIS
110f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " efCPHS_MWI=" + efCPHS_MWI
111f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mEfCff=" + mEfCff
112f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " mEfCfis=" + mEfCfis
113f92cb4bd5519427a0db673709d94683a8baf203aWink Saville                + " getOperatorNumeric=" + getOperatorNumeric();
114f92cb4bd5519427a0db673709d94683a8baf203aWink Saville    }
115f92cb4bd5519427a0db673709d94683a8baf203aWink Saville
116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Constants
117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Bitmasks for SPN display rules.
119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int SPN_RULE_SHOW_SPN  = 0x01;
120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int SPN_RULE_SHOW_PLMN = 0x02;
121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // From TS 51.011 EF[SPDI] section
123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SPDI = 0xA3;
124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SPDI_PLMN_LIST = 0x80;
125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Full Name IEI from TS 24.008
127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_FULL_NETWORK_NAME = 0x43;
128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Short Name IEI from TS 24.008
130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int TAG_SHORT_NETWORK_NAME = 0x45;
131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // active CFF from CPHS 4.2 B.4.5
133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_LINE1_MASK = 0x0f;
136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    static final int CFF_LINE1_RESET = 0xf0;
137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // CPHS Service Table (See CPHS 4.2 B.3.1)
139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int CPHS_SST_MBN_MASK = 0x30;
140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int CPHS_SST_MBN_ENABLED = 0x30;
141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Event Constants
143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
144e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_APP_READY = 1;
145e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_GET_IMSI_DONE = 3;
146e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    private static final int EVENT_GET_ICCID_DONE = 4;
147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MBI_DONE = 5;
148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MBDN_DONE = 6;
149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_MWIS_DONE = 7;
150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8;
151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM
152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_MSISDN_DONE = 10;
153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11;
154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SPN_DONE = 12;
155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SPDI_DONE = 13;
156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_UPDATE_DONE = 14;
157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_PNN_DONE = 15;
158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected static final int EVENT_GET_SST_DONE = 17;
159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_ALL_SMS_DONE = 18;
160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_MARK_SMS_READ_DONE = 19;
161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SET_MBDN_DONE = 20;
162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SMS_ON_SIM = 21;
163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_SMS_DONE = 22;
164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CFF_DONE = 24;
165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25;
166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_INFO_CPHS_DONE = 26;
167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SET_MSISDN_DONE = 30;
168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_SIM_REFRESH = 31;
169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CFIS_DONE = 32;
170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final int EVENT_GET_CSP_CPHS_DONE = 33;
171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
179c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914",
188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922",
189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930",
190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        "405931", "405932"
191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    };
192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Constructor
194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
195e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
196e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        super(app, c, ci);
197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        adnCache = new AdnRecordCache(mFh);
199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mVmConfig = new VoiceMailConstants();
201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mSpnOverride = new SpnOverride();
202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsRequested = false;  // No load request is made till SIM ready
204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // recordsToLoad is set to 0 because no requests are made yet
206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad = 0;
207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Start off by setting empty state
212e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        resetRecords();
213e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mParentApp.registerForReady(this, EVENT_APP_READY, null);
214f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (DBG) log("SIMRecords X ctor this=" + this);
215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void dispose() {
219f92cb4bd5519427a0db673709d94683a8baf203aWink Saville        if (DBG) log("Disposing SIMRecords this=" + this);
220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        //Unregister for all events
221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.unregisterForIccRefresh(this);
222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCi.unSetOnSmsOnSim(this);
223e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mParentApp.unregisterForReady(this);
224e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        resetRecords();
225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        super.dispose();
226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void finalize() {
229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if(DBG) log("finalized");
230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
232e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka    protected void resetRecords() {
233e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mImsi = null;
234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msisdn = null;
235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        voiceMailNum = null;
236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        countVoiceMessages = 0;
237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mncLength = UNINITIALIZED;
238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        iccid = null;
239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // -1 means no EF_SPN found; treat accordingly.
240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        spnDisplayCondition = -1;
241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        efMWIS = null;
242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        efCPHS_MWI = null;
243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        spdiNetworks = null;
244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        pnnHomeName = null;
245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        adnCache.reset();
247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("SIMRecords: onRadioOffOrNotAvailable set 'gsm.sim.operator.numeric' to operator=null");
249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, null);
250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, null);
251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // recordsRequested is set to false indicating that the SIM
254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // read requests made so far are not valid. This is set to
255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // true only when fresh set of read requests are made.
256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsRequested = false;
257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //***** Public Methods
261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getIMSI() {
267e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mImsi;
268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getMsisdnNumber() {
271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return msisdn;
272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public UsimServiceTable getUsimServiceTable() {
276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mUsimServiceTable;
277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set subscriber number to SIM record
281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The subscriber number is stored in EF_MSISDN (TS 51.011)
283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * When the operation is complete, onComplete will be sent to its handler
285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param number dailing nubmer (up to 20 digits)
288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        if the number starts with '+', then set to international TOA
289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param onComplete
290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        onComplete.obj will be an AsyncResult
291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception == null on success
292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception != null on fail
293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setMsisdnNumber(String alphaTag, String number,
295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message onComplete) {
296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msisdn = number;
298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        msisdnTag = alphaTag;
299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if(DBG) log("Set MSISDN: " + msisdnTag + " " + /*msisdn*/ "xxxxxxx");
301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
302c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AdnRecord adn = new AdnRecord(msisdnTag, msisdn);
304c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getMsisdnAlphaTag() {
310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return msisdnTag;
311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getVoiceMailNumber() {
314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return voiceMailNum;
315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Set voice mail number to SIM record
319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * The voice mail number can be stored either in EF_MBDN (TS 51.011) or
321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * EF_MAILBOX_CPHS (CPHS 4.2)
322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If EF_MBDN is available, store the voice mail number to EF_MBDN
324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * So the voice mail number will be stored in both EFs if both are available
328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * When the operation is complete, onComplete will be sent to its handler
332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param voiceNumber dailing nubmer (upto 20 digits)
335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        if the number is start with '+', then set to international TOA
336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param onComplete
337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        onComplete.obj will be an AsyncResult
338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception == null on success
339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ((AsyncResult)onComplete.obj).exception != null on fail
340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setVoiceMailNumber(String alphaTag, String voiceNumber,
342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Message onComplete) {
343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (isVoiceMailFixed) {
344c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AsyncResult.forMessage((onComplete)).exception =
345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new IccVmFixedException("Voicemail number is fixed by operator");
346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onComplete.sendToTarget();
347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        newVoiceMailNum = voiceNumber;
351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        newVoiceMailTag = alphaTag;
352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AdnRecord adn = new AdnRecord(newVoiceMailTag, newVoiceMailNum);
354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mailboxIndex != 0 && mailboxIndex != 0xff) {
356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AdnRecordLoader(mFh).updateEF(adn, EF_MBDN, EF_EXT6,
358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mailboxIndex, null,
359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_SET_MBDN_DONE, onComplete));
360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (isCphsMailboxEnabled()) {
362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS,
364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    EF_EXT1, 1, null,
365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete));
366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            AsyncResult.forMessage((onComplete)).exception =
369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new IccVmNotSupportedException("Update SIM voice mailbox error");
370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onComplete.sendToTarget();
371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getVoiceMailAlphaTag()
375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    {
376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return voiceMailTag;
377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
380c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Sets the SIM voice message waiting indicator records
381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param countWaiting The number of messages waiting, if known. Use
383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *                     -1 to indicate that an unknown number of
384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *                      messages are waiting
385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void
387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    setVoiceMessageWaiting(int line, int countWaiting) {
388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (line != 1) {
389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // only profile 1 is supported
390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // range check
394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (countWaiting < 0) {
395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            countWaiting = -1;
396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (countWaiting > 0xff) {
397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // TS 23.040 9.2.3.24.2
398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // "The value 255 shall be taken to mean 255 or greater"
399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            countWaiting = 0xff;
400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        countVoiceMessages = countWaiting;
403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (efMWIS != null) {
408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // TS 51.011 10.3.45
409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // lsb of byte 0 is 'voicemail' status
411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                efMWIS[0] = (byte)((efMWIS[0] & 0xfe)
412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    | (countVoiceMessages == 0 ? 0 : 1));
413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // byte 1 is the number of voice messages waiting
415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (countWaiting < 0) {
416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // The spec does not define what this should be
417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // if we don't know the count
418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    efMWIS[1] = 0;
419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    efMWIS[1] = (byte) countWaiting;
421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFLinearFixed(
424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    EF_MWIS, 1, efMWIS, null,
425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage (EVENT_UPDATE_DONE, EF_MWIS));
426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
428c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (efCPHS_MWI != null) {
429c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer CPHS4_2.WW6 B4.2.3
430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                efCPHS_MWI[0] = (byte)((efCPHS_MWI[0] & 0xf0)
431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            | (countVoiceMessages == 0 ? 0x5 : 0xa));
432c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFTransparent(
434c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    EF_VOICE_MAIL_INDICATOR_CPHS, efCPHS_MWI,
435c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS));
436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (ArrayIndexOutOfBoundsException ex) {
438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            logw("Error saving voice mail state to SIM. Probably malformed SIM record", ex);
439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
442a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    // Validate data is !null and the MSP (Multiple Subscriber Profile)
443a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    // byte is between 1 and 4. See ETSI TS 131 102 v11.3.0 section 4.2.64.
444a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    private boolean validEfCfis(byte[] data) {
445a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville        return ((data != null) && (data[0] >= 1) && (data[0] <= 4));
446a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville    }
447a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville
448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean getVoiceCallForwardingFlag() {
453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return callForwardingEnabled;
454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void setVoiceCallForwardingFlag(int line, boolean enable) {
461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (line != 1) return; // only line 1 is supported
463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        callForwardingEnabled = enable;
465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try {
469a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville            if (validEfCfis(mEfCfis)) {
470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // lsb is of byte 1 is voice status
471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (enable) {
472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCfis[1] |= 1;
473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCfis[1] &= 0xfe;
475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
477a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                log("setVoiceCallForwardingFlag: enable=" + enable
478a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                        + " mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));
479a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville
480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // TODO: Should really update other fields in EF_CFIS, eg,
481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // dialing number.  We don't read or use it right now.
482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFLinearFixed(
484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EF_CFIS, 1, mEfCfis, null,
485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage (EVENT_UPDATE_DONE, EF_CFIS));
486a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville            } else {
487a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                log("setVoiceCallForwardingFlag: ignoring enable=" + enable
488a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                        + " invalid mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));
489c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (mEfCff != null) {
492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (enable) {
493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            | CFF_UNCONDITIONAL_ACTIVE);
495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            | CFF_UNCONDITIONAL_DEACTIVE);
498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.updateEFTransparent(
501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        EF_CFF_CPHS, mEfCff,
502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } catch (ArrayIndexOutOfBoundsException ex) {
505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            logw("Error saving call fowarding flag to SIM. "
506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + "Probably malformed SIM record", ex);
507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Called by STK Service when REFRESH is received.
513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param fileChanged indicates whether any files changed
514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param fileList if non-null, a list of EF files that changed
515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void onRefresh(boolean fileChanged, int[] fileList) {
517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (fileChanged) {
518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // A future optimization would be to inspect fileList and
519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // only reload those files that we care about.  For now,
520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // just re-fetch all SIM records that we cache.
521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            fetchSimRecords();
522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@inheritDoc}
527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public String getOperatorNumeric() {
530e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mImsi == null) {
531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("getOperatorNumeric: IMSI == null");
532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return null;
533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mncLength == UNINITIALIZED || mncLength == UNKNOWN) {
535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            log("getSIMOperatorNumeric: bad mncLength");
536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return null;
537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Length = length of MCC + length of MNC
540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // length of mcc = 3 (TS 23.003 Section 2.2)
541e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        return mImsi.substring(0, 3 + mncLength);
542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    // ***** Overridden from Handler
545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void handleMessage(Message msg) {
546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AsyncResult ar;
547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        AdnRecord adn;
548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte data[];
550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        boolean isRecordLoadResponse = false;
552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
553bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka        if (mDestroyed.get()) {
554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("Received message " + msg + "[" + msg.what + "] " +
555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    " while being destroyed. Ignoring.");
556c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        try { switch (msg.what) {
560e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka            case EVENT_APP_READY:
561e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                onReady();
562e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                break;
563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            /* IO events */
565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_IMSI_DONE:
566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Exception querying IMSI, Exception:" + ar.exception);
572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
573c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
574c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
575e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mImsi = (String) ar.result;
576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // than 15 (and usually 15).
579e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
580e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    loge("invalid IMSI " + mImsi);
581e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    mImsi = null;
582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("IMSI: " + /* imsi.substring(0, 6) +*/ "xxxxxxx");
585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (((mncLength == UNKNOWN) || (mncLength == 2)) &&
587e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        ((mImsi != null) && (mImsi.length() >= 6))) {
588e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    String mccmncCode = mImsi.substring(0, 6);
589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (mccmnc.equals(mccmncCode)) {
591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            mncLength = 3;
592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            break;
593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (mncLength == UNKNOWN) {
598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // the SIM has told us all it knows, but it didn't know the mnc length.
599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // guess using the mcc
600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    try {
601e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        int mcc = Integer.parseInt(mImsi.substring(0,3));
602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mncLength = MccTable.smallestDigitsMccForMnc(mcc);
603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } catch (NumberFormatException e) {
604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mncLength = UNKNOWN;
605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        loge("Corrupt IMSI!");
606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (mncLength != UNKNOWN && mncLength != UNINITIALIZED) {
610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // finally have both the imsi and the mncLength and can parse the imsi properly
611e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    MccTable.updateMccMncConfiguration(mContext, mImsi.substring(0, 3 + mncLength));
612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
613e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                mImsiReadyRegistrants.notifyRegistrants();
614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MBI_DONE:
617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean isValidMbdn;
618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[]) ar.result;
622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isValidMbdn = false;
624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer TS 51.011 Section 10.3.44 for content details
626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("EF_MBI: " + IccUtils.bytesToHexString(data));
627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Voice mail record number stored first
629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mailboxIndex = (int)data[0] & 0xff;
630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // check if dailing numbe id valid
632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (mailboxIndex != 0 && mailboxIndex != 0xff) {
633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("Got valid mailbox number for MBDN");
634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        isValidMbdn = true;
635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
636c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // one more record to load
639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                recordsToLoad += 1;
640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (isValidMbdn) {
642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Note: MBDN was not included in NUM_OF_SIM_RECORDS_LOADED
643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // If this EF not present, try mailbox as in CPHS standard
647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // CPHS (CPHS4_2.WW6) is a european standard.
648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS,
649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_EXT1, 1,
650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CPHS_MAILBOX_DONE:
655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MBDN_DONE:
656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //Resetting the voice mail number and voice mail tag to null
657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //as these should be updated from the data read from EF_MBDN.
658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //If they are not reset, incase of invalid data/exception these
659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //variables are retaining their previous values and are
660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                //causing invalid voice mailbox info display to user.
661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                voiceMailNum = null;
662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                voiceMailTag = null;
663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Invalid or missing EF"
670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]"));
671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Bug #645770 fall back to CPHS
673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME should use SST to decide
674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (msg.what == EVENT_GET_MBDN_DONE) {
676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        //load CPHS on fail...
677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // FIXME right now, only load line1's CPHS voice mail entry
678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        recordsToLoad += 1;
680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        new AdnRecordLoader(mFh).loadFromEF(
681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                EF_MAILBOX_CPHS, EF_EXT1, 1,
682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                adn = (AdnRecord)ar.result;
688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("VM: " + adn +
690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) {
693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Bug #645770 fall back to CPHS
694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME should use SST to decide
695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // FIXME right now, only load line1's CPHS voice mail entry
696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    recordsToLoad += 1;
697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).loadFromEF(
698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_MAILBOX_CPHS, EF_EXT1, 1,
699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
702c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
703c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
704c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                voiceMailNum = adn.getNumber();
705c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                voiceMailTag = adn.getAlphaTag();
706c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
707c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
708c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MSISDN_DONE:
709c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
710c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
711c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
712c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
713c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
714c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Invalid or missing EF[MSISDN]");
715c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
716c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
717c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
718c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                adn = (AdnRecord)ar.result;
719c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
720c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                msisdn = adn.getNumber();
721c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                msisdnTag = adn.getAlphaTag();
722c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
723c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("MSISDN: " + /*msisdn*/ "xxxxxxx");
724c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
725c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
726c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_MSISDN_DONE:
727c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
728c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
729c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
730c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.userObj != null) {
731c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
732c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = ar.exception;
733c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((Message) ar.userObj).sendToTarget();
734c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
735c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
736c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
737c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_MWIS_DONE:
738c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
739c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
740c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
741c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
742c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
743c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
744c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
745c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
746c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
747c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_MWIS: " + IccUtils.bytesToHexString(data));
748c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
749c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                efMWIS = data;
750c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
751c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if ((data[0] & 0xff) == 0xff) {
752c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("Uninitialized record MWIS");
753c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
754c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
755c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
756c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Refer TS 51.011 Section 10.3.45 for the content description
757c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                boolean voiceMailWaiting = ((data[0] & 0x01) != 0);
758c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                countVoiceMessages = data[1] & 0xff;
759c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
760c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (voiceMailWaiting && countVoiceMessages == 0) {
761c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Unknown count = -1
762c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    countVoiceMessages = -1;
763c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
764c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
765c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
766c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
767c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
768c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE:
769c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
770c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
771c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
772c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
773c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
774c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
775c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
776c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
777c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
778c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                efCPHS_MWI = data;
779c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
780c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Use this data if the EF[MWIS] exists and
781c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // has been loaded
782c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
783c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (efMWIS == null) {
784c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    int indicator = (int)(data[0] & 0xf);
785c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
786c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // Refer CPHS4_2.WW6 B4.2.3
787c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (indicator == 0xA) {
788c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // Unknown count = -1
789c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        countVoiceMessages = -1;
790c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    } else if (indicator == 0x5) {
791c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        countVoiceMessages = 0;
792c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
793c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
794c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
795c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
796c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
797c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
798c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_ICCID_DONE:
799c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
800c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
801c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
802c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
803c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
804c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
805c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
806c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
807c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
808c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                iccid = IccUtils.bcdToString(data, 0, data.length);
809c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
810c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("iccid: " + iccid);
811c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
812c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
813c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
814c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
815c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_AD_DONE:
816c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                try {
817c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    isRecordLoadResponse = true;
818c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
819c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ar = (AsyncResult)msg.obj;
820c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[])ar.result;
821c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
822c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.exception != null) {
823c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
824c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
825c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
826c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("EF_AD: " + IccUtils.bytesToHexString(data));
827c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
828c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (data.length < 3) {
829c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("Corrupt AD data on SIM");
830c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
831c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
832c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
833c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (data.length == 3) {
834c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        log("MNC length not present in EF_AD");
835c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
836c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
837c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
838c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mncLength = (int)data[3] & 0xf;
839c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
840c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (mncLength == 0xf) {
841c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mncLength = UNKNOWN;
842c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
843c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } finally {
844c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (((mncLength == UNINITIALIZED) || (mncLength == UNKNOWN) ||
845e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                            (mncLength == 2)) && ((mImsi != null) && (mImsi.length() >= 6))) {
846e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        String mccmncCode = mImsi.substring(0, 6);
847c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
848c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            if (mccmnc.equals(mccmncCode)) {
849c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                mncLength = 3;
850c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                break;
851c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
852c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
853c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
854c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
855c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (mncLength == UNKNOWN || mncLength == UNINITIALIZED) {
856e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                        if (mImsi != null) {
857c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            try {
858e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                                int mcc = Integer.parseInt(mImsi.substring(0,3));
859c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
860c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                mncLength = MccTable.smallestDigitsMccForMnc(mcc);
861c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            } catch (NumberFormatException e) {
862c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                mncLength = UNKNOWN;
863c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                loge("Corrupt IMSI!");
864c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            }
865c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        } else {
866c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            // Indicate we got this info, but it didn't contain the length.
867c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            mncLength = UNKNOWN;
868c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
869c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            log("MNC length not present in EF_AD");
870c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        }
871c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
872e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    if (mImsi != null && mncLength != UNKNOWN) {
873c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // finally have both imsi and the length of the mnc and can parse
874c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        // the imsi properly
875c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        MccTable.updateMccMncConfiguration(mContext,
876e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                                mImsi.substring(0, 3 + mncLength));
877c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
878c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
879c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
880c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
881c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SPN_DONE:
882c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
883c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
884c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                getSpnFsm(false, ar);
885c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
886c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
887c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CFF_DONE:
888c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
889c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
890c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult) msg.obj;
891c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[]) ar.result;
892c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
893c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
894c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
895c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
896c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
897c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
898c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mEfCff = data;
899c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
900a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                if (validEfCfis(mEfCfis)) {
901c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    callForwardingEnabled =
902c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE);
903c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
904c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
905a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                } else {
906a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    log("EVENT_GET_CFF_DONE: invalid mEfCfis="
907a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                            + IccUtils.bytesToHexString(mEfCfis));
908c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
909c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
910c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
911c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SPDI_DONE:
912c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
913c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
914c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
915c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
916c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
917c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
918c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
919c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
920c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
921c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                parseEfSpdi(data);
922c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
923c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
924c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_UPDATE_DONE:
925c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
926c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
927c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    logw("update failed. ", ar.exception);
928c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
929c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
930c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
931c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_PNN_DONE:
932c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
933c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
934c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
935c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
936c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
937c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
938c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
939c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
940c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
941c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                SimTlv tlv = new SimTlv(data, 0, data.length);
942c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
943c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                for ( ; tlv.isValidObject() ; tlv.nextObject()) {
944c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (tlv.getTag() == TAG_FULL_NETWORK_NAME) {
945c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        pnnHomeName
946c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = IccUtils.networkNameToString(
947c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                tlv.getData(), 0, tlv.getData().length);
948c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        break;
949c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
950c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
951c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
952c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
953c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_ALL_SMS_DONE:
954c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
955c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
956c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
957c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null)
958c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
959c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
960c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                handleSmses((ArrayList) ar.result);
961c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
962c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
963c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_MARK_SMS_READ_DONE:
964c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Log.i("ENF", "marked read: sms " + msg.arg1);
965c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
966c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
967c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
968c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SMS_ON_SIM:
969c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
970c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
971c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
972c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
973c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int[] index = (int[])ar.result;
974c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
975c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null || index.length != 1) {
976c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Error on SMS_ON_SIM with exp "
977c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + ar.exception + " length " + index.length);
978c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
979c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    log("READ EF_SMS RECORD index=" + index[0]);
980c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFLinearFixed(EF_SMS,index[0],
981c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_SMS_DONE));
982c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
983c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
984c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
985c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SMS_DONE:
986c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
987c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
988c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
989c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    handleSms((byte[])ar.result);
990c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
991c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Error on GET_SMS with exp " + ar.exception);
992c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
993c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
994c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_SST_DONE:
995c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
996c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
997c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
998c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
999c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1000c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1001c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1002c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1003c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1004c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mUsimServiceTable = new UsimServiceTable(data);
1005c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("SST: " + mUsimServiceTable);
1006c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1007c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1008c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_INFO_CPHS_DONE:
1009c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1010c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1011c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1012c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1013c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1014c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1015c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1016c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1017c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mCphsInfo = (byte[])ar.result;
1018c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1019c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("iCPHS: " + IccUtils.bytesToHexString(mCphsInfo));
1020c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            break;
1021c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1022c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_MBDN_DONE:
1023c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1024c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1025c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1026c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
1027c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    voiceMailNum = newVoiceMailNum;
1028c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    voiceMailTag = newVoiceMailTag;
1029c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1030c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1031c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (isCphsMailboxEnabled()) {
1032c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    adn = new AdnRecord(voiceMailTag, voiceMailNum);
1033c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    Message onCphsCompleted = (Message) ar.userObj;
1034c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1035c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    /* write to cphs mailbox whenever it is available but
1036c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * we only need notify caller once if both updating are
1037c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * successful.
1038c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    *
1039c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * so if set_mbdn successful, notify caller here and set
1040c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    * onCphsCompleted to null
1041c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    */
1042c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.exception == null && ar.userObj != null) {
1043c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        AsyncResult.forMessage(((Message) ar.userObj)).exception
1044c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                = null;
1045c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((Message) ar.userObj).sendToTarget();
1046c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1047c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        if (DBG) log("Callback with MBDN successful.");
1048c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1049c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        onCphsCompleted = null;
1050c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1051c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1052c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    new AdnRecordLoader(mFh).
1053c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null,
1054c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE,
1055c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                    onCphsCompleted));
1056c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1057c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (ar.userObj != null) {
1058c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        AsyncResult.forMessage(((Message) ar.userObj)).exception
1059c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                                = ar.exception;
1060c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        ((Message) ar.userObj).sendToTarget();
1061c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    }
1062c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1063c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1064c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SET_CPHS_MAILBOX_DONE:
1065c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1066c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1067c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if(ar.exception == null) {
1068c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    voiceMailNum = newVoiceMailNum;
1069c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    voiceMailTag = newVoiceMailTag;
1070c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1071c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Set CPHS MailBox with exception: "
1072c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + ar.exception);
1073c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1074c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.userObj != null) {
1075c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Callback with CPHS MB successful.");
1076c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    AsyncResult.forMessage(((Message) ar.userObj)).exception
1077c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            = ar.exception;
1078c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    ((Message) ar.userObj).sendToTarget();
1079c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1080c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1081c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_SIM_REFRESH:
1082c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = false;
1083c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1084c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("Sim REFRESH with exception: " + ar.exception);
1085c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception == null) {
1086c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    handleSimRefresh((IccRefreshResponse)ar.result);
1087c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1088c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1089c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CFIS_DONE:
1090c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1091c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1092c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1093c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
1094c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1095c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1096c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1097c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1098c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1099c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CFIS: " + IccUtils.bytesToHexString(data));
1100c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1101a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                if (validEfCfis(data)) {
1102a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    mEfCfis = data;
1103c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1104a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    // Refer TS 51.011 Section 10.3.46 for the content description
1105a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    callForwardingEnabled = ((data[1] & 0x01) != 0);
1106a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    log("EF_CFIS: callFordwardingEnabled=" + callForwardingEnabled);
1107c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1108a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
1109a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                } else {
1110a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                    log("EF_CFIS: invalid data=" + IccUtils.bytesToHexString(data));
1111a2985af1d00f7db8cb11da3874dc74e0c7ff7088Wink Saville                }
1112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1113c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1114c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EVENT_GET_CSP_CPHS_DONE:
1115c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                isRecordLoadResponse = true;
1116c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1117c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ar = (AsyncResult)msg.obj;
1118c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1119c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar.exception != null) {
1120c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    loge("Exception in fetching EF_CSP data " + ar.exception);
1121c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    break;
1122c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1123c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1124c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                data = (byte[])ar.result;
1125c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1126c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_CSP: " + IccUtils.bytesToHexString(data));
1127c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                handleEfCspData(data);
1128c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1129c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1130c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1131c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                super.handleMessage(msg);   // IccRecords handles generic record load responses
1132c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1133c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }}catch (RuntimeException exc) {
1134c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // I don't want these exceptions to be fatal
1135c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            logw("Exception parsing SIM record", exc);
1136c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } finally {
1137c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Count up record load responses even if they are fails
1138c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (isRecordLoadResponse) {
1139c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                onRecordLoaded();
1140c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1141c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1142c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1143c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1144c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleFileUpdate(int efid) {
1145c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch(efid) {
1146c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_MBDN:
1147c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                recordsToLoad++;
1148c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
1149c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
1150c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1151c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_MAILBOX_CPHS:
1152c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                recordsToLoad++;
1153c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
1154c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
1155c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1156c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case EF_CSP_CPHS:
1157c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                recordsToLoad++;
1158c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("[CSP] SIM Refresh for EF_CSP_CPHS");
1159c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.loadEFTransparent(EF_CSP_CPHS,
1160c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage(EVENT_GET_CSP_CPHS_DONE));
1161c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1162c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1163c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // For now, fetch all records if this is not a
1164c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // voicemail number.
1165c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // TODO: Handle other cases, instead of fetching all.
1166c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                adnCache.reset();
1167c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                fetchSimRecords();
1168c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1169c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1170c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1171c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1172c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleSimRefresh(IccRefreshResponse refreshResponse){
1173c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (refreshResponse == null) {
1174c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (DBG) log("handleSimRefresh received without input");
1175c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1176c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1177c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1178c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (refreshResponse.aid != null &&
1179e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                !refreshResponse.aid.equals(mParentApp.getAid())) {
1180c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // This is for different app. Ignore.
1181c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1182c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1183c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1184c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch (refreshResponse.refreshResult) {
1185c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
1186c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_FILE_UPDATED");
1187c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                handleFileUpdate(refreshResponse.efId);
1188c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1189c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_INIT:
1190c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_REFRESH_INIT");
1191c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // need to reload all files (that we care about)
1192c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                adnCache.reset();
1193c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                fetchSimRecords();
1194c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1195c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case IccRefreshResponse.REFRESH_RESULT_RESET:
1196c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET");
1197c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mCi.setRadioPower(false, null);
1198c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                /* Note: no need to call setRadioPower(true).  Assuming the desired
1199c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * radio power state is still ON (as tracked by ServiceStateTracker),
1200c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * ServiceStateTracker will call setRadioPower when it receives the
1201c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * RADIO_STATE_CHANGED notification for the power off.  And if the
1202c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * desired power state has changed in the interim, we don't want to
1203c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                * override it with an unconditional power on.
1204c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                */
1205c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1206c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1207c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // unknown refresh operation
1208c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (DBG) log("handleSimRefresh with unknown operation");
1209c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1210c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1211c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1212c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1213c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1214c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Dispatch 3GPP format message. Overridden for CDMA/LTE phones by
1215c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * {@link com.android.internal.telephony.cdma.CdmaLteUiccRecords}
1216c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * to send messages to the secondary 3GPP format SMS dispatcher.
1217c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1218c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected int dispatchGsmMessage(SmsMessageBase message) {
1219c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mNewSmsRegistrants.notifyResult(message);
1220c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return 0;
1221c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1222c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1223c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleSms(byte[] ba) {
1224c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ba[0] != 0)
1225c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            Log.d("ENF", "status : " + ba[0]);
1226c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1227c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1228c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 3 == "received by MS from network; message to be read"
1229c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (ba[0] == 3) {
1230c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            int n = ba.length;
1231c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1232c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Note: Data may include trailing FF's.  That's OK; message
1233c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // should still parse correctly.
1234c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] pdu = new byte[n - 1];
1235c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            System.arraycopy(ba, 1, pdu, 0, n - 1);
1236c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            SmsMessage message = SmsMessage.createFromPdu(pdu);
1237c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1238c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            dispatchGsmMessage(message);
1239c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1240c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1241c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1242c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1243c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleSmses(ArrayList messages) {
1244c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int count = messages.size();
1245c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1246c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0; i < count; i++) {
1247c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] ba = (byte[]) messages.get(i);
1248c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1249c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ba[0] != 0)
1250c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                Log.i("ENF", "status " + i + ": " + ba[0]);
1251c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1252c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1253c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // 3 == "received by MS from network; message to be read"
1254c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1255c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (ba[0] == 3) {
1256c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                int n = ba.length;
1257c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1258c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Note: Data may include trailing FF's.  That's OK; message
1259c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // should still parse correctly.
1260c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                byte[] pdu = new byte[n - 1];
1261c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                System.arraycopy(ba, 1, pdu, 0, n - 1);
1262c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                SmsMessage message = SmsMessage.createFromPdu(pdu);
1263c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1264c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                dispatchGsmMessage(message);
1265c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1266c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
1267c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // 1 == "received by MS from network; message read"
1268c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1269c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                ba[0] = 1;
1270c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1271c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (false) { // XXX writing seems to crash RdoServD
1272c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.updateEFLinearFixed(EF_SMS,
1273c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            i, ba, null, obtainMessage(EVENT_MARK_SMS_READ_DONE, i));
1274c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1275c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1276c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1277c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1278c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1279c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onRecordLoaded() {
1280c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // One record loaded successfully or failed, In either case
1281c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // we need to update the recordsToLoad count
1282c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad -= 1;
1283c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
1284c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1285c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (recordsToLoad == 0 && recordsRequested == true) {
1286c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            onAllRecordsLoaded();
1287c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (recordsToLoad < 0) {
1288c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("recordsToLoad <0, programmer error suspected");
1289c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            recordsToLoad = 0;
1290c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1291c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1292c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1293c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void onAllRecordsLoaded() {
1294c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        String operator = getOperatorNumeric();
1295c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1296c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Some fields require more than one SIM record to set
1297c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1298c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("SIMRecords: onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
1299c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                operator + "'");
1300c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
1301c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1302e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        if (mImsi != null) {
1303c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
1304e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka                    MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3))));
1305c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1306c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        else {
1307c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            loge("onAllRecordsLoaded: imsi is NULL!");
1308c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1309c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1310c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        setVoiceMailByCountry(operator);
1311c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        setSpnFromConfig(operator);
1312c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1313c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsLoadedRegistrants.notifyRegistrants(
1314c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            new AsyncResult(null, null, null));
1315c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1316c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1317c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    //***** Private methods
1318c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1319c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setSpnFromConfig(String carrier) {
1320c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mSpnOverride.containsCarrier(carrier)) {
1321c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            spn = mSpnOverride.getSpn(carrier);
1322c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1323c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1324c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1325c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1326c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void setVoiceMailByCountry (String spn) {
1327c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mVmConfig.containsCarrier(spn)) {
1328c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            isVoiceMailFixed = true;
1329c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            voiceMailNum = mVmConfig.getVoiceMailNumber(spn);
1330c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            voiceMailTag = mVmConfig.getVoiceMailTag(spn);
1331c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1332c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1333c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1334c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1335c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public void onReady() {
1336c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        fetchSimRecords();
1337c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1338c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1339c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void fetchSimRecords() {
1340c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsRequested = true;
1341c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1342c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("fetchSimRecords " + recordsToLoad);
1343c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1344e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka        mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
1345c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1346c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1347c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
1348c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1349c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1350c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // FIXME should examine EF[MSISDN]'s capability configuration
1351c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // to determine which is the voice/data/fax line
1352c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1,
1353c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    obtainMessage(EVENT_GET_MSISDN_DONE));
1354c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1355c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1356c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Record number is subscriber profile
1357c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE));
1358c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1359c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1360c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
1361c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1362c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1363c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Record number is subscriber profile
1364c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE));
1365c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1366c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1367c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1368c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Also load CPHS-style voice mail indicator, which stores
1369c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // the same info as EF[MWIS]. If both exist, both are updated
1370c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // but the EF[MWIS] data is preferred
1371c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Please note this must be loaded after EF[MWIS]
1372c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(
1373c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                EF_VOICE_MAIL_INDICATOR_CPHS,
1374c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));
1375c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1376c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1377c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Same goes for Call Forward Status indicator: fetch both
1378c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
1379c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
1380c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1381c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
1382c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1383c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1384c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1385c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        getSpnFsm(true, null);
1386c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1387c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE));
1388c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1389c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1390c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE));
1391c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1392c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1393c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
1394c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1395c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1396c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
1397c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1398c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1399c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
1400c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        recordsToLoad++;
1401c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1402c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // XXX should seek instead of examining them all
1403c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (false) { // XXX
1404c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
1405c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            recordsToLoad++;
1406c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1407c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1408c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (CRASH_RIL) {
1409c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String sms = "0107912160130310f20404d0110041007030208054832b0120"
1410c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1411c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1412c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1413c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1414c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                         + "ffffffffffffffffffffffffffffff";
1415c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            byte[] ba = IccUtils.hexStringToBytes(sms);
1416c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1417c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            mFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
1418c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
1419c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1420c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (DBG) log("fetchSimRecords " + recordsToLoad + " requested: " + recordsRequested);
1421c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1422c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1423c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1424c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Returns the SpnDisplayRule based on settings on the SIM and the
1425c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * specified plmn (currently-registered PLMN).  See TS 22.101 Annex A
1426c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * and TS 51.011 10.3.11 for details.
1427c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
14282bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati     * If the SPN is not found on the SIM or is empty, the rule is
14292bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati     * always PLMN_ONLY.
1430c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1431c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    @Override
1432c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public int getDisplayRule(String plmn) {
1433c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int rule;
14342bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati        if (TextUtils.isEmpty(spn) || spnDisplayCondition == -1) {
14352bc7f2e1da139e183519af01f50940327ca9765eAnju Mathapati            // No EF_SPN content was found on the SIM, or not yet loaded.  Just show ONS.
1436c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_PLMN;
1437c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else if (isOnMatchingPlmn(plmn)) {
1438c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_SPN;
1439c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if ((spnDisplayCondition & 0x01) == 0x01) {
1440c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // ONS required when registered to HPLMN or PLMN in EF_SPDI
1441c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                rule |= SPN_RULE_SHOW_PLMN;
1442c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1443c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        } else {
1444c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            rule = SPN_RULE_SHOW_PLMN;
1445c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if ((spnDisplayCondition & 0x02) == 0x00) {
1446c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // SPN required if not registered to HPLMN or PLMN in EF_SPDI
1447c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                rule |= SPN_RULE_SHOW_SPN;
1448c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1449c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1450c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return rule;
1451c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1452c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1453c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1454c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Checks if plmn is HPLMN or on the spdiNetworks list.
1455c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1456c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean isOnMatchingPlmn(String plmn) {
1457c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmn == null) return false;
1458c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1459c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmn.equals(getOperatorNumeric())) {
1460c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return true;
1461c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1462c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1463c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (spdiNetworks != null) {
1464c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            for (String spdiNet : spdiNetworks) {
1465c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (plmn.equals(spdiNet)) {
1466c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    return true;
1467c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1468c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1469c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1470c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return false;
1471c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1472c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1473c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1474c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * States of Get SPN Finite State Machine which only used by getSpnFsm()
1475c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1476c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private enum Get_Spn_Fsm_State {
1477c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        IDLE,               // No initialized
1478c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        INIT,               // Start FSM
1479c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_3GPP,      // Load EF_SPN firstly
1480c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_CPHS,      // Load EF_SPN_CPHS secondly
1481c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last
1482c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1483c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1484c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1485c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Finite State Machine to load Service Provider Name , which can be stored
1486c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2)
1487c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1488c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * After starting, FSM will search SPN EFs in order and stop after finding
1489c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * the first valid SPN
1490c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1491c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * If the FSM gets restart while waiting for one of
1492c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * SPN EFs results (i.e. a SIM refresh occurs after issuing
1493c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * read EF_CPHS_SPN), it will re-initialize only after
1494c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * receiving and discarding the unfinished SPN EF result.
1495c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1496c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param start set true only for initialize loading
1497c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param ar the AsyncResult from loadEFTransparent
1498c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ar.exception holds exception in error
1499c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *        ar.result is byte[] for data in success
1500c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1501c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void getSpnFsm(boolean start, AsyncResult ar) {
1502c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte[] data;
1503c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1504c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (start) {
1505c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Check previous state to see if there is outstanding
1506c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // SPN read
1507c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if(spnState == Get_Spn_Fsm_State.READ_SPN_3GPP ||
1508c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville               spnState == Get_Spn_Fsm_State.READ_SPN_CPHS ||
1509c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville               spnState == Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS ||
1510c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville               spnState == Get_Spn_Fsm_State.INIT) {
1511c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // Set INIT then return so the INIT code
1512c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                // will run when the outstanding read done.
1513c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                spnState = Get_Spn_Fsm_State.INIT;
1514c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                return;
1515c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            } else {
1516c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                spnState = Get_Spn_Fsm_State.INIT;
1517c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1518c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1519c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1520c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        switch(spnState){
1521c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case INIT:
1522c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                spn = null;
1523c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1524c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                mFh.loadEFTransparent(EF_SPN,
1525c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                        obtainMessage(EVENT_GET_SPN_DONE));
1526c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                recordsToLoad++;
1527c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1528c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                spnState = Get_Spn_Fsm_State.READ_SPN_3GPP;
1529c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1530c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_3GPP:
1531c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1532c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
1533c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    spnDisplayCondition = 0xff & data[0];
1534c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    spn = IccUtils.adnStringFieldToString(data, 1, data.length - 1);
1535c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1536c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Load EF_SPN: " + spn
1537c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            + " spnDisplayCondition: " + spnDisplayCondition);
1538c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
1539c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1540c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    spnState = Get_Spn_Fsm_State.IDLE;
1541c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1542c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFTransparent( EF_SPN_CPHS,
1543c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            obtainMessage(EVENT_GET_SPN_DONE));
1544c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    recordsToLoad++;
1545c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1546c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    spnState = Get_Spn_Fsm_State.READ_SPN_CPHS;
1547c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1548c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // See TS 51.011 10.3.11.  Basically, default to
1549c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    // show PLMN always, and SPN also if roaming.
1550c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    spnDisplayCondition = -1;
1551c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1552c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1553c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_CPHS:
1554c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1555c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
15569386a53046f7cb9137b958c8d255306248c881cdJohan Redestig                    spn = IccUtils.adnStringFieldToString(data, 0, data.length);
1557c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1558c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Load EF_SPN_CPHS: " + spn);
1559c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
1560c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1561c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    spnState = Get_Spn_Fsm_State.IDLE;
1562c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                } else {
1563c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    mFh.loadEFTransparent(
1564c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                            EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE));
1565c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    recordsToLoad++;
1566c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1567c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    spnState = Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS;
1568c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1569c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1570c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            case READ_SPN_SHORT_CPHS:
1571c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                if (ar != null && ar.exception == null) {
1572c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    data = (byte[]) ar.result;
15739386a53046f7cb9137b958c8d255306248c881cdJohan Redestig                    spn = IccUtils.adnStringFieldToString(data, 0, data.length);
1574c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1575c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("Load EF_SPN_SHORT_CPHS: " + spn);
1576c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
1577c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }else {
1578c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                    if (DBG) log("No SPN loaded in either CHPS or 3GPP");
1579c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                }
1580c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1581c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                spnState = Get_Spn_Fsm_State.IDLE;
1582c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1583c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            default:
1584c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                spnState = Get_Spn_Fsm_State.IDLE;
1585c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1586c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1587c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1588c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1589c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Parse TS 51.011 EF[SPDI] record
1590c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * This record contains the list of numeric network IDs that
1591c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * are treated specially when determining SPN display
1592c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1593c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void
1594c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    parseEfSpdi(byte[] data) {
1595c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        SimTlv tlv = new SimTlv(data, 0, data.length);
1596c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1597c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte[] plmnEntries = null;
1598c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1599c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for ( ; tlv.isValidObject() ; tlv.nextObject()) {
1600c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Skip SPDI tag, if existant
1601c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (tlv.getTag() == TAG_SPDI) {
1602c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville              tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
1603c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1604c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // There should only be one TAG_SPDI_PLMN_LIST
1605c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
1606c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                plmnEntries = tlv.getData();
1607c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                break;
1608c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1609c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1610c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1611c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (plmnEntries == null) {
1612c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            return;
1613c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1614c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1615c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        spdiNetworks = new ArrayList<String>(plmnEntries.length / 3);
1616c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1617c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0 ; i + 2 < plmnEntries.length ; i += 3) {
1618c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            String plmnCode;
1619c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            plmnCode = IccUtils.bcdToString(plmnEntries, i, 3);
1620c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1621c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            // Valid operator codes are 5 or 6 digits
1622c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            if (plmnCode.length() >= 5) {
1623c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                log("EF_SPDI network: " + plmnCode);
1624c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                spdiNetworks.add(plmnCode);
1625c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville            }
1626c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1627c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1628c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1629c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1630c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * check to see if Mailbox Number is allocated and activated in CPHS SST
1631c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1632c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private boolean isCphsMailboxEnabled() {
1633c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        if (mCphsInfo == null)  return false;
1634c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED );
1635c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1636c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1637c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void log(String s) {
1638c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Log.d(LOG_TAG, "[SIMRecords] " + s);
1639c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1640c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1641c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void loge(String s) {
1642c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Log.e(LOG_TAG, "[SIMRecords] " + s);
1643c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1644c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1645c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void logw(String s, Throwable tr) {
1646c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Log.w(LOG_TAG, "[SIMRecords] " + s, tr);
1647c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1648c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1649c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    protected void logv(String s) {
1650c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        Log.v(LOG_TAG, "[SIMRecords] " + s);
1651c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1652c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1653c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1654c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Return true if "Restriction of menu options for manual PLMN selection"
1655c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * bit is set or EF_CSP data is unavailable, return false otherwise.
1656c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1657c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    public boolean isCspPlmnEnabled() {
1658c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        return mCspPlmnEnabled;
1659c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1660c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1661c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    /**
1662c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Parse EF_CSP data and check if
1663c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * "Restriction of menu options for manual PLMN selection" is
1664c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * Enabled/Disabled
1665c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     *
1666c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     * @param data EF_CSP hex data.
1667c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville     */
1668c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    private void handleEfCspData(byte[] data) {
1669c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
1670c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // 18 bytes (i.e 9 service groups info) and additional data specific to
1671c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // operator. The valueAddedServicesGroup is not part of standard
1672c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // services. This is operator specific and can be programmed any where.
1673c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // Normally this is programmed as 10th service after the standard
1674c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // services.
1675c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        int usedCspGroups = data.length / 2;
1676c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        // This is the "Servive Group Number" of "Value Added Services Group".
1677c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        byte valueAddedServicesGroup = (byte)0xC0;
1678c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1679c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        mCspPlmnEnabled = true;
1680c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        for (int i = 0; i < usedCspGroups; i++) {
1681c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             if (data[2 * i] == valueAddedServicesGroup) {
1682c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 log("[CSP] found ValueAddedServicesGroup, value " + data[(2 * i) + 1]);
1683c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 if ((data[(2 * i) + 1] & 0x80) == 0x80) {
1684c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Bit 8 is for
1685c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // "Restriction of menu options for manual PLMN selection".
1686c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection menu should be enabled.
1687c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mCspPlmnEnabled = true;
1688c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 } else {
1689c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mCspPlmnEnabled = false;
1690c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection menu should be disabled.
1691c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     // Operator Selection Mode should be set to Automatic.
1692c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     log("[CSP] Set Automatic Network Selection");
1693c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                     mNetworkSelectionModeAutomaticRegistrants.notifyRegistrants();
1694c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 }
1695c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville                 return;
1696c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville             }
1697c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        }
1698c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1699c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville        log("[CSP] Value Added Service Group (0xC0), not found!");
1700c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    }
1701c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
1702