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 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public String getNumber() { 14222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mNumber; 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public String[] getEmails() { 14622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mEmails; 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void setEmails(String[] emails) { 15022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville this.mEmails = emails; 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 153cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public String toString() { 15522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return "ADN Record '" + mAlphaTag + "' '" + mNumber + " " + mEmails + "'"; 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isEmpty() { 15922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return TextUtils.isEmpty(mAlphaTag) && TextUtils.isEmpty(mNumber) && mEmails == null; 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean hasExtendedRecord() { 16322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return mExtRecord != 0 && mExtRecord != 0xff; 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Helper function for {@link #isEqual}. */ 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static boolean stringCompareNullEqualsEmpty(String s1, String s2) { 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (s1 == s2) { 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (s1 == null) { 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville s1 = ""; 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (s2 == null) { 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville s2 = ""; 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (s1.equals(s2)); 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isEqual(AdnRecord adn) { 18122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return ( stringCompareNullEqualsEmpty(mAlphaTag, adn.mAlphaTag) && 18222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville stringCompareNullEqualsEmpty(mNumber, adn.mNumber) && 18322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville Arrays.equals(mEmails, adn.mEmails)); 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Parcelable Implementation 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 187cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int describeContents() { 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 192cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void writeToParcel(Parcel dest, int flags) { 19422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville dest.writeInt(mEfid); 19522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville dest.writeInt(mRecordNumber); 19622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville dest.writeString(mAlphaTag); 19722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville dest.writeString(mNumber); 19822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville dest.writeStringArray(mEmails); 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Build adn hex byte array based on record size 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The format of byte array is defined in 51.011 10.5.1 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param recordSize is the size X of EF record 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return hex byte[recordSize] to be written to EF record 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * return null for wrong format of dialing number or tag 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public byte[] buildAdnString(int recordSize) { 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] bcdNumber; 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] byteTag; 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] adnString; 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int footerOffset = recordSize - FOOTER_SIZE_BYTES; 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // create an empty record 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville adnString = new byte[recordSize]; 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < recordSize; i++) { 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville adnString[i] = (byte) 0xFF; 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 22122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (TextUtils.isEmpty(mNumber)) { 222ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "[buildAdnString] Empty dialing number"); 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return adnString; // return the empty record (for delete) 22422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mNumber.length() 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) { 226ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "[buildAdnString] Max length of dialing number is 20"); 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 22922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if (mAlphaTag != null && mAlphaTag.length() > footerOffset) { 230ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "[buildAdnString] Max length of tag is " + footerOffset); 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 23422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(mNumber); 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(bcdNumber, 0, adnString, 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville footerOffset + ADN_TON_AND_NPI, bcdNumber.length); 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville adnString[footerOffset + ADN_BCD_NUMBER_LENGTH] 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville = (byte) (bcdNumber.length); 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville adnString[footerOffset + ADN_CAPABILITY_ID] 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville = (byte) 0xFF; // Capability Id 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville adnString[footerOffset + ADN_EXTENSION_ID] 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville = (byte) 0xFF; // Extension Record Id 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 24622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (!TextUtils.isEmpty(mAlphaTag)) { 24722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville byteTag = GsmAlphabet.stringToGsm8BitPacked(mAlphaTag); 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(byteTag, 0, adnString, 0, byteTag.length); 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return adnString; 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See TS 51.011 10.5.10 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville appendExtRecord (byte[] extRecord) { 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (extRecord.length != EXT_RECORD_LENGTH_BYTES) { 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((extRecord[0] & EXT_RECORD_TYPE_MASK) 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville != EXT_RECORD_TYPE_ADDITIONAL_DATA) { 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((0xff & extRecord[1]) > MAX_EXT_CALLED_PARTY_LENGTH) { 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // invalid or empty record 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 27522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mNumber += PhoneNumberUtils.calledPartyBCDFragmentToString( 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville extRecord, 2, 0xff & extRecord[1]); 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // We don't support ext record chaining. 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (RuntimeException ex) { 281ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "Error parsing AdnRecord ext record", ex); 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //***** Private Methods 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * alphaTag and number are set to null on invalid format 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville parseRecord(byte[] record) { 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 29322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mAlphaTag = IccUtils.adnStringFieldToString( 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville record, 0, record.length - FOOTER_SIZE_BYTES); 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int footerOffset = record.length - FOOTER_SIZE_BYTES; 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numberLength = 0xff & record[footerOffset]; 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (numberLength > MAX_NUMBER_SIZE_BYTES) { 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Invalid number length 30222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mNumber = ""; 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Please note 51.011 10.5.1: 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // "If the Dialling Number/SSC String does not contain 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // a dialling number, e.g. a control string deactivating 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // a service, the TON/NPI byte shall be set to 'FF' by 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // the ME (see note 2)." 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 31322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mNumber = PhoneNumberUtils.calledPartyBCDToString( 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville record, footerOffset + 1, numberLength); 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 31722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mExtRecord = 0xff & record[record.length - 1]; 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 31922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mEmails = null; 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (RuntimeException ex) { 322ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "Error parsing AdnRecord", ex); 32322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mNumber = ""; 32422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mAlphaTag = ""; 32522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mEmails = null; 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 329