summaryrefslogtreecommitdiffstats
path: root/telephony/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'telephony/java/com')
-rw-r--r--telephony/java/com/android/internal/telephony/CommandsInterface.java19
-rw-r--r--telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl19
-rw-r--r--telephony/java/com/android/internal/telephony/IccRecords.java62
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java17
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java10
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java9
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneSubInfo.java52
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java25
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java20
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java1
-rw-r--r--telephony/java/com/android/internal/telephony/cat/ResponseData.java66
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java36
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java4
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java429
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/RuimRecords.java4
-rwxr-xr-xtelephony/java/com/android/internal/telephony/gsm/SIMRecords.java9
-rw-r--r--telephony/java/com/android/internal/telephony/ims/IsimRecords.java44
-rw-r--r--telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java157
-rw-r--r--telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java5
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedCommands.java4
20 files changed, 705 insertions, 287 deletions
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index b68cbe9..1caea70 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -1489,11 +1489,8 @@ public interface CommandsInterface {
/**
* Setup a packet data connection On successful completion, the result
- * message will return the following: [0] indicating PDP CID, which is
- * generated by RIL. This Connection ID is used in both GSM/UMTS and CDMA
- * modes [1] indicating the network interface name for GSM/UMTS or CDMA [2]
- * indicating the IP address for this interface for GSM/UMTS and NULL in the
- * case of CDMA
+ * message will return a {@link DataCallState} object containing the connection
+ * information.
*
* @param radioTechnology
* indicates whether to setup connection on radio technology CDMA
@@ -1569,7 +1566,7 @@ public interface CommandsInterface {
/**
* Request the status of the ICC and UICC cards.
*
- * @param response
+ * @param result
* Callback message containing {@link IccCardStatus} structure for the card.
*/
public void getIccCardStatus(Message result);
@@ -1583,4 +1580,14 @@ public interface CommandsInterface {
* or {@link Phone#LTE_ON_CDMA_TRUE}
*/
public int getLteOnCdmaMode();
+
+ /**
+ * Request the ISIM application on the UICC to perform the AKA
+ * challenge/response algorithm for IMS authentication. The nonce string
+ * and challenge response are Base64 encoded Strings.
+ *
+ * @param nonce the nonce string to pass with the ISIM authentication request
+ * @param response a callback message with the String response in the obj field
+ */
+ public void requestIsimAuthentication(String nonce, Message response);
}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index 5cba2e1..def770f 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -67,4 +67,23 @@ interface IPhoneSubInfo {
* Retrieves the alpha identifier associated with the voice mail number.
*/
String getVoiceMailAlphaTag();
+
+ /**
+ * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
+ * @return the IMPI, or null if not present or not loaded
+ */
+ String getIsimImpi();
+
+ /**
+ * Returns the IMS home network domain name that was loaded from the ISIM.
+ * @return the IMS domain name, or null if not present or not loaded
+ */
+ String getIsimDomain();
+
+ /**
+ * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
+ * @return an array of IMPU strings, with one IMPU per string, or null if
+ * not present or not loaded
+ */
+ String[] getIsimImpu();
}
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index 3a27901..84bfc40 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -22,6 +22,8 @@ import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
+import com.android.internal.telephony.ims.IsimRecords;
+
/**
* {@hide}
*/
@@ -70,6 +72,24 @@ public abstract class IccRecords extends Handler implements IccConstants {
// ***** Event Constants
protected static final int EVENT_SET_MSISDN_DONE = 30;
+ public static final int EVENT_GET_ICC_RECORD_DONE = 100;
+
+ /**
+ * Generic ICC record loaded callback. Subclasses can call EF load methods on
+ * {@link IccFileHandler} passing a Message for onLoaded with the what field set to
+ * {@link #EVENT_GET_ICC_RECORD_DONE} and the obj field set to an instance
+ * of this interface. The {@link #handleMessage} method in this class will print a
+ * log message using {@link #getEfName()} and decrement {@link #recordsToLoad}.
+ *
+ * If the record load was successful, {@link #onRecordLoaded} will be called with the result.
+ * Otherwise, an error log message will be output by {@link #handleMessage} and
+ * {@link #onRecordLoaded} will not be called.
+ */
+ public interface IccRecordLoaded {
+ String getEfName();
+ void onRecordLoaded(AsyncResult ar);
+ }
+
// ***** Constructor
public IccRecords(PhoneBase p) {
@@ -234,7 +254,32 @@ public abstract class IccRecords extends Handler implements IccConstants {
//***** Overridden from Handler
@Override
- public abstract void handleMessage(Message msg);
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_GET_ICC_RECORD_DONE:
+ try {
+ AsyncResult ar = (AsyncResult) msg.obj;
+ IccRecordLoaded recordLoaded = (IccRecordLoaded) ar.userObj;
+ if (DBG) log(recordLoaded.getEfName() + " LOADED");
+
+ if (ar.exception != null) {
+ loge("Record Load Exception: " + ar.exception);
+ } else {
+ recordLoaded.onRecordLoaded(ar);
+ }
+ }catch (RuntimeException exc) {
+ // I don't want these exceptions to be fatal
+ loge("Exception parsing SIM record: " + exc);
+ } finally {
+ // Count up record load responses even if they are fails
+ onRecordLoaded();
+ }
+ break;
+
+ default:
+ super.handleMessage(msg);
+ }
+ }
protected abstract void onRecordLoaded();
@@ -303,4 +348,19 @@ public abstract class IccRecords extends Handler implements IccConstants {
* @param s is the string to write
*/
protected abstract void log(String s);
+
+ /**
+ * Write error string to log file.
+ *
+ * @param s is the string to write
+ */
+ protected abstract void loge(String s);
+
+ /**
+ * Return an interface to retrieve the ISIM records for IMS, if available.
+ * @return the interface to retrieve the ISIM records, or null if not supported
+ */
+ public IsimRecords getIsimRecords() {
+ return null;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 4b02e8e..6347f37 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -28,6 +28,7 @@ import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import com.android.internal.telephony.DataConnection;
+import com.android.internal.telephony.ims.IsimRecords;
import com.android.internal.telephony.test.SimulatedRadioControl;
import java.util.List;
@@ -1730,4 +1731,20 @@ public interface Phone {
* false otherwise
*/
boolean isCspPlmnEnabled();
+
+ /**
+ * Return an interface to retrieve the ISIM records for IMS, if available.
+ * @return the interface to retrieve the ISIM records, or null if not supported
+ */
+ IsimRecords getIsimRecords();
+
+ /**
+ * Request the ISIM application on the UICC to perform the AKA
+ * challenge/response algorithm for IMS authentication. The nonce string
+ * and challenge response are Base64 encoded Strings.
+ *
+ * @param nonce the nonce string to pass with the ISIM authentication request
+ * @param response a callback message with the String response in the obj field
+ */
+ void requestIsimAuthentication(String nonce, Message response);
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index a0961ca..4f86ea8 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -37,6 +37,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
+import com.android.internal.telephony.ims.IsimRecords;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.gsm.SIMRecords;
import com.android.internal.telephony.gsm.SimCard;
@@ -1114,6 +1115,15 @@ public abstract class PhoneBase extends Handler implements Phone {
return false;
}
+ public IsimRecords getIsimRecords() {
+ Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
+ return null;
+ }
+
+ public void requestIsimAuthentication(String nonce, Message result) {
+ Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices");
+ }
+
/**
* Common error logger method for unexpected calls to CDMA-only methods.
*/
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index b5bfc76f..3678017 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -32,6 +32,7 @@ import android.util.Log;
import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.gsm.GSMPhone;
+import com.android.internal.telephony.ims.IsimRecords;
import com.android.internal.telephony.test.SimulatedRadioControl;
import java.util.List;
@@ -841,6 +842,14 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.isCspPlmnEnabled();
}
+ public IsimRecords getIsimRecords() {
+ return mActivePhone.getIsimRecords();
+ }
+
+ public void requestIsimAuthentication(String nonce, Message response) {
+ mActivePhone.requestIsimAuthentication(nonce, response);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
index a45cad1..de18d0a 100644
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
+++ b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
@@ -24,15 +24,19 @@ import android.os.Binder;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
+import com.android.internal.telephony.ims.IsimRecords;
+
public class PhoneSubInfo extends IPhoneSubInfo.Stub {
static final String LOG_TAG = "PHONE";
private Phone mPhone;
private Context mContext;
private static final String READ_PHONE_STATE =
android.Manifest.permission.READ_PHONE_STATE;
+ // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE
private static final String CALL_PRIVILEGED =
- // TODO Add core/res/AndriodManifest.xml#READ_PRIVILEGED_PHONE_STATE
android.Manifest.permission.CALL_PRIVILEGED;
+ private static final String READ_PRIVILEGED_PHONE_STATE =
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
public PhoneSubInfo(Phone phone) {
mPhone = phone;
@@ -131,6 +135,52 @@ public class PhoneSubInfo extends IPhoneSubInfo.Stub {
return (String) mPhone.getVoiceMailAlphaTag();
}
+ /**
+ * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
+ * @return the IMPI, or null if not present or not loaded
+ */
+ public String getIsimImpi() {
+ mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
+ "Requires READ_PRIVILEGED_PHONE_STATE");
+ IsimRecords isim = mPhone.getIsimRecords();
+ if (isim != null) {
+ return isim.getIsimImpi();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the IMS home network domain name that was loaded from the ISIM.
+ * @return the IMS domain name, or null if not present or not loaded
+ */
+ public String getIsimDomain() {
+ mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
+ "Requires READ_PRIVILEGED_PHONE_STATE");
+ IsimRecords isim = mPhone.getIsimRecords();
+ if (isim != null) {
+ return isim.getIsimDomain();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
+ * @return an array of IMPU strings, with one IMPU per string, or null if
+ * not present or not loaded
+ */
+ public String[] getIsimImpu() {
+ mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
+ "Requires READ_PRIVILEGED_PHONE_STATE");
+ IsimRecords isim = mPhone.getIsimRecords();
+ if (isim != null) {
+ return isim.getIsimImpu();
+ } else {
+ return null;
+ }
+ }
+
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
index 7009893..a287b2e 100644
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
@@ -95,6 +95,31 @@ public class PhoneSubInfoProxy extends IPhoneSubInfo.Stub {
return mPhoneSubInfo.getVoiceMailAlphaTag();
}
+ /**
+ * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
+ * @return the IMPI, or null if not present or not loaded
+ */
+ public String getIsimImpi() {
+ return mPhoneSubInfo.getIsimImpi();
+ }
+
+ /**
+ * Returns the IMS home network domain name that was loaded from the ISIM.
+ * @return the IMS domain name, or null if not present or not loaded
+ */
+ public String getIsimDomain() {
+ return mPhoneSubInfo.getIsimDomain();
+ }
+
+ /**
+ * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
+ * @return an array of IMPU strings, with one IMPU per string, or null if
+ * not present or not loaded
+ */
+ public String[] getIsimImpu() {
+ return mPhoneSubInfo.getIsimImpu();
+ }
+
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mPhoneSubInfo.dump(fd, pw, args);
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index c6ed405..3e13a86 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -47,17 +47,8 @@ import android.telephony.SmsMessage;
import android.text.TextUtils;
import android.util.Log;
-import com.android.internal.telephony.CallForwardInfo;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
-import com.android.internal.telephony.IccCardApplication;
-import com.android.internal.telephony.IccCardStatus;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.SmsResponse;
import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.internal.telephony.cdma.CdmaInformationRecords;
@@ -2255,6 +2246,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break;
+ case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
@@ -3461,6 +3453,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
+ case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION";
default: return "<unknown request>";
}
}
@@ -3704,4 +3697,13 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
+ public void requestIsimAuthentication(String nonce, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_ISIM_AUTHENTICATION, response);
+
+ rr.mp.writeString(nonce);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index facee5f..7fb7f41 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -261,6 +261,7 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
int RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
int RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104;
+ int RIL_REQUEST_ISIM_AUTHENTICATION = 105;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
diff --git a/telephony/java/com/android/internal/telephony/cat/ResponseData.java b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
index 55a2b63..1157c1a 100644
--- a/telephony/java/com/android/internal/telephony/cat/ResponseData.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
@@ -19,6 +19,10 @@ package com.android.internal.telephony.cat;
import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.GsmAlphabet;
import java.util.Calendar;
+import java.util.TimeZone;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+
import com.android.internal.telephony.cat.AppInterface.CommandType;
import java.io.ByteArrayOutputStream;
@@ -209,7 +213,6 @@ class DTTZResponseData extends ResponseData {
buf.write(tag); // tag
byte[] data = new byte[8];
- byte btmp; // temp variable
data[0] = 0x07; // Write length of DTTZ data
@@ -217,41 +220,62 @@ class DTTZResponseData extends ResponseData {
calendar = Calendar.getInstance();
}
// Fill year byte
- btmp = (byte) (calendar.get(java.util.Calendar.YEAR) % 100);
- data[1] = (byte) (btmp / 10);
- data[1] += (byte) ((btmp % 10) << 4);
+ data[1] = byteToBCD(calendar.get(java.util.Calendar.YEAR) % 100);
// Fill month byte
- btmp = (byte) (calendar.get(java.util.Calendar.MONTH) + 1);
- data[2] = (byte) (btmp / 10);
- data[2] += (byte) ((btmp % 10) << 4);
+ data[2] = byteToBCD(calendar.get(java.util.Calendar.MONTH) + 1);
// Fill day byte
- btmp = (byte) (calendar.get(java.util.Calendar.DATE));
- data[3] = (byte) (btmp / 10);
- data[3] += (byte) ((btmp % 10) << 4);
+ data[3] = byteToBCD(calendar.get(java.util.Calendar.DATE));
// Fill hour byte
- btmp = (byte) (calendar.get(java.util.Calendar.HOUR_OF_DAY));
- data[4] = (byte) (btmp / 10);
- data[4] += (byte) ((btmp % 10) << 4);
+ data[4] = byteToBCD(calendar.get(java.util.Calendar.HOUR_OF_DAY));
// Fill minute byte
- btmp = (byte) (calendar.get(java.util.Calendar.MINUTE));
- data[5] = (byte) (btmp / 10);
- data[5] += (byte) ((btmp % 10) << 4);
+ data[5] = byteToBCD(calendar.get(java.util.Calendar.MINUTE));
// Fill second byte
- btmp = (byte) (calendar.get(java.util.Calendar.SECOND));
- data[6] = (byte) (btmp / 10);
- data[6] += (byte) ((btmp % 10) << 4);
+ data[6] = byteToBCD(calendar.get(java.util.Calendar.SECOND));
- // No time zone info
- data[7] = (byte) 0xFF;
+ String tz = SystemProperties.get("persist.sys.timezone", "");
+ if (TextUtils.isEmpty(tz)) {
+ data[7] = (byte) 0xFF; // set FF in terminal response
+ } else {
+ TimeZone zone = TimeZone.getTimeZone(tz);
+ int zoneOffset = zone.getRawOffset() + zone.getDSTSavings();
+ data[7] = getTZOffSetByte(zoneOffset);
+ }
for (byte b : data) {
buf.write(b);
}
}
+
+ private byte byteToBCD(int value) {
+ if (value < 0 && value > 99) {
+ CatLog.d(this, "Err: byteToBCD conversion Value is " + value +
+ " Value has to be between 0 and 99");
+ return 0;
+ }
+
+ return (byte) ((value / 10) | ((value % 10) << 4));
+ }
+
+ private byte getTZOffSetByte(long offSetVal) {
+ boolean isNegative = (offSetVal < 0);
+
+ /*
+ * The 'offSetVal' is in milliseconds. Convert it to hours and compute
+ * offset While sending T.R to UICC, offset is expressed is 'quarters of
+ * hours'
+ */
+
+ long tzOffset = offSetVal / (15 * 60 * 1000);
+ tzOffset = (isNegative ? -1 : 1) * tzOffset;
+ byte bcdVal = byteToBCD((int) tzOffset);
+ // For negative offsets, put '1' in the msb
+ return isNegative ? (bcdVal |= 0x08) : bcdVal;
+ }
+
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index ac66b48..f4ed91d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * 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.
@@ -16,29 +16,19 @@
package com.android.internal.telephony.cdma;
-import android.os.SystemProperties;
+import android.content.ContentValues;
import android.content.Context;
+import android.database.SQLException;
import android.net.Uri;
-import android.content.Context;
+import android.os.Message;
import android.provider.Telephony;
-import android.content.ContentValues;
-import android.database.SQLException;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
+import android.util.Log;
-import com.android.internal.telephony.gsm.SIMRecords;
-import com.android.internal.telephony.gsm.SimCard;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.gsm.GsmDataConnectionTracker;
-
-import android.util.Log;
+import com.android.internal.telephony.gsm.SimCard;
+import com.android.internal.telephony.ims.IsimRecords;
public class CDMALTEPhone extends CDMAPhone {
static final String LOG_TAG = "CDMA";
@@ -68,7 +58,7 @@ public class CDMALTEPhone extends CDMAPhone {
DataState ret = DataState.DISCONNECTED;
if (mSST == null) {
- // Radio Technology Change is ongoning, dispose() and
+ // Radio Technology Change is ongoing, dispose() and
// removeReferences() have already been called
ret = DataState.DISCONNECTED;
@@ -146,6 +136,16 @@ public class CDMALTEPhone extends CDMAPhone {
}
@Override
+ public IsimRecords getIsimRecords() {
+ return mIccRecords.getIsimRecords();
+ }
+
+ @Override
+ public void requestIsimAuthentication(String nonce, Message result) {
+ mCM.requestIsimAuthentication(nonce, result);
+ }
+
+ @Override
protected void log(String s) {
if (DBG)
Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
index b9d7c46..b57af0e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
@@ -42,6 +42,10 @@ public final class CdmaLteUiccFileHandler extends IccFileHandler {
return MF_SIM + DF_CDMA;
case EF_AD:
return MF_SIM + DF_GSM;
+ case EF_IMPI:
+ case EF_DOMAIN:
+ case EF_IMPU:
+ return MF_SIM + DF_ADFISIM;
}
return getCommonIccEFPath(efid);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
index fc6abad..c4fa6f6 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
@@ -15,8 +15,10 @@
*/
package com.android.internal.telephony.cdma;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_TEST_CSIM;
+import android.os.AsyncResult;
+import android.os.SystemProperties;
+import android.util.Log;
+
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.IccCardApplication.AppType;
import com.android.internal.telephony.IccFileHandler;
@@ -25,12 +27,14 @@ import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.cdma.sms.UserData;
import com.android.internal.telephony.gsm.SIMRecords;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.util.Log;
-import java.util.Locale;
+import com.android.internal.telephony.ims.IsimRecords;
+import com.android.internal.telephony.ims.IsimUiccRecords;
+
import java.util.ArrayList;
+import java.util.Locale;
+
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_TEST_CSIM;
/**
* {@hide}
@@ -46,130 +50,191 @@ public final class CdmaLteUiccRecords extends SIMRecords {
private String mHomeSystemId;
private String mHomeNetworkId;
- private static final int EVENT_GET_PL_DONE = CSIM_EVENT_BASE;
- private static final int EVENT_GET_CSIM_LI_DONE = CSIM_EVENT_BASE + 1;
- private static final int EVENT_GET_CSIM_SPN_DONE = CSIM_EVENT_BASE + 2;
- private static final int EVENT_GET_CSIM_MDN_DONE = CSIM_EVENT_BASE + 3;
- private static final int EVENT_GET_CSIM_IMSIM_DONE = CSIM_EVENT_BASE + 4;
- private static final int EVENT_GET_CSIM_CDMAHOME_DONE = CSIM_EVENT_BASE + 5;
- private static final int EVENT_GET_CSIM_EPRL_DONE = CSIM_EVENT_BASE + 6;
+ private final IsimUiccRecords mIsimUiccRecords = new IsimUiccRecords();
public CdmaLteUiccRecords(PhoneBase p) {
super(p);
}
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
- byte data[];
-
- boolean isCsimRecordLoadResponse = false;
+ // Refer to ETSI TS 102.221
+ private class EfPlLoaded implements IccRecordLoaded {
+ public String getEfName() {
+ return "EF_PL";
+ }
- try { switch (msg.what) {
- case EVENT_GET_PL_DONE:
- // Refer to ETSI TS.102.221
- if (DBG) log("EF_GET_EF_PL_DONE");
- isCsimRecordLoadResponse = true;
+ public void onRecordLoaded(AsyncResult ar) {
+ mEFpl = (byte[]) ar.result;
+ if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl));
+ }
+ }
- ar = (AsyncResult) msg.obj;
+ // Refer to C.S0065 5.2.26
+ private class EfCsimLiLoaded implements IccRecordLoaded {
+ public String getEfName() {
+ return "EF_CSIM_LI";
+ }
- if (ar.exception != null) {
- Log.e(LOG_TAG, "ar.exception = " + ar.exception);
- break;
+ public void onRecordLoaded(AsyncResult ar) {
+ mEFli = (byte[]) ar.result;
+ // convert csim efli data to iso 639 format
+ for (int i = 0; i < mEFli.length; i+=2) {
+ switch(mEFli[i+1]) {
+ case 0x01: mEFli[i] = 'e'; mEFli[i+1] = 'n';break;
+ case 0x02: mEFli[i] = 'f'; mEFli[i+1] = 'r';break;
+ case 0x03: mEFli[i] = 'e'; mEFli[i+1] = 's';break;
+ case 0x04: mEFli[i] = 'j'; mEFli[i+1] = 'a';break;
+ case 0x05: mEFli[i] = 'k'; mEFli[i+1] = 'o';break;
+ case 0x06: mEFli[i] = 'z'; mEFli[i+1] = 'h';break;
+ case 0x07: mEFli[i] = 'h'; mEFli[i+1] = 'e';break;
+ default: mEFli[i] = ' '; mEFli[i+1] = ' ';
}
+ }
- mEFpl = (byte[]) ar.result;
- if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl));
- break;
+ if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli));
+ }
+ }
- case EVENT_GET_CSIM_LI_DONE:
- // Refer to C.S0065 5.2.26
- if (DBG) log("EVENT_GET_CSIM_LI_DONE");
- isCsimRecordLoadResponse = true;
+ // Refer to C.S0065 5.2.32
+ private class EfCsimSpnLoaded implements IccRecordLoaded {
+ public String getEfName() {
+ return "EF_CSIM_SPN";
+ }
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- Log.e(LOG_TAG, "ar.exception = " + ar.exception);
- break;
- }
+ public void onRecordLoaded(AsyncResult ar) {
+ byte[] data = (byte[]) ar.result;
+ if (DBG) log("CSIM_SPN=" +
+ IccUtils.bytesToHexString(data));
- mEFli = (byte[]) ar.result;
- // convert csim efli data to iso 639 format
- for (int i = 0; i < mEFli.length; i+=2) {
- switch(mEFli[i+1]) {
- case 0x01: mEFli[i] = 'e'; mEFli[i+1] = 'n';break;
- case 0x02: mEFli[i] = 'f'; mEFli[i+1] = 'r';break;
- case 0x03: mEFli[i] = 'e'; mEFli[i+1] = 's';break;
- case 0x04: mEFli[i] = 'j'; mEFli[i+1] = 'a';break;
- case 0x05: mEFli[i] = 'k'; mEFli[i+1] = 'o';break;
- case 0x06: mEFli[i] = 'z'; mEFli[i+1] = 'h';break;
- case 0x07: mEFli[i] = 'h'; mEFli[i+1] = 'e';break;
- default: mEFli[i] = ' '; mEFli[i+1] = ' ';
- }
- }
+ // C.S0065 for EF_SPN decoding
+ mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0);
- if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli));
- break;
- case EVENT_GET_CSIM_SPN_DONE:
- // Refer to C.S0065 5.2.32
- if (DBG) log("EVENT_GET_CSIM_SPN_DONE");
- isCsimRecordLoadResponse = true;
- ar = (AsyncResult) msg.obj;
+ int encoding = data[1];
+ int language = data[2];
+ byte[] spnData = new byte[32];
+ System.arraycopy(data, 3, spnData, 0, (data.length < 32) ? data.length : 32);
- if (ar.exception != null) {
- Log.e(LOG_TAG, "ar.exception=" + ar.exception);
- break;
- }
- onGetCSimSpnDone(ar);
- break;
- case EVENT_GET_CSIM_MDN_DONE:
- if (DBG) log("EVENT_GET_CSIM_MDN_DONE");
- isCsimRecordLoadResponse = true;
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- Log.e(LOG_TAG, "ar.exception=" + ar.exception);
+ int numBytes;
+ for (numBytes = 0; numBytes < spnData.length; numBytes++) {
+ if ((spnData[numBytes] & 0xFF) == 0xFF) break;
+ }
+
+ if (numBytes == 0) {
+ spn = "";
+ return;
+ }
+ try {
+ switch (encoding) {
+ case UserData.ENCODING_OCTET:
+ case UserData.ENCODING_LATIN:
+ spn = new String(spnData, 0, numBytes, "ISO-8859-1");
break;
- }
- onGetCSimMdnDone(ar);
- break;
- case EVENT_GET_CSIM_IMSIM_DONE:
- if (DBG) log("EVENT_GET_CSIM_IMSIM_DONE");
- isCsimRecordLoadResponse = true;
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- Log.e(LOG_TAG, "ar.exception=" + ar.exception);
+ case UserData.ENCODING_IA5:
+ case UserData.ENCODING_GSM_7BIT_ALPHABET:
+ case UserData.ENCODING_7BIT_ASCII:
+ spn = GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes*8)/7);
break;
- }
- onGetCSimImsimDone(ar);
- break;
- case EVENT_GET_CSIM_CDMAHOME_DONE:
- if (DBG) log("EVENT_GET_CSIM_CDMAHOME_DONE");
- isCsimRecordLoadResponse = true;
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- Log.e(LOG_TAG, "ar.exception=" + ar.exception);
+ case UserData.ENCODING_UNICODE_16:
+ spn = new String(spnData, 0, numBytes, "utf-16");
break;
+ default:
+ log("SPN encoding not supported");
}
- onGetCSimCdmaHomeDone(ar);
- break;
- case EVENT_GET_CSIM_EPRL_DONE:
- if (DBG) log("EVENT_GET_CSIM_EPRL_DONE");
- isCsimRecordLoadResponse = true;
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- Log.e(LOG_TAG, "ar.exception=" + ar.exception);
- break;
+ } catch(Exception e) {
+ log("spn decode error: " + e);
+ }
+ if (DBG) log("spn=" + spn);
+ if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition);
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, spn);
+ }
+ }
+
+ private class EfCsimMdnLoaded implements IccRecordLoaded {
+ public String getEfName() {
+ return "EF_CSIM_MDN";
+ }
+
+ public void onRecordLoaded(AsyncResult ar) {
+ byte[] data = (byte[]) ar.result;
+ if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data));
+ int mdnDigitsNum = 0x0F & data[0];
+ mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum);
+ if (DBG) log("CSIM MDN=" + mMdn);
+ }
+ }
+
+ private class EfCsimImsimLoaded implements IccRecordLoaded {
+ public String getEfName() {
+ return "EF_CSIM_IMSIM";
+ }
+
+ public void onRecordLoaded(AsyncResult ar) {
+ byte[] data = (byte[]) ar.result;
+ if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data));
+ // C.S0065 section 5.2.2 for IMSI_M encoding
+ // C.S0005 section 2.3.1 for MIN encoding in IMSI_M.
+ boolean provisioned = ((data[7] & 0x80) == 0x80);
+
+ if (provisioned) {
+ int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]);
+ int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6;
+ int digit7 = 0x0F & (data[4] >> 2);
+ if (digit7 > 0x09) digit7 = 0;
+ int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]);
+ first3digits = adjstMinDigits(first3digits);
+ second3digits = adjstMinDigits(second3digits);
+ last3digits = adjstMinDigits(last3digits);
+
+ StringBuilder builder = new StringBuilder();
+ builder.append(String.format(Locale.US, "%03d", first3digits));
+ builder.append(String.format(Locale.US, "%03d", second3digits));
+ builder.append(String.format(Locale.US, "%d", digit7));
+ builder.append(String.format(Locale.US, "%03d", last3digits));
+ mMin = builder.toString();
+ if (DBG) log("min present=" + mMin);
+ } else {
+ if (DBG) log("min not present");
+ }
+ }
+ }
+
+ private class EfCsimCdmaHomeLoaded implements IccRecordLoaded {
+ public String getEfName() {
+ return "EF_CSIM_CDMAHOME";
+ }
+
+ public void onRecordLoaded(AsyncResult ar) {
+ // Per C.S0065 section 5.2.8
+ ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result;
+ if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size());
+ if (dataList.isEmpty()) {
+ return;
+ }
+ StringBuilder sidBuf = new StringBuilder();
+ StringBuilder nidBuf = new StringBuilder();
+
+ for (byte[] data : dataList) {
+ if (data.length == 5) {
+ int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
+ int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
+ sidBuf.append(sid).append(',');
+ nidBuf.append(nid).append(',');
}
- onGetCSimEprlDone(ar);
- break;
- default:
- super.handleMessage(msg);
- }}catch (RuntimeException exc) {
- Log.w(LOG_TAG, "Exception parsing SIM record", exc);
- } finally {
- if (isCsimRecordLoadResponse) {
- onRecordLoaded();
}
+ // remove trailing ","
+ sidBuf.setLength(sidBuf.length()-1);
+ nidBuf.setLength(nidBuf.length()-1);
+
+ mHomeSystemId = sidBuf.toString();
+ mHomeNetworkId = nidBuf.toString();
+ }
+ }
+
+ private class EfCsimEprlLoaded implements IccRecordLoaded {
+ public String getEfName() {
+ return "EF_CSIM_EPRL";
+ }
+ public void onRecordLoaded(AsyncResult ar) {
+ onGetCSimEprlDone(ar);
}
}
@@ -189,8 +254,8 @@ public final class CdmaLteUiccRecords extends SIMRecords {
@Override
protected void onAllRecordsLoaded() {
- super.onAllRecordsLoaded();
setLocaleFromCsim();
+ super.onAllRecordsLoaded(); // broadcasts ICC state change to "LOADED"
}
@Override
@@ -207,112 +272,36 @@ public final class CdmaLteUiccRecords extends SIMRecords {
iccFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
recordsToLoad++;
- iccFh.loadEFTransparent(EF_PL, obtainMessage(EVENT_GET_PL_DONE));
+ iccFh.loadEFTransparent(EF_PL,
+ obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded()));
recordsToLoad++;
- iccFh.loadEFTransparent(EF_CSIM_LI, obtainMessage(EVENT_GET_CSIM_LI_DONE));
+ iccFh.loadEFTransparent(EF_CSIM_LI,
+ obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded()));
recordsToLoad++;
- iccFh.loadEFTransparent(EF_CSIM_SPN, obtainMessage(EVENT_GET_CSIM_SPN_DONE));
+ iccFh.loadEFTransparent(EF_CSIM_SPN,
+ obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimSpnLoaded()));
recordsToLoad++;
- iccFh.loadEFLinearFixed(EF_CSIM_MDN, 1, obtainMessage(EVENT_GET_CSIM_MDN_DONE));
+ iccFh.loadEFLinearFixed(EF_CSIM_MDN, 1,
+ obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMdnLoaded()));
recordsToLoad++;
- iccFh.loadEFTransparent(EF_CSIM_IMSIM, obtainMessage(EVENT_GET_CSIM_IMSIM_DONE));
+ iccFh.loadEFTransparent(EF_CSIM_IMSIM,
+ obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimImsimLoaded()));
recordsToLoad++;
iccFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME,
- obtainMessage(EVENT_GET_CSIM_CDMAHOME_DONE));
+ obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimCdmaHomeLoaded()));
recordsToLoad++;
- iccFh.loadEFTransparent(EF_CSIM_EPRL, obtainMessage(EVENT_GET_CSIM_EPRL_DONE));
+ iccFh.loadEFTransparent(EF_CSIM_EPRL,
+ obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimEprlLoaded()));
recordsToLoad++;
- }
-
- private void onGetCSimSpnDone(AsyncResult ar) {
- byte[] data = (byte[]) ar.result;
- if (DBG) log("CSIM_SPN=" +
- IccUtils.bytesToHexString(data));
-
- // C.S0065 for EF_SPN decoding
- mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0) ? true : false;
-
- int encoding = data[1];
- int language = data[2];
- byte[] spnData = new byte[32];
- System.arraycopy(data, 3, spnData, 0, (data.length < 32)?data.length:32);
-
- int numBytes;
- for (numBytes = 0; numBytes < spnData.length; numBytes++) {
- if ((spnData[numBytes] & 0xFF) == 0xFF) break;
- }
- if (numBytes == 0) {
- spn = "";
- return;
- }
- try {
- switch (encoding) {
- case UserData.ENCODING_OCTET:
- case UserData.ENCODING_LATIN:
- spn = new String(spnData, 0, numBytes, "ISO-8859-1");
- break;
- case UserData.ENCODING_IA5:
- case UserData.ENCODING_GSM_7BIT_ALPHABET:
- case UserData.ENCODING_7BIT_ASCII:
- spn = GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes*8)/7);
- break;
- case UserData.ENCODING_UNICODE_16:
- spn = new String(spnData, 0, numBytes, "utf-16");
- break;
- default:
- log("SPN encoding not supported");
- }
- } catch(Exception e) {
- log("spn decode error: " + e);
- }
- if (DBG) log("spn=" + spn);
- if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition);
- phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, spn);
- }
-
- private void onGetCSimMdnDone(AsyncResult ar) {
- byte[] data = (byte[]) ar.result;
- if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data));
- int mdnDigitsNum = 0x0F & data[0];
- mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum);
- if (DBG) log("CSIM MDN=" + mMdn);
- }
-
- private void onGetCSimImsimDone(AsyncResult ar) {
- byte[] data = (byte[]) ar.result;
- if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data));
- // C.S0065 section 5.2.2 for IMSI_M encoding
- // C.S0005 section 2.3.1 for MIN encoding in IMSI_M.
- boolean provisioned = ((data[7] & 0x80) == 0x80);
-
- if (provisioned) {
- int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]);
- int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6;
- int digit7 = 0x0F & (data[4] >> 2);
- if (digit7 > 0x09) digit7 = 0;
- int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]);
- first3digits = adjstMinDigits(first3digits);
- second3digits = adjstMinDigits(second3digits);
- last3digits = adjstMinDigits(last3digits);
-
- StringBuilder builder = new StringBuilder();
- builder.append(String.format(Locale.US, "%03d", first3digits));
- builder.append(String.format(Locale.US, "%03d", second3digits));
- builder.append(String.format(Locale.US, "%d", digit7));
- builder.append(String.format(Locale.US, "%03d", last3digits));
- if (DBG) log("min present=" + builder.toString());
-
- mMin = builder.toString();
- } else {
- if (DBG) log("min not present");
- }
+ // load ISIM records
+ recordsToLoad += mIsimUiccRecords.fetchIsimRecords(iccFh, this);
}
private int adjstMinDigits (int digits) {
@@ -324,32 +313,6 @@ public final class CdmaLteUiccRecords extends SIMRecords {
return digits;
}
- private void onGetCSimCdmaHomeDone(AsyncResult ar) {
- // Per C.S0065 section 5.2.8
- ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result;
- if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size());
- if (dataList.isEmpty()) {
- return;
- }
- StringBuilder sidBuf = new StringBuilder();
- StringBuilder nidBuf = new StringBuilder();
-
- for (byte[] data : dataList) {
- if (data.length == 5) {
- int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
- int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
- sidBuf.append(sid).append(",");
- nidBuf.append(nid).append(",");
- }
- }
- // remove trailing ","
- sidBuf.setLength(sidBuf.length()-1);
- nidBuf.setLength(nidBuf.length()-1);
-
- mHomeSystemId = sidBuf.toString();
- mHomeNetworkId = nidBuf.toString();
- }
-
private void onGetCSimEprlDone(AsyncResult ar) {
// C.S0065 section 5.2.57 for EFeprl encoding
// C.S0016 section 3.5.5 for PRL format.
@@ -418,6 +381,11 @@ public final class CdmaLteUiccRecords extends SIMRecords {
if (DBG) Log.d(LOG_TAG, "[CSIM] " + s);
}
+ @Override
+ protected void loge(String s) {
+ if (DBG) Log.e(LOG_TAG, "[CSIM] " + s);
+ }
+
public String getMdn() {
return mMdn;
}
@@ -443,6 +411,11 @@ public final class CdmaLteUiccRecords extends SIMRecords {
}
@Override
+ public IsimRecords getIsimRecords() {
+ return mIsimUiccRecords;
+ }
+
+ @Override
public boolean isProvisioned() {
// If UICC card has CSIM app, look for MDN and MIN field
// to determine if the SIM is provisioned. Otherwise,
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index 9af2d26..9850b9f 100755
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -443,4 +443,8 @@ public final class RuimRecords extends IccRecords {
Log.d(LOG_TAG, "[RuimRecords] " + s);
}
+ @Override
+ protected void loge(String s) {
+ Log.e(LOG_TAG, "[RuimRecords] " + s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index b0bad56..28034cc 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -147,8 +147,6 @@ public class SIMRecords extends IccRecords {
private static final int EVENT_GET_CFIS_DONE = 32;
private static final int EVENT_GET_CSP_CPHS_DONE = 33;
- protected static final int CSIM_EVENT_BASE = 100;
-
// Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
@@ -1089,6 +1087,9 @@ public class SIMRecords extends IccRecords {
handleEfCspData(data);
break;
+ default:
+ super.handleMessage(msg); // IccRecords handles generic record load responses
+
}}catch (RuntimeException exc) {
// I don't want these exceptions to be fatal
Log.w(LOG_TAG, "Exception parsing SIM record", exc);
@@ -1573,6 +1574,10 @@ public class SIMRecords extends IccRecords {
Log.d(LOG_TAG, "[SIMRecords] " + s);
}
+ protected void loge(String s) {
+ Log.e(LOG_TAG, "[SIMRecords] " + s);
+ }
+
/**
* Return true if "Restriction of menu options for manual PLMN selection"
* bit is set or EF_CSP data is unavailable, return false otherwise.
diff --git a/telephony/java/com/android/internal/telephony/ims/IsimRecords.java b/telephony/java/com/android/internal/telephony/ims/IsimRecords.java
new file mode 100644
index 0000000..b8b98b9
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ims/IsimRecords.java
@@ -0,0 +1,44 @@
+/*
+ * 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.ims;
+
+/**
+ * {@hide}
+ */
+public interface IsimRecords {
+
+ /**
+ * Return the IMS private user identity (IMPI).
+ * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM.
+ * @return the IMS private user identity string, or null if not available
+ */
+ String getIsimImpi();
+
+ /**
+ * Return the IMS home network domain name.
+ * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM.
+ * @return the IMS home network domain name, or null if not available
+ */
+ String getIsimDomain();
+
+ /**
+ * Return an array of IMS public user identities (IMPU).
+ * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM.
+ * @return an array of IMS public user identity strings, or null if not available
+ */
+ String[] getIsimImpu();
+}
diff --git a/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java b/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java
new file mode 100644
index 0000000..ee1a42d
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java
@@ -0,0 +1,157 @@
+/*
+ * 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.ims;
+
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.internal.telephony.IccFileHandler;
+import com.android.internal.telephony.IccRecords;
+import com.android.internal.telephony.gsm.SimTlv;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+
+import static com.android.internal.telephony.IccConstants.EF_DOMAIN;
+import static com.android.internal.telephony.IccConstants.EF_IMPI;
+import static com.android.internal.telephony.IccConstants.EF_IMPU;
+
+/**
+ * {@hide}
+ */
+public final class IsimUiccRecords implements IsimRecords {
+ protected static final String LOG_TAG = "GSM";
+
+ private static final boolean DBG = true;
+ private static final boolean DUMP_RECORDS = false; // Note: PII is logged when this is true
+
+ // ISIM EF records (see 3GPP TS 31.103)
+ private String mIsimImpi; // IMS private user identity
+ private String mIsimDomain; // IMS home network domain name
+ private String[] mIsimImpu; // IMS public user identity(s)
+
+ private static final int TAG_ISIM_VALUE = 0x80; // From 3GPP TS 31.103
+
+ private class EfIsimImpiLoaded implements IccRecords.IccRecordLoaded {
+ public String getEfName() {
+ return "EF_ISIM_IMPI";
+ }
+ public void onRecordLoaded(AsyncResult ar) {
+ byte[] data = (byte[]) ar.result;
+ mIsimImpi = isimTlvToString(data);
+ if (DUMP_RECORDS) log("EF_IMPI=" + mIsimImpi);
+ }
+ }
+
+ private class EfIsimImpuLoaded implements IccRecords.IccRecordLoaded {
+ public String getEfName() {
+ return "EF_ISIM_IMPU";
+ }
+ public void onRecordLoaded(AsyncResult ar) {
+ ArrayList<byte[]> impuList = (ArrayList<byte[]>) ar.result;
+ if (DBG) log("EF_IMPU record count: " + impuList.size());
+ mIsimImpu = new String[impuList.size()];
+ int i = 0;
+ for (byte[] identity : impuList) {
+ String impu = isimTlvToString(identity);
+ if (DUMP_RECORDS) log("EF_IMPU[" + i + "]=" + impu);
+ mIsimImpu[i++] = impu;
+ }
+ }
+ }
+
+ private class EfIsimDomainLoaded implements IccRecords.IccRecordLoaded {
+ public String getEfName() {
+ return "EF_ISIM_DOMAIN";
+ }
+ public void onRecordLoaded(AsyncResult ar) {
+ byte[] data = (byte[]) ar.result;
+ mIsimDomain = isimTlvToString(data);
+ if (DUMP_RECORDS) log("EF_DOMAIN=" + mIsimDomain);
+ }
+ }
+
+ /**
+ * Request the ISIM records to load.
+ * @param iccFh the IccFileHandler to load the records from
+ * @param h the Handler to which the response message will be sent
+ * @return the number of EF record requests that were added
+ */
+ public int fetchIsimRecords(IccFileHandler iccFh, Handler h) {
+ iccFh.loadEFTransparent(EF_IMPI, h.obtainMessage(
+ IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpiLoaded()));
+ iccFh.loadEFLinearFixedAll(EF_IMPU, h.obtainMessage(
+ IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpuLoaded()));
+ iccFh.loadEFTransparent(EF_DOMAIN, h.obtainMessage(
+ IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimDomainLoaded()));
+ return 3; // number of EF record load requests
+ }
+
+ /**
+ * ISIM records for IMS are stored inside a Tag-Length-Value record as a UTF-8 string
+ * with tag value 0x80.
+ * @param record the byte array containing the IMS data string
+ * @return the decoded String value, or null if the record can't be decoded
+ */
+ private static String isimTlvToString(byte[] record) {
+ SimTlv tlv = new SimTlv(record, 0, record.length);
+ do {
+ if (tlv.getTag() == TAG_ISIM_VALUE) {
+ return new String(tlv.getData(), Charset.forName("UTF-8"));
+ }
+ } while (tlv.nextObject());
+
+ Log.e(LOG_TAG, "[ISIM] can't find TLV tag in ISIM record, returning null");
+ return null;
+ }
+
+ void log(String s) {
+ if (DBG) Log.d(LOG_TAG, "[ISIM] " + s);
+ }
+
+ void loge(String s) {
+ if (DBG) Log.e(LOG_TAG, "[ISIM] " + s);
+ }
+
+ /**
+ * Return the IMS private user identity (IMPI).
+ * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM.
+ * @return the IMS private user identity string, or null if not available
+ */
+ public String getIsimImpi() {
+ return mIsimImpi;
+ }
+
+ /**
+ * Return the IMS home network domain name.
+ * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM.
+ * @return the IMS home network domain name, or null if not available
+ */
+ public String getIsimDomain() {
+ return mIsimDomain;
+ }
+
+ /**
+ * Return an array of IMS public user identities (IMPU).
+ * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM.
+ * @return an array of IMS public user identity strings, or null if not available
+ */
+ public String[] getIsimImpu() {
+ return (mIsimImpu != null) ? mIsimImpu.clone() : null;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
index 5208ccd..85ce6e0 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
@@ -186,7 +186,7 @@ class SipCommandInterface extends BaseCommands implements CommandsInterface {
public void setupDataCall(String radioTechnology, String profile,
String apn, String user, String password, String authType,
- String protcol, Message result) {
+ String protocol, Message result) {
}
public void deactivateDataCall(int cid, int reason, Message result) {
@@ -403,4 +403,7 @@ class SipCommandInterface extends BaseCommands implements CommandsInterface {
public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
Message response) {
}
+
+ public void requestIsimAuthentication(String nonce, Message response) {
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index 80de9f3..a2a344f 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -1501,4 +1501,8 @@ public final class SimulatedCommands extends BaseCommands
Message response) {
unimplemented(response);
}
+
+ public void requestIsimAuthentication(String nonce, Message response) {
+ unimplemented(response);
+ }
}