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
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log;
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
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        State (int value) {this.value = value;}
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        private final int value;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public int value() {return value;};
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean isMT;
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    State state;
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean isMpty;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    String number;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    int TOA;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CallInfo (boolean isMT, State state, boolean isMpty, String number) {
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.isMT = isMT;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.state = state;
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.isMpty = isMpty;
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        this.number = number;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (number.length() > 0 && number.charAt(0) == '+') {
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TOA = PhoneNumberUtils.TOA_International;
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            TOA = 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: "
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            + index + "," + (isMT ? "1" : "0") +","
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            + state.value() + ",0," + (isMpty ? "1" : "0")
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            + ",\"" + number + "\"," + TOA;
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;
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret.isMT = isMT;
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ret.state = DriverCall.stateFromCLCC(state.value());
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (ATParseEx ex) {
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new RuntimeException("should never happen", ex);
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret.isMpty = isMpty;
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret.number = number;
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ret.TOA = TOA;
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() {
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return state == State.ACTIVE || state == State.HOLDING;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    isConnecting() {
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return state == State.DIALING || state == State.ALERTING;
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    boolean
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    isRinging() {
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return state == State.INCOMING || state == 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
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    CallInfo calls[] = new CallInfo[MAX_CALLS];
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean autoProgressConnecting = true;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean nextDialFailImmediately;
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
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    handleMessage(Message msg) {
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) { switch (msg.what) {
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // PLEASE REMEMBER
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // calls may have hung up by the time delayed events happen
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case EVENT_PROGRESS_CALL_STATE:
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                progressConnectingCallState();
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }}
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    //***** Public Methods
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Start the simulated phone ringing
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * true if succeeded, false if failed
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    triggerRing(String number) {
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int empty = -1;
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean isCallWaiting = false;
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // ensure there aren't already calls INCOMING or WAITING
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo call = calls[i];
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call == null && empty < 0) {
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    empty = i;
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (call != null
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    && (call.state == CallInfo.State.INCOMING
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || call.state == CallInfo.State.WAITING)
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Log.w("ModelInterpreter",
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        "triggerRing failed; phone already ringing");
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return false;
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (call != null) {
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    isCallWaiting = true;
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (empty < 0 ) {
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.w("ModelInterpreter", "triggerRing failed; all full");
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            calls[empty] = CallInfo.createIncomingCall(
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                PhoneNumberUtils.extractNetworkPortion(number));
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (isCallWaiting) {
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                calls[empty].state = CallInfo.State.WAITING;
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** If a call is DIALING or ALERTING, progress it to the next state */
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    progressConnectingCallState() {
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this)  {
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo call = calls[i];
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null && call.state == CallInfo.State.DIALING) {
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    call.state = CallInfo.State.ALERTING;
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (autoProgressConnecting) {
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        sendMessageDelayed(
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                obtainMessage(EVENT_PROGRESS_CALL_STATE, call),
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                                CONNECTING_PAUSE_MSEC);
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (call != null
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        && call.state == CallInfo.State.ALERTING
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    call.state = CallInfo.State.ACTIVE;
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    progressConnectingToActive() {
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this)  {
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo call = calls[i];
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null && (call.state == CallInfo.State.DIALING
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    || call.state == CallInfo.State.ALERTING)
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    call.state = CallInfo.State.ACTIVE;
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** automatically progress mobile originated calls to ACTIVE.
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *  default to true
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setAutoProgressConnectingCall(boolean b) {
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        autoProgressConnecting = b;
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    setNextDialFailImmediately(boolean b) {
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        nextDialFailImmediately = b;
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * hangup ringing, dialing, or active calls
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if call was hung up, false if not
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    triggerHangupForeground() {
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean found;
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            found = false;
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo call = calls[i];
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    && (call.state == CallInfo.State.INCOMING
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || call.state == CallInfo.State.WAITING)
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    calls[i] = null;
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo call = calls[i];
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    && (call.state == CallInfo.State.DIALING
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || call.state == CallInfo.State.ACTIVE
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || call.state == CallInfo.State.ALERTING)
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    calls[i] = null;
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return found;
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * hangup holding calls
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if call was hung up, false if not
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    triggerHangupBackground() {
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean found = false;
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo call = calls[i];
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null && call.state == CallInfo.State.HOLDING) {
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    calls[i] = null;
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return found;
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * hangup all
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * returns true if call was hung up, false if not
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    triggerHangupAll() {
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized(this) {
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean found = false;
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo call = calls[i];
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (calls[i] != null) {
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                calls[i] = null;
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return found;
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onAnswer() {
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        synchronized (this) {
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo call = calls[i];
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (call != null
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    && (call.state == CallInfo.State.INCOMING
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        || call.state == CallInfo.State.WAITING)
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return switchActiveAndHeldOrWaiting();
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return false;
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onHangup() {
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean found = false;
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo call = calls[i];
3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call != null && call.state != CallInfo.State.WAITING) {
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                calls[i] = null;
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                found = true;
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return found;
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onChld(char c0, char c1) {
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean ret;
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int callIndex = 0;
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (c1 != 0) {
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            callIndex = c1 - '1';
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (callIndex < 0 || callIndex >= calls.length) {
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch (c0) {
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '0':
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret = releaseHeldOrUDUB();
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '1':
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c1 <= 0) {
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ret = releaseActiveAcceptHeldOrWaiting();
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (calls[callIndex] == null) {
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ret = false;
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    } else {
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        calls[callIndex] = null;
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        ret = true;
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '2':
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c1 <= 0) {
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ret = switchActiveAndHeldOrWaiting();
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else {
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ret = separateCall(callIndex);
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '3':
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret = conference();
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '4':
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret = explicitCallTransfer();
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            case '5':
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (true) { //just so javac doesnt complain about break
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    //CCBS not impled
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    ret = false;
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            default:
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret = false;
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    releaseHeldOrUDUB() {
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean found = false;
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null && c.isRinging()) {
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                found = true;
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                calls[i] = null;
4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!found) {
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo c = calls[i];
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c != null && c.state == CallInfo.State.HOLDING) {
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    found = true;
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    calls[i] = null;
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // don't stop...there may be more than one
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    releaseActiveAcceptHeldOrWaiting() {
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean foundHeld = false;
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean foundActive = false;
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null && c.state == CallInfo.State.ACTIVE) {
4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                calls[i] = null;
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                foundActive = true;
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!foundActive) {
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // FIXME this may not actually be how most basebands react
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // CHLD=1 may not hang up dialing/alerting calls
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CallInfo c = calls[i];
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c != null
4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        && (c.state == CallInfo.State.DIALING
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            || c.state == CallInfo.State.ALERTING)
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    calls[i] = null;
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    foundActive = true;
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null && c.state == CallInfo.State.HOLDING) {
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                c.state = CallInfo.State.ACTIVE;
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                foundHeld = true;
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (foundHeld) {
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null && c.isRinging()) {
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                c.state = CallInfo.State.ACTIVE;
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return true;
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    switchActiveAndHeldOrWaiting() {
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasHeld = false;
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // first, are there held calls?
5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null && c.state == CallInfo.State.HOLDING) {
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasHeld = true;
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Now, switch
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c.state == CallInfo.State.ACTIVE) {
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    c.state = CallInfo.State.HOLDING;
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (c.state == CallInfo.State.HOLDING) {
5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    c.state = CallInfo.State.ACTIVE;
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!hasHeld && c.isRinging())  {
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    c.state = CallInfo.State.ACTIVE;
5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    separateCall(int index) {
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c;
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c = calls[index];
5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c == null || c.isConnecting() || countActiveLines() != 1) {
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.state = CallInfo.State.ACTIVE;
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c.isMpty = false;
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0 ; i < calls.length ; i++) {
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int countHeld=0, lastHeld=0;
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (i != index) {
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CallInfo cb = calls[i];
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (cb != null && cb.state == CallInfo.State.ACTIVE) {
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        cb.state = CallInfo.State.HOLDING;
5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        countHeld++;
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        lastHeld = i;
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (countHeld == 1) {
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    // if there's only one left, clear the MPTY flag
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    calls[lastHeld].isMpty = false;
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (InvalidStateEx ex) {
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    conference() {
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int countCalls = 0;
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if there's connecting calls, we can't do this yet
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                countCalls++;
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c.isConnecting()) {
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return false;
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                c.state = CallInfo.State.ACTIVE;
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (countCalls > 0) {
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    c.isMpty = true;
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    explicitCallTransfer() {
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int countCalls = 0;
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // if there's connecting calls, we can't do this yet
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                countCalls++;
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c.isConnecting()) {
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    return false;
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // disconnect the subscriber from both calls
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return triggerHangupAll();
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    onDial(String address) {
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CallInfo call;
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int freeSlot = -1;
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.d("GSM", "SC> dial '" + address + "'");
6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (nextDialFailImmediately) {
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            nextDialFailImmediately = false;
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d("GSM", "SC< dial fail (per request)");
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String phNum = PhoneNumberUtils.extractNetworkPortion(address);
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phNum.length() == 0) {
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d("GSM", "SC< dial fail (invalid ph num)");
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Ignore setting up GPRS
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (phNum.startsWith("*99") && phNum.endsWith("#")) {
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d("GSM", "SC< dial ignored (gprs)");
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // There can be at most 1 active "line" when we initiate
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // a new call
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (countActiveLines() > 1) {
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.d("GSM", "SC< dial fail (invalid call state)");
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (InvalidStateEx ex) {
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d("GSM", "SC< dial fail (invalid call state)");
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (freeSlot < 0 && calls[i] == null) {
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                freeSlot = i;
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (calls[i] != null && !calls[i].isActiveOrHeld()) {
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Can't make outgoing calls when there is a ringing or
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // connecting outgoing call
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Log.d("GSM", "SC< dial fail (invalid call state)");
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return false;
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else if (calls[i] != null && calls[i].state == CallInfo.State.ACTIVE) {
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // All active calls behome held
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                calls[i].state = CallInfo.State.HOLDING;
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (freeSlot < 0) {
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Log.d("GSM", "SC< dial fail (invalid call state)");
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return false;
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        calls[freeSlot] = CallInfo.createOutgoingCall(phNum);
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (autoProgressConnecting) {
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sendMessageDelayed(
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]),
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    CONNECTING_PAUSE_MSEC);
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.d("GSM", "SC< dial (slot = " + freeSlot + ")");
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return true;
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<DriverCall>
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getDriverCalls() {
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<DriverCall> ret = new ArrayList<DriverCall>(calls.length);
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                DriverCall dc;
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                dc = c.toDriverCall(i + 1);
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret.add(dc);
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Log.d("GSM", "SC< getDriverCalls " + ret);
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public List<String>
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    getClccLines() {
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        ArrayList<String> ret = new ArrayList<String>(calls.length);
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo c = calls[i];
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c != null) {
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ret.add((c.toCLCCLine(i + 1)));
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private int
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    countActiveLines() throws InvalidStateEx {
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasMpty = false;
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasHeld = false;
7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasActive = false;
7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasConnecting = false;
7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean hasRinging = false;
7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean mptyIsHeld = false;
7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0 ; i < calls.length ; i++) {
7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            CallInfo call = calls[i];
7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (call != null) {
7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (!hasMpty && call.isMpty) {
7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    mptyIsHeld = call.state == CallInfo.State.HOLDING;
7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (call.isMpty && mptyIsHeld
7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    && call.state == CallInfo.State.ACTIVE
7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Log.e("ModelInterpreter", "Invalid state");
7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    throw new InvalidStateEx();
7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                } else if (!call.isMpty && hasMpty && mptyIsHeld
7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    && call.state == CallInfo.State.HOLDING
7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                ) {
7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    Log.e("ModelInterpreter", "Invalid state");
7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    throw new InvalidStateEx();
7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasMpty |= call.isMpty;
7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasHeld |= call.state == CallInfo.State.HOLDING;
7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasActive |= call.state == CallInfo.State.ACTIVE;
7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasConnecting |= call.isConnecting();
7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                hasRinging |= call.isRinging();
7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int ret = 0;
8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasHeld) ret++;
8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasActive) ret++;
8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasConnecting) ret++;
8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (hasRinging) ret++;
8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
810