10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkapackage com.android.internal.telephony.uicc;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Parcel;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Parcelable;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils;
23ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
25d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.GsmAlphabet;
26d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Used to load or store ADNs (Abbreviated Dialing Numbers).
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class AdnRecord implements Parcelable {
38cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "AdnRecord";
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mAlphaTag = null;
4322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mNumber = null;
4422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String[] mEmails;
4522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mExtRecord = 0xff;
4622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mEfid;                   // or 0 if none
4722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mRecordNumber;           // or 0 if none
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constants
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // In an ADN record, everything but the alpha identifier
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // is in a footer that's 14 bytes
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int FOOTER_SIZE_BYTES = 14;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Maximum size of the un-extended number field
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_NUMBER_SIZE_BYTES = 11;
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EXT_RECORD_LENGTH_BYTES = 13;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EXT_RECORD_TYPE_ADDITIONAL_DATA = 2;
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EXT_RECORD_TYPE_MASK = 3;
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_EXT_CALLED_PARTY_LENGTH = 0xa;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // ADN offset
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int ADN_BCD_NUMBER_LENGTH = 0;
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int ADN_TON_AND_NPI = 1;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int ADN_DIALING_NUMBER_START = 2;
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int ADN_DIALING_NUMBER_END = 11;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int ADN_CAPABILITY_ID = 12;
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int ADN_EXTENSION_ID = 13;
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Static Methods
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static final Parcelable.Creator<AdnRecord> CREATOR
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            = new Parcelable.Creator<AdnRecord>() {
76cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public AdnRecord createFromParcel(Parcel source) {
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int efid;
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int recordNumber;
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String alphaTag;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String number;
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String[] emails;
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            efid = source.readInt();
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            recordNumber = source.readInt();
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            alphaTag = source.readString();
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            number = source.readString();
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            emails = source.readStringArray();
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return new AdnRecord(efid, recordNumber, alphaTag, number, emails);
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
93cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public AdnRecord[] newArray(int size) {
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return new AdnRecord[size];
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructor
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public AdnRecord (byte[] record) {
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this(0, 0, record);
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public AdnRecord (int efid, int recordNumber, byte[] record) {
10622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mEfid = efid;
10722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mRecordNumber = recordNumber;
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        parseRecord(record);
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public AdnRecord (String alphaTag, String number) {
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this(0, 0, alphaTag, number);
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public AdnRecord (String alphaTag, String number, String[] emails) {
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this(0, 0, alphaTag, number, emails);
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public AdnRecord (int efid, int recordNumber, String alphaTag, String number, String[] emails) {
12022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mEfid = efid;
12122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mRecordNumber = recordNumber;
12222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mAlphaTag = alphaTag;
12322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mNumber = number;
12422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mEmails = emails;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public AdnRecord(int efid, int recordNumber, String alphaTag, String number) {
12822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mEfid = efid;
12922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mRecordNumber = recordNumber;
13022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mAlphaTag = alphaTag;
13122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mNumber = number;
13222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mEmails = null;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Methods
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String getAlphaTag() {
13822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mAlphaTag;
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
141a62d723815dad650884714e801421b6d7cb34f91Jack Yu    public int getEfid() {
142a62d723815dad650884714e801421b6d7cb34f91Jack Yu        return mEfid;
143a62d723815dad650884714e801421b6d7cb34f91Jack Yu    }
144a62d723815dad650884714e801421b6d7cb34f91Jack Yu
145a62d723815dad650884714e801421b6d7cb34f91Jack Yu    public int getRecId() {
146a62d723815dad650884714e801421b6d7cb34f91Jack Yu        return mRecordNumber;
147a62d723815dad650884714e801421b6d7cb34f91Jack Yu    }
148a62d723815dad650884714e801421b6d7cb34f91Jack Yu
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String getNumber() {
15022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mNumber;
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
15341dbb357027b08952c7d839e798c1e161ce3a49dJack Yu    public void setNumber(String number) {
15441dbb357027b08952c7d839e798c1e161ce3a49dJack Yu        mNumber = number;
15541dbb357027b08952c7d839e798c1e161ce3a49dJack Yu    }
15641dbb357027b08952c7d839e798c1e161ce3a49dJack Yu
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String[] getEmails() {
15822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mEmails;
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void setEmails(String[] emails) {
16222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        this.mEmails = emails;
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
165cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String toString() {
16730c45c4b31efb140679e4d945199f5c4296d21cdfionaxu        return "ADN Record '" + mAlphaTag + "' '" + Rlog.pii(LOG_TAG, mNumber) + " "
16830c45c4b31efb140679e4d945199f5c4296d21cdfionaxu                + Rlog.pii(LOG_TAG, mEmails) + "'";
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isEmpty() {
17222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return TextUtils.isEmpty(mAlphaTag) && TextUtils.isEmpty(mNumber) && mEmails == null;
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean hasExtendedRecord() {
17622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mExtRecord != 0 && mExtRecord != 0xff;
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Helper function for {@link #isEqual}. */
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static boolean stringCompareNullEqualsEmpty(String s1, String s2) {
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (s1 == s2) {
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (s1 == null) {
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            s1 = "";
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (s2 == null) {
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            s2 = "";
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return (s1.equals(s2));
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isEqual(AdnRecord adn) {
19422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return ( stringCompareNullEqualsEmpty(mAlphaTag, adn.mAlphaTag) &&
19522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                stringCompareNullEqualsEmpty(mNumber, adn.mNumber) &&
19622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                Arrays.equals(mEmails, adn.mEmails));
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Parcelable Implementation
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
200cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public int describeContents() {
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return 0;
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
205cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void writeToParcel(Parcel dest, int flags) {
20722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        dest.writeInt(mEfid);
20822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        dest.writeInt(mRecordNumber);
20922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        dest.writeString(mAlphaTag);
21022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        dest.writeString(mNumber);
21122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        dest.writeStringArray(mEmails);
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Build adn hex byte array based on record size
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The format of byte array is defined in 51.011 10.5.1
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param recordSize is the size X of EF record
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return hex byte[recordSize] to be written to EF record
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *          return null for wrong format of dialing number or tag
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public byte[] buildAdnString(int recordSize) {
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] bcdNumber;
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] byteTag;
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] adnString;
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int footerOffset = recordSize - FOOTER_SIZE_BYTES;
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // create an empty record
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        adnString = new byte[recordSize];
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < recordSize; i++) {
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            adnString[i] = (byte) 0xFF;
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (TextUtils.isEmpty(mNumber)) {
235ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.w(LOG_TAG, "[buildAdnString] Empty dialing number");
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return adnString;   // return the empty record (for delete)
23722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        } else if (mNumber.length()
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) {
239ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.w(LOG_TAG,
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    "[buildAdnString] Max length of dialing number is 20");
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
24283d54a44ffbd19bb35599fb6483233e1e3751852Yuta Ui        }
24383d54a44ffbd19bb35599fb6483233e1e3751852Yuta Ui
24483d54a44ffbd19bb35599fb6483233e1e3751852Yuta Ui        byteTag = !TextUtils.isEmpty(mAlphaTag) ? GsmAlphabet.stringToGsm8BitPacked(mAlphaTag)
24583d54a44ffbd19bb35599fb6483233e1e3751852Yuta Ui                : new byte[0];
24683d54a44ffbd19bb35599fb6483233e1e3751852Yuta Ui
24783d54a44ffbd19bb35599fb6483233e1e3751852Yuta Ui        if (byteTag.length > footerOffset) {
24883d54a44ffbd19bb35599fb6483233e1e3751852Yuta Ui            Rlog.w(LOG_TAG, "[buildAdnString] Max length of tag is " + footerOffset);
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
25122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(mNumber);
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            System.arraycopy(bcdNumber, 0, adnString,
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    footerOffset + ADN_TON_AND_NPI, bcdNumber.length);
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            adnString[footerOffset + ADN_BCD_NUMBER_LENGTH]
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    = (byte) (bcdNumber.length);
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            adnString[footerOffset + ADN_CAPABILITY_ID]
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    = (byte) 0xFF; // Capability Id
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            adnString[footerOffset + ADN_EXTENSION_ID]
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    = (byte) 0xFF; // Extension Record Id
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
26383d54a44ffbd19bb35599fb6483233e1e3751852Yuta Ui            if (byteTag.length > 0) {
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                System.arraycopy(byteTag, 0, adnString, 0, byteTag.length);
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return adnString;
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * See TS 51.011 10.5.10
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    appendExtRecord (byte[] extRecord) {
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (extRecord.length != EXT_RECORD_LENGTH_BYTES) {
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if ((extRecord[0] & EXT_RECORD_TYPE_MASK)
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    != EXT_RECORD_TYPE_ADDITIONAL_DATA) {
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if ((0xff & extRecord[1]) > MAX_EXT_CALLED_PARTY_LENGTH) {
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // invalid or empty record
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
29122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mNumber += PhoneNumberUtils.calledPartyBCDFragmentToString(
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                        extRecord, 2, 0xff & extRecord[1]);
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // We don't support ext record chaining.
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
297ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.w(LOG_TAG, "Error parsing AdnRecord ext record", ex);
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Private Methods
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * alphaTag and number are set to null on invalid format
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    parseRecord(byte[] record) {
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
30922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAlphaTag = IccUtils.adnStringFieldToString(
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            record, 0, record.length - FOOTER_SIZE_BYTES);
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int footerOffset = record.length - FOOTER_SIZE_BYTES;
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int numberLength = 0xff & record[footerOffset];
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (numberLength > MAX_NUMBER_SIZE_BYTES) {
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Invalid number length
31822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mNumber = "";
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Please note 51.011 10.5.1:
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            //
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // "If the Dialling Number/SSC String does not contain
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // a dialling number, e.g. a control string deactivating
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // a service, the TON/NPI byte shall be set to 'FF' by
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // the ME (see note 2)."
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
32922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mNumber = PhoneNumberUtils.calledPartyBCDToString(
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            record, footerOffset + 1, numberLength);
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
33322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mExtRecord = 0xff & record[record.length - 1];
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
33522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mEmails = null;
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException ex) {
338ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            Rlog.w(LOG_TAG, "Error parsing AdnRecord", ex);
33922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mNumber = "";
34022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mAlphaTag = "";
34122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mEmails = null;
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
345