package com.android.internal.telephony.gsm;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import android.content.Context;
import android.os.AsyncResult;
import android.os.Message;
import android.os.SystemProperties;
import android.util.Log;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.AdnRecordCache;
import com.android.internal.telephony.AdnRecordLoader;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccRecords;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.IccVmFixedException;
import com.android.internal.telephony.IccVmNotSupportedException;
import com.android.internal.telephony.MccTable;
import java.util.ArrayList;
/**
* {@hide}
*/
public final class SIMRecords extends IccRecords {
static final String LOG_TAG = "GSM";
private static final boolean CRASH_RIL = false;
private static final boolean DBG = true;
// ***** Instance Variables
VoiceMailConstants mVmConfig;
SpnOverride mSpnOverride;
// ***** Cached SIM State; cleared on channel close
String imsi;
boolean callForwardingEnabled;
/**
* States only used by getSpnFsm FSM
*/
private Get_Spn_Fsm_State spnState;
/** CPHS service information (See CPHS 4.2 B.3.1.1)
* It will be set in onSimReady if reading GET_CPHS_INFO successfully
* mCphsInfo[0] is CPHS Phase
* mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
*/
private byte[] mCphsInfo = null;
byte[] efMWIS = null;
byte[] efCPHS_MWI =null;
byte[] mEfCff = null;
byte[] mEfCfis = null;
int spnDisplayCondition;
// Numeric network codes listed in TS 51.011 EF[SPDI]
ArrayList<String> spdiNetworks = null;
String pnnHomeName = null;
// ***** Constants
// Bitmasks for SPN display rules.
static final int SPN_RULE_SHOW_SPN = 0x01;
static final int SPN_RULE_SHOW_PLMN = 0x02;
// From TS 51.011 EF[SPDI] section
static final int TAG_SPDI_PLMN_LIST = 0x80;
// Full Name IEI from TS 24.008
static final int TAG_FULL_NETWORK_NAME = 0x43;
// Short Name IEI from TS 24.008
static final int TAG_SHORT_NETWORK_NAME = 0x45;
// active CFF from CPHS 4.2 B.4.5
static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
static final int CFF_LINE1_MASK = 0x0f;
static final int CFF_LINE1_RESET = 0xf0;
// CPHS Service Table (See CPHS 4.2 B.3.1)
private static final int CPHS_SST_MBN_MASK = 0x30;
private static final int CPHS_SST_MBN_ENABLED = 0x30;
// ***** Event Constants
private static final int EVENT_SIM_READY = 1;
private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
private static final int EVENT_GET_IMSI_DONE = 3;
private static final int EVENT_GET_ICCID_DONE = 4;
private static final int EVENT_GET_MBI_DONE = 5;
private static final int EVENT_GET_MBDN_DONE = 6;
private static final int EVENT_GET_MWIS_DONE = 7;
private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8;
private static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM
private static final int EVENT_GET_MSISDN_DONE = 10;
private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11;
private static final int EVENT_GET_SPN_DONE = 12;
private static final int EVENT_GET_SPDI_DONE = 13;
private static final int EVENT_UPDATE_DONE = 14;
private static final int EVENT_GET_PNN_DONE = 15;
private static final int EVENT_GET_SST_DONE = 17;
private static final int EVENT_GET_ALL_SMS_DONE = 18;
private static final int EVENT_MARK_SMS_READ_DONE = 19;
private static final int EVENT_SET_MBDN_DONE = 20;
private static final int EVENT_SMS_ON_SIM = 21;
private static final int EVENT_GET_SMS_DONE = 22;
private static final int EVENT_GET_CFF_DONE = 24;
private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25;
private static final int EVENT_GET_INFO_CPHS_DONE = 26;
private static final int EVENT_SET_MSISDN_DONE = 30;
private static final int EVENT_SIM_REFRESH = 31;
private static final int EVENT_GET_CFIS_DONE = 32;
// Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
"405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
"405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
"405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
"405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
"405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
"405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
"405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
"405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
"405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
"405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
"405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
"405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
"405886", "405908", "405909", "405910", "405911", "405925", "405926", "405927",
"405928", "405929", "405932"
};
// ***** Constructor
SIMRecords(GSMPhone p) {
super(p);
adnCache = new AdnRecordCache(phone);
mVmConfig = new VoiceMailConstants();
mSpnOverride = new SpnOverride();
recordsRequested = false; // No load request is made till SIM ready
// recordsToLoad is set to 0 because no requests are made yet
recordsToLoad = 0;
p.mCM.registerForSIMReady(this, EVENT_SIM_READY, null);
p.mCM.registerForOffOrNotAvailable(
this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mCM.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
p.mCM.setOnIccRefresh(this, EVENT_SIM_REFRESH, null);
// Start off by setting empty state
onRadioOffOrNotAvailable();
}
public void dispose() {
//Unregister for all events
phone.mCM.unregisterForSIMReady(this);
phone.mCM.unregisterForOffOrNotAvailable( this);
phone.mCM.unSetOnIccRefresh(this);
}
protected void finalize() {
if(DBG) Log.d(LOG_TAG, "SIMRecords finalized");
}
protected void onRadioOffOrNotAvailable() {
imsi = null;
msisdn = null;
voiceMailNum = null;
countVoiceMessages = 0;
mncLength = UNINITIALIZED;
iccid = null;
// -1 means no EF_SPN found; treat accordingly.
spnDisplayCondition = -1;
efMWIS = null;
efCPHS_MWI = null;
spdiNetworks = null;
pnnHomeName = null;
adnCache.reset();
phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null);
phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, null);
phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
// recordsRequested is set to false indicating that the SIM
// read requests made so far are not valid. This is set to
// true only when fresh set of read requests are made.
recordsRequested = false;
}
//***** Public Methods
/** Returns null if SIM is not yet ready */
public String getIMSI() {
return imsi;
}
publi