114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang/**
214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * Copyright (C) 2010 The Android Open Source Project
314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang *
414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * Licensed under the Apache License, Version 2.0 (the "License");
514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * you may not use this file except in compliance with the License.
614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * You may obtain a copy of the License at
714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang *
814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang *      http://www.apache.org/licenses/LICENSE-2.0
914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang *
1014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * Unless required by applicable law or agreed to in writing, software
1114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * distributed under the License is distributed on an "AS IS" BASIS,
1214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * See the License for the specific language governing permissions and
1414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * limitations under the License.
1514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang */
1614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
1714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang/**
1814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * The Radio object contains a set of methods and objects to handle ril request
1914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * which is passed from simulatedRadioWorker queue. The global object initialize
2014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * an instance of Radio object by calling "new Radio". For each ril request,
2114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * rilDispatchTable gets searched and the corresponding method is called.
2214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * Extra requests are also defined to process unsolicited rerequests.
2314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang *
2414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * The rilDispatchTable is an array indexed by RIL_REQUEST_* or REQUEST_UNSOL_*,
2514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * in which each request corresponds to a functions defined in the Radio object.
2614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * We need to pay attention when using "this" within those functions. When they are
2714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * called in "this.process" using
2814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang *               result = this.radioDispatchTable[req.reqNum])(req);
2914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * this scope of "this" within those functions are the radioDispatchTable, not the
3014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * object that "this.process" belongs to. Using "this." to access other
3114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * functions in the object may cause trouble.
3214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * To avoid that, the object is passed in when those functions are called as
3314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * shown in the following:
3414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang *                 result = (this.radioDispatchTable[req.reqNum]).call(this, req);
3514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang */
3614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
3714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang/**
3814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * Set radio state
3914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang */
4014171dca025273fb64b239c1ec86ed7d4b677343Xia Wangfunction setRadioState(newState) {
4114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    newRadioState = newState;
4214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    if (typeof newState == 'string') {
4314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        newRadioState = globals[newState];
4414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (typeof newRadioState == 'undefined') {
4514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            throw('setRadioState: Unknow string: ' + newState);
4614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
4714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
4814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    if ((newRadioState < RADIOSTATE_OFF) || (newRadioState > RADIOSTATE_NV_READY)) {
4914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        throw('setRadioState: newRadioState: ' + newRadioState + ' is invalid');
5014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
5114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    gRadioState = newRadioState;
5214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    sendRilUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED);
5314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang}
5414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
5514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang/**
5614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * Create a call.
5714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang *
5814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * @return a RilCall
5914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang */
6014171dca025273fb64b239c1ec86ed7d4b677343Xia Wangfunction RilCall(state, phoneNumber, callerName) {
6114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.state = state;
6214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.index = 0;
6314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.toa = 0;
6414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.isMpty = false;
6514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.isMt = false;
6614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.als = 0;
6714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.isVoice = true;
6814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.isVoicePrivacy = false;
6914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.number = phoneNumber;
7014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.numberPresentation = 0;
7114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.name = callerName;
7214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang}
7314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
7414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang/**
7514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * Simulated Radio
7614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang */
7714171dca025273fb64b239c1ec86ed7d4b677343Xia Wangfunction Radio() {
7814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var registrationState = '1';
7914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var lac = '0';
8014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var cid = '0';
8114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var radioTechnology = '3';
8214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var baseStationId = NULL_RESPONSE_STRING;
8314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var baseStationLatitude = NULL_RESPONSE_STRING;
8414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var baseStationLongitude = NULL_RESPONSE_STRING;
8514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var concurrentServices = NULL_RESPONSE_STRING;
8614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var systemId  = NULL_RESPONSE_STRING;
8714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var networkId = NULL_RESPONSE_STRING;
8814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var roamingIndicator = NULL_RESPONSE_STRING;
8914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var prlActive = NULL_RESPONSE_STRING;
9014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var defaultRoamingIndicator = NULL_RESPONSE_STRING;
9114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var registrationDeniedReason = NULL_RESPONSE_STRING;
9214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var primaryScrambingCode = NULL_RESPONSE_STRING;
9314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
9414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var NETWORK_SELECTION_MODE_AUTOMATIC = 0;
9514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var NETWORK_SELECTION_MODE_MANUAL = 1;
9614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var networkSelectionMode = NETWORK_SELECTION_MODE_AUTOMATIC;
9714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
9814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var muteState = 0;   // disable mute
9914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
10014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    // Number of active calls in calls
10114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var numberActiveCalls = 0;
10214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
10314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    // Maximum number of active calls
10414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var maxNumberActiveCalls = 7;
10514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var maxConnectionsPerCall = 5; // only 5 connections allowed per call
10614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
107bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang    // Flag to denote whether an incoming/waiting call is answered
108230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang    var incomingCallIsProcessed = false;
10914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
1102b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    // Call transition flag
1112b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    var callTransitionFlag = false;  // default to auto-transition
1122b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
1132b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    var lastCallFailCause = 0;
1142b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
11514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    // Array of "active" calls
11614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var calls = Array(maxNumberActiveCalls + 1);
11714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
11814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    // The result returned by the request handlers
11914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var result = new Object();
12014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
12114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    function GWSignalStrength() {
12214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        this.signalStrength = 10;  // 10 * 2 + (-113) = -93dBm, make it three bars
12314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        this.bitErrorRate = 0;
12414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
12514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
12614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    function CDMASignalStrength() {
12714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        this.dbm = -1;
12814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        this.ecio = -1;
12914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
13014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
13114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    function EVDOSignalStrength() {
13214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        this.dbm = -1;
13314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        this.ecio = -1;
13414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        this.signalNoiseRatio = 0;
13514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
13614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
1372c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    function LTESignalStrength() {
1382c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        this.signalStrength = -1;
1392c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        this.rsrp = 0;
1402c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        this.rsrq = 0;
1412c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        this.rssnr = 0;
1422c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        this.cqi = 0;
1432c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    }
1442c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville
14514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var gwSignalStrength = new GWSignalStrength;
14614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var cdmaSignalStrength = new CDMASignalStrength();
14714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    var evdoSignalStrength = new EVDOSignalStrength();
1482c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    var lteSignalStrength = new LTESignalStrength();
14914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
15014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
15114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * The the array of calls, this is a sparse
15214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * array and some elements maybe 'undefined'.
15314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
15414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @return Array of RilCall's
15514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
15614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.getCalls =  function() {
15714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return calls;
15814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
15914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
16014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
16114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @return the RilCall at calls[index] or null if undefined.
16214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
16314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.getCall = function(index) {
16414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var c = null;
16514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        try {
16614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            c = calls[index];
16714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if (typeof c == 'undefined') {
16814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                c = null;
16914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
17014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        } catch (err) {
17114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            c = null;
17214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
17314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return c;
17414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
17514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
1762b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    /**
1772b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * @return the first call that is in the given state
1782b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     */
1792b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.getCallIdByState = function(callState) {
1802b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if ((callState < CALLSTATE_ACTIVE) || (callState > CALLSTATE_WAITING)) {
1812b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return null;
1822b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
1832b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        for (var i = 0; i < calls.length; i++) {
1842b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            if (typeof calls[i] != 'undefined') {
1852b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                if (calls[i].state == callState) {
1862b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                    return i;
1872b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                }
1882b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            }
1892b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
1902b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        return null;
1912b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
1922b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
19314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /** Add an active call
19414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
19514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @return a RilCall or null if too many active calls.
19614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
19714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.addCall = function(state, phoneNumber, callerName) {
19814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: addCall');
19914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var c = null;
20014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (numberActiveCalls < maxNumberActiveCalls) {
20114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            numberActiveCalls += 1;
20214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            c = new RilCall(state, phoneNumber, callerName);
20314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            // call index should fall in the closure of [1, 7]
20414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            // Search for an "undefined" element in the array and insert the call
20514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            for (var i = 1; i < (maxNumberActiveCalls + 1); i++) {
20614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                print('Radio: addCall, i=' + i);
20714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                if (typeof calls[i] == 'undefined') {
20814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    print('Radio: addCall, calls[' + i + '] is undefined');
20914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    c.index = i;
21014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    calls[i] = c;
21114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    break;
21214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                }
21314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
21414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            this.printCalls(calls);
21514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
21614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return c;
21714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
21814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
21914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
22014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Remove the call, does nothing if the call is undefined.
22114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
22214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param index into calls to remove.
22314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @return the call removed or null if did not exist
22414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
22514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.removeCall =  function(index) {
22614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var c = null;
22714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if ((numberActiveCalls > 0)
22814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                 && (index < calls.length)
22914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                 && (typeof calls[index] != 'undefined')) {
23014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            c = calls[index];
23114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            delete calls[index];
23214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            numberActiveCalls -= 1;
23314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if (numberActiveCalls == 0) {
23414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                calls = new Array();
23514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
23614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        } else {
23714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            c = null;
23814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
23914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return c;
24014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
24114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
24214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
24314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Print the call
24414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
24514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param c is the RilCall to print
24614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
24714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.printCall = function(c) {
24814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if ((c != null) && (typeof c != 'undefined')) {
24914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            print('c[' + c.index + ']: index=' + c.index + ' state=' + c.state +
25014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                  ' number=' + c.number + ' name=' + c.name);
25114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
25214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
25314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
25414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
25514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Print all the calls.
25614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
25714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param callArray is an Array of RilCall's
25814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
25914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.printCalls = function(callArray) {
26014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (typeof callArray == 'undefined') {
26114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            callArray = calls;
26214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
26314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('callArray.length=' + callArray.length);
26414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        for (var i = 0; i < callArray.length; i++) {
26514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if ((callArray[i] == null) || (typeof callArray[i] == 'undefined')) {
26614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                print('c[' + i + ']: undefined');
26714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            } else {
26814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.printCall(callArray[i]);
26914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
27014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
27114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
27214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
27314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
2742b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * Count number of calls in the given state
2752b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     *
2762b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * @param callState is the give state
2772b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     */
2782b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.countCallsInState = function(callState) {
2792b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var count = 0;
2802b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if ((callState < CALLSTATE_ACTIVE) || (callState > CALLSTATE_WAITING)) {
2812b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            // not a valid call state
2822b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return null;
2832b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
2842b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        for (var i = 0; i < calls.length; i++) {
2852b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            if (typeof calls[i] != 'undefined') {
2862b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                if (calls[i].state == callState) {
2872b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                    count++;
2882b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                }
2892b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            }
2902b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
2912b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        return count;
2922b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
2932b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
2942b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    /**
29514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Print signal strength
29614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
29714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.printSignalStrength = function() {
29814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('rssi: '         + gwSignalStrength.signalStrength);
29914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('bitErrorRate: ' + gwSignalStrength.bitErrorRate);
30014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('cdmaDbm: '  +  cdmaSignalStrength.dbm);
30114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('cdmaEcio: ' + cdmaSignalStrength.ecio);
30214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('evdoRssi: ' + evdoSignalStrength.dbm);
30314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('evdoEcio: ' + evdoSignalStrength.ecio);
30414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('evdoSnr: '  + evdoSignalStrength.signalNoiseRatio);
3052c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        print('lteRssi: '  + lteSignalStrength.signalStrength);
3062c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        print('lteRsrp: '  + lteSignalStrength.rsrp);
3072c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        print('lteRsrq: '  + lteSignalStrength.rsrq);
3082c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        print('lteRssnr: ' + lteSignalStrength.rssnr);
3092c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        print('lteCqi: '   + lteSignalStrength.cqi);
31014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
31114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
31214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
31314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * set signal strength
31414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
31514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param rssi and bitErrorRate are signal strength parameters for GSM
31614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *        cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr are parameters for CDMA & EVDO
31714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
31814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.setSignalStrength = function(rssi, bitErrorRate, cdmaDbm, cdmaEcio, evdoRssi,
3192c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                                      evdoEcio, evdoSnr, lteSigStrength, lteRsrp,
3202c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                                      lteRsrq, lteRssnr, lteCqi) {
32114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('setSignalStrength E');
32214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
32314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (rssi != 99) {
32414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if ((rssi < 0) || (rssi > 31)) {
32514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                throw ('not a valid signal strength');
32614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
32714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
32814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // update signal strength
32914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        gwSignalStrength.signalStrength = rssi;
33014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        gwSignalStrength.bitErrorRate = bitErrorRate;
33114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        cdmaSignalStrength.dbm = cdmaDbm;
33214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        cdmaSignalStrength.ecio = cdmaEcio;
33314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        evdoSignalStrength.dbm = evdoRssi;
33414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        evdoSignalStrength.ecio = evdoEcio;
33514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        evdoSignalStrength.signalNoiseRatio = evdoSnr;
3362c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        lteSignalStrength.signalStrength = lteSigStrength;
3372c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        lteSignalStrength.rsrp = lteRsrp;
3382c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        lteSignalStrength.rsrq = lteRsrq;
3392c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        lteSignalStrength.rssnr = lteRssnr;
3402c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        lteSignalStrength.cqi = lteCqi;
34114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
34214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // pack the signal strength into RspSignalStrength and send a unsolicited response
34314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var rsp = new Object();
34414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
34514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.gwSignalstrength = gwSignalStrength;
34614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.cdmSignalstrength = cdmaSignalStrength;
34714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.evdoSignalstrength = evdoSignalStrength;
3482c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        rsp.lteSignalstrength = lteSignalStrength;
34914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
35014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var response = rilSchema[packageNameAndSeperator +
35114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                             'RspSignalStrength'].serialize(rsp);
35214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
35314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        sendRilUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH, response);
35414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
35514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // send the unsolicited signal strength every 1 minute.
35614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        simulatedRadioWorker.addDelayed(
35714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            {'reqNum' : CMD_UNSOL_SIGNAL_STRENGTH}, 60000);
35814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('setSignalStrength X');
35914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
36014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
36114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
36214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_GET_CURRENT_CALL
36314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
36414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
36514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
36614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestGetCurrentCalls = function(req) { // 9
36714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestGetCurrentCalls E');
36814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var rsp = new Object();
36914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
37014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // pack calls into rsp.calls
37114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.calls = new Array();
37214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var i;
37314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var j;
37414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        for (i = 0, j = 0; i < calls.length; i++) {
37514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if (typeof calls[i] != 'undefined') {
37614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                rsp.calls[j++] = calls[i];
37714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
37814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
37914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        result.responseProtobuf = rilSchema[packageNameAndSeperator +
38014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                            'RspGetCurrentCalls'].serialize(rsp);
38114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
38214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
38314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
38414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
38514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_DIAL
38614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
38714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
38814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
38914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestDial = function(req) { // 10
39014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestDial E');
39114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var newCall = new Object();
39214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        newCall = this.addCall(CALLSTATE_DIALING, req.data.address, '');
39314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (newCall == null) {
39414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.rilErrCode = RIL_E_GENERIC_FAILURE;
39514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            return result;
39614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
39714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        this.printCalls(calls);
39814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
39914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('after add the call');
40014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // Set call state to dialing
40114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        simulatedRadioWorker.add(
40214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        {'reqNum' : CMD_CALL_STATE_CHANGE,
40314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                         'callType' : OUTGOING,
40414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                         'callIndex' : newCall.index,
40514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                         'nextState' : CALLSTATE_DIALING});
4062b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if (!callTransitionFlag) {
4072b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            // for auto transition
4082b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            // Update call state to alerting after 1 second
4092b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            simulatedRadioWorker.addDelayed(
4102b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                {'reqNum' : CMD_CALL_STATE_CHANGE,
4112b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                 'callType' : OUTGOING,
4122b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                 'callIndex' : newCall.index,
4132b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                 'nextState' : CALLSTATE_ALERTING}, 1000);
4142b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            // Update call state to active after 2 seconds
4152b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            simulatedRadioWorker.addDelayed(
4162b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                {'reqNum' : CMD_CALL_STATE_CHANGE,
4172b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                 'callType' : OUTGOING,
4182b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                 'callIndex': newCall.index,
4192b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                 'nextState' : CALLSTATE_ACTIVE}, 2000);
4202b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
42114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
42214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
42314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
42414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
42514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_HANG_UP
42614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
42714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
42814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
42914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestHangUp = function(req) { // 12
43014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestHangUp data.connection_index=' + req.data.connectionIndex);
43114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (this.removeCall(req.data.connectionIndex) == null) {
43214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.rilErrCode = RIL_E_GENERIC_FAILURE;
43314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            print('no connection to hangup');
43414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
43514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
43614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
43714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
43814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
43914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND
44014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *        Hang up waiting or held
44114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
44214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
44314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
44414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestHangupWaitingOrBackground = function(req) { // 13
44514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestHangupWaitingOrBackground');
44614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (numberActiveCalls <= 0) {
44714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang          result.rilErrCode = RIL_E_GENERIC_FAILURE;
44814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        } else {
44914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            for (var i = 0; i < calls.length; i++) {
45014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                if (typeof calls[i] != 'undefined') {
45114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    switch (calls[i].state) {
45214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        case CALLSTATE_HOLDING:
45314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        case CALLSTATE_WAITING:
454bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                        case CALLSTATE_INCOMING:
45514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            this.removeCall(i);
456230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang                            incomingCallIsProcessed = true;
45714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            break;
45814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        default:
45914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            result.rilErrCode = RIL_E_GENERIC_FAILURE;
46014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            break;
46114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
46214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    this.printCalls(calls);
46314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
46414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        return result;
46514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
46614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                } // end of processing call[i]
46714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            } // end of for
46814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
46914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
47014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        simulatedRadioWorker.add(
47114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang          {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
47214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
47314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
47414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
47514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
47614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
47714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *   release all active calls (if any exist) and resume held or waiting calls.
47814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
47914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
48014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestHangUpForegroundResumeBackground = function(req) { //14
48114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestHangUpForegroundResumeBackground');
48214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (numberActiveCalls <= 0) {
48314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.rilErrCode = RIL_E_GENERIC_FAILURE;
48414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        } else {
48514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            for (var i = 0; i < calls.length; i++) {
48614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                if (typeof calls[i] != 'undefined') {
48714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    switch (calls[i].state) {
48814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        case CALLSTATE_ACTIVE:
48914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            this.removeCall(i);
49014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            break;
49114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        case CALLSTATE_HOLDING:
49214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        case CALLSTATE_WAITING:
49314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                          calls[i].state = CALLSTATE_ACTIVE;
49414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            break;
49514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        default:
49614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            result.rilErrCode = RIL_E_GENERIC_FAILURE;
49714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            break;
49814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
49914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    this.printCalls(calls);
50014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
50114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        return result;
50214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
50314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                } // end of processing call[i]
50414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
50514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
50614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
50714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        simulatedRadioWorker.add(
50814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang          {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
50914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
51014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
51114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
51214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
51314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE
51414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
51514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *     BEFORE                               AFTER
51614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Call 1   Call 2                 Call 1       Call 2
51714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * ACTIVE   HOLDING                HOLDING     ACTIVE
51814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * ACTIVE   WAITING                HOLDING     ACTIVE
51914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * HOLDING  WAITING                HOLDING     ACTIVE
52014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * ACTIVE   IDLE                   HOLDING     IDLE
52114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * IDLE     IDLE                   IDLE        IDLE
52214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
52314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
52414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
52514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestSwitchWaitingOrHoldingAndActive = function(req) {  // 15
52614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestSwitchWaitingOrHoldingAndActive');
52714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: lastReq = ' + lastReq);
52814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: req.reqNum = ' + req.reqNum);
52914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (lastReq == req.reqNum) {
53014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            print('Radio: called twice');
53114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            return result;
53214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
53314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
53414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (numberActiveCalls <= 0) {
53514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.rilErrCode = RIL_E_GENERIC_FAILURE;
53614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        } else {
53714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            for (var i = 0; i < calls.length; i++) {
53814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                if (typeof calls[i] != 'undefined') {
53914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    switch (calls[i].state) {
54014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        case CALLSTATE_ACTIVE:
54114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            calls[i].state = CALLSTATE_HOLDING;
54214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            break;
54314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        case CALLSTATE_HOLDING:
54414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        case CALLSTATE_WAITING:
54514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            calls[i].state = CALLSTATE_ACTIVE;
54614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            break;
54714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        default:
54814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            result.rilErrCode = RIL_E_GENERIC_FAILURE;
54914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            break;
55014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
55114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    this.printCalls(calls);
55214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
55314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        return result;
55414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
55514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                } // end of processing call[i]
55614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            } // end of for
55714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
55814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
55914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        simulatedRadioWorker.add(
56014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang          {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
56114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
56214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
56314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
56414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
56514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_CONFERENCE
56614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Conference holding and active
56714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
56814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
56914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
57014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestConference = function(req) {  // 16
57114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestConference E');
57214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if ((numberActiveCalls <= 0) || (numberActiveCalls > maxConnectionsPerCall)) {
57314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            // The maximum number of connections within a call is 5
57414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.rilErrCode = RIL_E_GENERIC_FAILURE;
57514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            return result;
57614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        } else {
57714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            var numCallsInBadState = 0;
57814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            for (var i = 0; i < calls.length; i++) {
57914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                if (typeof calls[i] != 'undefined') {
58014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    if ((calls[i].state != CALLSTATE_ACTIVE) &&
58114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            (calls[i].state != CALLSTATE_HOLDING)) {
58214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        numCallsInBadState++;
58314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
58414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                }
58514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
58614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
58714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            // if there are calls not in ACITVE or HOLDING state, return error
58814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if (numCallsInBadState > 0) {
58914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                result.rilErrCode = RIL_E_GENERIC_FAILURE;
59014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                return result;
59114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            } else { // conference ACTIVE and HOLDING calls
59214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                for (var i = 0; i < calls.length; i++) {
59314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    if (typeof calls[i] != 'undefined') {
59414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        switch (calls[i].state) {
59514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            case CALLSTATE_ACTIVE:
59614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                break;
59714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            case CALLSTATE_HOLDING:
59814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                calls[i].state = CALLSTATE_ACTIVE;
59914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                break;
60014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            default:
60114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                result.rilErrCode = RIL_E_GENERIC_FAILURE;
60214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                break;
60314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        }
60414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
60514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    this.printCalls(calls);
60614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
60714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        return result;
60814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
60914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                }
61014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
61114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
61214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
61314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // Only if conferencing is successful,
61414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
61514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        simulatedRadioWorker.add(
61614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang          {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
61714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
61814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
61914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
62014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
6212b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * Handle RIL_REQUEST_LAST_CALL_FAIL_CAUSE
6222b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     *
6232b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * @param req is the request
6242b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     */
6252b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.rilRequestLastCallFailCause = function(req) {
6262b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        print('Radio: rilRequestLastCallFailCause E');
6272b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
6282b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var rsp = new Object();
6292b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        rsp.integers = new Array();
6302b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        rsp.integers[0] = lastCallFailCause;
6312b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
6322b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        result.responseProtobuf = rilSchema[packageNameAndSeperator +
6332b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                                            'RspIntegers'].serialize(rsp);
6342b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        return result;
6352b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
6362b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
6372b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    /**
63814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_SIGNAL_STRENGTH
63914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
64014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
64114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
64214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestSignalStrength = function(req) { // 19
64314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestSignalStrength E');
64414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var rsp = new Object();
64514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
64614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // pack the signal strength into RspSignalStrength
64714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.gwSignalstrength = gwSignalStrength;
64814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.cdmaSignalstrength = cdmaSignalStrength;
64914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.evdoSignalstrength = evdoSignalStrength;
65014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
65114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        result.responseProtobuf = rilSchema[packageNameAndSeperator +
65214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                            'RspSignalStrength'].serialize(rsp);
65314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
65414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
65514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
65614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
6572c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville     * Handle RIL_REQUEST_VOICE_REGISTRATION_STATE
65814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
65914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
66014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
6612c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    this.rilRequestVoiceRegistrationState = function(req) { // 20
6622c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        print('Radio: rilRequestVoiceRegistrationState');
66314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
66414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var rsp = new Object();
66514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings = Array();
66614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[0] = registrationState;
66714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[1] = lac;
66814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[2] = cid;
66914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[3] = radioTechnology;
67014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[4] = baseStationId;
67114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[5] = baseStationLatitude;
67214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[6] = baseStationLongitude;
67314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[7] = concurrentServices;
67414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[8] = systemId;
67514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[9] = networkId;
67614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[10] = roamingIndicator;
67714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[11] = prlActive;
67814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[12] = defaultRoamingIndicator;
67914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[13] = registrationDeniedReason;
68014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[14] = primaryScrambingCode;
68114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
68214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        result.responseProtobuf = rilSchema[packageNameAndSeperator +
68314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                 'RspStrings'].serialize(rsp);
68414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
68514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
68614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
68714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
6882c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville     * Handle RIL_REQUEST_DATA_REGISTRATION_STATE
68914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
69014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
69114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
6922c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    this.rilRequestDataRegistrationState = function(req) { // 21
6932c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        print('Radio: rilRequestDataRegistrationState');
69414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
69514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var rsp = new Object();
69614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings = Array();
69714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[0] = registrationState;
69814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[1] = lac;
69914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[2] = cid;
70014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[3] = radioTechnology;
70114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
70214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        result.responseProtobuf = rilSchema[packageNameAndSeperator +
70314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                 'RspStrings'].serialize(rsp);
70414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
70514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
70614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
70714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
708bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     * Handle RIL_REQUEST_ANSWER
709bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     *
710bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     * @param req is the Request
711bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     */
712bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang    this.rilRequestAnswer = function(req) { // 40
713bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang        print('Radio: rilRequestAnswer');
714bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
715bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang        if (numberActiveCalls != 1) {
716bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang            result.rilErrCode = RIL_E_GENERIC_FAILURE;
717bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang            return result;
718bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang        } else {
719bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang            for (var i = 0; i < calls.length; i++) {
720bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                if (typeof calls[i] != 'undefined') {
721bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                    if (calls[i].state == CALLSTATE_INCOMING) {
722bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                        calls[i].state = CALLSTATE_ACTIVE;
723bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                        break;
724bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                    } else {
725bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                        result.rilErrCode = RIL_E_GENERIC_FAILURE;
726bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                        this.removeCall(i);
727bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                        return result;
728bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                    }
729bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                } // end of processing call[i]
730bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang            } // end of for
731bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang        }
732230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang        incomingCallIsProcessed = true;
733bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang        return result;
734bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang    }
735bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
736bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang    /**
73714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE
73814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
73914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
74014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
74114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestQueryNeworkSelectionMode = function(req) { // 45
74214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestQueryNeworkSelectionMode');
74314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
74414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var rsp = new Object();
74514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.integers = Array();
74614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.integers[0] = networkSelectionMode;
74714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
74814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        result.responseProtobuf = rilSchema[packageNameAndSeperator +
74914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                 'RspIntegers'].serialize(rsp);
75014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
75114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
75214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
75314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
75414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC
75514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
75614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
75714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
75814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestSetNeworkSelectionAutomatic = function(req) { // 46
75914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestSetNeworkSelectionAutomatic');
76014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
76114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        networkSelectionMode = NETWORK_SELECTION_MODE_AUTOMATIC;
76214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
76314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
76414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
76514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
76614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
76714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_BASE_BAND_VERSION
76814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
76914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
77014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
77114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestBaseBandVersion = function(req) { // 51
77214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestBaseBandVersion');
77314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var rsp = new Object();
77414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings = Array();
77514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        rsp.strings[0] = gBaseBandVersion;
77614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
77714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        result.responseProtobuf = rilSchema[packageNameAndSeperator +
77814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                 'RspStrings'].serialize(rsp);
77914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
78014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
78114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
78214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
78314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_SEPRATE_CONNECTION
78414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Separate a party from a multiparty call placing the multiparty call
78514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * (less the specified party) on hold and leaving the specified party
78614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * as the only other member of the current (active) call
78714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
78814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * See TS 22.084 1.3.8.2 (iii)
78914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
79014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
79114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
79214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilReqestSeparateConnection = function(req) {  // 52
79314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilReqestSeparateConnection');
79414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        var index = req.data.index;
79514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
79614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (numberActiveCalls <= 0) {
79714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.rilErrCode = RIL_E_GENERIC_FAILURE;
79814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            return result;
79914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        } else {
80014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            // get the connection to separate
80114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            var separateConn = this.getCall(req.data.index);
80214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if (separateConn == null) {
80314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                result.rilErrCode = RIL_E_GENERIC_FAILURE;
80414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                return result;
80514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            } else {
80614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                if (separateConn.state != CALLSTATE_ACTIVE) {
80714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    result.rilErrCode = RIL_E_GENERIC_FAILURE;
80814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    return result;
80914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                }
81014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                // Put all other connections in hold.
81114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                for (var i = 0; i < calls.length; i++) {
81214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    if (index != i) {
81314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        // put all the active call to hold
81414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        if (typeof calls[i] != 'undefined') {
81514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            switch (calls[i].state) {
81614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                case CALLSTATE_ACTIVE:
81714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                    calls[i].state = CALLSTATE_HOLDING;
81814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                    break;
81914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                default:
82014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                    result.rilErrCode = RIL_E_GENERIC_FAILURE;
82114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                    break;
82214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            }
82314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            this.printCalls(calls);
82414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
82514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                                return result;
82614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                            }
82714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                        }  // end of processing call[i]
82814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    }
82914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                }  // end of for
83014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
83114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
83214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
83314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
83414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        simulatedRadioWorker.add(
83514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang          {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
83614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
83714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
83814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
83914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
84014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_SET_MUTE
84114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
84214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestSetMute = function(req) { // 53
84314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestSetMute: req.data.state=' + req.data.state);
84414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        muteState = req.data.state;
84514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        if (gRadioState == RADIOSTATE_UNAVAILABLE) {
84614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.rilErrCode = RIL_E_RADIO_NOT_AVAILABLE;
84714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
84814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
84914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
85014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
85114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
85214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Handle RIL_REQUEST_SCREEN_STATE
85314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     *
85414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * @param req is the Request
85514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
85614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.rilRequestScreenState = function(req) { // 61
85714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        print('Radio: rilRequestScreenState: req.data.state=' + req.data.state);
85814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        screenState = req.data.state;
85914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        return result;
86014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
86114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
86214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
86314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Delay test
86414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
86514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     this.cmdDelayTest = function(req) { // 2000
86614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         print('cmdDelayTest: req.hello=' + req.hello);
86714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         result.sendResponse = false;
86814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         return result;
86914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     }
87014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
87114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     /**
87214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      * Delay for RIL_UNSOL_SIGNAL_STRENGTH
87314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      * TODO: Simulate signal strength changes:
87414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      * Method 1: provide an array for signal strength, and send the unsolicited
87514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      *           reponse periodically (the period can also be simulated)
87614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      * Method 2: Simulate signal strength randomly (within a certain range) and
87714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      *           send the response periodically.
87814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      */
87914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     this.cmdUnsolSignalStrength = function(req) { // 2001
88014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         print('cmdUnsolSignalStrength: req.reqNum=' + req.reqNum);
88114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         var rsp = new Object();
88214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
88314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // pack the signal strength into RspSignalStrength
88414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         rsp.gwSignalstrength = gwSignalStrength;
88514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         rsp.cdmaSignalstrength = cdmaSignalStrength;
88614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         rsp.evdoSignalstrength = evdoSignalStrength;
88714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
88814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         response = rilSchema[packageNameAndSeperator +
88914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                              'RspSignalStrength'].serialize(rsp);
89014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
89114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // upldate signal strength
89214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         sendRilUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH, response);
89314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
89414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // Send the unsolicited signal strength every 1 minute.
89514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         simulatedRadioWorker.addDelayed(
89614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang             {'reqNum' : CMD_UNSOL_SIGNAL_STRENGTH}, 60000);
89714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
89814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // this is not a request, no response is needed
89914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         result.sendResponse = false;
90014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         return result;
90114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     }
90214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
90314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     /**
90414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      * Send RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
90514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      */
90614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     this.cmdUnsolCallStateChanged = function(req) { // 2002
90714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         print('cmdUnsolCallStateChanged: req.reqNum=' + req.reqNum);
90814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         sendRilUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
90914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         result.sendResponse = false;
91014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         return result;
91114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     }
91214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
91314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     /**
91414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      * Simulate call state change
91514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang      */
91614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     this.cmdCallStateChange = function(req) { // 2003
91714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         print('cmdCallStateChange: req.reqNum=' + req.reqNum);
91814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         print('cmdCallStateChange: req.callType=' + req.callType);
91914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         print('cmdCallStateChange: req.callIndex=' + req.callIndex);
92014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         print('cmdCallStateChange: req.nextState=' + req.nextState);
92114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
92214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // if it is an outgoing call, update the call state of the call
92314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // Send out call state changed flag
92414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         var curCall = this.getCall(req.callIndex);
92514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         this.printCall(curCall);
92614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
92714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         if (curCall != null) {
92814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang             curCall.state = req.nextState;
92914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         } else {
93014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang             this.removeCall(req.callIndex);
93114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         }
93214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
93314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // TODO: if it is an incoming call, update the call state of the call
93414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // Send out call state change flag
93514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         // Send out RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
93614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         simulatedRadioWorker.add(
93714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang           {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
93814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         result.sendResponse = false;
93914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang         return result;
94014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     }
941bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
942bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     /**
943bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang      * send UNSOL_CALL_STATE_CHANGED and UNSOL_CALL_RING
944bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang      */
945bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     this.cmdUnsolCallRing = function(req) { // 2004
946bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         print('cmdUnsolCallRing: req.reqNum=' + req.reqNum);
947230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang         if(!incomingCallIsProcessed) {
948230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang             sendRilUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
949230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang             sendRilUnsolicitedResponse(RIL_UNSOL_CALL_RING);
950bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
951230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang             // Send the next alert in 3 seconds. [refer to ril.h definition]
952230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang             simulatedRadioWorker.addDelayed(
953230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang                 {'reqNum' : CMD_UNSOL_CALL_RING}, 3000);
954230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang         }
955bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         result.sendResponse = false;
956bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         return result;
957bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     }
958bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
959bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     /**
960bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang      * Create an incoming call for the giving number
961bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang      * return CTRL_STATUS_ERR if there is already a call in any of the states of
962bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang      * dialing, alerting, incoming, waiting [TS 22 030 6.5] , else
963bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang      * return CTRL_STATUS_OK and update the call state
964bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang      */
965bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang     this.ctrlServerCmdStartInComingCall = function(req) {  // 1001
966bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         print('ctrlServerCmdStartInComingCall: req.reqNum:' + req.reqNum);
967bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         print('ctrlServerCmdStartInComingCall: req.data.phonenumber:' + req.data.phoneNumber);
968bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
969bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         var phoneNumber = req.data.phoneNumber;
970bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         var state;
971bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
972bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         if (numberActiveCalls <= 0) {
973bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang             // If there is no connection in use, the call state is INCOMING
974bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang             state = CALLSTATE_INCOMING;
975bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         } else {
976bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang             // If there is call in any of the states of dialing, alerting, incoming
977bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang             // waiting, this MT call can not be set
978bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang             for (var i  = 0; i < calls.length; i++) {
979bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                 if (typeof calls[i] != 'undefined') {
980bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                     if ( (calls[i].state == CALLSTATE_DIALING) ||
981bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                          (calls[i].state == CALLSTATE_ALERTING) ||
982bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                          (calls[i].state == CALLSTATE_INCOMING) ||
983bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                          (calls[i].state == CALLSTATE_WAITING))
984bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                     {
985bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                         result.rilErrCode = CTRL_STATUS_ERR;
986bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                         return result;
987bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                     }
988bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                 }
989bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang             }
990bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang             // If the incoming call is a second call, the state is WAITING
991bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang             state = CALLSTATE_WAITING;
992bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         }
993bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
994bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         // Add call to the call array
995bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         this.addCall(state, phoneNumber, '');
996bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
997230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang         // set the incomingCallIsProcessed flag to be false
998230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang         incomingCallIsProcessed = false;
999bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
1000bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         simulatedRadioWorker.add(
1001bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang           {'reqNum' : CMD_UNSOL_CALL_RING});
1002bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
1003bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         result.rilErrCode = CTRL_STATUS_OK;
1004bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang         return result;
10052b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
10062b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10072b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    /**
10082b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * Handle control command CTRL_CMD_HANGUP_CONN_REMOTE
10092b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     *   hangup the connection for the given failure cause
10102b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     *
10112b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     *@param req is the control request
10122b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     */
10132b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.ctrlServerCmdHangupConnRemote = function(req) {    // 1002
10142b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        print('ctrlServerCmdHangupConnRemote: req.data.connectionId=' + req.data.connectionId +
10152b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang              ' req.data.callFailCause' + req.data.callFailCause);
10162b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10172b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var connection = req.data.connectionId;
10182b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var failureCause = req.data.callFailCause;
10192b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10202b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        this.printCalls(calls);
10212b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var hangupCall = this.removeCall(connection);
10222b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if (hangupCall == null) {
10232b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('ctrlServerCmdHangupConnRemote: connection id is required.');
10242b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_ERR;
10252b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return result;
10262b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        } else {
10272b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            // for incoming call, stop sending call ring
10282b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            if ((hangupCall.state == CALLSTATE_INCOMING) ||
10292b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                (hangupCall.state == CALLSTATE_WAITING)) {
1030230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang                incomingCallIsProcessed = true;
10312b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            }
10322b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
10332b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        this.printCalls(calls);
10342b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        lastCallFailCause = failureCause;
10352b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10362b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        // send out call state changed response
10372b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        simulatedRadioWorker.add(
10382b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
10392b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10402b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        result.rilErrCode = CTRL_STATUS_OK;
10412b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        return result;
10422b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
10432b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10442b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    /**
10452b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * Set call transition flag
10462b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     */
10472b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.ctrlServerCmdSetCallTransitionFlag = function(req) {  // 1003
10482b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        print('ctrlServerCmdSetCallTransitionFlag: flag=' + req.data.flag);
10492b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10502b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        callTransitionFlag = req.data.flag;
10512b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        result.rilErrCode = CTRL_STATUS_OK;
10522b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        return result;
10532b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
10542b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10552b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    /**
10562b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * Set the dialing call to alert
10572b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     */
10582b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.ctrlServerCmdSetCallAlert = function(req) {    // 1004
10592b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        print('ctrlServerCmdSetCallAlert: E');
10602b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10612b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if (callTransitionFlag == false) {
10622b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('ctrlServerCmdSetCallAlert: need to set the flag first');
10632b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_ERR;
10642b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return result;
10652b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
10662b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if (numberActiveCalls <= 0) {
10672b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('ctrlServerCmdSetCallAlert: no active calls');
10682b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_ERR;
10692b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return result;
10702b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
10712b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var dialingCalls = this.countCallsInState(CALLSTATE_DIALING);
10722b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var index = this.getCallIdByState(CALLSTATE_DIALING);
10732b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if ((dialingCalls == 1) && (index != null)) {
10742b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            calls[index].state = CALLSTATE_ALERTING;
10752b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        } else {
10762b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            // if there 0 or more than one call in dialing state, return error
10772b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('ctrlServerCmdSetCallAlert: no valid calls in dialing state');
10782b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_ERR;
10792b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return result;
10802b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
10812b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        // send unsolicited call state change response
10822b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        simulatedRadioWorker.add(
10832b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
10842b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10852b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        result.rilErrCode = CTRL_STATUS_OK;
10862b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        return result;
10872b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
10882b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10892b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    /**
10902b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * Set the alserting call to active
10912b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     */
10922b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.ctrlServerCmdSetCallActive = function(req) {   // 1005
10932b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        print('ctrlServerCmdSetCallActive: E');
10942b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
10952b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if (callTransitionFlag == false) {
10962b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('ctrlServerCmdSetCallActive: need to set the flag firt');
10972b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_ERR;
10982b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return result;
10992b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
11002b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if (numberActiveCalls <= 0) {
11012b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('ctrlServerCmdSetCallActive: no active calls');
11022b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_ERR;
11032b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return result;
11042b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
11052b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var alertingCalls = this.countCallsInState(CALLSTATE_ALERTING);
11062b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var index = this.getCallIdByState(CALLSTATE_ALERTING);
11072b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if ((alertingCalls == 1) && (index != null)) {
11082b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            calls[index].state = CALLSTATE_ACTIVE;
11092b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        } else {
11102b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('ctrlServerCmdSetCallActive: no valid calls in alert state');
11112b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_ERR;
11122b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            return result;
11132b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
11142b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        // send out unsolicited call state change response
11152b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        simulatedRadioWorker.add(
11162b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
11172b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
11182b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        result.rilErrCode = CTRL_STATUS_OK;
11192b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        return result;
11202b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
11212b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
11222b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    /**
11232b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     * Add a dialing call
11242b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang     */
11252b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.ctrlServerCmdAddDialingCall = function(req) {   // 1006
11262b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        print('ctrlServerCmdAddDialingCall: E');
11272b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang
11282b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var phoneNumber = req.data.phoneNumber;
11292b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        var dialingCalls = this.countCallsInState(CALLSTATE_DIALING);
11302b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        if (dialingCalls == 0) {
11312b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            this.addCall(CALLSTATE_DIALING, phoneNumber, '');
11322b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_OK;
11332b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        } else {
11342b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('ctrlServerCmdAddDialingCall: add dialing call failed');
11352b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            result.rilErrCode = CTRL_STATUS_ERR;
11362b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        }
11372b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang        return result;
11382b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    }
1139bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
114014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
114114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Process the request by dispatching to the request handlers
114214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
114314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.process = function(req) {
114414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        try {
11452b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang            print('Radio E: req.reqNum=' + req.reqNum + ' req.token=' + req.token);
114614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
114714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            // Assume the result will be true, successful and nothing to return
114814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.sendResponse = true;
114914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.rilErrCode = RIL_E_SUCCESS;
115014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            result.responseProtobuf = emptyProtobuf;
115114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
115214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            try {
115314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                // Pass "this" object to each ril request call such that
115414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                // they have the same scope
1155230e5a78415e41e7e41f087e369a589ca8d9c83eXia Wang                result = (this.radioDispatchTable[req.reqNum]).call(this, req);
115614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            } catch (err) {
115714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                print('Radio:process err = ' + err);
115814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                print('Radio: Unknown reqNum=' + req.reqNum);
115914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                result.rilErrCode = RIL_E_REQUEST_NOT_SUPPORTED;
116014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
116114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
116214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if (req.reqNum < 200) {
116314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                lastReq = req.reqNum;
116414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
116514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            if (result.sendResponse) {
1166bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                if (isCtrlServerDispatchCommand(req.reqNum)) {
11672b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                    //print('Command ' + req.reqNum + ' is a control server command');
1168bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                    sendCtrlRequestComplete(result.rilErrCode, req.reqNum,
1169bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                      req.token, result.responseProtobuf);
1170bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                } else {
11712b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                    //print('Request ' + req.reqNum + ' is a ril request');
1172bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                    sendRilRequestComplete(result.rilErrCode, req.reqNum,
1173bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                      req.token, result.responseProtobuf);
1174bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                }
117514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            }
117614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            //print('Radio X: req.reqNum=' + req.reqNum + ' req.token=' + req.token);
117714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        } catch (err) {
117814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang            print('Radio: Exception req.reqNum=' +
117914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                    req.reqNum + ' req.token=' + req.token + ' err=' + err);
118014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang        }
118114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    }
118214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
118314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    /**
118414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     * Construct the simulated radio
118514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang     */
118614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    print('Radio: constructor E');
118714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable = new Array();
118814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_GET_CURRENT_CALLS] = // 9
118914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestGetCurrentCalls;
119014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_DIAL] = // 10
119114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestDial;
119214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_HANGUP] =  // 12
119314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestHangUp;
119414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND] = // 13
119514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestHangupWaitingOrBackground;
119614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] =  // 14
119714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestHangUpForegroundResumeBackground;
119814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] =  // 15
119914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestSwitchWaitingOrHoldingAndActive;
120014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_CONFERENCE] = // 16
120114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestConference;
12022b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.radioDispatchTable[RIL_REQUEST_LAST_CALL_FAIL_CAUSE] = // 18
12032b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                this.rilRequestLastCallFailCause;
120414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_SIGNAL_STRENGTH] = // 19
120514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestSignalStrength;
12062c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    this.radioDispatchTable[RIL_REQUEST_VOICE_REGISTRATION_STATE] = // 20
12072c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                this.rilRequestVoiceRegistrationState;
12082c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    this.radioDispatchTable[RIL_REQUEST_DATA_REGISTRATION_STATE] = // 21
12092c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                this.rilRequestDataRegistrationState;
1210bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang    this.radioDispatchTable[RIL_REQUEST_ANSWER] = // 40
1211bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                this.rilRequestAnswer;
121214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE] = // 45
121314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestQueryNeworkSelectionMode;
121414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC] = // 46
121514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestSetNeworkSelectionAutomatic;
121614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_BASEBAND_VERSION] = // 51
121714171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestBaseBandVersion;
121814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_SEPARATE_CONNECTION] = // 52
121914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilReqestSeparateConnection;
122014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_SET_MUTE] = // 53
122114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestSetMute;
122214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[RIL_REQUEST_SCREEN_STATE] = // 61
122314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.rilRequestScreenState;
122414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
1225bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang    this.radioDispatchTable[CTRL_CMD_SET_MT_CALL] = //1001
1226bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                this.ctrlServerCmdStartInComingCall;
12272b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.radioDispatchTable[CTRL_CMD_HANGUP_CONN_REMOTE] = //1002
12282b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                this.ctrlServerCmdHangupConnRemote;
12292b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.radioDispatchTable[CTRL_CMD_SET_CALL_TRANSITION_FLAG] = //1003
12302b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                this.ctrlServerCmdSetCallTransitionFlag;
12312b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.radioDispatchTable[CTRL_CMD_SET_CALL_ALERT] =  // 1004
12322b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                this.ctrlServerCmdSetCallAlert;
12332b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.radioDispatchTable[CTRL_CMD_SET_CALL_ACTIVE] =  // 1005
12342b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                this.ctrlServerCmdSetCallActive;
12352b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang    this.radioDispatchTable[CTRL_CMD_ADD_DIALING_CALL] =  // 1006
12362b7b0f7d61dd1ee99722e27b51810fe51de92f0fXia Wang                this.ctrlServerCmdAddDialingCall;
1237bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
123814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[CMD_DELAY_TEST] = // 2000
123914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.cmdDelayTest;
124014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[CMD_UNSOL_SIGNAL_STRENGTH] =  // 2001
124114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.cmdUnsolSignalStrength;
124214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[CMD_UNSOL_CALL_STATE_CHANGED] =  // 2002
124314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.cmdUnsolCallStateChanged;
124414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    this.radioDispatchTable[CMD_CALL_STATE_CHANGE] = //2003
124514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang                this.cmdCallStateChange;
1246bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang    this.radioDispatchTable[CMD_UNSOL_CALL_RING] = //2004
1247bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang                this.cmdUnsolCallRing;
1248bf40f252c66f13c51fb113c343e1728f8a86662aXia Wang
124914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    print('Radio: constructor X');
125014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang}
125114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
125214171dca025273fb64b239c1ec86ed7d4b677343Xia Wang// The simulated radio instance and its associated Worker
125314171dca025273fb64b239c1ec86ed7d4b677343Xia Wangvar simulatedRadio = new Radio();
125414171dca025273fb64b239c1ec86ed7d4b677343Xia Wangvar simulatedRadioWorker = new Worker(function (req) {
125514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    simulatedRadio.process(req);
125614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang});
125714171dca025273fb64b239c1ec86ed7d4b677343Xia WangsimulatedRadioWorker.run();
125814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
125914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang// TODO: this is a workaround for bug http://b/issue?id=3001613
126014171dca025273fb64b239c1ec86ed7d4b677343Xia Wang// When adding a new all, two RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE
126114171dca025273fb64b239c1ec86ed7d4b677343Xia Wang// will be sent from the framework.
126214171dca025273fb64b239c1ec86ed7d4b677343Xia Wangvar lastReq = 0;
126314171dca025273fb64b239c1ec86ed7d4b677343Xia Wang
126414171dca025273fb64b239c1ec86ed7d4b677343Xia Wang/**
126514171dca025273fb64b239c1ec86ed7d4b677343Xia Wang * Optional tests
126614171dca025273fb64b239c1ec86ed7d4b677343Xia Wang */
126714171dca025273fb64b239c1ec86ed7d4b677343Xia Wangif (false) {
126814171dca025273fb64b239c1ec86ed7d4b677343Xia Wang    include("simulated_radio_tests.js");
126914171dca025273fb64b239c1ec86ed7d4b677343Xia Wang}
1270