Home | History | Annotate | Download | only in js
      1 /**
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /**
     18  * The Radio object contains a set of methods and objects to handle ril request
     19  * which is passed from simulatedRadioWorker queue. The global object initialize
     20  * an instance of Radio object by calling "new Radio". For each ril request,
     21  * rilDispatchTable gets searched and the corresponding method is called.
     22  * Extra requests are also defined to process unsolicited rerequests.
     23  *
     24  * The rilDispatchTable is an array indexed by RIL_REQUEST_* or REQUEST_UNSOL_*,
     25  * in which each request corresponds to a functions defined in the Radio object.
     26  * We need to pay attention when using "this" within those functions. When they are
     27  * called in "this.process" using
     28  *               result = this.radioDispatchTable[req.reqNum])(req);
     29  * this scope of "this" within those functions are the radioDispatchTable, not the
     30  * object that "this.process" belongs to. Using "this." to access other
     31  * functions in the object may cause trouble.
     32  * To avoid that, the object is passed in when those functions are called as
     33  * shown in the following:
     34  *                 result = (this.radioDispatchTable[req.reqNum]).call(this, req);
     35  */
     36 
     37 /**
     38  * Set radio state
     39  */
     40 function setRadioState(newState) {
     41     newRadioState = newState;
     42     if (typeof newState == 'string') {
     43         newRadioState = globals[newState];
     44         if (typeof newRadioState == 'undefined') {
     45             throw('setRadioState: Unknow string: ' + newState);
     46         }
     47     }
     48     if ((newRadioState < RADIOSTATE_OFF) || (newRadioState > RADIOSTATE_NV_READY)) {
     49         throw('setRadioState: newRadioState: ' + newRadioState + ' is invalid');
     50     }
     51     gRadioState = newRadioState;
     52     sendRilUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED);
     53 }
     54 
     55 /**
     56  * Create a call.
     57  *
     58  * @return a RilCall
     59  */
     60 function RilCall(state, phoneNumber, callerName) {
     61     this.state = state;
     62     this.index = 0;
     63     this.toa = 0;
     64     this.isMpty = false;
     65     this.isMt = false;
     66     this.als = 0;
     67     this.isVoice = true;
     68     this.isVoicePrivacy = false;
     69     this.number = phoneNumber;
     70     this.numberPresentation = 0;
     71     this.name = callerName;
     72 }
     73 
     74 /**
     75  * Simulated Radio
     76  */
     77 function Radio() {
     78     var registrationState = '1';
     79     var lac = '0';
     80     var cid = '0';
     81     var radioTechnology = '3';
     82     var baseStationId = NULL_RESPONSE_STRING;
     83     var baseStationLatitude = NULL_RESPONSE_STRING;
     84     var baseStationLongitude = NULL_RESPONSE_STRING;
     85     var concurrentServices = NULL_RESPONSE_STRING;
     86     var systemId  = NULL_RESPONSE_STRING;
     87     var networkId = NULL_RESPONSE_STRING;
     88     var roamingIndicator = NULL_RESPONSE_STRING;
     89     var prlActive = NULL_RESPONSE_STRING;
     90     var defaultRoamingIndicator = NULL_RESPONSE_STRING;
     91     var registrationDeniedReason = NULL_RESPONSE_STRING;
     92     var primaryScrambingCode = NULL_RESPONSE_STRING;
     93 
     94     var NETWORK_SELECTION_MODE_AUTOMATIC = 0;
     95     var NETWORK_SELECTION_MODE_MANUAL = 1;
     96     var networkSelectionMode = NETWORK_SELECTION_MODE_AUTOMATIC;
     97 
     98     var muteState = 0;   // disable mute
     99 
    100     // Number of active calls in calls
    101     var numberActiveCalls = 0;
    102 
    103     // Maximum number of active calls
    104     var maxNumberActiveCalls = 7;
    105     var maxConnectionsPerCall = 5; // only 5 connections allowed per call
    106 
    107     // Flag to denote whether an incoming/waiting call is answered
    108     var incomingCallIsProcessed = false;
    109 
    110     // Call transition flag
    111     var callTransitionFlag = false;  // default to auto-transition
    112 
    113     var lastCallFailCause = 0;
    114 
    115     // Array of "active" calls
    116     var calls = Array(maxNumberActiveCalls + 1);
    117 
    118     // The result returned by the request handlers
    119     var result = new Object();
    120 
    121     function GWSignalStrength() {
    122         this.signalStrength = 10;  // 10 * 2 + (-113) = -93dBm, make it three bars
    123         this.bitErrorRate = 0;
    124     }
    125 
    126     function CDMASignalStrength() {
    127         this.dbm = -1;
    128         this.ecio = -1;
    129     }
    130 
    131     function EVDOSignalStrength() {
    132         this.dbm = -1;
    133         this.ecio = -1;
    134         this.signalNoiseRatio = 0;
    135     }
    136 
    137     function LTESignalStrength() {
    138         this.signalStrength = -1;
    139         this.rsrp = 0;
    140         this.rsrq = 0;
    141         this.rssnr = 0;
    142         this.cqi = 0;
    143     }
    144 
    145     var gwSignalStrength = new GWSignalStrength;
    146     var cdmaSignalStrength = new CDMASignalStrength();
    147     var evdoSignalStrength = new EVDOSignalStrength();
    148     var lteSignalStrength = new LTESignalStrength();
    149 
    150     /**
    151      * The the array of calls, this is a sparse
    152      * array and some elements maybe 'undefined'.
    153      *
    154      * @return Array of RilCall's
    155      */
    156     this.getCalls =  function() {
    157         return calls;
    158     }
    159 
    160     /**
    161      * @return the RilCall at calls[index] or null if undefined.
    162      */
    163     this.getCall = function(index) {
    164         var c = null;
    165         try {
    166             c = calls[index];
    167             if (typeof c == 'undefined') {
    168                 c = null;
    169             }
    170         } catch (err) {
    171             c = null;
    172         }
    173         return c;
    174     }
    175 
    176     /**
    177      * @return the first call that is in the given state
    178      */
    179     this.getCallIdByState = function(callState) {
    180         if ((callState < CALLSTATE_ACTIVE) || (callState > CALLSTATE_WAITING)) {
    181             return null;
    182         }
    183         for (var i = 0; i < calls.length; i++) {
    184             if (typeof calls[i] != 'undefined') {
    185                 if (calls[i].state == callState) {
    186                     return i;
    187                 }
    188             }
    189         }
    190         return null;
    191     }
    192 
    193     /** Add an active call
    194      *
    195      * @return a RilCall or null if too many active calls.
    196      */
    197     this.addCall = function(state, phoneNumber, callerName) {
    198         print('Radio: addCall');
    199         var c = null;
    200         if (numberActiveCalls < maxNumberActiveCalls) {
    201             numberActiveCalls += 1;
    202             c = new RilCall(state, phoneNumber, callerName);
    203             // call index should fall in the closure of [1, 7]
    204             // Search for an "undefined" element in the array and insert the call
    205             for (var i = 1; i < (maxNumberActiveCalls + 1); i++) {
    206                 print('Radio: addCall, i=' + i);
    207                 if (typeof calls[i] == 'undefined') {
    208                     print('Radio: addCall, calls[' + i + '] is undefined');
    209                     c.index = i;
    210                     calls[i] = c;
    211                     break;
    212                 }
    213             }
    214             this.printCalls(calls);
    215         }
    216         return c;
    217     }
    218 
    219     /**
    220      * Remove the call, does nothing if the call is undefined.
    221      *
    222      * @param index into calls to remove.
    223      * @return the call removed or null if did not exist
    224      */
    225     this.removeCall =  function(index) {
    226         var c = null;
    227         if ((numberActiveCalls > 0)
    228                  && (index < calls.length)
    229                  && (typeof calls[index] != 'undefined')) {
    230             c = calls[index];
    231             delete calls[index];
    232             numberActiveCalls -= 1;
    233             if (numberActiveCalls == 0) {
    234                 calls = new Array();
    235             }
    236         } else {
    237             c = null;
    238         }
    239         return c;
    240     }
    241 
    242     /**
    243      * Print the call
    244      *
    245      * @param c is the RilCall to print
    246      */
    247     this.printCall = function(c) {
    248         if ((c != null) && (typeof c != 'undefined')) {
    249             print('c[' + c.index + ']: index=' + c.index + ' state=' + c.state +
    250                   ' number=' + c.number + ' name=' + c.name);
    251         }
    252     }
    253 
    254     /**
    255      * Print all the calls.
    256      *
    257      * @param callArray is an Array of RilCall's
    258      */
    259     this.printCalls = function(callArray) {
    260         if (typeof callArray == 'undefined') {
    261             callArray = calls;
    262         }
    263         print('callArray.length=' + callArray.length);
    264         for (var i = 0; i < callArray.length; i++) {
    265             if ((callArray[i] == null) || (typeof callArray[i] == 'undefined')) {
    266                 print('c[' + i + ']: undefined');
    267             } else {
    268                 this.printCall(callArray[i]);
    269             }
    270         }
    271     }
    272 
    273     /**
    274      * Count number of calls in the given state
    275      *
    276      * @param callState is the give state
    277      */
    278     this.countCallsInState = function(callState) {
    279         var count = 0;
    280         if ((callState < CALLSTATE_ACTIVE) || (callState > CALLSTATE_WAITING)) {
    281             // not a valid call state
    282             return null;
    283         }
    284         for (var i = 0; i < calls.length; i++) {
    285             if (typeof calls[i] != 'undefined') {
    286                 if (calls[i].state == callState) {
    287                     count++;
    288                 }
    289             }
    290         }
    291         return count;
    292     }
    293 
    294     /**
    295      * Print signal strength
    296      */
    297     this.printSignalStrength = function() {
    298         print('rssi: '         + gwSignalStrength.signalStrength);
    299         print('bitErrorRate: ' + gwSignalStrength.bitErrorRate);
    300         print('cdmaDbm: '  +  cdmaSignalStrength.dbm);
    301         print('cdmaEcio: ' + cdmaSignalStrength.ecio);
    302         print('evdoRssi: ' + evdoSignalStrength.dbm);
    303         print('evdoEcio: ' + evdoSignalStrength.ecio);
    304         print('evdoSnr: '  + evdoSignalStrength.signalNoiseRatio);
    305         print('lteRssi: '  + lteSignalStrength.signalStrength);
    306         print('lteRsrp: '  + lteSignalStrength.rsrp);
    307         print('lteRsrq: '  + lteSignalStrength.rsrq);
    308         print('lteRssnr: ' + lteSignalStrength.rssnr);
    309         print('lteCqi: '   + lteSignalStrength.cqi);
    310     }
    311 
    312     /**
    313      * set signal strength
    314      *
    315      * @param rssi and bitErrorRate are signal strength parameters for GSM
    316      *        cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr are parameters for CDMA & EVDO
    317      */
    318     this.setSignalStrength = function(rssi, bitErrorRate, cdmaDbm, cdmaEcio, evdoRssi,
    319                                       evdoEcio, evdoSnr, lteSigStrength, lteRsrp,
    320                                       lteRsrq, lteRssnr, lteCqi) {
    321         print('setSignalStrength E');
    322 
    323         if (rssi != 99) {
    324             if ((rssi < 0) || (rssi > 31)) {
    325                 throw ('not a valid signal strength');
    326             }
    327         }
    328         // update signal strength
    329         gwSignalStrength.signalStrength = rssi;
    330         gwSignalStrength.bitErrorRate = bitErrorRate;
    331         cdmaSignalStrength.dbm = cdmaDbm;
    332         cdmaSignalStrength.ecio = cdmaEcio;
    333         evdoSignalStrength.dbm = evdoRssi;
    334         evdoSignalStrength.ecio = evdoEcio;
    335         evdoSignalStrength.signalNoiseRatio = evdoSnr;
    336         lteSignalStrength.signalStrength = lteSigStrength;
    337         lteSignalStrength.rsrp = lteRsrp;
    338         lteSignalStrength.rsrq = lteRsrq;
    339         lteSignalStrength.rssnr = lteRssnr;
    340         lteSignalStrength.cqi = lteCqi;
    341 
    342         // pack the signal strength into RspSignalStrength and send a unsolicited response
    343         var rsp = new Object();
    344 
    345         rsp.gwSignalstrength = gwSignalStrength;
    346         rsp.cdmSignalstrength = cdmaSignalStrength;
    347         rsp.evdoSignalstrength = evdoSignalStrength;
    348         rsp.lteSignalstrength = lteSignalStrength;
    349 
    350         var response = rilSchema[packageNameAndSeperator +
    351                              'RspSignalStrength'].serialize(rsp);
    352 
    353         sendRilUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH, response);
    354 
    355         // send the unsolicited signal strength every 1 minute.
    356         simulatedRadioWorker.addDelayed(
    357             {'reqNum' : CMD_UNSOL_SIGNAL_STRENGTH}, 60000);
    358         print('setSignalStrength X');
    359     }
    360 
    361     /**
    362      * Handle RIL_REQUEST_GET_CURRENT_CALL
    363      *
    364      * @param req is the Request
    365      */
    366     this.rilRequestGetCurrentCalls = function(req) { // 9
    367         print('Radio: rilRequestGetCurrentCalls E');
    368         var rsp = new Object();
    369 
    370         // pack calls into rsp.calls
    371         rsp.calls = new Array();
    372         var i;
    373         var j;
    374         for (i = 0, j = 0; i < calls.length; i++) {
    375             if (typeof calls[i] != 'undefined') {
    376                 rsp.calls[j++] = calls[i];
    377             }
    378         }
    379         result.responseProtobuf = rilSchema[packageNameAndSeperator +
    380                                             'RspGetCurrentCalls'].serialize(rsp);
    381         return result;
    382     }
    383 
    384     /**
    385      * Handle RIL_REQUEST_DIAL
    386      *
    387      * @param req is the Request
    388      */
    389     this.rilRequestDial = function(req) { // 10
    390         print('Radio: rilRequestDial E');
    391         var newCall = new Object();
    392         newCall = this.addCall(CALLSTATE_DIALING, req.data.address, '');
    393         if (newCall == null) {
    394             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    395             return result;
    396         }
    397         this.printCalls(calls);
    398 
    399         print('after add the call');
    400         // Set call state to dialing
    401         simulatedRadioWorker.add(
    402                         {'reqNum' : CMD_CALL_STATE_CHANGE,
    403                          'callType' : OUTGOING,
    404                          'callIndex' : newCall.index,
    405                          'nextState' : CALLSTATE_DIALING});
    406         if (!callTransitionFlag) {
    407             // for auto transition
    408             // Update call state to alerting after 1 second
    409             simulatedRadioWorker.addDelayed(
    410                 {'reqNum' : CMD_CALL_STATE_CHANGE,
    411                  'callType' : OUTGOING,
    412                  'callIndex' : newCall.index,
    413                  'nextState' : CALLSTATE_ALERTING}, 1000);
    414             // Update call state to active after 2 seconds
    415             simulatedRadioWorker.addDelayed(
    416                 {'reqNum' : CMD_CALL_STATE_CHANGE,
    417                  'callType' : OUTGOING,
    418                  'callIndex': newCall.index,
    419                  'nextState' : CALLSTATE_ACTIVE}, 2000);
    420         }
    421         return result;
    422     }
    423 
    424     /**
    425      * Handle RIL_REQUEST_HANG_UP
    426      *
    427      * @param req is the Request
    428      */
    429     this.rilRequestHangUp = function(req) { // 12
    430         print('Radio: rilRequestHangUp data.connection_index=' + req.data.connectionIndex);
    431         if (this.removeCall(req.data.connectionIndex) == null) {
    432             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    433             print('no connection to hangup');
    434         }
    435         return result;
    436     }
    437 
    438     /**
    439      * Handle RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND
    440      *        Hang up waiting or held
    441      *
    442      * @param req is the Request
    443      */
    444     this.rilRequestHangupWaitingOrBackground = function(req) { // 13
    445         print('Radio: rilRequestHangupWaitingOrBackground');
    446         if (numberActiveCalls <= 0) {
    447           result.rilErrCode = RIL_E_GENERIC_FAILURE;
    448         } else {
    449             for (var i = 0; i < calls.length; i++) {
    450                 if (typeof calls[i] != 'undefined') {
    451                     switch (calls[i].state) {
    452                         case CALLSTATE_HOLDING:
    453                         case CALLSTATE_WAITING:
    454                         case CALLSTATE_INCOMING:
    455                             this.removeCall(i);
    456                             incomingCallIsProcessed = true;
    457                             break;
    458                         default:
    459                             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    460                             break;
    461                     }
    462                     this.printCalls(calls);
    463                     if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
    464                         return result;
    465                     }
    466                 } // end of processing call[i]
    467             } // end of for
    468         }
    469         // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
    470         simulatedRadioWorker.add(
    471           {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
    472         return result;
    473     }
    474 
    475     /**
    476      * Handle RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
    477      *   release all active calls (if any exist) and resume held or waiting calls.
    478      * @param req is the Request
    479      */
    480     this.rilRequestHangUpForegroundResumeBackground = function(req) { //14
    481         print('Radio: rilRequestHangUpForegroundResumeBackground');
    482         if (numberActiveCalls <= 0) {
    483             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    484         } else {
    485             for (var i = 0; i < calls.length; i++) {
    486                 if (typeof calls[i] != 'undefined') {
    487                     switch (calls[i].state) {
    488                         case CALLSTATE_ACTIVE:
    489                             this.removeCall(i);
    490                             break;
    491                         case CALLSTATE_HOLDING:
    492                         case CALLSTATE_WAITING:
    493                           calls[i].state = CALLSTATE_ACTIVE;
    494                             break;
    495                         default:
    496                             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    497                             break;
    498                     }
    499                     this.printCalls(calls);
    500                     if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
    501                         return result;
    502                     }
    503                 } // end of processing call[i]
    504             }
    505         }
    506         // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
    507         simulatedRadioWorker.add(
    508           {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
    509         return result;
    510     }
    511 
    512     /**
    513      * Handle RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE
    514      *
    515      *     BEFORE                               AFTER
    516      * Call 1   Call 2                 Call 1       Call 2
    517      * ACTIVE   HOLDING                HOLDING     ACTIVE
    518      * ACTIVE   WAITING                HOLDING     ACTIVE
    519      * HOLDING  WAITING                HOLDING     ACTIVE
    520      * ACTIVE   IDLE                   HOLDING     IDLE
    521      * IDLE     IDLE                   IDLE        IDLE
    522      *
    523      * @param req is the Request
    524      */
    525     this.rilRequestSwitchWaitingOrHoldingAndActive = function(req) {  // 15
    526         print('Radio: rilRequestSwitchWaitingOrHoldingAndActive');
    527         print('Radio: lastReq = ' + lastReq);
    528         print('Radio: req.reqNum = ' + req.reqNum);
    529         if (lastReq == req.reqNum) {
    530             print('Radio: called twice');
    531             return result;
    532         }
    533 
    534         if (numberActiveCalls <= 0) {
    535             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    536         } else {
    537             for (var i = 0; i < calls.length; i++) {
    538                 if (typeof calls[i] != 'undefined') {
    539                     switch (calls[i].state) {
    540                         case CALLSTATE_ACTIVE:
    541                             calls[i].state = CALLSTATE_HOLDING;
    542                             break;
    543                         case CALLSTATE_HOLDING:
    544                         case CALLSTATE_WAITING:
    545                             calls[i].state = CALLSTATE_ACTIVE;
    546                             break;
    547                         default:
    548                             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    549                             break;
    550                     }
    551                     this.printCalls(calls);
    552                     if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
    553                         return result;
    554                     }
    555                 } // end of processing call[i]
    556             } // end of for
    557         }
    558         // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
    559         simulatedRadioWorker.add(
    560           {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
    561         return result;
    562     }
    563 
    564     /**
    565      * Handle RIL_REQUEST_CONFERENCE
    566      * Conference holding and active
    567      *
    568      * @param req is the Request
    569      */
    570     this.rilRequestConference = function(req) {  // 16
    571         print('Radio: rilRequestConference E');
    572         if ((numberActiveCalls <= 0) || (numberActiveCalls > maxConnectionsPerCall)) {
    573             // The maximum number of connections within a call is 5
    574             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    575             return result;
    576         } else {
    577             var numCallsInBadState = 0;
    578             for (var i = 0; i < calls.length; i++) {
    579                 if (typeof calls[i] != 'undefined') {
    580                     if ((calls[i].state != CALLSTATE_ACTIVE) &&
    581                             (calls[i].state != CALLSTATE_HOLDING)) {
    582                         numCallsInBadState++;
    583                     }
    584                 }
    585             }
    586 
    587             // if there are calls not in ACITVE or HOLDING state, return error
    588             if (numCallsInBadState > 0) {
    589                 result.rilErrCode = RIL_E_GENERIC_FAILURE;
    590                 return result;
    591             } else { // conference ACTIVE and HOLDING calls
    592                 for (var i = 0; i < calls.length; i++) {
    593                     if (typeof calls[i] != 'undefined') {
    594                         switch (calls[i].state) {
    595                             case CALLSTATE_ACTIVE:
    596                                 break;
    597                             case CALLSTATE_HOLDING:
    598                                 calls[i].state = CALLSTATE_ACTIVE;
    599                                 break;
    600                             default:
    601                                 result.rilErrCode = RIL_E_GENERIC_FAILURE;
    602                                 break;
    603                         }
    604                     }
    605                     this.printCalls(calls);
    606                     if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
    607                         return result;
    608                     }
    609                 }
    610             }
    611         }
    612 
    613         // Only if conferencing is successful,
    614         // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
    615         simulatedRadioWorker.add(
    616           {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
    617         return result;
    618     }
    619 
    620     /**
    621      * Handle RIL_REQUEST_LAST_CALL_FAIL_CAUSE
    622      *
    623      * @param req is the request
    624      */
    625     this.rilRequestLastCallFailCause = function(req) {
    626         print('Radio: rilRequestLastCallFailCause E');
    627 
    628         var rsp = new Object();
    629         rsp.integers = new Array();
    630         rsp.integers[0] = lastCallFailCause;
    631 
    632         result.responseProtobuf = rilSchema[packageNameAndSeperator +
    633                                             'RspIntegers'].serialize(rsp);
    634         return result;
    635     }
    636 
    637     /**
    638      * Handle RIL_REQUEST_SIGNAL_STRENGTH
    639      *
    640      * @param req is the Request
    641      */
    642     this.rilRequestSignalStrength = function(req) { // 19
    643         print('Radio: rilRequestSignalStrength E');
    644         var rsp = new Object();
    645 
    646         // pack the signal strength into RspSignalStrength
    647         rsp.gwSignalstrength = gwSignalStrength;
    648         rsp.cdmaSignalstrength = cdmaSignalStrength;
    649         rsp.evdoSignalstrength = evdoSignalStrength;
    650 
    651         result.responseProtobuf = rilSchema[packageNameAndSeperator +
    652                                             'RspSignalStrength'].serialize(rsp);
    653         return result;
    654     }
    655 
    656     /**
    657      * Handle RIL_REQUEST_VOICE_REGISTRATION_STATE
    658      *
    659      * @param req is the Request
    660      */
    661     this.rilRequestVoiceRegistrationState = function(req) { // 20
    662         print('Radio: rilRequestVoiceRegistrationState');
    663 
    664         var rsp = new Object();
    665         rsp.strings = Array();
    666         rsp.strings[0] = registrationState;
    667         rsp.strings[1] = lac;
    668         rsp.strings[2] = cid;
    669         rsp.strings[3] = radioTechnology;
    670         rsp.strings[4] = baseStationId;
    671         rsp.strings[5] = baseStationLatitude;
    672         rsp.strings[6] = baseStationLongitude;
    673         rsp.strings[7] = concurrentServices;
    674         rsp.strings[8] = systemId;
    675         rsp.strings[9] = networkId;
    676         rsp.strings[10] = roamingIndicator;
    677         rsp.strings[11] = prlActive;
    678         rsp.strings[12] = defaultRoamingIndicator;
    679         rsp.strings[13] = registrationDeniedReason;
    680         rsp.strings[14] = primaryScrambingCode;
    681 
    682         result.responseProtobuf = rilSchema[packageNameAndSeperator +
    683                                  'RspStrings'].serialize(rsp);
    684         return result;
    685     }
    686 
    687     /**
    688      * Handle RIL_REQUEST_DATA_REGISTRATION_STATE
    689      *
    690      * @param req is the Request
    691      */
    692     this.rilRequestDataRegistrationState = function(req) { // 21
    693         print('Radio: rilRequestDataRegistrationState');
    694 
    695         var rsp = new Object();
    696         rsp.strings = Array();
    697         rsp.strings[0] = registrationState;
    698         rsp.strings[1] = lac;
    699         rsp.strings[2] = cid;
    700         rsp.strings[3] = radioTechnology;
    701 
    702         result.responseProtobuf = rilSchema[packageNameAndSeperator +
    703                                  'RspStrings'].serialize(rsp);
    704         return result;
    705     }
    706 
    707     /**
    708      * Handle RIL_REQUEST_ANSWER
    709      *
    710      * @param req is the Request
    711      */
    712     this.rilRequestAnswer = function(req) { // 40
    713         print('Radio: rilRequestAnswer');
    714 
    715         if (numberActiveCalls != 1) {
    716             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    717             return result;
    718         } else {
    719             for (var i = 0; i < calls.length; i++) {
    720                 if (typeof calls[i] != 'undefined') {
    721                     if (calls[i].state == CALLSTATE_INCOMING) {
    722                         calls[i].state = CALLSTATE_ACTIVE;
    723                         break;
    724                     } else {
    725                         result.rilErrCode = RIL_E_GENERIC_FAILURE;
    726                         this.removeCall(i);
    727                         return result;
    728                     }
    729                 } // end of processing call[i]
    730             } // end of for
    731         }
    732         incomingCallIsProcessed = true;
    733         return result;
    734     }
    735 
    736     /**
    737      * Handle RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE
    738      *
    739      * @param req is the Request
    740      */
    741     this.rilRequestQueryNeworkSelectionMode = function(req) { // 45
    742         print('Radio: rilRequestQueryNeworkSelectionMode');
    743 
    744         var rsp = new Object();
    745         rsp.integers = Array();
    746         rsp.integers[0] = networkSelectionMode;
    747 
    748         result.responseProtobuf = rilSchema[packageNameAndSeperator +
    749                                  'RspIntegers'].serialize(rsp);
    750         return result;
    751     }
    752 
    753     /**
    754      * Handle RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC
    755      *
    756      * @param req is the Request
    757      */
    758     this.rilRequestSetNeworkSelectionAutomatic = function(req) { // 46
    759         print('Radio: rilRequestSetNeworkSelectionAutomatic');
    760 
    761         networkSelectionMode = NETWORK_SELECTION_MODE_AUTOMATIC;
    762 
    763         return result;
    764     }
    765 
    766     /**
    767      * Handle RIL_REQUEST_BASE_BAND_VERSION
    768      *
    769      * @param req is the Request
    770      */
    771     this.rilRequestBaseBandVersion = function(req) { // 51
    772         print('Radio: rilRequestBaseBandVersion');
    773         var rsp = new Object();
    774         rsp.strings = Array();
    775         rsp.strings[0] = gBaseBandVersion;
    776 
    777         result.responseProtobuf = rilSchema[packageNameAndSeperator +
    778                                  'RspStrings'].serialize(rsp);
    779         return result;
    780     }
    781 
    782     /**
    783      * Handle RIL_REQUEST_SEPRATE_CONNECTION
    784      * Separate a party from a multiparty call placing the multiparty call
    785      * (less the specified party) on hold and leaving the specified party
    786      * as the only other member of the current (active) call
    787      *
    788      * See TS 22.084 1.3.8.2 (iii)
    789      *
    790      * @param req is the Request
    791      */
    792     this.rilReqestSeparateConnection = function(req) {  // 52
    793         print('Radio: rilReqestSeparateConnection');
    794         var index = req.data.index;
    795 
    796         if (numberActiveCalls <= 0) {
    797             result.rilErrCode = RIL_E_GENERIC_FAILURE;
    798             return result;
    799         } else {
    800             // get the connection to separate
    801             var separateConn = this.getCall(req.data.index);
    802             if (separateConn == null) {
    803                 result.rilErrCode = RIL_E_GENERIC_FAILURE;
    804                 return result;
    805             } else {
    806                 if (separateConn.state != CALLSTATE_ACTIVE) {
    807                     result.rilErrCode = RIL_E_GENERIC_FAILURE;
    808                     return result;
    809                 }
    810                 // Put all other connections in hold.
    811                 for (var i = 0; i < calls.length; i++) {
    812                     if (index != i) {
    813                         // put all the active call to hold
    814                         if (typeof calls[i] != 'undefined') {
    815                             switch (calls[i].state) {
    816                                 case CALLSTATE_ACTIVE:
    817                                     calls[i].state = CALLSTATE_HOLDING;
    818                                     break;
    819                                 default:
    820                                     result.rilErrCode = RIL_E_GENERIC_FAILURE;
    821                                     break;
    822                             }
    823                             this.printCalls(calls);
    824                             if(result.rilErrCode == RIL_E_GENERIC_FAILURE) {
    825                                 return result;
    826                             }
    827                         }  // end of processing call[i]
    828                     }
    829                 }  // end of for
    830             }
    831         }
    832 
    833         // Send out RIL_UNSOL_CALL_STATE_CHANGED after the request is returned
    834         simulatedRadioWorker.add(
    835           {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
    836         return result;
    837     }
    838 
    839     /**
    840      * Handle RIL_REQUEST_SET_MUTE
    841      */
    842     this.rilRequestSetMute = function(req) { // 53
    843         print('Radio: rilRequestSetMute: req.data.state=' + req.data.state);
    844         muteState = req.data.state;
    845         if (gRadioState == RADIOSTATE_UNAVAILABLE) {
    846             result.rilErrCode = RIL_E_RADIO_NOT_AVAILABLE;
    847         }
    848         return result;
    849     }
    850 
    851     /**
    852      * Handle RIL_REQUEST_SCREEN_STATE
    853      *
    854      * @param req is the Request
    855      */
    856     this.rilRequestScreenState = function(req) { // 61
    857         print('Radio: rilRequestScreenState: req.data.state=' + req.data.state);
    858         screenState = req.data.state;
    859         return result;
    860     }
    861 
    862     /**
    863      * Delay test
    864      */
    865      this.cmdDelayTest = function(req) { // 2000
    866          print('cmdDelayTest: req.hello=' + req.hello);
    867          result.sendResponse = false;
    868          return result;
    869      }
    870 
    871      /**
    872       * Delay for RIL_UNSOL_SIGNAL_STRENGTH
    873       * TODO: Simulate signal strength changes:
    874       * Method 1: provide an array for signal strength, and send the unsolicited
    875       *           reponse periodically (the period can also be simulated)
    876       * Method 2: Simulate signal strength randomly (within a certain range) and
    877       *           send the response periodically.
    878       */
    879      this.cmdUnsolSignalStrength = function(req) { // 2001
    880          print('cmdUnsolSignalStrength: req.reqNum=' + req.reqNum);
    881          var rsp = new Object();
    882 
    883          // pack the signal strength into RspSignalStrength
    884          rsp.gwSignalstrength = gwSignalStrength;
    885          rsp.cdmaSignalstrength = cdmaSignalStrength;
    886          rsp.evdoSignalstrength = evdoSignalStrength;
    887 
    888          response = rilSchema[packageNameAndSeperator +
    889                               'RspSignalStrength'].serialize(rsp);
    890 
    891          // upldate signal strength
    892          sendRilUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH, response);
    893 
    894          // Send the unsolicited signal strength every 1 minute.
    895          simulatedRadioWorker.addDelayed(
    896              {'reqNum' : CMD_UNSOL_SIGNAL_STRENGTH}, 60000);
    897 
    898          // this is not a request, no response is needed
    899          result.sendResponse = false;
    900          return result;
    901      }
    902 
    903      /**
    904       * Send RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
    905       */
    906      this.cmdUnsolCallStateChanged = function(req) { // 2002
    907          print('cmdUnsolCallStateChanged: req.reqNum=' + req.reqNum);
    908          sendRilUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
    909          result.sendResponse = false;
    910          return result;
    911      }
    912 
    913      /**
    914       * Simulate call state change
    915       */
    916      this.cmdCallStateChange = function(req) { // 2003
    917          print('cmdCallStateChange: req.reqNum=' + req.reqNum);
    918          print('cmdCallStateChange: req.callType=' + req.callType);
    919          print('cmdCallStateChange: req.callIndex=' + req.callIndex);
    920          print('cmdCallStateChange: req.nextState=' + req.nextState);
    921 
    922          // if it is an outgoing call, update the call state of the call
    923          // Send out call state changed flag
    924          var curCall = this.getCall(req.callIndex);
    925          this.printCall(curCall);
    926 
    927          if (curCall != null) {
    928              curCall.state = req.nextState;
    929          } else {
    930              this.removeCall(req.callIndex);
    931          }
    932 
    933          // TODO: if it is an incoming call, update the call state of the call
    934          // Send out call state change flag
    935          // Send out RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
    936          simulatedRadioWorker.add(
    937            {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
    938          result.sendResponse = false;
    939          return result;
    940      }
    941 
    942      /**
    943       * send UNSOL_CALL_STATE_CHANGED and UNSOL_CALL_RING
    944       */
    945      this.cmdUnsolCallRing = function(req) { // 2004
    946          print('cmdUnsolCallRing: req.reqNum=' + req.reqNum);
    947          if(!incomingCallIsProcessed) {
    948              sendRilUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
    949              sendRilUnsolicitedResponse(RIL_UNSOL_CALL_RING);
    950 
    951              // Send the next alert in 3 seconds. [refer to ril.h definition]
    952              simulatedRadioWorker.addDelayed(
    953                  {'reqNum' : CMD_UNSOL_CALL_RING}, 3000);
    954          }
    955          result.sendResponse = false;
    956          return result;
    957      }
    958 
    959      /**
    960       * Create an incoming call for the giving number
    961       * return CTRL_STATUS_ERR if there is already a call in any of the states of
    962       * dialing, alerting, incoming, waiting [TS 22 030 6.5] , else
    963       * return CTRL_STATUS_OK and update the call state
    964       */
    965      this.ctrlServerCmdStartInComingCall = function(req) {  // 1001
    966          print('ctrlServerCmdStartInComingCall: req.reqNum:' + req.reqNum);
    967          print('ctrlServerCmdStartInComingCall: req.data.phonenumber:' + req.data.phoneNumber);
    968 
    969          var phoneNumber = req.data.phoneNumber;
    970          var state;
    971 
    972          if (numberActiveCalls <= 0) {
    973              // If there is no connection in use, the call state is INCOMING
    974              state = CALLSTATE_INCOMING;
    975          } else {
    976              // If there is call in any of the states of dialing, alerting, incoming
    977              // waiting, this MT call can not be set
    978              for (var i  = 0; i < calls.length; i++) {
    979                  if (typeof calls[i] != 'undefined') {
    980                      if ( (calls[i].state == CALLSTATE_DIALING) ||
    981                           (calls[i].state == CALLSTATE_ALERTING) ||
    982                           (calls[i].state == CALLSTATE_INCOMING) ||
    983                           (calls[i].state == CALLSTATE_WAITING))
    984                      {
    985                          result.rilErrCode = CTRL_STATUS_ERR;
    986                          return result;
    987                      }
    988                  }
    989              }
    990              // If the incoming call is a second call, the state is WAITING
    991              state = CALLSTATE_WAITING;
    992          }
    993 
    994          // Add call to the call array
    995          this.addCall(state, phoneNumber, '');
    996 
    997          // set the incomingCallIsProcessed flag to be false
    998          incomingCallIsProcessed = false;
    999 
   1000          simulatedRadioWorker.add(
   1001            {'reqNum' : CMD_UNSOL_CALL_RING});
   1002 
   1003          result.rilErrCode = CTRL_STATUS_OK;
   1004          return result;
   1005     }
   1006 
   1007     /**
   1008      * Handle control command CTRL_CMD_HANGUP_CONN_REMOTE
   1009      *   hangup the connection for the given failure cause
   1010      *
   1011      *@param req is the control request
   1012      */
   1013     this.ctrlServerCmdHangupConnRemote = function(req) {    // 1002
   1014         print('ctrlServerCmdHangupConnRemote: req.data.connectionId=' + req.data.connectionId +
   1015               ' req.data.callFailCause' + req.data.callFailCause);
   1016 
   1017         var connection = req.data.connectionId;
   1018         var failureCause = req.data.callFailCause;
   1019 
   1020         this.printCalls(calls);
   1021         var hangupCall = this.removeCall(connection);
   1022         if (hangupCall == null) {
   1023             print('ctrlServerCmdHangupConnRemote: connection id is required.');
   1024             result.rilErrCode = CTRL_STATUS_ERR;
   1025             return result;
   1026         } else {
   1027             // for incoming call, stop sending call ring
   1028             if ((hangupCall.state == CALLSTATE_INCOMING) ||
   1029                 (hangupCall.state == CALLSTATE_WAITING)) {
   1030                 incomingCallIsProcessed = true;
   1031             }
   1032         }
   1033         this.printCalls(calls);
   1034         lastCallFailCause = failureCause;
   1035 
   1036         // send out call state changed response
   1037         simulatedRadioWorker.add(
   1038             {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
   1039 
   1040         result.rilErrCode = CTRL_STATUS_OK;
   1041         return result;
   1042     }
   1043 
   1044     /**
   1045      * Set call transition flag
   1046      */
   1047     this.ctrlServerCmdSetCallTransitionFlag = function(req) {  // 1003
   1048         print('ctrlServerCmdSetCallTransitionFlag: flag=' + req.data.flag);
   1049 
   1050         callTransitionFlag = req.data.flag;
   1051         result.rilErrCode = CTRL_STATUS_OK;
   1052         return result;
   1053     }
   1054 
   1055     /**
   1056      * Set the dialing call to alert
   1057      */
   1058     this.ctrlServerCmdSetCallAlert = function(req) {    // 1004
   1059         print('ctrlServerCmdSetCallAlert: E');
   1060 
   1061         if (callTransitionFlag == false) {
   1062             print('ctrlServerCmdSetCallAlert: need to set the flag first');
   1063             result.rilErrCode = CTRL_STATUS_ERR;
   1064             return result;
   1065         }
   1066         if (numberActiveCalls <= 0) {
   1067             print('ctrlServerCmdSetCallAlert: no active calls');
   1068             result.rilErrCode = CTRL_STATUS_ERR;
   1069             return result;
   1070         }
   1071         var dialingCalls = this.countCallsInState(CALLSTATE_DIALING);
   1072         var index = this.getCallIdByState(CALLSTATE_DIALING);
   1073         if ((dialingCalls == 1) && (index != null)) {
   1074             calls[index].state = CALLSTATE_ALERTING;
   1075         } else {
   1076             // if there 0 or more than one call in dialing state, return error
   1077             print('ctrlServerCmdSetCallAlert: no valid calls in dialing state');
   1078             result.rilErrCode = CTRL_STATUS_ERR;
   1079             return result;
   1080         }
   1081         // send unsolicited call state change response
   1082         simulatedRadioWorker.add(
   1083             {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
   1084 
   1085         result.rilErrCode = CTRL_STATUS_OK;
   1086         return result;
   1087     }
   1088 
   1089     /**
   1090      * Set the alserting call to active
   1091      */
   1092     this.ctrlServerCmdSetCallActive = function(req) {   // 1005
   1093         print('ctrlServerCmdSetCallActive: E');
   1094 
   1095         if (callTransitionFlag == false) {
   1096             print('ctrlServerCmdSetCallActive: need to set the flag firt');
   1097             result.rilErrCode = CTRL_STATUS_ERR;
   1098             return result;
   1099         }
   1100         if (numberActiveCalls <= 0) {
   1101             print('ctrlServerCmdSetCallActive: no active calls');
   1102             result.rilErrCode = CTRL_STATUS_ERR;
   1103             return result;
   1104         }
   1105         var alertingCalls = this.countCallsInState(CALLSTATE_ALERTING);
   1106         var index = this.getCallIdByState(CALLSTATE_ALERTING);
   1107         if ((alertingCalls == 1) && (index != null)) {
   1108             calls[index].state = CALLSTATE_ACTIVE;
   1109         } else {
   1110             print('ctrlServerCmdSetCallActive: no valid calls in alert state');
   1111             result.rilErrCode = CTRL_STATUS_ERR;
   1112             return result;
   1113         }
   1114         // send out unsolicited call state change response
   1115         simulatedRadioWorker.add(
   1116             {'reqNum' : CMD_UNSOL_CALL_STATE_CHANGED});
   1117 
   1118         result.rilErrCode = CTRL_STATUS_OK;
   1119         return result;
   1120     }
   1121 
   1122     /**
   1123      * Add a dialing call
   1124      */
   1125     this.ctrlServerCmdAddDialingCall = function(req) {   // 1006
   1126         print('ctrlServerCmdAddDialingCall: E');
   1127 
   1128         var phoneNumber = req.data.phoneNumber;
   1129         var dialingCalls = this.countCallsInState(CALLSTATE_DIALING);
   1130         if (dialingCalls == 0) {
   1131             this.addCall(CALLSTATE_DIALING, phoneNumber, '');
   1132             result.rilErrCode = CTRL_STATUS_OK;
   1133         } else {
   1134             print('ctrlServerCmdAddDialingCall: add dialing call failed');
   1135             result.rilErrCode = CTRL_STATUS_ERR;
   1136         }
   1137         return result;
   1138     }
   1139 
   1140     /**
   1141      * Process the request by dispatching to the request handlers
   1142      */
   1143     this.process = function(req) {
   1144         try {
   1145             print('Radio E: req.reqNum=' + req.reqNum + ' req.token=' + req.token);
   1146 
   1147             // Assume the result will be true, successful and nothing to return
   1148             result.sendResponse = true;
   1149             result.rilErrCode = RIL_E_SUCCESS;
   1150             result.responseProtobuf = emptyProtobuf;
   1151 
   1152             try {
   1153                 // Pass "this" object to each ril request call such that
   1154                 // they have the same scope
   1155                 result = (this.radioDispatchTable[req.reqNum]).call(this, req);
   1156             } catch (err) {
   1157                 print('Radio:process err = ' + err);
   1158                 print('Radio: Unknown reqNum=' + req.reqNum);
   1159                 result.rilErrCode = RIL_E_REQUEST_NOT_SUPPORTED;
   1160             }
   1161 
   1162             if (req.reqNum < 200) {
   1163                 lastReq = req.reqNum;
   1164             }
   1165             if (result.sendResponse) {
   1166                 if (isCtrlServerDispatchCommand(req.reqNum)) {
   1167                     //print('Command ' + req.reqNum + ' is a control server command');
   1168                     sendCtrlRequestComplete(result.rilErrCode, req.reqNum,
   1169                       req.token, result.responseProtobuf);
   1170                 } else {
   1171                     //print('Request ' + req.reqNum + ' is a ril request');
   1172                     sendRilRequestComplete(result.rilErrCode, req.reqNum,
   1173                       req.token, result.responseProtobuf);
   1174                 }
   1175             }
   1176             //print('Radio X: req.reqNum=' + req.reqNum + ' req.token=' + req.token);
   1177         } catch (err) {
   1178             print('Radio: Exception req.reqNum=' +
   1179                     req.reqNum + ' req.token=' + req.token + ' err=' + err);
   1180         }
   1181     }
   1182 
   1183     /**
   1184      * Construct the simulated radio
   1185      */
   1186     print('Radio: constructor E');
   1187     this.radioDispatchTable = new Array();
   1188     this.radioDispatchTable[RIL_REQUEST_GET_CURRENT_CALLS] = // 9
   1189                 this.rilRequestGetCurrentCalls;
   1190     this.radioDispatchTable[RIL_REQUEST_DIAL] = // 10
   1191                 this.rilRequestDial;
   1192     this.radioDispatchTable[RIL_REQUEST_HANGUP] =  // 12
   1193                 this.rilRequestHangUp;
   1194     this.radioDispatchTable[RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND] = // 13
   1195                 this.rilRequestHangupWaitingOrBackground;
   1196     this.radioDispatchTable[RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] =  // 14
   1197                 this.rilRequestHangUpForegroundResumeBackground;
   1198     this.radioDispatchTable[RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] =  // 15
   1199                 this.rilRequestSwitchWaitingOrHoldingAndActive;
   1200     this.radioDispatchTable[RIL_REQUEST_CONFERENCE] = // 16
   1201                 this.rilRequestConference;
   1202     this.radioDispatchTable[RIL_REQUEST_LAST_CALL_FAIL_CAUSE] = // 18
   1203                 this.rilRequestLastCallFailCause;
   1204     this.radioDispatchTable[RIL_REQUEST_SIGNAL_STRENGTH] = // 19
   1205                 this.rilRequestSignalStrength;
   1206     this.radioDispatchTable[RIL_REQUEST_VOICE_REGISTRATION_STATE] = // 20
   1207                 this.rilRequestVoiceRegistrationState;
   1208     this.radioDispatchTable[RIL_REQUEST_DATA_REGISTRATION_STATE] = // 21
   1209                 this.rilRequestDataRegistrationState;
   1210     this.radioDispatchTable[RIL_REQUEST_ANSWER] = // 40
   1211                 this.rilRequestAnswer;
   1212     this.radioDispatchTable[RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE] = // 45
   1213                 this.rilRequestQueryNeworkSelectionMode;
   1214     this.radioDispatchTable[RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC] = // 46
   1215                 this.rilRequestSetNeworkSelectionAutomatic;
   1216     this.radioDispatchTable[RIL_REQUEST_BASEBAND_VERSION] = // 51
   1217                 this.rilRequestBaseBandVersion;
   1218     this.radioDispatchTable[RIL_REQUEST_SEPARATE_CONNECTION] = // 52
   1219                 this.rilReqestSeparateConnection;
   1220     this.radioDispatchTable[RIL_REQUEST_SET_MUTE] = // 53
   1221                 this.rilRequestSetMute;
   1222     this.radioDispatchTable[RIL_REQUEST_SCREEN_STATE] = // 61
   1223                 this.rilRequestScreenState;
   1224 
   1225     this.radioDispatchTable[CTRL_CMD_SET_MT_CALL] = //1001
   1226                 this.ctrlServerCmdStartInComingCall;
   1227     this.radioDispatchTable[CTRL_CMD_HANGUP_CONN_REMOTE] = //1002
   1228                 this.ctrlServerCmdHangupConnRemote;
   1229     this.radioDispatchTable[CTRL_CMD_SET_CALL_TRANSITION_FLAG] = //1003
   1230                 this.ctrlServerCmdSetCallTransitionFlag;
   1231     this.radioDispatchTable[CTRL_CMD_SET_CALL_ALERT] =  // 1004
   1232                 this.ctrlServerCmdSetCallAlert;
   1233     this.radioDispatchTable[CTRL_CMD_SET_CALL_ACTIVE] =  // 1005
   1234                 this.ctrlServerCmdSetCallActive;
   1235     this.radioDispatchTable[CTRL_CMD_ADD_DIALING_CALL] =  // 1006
   1236                 this.ctrlServerCmdAddDialingCall;
   1237 
   1238     this.radioDispatchTable[CMD_DELAY_TEST] = // 2000
   1239                 this.cmdDelayTest;
   1240     this.radioDispatchTable[CMD_UNSOL_SIGNAL_STRENGTH] =  // 2001
   1241                 this.cmdUnsolSignalStrength;
   1242     this.radioDispatchTable[CMD_UNSOL_CALL_STATE_CHANGED] =  // 2002
   1243                 this.cmdUnsolCallStateChanged;
   1244     this.radioDispatchTable[CMD_CALL_STATE_CHANGE] = //2003
   1245                 this.cmdCallStateChange;
   1246     this.radioDispatchTable[CMD_UNSOL_CALL_RING] = //2004
   1247                 this.cmdUnsolCallRing;
   1248 
   1249     print('Radio: constructor X');
   1250 }
   1251 
   1252 // The simulated radio instance and its associated Worker
   1253 var simulatedRadio = new Radio();
   1254 var simulatedRadioWorker = new Worker(function (req) {
   1255     simulatedRadio.process(req);
   1256 });
   1257 simulatedRadioWorker.run();
   1258 
   1259 // TODO: this is a workaround for bug http://b/issue?id=3001613
   1260 // When adding a new all, two RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE
   1261 // will be sent from the framework.
   1262 var lastReq = 0;
   1263 
   1264 /**
   1265  * Optional tests
   1266  */
   1267 if (false) {
   1268     include("simulated_radio_tests.js");
   1269 }
   1270