blob: 775b15e194d2d921718a1d2b3696a255cf16d749 [file] [log] [blame]
Zvikomborero Vincent Zvikaramba142ccf62016-07-28 04:53:08 -04001/*
2 * Copyright (C) 2011 The CyanogenMod Project <http://www.cyanogenmod.org>
3 * Copyright (C) 2014 MaclawStudio
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.internal.telephony;
19
20import static com.android.internal.telephony.RILConstants.*;
21import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
22import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
23import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
24import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
25import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA;
26import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
27import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
28
29
30import com.android.internal.telephony.CommandException;
31import com.android.internal.telephony.dataconnection.DataCallResponse;
32import com.android.internal.telephony.dataconnection.DcFailCause;
33import com.android.internal.telephony.RILConstants;
34import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec;
35import com.android.internal.telephony.cdma.SignalToneUtil;
36
37import android.content.BroadcastReceiver;
38import android.content.Context;
39import android.content.Intent;
40import android.content.IntentFilter;
41import android.content.res.Resources;
42import android.net.ConnectivityManager;
43import android.net.LocalSocket;
44import android.net.LocalSocketAddress;
45import android.net.NetworkInfo;
46import android.os.AsyncResult;
47import android.os.Handler;
48import android.os.HandlerThread;
49import android.os.Looper;
50import android.os.Message;
51import android.os.Parcel;
52import android.os.PowerManager;
53import android.os.PowerManager.WakeLock;
54import android.telephony.NeighboringCellInfo;
55import android.telephony.PhoneNumberUtils;
56import android.telephony.SignalStrength;
57import android.telephony.SmsManager;
58import android.telephony.SmsMessage;
59import android.text.TextUtils;
60import android.telephony.Rlog;
61
62import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
63import com.android.internal.telephony.gsm.SuppServiceNotification;
64import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
65import com.android.internal.telephony.cdma.CdmaInformationRecords;
66
67import java.io.ByteArrayInputStream;
68import java.io.DataInputStream;
69import java.io.IOException;
70import java.io.InputStream;
71import java.lang.Runtime;
72import java.util.ArrayList;
73import java.util.Collections;
74import java.util.Iterator;
75
76public class SamsungRIL extends RIL implements CommandsInterface {
77
78 //SAMSUNG STATES
79 static final int RIL_REQUEST_GET_CELL_BROADCAST_CONFIG = 10002;
80
81 static final int RIL_REQUEST_SEND_ENCODED_USSD = 10005;
82 static final int RIL_REQUEST_SET_PDA_MEMORY_STATUS = 10006;
83 static final int RIL_REQUEST_GET_PHONEBOOK_STORAGE_INFO = 10007;
84 static final int RIL_REQUEST_GET_PHONEBOOK_ENTRY = 10008;
85 static final int RIL_REQUEST_ACCESS_PHONEBOOK_ENTRY = 10009;
86 static final int RIL_REQUEST_DIAL_VIDEO_CALL = 10010;
87 static final int RIL_REQUEST_CALL_DEFLECTION = 10011;
88 static final int RIL_REQUEST_READ_SMS_FROM_SIM = 10012;
89 static final int RIL_REQUEST_USIM_PB_CAPA = 10013;
90 static final int RIL_REQUEST_LOCK_INFO = 10014;
91
92 static final int RIL_REQUEST_DIAL_EMERGENCY = 10016;
93 static final int RIL_REQUEST_GET_STOREAD_MSG_COUNT = 10017;
94 static final int RIL_REQUEST_STK_SIM_INIT_EVENT = 10018;
95 static final int RIL_REQUEST_GET_LINE_ID = 10019;
96 static final int RIL_REQUEST_SET_LINE_ID = 10020;
97 static final int RIL_REQUEST_GET_SERIAL_NUMBER = 10021;
98 static final int RIL_REQUEST_GET_MANUFACTURE_DATE_NUMBER = 10022;
99 static final int RIL_REQUEST_GET_BARCODE_NUMBER = 10023;
100 static final int RIL_REQUEST_UICC_GBA_AUTHENTICATE_BOOTSTRAP = 10024;
101 static final int RIL_REQUEST_UICC_GBA_AUTHENTICATE_NAF = 10025;
102 static final int RIL_REQUEST_SIM_TRANSMIT_BASIC = 10026;
103 static final int RIL_REQUEST_SIM_OPEN_CHANNEL = 10027;
104 static final int RIL_REQUEST_SIM_CLOSE_CHANNEL = 10028;
105 static final int RIL_REQUEST_SIM_TRANSMIT_CHANNEL = 10029;
106 static final int RIL_REQUEST_SIM_AUTH = 10030;
107 static final int RIL_REQUEST_PS_ATTACH = 10031;
108 static final int RIL_REQUEST_PS_DETACH = 10032;
109 static final int RIL_REQUEST_ACTIVATE_DATA_CALL = 10033;
110 static final int RIL_REQUEST_CHANGE_SIM_PERSO = 10034;
111 static final int RIL_REQUEST_ENTER_SIM_PERSO = 10035;
112 static final int RIL_REQUEST_GET_TIME_INFO = 10036;
113 static final int RIL_REQUEST_OMADM_SETUP_SESSION = 10037;
114 static final int RIL_REQUEST_OMADM_SERVER_START_SESSION = 10038;
115 static final int RIL_REQUEST_OMADM_CLIENT_START_SESSION = 10039;
116 static final int RIL_REQUEST_OMADM_SEND_DATA = 10040;
117 static final int RIL_REQUEST_CDMA_GET_DATAPROFILE = 10041;
118 static final int RIL_REQUEST_CDMA_SET_DATAPROFILE = 10042;
119 static final int RIL_REQUEST_CDMA_GET_SYSTEMPROPERTIES = 10043;
120 static final int RIL_REQUEST_CDMA_SET_SYSTEMPROPERTIES = 10044;
121 static final int RIL_REQUEST_SEND_SMS_COUNT = 10045;
122 static final int RIL_REQUEST_SEND_SMS_MSG = 10046;
123 static final int RIL_REQUEST_SEND_SMS_MSG_READ_STATUS = 10047;
124 static final int RIL_REQUEST_MODEM_HANGUP = 10048;
125 static final int RIL_REQUEST_SET_SIM_POWER = 10049;
126 static final int RIL_REQUEST_SET_PREFERRED_NETWORK_LIST = 10050;
127 static final int RIL_REQUEST_GET_PREFERRED_NETWORK_LIST = 10051;
128 static final int RIL_REQUEST_HANGUP_VT = 10052;
129
130 static final int RIL_UNSOL_RELEASE_COMPLETE_MESSAGE = 11001;
131 static final int RIL_UNSOL_STK_SEND_SMS_RESULT = 11002;
132 static final int RIL_UNSOL_STK_CALL_CONTROL_RESULT = 11003;
133 static final int RIL_UNSOL_DUN_CALL_STATUS = 11004;
134
135 static final int RIL_UNSOL_O2_HOME_ZONE_INFO = 11007;
136 static final int RIL_UNSOL_DEVICE_READY_NOTI = 11008;
137 static final int RIL_UNSOL_GPS_NOTI = 11009;
138 static final int RIL_UNSOL_AM = 11010;
139 static final int RIL_UNSOL_DUN_PIN_CONTROL_SIGNAL = 11011;
140 static final int RIL_UNSOL_DATA_SUSPEND_RESUME = 11012;
141 static final int RIL_UNSOL_SAP = 11013;
142
143 static final int RIL_UNSOL_SIM_SMS_STORAGE_AVAILALE = 11015;
144 static final int RIL_UNSOL_HSDPA_STATE_CHANGED = 11016;
145 static final int RIL_UNSOL_TWO_MIC_STATE = 11018;
146 static final int RIL_UNSOL_DHA_STATE = 11019;
147 static final int RIL_UNSOL_UART = 11020;
148 static final int RIL_UNSOL_RESPONSE_HANDOVER = 11021;
149 static final int RIL_UNSOL_IPV6_ADDR = 11022;
150 static final int RIL_UNSOL_NWK_INIT_DISC_REQUEST = 11023;
151 static final int RIL_UNSOL_RTS_INDICATION = 11024;
152 static final int RIL_UNSOL_OMADM_SEND_DATA = 11025;
153 static final int RIL_UNSOL_DUN = 11026;
154 static final int RIL_UNSOL_SYSTEM_REBOOT = 11027;
155 static final int RIL_UNSOL_VOICE_PRIVACY_CHANGED = 11028;
156 static final int RIL_UNSOL_UTS_GETSMSCOUNT = 11029;
157 static final int RIL_UNSOL_UTS_GETSMSMSG = 11030;
158 static final int RIL_UNSOL_UTS_GET_UNREAD_SMS_STATUS = 11031;
159 static final int RIL_UNSOL_MIP_CONNECT_STATUS = 11032;
160
161 protected HandlerThread mSamsungRILThread;
162 protected ConnectivityHandler mSamsungRILHandler;
163
164 public SamsungRIL(Context context, int networkMode, int cdmaSubscription) {
165 super(context, networkMode, cdmaSubscription);
166 mQANElements = 5;
167 }
168
169 static String
170 requestToString(int request) {
171 switch (request) {
172 case RIL_REQUEST_DIAL_EMERGENCY: return "DIAL_EMERGENCY";
173 default: return RIL.requestToString(request);
174 }
175 }
176
177 @Override
178 public void setCurrentPreferredNetworkType() {
179 if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType IGNORED");
180 /* Google added this as a fix for crespo loosing network type after
181 * taking an OTA. This messes up the data connection state for us
182 * due to the way we handle network type change (disable data
183 * then change then re-enable).
184 */
185 }
186
187 private boolean NeedReconnect()
188 {
189 ConnectivityManager cm =
190 (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
191 NetworkInfo ni_active = cm.getActiveNetworkInfo();
192
193 return ni_active != null && ni_active.getTypeName().equalsIgnoreCase( "mobile" ) &&
194 ni_active.isConnected() && cm.getMobileDataEnabled();
195 }
196
197 @Override
198 public void setPreferredNetworkType(int networkType , Message response) {
199 /* Samsung modem implementation does bad things when a datacall is running
200 * while switching the preferred networktype.
201 */
202 HandlerThread handlerThread;
203 Looper looper;
204
205 if(NeedReconnect())
206 {
207 if (mSamsungRILHandler == null) {
208
209 handlerThread = new HandlerThread("mSamsungRILThread");
210 mSamsungRILThread = handlerThread;
211
212 mSamsungRILThread.start();
213
214 looper = mSamsungRILThread.getLooper();
215 mSamsungRILHandler = new ConnectivityHandler(mContext, looper);
216 }
217 mSamsungRILHandler.setPreferedNetworkType(networkType, response);
218 } else {
219 if (mSamsungRILHandler != null) {
220 mSamsungRILThread = null;
221 mSamsungRILHandler = null;
222 }
223 sendPreferedNetworktype(networkType, response);
224 }
225
226 }
227
228 //Sends the real RIL request to the modem.
229 private void sendPreferedNetworktype(int networkType, Message response) {
230 RILRequest rr = RILRequest.obtain(
231 RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);
232
233 rr.mParcel.writeInt(1);
234 rr.mParcel.writeInt(networkType);
235
236 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
237 + " : " + networkType);
238
239 send(rr);
240 }
241
242 /* private class that does the handling for the dataconnection
243 * dataconnection is done async, so we send the request for disabling it,
244 * wait for the response, set the prefered networktype and notify the
245 * real sender with its result.
246 */
247 private class ConnectivityHandler extends Handler{
248
249 private static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 30;
250 private Context mContext;
251 private int mDesiredNetworkType;
252 //the original message, we need it for calling back the original caller when done
253 private Message mNetworktypeResponse;
254 private ConnectivityBroadcastReceiver mConnectivityReceiver = new ConnectivityBroadcastReceiver();
255
256 public ConnectivityHandler(Context context, Looper looper)
257 {
258 super (looper);
259 mContext = context;
260 }
261
262 private void startListening() {
263 IntentFilter filter = new IntentFilter();
264 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
265 mContext.registerReceiver(mConnectivityReceiver, filter);
266 }
267
268 private synchronized void stopListening() {
269 mContext.unregisterReceiver(mConnectivityReceiver);
270 }
271
272 public void setPreferedNetworkType(int networkType, Message response)
273 {
274 Rlog.d(RILJ_LOG_TAG, "Mobile Dataconnection is online setting it down");
275 mDesiredNetworkType = networkType;
276 mNetworktypeResponse = response;
277 ConnectivityManager cm =
278 (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
279 //start listening for the connectivity change broadcast
280 startListening();
281 cm.setMobileDataEnabled(false);
282 }
283
284 @Override
285 public void handleMessage(Message msg) {
286 switch(msg.what) {
287 //networktype was set, now we can enable the dataconnection again
288 case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
289 ConnectivityManager cm =
290 (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
291
292 Rlog.d(RILJ_LOG_TAG, "preferred NetworkType set upping Mobile Dataconnection");
293 cm.setMobileDataEnabled(true);
294 //everything done now call back that we have set the networktype
295 AsyncResult.forMessage(mNetworktypeResponse, null, null);
296 mNetworktypeResponse.sendToTarget();
297 mNetworktypeResponse = null;
298 break;
299 default:
300 throw new RuntimeException("unexpected event not handled");
301 }
302 }
303
304 private class ConnectivityBroadcastReceiver extends BroadcastReceiver {
305
306 @Override
307 public void onReceive(Context context, Intent intent) {
308 String action = intent.getAction();
309 if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
310 Rlog.w(RILJ_LOG_TAG, "onReceived() called with " + intent);
311 return;
312 }
313 boolean noConnectivity =
314 intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
315
316 if (noConnectivity) {
317 //Ok dataconnection is down, now set the networktype
318 Rlog.w(RILJ_LOG_TAG, "Mobile Dataconnection is now down setting preferred NetworkType");
319 stopListening();
320 sendPreferedNetworktype(mDesiredNetworkType, obtainMessage(MESSAGE_SET_PREFERRED_NETWORK_TYPE));
321 mDesiredNetworkType = -1;
322 }
323 }
324 }
325 }
326
327 @Override
328 protected RILRequest findAndRemoveRequestFromList(int serial) {
329 long removalTime = System.currentTimeMillis();
330 long timeDiff = 0;
331 RILRequest rr = null;
332
333 synchronized (mRequestList) {
334
335 rr = mRequestList.get(serial);
336
337 if (rr != null) {
338 mRequestList.remove(serial);
339 return rr;
340 }
341 else
342 {
343 // We need some special code here for the Samsung RIL,
344 // which isn't responding to some requests.
345 // We will print a list of such stale requests which
346 // haven't yet received a response. If the timeout fires
347 // first, then the wakelock is released without debugging.
348 timeDiff = removalTime - rr.creationTime;
349 if ( timeDiff > mWakeLockTimeout ) {
350 Rlog.d(RILJ_LOG_TAG, "No response for [" + rr.mSerial + "] " +
351 requestToString(rr.mRequest) + " after " + timeDiff + " milliseconds.");
352
353 /* Don't actually remove anything for now. Consider uncommenting this to
354 purge stale requests */
355
356 /*
357 itr.remove();
358 if (mRequestMessagesWaiting > 0) {
359 mRequestMessagesWaiting--;
360 }
361
362 // We don't handle the callback (ie. rr.mResult) for
363 // RIL_REQUEST_SET_TTY_MODE, which is
364 // RIL_REQUEST_QUERY_TTY_MODE. The reason for not doing
365 // so is because it will also not get a response from the
366 // Samsung RIL
367 rr.release();
368 */
369 }
370 }
371 }
372 return null;
373 }
374
375 @Override
376 protected RILRequest processSolicited (Parcel p) {
377 int serial, error;
378 boolean found = false;
379
380 serial = p.readInt();
381 error = p.readInt();
382
383 RILRequest rr;
384
385 rr = findAndRemoveRequestFromList(serial);
386
387 if (rr == null) {
388 Rlog.w(RILJ_LOG_TAG, "Unexpected solicited response! sn: "
389 + serial + " error: " + error);
390 return null;
391 }
392
393 Object ret = null;
394
395 if (error == 0 || p.dataAvail() > 0) {
396 // either command succeeds or command fails but with data payload
397 try {switch (rr.mRequest) {
398
399 case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break;
400 case RIL_REQUEST_ENTER_SIM_PIN: ret = responseInts(p); break;
401 case RIL_REQUEST_ENTER_SIM_PUK: ret = responseInts(p); break;
402 case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseInts(p); break;
403 case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseInts(p); break;
404 case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseInts(p); break;
405 case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseInts(p); break;
406 case RIL_REQUEST_ENTER_DEPERSONALIZATION_CODE: ret = responseInts(p); break;
407 case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break;
408 case RIL_REQUEST_DIAL: ret = responseVoid(p); break;
409 case RIL_REQUEST_GET_IMSI: ret = responseString(p); break;
410 case RIL_REQUEST_HANGUP: ret = responseVoid(p); break;
411 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break;
412 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: ret = responseVoid(p); break;
413 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break;
414 case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break;
415 case RIL_REQUEST_UDUB: ret = responseVoid(p); break;
416 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break;
417 case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
418 case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseStrings(p); break;
419 case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break;
420 case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break;
421 case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break;
422 case RIL_REQUEST_DTMF: ret = responseVoid(p); break;
423 case RIL_REQUEST_SEND_SMS: ret = responseSMS(p); break;
424 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret = responseSMS(p); break;
425 case RIL_REQUEST_SETUP_DATA_CALL: ret = responseSetupDataCall(p); break;
426 case RIL_REQUEST_SIM_IO: ret = responseICC_IO(p); break;
427 case RIL_REQUEST_SEND_USSD: ret = responseVoid(p); break;
428 case RIL_REQUEST_CANCEL_USSD: ret = responseVoid(p); break;
429 case RIL_REQUEST_GET_CLIR: ret = responseInts(p); break;
430 case RIL_REQUEST_SET_CLIR: ret = responseVoid(p); break;
431 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret = responseCallForward(p); break;
432 case RIL_REQUEST_SET_CALL_FORWARD: ret = responseVoid(p); break;
433 case RIL_REQUEST_QUERY_CALL_WAITING: ret = responseInts(p); break;
434 case RIL_REQUEST_SET_CALL_WAITING: ret = responseVoid(p); break;
435 case RIL_REQUEST_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
436 case RIL_REQUEST_GET_IMEI: ret = responseString(p); break;
437 case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break;
438 case RIL_REQUEST_ANSWER: ret = responseVoid(p); break;
439 case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseVoid(p); break;
440 case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break;
441 case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break;
442 case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break;
443 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break;
444 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break;
445 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret = responseVoid(p); break;
446 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret = responseOperatorInfos(p); break;
447 case RIL_REQUEST_DTMF_START: ret = responseVoid(p); break;
448 case RIL_REQUEST_DTMF_STOP: ret = responseVoid(p); break;
449 case RIL_REQUEST_BASEBAND_VERSION: ret = responseString(p); break;
450 case RIL_REQUEST_SEPARATE_CONNECTION: ret = responseVoid(p); break;
451 case RIL_REQUEST_SET_MUTE: ret = responseVoid(p); break;
452 case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break;
453 case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break;
454 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret = responseInts(p); break;
455 case RIL_REQUEST_DATA_CALL_LIST: ret = responseDataCallList(p); break;
456 case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break;
457 case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break;
458 case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break;
459 case RIL_REQUEST_SCREEN_STATE: ret = responseVoid(p); break;
460 case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break;
461 case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break;
462 case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break;
463 case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break;
464 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break;
465 case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break;
466 case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break;
467 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break;
468 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break;
469 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break;
470 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break;
471 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break;
472 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseGetPreferredNetworkType(p); break;
473 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
474 case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
475 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break;
476 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break;
477 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break;
478 case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break;
479 case RIL_REQUEST_QUERY_TTY_MODE: ret = responseInts(p); break;
480 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret = responseVoid(p); break;
481 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret = responseInts(p); break;
482 case RIL_REQUEST_CDMA_FLASH: ret = responseVoid(p); break;
483 case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break;
484 case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break;
485 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
486 case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break;
487 case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
488 case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
489 case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break;
490 case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
491 case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
492 case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret = responseVoid(p); break;
493 case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break;
494 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break;
495 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break;
496 case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break;
497 case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
498 case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
499 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
500 case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
501 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
502 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break;
503 case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break;
504 case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
505 case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
506 case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break;
507 case RIL_REQUEST_DIAL_EMERGENCY: ret = responseVoid(p); break;
508 default:
509 throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
510 //break;
511 }} catch (Throwable tr) {
512 // Exceptions here usually mean invalid RIL responses
513
514 Rlog.w(RILJ_LOG_TAG, rr.serialString() + "< "
515 + requestToString(rr.mRequest)
516 + " exception, possible invalid RIL response", tr);
517
518 if (rr.mResult != null) {
519 AsyncResult.forMessage(rr.mResult, null, tr);
520 rr.mResult.sendToTarget();
521 }
522 return rr;
523 }
524 }
525
526 if (error != 0) {
527 //ugly fix for Samsung messing up SMS_SEND request fail in binary RIL
528 if(!(error == -1 && rr.mRequest == RIL_REQUEST_SEND_SMS))
529 {
530 rr.onError(error, ret);
531 return rr;
532 } else {
533 try
534 {
535 ret = responseSMS(p);
536 } catch (Throwable tr) {
537 Rlog.w(RILJ_LOG_TAG, rr.serialString() + "< "
538 + requestToString(rr.mRequest)
539 + " exception, Processing Samsung SMS fix ", tr);
540 rr.onError(error, ret);
541 return rr;
542 }
543 }
544 }
545
546 if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
547 + " " + retToString(rr.mRequest, ret));
548
549 if (rr.mResult != null) {
550 AsyncResult.forMessage(rr.mResult, ret, null);
551 rr.mResult.sendToTarget();
552 }
553
554 return rr;
555 }
556
557 @Override
558 public void
559 dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
560 RILRequest rr;
561 if (PhoneNumberUtils.isEmergencyNumber(address)) {
562 dialEmergencyCall(address, clirMode, result);
563 return;
564 }
565
566 rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
567 rr.mParcel.writeString(address);
568 rr.mParcel.writeInt(clirMode);
569 rr.mParcel.writeInt(0); // UUS information is absent
570
571 if (uusInfo == null) {
572 rr.mParcel.writeInt(0); // UUS information is absent
573 } else {
574 rr.mParcel.writeInt(1); // UUS information is present
575 rr.mParcel.writeInt(uusInfo.getType());
576 rr.mParcel.writeInt(uusInfo.getDcs());
577 rr.mParcel.writeByteArray(uusInfo.getUserData());
578 }
579
580 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
581
582 send(rr);
583 }
584
585 public void
586 dialEmergencyCall(String address, int clirMode, Message result) {
587 RILRequest rr;
588 Rlog.v(RILJ_LOG_TAG, "Emergency dial: " + address);
589
590 rr = RILRequest.obtain(RIL_REQUEST_DIAL_EMERGENCY, result);
591 rr.mParcel.writeString(address + "/");
592 rr.mParcel.writeInt(clirMode);
593 rr.mParcel.writeInt(0);
594 rr.mParcel.writeInt(0);
595
596 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
597
598 send(rr);
599 }
600
601 @Override
602 protected void
603 processUnsolicited (Parcel p) {
604 Object ret;
605 int dataPosition = p.dataPosition();
606 int response = p.readInt();
607
608 switch (response) {
609 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
610 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseString(p); break;
611 case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
612 // SAMSUNG STATES
613 case RIL_UNSOL_AM: ret = responseString(p); break;
614 case RIL_UNSOL_DUN_PIN_CONTROL_SIGNAL: ret = responseVoid(p); break;
615 case RIL_UNSOL_DATA_SUSPEND_RESUME: ret = responseInts(p); break;
616 case RIL_UNSOL_STK_CALL_CONTROL_RESULT: ret = responseVoid(p); break;
617 case RIL_UNSOL_TWO_MIC_STATE: ret = responseInts(p); break;
618
619 default:
620 // Rewind the Parcel
621 p.setDataPosition(dataPosition);
622
623 // Forward responses that we are not overriding to the super class
624 super.processUnsolicited(p);
625 return;
626 }
627
628 switch (response) {
629 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
630 /* has bonus radio state int */
631 int state = p.readInt();
632 Rlog.d(RILJ_LOG_TAG, "Radio state: " + state);
633
634 switch (state) {
635 case 2:
636 // RADIO_UNAVAILABLE
637 state = 1;
638 break;
639 case 3:
640 // RADIO_ON
641 state = 10;
642 break;
643 case 4:
644 // RADIO_ON
645 state = 10;
646 // When SIM is PIN-unlocked, RIL doesn't respond with RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED.
647 // We notify the system here.
648 Rlog.d(RILJ_LOG_TAG, "SIM is PIN-unlocked now");
649 if (mIccStatusChangedRegistrants != null) {
650 mIccStatusChangedRegistrants.notifyRegistrants();
651 }
652 break;
653 }
654 RadioState newState = getRadioStateFromInt(state);
655 Rlog.d(RILJ_LOG_TAG, "New Radio state: " + state + " (" + newState.toString() + ")");
656 switchToRadioState(newState);
657 break;
658 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
659 if (RILJ_LOGD) unsljLogRet(response, ret);
660
661 if (mGsmBroadcastSmsRegistrant != null) {
662 mGsmBroadcastSmsRegistrant
663 .notifyRegistrant(new AsyncResult(null, ret, null));
664 }
665 break;
666 case RIL_UNSOL_RIL_CONNECTED:
667 if (RILJ_LOGD) unsljLogRet(response, ret);
668
669 // Initial conditions
670 setRadioPower(false, null);
671 sendPreferedNetworktype(mPreferredNetworkType, null);
672 setCdmaSubscriptionSource(mCdmaSubscription, null);
673 notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
674 break;
675 // SAMSUNG STATES
676 case RIL_UNSOL_AM:
677 if (RILJ_LOGD) samsungUnsljLogRet(response, ret);
678 String amString = (String) ret;
679 Rlog.d(RILJ_LOG_TAG, "Executing AM: " + amString);
680
681 try {
682 Runtime.getRuntime().exec("am " + amString);
683 } catch (IOException e) {
684 e.printStackTrace();
685 Rlog.e(RILJ_LOG_TAG, "am " + amString + " could not be executed.");
686 }
687 break;
688 case RIL_UNSOL_DUN_PIN_CONTROL_SIGNAL:
689 if (RILJ_LOGD) samsungUnsljLogRet(response, ret);
690 break;
691 case RIL_UNSOL_DATA_SUSPEND_RESUME:
692 if (RILJ_LOGD) samsungUnsljLogRet(response, ret);
693 break;
694 case RIL_UNSOL_STK_CALL_CONTROL_RESULT:
695 if (RILJ_LOGD) samsungUnsljLogRet(response, ret);
696 break;
697 case RIL_UNSOL_TWO_MIC_STATE:
698 if (RILJ_LOGD) samsungUnsljLogRet(response, ret);
699 break;
700 }
701 }
702
703 static String
704 samsungResponseToString(int request)
705 {
706 switch(request) {
707 // SAMSUNG STATES
708 case RIL_UNSOL_AM: return "RIL_UNSOL_AM";
709 case RIL_UNSOL_DUN_PIN_CONTROL_SIGNAL: return "RIL_UNSOL_DUN_PIN_CONTROL_SIGNAL";
710 case RIL_UNSOL_DATA_SUSPEND_RESUME: return "RIL_UNSOL_DATA_SUSPEND_RESUME";
711 case RIL_UNSOL_STK_CALL_CONTROL_RESULT: return "RIL_UNSOL_STK_CALL_CONTROL_RESULT";
712 case RIL_UNSOL_TWO_MIC_STATE: return "RIL_UNSOL_TWO_MIC_STATE";
713 default: return "<unknown response: "+request+">";
714 }
715 }
716
717 protected void samsungUnsljLog(int response) {
718 riljLog("[UNSL]< " + samsungResponseToString(response));
719 }
720
721 protected void samsungUnsljLogMore(int response, String more) {
722 riljLog("[UNSL]< " + samsungResponseToString(response) + " " + more);
723 }
724
725 protected void samsungUnsljLogRet(int response, Object ret) {
726 riljLog("[UNSL]< " + samsungResponseToString(response) + " " + retToString(response, ret));
727 }
728
729 protected void samsungUnsljLogvRet(int response, Object ret) {
730 riljLogv("[UNSL]< " + samsungResponseToString(response) + " " + retToString(response, ret));
731 }
732
733 @Override
734 protected Object
735 responseCallList(Parcel p) {
736 int num;
737 boolean isVideo;
738 ArrayList<DriverCall> response;
739 DriverCall dc;
740 int dataAvail = p.dataAvail();
741 int pos = p.dataPosition();
742 int size = p.dataSize();
743
744 Rlog.d(RILJ_LOG_TAG, "Parcel size = " + size);
745 Rlog.d(RILJ_LOG_TAG, "Parcel pos = " + pos);
746 Rlog.d(RILJ_LOG_TAG, "Parcel dataAvail = " + dataAvail);
747
748 //Samsung changes
749 num = p.readInt();
750
751 Rlog.d(RILJ_LOG_TAG, "num = " + num);
752 response = new ArrayList<DriverCall>(num);
753
754 for (int i = 0 ; i < num ; i++) {
755
756 dc = new DriverCall();
757 dc.state = DriverCall.stateFromCLCC(p.readInt());
758 dc.index = p.readInt();
759 dc.TOA = p.readInt();
760 dc.isMpty = (0 != p.readInt());
761 dc.isMT = (0 != p.readInt());
762 dc.als = p.readInt();
763 dc.isVoice = (0 != p.readInt());
764 isVideo = (0 != p.readInt());
765 dc.isVoicePrivacy = (0 != p.readInt());
766 dc.number = p.readString();
767 int np = p.readInt();
768 dc.numberPresentation = DriverCall.presentationFromCLIP(np);
769 dc.name = p.readString();
770 dc.namePresentation = p.readInt();
771 int uusInfoPresent = p.readInt();
772
773 Rlog.d(RILJ_LOG_TAG, "state = " + dc.state);
774 Rlog.d(RILJ_LOG_TAG, "index = " + dc.index);
775 Rlog.d(RILJ_LOG_TAG, "state = " + dc.TOA);
776 Rlog.d(RILJ_LOG_TAG, "isMpty = " + dc.isMpty);
777 Rlog.d(RILJ_LOG_TAG, "isMT = " + dc.isMT);
778 Rlog.d(RILJ_LOG_TAG, "als = " + dc.als);
779 Rlog.d(RILJ_LOG_TAG, "isVoice = " + dc.isVoice);
780 Rlog.d(RILJ_LOG_TAG, "isVideo = " + isVideo);
781 Rlog.d(RILJ_LOG_TAG, "number = " + dc.number);
782 Rlog.d(RILJ_LOG_TAG, "np = " + np);
783 Rlog.d(RILJ_LOG_TAG, "name = " + dc.name);
784 Rlog.d(RILJ_LOG_TAG, "namePresentation = " + dc.namePresentation);
785 Rlog.d(RILJ_LOG_TAG, "uusInfoPresent = " + uusInfoPresent);
786
787 if (uusInfoPresent == 1) {
788 dc.uusInfo = new UUSInfo();
789 dc.uusInfo.setType(p.readInt());
790 dc.uusInfo.setDcs(p.readInt());
791 byte[] userData = p.createByteArray();
792 dc.uusInfo.setUserData(userData);
793 Rlog.v(RILJ_LOG_TAG, String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
794 dc.uusInfo.getType(), dc.uusInfo.getDcs(),
795 dc.uusInfo.getUserData().length));
796 Rlog.v(RILJ_LOG_TAG, "Incoming UUS : data (string)="
797 + new String(dc.uusInfo.getUserData()));
798 Rlog.v(RILJ_LOG_TAG, "Incoming UUS : data (hex): "
799 + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
800 } else {
801 Rlog.v(RILJ_LOG_TAG, "Incoming UUS : NOT present!");
802 }
803
804 // Make sure there's a leading + on addresses with a TOA of 145
805 dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
806
807 response.add(dc);
808
809 if (dc.isVoicePrivacy) {
810 mVoicePrivacyOnRegistrants.notifyRegistrants();
811 Rlog.d(RILJ_LOG_TAG, "InCall VoicePrivacy is enabled");
812 } else {
813 mVoicePrivacyOffRegistrants.notifyRegistrants();
814 Rlog.d(RILJ_LOG_TAG, "InCall VoicePrivacy is disabled");
815 }
816 }
817
818 Collections.sort(response);
819
820 return response;
821 }
822
823 @Override
824 protected Object responseGetPreferredNetworkType(Parcel p) {
825 int [] response = (int[]) responseInts(p);
826
827 if (response.length >= 1) {
828 // Since this is the response for getPreferredNetworkType
829 // we'll assume that it should be the value we want the
830 // vendor ril to take if we reestablish a connection to it.
831 mPreferredNetworkType = response[0];
832 }
833
834 // When the modem responds Phone.NT_MODE_GLOBAL, it means Phone.NT_MODE_WCDMA_PREF
835 if (response[0] == Phone.NT_MODE_GLOBAL) {
836 Rlog.d(RILJ_LOG_TAG, "Overriding network type response from GLOBAL to WCDMA preferred");
837 response[0] = Phone.NT_MODE_WCDMA_PREF;
838 }
839
840 return response;
841 }
842
843 @Override
844 protected Object
845 responseSignalStrength(Parcel p) {
846 int numInts = 12;
847 int response[];
848
849 /* TODO: Add SignalStrength class to match RIL_SignalStrength */
850 response = new int[numInts];
851 for (int i = 0 ; i < numInts ; i++) {
852 response[i] = p.readInt();
853 }
854
855 /* Matching Samsung signal strength to asu.
856 Method taken from Samsungs cdma/gsmSignalStateTracker */
857 response[0] = ((response[0] & 0xFF00) >> 8) * 3; //gsmDbm
858 response[1] = -1; //gsmEcio
859 response[2] = (response[2] < 0)?-120:-response[2]; //cdmaDbm
860 response[3] = (response[3] < 0)?-160:-response[3]; //cdmaEcio
861 response[4] = (response[4] < 0)?-120:-response[4]; //evdoRssi
862 response[5] = (response[5] < 0)?-1:-response[5]; //evdoEcio
863 if(response[6] < 0 || response[6] > 8)
864 response[6] = -1;
865
866 SignalStrength signalStrength = new SignalStrength(
867 response[0], response[1], response[2], response[3], response[4],
868 response[5], response[6], true);
869 return signalStrength;
870 }
871
872 @Override public void
873 getVoiceRadioTechnology(Message result) {
874 RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_RADIO_TECH, result);
875
876 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
877
878 // RIL versions below 7 do not support this request
879 if (mRilVersion >= 7)
880 send(rr);
881 else
882 Rlog.d(RILJ_LOG_TAG, "RIL_REQUEST_VOICE_RADIO_TECH blocked!!!");
883 }
884
885 @Override
886 public void getCdmaSubscriptionSource(Message response) {
887 RILRequest rr = RILRequest.obtain(
888 RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response);
889
890 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
891 Rlog.d(RILJ_LOG_TAG, "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE blocked!!!");
892 //send(rr);
893 }
894}