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.test;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Looper;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.ATParseEx;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.DriverCall;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass CallInfo {
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    enum State {
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ACTIVE(0),
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        HOLDING(1),
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DIALING(2),    // MO call only
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ALERTING(3),   // MO call only
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        INCOMING(4),   // MT call only
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        WAITING(5);    // MT call only
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        State(int value) {mValue = value;}
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        private final int mValue;
4222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        public int value() {return mValue;}
43cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    }
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mIsMT;
4622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    State mState;
4722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    boolean mIsMpty;
4822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    String mNumber;
4922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    int mTOA;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CallInfo (boolean isMT, State state, boolean isMpty, String number) {
5222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mIsMT = isMT;
5322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mState = state;
5422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mIsMpty = isMpty;
5522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNumber = number;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (number.length() > 0 && number.charAt(0) == '+') {
5822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mTOA = PhoneNumberUtils.TOA_International;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
6022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mTOA = PhoneNumberUtils.TOA_Unknown;
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static CallInfo
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    createOutgoingCall(String number) {
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return new CallInfo (false, State.DIALING, false, number);
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static CallInfo
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    createIncomingCall(String number) {
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return new CallInfo (true, State.INCOMING, false, number);
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    String
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    toCLCCLine(int index) {
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            "+CLCC: "
7822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            + index + "," + (mIsMT ? "1" : "0") +","
7922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            + mState.value() + ",0," + (mIsMpty ? "1" : "0")
8022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            + ",\"" + mNumber + "\"," + mTOA;
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    DriverCall
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    toDriverCall(int index) {
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        DriverCall ret;
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret = new DriverCall();
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret.index = index;
9022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        ret.isMT = mIsMT;
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
9322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            ret.state = DriverCall.stateFromCLCC(mState.value());
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (ATParseEx ex) {
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException("should never happen", ex);
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
9822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        ret.isMpty = mIsMpty;
9922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        ret.number = mNumber;
10022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        ret.TOA = mTOA;
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret.isVoice = true;
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret.als = 0;
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    isActiveOrHeld() {
11022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mState == State.ACTIVE || mState == State.HOLDING;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    isConnecting() {
11522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mState == State.DIALING || mState == State.ALERTING;
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    isRinging() {
12022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mState == State.INCOMING || mState == State.WAITING;
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass InvalidStateEx extends Exception {
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    InvalidStateEx() {
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass SimulatedGsmCallState extends Handler {
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Instance Variables
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    CallInfo mCalls[] = new CallInfo[MAX_CALLS];
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
13722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mAutoProgressConnecting = true;
13822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private boolean mNextDialFailImmediately;
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Event Constants
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int EVENT_PROGRESS_CALL_STATE = 1;
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Constants
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int MAX_CALLS = 7;
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** number of msec between dialing -> alerting and alerting->active */
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final int CONNECTING_PAUSE_MSEC = 5 * 100;
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Overridden from Handler
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public SimulatedGsmCallState(Looper looper) {
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super(looper);
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
158cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville    @Override
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage(Message msg) {
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) { switch (msg.what) {
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // PLEASE REMEMBER
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // calls may have hung up by the time delayed events happen
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_PROGRESS_CALL_STATE:
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                progressConnectingCallState();
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }}
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Public Methods
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Start the simulated phone ringing
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * true if succeeded, false if failed
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    triggerRing(String number) {
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int empty = -1;
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean isCallWaiting = false;
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // ensure there aren't already calls INCOMING or WAITING
18422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
18522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo call = mCalls[i];
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call == null && empty < 0) {
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    empty = i;
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (call != null
19022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    && (call.mState == CallInfo.State.INCOMING
19122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        || call.mState == CallInfo.State.WAITING)
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
19399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                    Rlog.w("ModelInterpreter",
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        "triggerRing failed; phone already ringing");
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return false;
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (call != null) {
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    isCallWaiting = true;
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (empty < 0 ) {
20299c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.w("ModelInterpreter", "triggerRing failed; all full");
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
20622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mCalls[empty] = CallInfo.createIncomingCall(
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                PhoneNumberUtils.extractNetworkPortion(number));
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (isCallWaiting) {
21022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCalls[empty].mState = CallInfo.State.WAITING;
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** If a call is DIALING or ALERTING, progress it to the next state */
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    progressConnectingCallState() {
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this)  {
22122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
22222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo call = mCalls[i];
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (call != null && call.mState == CallInfo.State.DIALING) {
22522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    call.mState = CallInfo.State.ALERTING;
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
22722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mAutoProgressConnecting) {
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        sendMessageDelayed(
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                obtainMessage(EVENT_PROGRESS_CALL_STATE, call),
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                CONNECTING_PAUSE_MSEC);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (call != null
23422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        && call.mState == CallInfo.State.ALERTING
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
23622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    call.mState = CallInfo.State.ACTIVE;
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    progressConnectingToActive() {
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this)  {
24722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
24822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo call = mCalls[i];
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
25022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (call != null && (call.mState == CallInfo.State.DIALING
25122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    || call.mState == CallInfo.State.ALERTING)
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
25322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    call.mState = CallInfo.State.ACTIVE;
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** automatically progress mobile originated calls to ACTIVE.
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  default to true
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setAutoProgressConnectingCall(boolean b) {
26522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mAutoProgressConnecting = b;
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setNextDialFailImmediately(boolean b) {
27022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNextDialFailImmediately = b;
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * hangup ringing, dialing, or active calls
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if call was hung up, false if not
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    triggerHangupForeground() {
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean found;
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            found = false;
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
28422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
28522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo call = mCalls[i];
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null
28822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    && (call.mState == CallInfo.State.INCOMING
28922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        || call.mState == CallInfo.State.WAITING)
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
29122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCalls[i] = null;
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
29622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
29722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo call = mCalls[i];
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null
30022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    && (call.mState == CallInfo.State.DIALING
30122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        || call.mState == CallInfo.State.ACTIVE
30222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        || call.mState == CallInfo.State.ALERTING)
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
30422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCalls[i] = null;
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return found;
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * hangup holding calls
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if call was hung up, false if not
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    triggerHangupBackground() {
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean found = false;
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
32122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
32222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo call = mCalls[i];
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
32422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (call != null && call.mState == CallInfo.State.HOLDING) {
32522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCalls[i] = null;
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return found;
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * hangup all
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if call was hung up, false if not
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    triggerHangupAll() {
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) {
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean found = false;
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
34322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
34422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo call = mCalls[i];
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
34622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mCalls[i] != null) {
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
35022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCalls[i] = null;
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return found;
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onAnswer() {
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
36022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
36122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo call = mCalls[i];
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null
36422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    && (call.mState == CallInfo.State.INCOMING
36522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        || call.mState == CallInfo.State.WAITING)
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return switchActiveAndHeldOrWaiting();
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onHangup() {
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean found = false;
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
37922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
38022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo call = mCalls[i];
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
38222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (call != null && call.mState != CallInfo.State.WAITING) {
38322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCalls[i] = null;
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                found = true;
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return found;
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onChld(char c0, char c1) {
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean ret;
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int callIndex = 0;
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (c1 != 0) {
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            callIndex = c1 - '1';
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
39922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (callIndex < 0 || callIndex >= mCalls.length) {
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (c0) {
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '0':
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret = releaseHeldOrUDUB();
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '1':
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c1 <= 0) {
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ret = releaseActiveAcceptHeldOrWaiting();
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
41222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mCalls[callIndex] == null) {
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ret = false;
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
41522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mCalls[callIndex] = null;
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ret = true;
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '2':
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c1 <= 0) {
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ret = switchActiveAndHeldOrWaiting();
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ret = separateCall(callIndex);
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '3':
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret = conference();
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '4':
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret = explicitCallTransfer();
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '5':
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (true) { //just so javac doesnt complain about break
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    //CCBS not impled
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ret = false;
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret = false;
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    releaseHeldOrUDUB() {
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean found = false;
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
45122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
45222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null && c.isRinging()) {
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                found = true;
45622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCalls[i] = null;
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!found) {
46222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
46322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo c = mCalls[i];
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
46522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (c != null && c.mState == CallInfo.State.HOLDING) {
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
46722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCalls[i] = null;
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // don't stop...there may be more than one
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    releaseActiveAcceptHeldOrWaiting() {
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean foundHeld = false;
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean foundActive = false;
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
48222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
48322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
48522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (c != null && c.mState == CallInfo.State.ACTIVE) {
48622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCalls[i] = null;
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                foundActive = true;
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!foundActive) {
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // FIXME this may not actually be how most basebands react
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // CHLD=1 may not hang up dialing/alerting calls
49422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
49522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                CallInfo c = mCalls[i];
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c != null
49822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        && (c.mState == CallInfo.State.DIALING
49922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                            || c.mState == CallInfo.State.ALERTING)
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
50122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCalls[i] = null;
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    foundActive = true;
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
50722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
50822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
51022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (c != null && c.mState == CallInfo.State.HOLDING) {
51122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                c.mState = CallInfo.State.ACTIVE;
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                foundHeld = true;
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (foundHeld) {
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
52022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
52122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null && c.isRinging()) {
52422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                c.mState = CallInfo.State.ACTIVE;
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    switchActiveAndHeldOrWaiting() {
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasHeld = false;
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // first, are there held calls?
53722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
53822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
54022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (c != null && c.mState == CallInfo.State.HOLDING) {
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasHeld = true;
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Now, switch
54722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
54822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
55122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (c.mState == CallInfo.State.ACTIVE) {
55222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    c.mState = CallInfo.State.HOLDING;
55322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                } else if (c.mState == CallInfo.State.HOLDING) {
55422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    c.mState = CallInfo.State.ACTIVE;
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!hasHeld && c.isRinging())  {
55622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    c.mState = CallInfo.State.ACTIVE;
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    separateCall(int index) {
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c;
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
57022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            c = mCalls[index];
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c == null || c.isConnecting() || countActiveLines() != 1) {
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
57622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            c.mState = CallInfo.State.ACTIVE;
57722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            c.mIsMpty = false;
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
57922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            for (int i = 0 ; i < mCalls.length ; i++) {
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int countHeld=0, lastHeld=0;
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (i != index) {
58322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    CallInfo cb = mCalls[i];
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
58522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (cb != null && cb.mState == CallInfo.State.ACTIVE) {
58622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        cb.mState = CallInfo.State.HOLDING;
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        countHeld++;
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        lastHeld = i;
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (countHeld == 1) {
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // if there's only one left, clear the MPTY flag
59422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mCalls[lastHeld].mIsMpty = false;
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (InvalidStateEx ex) {
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    conference() {
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int countCalls = 0;
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if there's connecting calls, we can't do this yet
61122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
61222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                countCalls++;
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c.isConnecting()) {
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return false;
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
62222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
62322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
62622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                c.mState = CallInfo.State.ACTIVE;
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (countCalls > 0) {
62822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    c.mIsMpty = true;
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    explicitCallTransfer() {
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int countCalls = 0;
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if there's connecting calls, we can't do this yet
64122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
64222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                countCalls++;
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c.isConnecting()) {
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return false;
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // disconnect the subscriber from both calls
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return triggerHangupAll();
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onDial(String address) {
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CallInfo call;
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int freeSlot = -1;
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
66299c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d("GSM", "SC> dial '" + address + "'");
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
66422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mNextDialFailImmediately) {
66522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mNextDialFailImmediately = false;
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
66799c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.d("GSM", "SC< dial fail (per request)");
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String phNum = PhoneNumberUtils.extractNetworkPortion(address);
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phNum.length() == 0) {
67499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.d("GSM", "SC< dial fail (invalid ph num)");
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Ignore setting up GPRS
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phNum.startsWith("*99") && phNum.endsWith("#")) {
68099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.d("GSM", "SC< dial ignored (gprs)");
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // There can be at most 1 active "line" when we initiate
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // a new call
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (countActiveLines() > 1) {
68899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.d("GSM", "SC< dial fail (invalid call state)");
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (InvalidStateEx ex) {
69299c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.d("GSM", "SC< dial fail (invalid call state)");
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
69622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
69722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (freeSlot < 0 && mCalls[i] == null) {
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                freeSlot = i;
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
70122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            if (mCalls[i] != null && !mCalls[i].isActiveOrHeld()) {
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Can't make outgoing calls when there is a ringing or
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // connecting outgoing call
70499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                Rlog.d("GSM", "SC< dial fail (invalid call state)");
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
70622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            } else if (mCalls[i] != null && mCalls[i].mState == CallInfo.State.ACTIVE) {
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // All active calls behome held
70822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mCalls[i].mState = CallInfo.State.HOLDING;
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (freeSlot < 0) {
71399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville            Rlog.d("GSM", "SC< dial fail (invalid call state)");
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
71722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mCalls[freeSlot] = CallInfo.createOutgoingCall(phNum);
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
71922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mAutoProgressConnecting) {
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sendMessageDelayed(
72122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    obtainMessage(EVENT_PROGRESS_CALL_STATE, mCalls[freeSlot]),
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CONNECTING_PAUSE_MSEC);
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
72599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d("GSM", "SC< dial (slot = " + freeSlot + ")");
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<DriverCall>
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getDriverCalls() {
73222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        ArrayList<DriverCall> ret = new ArrayList<DriverCall>(mCalls.length);
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
73422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
73522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DriverCall dc;
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = c.toDriverCall(i + 1);
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret.add(dc);
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
74599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville        Rlog.d("GSM", "SC< getDriverCalls " + ret);
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<String>
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getClccLines() {
75222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        ArrayList<String> ret = new ArrayList<String>(mCalls.length);
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
75422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
75522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo c = mCalls[i];
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret.add((c.toCLCCLine(i + 1)));
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    countActiveLines() throws InvalidStateEx {
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasMpty = false;
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasHeld = false;
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasActive = false;
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasConnecting = false;
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRinging = false;
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean mptyIsHeld = false;
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
77422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = 0 ; i < mCalls.length ; i++) {
77522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            CallInfo call = mCalls[i];
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call != null) {
77822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (!hasMpty && call.mIsMpty) {
77922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    mptyIsHeld = call.mState == CallInfo.State.HOLDING;
78022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                } else if (call.mIsMpty && mptyIsHeld
78122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    && call.mState == CallInfo.State.ACTIVE
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
78399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                    Rlog.e("ModelInterpreter", "Invalid state");
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    throw new InvalidStateEx();
78522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                } else if (!call.mIsMpty && hasMpty && mptyIsHeld
78622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    && call.mState == CallInfo.State.HOLDING
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
78899c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville                    Rlog.e("ModelInterpreter", "Invalid state");
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    throw new InvalidStateEx();
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
79222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                hasMpty |= call.mIsMpty;
79322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                hasHeld |= call.mState == CallInfo.State.HOLDING;
79422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                hasActive |= call.mState == CallInfo.State.ACTIVE;
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasConnecting |= call.isConnecting();
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasRinging |= call.isRinging();
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int ret = 0;
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasHeld) ret++;
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActive) ret++;
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasConnecting) ret++;
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRinging) ret++;
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
811