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

Commit 42d62ba5 authored by Muralidhar Reddy's avatar Muralidhar Reddy
Browse files

[MEP] Add enabledOnEsimPort 9F20 tag only if the euicc supports Multiple Enabled Profiles

If 9F20 tag is added without judging the MEP capaility from ATR, APDU response from P21 devices is not proper(i.e. for GetProfileInfo/BF2D command).
Inorder to support GetProfileInfo/BF2D command for both P21 and P22 devices, add 9F20 tag only after judging the esim OS MEP capability.

Bug: 210772152
Test: manual, atest FrameworksTelephonyTests
Change-Id: I4a1734275b42e8084df84be14c74033447dc9dae
parent bf197ed4
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ public class AnswerToReset {
    private static final int B8_MASK = 0x80;
    private static final int B7_MASK = 0x40;
    private static final int B2_MASK = 0x02;
    private static final int B1_MASK = 0x01;

    public static final byte DIRECT_CONVENTION = (byte) 0x3B;
    public static final byte INVERSE_CONVENTION = (byte) 0x3F;
@@ -55,6 +56,7 @@ public class AnswerToReset {
    private boolean mIsDirectConvention;
    private boolean mOnlyTEqualsZero = true;
    private boolean mIsEuiccSupported;
    private boolean mIsMultipleEnabledProfilesSupported = false;
    private byte mFormatByte;
    private ArrayList<InterfaceByte> mInterfaceBytes = new ArrayList<>();
    private HistoricalBytes mHistoricalBytes;
@@ -147,15 +149,21 @@ public class AnswerToReset {
        return b == null ? null : IccUtils.byteToHex(b);
    }

    private void checkIsEuiccSupported() {
    private void checkEuiccSupportedCapabilities() {
        // eUICC is supported only if the b8 and b2 of the first tB after T=15 are set to 1.
        // MEP is supported only if the b8 and b1 of the first tB after T=15 are set to 1.
        for (int i = 0; i < mInterfaceBytes.size() - 1; i++) {
            if (mInterfaceBytes.get(i).getTD() != null
                    && (mInterfaceBytes.get(i).getTD() & T_MASK) == T_VALUE_FOR_GLOBAL_INTERFACE
                    && mInterfaceBytes.get(i + 1).getTB() != null
                    && (mInterfaceBytes.get(i + 1).getTB() & B8_MASK) != 0
                    && mInterfaceBytes.get(i + 1).getTB() != null) {
                if ((mInterfaceBytes.get(i + 1).getTB() & B8_MASK) != 0
                        && (mInterfaceBytes.get(i + 1).getTB() & B2_MASK) != 0) {
                    mIsEuiccSupported = true;
                }
                if ((mInterfaceBytes.get(i + 1).getTB() & B8_MASK) != 0
                        && (mInterfaceBytes.get(i + 1).getTB() & B1_MASK) != 0) {
                    mIsMultipleEnabledProfilesSupported = true;
                }
                return;
            }
        }
@@ -330,7 +338,7 @@ public class AnswerToReset {
            return false;
        }
        log("Successfully parsed the ATR string " + atr + " into " + toString());
        checkIsEuiccSupported();
        checkEuiccSupportedCapabilities();
        return true;
    }

@@ -477,6 +485,10 @@ public class AnswerToReset {
        }
    }

    public boolean isMultipleEnabledProfilesSupported() {
        return mIsMultipleEnabledProfilesSupported;
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
+6 −2
Original line number Diff line number Diff line
@@ -49,14 +49,17 @@ public class UiccCard {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    private CardState mCardState;
    protected String mCardId;
    private boolean mIsSupportsMultipleEnabledProfiles;

    protected HashMap<Integer, UiccPort> mUiccPorts = new HashMap<>();
    private HashMap<Integer, Integer> mPhoneIdToPortIdx = new HashMap<>();

    public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock) {
    public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
            boolean isSupportsMultipleEnabledProfiles) {
        if (DBG) log("Creating");
        mCardState = ics.mCardState;
        mLock = lock;
        mIsSupportsMultipleEnabledProfiles = isSupportsMultipleEnabledProfiles;
        update(c, ci, ics, phoneId);
    }

@@ -105,7 +108,8 @@ public class UiccCard {
                UiccPort port = mUiccPorts.get(portIdx);
                if (port == null) {
                    if (this instanceof EuiccCard) {
                        port = new EuiccPort(c, ci, ics, phoneId, mLock, this); // eSim
                        port = new EuiccPort(c, ci, ics, phoneId, mLock, this,
                                mIsSupportsMultipleEnabledProfiles); // eSim
                    } else {
                        port = new UiccPort(c, ci, ics, phoneId, mLock, this); // pSim
                    }
+17 −7
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ public class UiccSlot extends Handler {
    private Context mContext;
    private UiccCard mUiccCard;
    private boolean mIsEuicc;
    private boolean mIsEuiccSupportsMultipleEnabledProfiles;
    private String mEid;
    private AnswerToReset mAtr;
    private boolean mIsRemovable;
@@ -128,14 +129,16 @@ public class UiccSlot extends Handler {
                }

                if (!mIsEuicc) {
                    mUiccCard = new UiccCard(mContext, ci, ics, phoneId, mLock);
                    // Uicc does not support MEP, passing false by default.
                    mUiccCard = new UiccCard(mContext, ci, ics, phoneId, mLock, false);
                } else {
                    // The EID should be reported with the card status, but in case it's not we want
                    // to catch that here
                    if (TextUtils.isEmpty(ics.eid)) {
                        loge("update: eid is missing. ics.eid=" + ics.eid);
                    }
                    mUiccCard = new EuiccCard(mContext, ci, ics, phoneId, mLock);
                    mUiccCard = new EuiccCard(mContext, ci, ics, phoneId, mLock,
                            mIsEuiccSupportsMultipleEnabledProfiles);
                }
            } else {
                if (mUiccCard != null) {
@@ -341,17 +344,22 @@ public class UiccSlot extends Handler {
        return true;
    }

    private void checkIsEuiccSupported() {
        if (mAtr != null && mAtr.isEuiccSupported()) {
            mIsEuicc = true;
        } else {
    private void checkEuiccSupportedCapabilities() {
        if (mAtr == null) {
            mIsEuicc = false;
            mIsEuiccSupportsMultipleEnabledProfiles = false;
            return;
        }
        mIsEuicc = mAtr.isEuiccSupported();
        mIsEuiccSupportsMultipleEnabledProfiles = mAtr.isMultipleEnabledProfilesSupported();
        log(" checkEuiccSupportedCapabilities : isEuicc-> " + mIsEuicc
                + " isMultipleEnabledProfilesSupported-> "
                + mIsEuiccSupportsMultipleEnabledProfiles);
    }

    private void parseAtr(String atr) {
        mAtr = AnswerToReset.parseAtr(atr);
        checkIsEuiccSupported();
        checkEuiccSupportedCapabilities();
    }

    public boolean isEuicc() {
@@ -537,6 +545,8 @@ public class UiccSlot extends Handler {
        pw.println("UiccSlot:");
        pw.println(" mActive=" + mActive);
        pw.println(" mIsEuicc=" + mIsEuicc);
        pw.println(" mIsEuiccSupportsMultipleEnabledProfiles="
                + mIsEuiccSupportsMultipleEnabledProfiles);
        pw.println(" mIsRemovable=" + mIsRemovable);
        pw.println(" mLastRadioState=" + mLastRadioState);
        pw.println(" mIccIds=" + mIccIds.values());
+3 −2
Original line number Diff line number Diff line
@@ -41,8 +41,9 @@ public class EuiccCard extends UiccCard {
    private volatile String mEid;
    private RegistrantList mEidReadyRegistrants;

    public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock) {
        super(c, ci, ics, phoneId, lock);
    public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
            boolean isSupportsMultipleEnabledProfiles) {
        super(c, ci, ics, phoneId, lock, isSupportsMultipleEnabledProfiles);
        if (TextUtils.isEmpty(ics.eid)) {
            loge("no eid given in constructor for phone " + phoneId);
            loadEidAndNotifyRegistrants();
+11 −3
Original line number Diff line number Diff line
@@ -123,9 +123,11 @@ public class EuiccPort extends UiccPort {
    private final ApduSender mApduSender;
    private EuiccSpecVersion mSpecVersion;
    private volatile String mEid;
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public boolean mIsSupportsMultipleEnabledProfiles;

    public EuiccPort(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
            UiccCard card) {
            UiccCard card, boolean isSupportsMultipleEnabledProfiles) {
        super(c, ci, ics, phoneId, lock, card);
        // TODO: Set supportExtendedApdu based on ATR.
        mApduSender = new ApduSender(ci, ISD_R_AID, false /* supportExtendedApdu */);
@@ -135,6 +137,7 @@ public class EuiccPort extends UiccPort {
            mEid = ics.eid;
            mCardId = ics.eid;
        }
        mIsSupportsMultipleEnabledProfiles = isSupportsMultipleEnabledProfiles;
    }

    /**
@@ -169,10 +172,12 @@ public class EuiccPort extends UiccPort {
     * @since 1.1.0 [GSMA SGP.22]
     */
    public void getAllProfiles(AsyncResultCallback<EuiccProfileInfo[]> callback, Handler handler) {
        byte[] profileTags = mIsSupportsMultipleEnabledProfiles ? Tags.EUICC_PROFILE_MEP_TAGS
                : Tags.EUICC_PROFILE_TAGS;
        sendApdu(
                newRequestProvider((RequestBuilder requestBuilder) ->
                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_PROFILES)
                                .addChildAsBytes(Tags.TAG_TAG_LIST, Tags.EUICC_PROFILE_TAGS)
                                .addChildAsBytes(Tags.TAG_TAG_LIST, profileTags)
                                .build().toHex())),
                response -> {
                    List<Asn1Node> profileNodes = new Asn1Decoder(response).nextNode()
@@ -209,6 +214,8 @@ public class EuiccPort extends UiccPort {
     */
    public final void getProfile(String iccid, AsyncResultCallback<EuiccProfileInfo> callback,
            Handler handler) {
        byte[] profileTags = mIsSupportsMultipleEnabledProfiles ? Tags.EUICC_PROFILE_MEP_TAGS
                : Tags.EUICC_PROFILE_TAGS;
        sendApdu(
                newRequestProvider((RequestBuilder requestBuilder) ->
                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_PROFILES)
@@ -216,7 +223,7 @@ public class EuiccPort extends UiccPort {
                                        .addChildAsBytes(Tags.TAG_ICCID,
                                                IccUtils.bcdToBytes(padTrailingFs(iccid)))
                                        .build())
                                .addChildAsBytes(Tags.TAG_TAG_LIST, Tags.EUICC_PROFILE_TAGS)
                                .addChildAsBytes(Tags.TAG_TAG_LIST, profileTags)
                                .build().toHex())),
                response -> {
                    List<Asn1Node> profileNodes = new Asn1Decoder(response).nextNode()
@@ -1398,5 +1405,6 @@ public class EuiccPort extends UiccPort {
        super.dump(fd, pw, args);
        pw.println("EuiccPort:");
        pw.println(" mEid=" + mEid);
        pw.println(" mIsSupportsMultipleEnabledProfiles=" + mIsSupportsMultipleEnabledProfiles);
    }
}
Loading