Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58ee74d4 authored by Nathan Harold's avatar Nathan Harold Committed by android-build-merger
Browse files

Add PLMN Selection Info to SIM Records

am: 14545cbe

Change-Id: I1071e41f919a173585f20e9c1d407383b2adcc6e
parents ecca8c95 14545cbe
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -82,6 +82,21 @@ public interface IccConstants {
    static final int EF_PCSCF = 0x6F09;
    static final int EF_PSI = 0x6FE5;

    //PLMN Selection Information w/ Access Technology TS 131.102
    static final int EF_PLMN_W_ACT = 0x6F60;
    static final int EF_OPLMN_W_ACT = 0x6F61;
    static final int EF_HPLMN_W_ACT = 0x6F62;

    //Equivalent Home and Forbidden PLMN Lists TS 131.102
    static final int EF_EHPLMN = 0x6FD9;
    static final int EF_FPLMN = 0x6F7B;

    // Last Roaming Selection Indicator
    static final int EF_LRPLMNSI = 0x6FDC;

    //Search interval for higher priority PLMNs
    static final int EF_HPPLMN = 0x6F31;

    // SMS record length from TS 51.011 10.5.3
    static public final int SMS_RECORD_LENGTH = 176;
    // SMS record length from C.S0023 3.4.27
+7 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.telephony.uicc;

import android.os.*;

import com.android.internal.telephony.CommandsInterface;

import java.util.ArrayList;
@@ -25,6 +26,7 @@ import java.util.ArrayList;
 * {@hide}
 */
public abstract class IccFileHandler extends Handler implements IccConstants {
    private static final boolean VDBG = false;

    //from TS 11.11 9.1 or elsewhere
    static protected final int COMMAND_READ_BINARY = 0xb0;
@@ -516,6 +518,11 @@ public abstract class IccFileHandler extends Handler implements IccConstants {

                fileid = msg.arg1;

                if (VDBG) {
                    logd(String.format("Contents of the Select Response for command %x: ", fileid)
                            + IccUtils.bytesToHexString(data));
                }

                if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
                    throw new IccFileTypeMismatch();
                }
@@ -628,7 +635,6 @@ public abstract class IccFileHandler extends Handler implements IccConstants {

    protected abstract String getEFPath(int efid);
    protected abstract void logd(String s);

    protected abstract void loge(String s);

}
+7 −0
Original line number Diff line number Diff line
@@ -88,6 +88,13 @@ public abstract class IccRecords extends Handler implements IccConstants {
    protected String mGid2;
    protected String mPrefLang;

    protected PlmnActRecord[] mHplmnActRecords;
    protected PlmnActRecord[] mOplmnActRecords;
    protected PlmnActRecord[] mPlmnActRecords;

    protected String[] mEhplmns;
    protected String[] mFplmns;

    private final Object mLock = new Object();

    // ***** Constants
+23 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.graphics.Color;
import android.telephony.Rlog;

import com.android.internal.telephony.GsmAlphabet;

import java.io.UnsupportedEncodingException;

/**
@@ -60,6 +61,28 @@ public class IccUtils {
        return ret.toString();
    }

    /**
     * PLMN (MCC/MNC) is encoded as per 24.008 10.5.1.3
     * Returns a concatenated string of MCC+MNC, stripping
     * a trailing character for a 2-digit MNC
     */
    public static String bcdPlmnToString(byte[] data, int offset) {
        if (offset + 3 > data.length) {
            return null;
        }
        byte[] trans = new byte[3];
        trans[0] = (byte) ((data[0 + offset] << 4) | ((data[0 + offset] >> 4) & 0xF));
        trans[1] = (byte) ((data[1 + offset] << 4) | (data[2 + offset] & 0xF));
        trans[2] = (byte) ((data[2 + offset] & 0xF0) | ((data[1 + offset] >> 4) & 0xF));
        String ret = bytesToHexString(trans);

        // For a 2-digit MNC we trim the trailing 'f'
        if (ret.endsWith("f")) {
            ret = ret.substring(0, ret.length() - 1);
        }
        return ret;
    }

    /**
     * Some fields (like ICC ID) in GSM SIMs are stored as nibble-swizzled BCH
     */
+144 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2006 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.uicc;

import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Rlog;

import java.util.Arrays;

/**
 * {@hide}
 */
public class PlmnActRecord implements Parcelable {
    private static final String LOG_TAG = "PlmnActRecord";

    // Values specified in 3GPP 31.102 sec. 4.2.5
    public static final int ACCESS_TECH_UTRAN = 0x8000;
    public static final int ACCESS_TECH_EUTRAN = 0x4000;
    public static final int ACCESS_TECH_GSM = 0x0080;
    public static final int ACCESS_TECH_GSM_COMPACT = 0x0040;
    public static final int ACCESS_TECH_CDMA2000_HRPD = 0x0020;
    public static final int ACCESS_TECH_CDMA2000_1XRTT = 0x0010;
    public static final int ACCESS_TECH_RESERVED = 0x3F0F;

    public static final int ENCODED_LENGTH = 5;

    public final String plmn;
    public final int accessTechs;

    private static final boolean VDBG = true;

    public static final Parcelable.Creator<PlmnActRecord> CREATOR =
            new Parcelable.Creator<PlmnActRecord>() {
        @Override
        public PlmnActRecord createFromParcel(Parcel source) {
            return new PlmnActRecord(source.readString(), source.readInt());
        }

        @Override
        public PlmnActRecord[] newArray(int size) {
            return new PlmnActRecord[size];
        }
    };

    /* From 3gpp 31.102 section 4.2.5
     * Bytes 0-2 bcd-encoded PLMN-ID
     * Bytes 3-4 bitfield of access technologies
     */
    public PlmnActRecord(byte[] bytes, int offset) {
        if (VDBG) Rlog.v(LOG_TAG, "Creating PlmnActRecord " + offset);
        this.plmn = IccUtils.bcdPlmnToString(bytes, offset);
        this.accessTechs = ((int) bytes[offset + 3] << 8) | bytes[offset + 4];
    }

    private PlmnActRecord(String plmn, int accessTechs) {
        this.plmn = plmn;
        this.accessTechs = accessTechs;
    }

    private String accessTechString() {
        if (accessTechs == 0) {
            return "NONE";
        }

        StringBuilder sb = new StringBuilder();
        if ((accessTechs & ACCESS_TECH_UTRAN) != 0) {
            sb.append("UTRAN|");
        }
        if ((accessTechs & ACCESS_TECH_EUTRAN) != 0) {
            sb.append("EUTRAN|");
        }
        if ((accessTechs & ACCESS_TECH_GSM) != 0) {
            sb.append("GSM|");
        }
        if ((accessTechs & ACCESS_TECH_GSM_COMPACT) != 0) {
            sb.append("GSM_COMPACT|");
        }
        if ((accessTechs & ACCESS_TECH_CDMA2000_HRPD) != 0) {
            sb.append("CDMA2000_HRPD|");
        }
        if ((accessTechs & ACCESS_TECH_CDMA2000_1XRTT) != 0) {
            sb.append("CDMA2000_1XRTT|");
        }
        if ((accessTechs & ACCESS_TECH_RESERVED) != 0) {
            sb.append(String.format("UNKNOWN:%x|", accessTechs & ACCESS_TECH_RESERVED));
        }
        // Trim the tailing pipe character
        return sb.substring(0, sb.length() - 1);
    }

    @Override
    public String toString() {
        return String.format("{PLMN=%s,AccessTechs=%s}", plmn, accessTechString());
    }

    /**
     * Convenience method for extracting all records from encoded bytes
     */
    public static PlmnActRecord[] getRecords(byte[] recordBytes) {
        if (recordBytes == null || recordBytes.length == 0
                || recordBytes.length % ENCODED_LENGTH != 0) {
            Rlog.e(LOG_TAG, "Malformed PlmnActRecord, bytes: "
                    + ((recordBytes != null) ? Arrays.toString(recordBytes) : null));
            return null;
        }
        int numRecords = recordBytes.length / ENCODED_LENGTH;
        if (VDBG) Rlog.v(LOG_TAG, "Extracting Logs, count=" + numRecords);

        PlmnActRecord[] records = new PlmnActRecord[numRecords];

        for(int i = 0; i < numRecords; i++) {
            records[i] = new PlmnActRecord(recordBytes, i * ENCODED_LENGTH);
        }
        return records;
    }

    // Parcelable Implementation
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(plmn);
        dest.writeInt(accessTechs);
    }

}
Loading