blob: 1985d074f7e8ee15e6311052d706b6d18a7df032 [file] [log] [blame]
Zvikomborero Vincent Zvikarambae3990e42016-07-28 04:53:57 -04001/*
2 * Copyright (C) 2012-2014 The CyanogenMod 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;
18
19import static com.android.internal.telephony.RILConstants.*;
20
21import android.content.Context;
22import android.media.AudioManager;
23import android.os.AsyncResult;
24import android.os.Handler;
25import android.os.HandlerThread;
26import android.os.Looper;
27import android.os.Message;
28import android.os.Parcel;
29import android.telephony.SmsMessage;
30import android.os.SystemProperties;
31import android.os.SystemClock;
32import android.provider.Settings;
33import android.text.TextUtils;
34import android.telephony.Rlog;
35
36import android.telephony.SignalStrength;
37
38import android.telephony.PhoneNumberUtils;
39import com.android.internal.telephony.RILConstants;
40import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
41import com.android.internal.telephony.cdma.CdmaInformationRecords;
42import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec;
43import com.android.internal.telephony.cdma.SignalToneUtil;
44
45import java.io.IOException;
46import java.util.ArrayList;
47import java.util.Collections;
48
49import com.android.internal.telephony.uicc.IccCardApplicationStatus;
50import com.android.internal.telephony.uicc.IccCardStatus;
51
52/**
53 * Qualcomm RIL for the Samsung family.
54 * Quad core Exynos4 with Qualcomm modem and later is supported
55 * Snapdragon S3 and later is supported
56 * This RIL is univerisal meaning it supports CDMA and GSM radio.
57 * Handles most GSM and CDMA cases.
58 * {@hide}
59 */
60public class SamsungQualcommRIL extends RIL implements CommandsInterface {
61
62 private AudioManager mAudioManager;
63
64 private Object mSMSLock = new Object();
65 private boolean mIsSendingSMS = false;
66 private boolean isGSM = false;
67 public static final long SEND_SMS_TIMEOUT_IN_MS = 30000;
68 private boolean oldRilState = needsOldRilFeature("exynos4RadioState");
69 private boolean googleEditionSS = needsOldRilFeature("googleEditionSS");
70 private boolean driverCall = needsOldRilFeature("newDriverCall");
71 private boolean driverCallU = needsOldRilFeature("newDriverCallU");
72 private boolean dialCode = needsOldRilFeature("newDialCode");
73 public SamsungQualcommRIL(Context context, int networkMode,
74 int cdmaSubscription) {
75 super(context, networkMode, cdmaSubscription);
76 mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
77 }
78
79 @Override
80 protected Object
81 responseIccCardStatus(Parcel p) {
82 IccCardApplicationStatus appStatus;
83
84 IccCardStatus cardStatus = new IccCardStatus();
85 cardStatus.setCardState(p.readInt());
86 cardStatus.setUniversalPinState(p.readInt());
87 cardStatus.mGsmUmtsSubscriptionAppIndex = p.readInt();
88 cardStatus.mCdmaSubscriptionAppIndex = p.readInt();
89 cardStatus.mImsSubscriptionAppIndex = p.readInt();
90
91 int numApplications = p.readInt();
92
93 // limit to maximum allowed applications
94 if (numApplications > IccCardStatus.CARD_MAX_APPS) {
95 numApplications = IccCardStatus.CARD_MAX_APPS;
96 }
97 cardStatus.mApplications = new IccCardApplicationStatus[numApplications];
98
99 appStatus = new IccCardApplicationStatus();
100 for (int i = 0 ; i < numApplications ; i++) {
101 if (i!=0) {
102 appStatus = new IccCardApplicationStatus();
103 }
104 appStatus.app_type = appStatus.AppTypeFromRILInt(p.readInt());
105 appStatus.app_state = appStatus.AppStateFromRILInt(p.readInt());
106 appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(p.readInt());
107 appStatus.aid = p.readString();
108 appStatus.app_label = p.readString();
109 appStatus.pin1_replaced = p.readInt();
110 appStatus.pin1 = appStatus.PinStateFromRILInt(p.readInt());
111 appStatus.pin2 = appStatus.PinStateFromRILInt(p.readInt());
112 p.readInt(); // remaining_count_pin1 - pin1_num_retries
113 p.readInt(); // remaining_count_puk1 - puk1_num_retries
114 p.readInt(); // remaining_count_pin2 - pin2_num_retries
115 p.readInt(); // remaining_count_puk2 - puk2_num_retries
116 p.readInt(); // - perso_unblock_retries
117 cardStatus.mApplications[i] = appStatus;
118 }
119 if (numApplications==1 && !isGSM && appStatus.app_type == appStatus.AppTypeFromRILInt(2)) { // usim
120 cardStatus.mApplications = new IccCardApplicationStatus[numApplications+2];
121 cardStatus.mGsmUmtsSubscriptionAppIndex = 0;
122 cardStatus.mApplications[cardStatus.mGsmUmtsSubscriptionAppIndex]=appStatus;
123 cardStatus.mCdmaSubscriptionAppIndex = 1;
124 cardStatus.mImsSubscriptionAppIndex = 2;
125 IccCardApplicationStatus appStatus2 = new IccCardApplicationStatus();
126 appStatus2.app_type = appStatus2.AppTypeFromRILInt(4); // csim state
127 appStatus2.app_state = appStatus.app_state;
128 appStatus2.perso_substate = appStatus.perso_substate;
129 appStatus2.aid = appStatus.aid;
130 appStatus2.app_label = appStatus.app_label;
131 appStatus2.pin1_replaced = appStatus.pin1_replaced;
132 appStatus2.pin1 = appStatus.pin1;
133 appStatus2.pin2 = appStatus.pin2;
134 cardStatus.mApplications[cardStatus.mCdmaSubscriptionAppIndex] = appStatus2;
135 IccCardApplicationStatus appStatus3 = new IccCardApplicationStatus();
136 appStatus3.app_type = appStatus3.AppTypeFromRILInt(5); // ims state
137 appStatus3.app_state = appStatus.app_state;
138 appStatus3.perso_substate = appStatus.perso_substate;
139 appStatus3.aid = appStatus.aid;
140 appStatus3.app_label = appStatus.app_label;
141 appStatus3.pin1_replaced = appStatus.pin1_replaced;
142 appStatus3.pin1 = appStatus.pin1;
143 appStatus3.pin2 = appStatus.pin2;
144 cardStatus.mApplications[cardStatus.mImsSubscriptionAppIndex] = appStatus3;
145 }
146 return cardStatus;
147 }
148
149 @Override
150 public void
151 sendCdmaSms(byte[] pdu, Message result) {
152 smsLock();
153 super.sendCdmaSms(pdu, result);
154 }
155
156 @Override
157 public void
158 sendSMS (String smscPDU, String pdu, Message result) {
159 smsLock();
160 super.sendSMS(smscPDU, pdu, result);
161 }
162
163 private void smsLock(){
164 // Do not send a new SMS until the response for the previous SMS has been received
165 // * for the error case where the response never comes back, time out after
166 // 30 seconds and just try the next SEND_SMS
167 synchronized (mSMSLock) {
168 long timeoutTime = SystemClock.elapsedRealtime() + SEND_SMS_TIMEOUT_IN_MS;
169 long waitTimeLeft = SEND_SMS_TIMEOUT_IN_MS;
170 while (mIsSendingSMS && (waitTimeLeft > 0)) {
171 Rlog.d(RILJ_LOG_TAG, "sendSMS() waiting for response of previous SEND_SMS");
172 try {
173 mSMSLock.wait(waitTimeLeft);
174 } catch (InterruptedException ex) {
175 // ignore the interrupt and rewait for the remainder
176 }
177 waitTimeLeft = timeoutTime - SystemClock.elapsedRealtime();
178 }
179 if (waitTimeLeft <= 0) {
180 Rlog.e(RILJ_LOG_TAG, "sendSms() timed out waiting for response of previous CDMA_SEND_SMS");
181 }
182 mIsSendingSMS = true;
183 }
184
185 }
186
187 @Override
188 protected Object responseSignalStrength(Parcel p) {
189 int numInts = 12;
190 int response[];
191
192 // This is a mashup of algorithms used in
193 // SamsungQualcommUiccRIL.java
194
195 // Get raw data
196 response = new int[numInts];
197 for (int i = 0; i < numInts; i++) {
198 response[i] = p.readInt();
199 }
200 //gsm
201 response[0] &= 0xff; //gsmDbm
202
203 //cdma
204 // Take just the least significant byte as the signal strength
205 response[2] %= 256;
206 response[4] %= 256;
207
208 // RIL_LTE_SignalStrength
209 if (googleEditionSS && !isGSM){
210 response[8] = response[2];
211 }else if ((response[7] & 0xff) == 255 || response[7] == 99) {
212 // If LTE is not enabled, clear LTE results
213 // 7-11 must be -1 for GSM signal strength to be used (see
214 // frameworks/base/telephony/java/android/telephony/SignalStrength.java)
215 // make sure lte is disabled
216 response[7] = 99;
217 response[8] = SignalStrength.INVALID;
218 response[9] = SignalStrength.INVALID;
219 response[10] = SignalStrength.INVALID;
220 response[11] = SignalStrength.INVALID;
221 }else{ // lte is gsm on samsung/qualcomm cdma stack
222 response[7] &= 0xff;
223 }
224
225 return new SignalStrength(response[0], response[1], response[2], response[3], response[4], response[5], response[6], response[7], response[8], response[9], response[10], response[11], (p.readInt() != 0));
226
227 }
228
229 @Override
230 protected RadioState getRadioStateFromInt(int stateInt) {
231 if(!oldRilState)
232 super.getRadioStateFromInt(stateInt);
233 RadioState state;
234
235 /* RIL_RadioState ril.h */
236 switch(stateInt) {
237 case 0: state = RadioState.RADIO_OFF; break;
238 case 1:
239 case 2: state = RadioState.RADIO_UNAVAILABLE; break;
240 case 4:
241 // When SIM is PIN-unlocked, RIL doesn't respond with RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED.
242 // We notify the system here.
243 Rlog.d(RILJ_LOG_TAG, "SIM is PIN-unlocked now");
244 if (mIccStatusChangedRegistrants != null) {
245 mIccStatusChangedRegistrants.notifyRegistrants();
246 }
247 case 3:
248 case 5:
249 case 6:
250 case 7:
251 case 8:
252 case 9:
253 case 10:
254 case 13: state = RadioState.RADIO_ON; break;
255
256 default:
257 throw new RuntimeException(
258 "Unrecognized RIL_RadioState: " + stateInt);
259 }
260 return state;
261 }
262
263 @Override
264 public void setPhoneType(int phoneType){
265 super.setPhoneType(phoneType);
266 isGSM = (phoneType != RILConstants.CDMA_PHONE);
267 }
268
269 @Override
270 protected Object
271 responseCallList(Parcel p) {
272 samsungDriverCall = driverCallU || (driverCall && !isGSM) || mRilVersion < 7 ? false : true;
273 return super.responseCallList(p);
274 }
275
276 @Override
277 protected void
278 processUnsolicited (Parcel p) {
279 Object ret;
280 int dataPosition = p.dataPosition(); // save off position within the Parcel
281 int response = p.readInt();
282
283 switch(response) {
284 case RIL_UNSOL_RIL_CONNECTED: // Fix for NV/RUIM setting on CDMA SIM devices
285 // skip getcdmascriptionsource as if qualcomm handles it in the ril binary
286 ret = responseInts(p);
287 setRadioPower(false, null);
288 setPreferredNetworkType(mPreferredNetworkType, null);
289 int cdmaSubscription = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.CDMA_SUBSCRIPTION_MODE, -1);
290 if(cdmaSubscription != -1) {
291 setCdmaSubscriptionSource(mCdmaSubscription, null);
292 }
293 setCellInfoListRate(Integer.MAX_VALUE, null);
294 notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
295 break;
296 case RIL_UNSOL_NITZ_TIME_RECEIVED:
297 handleNitzTimeReceived(p);
298 break;
299 // SAMSUNG STATES
300 case SamsungExynos4RIL.RIL_UNSOL_AM:
301 ret = responseString(p);
302 String amString = (String) ret;
303 Rlog.d(RILJ_LOG_TAG, "Executing AM: " + amString);
304
305 try {
306 Runtime.getRuntime().exec("am " + amString);
307 } catch (IOException e) {
308 e.printStackTrace();
309 Rlog.e(RILJ_LOG_TAG, "am " + amString + " could not be executed.");
310 }
311 break;
312 case SamsungExynos4RIL.RIL_UNSOL_RESPONSE_HANDOVER:
313 ret = responseVoid(p);
314 break;
315 case 1036:
316 ret = responseVoid(p);
317 break;
318 case SamsungExynos4RIL.RIL_UNSOL_WB_AMR_STATE:
319 ret = responseInts(p);
320 setWbAmr(((int[])ret)[0]);
321 break;
322 default:
323 // Rewind the Parcel
324 p.setDataPosition(dataPosition);
325
326 // Forward responses that we are not overriding to the super class
327 super.processUnsolicited(p);
328 return;
329 }
330
331 }
332
333 @Override
334 protected RILRequest
335 processSolicited (Parcel p) {
336 int serial, error;
337 boolean found = false;
338
339 serial = p.readInt();
340 error = p.readInt();
341
342 RILRequest rr;
343
344 rr = findAndRemoveRequestFromList(serial);
345
346 if (rr == null) {
347 Rlog.w(RILJ_LOG_TAG, "Unexpected solicited response! sn: "
348 + serial + " error: " + error);
349 return null;
350 }
351
352 Object ret = null;
353
354 if (error == 0 || p.dataAvail() > 0) {
355 // either command succeeds or command fails but with data payload
356 try {switch (rr.mRequest) {
357 /*
358 cat libs/telephony/ril_commands.h \
359 | egrep "^ *{RIL_" \
360 | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
361 */
362 case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break;
363 case RIL_REQUEST_ENTER_SIM_PIN: ret = responseInts(p); break;
364 case RIL_REQUEST_ENTER_SIM_PUK: ret = responseInts(p); break;
365 case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseInts(p); break;
366 case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseInts(p); break;
367 case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseInts(p); break;
368 case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseInts(p); break;
369 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseInts(p); break;
370 case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break;
371 case RIL_REQUEST_DIAL: ret = responseVoid(p); break;
372 case RIL_REQUEST_GET_IMSI: ret = responseString(p); break;
373 case RIL_REQUEST_HANGUP: ret = responseVoid(p); break;
374 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break;
375 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: {
376 if (mTestingEmergencyCall.getAndSet(false)) {
377 if (mEmergencyCallbackModeRegistrant != null) {
378 riljLog("testing emergency call, notify ECM Registrants");
379 mEmergencyCallbackModeRegistrant.notifyRegistrant();
380 }
381 }
382 ret = responseVoid(p);
383 break;
384 }
385 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break;
386 case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break;
387 case RIL_REQUEST_UDUB: ret = responseVoid(p); break;
388 case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break;
389 case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
390 //modification start
391 // prevent exceptions from happenimg because the null value is null or a hexadecimel. so convert if it is not null
392 case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseVoiceDataRegistrationState(p); break;
393 case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseVoiceDataRegistrationState(p); break;
394 // this fixes bogus values the modem creates
395 // sometimes the ril may print out
396 // (always on sprint)
397 // sprint: (empty,empty,31000)
398 // this problemaic on sprint, lte won't start, response is slow
399 //speeds up response time on eherpderpd/lte networks
400 case RIL_REQUEST_OPERATOR: ret = operatorCheck(p); break;
401 //end modification
402 case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break;
403 case RIL_REQUEST_DTMF: ret = responseVoid(p); break;
404 case RIL_REQUEST_SEND_SMS: ret = responseSMS(p); break;
405 case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret = responseSMS(p); break;
406 case RIL_REQUEST_SETUP_DATA_CALL: ret = responseSetupDataCall(p); break;
407 case RIL_REQUEST_SIM_IO: ret = responseICC_IO(p); break;
408 case RIL_REQUEST_SEND_USSD: ret = responseVoid(p); break;
409 case RIL_REQUEST_CANCEL_USSD: ret = responseVoid(p); break;
410 case RIL_REQUEST_GET_CLIR: ret = responseInts(p); break;
411 case RIL_REQUEST_SET_CLIR: ret = responseVoid(p); break;
412 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret = responseCallForward(p); break;
413 case RIL_REQUEST_SET_CALL_FORWARD: ret = responseVoid(p); break;
414 case RIL_REQUEST_QUERY_CALL_WAITING: ret = responseInts(p); break;
415 case RIL_REQUEST_SET_CALL_WAITING: ret = responseVoid(p); break;
416 case RIL_REQUEST_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
417 case RIL_REQUEST_GET_IMEI: ret = responseString(p); break;
418 case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break;
419 case RIL_REQUEST_ANSWER: ret = responseVoid(p); break;
420 case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseVoid(p); break;
421 case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break;
422 case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break;
423 case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break;
424 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break;
425 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break;
426 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret = responseVoid(p); break;
427 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret = responseOperatorInfos(p); break;
428 case RIL_REQUEST_DTMF_START: ret = responseVoid(p); break;
429 case RIL_REQUEST_DTMF_STOP: ret = responseVoid(p); break;
430 case RIL_REQUEST_BASEBAND_VERSION: ret = responseString(p); break;
431 case RIL_REQUEST_SEPARATE_CONNECTION: ret = responseVoid(p); break;
432 case RIL_REQUEST_SET_MUTE: ret = responseVoid(p); break;
433 case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break;
434 case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break;
435 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret = responseInts(p); break;
436 case RIL_REQUEST_DATA_CALL_LIST: ret = responseDataCallList(p); break;
437 case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break;
438 case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break;
439 case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break;
440 case RIL_REQUEST_SCREEN_STATE: ret = responseVoid(p); break;
441 case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break;
442 case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break;
443 case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break;
444 case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break;
445 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break;
446 case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break;
447 case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break;
448 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break;
449 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break;
450 case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break;
451 case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break;
452 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break;
453 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseGetPreferredNetworkType(p); break;
454 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
455 case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
456 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break;
457 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break;
458 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break;
459 case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break;
460 case RIL_REQUEST_QUERY_TTY_MODE: ret = responseInts(p); break;
461 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret = responseVoid(p); break;
462 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret = responseInts(p); break;
463 case RIL_REQUEST_CDMA_FLASH: ret = responseVoid(p); break;
464 case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break;
465 case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break;
466 case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
467 case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break;
468 case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
469 case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
470 case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break;
471 case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
472 case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
473 case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret = responseVoid(p); break;
474 case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break;
475 case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break;
476 case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break;
477 case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break;
478 case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
479 case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
480 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
481 case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
482 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
483 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break;
484 case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break;
485 case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
486 case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
487 case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break;
488 case RIL_REQUEST_GET_CELL_INFO_LIST: ret = responseCellInfoList(p); break;
489 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: ret = responseVoid(p); break;
490 case RIL_REQUEST_SET_INITIAL_ATTACH_APN: ret = responseVoid(p); break;
491 case RIL_REQUEST_IMS_REGISTRATION_STATE: ret = responseInts(p); break;
492 case RIL_REQUEST_IMS_SEND_SMS: ret = responseSMS(p); break;
493 default:
494 throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
495 //break;
496 }} catch (Throwable tr) {
497 // Exceptions here usually mean invalid RIL responses
498
499 Rlog.w(RILJ_LOG_TAG, rr.serialString() + "< "
500 + requestToString(rr.mRequest)
501 + " exception, possible invalid RIL response", tr);
502
503 if (rr.mResult != null) {
504 AsyncResult.forMessage(rr.mResult, null, tr);
505 rr.mResult.sendToTarget();
506 }
507 return rr;
508 }
509 }
510
511 // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789.
512 // This is needed otherwise we don't automatically transition to the main lock
513 // screen when the pin or puk is entered incorrectly.
514 switch (rr.mRequest) {
515 case RIL_REQUEST_ENTER_SIM_PUK:
516 case RIL_REQUEST_ENTER_SIM_PUK2:
517 if (mIccStatusChangedRegistrants != null) {
518 if (RILJ_LOGD) {
519 riljLog("ON enter sim puk fakeSimStatusChanged: reg count="
520 + mIccStatusChangedRegistrants.size());
521 }
522 mIccStatusChangedRegistrants.notifyRegistrants();
523 }
524 break;
525 }
526
527 if (error != 0) {
528 switch (rr.mRequest) {
529 case RIL_REQUEST_ENTER_SIM_PIN:
530 case RIL_REQUEST_ENTER_SIM_PIN2:
531 case RIL_REQUEST_CHANGE_SIM_PIN:
532 case RIL_REQUEST_CHANGE_SIM_PIN2:
533 case RIL_REQUEST_SET_FACILITY_LOCK:
534 if (mIccStatusChangedRegistrants != null) {
535 if (RILJ_LOGD) {
536 riljLog("ON some errors fakeSimStatusChanged: reg count="
537 + mIccStatusChangedRegistrants.size());
538 }
539 mIccStatusChangedRegistrants.notifyRegistrants();
540 }
541 break;
542 }
543
544 rr.onError(error, ret);
545 } else {
546
547 if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
548 + " " + retToString(rr.mRequest, ret));
549
550 if (rr.mResult != null) {
551 AsyncResult.forMessage(rr.mResult, ret, null);
552 rr.mResult.sendToTarget();
553 }
554 }
555 return rr;
556 }
557
558 // CDMA FIXES, this fixes bogus values in nv/sim on d2/jf/t0 cdma family or bogus information from sim card
559 private Object
560 operatorCheck(Parcel p) {
561 String response[] = (String[])responseStrings(p);
562 for(int i=0; i<2; i++){
563 if (response[i]!= null){
564 response[i] = Operators.operatorReplace(response[i]);
565 }
566 }
567 return response;
568 }
569 // handle exceptions
570 private Object
571 responseVoiceDataRegistrationState(Parcel p) {
572 String response[] = (String[])responseStrings(p);
573 if (isGSM){
574 return response;
575 }
576 if ( response.length>=10){
577 for(int i=6; i<=9; i++){
578 if (response[i]== null){
579 response[i]=Integer.toString(Integer.MAX_VALUE);
580 } else {
581 try {
582 Integer.parseInt(response[i]);
583 } catch(NumberFormatException e) {
584 response[i]=Integer.toString(Integer.parseInt(response[i],16));
585 }
586 }
587 }
588 }
589
590 return response;
591 }
592 // has no effect
593 // for debugging purposes , just generate out anything from response
594 public static String s(String a[]){
595 StringBuffer result = new StringBuffer();
596
597 for (int i = 0; i < a.length; i++) {
598 result.append( a[i] );
599 result.append(",");
600 }
601 return result.toString();
602 }
603 // end of cdma fix
604
605 /**
606 * Set audio parameter "wb_amr" for HD-Voice (Wideband AMR).
607 *
608 * @param state: 0 = unsupported, 1 = supported.
609 * REQUIRED FOR JF FAMILY THIS SETS THE INFORMATION
610 * CRASHES WITHOUT THIS FUNCTION
611 * part of the new csd binary
612 */
613 private void setWbAmr(int state) {
614 if (state == 1) {
615 Rlog.d(RILJ_LOG_TAG, "setWbAmr(): setting audio parameter - wb_amr=on");
616 mAudioManager.setParameters("wide_voice_enable=true");
617 }else if (state == 0) {
618 Rlog.d(RILJ_LOG_TAG, "setWbAmr(): setting audio parameter - wb_amr=off");
619 mAudioManager.setParameters("wide_voice_enable=false");
620 }
621 }
622
623 // Workaround for Samsung CDMA "ring of death" bug:
624 //
625 // Symptom: As soon as the phone receives notice of an incoming call, an
626 // audible "old fashioned ring" is emitted through the earpiece and
627 // persists through the duration of the call, or until reboot if the call
628 // isn't answered.
629 //
630 // Background: The CDMA telephony stack implements a number of "signal info
631 // tones" that are locally generated by ToneGenerator and mixed into the
632 // voice call path in response to radio RIL_UNSOL_CDMA_INFO_REC requests.
633 // One of these tones, IS95_CONST_IR_SIG_IS54B_L, is requested by the
634 // radio just prior to notice of an incoming call when the voice call
635 // path is muted. CallNotifier is responsible for stopping all signal
636 // tones (by "playing" the TONE_CDMA_SIGNAL_OFF tone) upon receipt of a
637 // "new ringing connection", prior to unmuting the voice call path.
638 //
639 // Problem: CallNotifier's incoming call path is designed to minimize
640 // latency to notify users of incoming calls ASAP. Thus,
641 // SignalInfoTonePlayer requests are handled asynchronously by spawning a
642 // one-shot thread for each. Unfortunately the ToneGenerator API does
643 // not provide a mechanism to specify an ordering on requests, and thus,
644 // unexpected thread interleaving may result in ToneGenerator processing
645 // them in the opposite order that CallNotifier intended. In this case,
646 // playing the "signal off" tone first, followed by playing the "old
647 // fashioned ring" indefinitely.
648 //
649 // Solution: An API change to ToneGenerator is required to enable
650 // SignalInfoTonePlayer to impose an ordering on requests (i.e., drop any
651 // request that's older than the most recent observed). Such a change,
652 // or another appropriate fix should be implemented in AOSP first.
653 //
654 // Workaround: Intercept RIL_UNSOL_CDMA_INFO_REC requests from the radio,
655 // check for a signal info record matching IS95_CONST_IR_SIG_IS54B_L, and
656 // drop it so it's never seen by CallNotifier. If other signal tones are
657 // observed to cause this problem, they should be dropped here as well.
658 @Override
659 protected void notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
660 final int response = RIL_UNSOL_CDMA_INFO_REC;
661
662 if (infoRec.record instanceof CdmaSignalInfoRec) {
663 CdmaSignalInfoRec sir = (CdmaSignalInfoRec) infoRec.record;
664 if (sir != null
665 && sir.isPresent
666 && sir.signalType == SignalToneUtil.IS95_CONST_IR_SIGNAL_IS54B
667 && sir.alertPitch == SignalToneUtil.IS95_CONST_IR_ALERT_MED
668 && sir.signal == SignalToneUtil.IS95_CONST_IR_SIG_IS54B_L) {
669
670 Rlog.d(RILJ_LOG_TAG, "Dropping \"" + responseToString(response) + " "
671 + retToString(response, sir)
672 + "\" to prevent \"ring of death\" bug.");
673 return;
674 }
675 }
676
677 super.notifyRegistrantsCdmaInfoRec(infoRec);
678 }
679
680 private void
681 handleNitzTimeReceived(Parcel p) {
682 String nitz = (String)responseString(p);
683 //if (RILJ_LOGD) unsljLogRet(RIL_UNSOL_NITZ_TIME_RECEIVED, nitz);
684
685 // has bonus long containing milliseconds since boot that the NITZ
686 // time was received
687 long nitzReceiveTime = p.readLong();
688
689 Object[] result = new Object[2];
690
691 String fixedNitz = nitz;
692 String[] nitzParts = nitz.split(",");
693 if (nitzParts.length == 4) {
694 // 0=date, 1=time+zone, 2=dst, 3=garbage that confuses GsmServiceStateTracker (so remove it)
695 fixedNitz = nitzParts[0]+","+nitzParts[1]+","+nitzParts[2]+",";
696 }
697
698 result[0] = fixedNitz;
699 result[1] = Long.valueOf(nitzReceiveTime);
700
701 boolean ignoreNitz = SystemProperties.getBoolean(
702 TelephonyProperties.PROPERTY_IGNORE_NITZ, false);
703
704 if (ignoreNitz) {
705 if (RILJ_LOGD) riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED");
706 } else {
707 if (mNITZTimeRegistrant != null) {
708 mNITZTimeRegistrant
709 .notifyRegistrant(new AsyncResult (null, result, null));
710 } else {
711 // in case NITZ time registrant isnt registered yet
712 mLastNITZTimeInfo = result;
713 }
714 }
715 }
716
717 @Override
718 protected Object
719 responseSMS(Parcel p) {
720 // Notify that sendSMS() can send the next SMS
721 synchronized (mSMSLock) {
722 mIsSendingSMS = false;
723 mSMSLock.notify();
724 }
725
726 return super.responseSMS(p);
727 }
728
729 @Override
730 public void
731 dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
732 if(!dialCode){
733 super.dial(address, clirMode, uusInfo, result);
734 return;
735 }
736 RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
737
738 rr.mParcel.writeString(address);
739 rr.mParcel.writeInt(clirMode);
740 rr.mParcel.writeInt(0);
741 rr.mParcel.writeInt(1);
742 rr.mParcel.writeString("");
743
744 if (uusInfo == null) {
745 rr.mParcel.writeInt(0); // UUS information is absent
746 } else {
747 rr.mParcel.writeInt(1); // UUS information is present
748 rr.mParcel.writeInt(uusInfo.getType());
749 rr.mParcel.writeInt(uusInfo.getDcs());
750 rr.mParcel.writeByteArray(uusInfo.getUserData());
751 }
752
753 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
754
755 send(rr);
756 }
757
758 //this method is used in the search network functionality.
759 // in mobile network setting-> network operators
760 @Override
761 protected Object
762 responseOperatorInfos(Parcel p) {
763 String strings[] = (String [])responseStrings(p);
764 ArrayList<OperatorInfo> ret;
765
766 if (strings.length % mQANElements != 0) {
767 throw new RuntimeException(
768 "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
769 + strings.length + " strings, expected multiple of " + mQANElements);
770 }
771
772 ret = new ArrayList<OperatorInfo>(strings.length / mQANElements);
773 Operators init = null;
774 if (strings.length != 0) {
775 init = new Operators();
776 }
777 for (int i = 0 ; i < strings.length ; i += mQANElements) {
778 String temp = init.unOptimizedOperatorReplace(strings[i+0]);
779 ret.add (
780 new OperatorInfo(
781 temp, //operatorAlphaLong
782 temp,//operatorAlphaShort
783 strings[i+2],//operatorNumeric
784 strings[i+3]));//state
785 }
786
787 return ret;
788 }
789}