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
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cdma;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandException;
223a96b0ee1d152549279c58ba24a0a035cc9a557bAmit Mahajanimport com.android.internal.telephony.GsmCdmaPhone;
233522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Savilleimport com.android.internal.telephony.uicc.UiccCardApplication;
243522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Savilleimport com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.MmiCode;
26a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Phone;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
3199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.regex.Pattern;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.regex.Matcher;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This class can handle Puk code Mmi
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic final class CdmaMmiCode  extends Handler implements MmiCode {
43cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    static final String LOG_TAG = "CdmaMmiCode";
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Constants
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // From TS 22.030 6.5.2
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String ACTION_REGISTER = "**";
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
503522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    // Supplementary Service codes for PIN/PIN2/PUK/PUK2 from TS 22.030 Annex B
513522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    static final String SC_PIN          = "04";
523522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    static final String SC_PIN2         = "042";
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String SC_PUK          = "05";
543522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    static final String SC_PUK2         = "052";
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Event Constant
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_SET_COMPLETE = 1;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Instance Variables
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
623a96b0ee1d152549279c58ba24a0a035cc9a557bAmit Mahajan    GsmCdmaPhone mPhone;
6322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    Context mContext;
643522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    UiccCardApplication mUiccApplication;
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mAction;              // ACTION_REGISTER
6722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mSc;                  // Service Code
6822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mSia, mSib, mSic;     // Service Info a,b,c
6922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPoundString;         // Entire MMI string up to and including #
7022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mDialingNumber;
7122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mPwd;                 // For password registration
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    State mState = State.PENDING;
7422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CharSequence mMessage;
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Class Variables
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static Pattern sPatternSuppService = Pattern.compile(
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*       1  2                    3          4  5       6   7         8    9     10  11             12
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         1 = Full string up to and including #
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         2 = action
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         3 = service code
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         5 = SIA
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         7 = SIB
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         9 = SIC
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         10 = dialing number
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville*/
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_POUND_STRING = 1;
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_ACTION = 2;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SERVICE_CODE = 3;
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIA = 5;
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIB = 7;
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_SIC = 9;
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_PWD_CONFIRM = 11;
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MATCH_GROUP_DIALING_NUMBER = 12;
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Public Class methods
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Check if provided string contains Mmi code in it and create corresponding
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Mmi if it does
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static CdmaMmiCode
1093a96b0ee1d152549279c58ba24a0a035cc9a557bAmit Mahajan    newFromDialString(String dialString, GsmCdmaPhone phone, UiccCardApplication app) {
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Matcher m;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CdmaMmiCode ret = null;
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        m = sPatternSuppService.matcher(dialString);
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Is this formatted like a standard supplementary service code?
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (m.matches()) {
1173522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville            ret = new CdmaMmiCode(phone,app);
11822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mPoundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
11922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mAction = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
12022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
12122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
12222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
12322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mSic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
12422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mPwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
12522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.mDialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Private Class methods
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** make empty strings be null.
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  Regexp returns empty strings for empty groups
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static String
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    makeEmptyNull (String s) {
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (s != null && s.length() == 0) return null;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return s;
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Constructor
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1463a96b0ee1d152549279c58ba24a0a035cc9a557bAmit Mahajan    CdmaMmiCode (GsmCdmaPhone phone, UiccCardApplication app) {
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super(phone.getHandler().getLooper());
14822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone = phone;
14922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mContext = phone.getContext();
1503522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville        mUiccApplication = app;
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // MmiCode implementation
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
155cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public State
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getState() {
15822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mState;
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
161cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public CharSequence
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getMessage() {
16422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mMessage;
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public Phone
168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    getPhone() {
169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return ((Phone) mPhone);
170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // inherited javadoc suffices
173cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    cancel() {
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Complete or failed cannot be cancelled
17722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mState == State.COMPLETE || mState == State.FAILED) {
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return;
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
18122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mState = State.CANCELLED;
18222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone (this);
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
185cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isCancelable() {
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Instance Methods
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1953a96b0ee1d152549279c58ba24a0a035cc9a557bAmit Mahajan    public boolean isPinPukCommand() {
1963522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville        return mSc != null && (mSc.equals(SC_PIN) || mSc.equals(SC_PIN2)
1973522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                              || mSc.equals(SC_PUK) || mSc.equals(SC_PUK2));
1983522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    }
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean isRegister() {
20122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mAction != null && mAction.equals(ACTION_REGISTER);
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
204cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean isUssdRequest() {
20699c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode");
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Process a MMI PUK code */
2113a96b0ee1d152549279c58ba24a0a035cc9a557bAmit Mahajan    public void
2123522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    processCode() {
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
2143522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville            if (isPinPukCommand()) {
2153522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                // TODO: This is the same as the code in GsmMmiCode.java,
2163522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                // MmiCode should be an abstract or base class and this and
2173522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                // other common variables and code should be promoted.
2183522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville
2193522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                // sia = old PIN or PUK
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // sib = new PIN
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // sic = new PIN
22222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                String oldPinOrPuk = mSia;
2233522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                String newPinOrPuk = mSib;
2243522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                int pinLen = newPinOrPuk.length();
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (isRegister()) {
2263522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    if (!newPinOrPuk.equals(mSic)) {
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // password mismatch; return error
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        handlePasswordError(com.android.internal.R.string.mismatchPin);
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else if (pinLen < 4 || pinLen > 8 ) {
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        // invalid length
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        handlePasswordError(com.android.internal.R.string.invalidPin);
2323522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    } else if (mSc.equals(SC_PIN)
2333522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            && mUiccApplication != null
2343522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            && mUiccApplication.getState() == AppState.APPSTATE_PUK) {
2353522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // Sim is puk-locked
2363522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        handlePasswordError(com.android.internal.R.string.needPuk);
2373522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    } else if (mUiccApplication != null) {
2383522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        Rlog.d(LOG_TAG, "process mmi service code using UiccApp sc=" + mSc);
2393522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville
2403522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // We have an app and the pre-checks are OK
2413522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        if (mSc.equals(SC_PIN)) {
2423522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            mUiccApplication.changeIccLockPassword(oldPinOrPuk, newPinOrPuk,
2433522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    obtainMessage(EVENT_SET_COMPLETE, this));
2443522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else if (mSc.equals(SC_PIN2)) {
2453522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            mUiccApplication.changeIccFdnPassword(oldPinOrPuk, newPinOrPuk,
2463522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    obtainMessage(EVENT_SET_COMPLETE, this));
2473522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else if (mSc.equals(SC_PUK)) {
2483522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            mUiccApplication.supplyPuk(oldPinOrPuk, newPinOrPuk,
2493522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    obtainMessage(EVENT_SET_COMPLETE, this));
2503522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else if (mSc.equals(SC_PUK2)) {
2513522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            mUiccApplication.supplyPuk2(oldPinOrPuk, newPinOrPuk,
2523522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    obtainMessage(EVENT_SET_COMPLETE, this));
2533522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else {
2543522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            throw new RuntimeException("Unsupported service code=" + mSc);
2553522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        }
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
2573522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        throw new RuntimeException("No application mUiccApplicaiton is null");
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
2603522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    throw new RuntimeException ("Ivalid register/action=" + mAction);
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (RuntimeException exc) {
26422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
26522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mMessage = mContext.getText(com.android.internal.R.string.mmiError);
26622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mPhone.onMMIDone(this);
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void handlePasswordError(int res) {
27122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mState = State.FAILED;
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder sb = new StringBuilder(getScString());
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append("\n");
27422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        sb.append(mContext.getText(res));
27522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMessage = sb;
27622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone(this);
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
279cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage (Message msg) {
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        AsyncResult ar;
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (msg.what == EVENT_SET_COMPLETE) {
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ar = (AsyncResult) (msg.obj);
2863522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville            onSetComplete(msg, ar);
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
28899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.e(LOG_TAG, "Unexpected reply");
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Private instance methods
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CharSequence getScString() {
29422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mSc != null) {
2953522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville            if (isPinPukCommand()) {
29622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                return mContext.getText(com.android.internal.R.string.PinMmi);
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return "";
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
3043522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville    onSetComplete(Message msg, AsyncResult ar){
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder sb = new StringBuilder(getScString());
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sb.append("\n");
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (ar.exception != null) {
30922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (ar.exception instanceof CommandException) {
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (err == CommandException.Error.PASSWORD_INCORRECT) {
3133522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    if (isPinPukCommand()) {
3143522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // look specifically for the PUK commands and adjust
3153522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // the message accordingly.
3163522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        if (mSc.equals(SC_PUK) || mSc.equals(SC_PUK2)) {
3173522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            sb.append(mContext.getText(
3183522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    com.android.internal.R.string.badPuk));
3193522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        } else {
3203522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            sb.append(mContext.getText(
3213522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    com.android.internal.R.string.badPin));
3223522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        }
3233522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        // Get the No. of retries remaining to unlock PUK/PUK2
3243522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        int attemptsRemaining = msg.arg1;
3256d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville                        if (attemptsRemaining <= 0) {
3266d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville                            Rlog.d(LOG_TAG, "onSetComplete: PUK locked,"
3276d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville                                    + " cancel as lock screen will handle this");
3286d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville                            mState = State.CANCELLED;
3296d3c836bb8991e9cf7ffb322ebabf48c2446126dWink Saville                        } else if (attemptsRemaining > 0) {
3303522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            Rlog.d(LOG_TAG, "onSetComplete: attemptsRemaining="+attemptsRemaining);
3313522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            sb.append(mContext.getResources().getQuantityString(
3323522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    com.android.internal.R.plurals.pinpuk_attempts,
3333522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                                    attemptsRemaining, attemptsRemaining));
3343522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        }
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
33622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        sb.append(mContext.getText(
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                com.android.internal.R.string.passwordIncorrect));
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
3393522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                } else if (err == CommandException.Error.SIM_PUK2) {
3403522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    sb.append(mContext.getText(
3413522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            com.android.internal.R.string.badPin));
3423522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    sb.append("\n");
3433522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    sb.append(mContext.getText(
3443522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                            com.android.internal.R.string.needPuk2));
3453522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                } else if (err == CommandException.Error.REQUEST_NOT_SUPPORTED) {
3463522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    if (mSc.equals(SC_PIN)) {
3473522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                        sb.append(mContext.getText(com.android.internal.R.string.enablePin));
3483522c54a64f577f2b657a775dae9b4eb2d8003d5Wink Saville                    }
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
35022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    sb.append(mContext.getText(
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            com.android.internal.R.string.mmiError));
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
35422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sb.append(mContext.getText(
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        com.android.internal.R.string.mmiError));
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (isRegister()) {
35822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.COMPLETE;
35922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            sb.append(mContext.getText(
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    com.android.internal.R.string.serviceRegistered));
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
36222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mState = State.FAILED;
36322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            sb.append(mContext.getText(
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    com.android.internal.R.string.mmiError));
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
36722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mMessage = sb;
36822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mPhone.onMMIDone(this);
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
372