blob: 588fb1a6e51af695a20ad4e7a2d8d5028fde9613 [file] [log] [blame]
Zvikomborero VIncent Zvikaramba57b385f2016-08-01 11:12:45 -04001/*
2 * Copyright (c) 2014, The CyanogenMod Project. All rights reserved.
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.telephony.Rlog;
23import android.os.AsyncResult;
24import android.os.Message;
25import android.os.Parcel;
26import android.os.SystemProperties;
27import android.telephony.PhoneNumberUtils;
28import android.telephony.SignalStrength;
29import com.android.internal.telephony.uicc.IccCardApplicationStatus;
30import com.android.internal.telephony.uicc.IccCardStatus;
31import java.util.ArrayList;
32import java.util.Collections;
Zvikomborero VIncent Zvikaramba5b1059b2016-08-30 19:36:40 -040033import android.media.AudioManager;
Zvikomborero VIncent Zvikaramba57b385f2016-08-01 11:12:45 -040034
35/**
36 * Qualcomm RIL for Samsung MSM8916 (3G) devices
37 * {@hide}
38 */
39public class SamsungQcomRIL extends RIL {
40
41 private static final int RIL_REQUEST_DIAL_EMERGENCY = 10001;
42 private static final int RIL_UNSOL_ON_SS_LL = 11055;
43
Zvikomborero VIncent Zvikaramba5b1059b2016-08-30 19:36:40 -040044 private AudioManager mAudioManager;
45
Zvikomborero VIncent Zvikaramba57b385f2016-08-01 11:12:45 -040046 public SamsungQcomRIL(Context context, int networkMode, int cdmaSubscription) {
47 super(context, networkMode, cdmaSubscription, null);
Zvikomborero VIncent Zvikaramba5b1059b2016-08-30 19:36:40 -040048 mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
Zvikomborero VIncent Zvikaramba57b385f2016-08-01 11:12:45 -040049 mQANElements = 6;
50 }
51
52 public SamsungQcomRIL(Context context, int preferredNetworkType,
53 int cdmaSubscription, Integer instanceId) {
54 super(context, preferredNetworkType, cdmaSubscription, instanceId);
Zvikomborero VIncent Zvikaramba5b1059b2016-08-30 19:36:40 -040055 mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
Zvikomborero VIncent Zvikaramba57b385f2016-08-01 11:12:45 -040056 mQANElements = 6;
57 }
58
59 @Override
60 public void
61 dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
62 if (PhoneNumberUtils.isEmergencyNumber(address)) {
63 dialEmergencyCall(address, clirMode, result);
64 return;
65 }
66
67 RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
68
69 rr.mParcel.writeString(address);
70 rr.mParcel.writeInt(clirMode);
71 rr.mParcel.writeInt(0); // CallDetails.call_type
72 rr.mParcel.writeInt(1); // CallDetails.call_domain
73 rr.mParcel.writeString(""); // CallDetails.getCsvFromExtras
74
75 if (uusInfo == null) {
76 rr.mParcel.writeInt(0); // UUS information is absent
77 } else {
78 rr.mParcel.writeInt(1); // UUS information is present
79 rr.mParcel.writeInt(uusInfo.getType());
80 rr.mParcel.writeInt(uusInfo.getDcs());
81 rr.mParcel.writeByteArray(uusInfo.getUserData());
82 }
83
84 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
85
86 send(rr);
87 }
88
89 @Override
90 protected Object
91 responseIccCardStatus(Parcel p) {
92 IccCardApplicationStatus appStatus;
93
94 IccCardStatus cardStatus = new IccCardStatus();
95 cardStatus.setCardState(p.readInt());
96 cardStatus.setUniversalPinState(p.readInt());
97 cardStatus.mGsmUmtsSubscriptionAppIndex = p.readInt();
98 cardStatus.mCdmaSubscriptionAppIndex = p.readInt();
99 cardStatus.mImsSubscriptionAppIndex = p.readInt();
100
101 int numApplications = p.readInt();
102
103 // limit to maximum allowed applications
104 if (numApplications > IccCardStatus.CARD_MAX_APPS) {
105 numApplications = IccCardStatus.CARD_MAX_APPS;
106 }
107 cardStatus.mApplications = new IccCardApplicationStatus[numApplications];
108
109 for (int i = 0 ; i < numApplications ; i++) {
110 appStatus = new IccCardApplicationStatus();
111 appStatus.app_type = appStatus.AppTypeFromRILInt(p.readInt());
112 appStatus.app_state = appStatus.AppStateFromRILInt(p.readInt());
113 appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(p.readInt());
114 appStatus.aid = p.readString();
115 appStatus.app_label = p.readString();
116 appStatus.pin1_replaced = p.readInt();
117 appStatus.pin1 = appStatus.PinStateFromRILInt(p.readInt());
118 appStatus.pin2 = appStatus.PinStateFromRILInt(p.readInt());
119 p.readInt(); // pin1_num_retries
120 p.readInt(); // puk1_num_retries
121 p.readInt(); // pin2_num_retries
122 p.readInt(); // puk2_num_retries
123 p.readInt(); // perso_unblock_retries
124
125 cardStatus.mApplications[i] = appStatus;
126 }
127 return cardStatus;
128 }
129
130 @Override
131 protected Object
132 responseCallList(Parcel p) {
133 int num;
134 int voiceSettings;
135 ArrayList<DriverCall> response;
136 DriverCall dc;
137
138 num = p.readInt();
139 response = new ArrayList<DriverCall>(num);
140
141 if (RILJ_LOGV) {
142 riljLog("responseCallList: num=" + num +
143 " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant +
144 " mTestingEmergencyCall=" + mTestingEmergencyCall.get());
145 }
146 for (int i = 0 ; i < num ; i++) {
147 dc = new DriverCall();
148
149 dc.state = DriverCall.stateFromCLCC(p.readInt());
150 dc.index = p.readInt() & 0xff;
151 dc.TOA = p.readInt();
152 dc.isMpty = (0 != p.readInt());
153 dc.isMT = (0 != p.readInt());
154 dc.als = p.readInt();
155 voiceSettings = p.readInt();
156 dc.isVoice = (0 == voiceSettings) ? false : true;
157 boolean isVideo;
158 int call_type = p.readInt(); // Samsung CallDetails
159 int call_domain = p.readInt(); // Samsung CallDetails
160 String csv = p.readString(); // Samsung CallDetails
161 dc.isVoicePrivacy = (0 != p.readInt());
162 dc.number = p.readString();
163 int np = p.readInt();
164 dc.numberPresentation = DriverCall.presentationFromCLIP(np);
165 dc.name = p.readString();
166 dc.namePresentation = DriverCall.presentationFromCLIP(p.readInt());
167 int uusInfoPresent = p.readInt();
168 if (uusInfoPresent == 1) {
169 dc.uusInfo = new UUSInfo();
170 dc.uusInfo.setType(p.readInt());
171 dc.uusInfo.setDcs(p.readInt());
172 byte[] userData = p.createByteArray();
173 dc.uusInfo.setUserData(userData);
174 riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
175 dc.uusInfo.getType(), dc.uusInfo.getDcs(),
176 dc.uusInfo.getUserData().length));
177 riljLogv("Incoming UUS : data (string)="
178 + new String(dc.uusInfo.getUserData()));
179 riljLogv("Incoming UUS : data (hex): "
180 + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
181 } else {
182 riljLogv("Incoming UUS : NOT present!");
183 }
184
185 // Make sure there's a leading + on addresses with a TOA of 145
186 dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
187
188 response.add(dc);
189
190 if (dc.isVoicePrivacy) {
191 mVoicePrivacyOnRegistrants.notifyRegistrants();
192 riljLog("InCall VoicePrivacy is enabled");
193 } else {
194 mVoicePrivacyOffRegistrants.notifyRegistrants();
195 riljLog("InCall VoicePrivacy is disabled");
196 }
197 }
198
199 Collections.sort(response);
200
201 if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) {
202 if (mEmergencyCallbackModeRegistrant != null) {
203 riljLog("responseCallList: call ended, testing emergency call," +
204 " notify ECM Registrants");
205 mEmergencyCallbackModeRegistrant.notifyRegistrant();
206 }
207 }
208
209 return response;
210 }
211
212 @Override
213 protected Object
214 responseSignalStrength(Parcel p) {
215 int gsmSignalStrength = p.readInt() & 0xff;
216 int gsmBitErrorRate = p.readInt();
217 int cdmaDbm = p.readInt();
218 int cdmaEcio = p.readInt();
219 int evdoDbm = p.readInt();
220 int evdoEcio = p.readInt();
221 int evdoSnr = p.readInt();
222 int lteSignalStrength = p.readInt();
223 int lteRsrp = p.readInt();
224 int lteRsrq = p.readInt();
225 int lteRssnr = p.readInt();
226 int lteCqi = p.readInt();
227 int tdScdmaRscp = p.readInt();
228 // constructor sets default true, makeSignalStrengthFromRilParcel does not set it
229 boolean isGsm = true;
230
231 if ((lteSignalStrength & 0xff) == 255 || lteSignalStrength == 99) {
232 lteSignalStrength = 99;
233 lteRsrp = SignalStrength.INVALID;
234 lteRsrq = SignalStrength.INVALID;
235 lteRssnr = SignalStrength.INVALID;
236 lteCqi = SignalStrength.INVALID;
237 } else {
238 lteSignalStrength &= 0xff;
239 }
240
241 if (RILJ_LOGD)
242 riljLog("gsmSignalStrength:" + gsmSignalStrength + " gsmBitErrorRate:" + gsmBitErrorRate +
243 " cdmaDbm:" + cdmaDbm + " cdmaEcio:" + cdmaEcio + " evdoDbm:" + evdoDbm +
244 " evdoEcio: " + evdoEcio + " evdoSnr:" + evdoSnr +
245 " lteSignalStrength:" + lteSignalStrength + " lteRsrp:" + lteRsrp +
246 " lteRsrq:" + lteRsrq + " lteRssnr:" + lteRssnr + " lteCqi:" + lteCqi +
247 " tdScdmaRscp:" + tdScdmaRscp + " isGsm:" + (isGsm ? "true" : "false"));
248
249 return new SignalStrength(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, evdoDbm,
250 evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, lteRsrq, lteRssnr, lteCqi,
251 tdScdmaRscp, isGsm);
252 }
253
254 @Override
255 protected void
256 processUnsolicited (Parcel p) {
257 Object ret;
258 int dataPosition = p.dataPosition();
259 int response = p.readInt();
260 int newResponse = response;
261
262 switch(response) {
263 case RIL_UNSOL_ON_SS_LL:
264 newResponse = RIL_UNSOL_ON_SS;
265 break;
266 }
267 if (newResponse != response) {
268 p.setDataPosition(dataPosition);
269 p.writeInt(newResponse);
270 }
271 p.setDataPosition(dataPosition);
272 super.processUnsolicited(p);
273 }
274
275 @Override
276 public void
277 acceptCall (Message result) {
278 RILRequest rr
279 = RILRequest.obtain(RIL_REQUEST_ANSWER, result);
280
281 rr.mParcel.writeInt(1);
282 rr.mParcel.writeInt(0);
283
284 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
285
286 send(rr);
287 }
288
289 private void
290 dialEmergencyCall(String address, int clirMode, Message result) {
291 RILRequest rr;
292
293 rr = RILRequest.obtain(RIL_REQUEST_DIAL_EMERGENCY, result);
294 rr.mParcel.writeString(address);
295 rr.mParcel.writeInt(clirMode);
296 rr.mParcel.writeInt(0); // CallDetails.call_type
297 rr.mParcel.writeInt(3); // CallDetails.call_domain
298 rr.mParcel.writeString(""); // CallDetails.getCsvFromExtra
299 rr.mParcel.writeInt(0); // Unknown
300
301 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
302
303 send(rr);
304 }
305
306 @Override
307 protected RILRequest
308 processSolicited (Parcel p) {
309 int serial, error;
310 boolean found = false;
311 int dataPosition = p.dataPosition(); // save off position within the Parcel
312 serial = p.readInt();
313 error = p.readInt();
314 RILRequest rr = null;
315 /* Pre-process the reply before popping it */
316 synchronized (mRequestList) {
317 RILRequest tr = mRequestList.get(serial);
318 if (tr != null && tr.mSerial == serial) {
319 if (error == 0 || p.dataAvail() > 0) {
320 try {switch (tr.mRequest) {
321 /* Get those we're interested in */
322 case RIL_REQUEST_DATA_REGISTRATION_STATE:
323 rr = tr;
324 break;
325 }} catch (Throwable thr) {
326 // Exceptions here usually mean invalid RIL responses
327 if (tr.mResult != null) {
328 AsyncResult.forMessage(tr.mResult, null, thr);
329 tr.mResult.sendToTarget();
330 }
331 return tr;
332 }
333 }
334 }
335 }
336 if (rr == null) {
337 /* Nothing we care about, go up */
338 p.setDataPosition(dataPosition);
339 // Forward responses that we are not overriding to the super class
340 return super.processSolicited(p);
341 }
342 rr = findAndRemoveRequestFromList(serial);
343 if (rr == null) {
344 return rr;
345 }
346 Object ret = null;
347 if (error == 0 || p.dataAvail() > 0) {
348 switch (rr.mRequest) {
349 case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseDataRegistrationState(p); break;
350 default:
351 throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
352 }
353 //break;
354 }
355 if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
356 + " " + retToString(rr.mRequest, ret));
357 if (rr.mResult != null) {
358 AsyncResult.forMessage(rr.mResult, ret, null);
359 rr.mResult.sendToTarget();
360 }
361 return rr;
362 }
363
364 private Object
365 responseDataRegistrationState(Parcel p) {
366 String response[] = (String[])responseStrings(p);
367 /* DANGER WILL ROBINSON
368 * In some cases from Vodaphone we are receiving a RAT of 102
369 * while in tunnels of the metro. Lets Assume that if we
370 * receive 102 we actually want a RAT of 2 for EDGE service */
371 if (response.length > 4 &&
372 response[0].equals("1") &&
373 response[3].equals("102")) {
374 response[3] = "2";
375 }
376 return response;
377 }
Zvikomborero VIncent Zvikaramba5b1059b2016-08-30 19:36:40 -0400378
379 private void setWbAmr(int state) {
380 if (state == 1) {
381 Rlog.d(RILJ_LOG_TAG, "setWbAmr(): setting audio parameter - wb_amr=on");
382 mAudioManager.setParameters("wb_amr=on");
383 }else if (state == 0) {
384 Rlog.d(RILJ_LOG_TAG, "setWbAmr(): setting audio parameter - wb_amr=off");
385 mAudioManager.setParameters("wb_amr=off");
386 }
387 }
Zvikomborero VIncent Zvikaramba57b385f2016-08-01 11:12:45 -0400388}