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