/*
* 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;
}
}