Add wrapper classes for UICC service tables.

The USIM application on the UICC contains an EF for the USIM service table,
a byte array containing a bit field of available services on the USIM.

IccServiceTable is an abstract class to manage a byte array containing a
service table and map it to human-readable enum values defined in the
subclass, e.g. UsimServiceTable. The availability of a service can be
tested with isAvailable(), which is implemented in the subclass to take
an enum, e.g. UsimService, as a parameter, and passes the ordinal to the
generic isAvailable() in the parent. IccServiceTable also provides a
toString() method that returns a human-readable list of enabled services.

The ISIM application for IMS contains a similar ISIM service table.
This can be supported with a new IsimServiceTable class in the future.

Change-Id: I9c3134672ed306e297dd35d633235cffca510aad
This commit is contained in:
Jake Hamby
2011-09-24 13:58:45 -07:00
parent dd579c3e92
commit 4db49b33b8
7 changed files with 398 additions and 6 deletions

View File

@@ -57,7 +57,6 @@ public abstract class IccRecords extends Handler implements IccConstants {
protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
protected String spn;
protected int spnDisplayCondition;
// ***** Constants

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.util.Log;
/**
* Wrapper class for an ICC EF containing a bit field of enabled services.
*/
public abstract class IccServiceTable {
protected final byte[] mServiceTable;
protected IccServiceTable(byte[] table) {
mServiceTable = table;
}
// Get the class name to use for log strings
protected abstract String getTag();
// Get the array of enums to use for toString
protected abstract Object[] getValues();
/**
* Returns if the specified service is available.
* @param service the service number as a zero-based offset (the enum ordinal)
* @return true if the service is available; false otherwise
*/
protected boolean isAvailable(int service) {
int offset = service / 8;
if (offset >= mServiceTable.length) {
// Note: Enums are zero-based, but the TS service numbering is one-based
Log.e(getTag(), "isAvailable for service " + (service + 1) + " fails, max service is " +
(mServiceTable.length * 8));
return false;
}
int bit = service % 8;
return (mServiceTable[offset] & (1 << bit)) != 0;
}
public String toString() {
Object[] values = getValues();
int numBytes = mServiceTable.length;
StringBuilder builder = new StringBuilder(getTag()).append('[')
.append(numBytes * 8).append("]={ ");
boolean addComma = false;
for (int i = 0; i < numBytes; i++) {
byte currentByte = mServiceTable[i];
for (int bit = 0; bit < 8; bit++) {
if ((currentByte & (1 << bit)) != 0) {
if (addComma) {
builder.append(", ");
} else {
addComma = true;
}
int ordinal = (i * 8) + bit;
if (ordinal < values.length) {
builder.append(values[ordinal]);
} else {
builder.append('#').append(ordinal + 1); // service number (one-based)
}
}
}
}
return builder.append(" }").toString();
}
}

View File

@@ -282,6 +282,9 @@ public final class CdmaLteUiccRecords extends SIMRecords {
obtainMessage(EVENT_GET_MSISDN_DONE));
recordsToLoad++;
iccFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
recordsToLoad++;
iccFh.loadEFTransparent(EF_CSIM_LI,
obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded()));
recordsToLoad++;
@@ -384,12 +387,12 @@ public final class CdmaLteUiccRecords extends SIMRecords {
@Override
protected void log(String s) {
if (DBG) Log.d(LOG_TAG, "[CSIM] " + s);
Log.d(LOG_TAG, "[CSIM] " + s);
}
@Override
protected void loge(String s) {
if (DBG) Log.e(LOG_TAG, "[CSIM] " + s);
Log.e(LOG_TAG, "[CSIM] " + s);
}
public String getMdn() {

View File

@@ -91,6 +91,8 @@ public class SIMRecords extends IccRecords {
String pnnHomeName = null;
UsimServiceTable mUsimServiceTable;
// ***** Constants
// Bitmasks for SPN display rules.
@@ -134,7 +136,7 @@ public class SIMRecords extends IccRecords {
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;
protected 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;
@@ -246,6 +248,10 @@ public class SIMRecords extends IccRecords {
return msisdn;
}
public UsimServiceTable getUsimServiceTable() {
return mUsimServiceTable;
}
/**
* Set subscriber number to SIM record
*
@@ -961,8 +967,9 @@ public class SIMRecords extends IccRecords {
break;
}
//Log.d(LOG_TAG, "SST: " + IccUtils.bytesToHexString(data));
break;
mUsimServiceTable = new UsimServiceTable(data);
if (DBG) log("SST: " + mUsimServiceTable);
break;
case EVENT_GET_INFO_CPHS_DONE:
isRecordLoadResponse = true;

View File

@@ -0,0 +1,142 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
import com.android.internal.telephony.IccServiceTable;
/**
* Wrapper class for the USIM Service Table EF.
* See 3GPP TS 31.102 Release 10 section 4.2.8
*/
public final class UsimServiceTable extends IccServiceTable {
public enum UsimService {
PHONEBOOK,
FDN, // Fixed Dialing Numbers
FDN_EXTENSION, // FDN extension data in EF_EXT2
SDN, // Service Dialing Numbers
SDN_EXTENSION, // SDN extension data in EF_EXT3
BDN, // Barred Dialing Numbers
BDN_EXTENSION, // BDN extension data in EF_EXT4
OUTGOING_CALL_INFO,
INCOMING_CALL_INFO,
SM_STORAGE,
SM_STATUS_REPORTS,
SM_SERVICE_PARAMS,
ADVICE_OF_CHARGE,
CAP_CONFIG_PARAMS_2,
CB_MESSAGE_ID,
CB_MESSAGE_ID_RANGES,
GROUP_ID_LEVEL_1,
GROUP_ID_LEVEL_2,
SPN, // Service Provider Name
USER_PLMN_SELECT,
MSISDN,
IMAGE,
LOCALISED_SERVICE_AREAS,
EMLPP, // Enhanced Multi-Level Precedence and Preemption
EMLPP_AUTO_ANSWER,
RFU,
GSM_ACCESS,
DATA_DL_VIA_SMS_PP,
DATA_DL_VIA_SMS_CB,
CALL_CONTROL_BY_USIM,
MO_SMS_CONTROL_BY_USIM,
RUN_AT_COMMAND,
IGNORED_1,
ENABLED_SERVICES_TABLE,
APN_CONTROL_LIST,
DEPERSONALISATION_CONTROL_KEYS,
COOPERATIVE_NETWORK_LIST,
GSM_SECURITY_CONTEXT,
CPBCCH_INFO,
INVESTIGATION_SCAN,
MEXE,
OPERATOR_PLMN_SELECT,
HPLMN_SELECT,
EXTENSION_5, // Extension data for ICI, OCI, MSISDN in EF_EXT5
PLMN_NETWORK_NAME,
OPERATOR_PLMN_LIST,
MBDN, // Mailbox Dialing Numbers
MWI_STATUS, // Message Waiting Indication status
CFI_STATUS, // Call Forwarding Indication status
IGNORED_2,
SERVICE_PROVIDER_DISPLAY_INFO,
MMS_NOTIFICATION,
MMS_NOTIFICATION_EXTENSION, // MMS Notification extension data in EF_EXT8
GPRS_CALL_CONTROL_BY_USIM,
MMS_CONNECTIVITY_PARAMS,
NETWORK_INDICATION_OF_ALERTING,
VGCS_GROUP_ID_LIST,
VBS_GROUP_ID_LIST,
PSEUDONYM,
IWLAN_USER_PLMN_SELECT,
IWLAN_OPERATOR_PLMN_SELECT,
USER_WSID_LIST,
OPERATOR_WSID_LIST,
VGCS_SECURITY,
VBS_SECURITY,
WLAN_REAUTH_IDENTITY,
MM_STORAGE,
GBA, // Generic Bootstrapping Architecture
MBMS_SECURITY,
DATA_DL_VIA_USSD,
EQUIVALENT_HPLMN,
TERMINAL_PROFILE_AFTER_UICC_ACTIVATION,
EQUIVALENT_HPLMN_PRESENTATION,
LAST_RPLMN_SELECTION_INDICATION,
OMA_BCAST_PROFILE,
GBA_LOCAL_KEY_ESTABLISHMENT,
TERMINAL_APPLICATIONS,
SPN_ICON,
PLMN_NETWORK_NAME_ICON,
USIM_IP_CONNECTION_PARAMS,
IWLAN_HOME_ID_LIST,
IWLAN_EQUIVALENT_HPLMN_PRESENTATION,
IWLAN_HPLMN_PRIORITY_INDICATION,
IWLAN_LAST_REGISTERED_PLMN,
EPS_MOBILITY_MANAGEMENT_INFO,
ALLOWED_CSG_LISTS_AND_INDICATIONS,
CALL_CONTROL_ON_EPS_PDN_CONNECTION_BY_USIM,
HPLMN_DIRECT_ACCESS,
ECALL_DATA,
OPERATOR_CSG_LISTS_AND_INDICATIONS,
SM_OVER_IP,
CSG_DISPLAY_CONTROL,
IMS_COMMUNICATION_CONTROL_BY_USIM,
EXTENDED_TERMINAL_APPLICATIONS,
UICC_ACCESS_TO_IMS,
NAS_CONFIG_BY_USIM
}
public UsimServiceTable(byte[] table) {
super(table);
}
public boolean isAvailable(UsimService service) {
return super.isAvailable(service.ordinal());
}
@Override
protected String getTag() {
return "UsimServiceTable";
}
@Override
protected Object[] getValues() {
return UsimService.values();
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
/**
* Test IccServiceTable class.
*/
public class IccServiceTableTest extends AndroidTestCase {
static class TestIccServiceTable extends IccServiceTable {
public enum TestIccService {
SERVICE1,
SERVICE2,
SERVICE3,
SERVICE4
}
public TestIccServiceTable(byte[] table) {
super(table);
}
public boolean isAvailable(TestIccService service) {
return super.isAvailable(service.ordinal());
}
@Override
protected String getTag() {
return "TestIccServiceTable";
}
@Override
protected Object[] getValues() {
return TestIccService.values();
}
}
@SmallTest
public void testIccServiceTable() {
byte[] noServices = {0x00};
byte[] service1 = {0x01};
byte[] service4 = {0x08};
byte[] allServices = {0x0f};
TestIccServiceTable testTable1 = new TestIccServiceTable(noServices);
assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
TestIccServiceTable testTable2 = new TestIccServiceTable(service1);
assertTrue(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
TestIccServiceTable testTable3 = new TestIccServiceTable(service4);
assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
assertTrue(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
TestIccServiceTable testTable4 = new TestIccServiceTable(allServices);
assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
/**
* Test UsimServiceTable class.
*/
public class UsimServiceTableTest extends AndroidTestCase {
@SmallTest
public void testUsimServiceTable() {
byte[] noServices = {0x00};
byte[] service1 = {0x01, 0x00};
byte[] service8 = {(byte) 0x80, 0x00, 0x00};
byte[] service8And9 = {(byte) 0x80, 0x01};
byte[] service28 = {0x00, 0x00, 0x00, 0x08};
byte[] service89To96 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, (byte) 0xff};
UsimServiceTable testTable1 = new UsimServiceTable(noServices);
assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.FDN));
assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
UsimServiceTable testTable2 = new UsimServiceTable(service1);
assertTrue(testTable2.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.FDN));
assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
UsimServiceTable testTable3 = new UsimServiceTable(service8);
assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
assertTrue(testTable3.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
UsimServiceTable testTable4 = new UsimServiceTable(service8And9);
assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.SM_STORAGE));
assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
UsimServiceTable testTable5 = new UsimServiceTable(service28);
assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
assertTrue(testTable5.isAvailable(UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP));
assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
UsimServiceTable testTable6 = new UsimServiceTable(service89To96);
assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.HPLMN_DIRECT_ACCESS));
assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.ECALL_DATA));
assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.SM_OVER_IP));
assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.UICC_ACCESS_TO_IMS));
assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
}
}