Merge "Add ISIM application support for LTE devices."
This commit is contained in:
@@ -582,6 +582,12 @@
|
||||
android:label="@string/permlab_readPhoneState"
|
||||
android:description="@string/permdesc_readPhoneState" />
|
||||
|
||||
<!-- Allows read access to privileged phone state.
|
||||
@hide Used internally. -->
|
||||
<permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
|
||||
android:permissionGroup="android.permission-group.PHONE_CALLS"
|
||||
android:protectionLevel="signatureOrSystem" />
|
||||
|
||||
<!-- ================================== -->
|
||||
<!-- Permissions for sdcard interaction -->
|
||||
<!-- ================================== -->
|
||||
|
||||
@@ -832,6 +832,55 @@ public class TelephonyManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
|
||||
* @return the IMPI, or null if not present or not loaded
|
||||
* @hide
|
||||
*/
|
||||
public String getIsimImpi() {
|
||||
try {
|
||||
return getSubscriberInfo().getIsimImpi();
|
||||
} catch (RemoteException ex) {
|
||||
return null;
|
||||
} catch (NullPointerException ex) {
|
||||
// This could happen before phone restarts due to crashing
|
||||
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
|
||||
* @hide
|
||||
*/
|
||||
public String getIsimDomain() {
|
||||
try {
|
||||
return getSubscriberInfo().getIsimDomain();
|
||||
} catch (RemoteException ex) {
|
||||
return null;
|
||||
} catch (NullPointerException ex) {
|
||||
// This could happen before phone restarts due to crashing
|
||||
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
|
||||
* @hide
|
||||
*/
|
||||
public String[] getIsimImpu() {
|
||||
try {
|
||||
return getSubscriberInfo().getIsimImpu();
|
||||
} catch (RemoteException ex) {
|
||||
return null;
|
||||
} catch (NullPointerException ex) {
|
||||
// This could happen before phone restarts due to crashing
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IPhoneSubInfo getSubscriberInfo() {
|
||||
// get it each time because that process crashes a lot
|
||||
return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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}
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.Context;
|
||||
import android.net.Uri;
|
||||
import android.content.Context;
|
||||
import android.provider.Telephony;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.SQLException;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.net.Uri;
|
||||
import android.os.Message;
|
||||
import android.provider.Telephony;
|
||||
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;
|
||||
@@ -145,6 +135,16 @@ public class CDMALTEPhone extends CDMAPhone {
|
||||
return mImeiSv;
|
||||
}
|
||||
|
||||
@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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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[];
|
||||
// Refer to ETSI TS 102.221
|
||||
private class EfPlLoaded implements IccRecordLoaded {
|
||||
public String getEfName() {
|
||||
return "EF_PL";
|
||||
}
|
||||
|
||||
boolean isCsimRecordLoadResponse = false;
|
||||
public void onRecordLoaded(AsyncResult ar) {
|
||||
mEFpl = (byte[]) ar.result;
|
||||
if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
// Refer to C.S0065 5.2.26
|
||||
private class EfCsimLiLoaded implements IccRecordLoaded {
|
||||
public String getEfName() {
|
||||
return "EF_CSIM_LI";
|
||||
}
|
||||
|
||||
ar = (AsyncResult) msg.obj;
|
||||
|
||||
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;
|
||||
|
||||
case EVENT_GET_CSIM_LI_DONE:
|
||||
// Refer to C.S0065 5.2.26
|
||||
if (DBG) log("EVENT_GET_CSIM_LI_DONE");
|
||||
isCsimRecordLoadResponse = true;
|
||||
|
||||
ar = (AsyncResult) msg.obj;
|
||||
if (ar.exception != null) {
|
||||
Log.e(LOG_TAG, "ar.exception = " + ar.exception);
|
||||
break;
|
||||
}
|
||||
|
||||
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] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
onGetCSimEprlDone(ar);
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
}}catch (RuntimeException exc) {
|
||||
Log.w(LOG_TAG, "Exception parsing SIM record", exc);
|
||||
} finally {
|
||||
if (isCsimRecordLoadResponse) {
|
||||
onRecordLoaded();
|
||||
}
|
||||
|
||||
if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli));
|
||||
}
|
||||
}
|
||||
|
||||
// Refer to C.S0065 5.2.32
|
||||
private class EfCsimSpnLoaded implements IccRecordLoaded {
|
||||
public String getEfName() {
|
||||
return "EF_CSIM_SPN";
|
||||
}
|
||||
|
||||
public void onRecordLoaded(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);
|
||||
|
||||
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 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(',');
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
@@ -442,6 +410,11 @@ public final class CdmaLteUiccRecords extends SIMRecords {
|
||||
return mCsimSpnDisplayCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsimRecords getIsimRecords() {
|
||||
return mIsimUiccRecords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProvisioned() {
|
||||
// If UICC card has CSIM app, look for MDN and MIN field
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1501,4 +1501,8 @@ public final class SimulatedCommands extends BaseCommands
|
||||
Message response) {
|
||||
unimplemented(response);
|
||||
}
|
||||
|
||||
public void requestIsimAuthentication(String nonce, Message response) {
|
||||
unimplemented(response);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user