1afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang/* 2afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * Copyright (C) 2010, The Android Open Source Project 3afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * 4afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * you may not use this file except in compliance with the License. 6afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * You may obtain a copy of the License at 7afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * 8afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * http://www.apache.org/licenses/LICENSE-2.0 9afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * 10afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * Unless required by applicable law or agreed to in writing, software 11afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * distributed under the License is distributed on an "AS IS" BASIS, 12afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * See the License for the specific language governing permissions and 14afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * limitations under the License. 15afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang */ 16afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 17afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangpackage com.android.internal.telephony.mockril; 18afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 19afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport android.os.Bundle; 20afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport android.util.Log; 21afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport android.telephony.PhoneNumberUtils; 22afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 23afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport com.android.internal.communication.MsgHeader; 24afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport com.android.internal.communication.Msg; 25afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport com.android.internal.telephony.RilChannel; 26afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport com.android.internal.telephony.ril_proto.RilCtrlCmds; 27afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport com.android.internal.telephony.ril_proto.RilCmds; 28afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport com.google.protobuf.micro.MessageMicro; 29afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 30afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangimport java.io.IOException; 31afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 32afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang/** 33afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * Contain a list of commands to control Mock RIL. Before using these commands the devices 34afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * needs to be set with Mock RIL. Refer to hardware/ril/mockril/README.txt for details. 35afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * 36afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang */ 37afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wangpublic class MockRilController { 38afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang private static final String TAG = "MockRILController"; 39afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang private RilChannel mRilChannel = null; 40afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang private Msg mMessage = null; 41afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 42afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang public MockRilController() throws IOException { 43afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang mRilChannel = RilChannel.makeRilChannel(); 44afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 45afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 46afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang /** 47afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * Close the channel after the communication is done. 48afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * This method has to be called after the test is finished. 49afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang */ 50afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang public void closeChannel() { 51afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang mRilChannel.close(); 52afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 53afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 54afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang /** 55afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * Send commands and return true on success 56afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @param cmd for MsgHeader 57afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @param token for MsgHeader 58afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @param status for MsgHeader 59afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @param pbData for Msg data 60afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @return true if command is sent successfully, false if it fails 61afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang */ 62afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang private boolean sendCtrlCommand(int cmd, long token, int status, MessageMicro pbData) { 63afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang try { 64afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Msg.send(mRilChannel, cmd, token, status, pbData); 65afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } catch (IOException e) { 66afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Log.v(TAG, "send command : %d failed: " + e.getStackTrace()); 67afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return false; 68afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 69afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return true; 70afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 71afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 72afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang /** 73afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * Get control response 74afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @return Msg if response is received, else return null. 75afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang */ 76afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang private Msg getCtrlResponse() { 77afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Msg response = null; 78afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang try { 79afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang response = Msg.recv(mRilChannel); 80afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } catch (IOException e) { 81afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Log.v(TAG, "receive response for getRadioState() error: " + e.getStackTrace()); 82afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return null; 83afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 84afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return response; 85afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 86afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 87afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang /** 88afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @return the radio state if it is valid, otherwise return -1 89afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang */ 90afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang public int getRadioState() { 91afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_GET_RADIO_STATE, 0, 0, null)) { 92afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return -1; 93afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 94afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Msg response = getCtrlResponse(); 95afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang if (response == null) { 96afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Log.v(TAG, "failed to get response"); 97afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return -1; 98afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 99afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang response.printHeader(TAG); 100afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang RilCtrlCmds.CtrlRspRadioState resp = 101afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class); 102afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang int state = resp.getState(); 103afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang if ((state >= RilCmds.RADIOSTATE_OFF) && (state <= RilCmds.RADIOSTATE_NV_READY)) 104afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return state; 105afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang else 106afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return -1; 107afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 108afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 109afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang /** 110afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * Set the radio state of mock ril to the given state 111afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @param state for given radio state 112afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * @return true if the state is set successful, false if it fails 113afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang */ 114afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang public boolean setRadioState(int state) { 115afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang RilCtrlCmds.CtrlReqRadioState req = new RilCtrlCmds.CtrlReqRadioState(); 116afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang if (state < 0 || state > RilCmds.RADIOSTATE_NV_READY) { 117afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Log.v(TAG, "the give radio state is not valid."); 118afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return false; 119afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 120afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang req.setState(state); 121afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, req)) { 122afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Log.v(TAG, "send set radio state request failed."); 123afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return false; 124afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 125afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Msg response = getCtrlResponse(); 126afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang if (response == null) { 127afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Log.v(TAG, "failed to get response for setRadioState"); 128afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return false; 129afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 130afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang response.printHeader(TAG); 131afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang RilCtrlCmds.CtrlRspRadioState resp = 132afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class); 133afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang int curstate = resp.getState(); 134afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return curstate == state; 135afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 136afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 137afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang /** 138ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * Start an incoming call for the given phone number 139afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang * 140ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @param phoneNumber is the number to show as incoming call 141ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @return true if the incoming call is started successfully, false if it fails. 142afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang */ 143ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang public boolean startIncomingCall(String phoneNumber) { 144afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang RilCtrlCmds.CtrlReqSetMTCall req = new RilCtrlCmds.CtrlReqSetMTCall(); 145afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 146afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang req.setPhoneNumber(phoneNumber); 147afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, req)) { 148afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang Log.v(TAG, "send CMD_SET_MT_CALL request failed"); 149afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return false; 150afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 151afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang return true; 152afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang } 153afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang 154ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang /** 155ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * Hang up a connection remotelly for the given call fail cause 156ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * 157ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @param connectionID is the connection to be hung up 158ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @param failCause is the call fail cause defined in ril.h 159ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @return true if the hangup is successful, false if it fails 160ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang */ 161ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang public boolean hangupRemote(int connectionId, int failCause) { 162ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang RilCtrlCmds.CtrlHangupConnRemote req = new RilCtrlCmds.CtrlHangupConnRemote(); 163ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang req.setConnectionId(connectionId); 164ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang req.setCallFailCause(failCause); 165ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang 166ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, req)) { 167ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang Log.v(TAG, "send CTRL_CMD_HANGUP_CONN_REMOTE request failed"); 168ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang return false; 169ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang } 170ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang return true; 171ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang } 172ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang 173ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang /** 174ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * Set call transition flag to the Mock Ril 175ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * 176ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @param flag is a boolean value for the call transiton flag 177ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * true: call transition: dialing->alert, alert->active is controlled 178ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * false: call transition is automatically handled by Mock Ril 179ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @return true if the request is successful, false if it failed to set the flag 180ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang */ 181ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang public boolean setCallTransitionFlag(boolean flag) { 182ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang RilCtrlCmds.CtrlSetCallTransitionFlag req = new RilCtrlCmds.CtrlSetCallTransitionFlag(); 183ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang 184ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang req.setFlag(flag); 185ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang 186ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, req)) { 187ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang Log.v(TAG, "send CTRL_CMD_SET_CALL_TRANSITION_FLAG request failed"); 188ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang return false; 189ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang } 190ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang return true; 191ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang } 192ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang 193ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang /** 194ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * Set the dialing call to alert if the call transition flag is true 195ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * 196ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @return true if the call transition is successful, false if it fails 197ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang */ 198ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang public boolean setDialCallToAlert() { 199ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null)) { 200ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang Log.v(TAG, "send CTRL_CMD_SET_CALL_ALERT request failed"); 201ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang return false; 202ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang } 203ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang return true; 204ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang } 205ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang 206ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang /** 207ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * Set the alert call to active if the call transition flag is true 208ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * 209ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang * @return true if the call transition is successful, false if it fails 210ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang */ 211ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang public boolean setAlertCallToActive() { 212ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null)) { 213ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang Log.v(TAG, "send CTRL_CMD_SET_CALL_ACTIVE request failed"); 214ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang return false; 215ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang } 216ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang return true; 217ffcb68719bca6816fc0f39135b41b4c7320042d5Xia Wang } 218afeeaf351a6d48ff218b31775de9b73c8848eba5Xia Wang} 219