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 java.util.ArrayList;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Looper;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
25ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
277e9b726788dff57196b4b6046987f22e1881e613Preeti Ahujaimport com.android.internal.telephony.uicc.IccConstants;
287e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class AdnRecordLoader extends Handler {
30cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    final static String LOG_TAG = "AdnRecordLoader";
31cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    final static boolean VDBG = false;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private IccFileHandler mFh;
3622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mEf;
3722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mExtensionEF;
3822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mPendingExtLoads;
3922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    Message mUserResponse;
4022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPin2;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // For "load one"
4322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mRecordNumber;
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // for "load all"
4622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    ArrayList<AdnRecord> mAdns; // only valid after EVENT_ADN_LOAD_ALL_DONE
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Either an AdnRecord or a reference to adns depending
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // if this is a load one or load all operation
5022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    Object mResult;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Event Constants
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_ADN_LOAD_DONE = 1;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_EXT_RECORD_LOAD_DONE = 2;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_ADN_LOAD_ALL_DONE = 3;
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_EF_LINEAR_RECORD_SIZE_DONE = 4;
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_UPDATE_RECORD_DONE = 5;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constructor
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
62d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka    AdnRecordLoader(IccFileHandler fh) {
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // The telephony unit-test cases may create AdnRecords
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // in secondary threads
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super(Looper.getMainLooper());
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mFh = fh;
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
697e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja    private String getEFPath(int efid) {
707e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja        if (efid == IccConstants.EF_ADN) {
717e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja            return IccConstants.MF_SIM + IccConstants.DF_TELECOM;
727e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja        }
737e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja
747e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja        return null;
757e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja    }
767e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Resulting AdnRecord is placed in response.obj.result
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or response.obj.exception is set
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    loadFromEF(int ef, int extensionEF, int recordNumber,
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Message response) {
8422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mEf = ef;
8522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mExtensionEF = extensionEF;
8622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordNumber = recordNumber;
8722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mUserResponse = response;
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
897e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja       mFh.loadEFLinearFixed(
907e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja               ef, getEFPath(ef), recordNumber,
917e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja               obtainMessage(EVENT_ADN_LOAD_DONE));
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Resulting ArrayList&lt;adnRecord> is placed in response.obj.result
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * or response.obj.exception is set
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    loadAllFromEF(int ef, int extensionEF,
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Message response) {
10222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mEf = ef;
10322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mExtensionEF = extensionEF;
10422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mUserResponse = response;
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1067e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja        /* If we are loading from EF_ADN, specifically
1077e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja         * specify the path as well, since, on some cards,
1087e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja         * the fileid is not unique.
1097e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja         */
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mFh.loadEFLinearFixedAll(
1117e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja                ef, getEFPath(ef),
1127e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja                obtainMessage(EVENT_ADN_LOAD_ALL_DONE));
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Write adn to a EF SIM record
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * It will get the record size of EF record and compose hex adn array
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * then write the hex array to EF record
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param adn is set with alphaTag and phone number
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param ef EF fileid
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param extensionEF extension EF fileid
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param recordNumber 1-based record index
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param pin2 for CHV2 operations, must be null if pin2 is not needed
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param response will be sent to its handler when completed
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    updateEF(AdnRecord adn, int ef, int extensionEF, int recordNumber,
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String pin2, Message response) {
13022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mEf = ef;
13122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mExtensionEF = extensionEF;
13222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mRecordNumber = recordNumber;
13322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mUserResponse = response;
13422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPin2 = pin2;
1357e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja
1367e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja        mFh.getEFLinearRecordSize( ef, getEFPath(ef),
1377e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja                obtainMessage(EVENT_EF_LINEAR_RECORD_SIZE_DONE, adn));
1387e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja     }
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Overridden from Handler
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
142cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage(Message msg) {
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte data[];
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AdnRecord adn;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (msg.what) {
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_EF_LINEAR_RECORD_SIZE_DONE:
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ar = (AsyncResult)(msg.obj);
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    adn = (AdnRecord)(ar.userObj);
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (ar.exception != null) {
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        throw new RuntimeException("get EF record size failed",
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                ar.exception);
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    int[] recordSize = (int[])ar.result;
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // recordSize is int[3] array
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // int[0]  is the record length
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // int[1]  is the total length of the EF file
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // int[2]  is the number of records in the EF file
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // So int[0] * int[2] = int[1]
16622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                   if (recordSize.length != 3 || mRecordNumber > recordSize[2]) {
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        throw new RuntimeException("get wrong EF record size format",
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                ar.exception);
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    data = adn.buildAdnString(recordSize[0]);
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if(data == null) {
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        throw new RuntimeException("wrong ADN format",
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                ar.exception);
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1787e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja
1797e9b726788dff57196b4b6046987f22e1881e613Preeti Ahuja                    mFh.updateEFLinearFixed(mEf, getEFPath(mEf), mRecordNumber,
18022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            data, mPin2, obtainMessage(EVENT_UPDATE_RECORD_DONE));
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingExtLoads = 1;
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_UPDATE_RECORD_DONE:
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ar = (AsyncResult)(msg.obj);
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (ar.exception != null) {
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        throw new RuntimeException("update EF adn record failed",
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                ar.exception);
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
19122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingExtLoads = 0;
19222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mResult = null;
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_ADN_LOAD_DONE:
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ar = (AsyncResult)(msg.obj);
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    data = (byte[])(ar.result);
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (ar.exception != null) {
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        throw new RuntimeException("load failed", ar.exception);
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
202cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville                    if (VDBG) {
203ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                        Rlog.d(LOG_TAG,"ADN EF: 0x"
20422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            + Integer.toHexString(mEf)
20522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            + ":" + mRecordNumber
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            + "\n" + IccUtils.bytesToHexString(data));
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    adn = new AdnRecord(mEf, mRecordNumber, data);
21022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mResult = adn;
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (adn.hasExtendedRecord()) {
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // If we have a valid value in the ext record field,
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // we're not done yet: we need to read the corresponding
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // ext record and append it
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
21722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mPendingExtLoads = 1;
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        mFh.loadEFLinearFixed(
22022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mExtensionEF, adn.mExtRecord,
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_EXT_RECORD_LOAD_DONE:
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ar = (AsyncResult)(msg.obj);
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    data = (byte[])(ar.result);
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    adn = (AdnRecord)(ar.userObj);
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23041dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                    if (ar.exception == null) {
23141dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                        Rlog.d(LOG_TAG,"ADN extension EF: 0x"
23241dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                                + Integer.toHexString(mExtensionEF)
23341dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                                + ":" + adn.mExtRecord
23441dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                                + "\n" + IccUtils.bytesToHexString(data));
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
23641dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                        adn.appendExtRecord(data);
23741dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                    }
23841dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                    else {
23941dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                        // If we can't get the rest of the number from EF_EXT1, rather than
24041dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                        // providing the partial number, we clear the number since it's not
24141dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                        // dialable anyway. Do not throw exception here otherwise the rest
24241dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                        // of the good records will be dropped.
24341dbb357027b08952c7d839e798c1e161ce3a49dJack Yu
24441dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                        Rlog.e(LOG_TAG, "Failed to read ext record. Clear the number now.");
24541dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                        adn.setNumber("");
24641dbb357027b08952c7d839e798c1e161ce3a49dJack Yu                    }
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
24822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingExtLoads--;
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // result should have been set in
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // EVENT_ADN_LOAD_DONE or EVENT_ADN_LOAD_ALL_DONE
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case EVENT_ADN_LOAD_ALL_DONE:
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ar = (AsyncResult)(msg.obj);
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ArrayList<byte[]> datas = (ArrayList<byte[]>)(ar.result);
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (ar.exception != null) {
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        throw new RuntimeException("load failed", ar.exception);
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
26122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mAdns = new ArrayList<AdnRecord>(datas.size());
26222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mResult = mAdns;
26322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mPendingExtLoads = 0;
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    for(int i = 0, s = datas.size() ; i < s ; i++) {
26622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        adn = new AdnRecord(mEf, 1 + i, datas.get(i));
26722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mAdns.add(adn);
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        if (adn.hasExtendedRecord()) {
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // If we have a valid value in the ext record field,
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // we're not done yet: we need to read the corresponding
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            // ext record and append it
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
27422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            mPendingExtLoads++;
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            mFh.loadEFLinearFixed(
27722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                                mExtensionEF, adn.mExtRecord,
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        }
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException exc) {
28422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mUserResponse != null) {
28522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                AsyncResult.forMessage(mUserResponse)
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                .exception = exc;
28722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mUserResponse.sendToTarget();
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Loading is all or nothing--either every load succeeds
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // or we fail the whole thing.
29022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mUserResponse = null;
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
29522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mUserResponse != null && mPendingExtLoads == 0) {
29622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            AsyncResult.forMessage(mUserResponse).result
29722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                = mResult;
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
29922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mUserResponse.sendToTarget();
30022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mUserResponse = null;
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
304