Fix setCdmaBroadcastConfig in RIL.java to include all categories.
[android/platform/frameworks/opt/telephony.git] / src / java / com / android / internal / telephony / RIL.java
1 /*
2  * Copyright (C) 2006 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
17 package com.android.internal.telephony;
18
19 import static com.android.internal.telephony.RILConstants.*;
20 import static com.android.internal.util.Preconditions.checkNotNull;
21
22 import android.content.Context;
23 import android.hardware.radio.V1_0.Carrier;
24 import android.hardware.radio.V1_0.CarrierRestrictions;
25 import android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo;
26 import android.hardware.radio.V1_0.CdmaSmsAck;
27 import android.hardware.radio.V1_0.CdmaSmsMessage;
28 import android.hardware.radio.V1_0.CdmaSmsWriteArgs;
29 import android.hardware.radio.V1_0.CellInfoCdma;
30 import android.hardware.radio.V1_0.CellInfoGsm;
31 import android.hardware.radio.V1_0.CellInfoLte;
32 import android.hardware.radio.V1_0.CellInfoType;
33 import android.hardware.radio.V1_0.CellInfoWcdma;
34 import android.hardware.radio.V1_0.DataProfileInfo;
35 import android.hardware.radio.V1_0.Dial;
36 import android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo;
37 import android.hardware.radio.V1_0.GsmSmsMessage;
38 import android.hardware.radio.V1_0.HardwareConfigModem;
39 import android.hardware.radio.V1_0.IRadio;
40 import android.hardware.radio.V1_0.IccIo;
41 import android.hardware.radio.V1_0.ImsSmsMessage;
42 import android.hardware.radio.V1_0.LceDataInfo;
43 import android.hardware.radio.V1_0.MvnoType;
44 import android.hardware.radio.V1_0.NvWriteItem;
45 import android.hardware.radio.V1_0.RadioError;
46 import android.hardware.radio.V1_0.RadioIndicationType;
47 import android.hardware.radio.V1_0.RadioResponseInfo;
48 import android.hardware.radio.V1_0.RadioResponseType;
49 import android.hardware.radio.V1_0.ResetNvType;
50 import android.hardware.radio.V1_0.SelectUiccSub;
51 import android.hardware.radio.V1_0.SetupDataCallResult;
52 import android.hardware.radio.V1_0.SimApdu;
53 import android.hardware.radio.V1_0.SmsWriteArgs;
54 import android.hardware.radio.V1_0.UusInfo;
55 import android.hardware.radio.deprecated.V1_0.IOemHook;
56 import android.net.ConnectivityManager;
57 import android.os.AsyncResult;
58 import android.os.Handler;
59 import android.os.HwBinder;
60 import android.os.Message;
61 import android.os.Parcel;
62 import android.os.PowerManager;
63 import android.os.PowerManager.WakeLock;
64 import android.os.RemoteException;
65 import android.os.SystemClock;
66 import android.os.SystemProperties;
67 import android.os.WorkSource;
68 import android.service.carrier.CarrierIdentifier;
69 import android.telephony.CellInfo;
70 import android.telephony.ClientRequestStats;
71 import android.telephony.ModemActivityInfo;
72 import android.telephony.NeighboringCellInfo;
73 import android.telephony.PhoneNumberUtils;
74 import android.telephony.RadioAccessFamily;
75 import android.telephony.Rlog;
76 import android.telephony.SignalStrength;
77 import android.telephony.SmsManager;
78 import android.telephony.TelephonyHistogram;
79 import android.text.TextUtils;
80 import android.util.SparseArray;
81
82 import com.android.internal.telephony.cdma.CdmaInformationRecords;
83 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
84 import com.android.internal.telephony.dataconnection.DataCallResponse;
85 import com.android.internal.telephony.dataconnection.DataProfile;
86 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
87 import com.android.internal.telephony.metrics.TelephonyMetrics;
88 import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
89 import com.android.internal.telephony.uicc.IccUtils;
90
91 import java.io.ByteArrayInputStream;
92 import java.io.DataInputStream;
93 import java.io.FileDescriptor;
94 import java.io.IOException;
95 import java.io.PrintWriter;
96 import java.util.ArrayList;
97 import java.util.Arrays;
98 import java.util.List;
99 import java.util.Random;
100 import java.util.concurrent.atomic.AtomicBoolean;
101 import java.util.concurrent.atomic.AtomicInteger;
102 import java.util.concurrent.atomic.AtomicLong;
103
104 /**
105  * {@hide}
106  */
107
108 class RILRequest {
109     static final String LOG_TAG = "RilRequest";
110
111     //***** Class Variables
112     static Random sRandom = new Random();
113     static AtomicInteger sNextSerial = new AtomicInteger(0);
114     private static Object sPoolSync = new Object();
115     private static RILRequest sPool = null;
116     private static int sPoolSize = 0;
117     private static final int MAX_POOL_SIZE = 4;
118
119     //***** Instance Variables
120     int mSerial;
121     int mRequest;
122     Message mResult;
123     RILRequest mNext;
124     int mWakeLockType;
125     WorkSource mWorkSource;
126     String mClientId;
127     // time in ms when RIL request was made
128     long mStartTimeMs;
129
130     /**
131      * Retrieves a new RILRequest instance from the pool.
132      *
133      * @param request RIL_REQUEST_*
134      * @param result sent when operation completes
135      * @return a RILRequest instance from the pool.
136      */
137     private static RILRequest obtain(int request, Message result) {
138         RILRequest rr = null;
139
140         synchronized(sPoolSync) {
141             if (sPool != null) {
142                 rr = sPool;
143                 sPool = rr.mNext;
144                 rr.mNext = null;
145                 sPoolSize--;
146             }
147         }
148
149         if (rr == null) {
150             rr = new RILRequest();
151         }
152
153         rr.mSerial = sNextSerial.getAndIncrement();
154
155         rr.mRequest = request;
156         rr.mResult = result;
157
158         rr.mWakeLockType = RIL.INVALID_WAKELOCK;
159         rr.mWorkSource = null;
160         rr.mStartTimeMs = SystemClock.elapsedRealtime();
161         if (result != null && result.getTarget() == null) {
162             throw new NullPointerException("Message target must not be null");
163         }
164
165         return rr;
166     }
167
168
169     /**
170      * Retrieves a new RILRequest instance from the pool and sets the clientId
171      *
172      * @param request RIL_REQUEST_*
173      * @param result sent when operation completes
174      * @param workSource WorkSource to track the client
175      * @return a RILRequest instance from the pool.
176      */
177     static RILRequest obtain(int request, Message result, WorkSource workSource) {
178         RILRequest rr = null;
179
180         rr = obtain(request, result);
181         if(workSource != null) {
182             rr.mWorkSource = workSource;
183             rr.mClientId = String.valueOf(workSource.get(0)) + ":" + workSource.getName(0);
184         } else {
185             Rlog.e(LOG_TAG, "null workSource " + request);
186         }
187
188         return rr;
189     }
190
191     /**
192      * Returns a RILRequest instance to the pool.
193      *
194      * Note: This should only be called once per use.
195      */
196     void release() {
197         synchronized (sPoolSync) {
198             if (sPoolSize < MAX_POOL_SIZE) {
199                 mNext = sPool;
200                 sPool = this;
201                 sPoolSize++;
202                 mResult = null;
203                 if(mWakeLockType != RIL.INVALID_WAKELOCK) {
204                     //This is OK for some wakelock types and not others
205                     if(mWakeLockType == RIL.FOR_WAKELOCK) {
206                         Rlog.e(LOG_TAG, "RILRequest releasing with held wake lock: "
207                                 + serialString());
208                     }
209                 }
210             }
211         }
212     }
213
214     private RILRequest() {
215     }
216
217     static void
218     resetSerial() {
219         // use a random so that on recovery we probably don't mix old requests
220         // with new.
221         sNextSerial.set(sRandom.nextInt());
222     }
223
224     String
225     serialString() {
226         //Cheesy way to do %04d
227         StringBuilder sb = new StringBuilder(8);
228         String sn;
229
230         long adjustedSerial = (((long)mSerial) - Integer.MIN_VALUE)%10000;
231
232         sn = Long.toString(adjustedSerial);
233
234         //sb.append("J[");
235         sb.append('[');
236         for (int i = 0, s = sn.length() ; i < 4 - s; i++) {
237             sb.append('0');
238         }
239
240         sb.append(sn);
241         sb.append(']');
242         return sb.toString();
243     }
244
245     void
246     onError(int error, Object ret) {
247         CommandException ex;
248
249         ex = CommandException.fromRilErrno(error);
250
251         if (RIL.RILJ_LOGD) Rlog.d(LOG_TAG, serialString() + "< "
252             + RIL.requestToString(mRequest)
253             + " error: " + ex + " ret=" + RIL.retToString(mRequest, ret));
254
255         if (mResult != null) {
256             AsyncResult.forMessage(mResult, ret, ex);
257             mResult.sendToTarget();
258         }
259     }
260 }
261
262
263 /**
264  * RIL implementation of the CommandsInterface.
265  *
266  * {@hide}
267  */
268 public final class RIL extends BaseCommands implements CommandsInterface {
269     static final String RILJ_LOG_TAG = "RILJ";
270     // Have a separate wakelock instance for Ack
271     static final String RILJ_ACK_WAKELOCK_NAME = "RILJ_ACK_WL";
272     static final boolean RILJ_LOGD = true;
273     static final boolean RILJ_LOGV = false; // STOPSHIP if true
274     static final int RIL_HISTOGRAM_BUCKET_COUNT = 5;
275
276     /**
277      * Wake lock timeout should be longer than the longest timeout in
278      * the vendor ril.
279      */
280     private static final int DEFAULT_WAKE_LOCK_TIMEOUT_MS = 60000;
281
282     // Wake lock default timeout associated with ack
283     private static final int DEFAULT_ACK_WAKE_LOCK_TIMEOUT_MS = 200;
284
285     private static final int DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS = 2000;
286
287     // Variables used to differentiate ack messages from request while calling clearWakeLock()
288     public static final int INVALID_WAKELOCK = -1;
289     public static final int FOR_WAKELOCK = 0;
290     public static final int FOR_ACK_WAKELOCK = 1;
291     private final ClientWakelockTracker mClientWakelockTracker = new ClientWakelockTracker();
292
293     //***** Instance Variables
294
295     final WakeLock mWakeLock;           // Wake lock associated with request/response
296     final WakeLock mAckWakeLock;        // Wake lock associated with ack sent
297     final int mWakeLockTimeout;         // Timeout associated with request/response
298     final int mAckWakeLockTimeout;      // Timeout associated with ack sent
299     // The number of wakelock requests currently active.  Don't release the lock
300     // until dec'd to 0
301     int mWakeLockCount;
302
303     // Variables used to identify releasing of WL on wakelock timeouts
304     volatile int mWlSequenceNum = 0;
305     volatile int mAckWlSequenceNum = 0;
306
307     SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
308     static SparseArray<TelephonyHistogram> mRilTimeHistograms = new
309             SparseArray<TelephonyHistogram>();
310
311     Object[]     mLastNITZTimeInfo;
312
313     // When we are testing emergency calls
314     AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
315
316     final Integer mPhoneId;
317
318     /* default work source which will blame phone process */
319     private WorkSource mRILDefaultWorkSource;
320
321     /* Worksource containing all applications causing wakelock to be held */
322     private WorkSource mActiveWakelockWorkSource;
323
324     /** Telephony metrics instance for logging metrics event */
325     private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
326
327     boolean mIsMobileNetworkSupported;
328     RadioResponse mRadioResponse;
329     RadioIndication mRadioIndication;
330     volatile IRadio mRadioProxy = null;
331     OemHookResponse mOemHookResponse;
332     OemHookIndication mOemHookIndication;
333     volatile IOemHook mOemHookProxy = null;
334     final AtomicLong mRadioProxyCookie = new AtomicLong(0);
335     final RadioProxyDeathRecipient mRadioProxyDeathRecipient;
336     final RilHandler mRilHandler;
337
338     //***** Events
339     static final int EVENT_WAKE_LOCK_TIMEOUT    = 2;
340     static final int EVENT_ACK_WAKE_LOCK_TIMEOUT    = 4;
341     static final int EVENT_BLOCKING_RESPONSE_TIMEOUT = 5;
342     static final int EVENT_RADIO_PROXY_DEAD     = 6;
343
344     //***** Constants
345
346     static final String[] HIDL_SERVICE_NAME = {"slot1", "slot2", "slot3"};
347
348     static final int IRADIO_GET_SERVICE_DELAY_MILLIS = 4 * 1000;
349
350     public static List<TelephonyHistogram> getTelephonyRILTimingHistograms() {
351         List<TelephonyHistogram> list;
352         synchronized (mRilTimeHistograms) {
353             list = new ArrayList<>(mRilTimeHistograms.size());
354             for (int i = 0; i < mRilTimeHistograms.size(); i++) {
355                 TelephonyHistogram entry = new TelephonyHistogram(mRilTimeHistograms.valueAt(i));
356                 list.add(entry);
357             }
358         }
359         return list;
360     }
361
362     class RilHandler extends Handler {
363         //***** Handler implementation
364         @Override public void
365         handleMessage(Message msg) {
366             RILRequest rr;
367
368             switch (msg.what) {
369                 case EVENT_WAKE_LOCK_TIMEOUT:
370                     // Haven't heard back from the last request.  Assume we're
371                     // not getting a response and  release the wake lock.
372
373                     // The timer of WAKE_LOCK_TIMEOUT is reset with each
374                     // new send request. So when WAKE_LOCK_TIMEOUT occurs
375                     // all requests in mRequestList already waited at
376                     // least DEFAULT_WAKE_LOCK_TIMEOUT_MS but no response.
377                     //
378                     // Note: Keep mRequestList so that delayed response
379                     // can still be handled when response finally comes.
380
381                     synchronized (mRequestList) {
382                         if (msg.arg1 == mWlSequenceNum && clearWakeLock(FOR_WAKELOCK)) {
383                             if (RILJ_LOGD) {
384                                 int count = mRequestList.size();
385                                 Rlog.d(RILJ_LOG_TAG, "WAKE_LOCK_TIMEOUT " +
386                                         " mRequestList=" + count);
387                                 for (int i = 0; i < count; i++) {
388                                     rr = mRequestList.valueAt(i);
389                                     Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] "
390                                             + requestToString(rr.mRequest));
391                                 }
392                             }
393                         }
394                     }
395                     break;
396
397                 case EVENT_ACK_WAKE_LOCK_TIMEOUT:
398                     if (msg.arg1 == mAckWlSequenceNum && clearWakeLock(FOR_ACK_WAKELOCK)) {
399                         if (RILJ_LOGV) {
400                             Rlog.d(RILJ_LOG_TAG, "ACK_WAKE_LOCK_TIMEOUT");
401                         }
402                     }
403                     break;
404
405                 case EVENT_BLOCKING_RESPONSE_TIMEOUT:
406                     int serial = msg.arg1;
407                     rr = findAndRemoveRequestFromList(serial);
408                     // If the request has already been processed, do nothing
409                     if(rr == null) {
410                         break;
411                     }
412
413                     //build a response if expected
414                     if (rr.mResult != null) {
415                         Object timeoutResponse = getResponseForTimedOutRILRequest(rr);
416                         AsyncResult.forMessage( rr.mResult, timeoutResponse, null);
417                         rr.mResult.sendToTarget();
418                         mMetrics.writeOnRilTimeoutResponse(mPhoneId, rr.mSerial, rr.mRequest);
419                     }
420
421                     decrementWakeLock(rr);
422                     rr.release();
423                     break;
424
425                 case EVENT_RADIO_PROXY_DEAD:
426                     riljLog("handleMessage: EVENT_RADIO_PROXY_DEAD cookie = " + msg.obj +
427                             " mRadioProxyCookie = " + mRadioProxyCookie.get());
428                     if ((long) msg.obj == mRadioProxyCookie.get()) {
429                         resetProxyAndRequestList();
430
431                         // todo: rild should be back up since message was sent with a delay. this is
432                         // a hack.
433                         getRadioProxy(null);
434                         getOemHookProxy(null);
435                     }
436                     break;
437             }
438         }
439     }
440
441     /**
442      * In order to prevent calls to Telephony from waiting indefinitely
443      * low-latency blocking calls will eventually time out. In the event of
444      * a timeout, this function generates a response that is returned to the
445      * higher layers to unblock the call. This is in lieu of a meaningful
446      * response.
447      * @param rr The RIL Request that has timed out.
448      * @return A default object, such as the one generated by a normal response
449      * that is returned to the higher layers.
450      **/
451     private static Object getResponseForTimedOutRILRequest(RILRequest rr) {
452         if (rr == null ) return null;
453
454         Object timeoutResponse = null;
455         switch(rr.mRequest) {
456             case RIL_REQUEST_GET_ACTIVITY_INFO:
457                 timeoutResponse = new ModemActivityInfo(
458                         0, 0, 0, new int [ModemActivityInfo.TX_POWER_LEVELS], 0, 0);
459                 break;
460         };
461         return timeoutResponse;
462     }
463
464     final class RadioProxyDeathRecipient implements HwBinder.DeathRecipient {
465         @Override
466         public void serviceDied(long cookie) {
467             // Deal with service going away
468             riljLog("serviceDied");
469             // todo: temp hack to send delayed message so that rild is back up by then
470             //mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie));
471             mRilHandler.sendMessageDelayed(
472                     mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie),
473                     IRADIO_GET_SERVICE_DELAY_MILLIS);
474         }
475     }
476
477     private void resetProxyAndRequestList() {
478         mRadioProxy = null;
479         mOemHookProxy = null;
480
481         // increment the cookie so that death notification can be ignored
482         mRadioProxyCookie.incrementAndGet();
483
484         setRadioState(RadioState.RADIO_UNAVAILABLE);
485
486         RILRequest.resetSerial();
487         // Clear request list on close
488         clearRequestList(RADIO_NOT_AVAILABLE, false);
489
490         // todo: need to get service right away so setResponseFunctions() can be called for
491         // unsolicited indications. getService() is not a blocking call, so it doesn't help to call
492         // it here. Current hack is to call getService() on death notification after a delay.
493     }
494
495     private IRadio getRadioProxy(Message result) {
496         if (!mIsMobileNetworkSupported) {
497             if (RILJ_LOGV) riljLog("getRadioProxy: Not calling getService(): wifi-only");
498             if (result != null) {
499                 AsyncResult.forMessage(result, null,
500                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
501                 result.sendToTarget();
502             }
503             return null;
504         }
505
506         if (mRadioProxy != null) {
507             return mRadioProxy;
508         }
509
510         try {
511             mRadioProxy = IRadio.getService(HIDL_SERVICE_NAME[mPhoneId == null ? 0 : mPhoneId]);
512             if (mRadioProxy != null) {
513                 mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
514                         mRadioProxyCookie.incrementAndGet());
515                 mRadioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
516             } else {
517                 riljLoge("getRadioProxy: mRadioProxy == null");
518             }
519         } catch (RemoteException | RuntimeException e) {
520             mRadioProxy = null;
521             riljLoge("RadioProxy getService/setResponseFunctions: " + e);
522         }
523
524         if (mRadioProxy == null) {
525             if (result != null) {
526                 AsyncResult.forMessage(result, null,
527                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
528                 result.sendToTarget();
529             }
530
531             // if service is not up, treat it like death notification to try to get service again
532             mRilHandler.sendMessageDelayed(
533                     mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD,
534                             mRadioProxyCookie.incrementAndGet()),
535                     IRADIO_GET_SERVICE_DELAY_MILLIS);
536         }
537
538         return mRadioProxy;
539     }
540
541     private IOemHook getOemHookProxy(Message result) {
542         if (!mIsMobileNetworkSupported) {
543             if (RILJ_LOGV) riljLog("getOemHookProxy: Not calling getService(): wifi-only");
544             if (result != null) {
545                 AsyncResult.forMessage(result, null,
546                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
547                 result.sendToTarget();
548             }
549             return null;
550         }
551
552         if (mOemHookProxy != null) {
553             return mOemHookProxy;
554         }
555
556         try {
557             mOemHookProxy = IOemHook.getService(
558                     HIDL_SERVICE_NAME[mPhoneId == null ? 0 : mPhoneId]);
559             if (mOemHookProxy != null) {
560                 // not calling linkToDeath() as ril service runs in the same process and death
561                 // notification for that should be sufficient
562                 mOemHookProxy.setResponseFunctions(mOemHookResponse, mOemHookIndication);
563             } else {
564                 riljLoge("getOemHookProxy: mOemHookProxy == null");
565             }
566         } catch (RemoteException | RuntimeException e) {
567             mOemHookProxy = null;
568             riljLoge("OemHookProxy getService/setResponseFunctions: " + e);
569         }
570
571         if (mOemHookProxy == null) {
572             if (result != null) {
573                 AsyncResult.forMessage(result, null,
574                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
575                 result.sendToTarget();
576             }
577
578             // if service is not up, treat it like death notification to try to get service again
579             mRilHandler.sendMessageDelayed(
580                     mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD,
581                             mRadioProxyCookie.incrementAndGet()),
582                     IRADIO_GET_SERVICE_DELAY_MILLIS);
583         }
584
585         return mOemHookProxy;
586     }
587
588     //***** Constructors
589
590     public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
591         this(context, preferredNetworkType, cdmaSubscription, null);
592     }
593
594     public RIL(Context context, int preferredNetworkType,
595             int cdmaSubscription, Integer instanceId) {
596         super(context);
597         if (RILJ_LOGD) {
598             riljLog("RIL: init preferredNetworkType=" + preferredNetworkType
599                     + " cdmaSubscription=" + cdmaSubscription + ")");
600         }
601
602         mContext = context;
603         mCdmaSubscription  = cdmaSubscription;
604         mPreferredNetworkType = preferredNetworkType;
605         mPhoneType = RILConstants.NO_PHONE;
606         mPhoneId = instanceId;
607
608         ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
609                 Context.CONNECTIVITY_SERVICE);
610         mIsMobileNetworkSupported = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
611
612         mRadioResponse = new RadioResponse(this);
613         mRadioIndication = new RadioIndication(this);
614         mOemHookResponse = new OemHookResponse(this);
615         mOemHookIndication = new OemHookIndication(this);
616         mRilHandler = new RilHandler();
617         mRadioProxyDeathRecipient = new RadioProxyDeathRecipient();
618
619         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
620         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_LOG_TAG);
621         mWakeLock.setReferenceCounted(false);
622         mAckWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_ACK_WAKELOCK_NAME);
623         mAckWakeLock.setReferenceCounted(false);
624         mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,
625                 DEFAULT_WAKE_LOCK_TIMEOUT_MS);
626         mAckWakeLockTimeout = SystemProperties.getInt(
627                 TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT, DEFAULT_ACK_WAKE_LOCK_TIMEOUT_MS);
628         mWakeLockCount = 0;
629         mRILDefaultWorkSource = new WorkSource(context.getApplicationInfo().uid,
630                 context.getPackageName());
631
632         TelephonyDevController tdc = TelephonyDevController.getInstance();
633         tdc.registerRIL(this);
634
635         // set radio callback; needed to set RadioIndication callback (should be done after
636         // wakelock stuff is initialized above as callbacks are received on separate binder threads)
637         getRadioProxy(null);
638         getOemHookProxy(null);
639     }
640
641     @Override public void
642     setOnNITZTime(Handler h, int what, Object obj) {
643         super.setOnNITZTime(h, what, obj);
644
645         // Send the last NITZ time if we have it
646         if (mLastNITZTimeInfo != null) {
647             mNITZTimeRegistrant
648                 .notifyRegistrant(
649                     new AsyncResult (null, mLastNITZTimeInfo, null));
650         }
651     }
652
653     private void addRequest(RILRequest rr) {
654         acquireWakeLock(rr, FOR_WAKELOCK);
655         synchronized (mRequestList) {
656             rr.mStartTimeMs = SystemClock.elapsedRealtime();
657             mRequestList.append(rr.mSerial, rr);
658         }
659     }
660
661     private RILRequest obtainRequest(int request, Message result, WorkSource workSource) {
662         RILRequest rr = RILRequest.obtain(request, result, workSource);
663         addRequest(rr);
664         return rr;
665     }
666
667     private void handleRadioProxyExceptionForRR(RILRequest rr, String caller, Exception e) {
668         riljLoge(caller + ": " + e);
669         resetProxyAndRequestList();
670
671         // service most likely died, handle exception like death notification to try to get service
672         // again
673         mRilHandler.sendMessageDelayed(
674                 mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD,
675                         mRadioProxyCookie.incrementAndGet()),
676                 IRADIO_GET_SERVICE_DELAY_MILLIS);
677     }
678
679     private String convertNullToEmptyString(String string) {
680         return string != null ? string : "";
681     }
682
683     @Override
684     public void
685     getIccCardStatus(Message result) {
686         IRadio radioProxy = getRadioProxy(result);
687         if (radioProxy != null) {
688             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIM_STATUS, result,
689                     mRILDefaultWorkSource);
690
691             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
692
693             try {
694                 radioProxy.getIccCardStatus(rr.mSerial);
695             } catch (RemoteException | RuntimeException e) {
696                 handleRadioProxyExceptionForRR(rr, "getIccCardStatus", e);
697             }
698         }
699     }
700
701     @Override public void
702     supplyIccPin(String pin, Message result) {
703         supplyIccPinForApp(pin, null, result);
704     }
705
706     @Override public void
707     supplyIccPinForApp(String pin, String aid, Message result) {
708         IRadio radioProxy = getRadioProxy(result);
709         if (radioProxy != null) {
710             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN, result,
711                     mRILDefaultWorkSource);
712
713             if (RILJ_LOGD) {
714                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
715                         + " aid = " + aid);
716             }
717
718             try {
719                 radioProxy.supplyIccPinForApp(rr.mSerial,
720                         convertNullToEmptyString(pin),
721                         convertNullToEmptyString(aid));
722             } catch (RemoteException | RuntimeException e) {
723                 handleRadioProxyExceptionForRR(rr, "supplyIccPinForApp", e);
724             }
725         }
726     }
727
728     @Override
729     public void supplyIccPuk(String puk, String newPin, Message result) {
730         supplyIccPukForApp(puk, newPin, null, result);
731     }
732
733     @Override
734     public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
735         IRadio radioProxy = getRadioProxy(result);
736         if (radioProxy != null) {
737             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK, result,
738                     mRILDefaultWorkSource);
739
740             if (RILJ_LOGD) {
741                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
742                         + " aid = " + aid);
743             }
744
745             try {
746                 radioProxy.supplyIccPukForApp(rr.mSerial,
747                         convertNullToEmptyString(puk),
748                         convertNullToEmptyString(newPin),
749                         convertNullToEmptyString(aid));
750             } catch (RemoteException | RuntimeException e) {
751                 handleRadioProxyExceptionForRR(rr, "supplyIccPukForApp", e);
752             }
753         }
754     }
755
756     @Override public void
757     supplyIccPin2(String pin, Message result) {
758         supplyIccPin2ForApp(pin, null, result);
759     }
760
761     @Override public void
762     supplyIccPin2ForApp(String pin, String aid, Message result) {
763         IRadio radioProxy = getRadioProxy(result);
764         if (radioProxy != null) {
765             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN2, result,
766                     mRILDefaultWorkSource);
767
768             if (RILJ_LOGD) {
769                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
770                         + " aid = " + aid);
771             }
772
773             try {
774                 radioProxy.supplyIccPin2ForApp(rr.mSerial,
775                         convertNullToEmptyString(pin),
776                         convertNullToEmptyString(aid));
777             } catch (RemoteException | RuntimeException e) {
778                 handleRadioProxyExceptionForRR(rr, "supplyIccPin2ForApp", e);
779             }
780         }
781     }
782
783     @Override public void
784     supplyIccPuk2(String puk2, String newPin2, Message result) {
785         supplyIccPuk2ForApp(puk2, newPin2, null, result);
786     }
787
788     @Override public void
789     supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
790         IRadio radioProxy = getRadioProxy(result);
791         if (radioProxy != null) {
792             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK2, result,
793                     mRILDefaultWorkSource);
794
795             if (RILJ_LOGD) {
796                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
797                         + " aid = " + aid);
798             }
799
800             try {
801                 radioProxy.supplyIccPuk2ForApp(rr.mSerial,
802                         convertNullToEmptyString(puk),
803                         convertNullToEmptyString(newPin2),
804                         convertNullToEmptyString(aid));
805             } catch (RemoteException | RuntimeException e) {
806                 handleRadioProxyExceptionForRR(rr, "supplyIccPuk2ForApp", e);
807             }
808         }
809     }
810
811     @Override public void
812     changeIccPin(String oldPin, String newPin, Message result) {
813         changeIccPinForApp(oldPin, newPin, null, result);
814     }
815
816     @Override public void
817     changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
818         IRadio radioProxy = getRadioProxy(result);
819         if (radioProxy != null) {
820             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_SIM_PIN, result,
821                     mRILDefaultWorkSource);
822
823             if (RILJ_LOGD) {
824                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " oldPin = "
825                         + oldPin + " newPin = " + newPin + " aid = " + aid);
826             }
827
828             try {
829                 radioProxy.changeIccPinForApp(rr.mSerial,
830                         convertNullToEmptyString(oldPin),
831                         convertNullToEmptyString(newPin),
832                         convertNullToEmptyString(aid));
833             } catch (RemoteException | RuntimeException e) {
834                 handleRadioProxyExceptionForRR(rr, "changeIccPinForApp", e);
835             }
836         }
837     }
838
839     @Override public void
840     changeIccPin2(String oldPin2, String newPin2, Message result) {
841         changeIccPin2ForApp(oldPin2, newPin2, null, result);
842     }
843
844     @Override public void
845     changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
846         IRadio radioProxy = getRadioProxy(result);
847         if (radioProxy != null) {
848             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_SIM_PIN2, result,
849                     mRILDefaultWorkSource);
850
851             if (RILJ_LOGD) {
852                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " oldPin = "
853                         + oldPin2 + " newPin = " + newPin2 + " aid = " + aid);
854             }
855
856             try {
857                 radioProxy.changeIccPin2ForApp(rr.mSerial,
858                         convertNullToEmptyString(oldPin2),
859                         convertNullToEmptyString(newPin2),
860                         convertNullToEmptyString(aid));
861             } catch (RemoteException | RuntimeException e) {
862                 handleRadioProxyExceptionForRR(rr, "changeIccPin2ForApp", e);
863             }
864         }
865     }
866
867     @Override
868     public void supplyNetworkDepersonalization(String netpin, Message result) {
869         IRadio radioProxy = getRadioProxy(result);
870         if (radioProxy != null) {
871             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result,
872                     mRILDefaultWorkSource);
873
874             if (RILJ_LOGD) {
875                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " netpin = "
876                         + netpin);
877             }
878
879             try {
880                 radioProxy.supplyNetworkDepersonalization(rr.mSerial,
881                         convertNullToEmptyString(netpin));
882             } catch (RemoteException | RuntimeException e) {
883                 handleRadioProxyExceptionForRR(rr, "supplyNetworkDepersonalization", e);
884             }
885         }
886     }
887
888     @Override
889     public void getCurrentCalls(Message result) {
890         IRadio radioProxy = getRadioProxy(result);
891         if (radioProxy != null) {
892             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CURRENT_CALLS, result,
893                     mRILDefaultWorkSource);
894
895             if (RILJ_LOGD) {
896                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
897             }
898
899             try {
900                 radioProxy.getCurrentCalls(rr.mSerial);
901             } catch (RemoteException | RuntimeException e) {
902                 handleRadioProxyExceptionForRR(rr, "getCurrentCalls", e);
903             }
904         }
905     }
906
907     @Override
908     public void dial(String address, int clirMode, Message result) {
909         dial(address, clirMode, null, result);
910     }
911
912     @Override
913     public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
914         IRadio radioProxy = getRadioProxy(result);
915         if (radioProxy != null) {
916             RILRequest rr = obtainRequest(RIL_REQUEST_DIAL, result,
917                     mRILDefaultWorkSource);
918
919             Dial dialInfo = new Dial();
920             dialInfo.address = convertNullToEmptyString(address);
921             dialInfo.clir = clirMode;
922             if (uusInfo != null) {
923                 UusInfo info = new UusInfo();
924                 info.uusType = uusInfo.getType();
925                 info.uusDcs = uusInfo.getDcs();
926                 info.uusData = new String(uusInfo.getUserData());
927                 dialInfo.uusInfo.add(info);
928             }
929
930             if (RILJ_LOGD) {
931                 // Do not log function arg for privacy
932                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
933             }
934
935             try {
936                 radioProxy.dial(rr.mSerial, dialInfo);
937             } catch (RemoteException | RuntimeException e) {
938                 handleRadioProxyExceptionForRR(rr, "dial", e);
939             }
940         }
941     }
942
943     @Override
944     public void getIMSI(Message result) {
945         getIMSIForApp(null, result);
946     }
947
948     @Override
949     public void getIMSIForApp(String aid, Message result) {
950         IRadio radioProxy = getRadioProxy(result);
951         if (radioProxy != null) {
952             RILRequest rr = obtainRequest(RIL_REQUEST_GET_IMSI, result,
953                     mRILDefaultWorkSource);
954
955             if (RILJ_LOGD) {
956                 riljLog(rr.serialString()
957                         + ">  " + requestToString(rr.mRequest) + " aid = " + aid);
958             }
959             try {
960                 radioProxy.getImsiForApp(rr.mSerial, convertNullToEmptyString(aid));
961             } catch (RemoteException | RuntimeException e) {
962                 handleRadioProxyExceptionForRR(rr, "getIMSIForApp", e);
963             }
964         }
965     }
966
967     @Override
968     public void hangupConnection(int gsmIndex, Message result) {
969         IRadio radioProxy = getRadioProxy(result);
970         if (radioProxy != null) {
971             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP, result,
972                     mRILDefaultWorkSource);
973
974             if (RILJ_LOGD) {
975                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " gsmIndex = "
976                         + gsmIndex);
977             }
978
979             try {
980                 radioProxy.hangup(rr.mSerial, gsmIndex);
981             } catch (RemoteException | RuntimeException e) {
982                 handleRadioProxyExceptionForRR(rr, "hangupConnection", e);
983             }
984         }
985     }
986
987     @Override
988     public void hangupWaitingOrBackground(Message result) {
989         IRadio radioProxy = getRadioProxy(result);
990         if (radioProxy != null) {
991             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, result,
992                     mRILDefaultWorkSource);
993
994             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
995
996             try {
997                 radioProxy.hangupWaitingOrBackground(rr.mSerial);
998             } catch (RemoteException | RuntimeException e) {
999                 handleRadioProxyExceptionForRR(rr, "hangupWaitingOrBackground", e);
1000             }
1001         }
1002     }
1003
1004     @Override
1005     public void hangupForegroundResumeBackground(Message result) {
1006         IRadio radioProxy = getRadioProxy(result);
1007         if (radioProxy != null) {
1008             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, result,
1009                     mRILDefaultWorkSource);
1010
1011             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1012
1013             try {
1014                 radioProxy.hangupForegroundResumeBackground(rr.mSerial);
1015             } catch (RemoteException | RuntimeException e) {
1016                 handleRadioProxyExceptionForRR(rr, "hangupForegroundResumeBackground", e);
1017             }
1018         }
1019     }
1020
1021     @Override
1022     public void switchWaitingOrHoldingAndActive(Message result) {
1023         IRadio radioProxy = getRadioProxy(result);
1024         if (radioProxy != null) {
1025             RILRequest rr = obtainRequest(RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, result,
1026                     mRILDefaultWorkSource);
1027
1028             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1029
1030             try {
1031                 radioProxy.switchWaitingOrHoldingAndActive(rr.mSerial);
1032             } catch (RemoteException | RuntimeException e) {
1033                 handleRadioProxyExceptionForRR(rr, "switchWaitingOrHoldingAndActive", e);
1034             }
1035         }
1036     }
1037
1038     @Override
1039     public void conference(Message result) {
1040         IRadio radioProxy = getRadioProxy(result);
1041         if (radioProxy != null) {
1042             RILRequest rr = obtainRequest(RIL_REQUEST_CONFERENCE, result,
1043                     mRILDefaultWorkSource);
1044
1045             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1046
1047             try {
1048                 radioProxy.conference(rr.mSerial);
1049             } catch (RemoteException | RuntimeException e) {
1050                 handleRadioProxyExceptionForRR(rr, "conference", e);
1051             }
1052         }
1053     }
1054
1055     @Override
1056     public void rejectCall(Message result) {
1057         IRadio radioProxy = getRadioProxy(result);
1058         if (radioProxy != null) {
1059             RILRequest rr = obtainRequest(RIL_REQUEST_UDUB, result,
1060                     mRILDefaultWorkSource);
1061
1062             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1063
1064             try {
1065                 radioProxy.rejectCall(rr.mSerial);
1066             } catch (RemoteException | RuntimeException e) {
1067                 handleRadioProxyExceptionForRR(rr, "rejectCall", e);
1068             }
1069         }
1070     }
1071
1072     @Override
1073     public void getLastCallFailCause(Message result) {
1074         IRadio radioProxy = getRadioProxy(result);
1075         if (radioProxy != null) {
1076             RILRequest rr = obtainRequest(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result,
1077                     mRILDefaultWorkSource);
1078
1079             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1080
1081             try {
1082                 radioProxy.getLastCallFailCause(rr.mSerial);
1083             } catch (RemoteException | RuntimeException e) {
1084                 handleRadioProxyExceptionForRR(rr, "getLastCallFailCause", e);
1085             }
1086         }
1087     }
1088
1089     @Override
1090     public void getSignalStrength(Message result) {
1091         IRadio radioProxy = getRadioProxy(result);
1092         if (radioProxy != null) {
1093             RILRequest rr = obtainRequest(RIL_REQUEST_SIGNAL_STRENGTH, result,
1094                     mRILDefaultWorkSource);
1095
1096             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1097
1098             try {
1099                 radioProxy.getSignalStrength(rr.mSerial);
1100             } catch (RemoteException | RuntimeException e) {
1101                 handleRadioProxyExceptionForRR(rr, "getSignalStrength", e);
1102             }
1103         }
1104     }
1105
1106     @Override
1107     public void getVoiceRegistrationState(Message result) {
1108         IRadio radioProxy = getRadioProxy(result);
1109         if (radioProxy != null) {
1110             RILRequest rr = obtainRequest(RIL_REQUEST_VOICE_REGISTRATION_STATE, result,
1111                     mRILDefaultWorkSource);
1112
1113             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1114
1115             try {
1116                 radioProxy.getVoiceRegistrationState(rr.mSerial);
1117             } catch (RemoteException | RuntimeException e) {
1118                 handleRadioProxyExceptionForRR(rr, "getVoiceRegistrationState", e);
1119             }
1120         }
1121     }
1122
1123     @Override
1124     public void getDataRegistrationState(Message result) {
1125         IRadio radioProxy = getRadioProxy(result);
1126         if (radioProxy != null) {
1127             RILRequest rr = obtainRequest(RIL_REQUEST_DATA_REGISTRATION_STATE, result,
1128                     mRILDefaultWorkSource);
1129
1130             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1131
1132             try {
1133                 radioProxy.getDataRegistrationState(rr.mSerial);
1134             } catch (RemoteException | RuntimeException e) {
1135                 handleRadioProxyExceptionForRR(rr, "getDataRegistrationState", e);
1136             }
1137         }
1138     }
1139
1140     @Override
1141     public void getOperator(Message result) {
1142         IRadio radioProxy = getRadioProxy(result);
1143         if (radioProxy != null) {
1144             RILRequest rr = obtainRequest(RIL_REQUEST_OPERATOR, result,
1145                     mRILDefaultWorkSource);
1146
1147             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1148
1149             try {
1150                 radioProxy.getOperator(rr.mSerial);
1151             } catch (RemoteException | RuntimeException e) {
1152                 handleRadioProxyExceptionForRR(rr, "getOperator", e);
1153             }
1154         }
1155     }
1156
1157     @Override
1158     public void setRadioPower(boolean on, Message result) {
1159         IRadio radioProxy = getRadioProxy(result);
1160         if (radioProxy != null) {
1161             RILRequest rr = obtainRequest(RIL_REQUEST_RADIO_POWER, result,
1162                     mRILDefaultWorkSource);
1163
1164             if (RILJ_LOGD) {
1165                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1166                         + " on = " + on);
1167             }
1168
1169             try {
1170                 radioProxy.setRadioPower(rr.mSerial, on);
1171             } catch (RemoteException | RuntimeException e) {
1172                 handleRadioProxyExceptionForRR(rr, "setRadioPower", e);
1173             }
1174         }
1175     }
1176
1177     @Override
1178     public void sendDtmf(char c, Message result) {
1179         IRadio radioProxy = getRadioProxy(result);
1180         if (radioProxy != null) {
1181             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF, result,
1182                     mRILDefaultWorkSource);
1183
1184             if (RILJ_LOGD) {
1185                 // Do not log function arg for privacy
1186                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1187             }
1188
1189             try {
1190                 radioProxy.sendDtmf(rr.mSerial, c + "");
1191             } catch (RemoteException | RuntimeException e) {
1192                 handleRadioProxyExceptionForRR(rr, "sendDtmf", e);
1193             }
1194         }
1195     }
1196
1197     private GsmSmsMessage constructGsmSendSmsRilRequest(String smscPdu, String pdu) {
1198         GsmSmsMessage msg = new GsmSmsMessage();
1199         msg.smscPdu = smscPdu == null ? "" : smscPdu;
1200         msg.pdu = pdu == null ? "" : pdu;
1201         return msg;
1202     }
1203
1204     @Override
1205     public void sendSMS(String smscPdu, String pdu, Message result) {
1206         IRadio radioProxy = getRadioProxy(result);
1207         if (radioProxy != null) {
1208             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS, result,
1209                     mRILDefaultWorkSource);
1210
1211             // Do not log function args for privacy
1212             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1213
1214             GsmSmsMessage msg = constructGsmSendSmsRilRequest(smscPdu, pdu);
1215
1216             try {
1217                 radioProxy.sendSms(rr.mSerial, msg);
1218                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
1219                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
1220             } catch (RemoteException | RuntimeException e) {
1221                 handleRadioProxyExceptionForRR(rr, "sendSMS", e);
1222             }
1223         }
1224     }
1225
1226     @Override
1227     public void sendSMSExpectMore(String smscPdu, String pdu, Message result) {
1228         IRadio radioProxy = getRadioProxy(result);
1229         if (radioProxy != null) {
1230             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS_EXPECT_MORE, result,
1231                     mRILDefaultWorkSource);
1232
1233             // Do not log function arg for privacy
1234             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1235
1236             GsmSmsMessage msg = constructGsmSendSmsRilRequest(smscPdu, pdu);
1237
1238             try {
1239                 radioProxy.sendSMSExpectMore(rr.mSerial, msg);
1240                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
1241                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
1242             } catch (RemoteException | RuntimeException e) {
1243                 handleRadioProxyExceptionForRR(rr, "sendSMSExpectMore", e);
1244             }
1245         }
1246     }
1247
1248     /**
1249      * Convert MVNO type string into MvnoType defined in types.hal.
1250      * @param mvnoType MVNO type
1251      * @return MVNO type in integer
1252      */
1253     private static int convertToHalMvnoType(String mvnoType) {
1254         switch (mvnoType) {
1255             case "imsi" : return MvnoType.IMSI;
1256             case "gid" : return MvnoType.GID;
1257             case "spn" : return MvnoType.SPN;
1258             default: return MvnoType.NONE;
1259         }
1260     }
1261
1262     /**
1263      * Convert to DataProfileInfo defined in types.hal
1264      * @param dp Data profile
1265      * @return A converted data profile
1266      */
1267     private static DataProfileInfo convertToHalDataProfile(DataProfile dp) {
1268         DataProfileInfo dpi = new DataProfileInfo();
1269
1270         dpi.profileId = dp.profileId;
1271         dpi.apn = dp.apn;
1272         dpi.protocol = dp.protocol;
1273         dpi.roamingProtocol = dp.roamingProtocol;
1274         dpi.authType = dp.authType;
1275         dpi.user = dp.user;
1276         dpi.password = dp.password;
1277         dpi.type = dp.type;
1278         dpi.maxConnsTime = dp.maxConnsTime;
1279         dpi.maxConns = dp.maxConns;
1280         dpi.waitTime = dp.waitTime;
1281         dpi.enabled = dp.enabled;
1282         dpi.supportedApnTypesBitmap = dp.supportedApnTypesBitmap;
1283         dpi.bearerBitmap = dp.bearerBitmap;
1284         dpi.mtu = dp.mtu;
1285         dpi.mvnoType = convertToHalMvnoType(dp.mvnoType);
1286         dpi.mvnoMatchData = dp.mvnoMatchData;
1287
1288         return dpi;
1289     }
1290
1291     /**
1292      * Convert NV reset type into ResetNvType defined in types.hal.
1293      * @param resetType NV reset type.
1294      * @return Converted reset type in integer or -1 if param is invalid.
1295      */
1296     private static int convertToHalResetNvType(int resetType) {
1297         /**
1298          * resetType values
1299          * 1 - reload all NV items
1300          * 2 - erase NV reset (SCRTN)
1301          * 3 - factory reset (RTN)
1302          */
1303         switch (resetType) {
1304             case 1: return ResetNvType.RELOAD;
1305             case 2: return ResetNvType.ERASE;
1306             case 3: return ResetNvType.FACTORY_RESET;
1307         }
1308         return -1;
1309     }
1310
1311     /**
1312      * Convert SetupDataCallResult defined in types.hal into DataCallResponse
1313      * @param dcResult setup data call result
1314      * @return converted DataCallResponse object
1315      */
1316     static DataCallResponse convertDataCallResult(SetupDataCallResult dcResult) {
1317         return new DataCallResponse(dcResult.status,
1318                 dcResult.suggestedRetryTime,
1319                 dcResult.cid,
1320                 dcResult.active,
1321                 dcResult.type,
1322                 dcResult.ifname,
1323                 dcResult.addresses,
1324                 dcResult.dnses,
1325                 dcResult.gateways,
1326                 dcResult.pcscf,
1327                 dcResult.mtu
1328         );
1329     }
1330
1331     @Override
1332     public void setupDataCall(int radioTechnology, DataProfile dataProfile, boolean isRoaming,
1333                               boolean allowRoaming, Message result) {
1334
1335         IRadio radioProxy = getRadioProxy(result);
1336         if (radioProxy != null) {
1337
1338             RILRequest rr = obtainRequest(RIL_REQUEST_SETUP_DATA_CALL, result,
1339                     mRILDefaultWorkSource);
1340
1341             // Convert to HAL data profile
1342             DataProfileInfo dpi = convertToHalDataProfile(dataProfile);
1343
1344             if (RILJ_LOGD) {
1345                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1346                         + ",radioTechnology=" + radioTechnology + ",isRoaming="
1347                         + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile);
1348             }
1349
1350             try {
1351                 radioProxy.setupDataCall(rr.mSerial, radioTechnology, dpi,
1352                         dataProfile.modemCognitive, allowRoaming, isRoaming);
1353                 mMetrics.writeRilSetupDataCall(mPhoneId, rr.mSerial, radioTechnology, dpi.profileId,
1354                         dpi.apn, dpi.authType, dpi.protocol);
1355             } catch (RemoteException | RuntimeException e) {
1356                 handleRadioProxyExceptionForRR(rr, "setupDataCall", e);
1357             }
1358         }
1359     }
1360
1361     @Override
1362     public void iccIO(int command, int fileId, String path, int p1, int p2, int p3,
1363                       String data, String pin2, Message result) {
1364         iccIOForApp(command, fileId, path, p1, p2, p3, data, pin2, null, result);
1365     }
1366
1367     @Override
1368     public void iccIOForApp(int command, int fileId, String path, int p1, int p2, int p3,
1369                  String data, String pin2, String aid, Message result) {
1370         IRadio radioProxy = getRadioProxy(result);
1371         if (radioProxy != null) {
1372             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_IO, result,
1373                     mRILDefaultWorkSource);
1374
1375             if (RILJ_LOGD) {
1376                 riljLog(rr.serialString() + "> iccIO: "
1377                         + requestToString(rr.mRequest) + " command = 0x"
1378                         + Integer.toHexString(command) + " fileId = 0x"
1379                         + Integer.toHexString(fileId) + " path = " + path + " p1 = "
1380                         + p1 + " p2 = " + p2 + " p3 = " + " data = " + data
1381                         + " aid = " + aid);
1382             }
1383
1384             IccIo iccIo = new IccIo();
1385             iccIo.command = command;
1386             iccIo.fileId = fileId;
1387             iccIo.path = convertNullToEmptyString(path);
1388             iccIo.p1 = p1;
1389             iccIo.p2 = p2;
1390             iccIo.p3 = p3;
1391             iccIo.data = convertNullToEmptyString(data);
1392             iccIo.pin2 = convertNullToEmptyString(pin2);
1393             iccIo.aid = convertNullToEmptyString(aid);
1394
1395             try {
1396                 radioProxy.iccIOForApp(rr.mSerial, iccIo);
1397             } catch (RemoteException | RuntimeException e) {
1398                 handleRadioProxyExceptionForRR(rr, "iccIOForApp", e);
1399             }
1400         }
1401     }
1402
1403     @Override
1404     public void sendUSSD(String ussd, Message result) {
1405         IRadio radioProxy = getRadioProxy(result);
1406         if (radioProxy != null) {
1407             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_USSD, result,
1408                     mRILDefaultWorkSource);
1409
1410             if (RILJ_LOGD) {
1411                 String logUssd = "*******";
1412                 if (RILJ_LOGV) logUssd = ussd;
1413                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1414                         + " ussd = " + logUssd);
1415             }
1416
1417             try {
1418                 radioProxy.sendUssd(rr.mSerial, convertNullToEmptyString(ussd));
1419             } catch (RemoteException | RuntimeException e) {
1420                 handleRadioProxyExceptionForRR(rr, "sendUSSD", e);
1421             }
1422         }
1423     }
1424
1425     @Override
1426     public void cancelPendingUssd(Message result) {
1427         IRadio radioProxy = getRadioProxy(result);
1428         if (radioProxy != null) {
1429             RILRequest rr = obtainRequest(RIL_REQUEST_CANCEL_USSD, result,
1430                     mRILDefaultWorkSource);
1431
1432             if (RILJ_LOGD) {
1433                 riljLog(rr.serialString()
1434                         + "> " + requestToString(rr.mRequest));
1435             }
1436
1437             try {
1438                 radioProxy.cancelPendingUssd(rr.mSerial);
1439             } catch (RemoteException | RuntimeException e) {
1440                 handleRadioProxyExceptionForRR(rr, "cancelPendingUssd", e);
1441             }
1442         }
1443     }
1444
1445     @Override
1446     public void getCLIR(Message result) {
1447         IRadio radioProxy = getRadioProxy(result);
1448         if (radioProxy != null) {
1449             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CLIR, result,
1450                     mRILDefaultWorkSource);
1451
1452             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1453
1454             try {
1455                 radioProxy.getClir(rr.mSerial);
1456             } catch (RemoteException | RuntimeException e) {
1457                 handleRadioProxyExceptionForRR(rr, "getCLIR", e);
1458             }
1459         }
1460     }
1461
1462     @Override
1463     public void setCLIR(int clirMode, Message result) {
1464         IRadio radioProxy = getRadioProxy(result);
1465         if (radioProxy != null) {
1466             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CLIR, result, mRILDefaultWorkSource);
1467
1468             if (RILJ_LOGD) {
1469                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1470                         + " clirMode = " + clirMode);
1471             }
1472
1473             try {
1474                 radioProxy.setClir(rr.mSerial, clirMode);
1475             } catch (RemoteException | RuntimeException e) {
1476                 handleRadioProxyExceptionForRR(rr, "setCLIR", e);
1477             }
1478         }
1479     }
1480
1481     @Override
1482     public void queryCallForwardStatus(int cfReason, int serviceClass,
1483                            String number, Message result) {
1484         IRadio radioProxy = getRadioProxy(result);
1485         if (radioProxy != null) {
1486             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, result,
1487                     mRILDefaultWorkSource);
1488
1489             if (RILJ_LOGD) {
1490                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1491                         + " cfreason = " + cfReason + " serviceClass = " + serviceClass);
1492             }
1493
1494             android.hardware.radio.V1_0.CallForwardInfo cfInfo =
1495                     new android.hardware.radio.V1_0.CallForwardInfo();
1496             cfInfo.reason = cfReason;
1497             cfInfo.serviceClass = serviceClass;
1498             cfInfo.toa = PhoneNumberUtils.toaFromString(number);
1499             cfInfo.number = convertNullToEmptyString(number);
1500             cfInfo.timeSeconds = 0;
1501
1502             try {
1503                 radioProxy.getCallForwardStatus(rr.mSerial, cfInfo);
1504             } catch (RemoteException | RuntimeException e) {
1505                 handleRadioProxyExceptionForRR(rr, "queryCallForwardStatus", e);
1506             }
1507         }
1508     }
1509
1510     @Override
1511     public void setCallForward(int action, int cfReason, int serviceClass,
1512                    String number, int timeSeconds, Message result) {
1513         IRadio radioProxy = getRadioProxy(result);
1514         if (radioProxy != null) {
1515             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CALL_FORWARD, result,
1516                     mRILDefaultWorkSource);
1517
1518             if (RILJ_LOGD) {
1519                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1520                         + " action = " + action + " cfReason = " + cfReason + " serviceClass = "
1521                         + serviceClass + " timeSeconds = " + timeSeconds);
1522             }
1523
1524             android.hardware.radio.V1_0.CallForwardInfo cfInfo =
1525                     new android.hardware.radio.V1_0.CallForwardInfo();
1526             cfInfo.status = action;
1527             cfInfo.reason = cfReason;
1528             cfInfo.serviceClass = serviceClass;
1529             cfInfo.toa = PhoneNumberUtils.toaFromString(number);
1530             cfInfo.number = convertNullToEmptyString(number);
1531             cfInfo.timeSeconds = timeSeconds;
1532
1533             try {
1534                 radioProxy.setCallForward(rr.mSerial, cfInfo);
1535             } catch (RemoteException | RuntimeException e) {
1536                 handleRadioProxyExceptionForRR(rr, "setCallForward", e);
1537
1538             }
1539         }
1540     }
1541
1542     @Override
1543     public void queryCallWaiting(int serviceClass, Message result) {
1544         IRadio radioProxy = getRadioProxy(result);
1545         if (radioProxy != null) {
1546             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_WAITING, result,
1547                     mRILDefaultWorkSource);
1548
1549             if (RILJ_LOGD) {
1550                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1551                         + " serviceClass = " + serviceClass);
1552             }
1553
1554             try {
1555                 radioProxy.getCallWaiting(rr.mSerial, serviceClass);
1556             } catch (RemoteException | RuntimeException e) {
1557                 handleRadioProxyExceptionForRR(rr, "queryCallWaiting", e);
1558             }
1559         }
1560     }
1561
1562     @Override
1563     public void setCallWaiting(boolean enable, int serviceClass, Message result) {
1564         IRadio radioProxy = getRadioProxy(result);
1565         if (radioProxy != null) {
1566             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CALL_WAITING, result,
1567                     mRILDefaultWorkSource);
1568
1569             if (RILJ_LOGD) {
1570                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1571                         + " enable = " + enable + " serviceClass = " + serviceClass);
1572             }
1573
1574             try {
1575                 radioProxy.setCallWaiting(rr.mSerial, enable, serviceClass);
1576             } catch (RemoteException | RuntimeException e) {
1577                 handleRadioProxyExceptionForRR(rr, "setCallWaiting", e);
1578             }
1579         }
1580     }
1581
1582     @Override
1583     public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
1584         IRadio radioProxy = getRadioProxy(result);
1585         if (radioProxy != null) {
1586             RILRequest rr = obtainRequest(RIL_REQUEST_SMS_ACKNOWLEDGE, result,
1587                     mRILDefaultWorkSource);
1588
1589             if (RILJ_LOGD) {
1590                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1591                         + " success = " + success + " cause = " + cause);
1592             }
1593
1594             try {
1595                 radioProxy.acknowledgeLastIncomingGsmSms(rr.mSerial, success, cause);
1596             } catch (RemoteException | RuntimeException e) {
1597                 handleRadioProxyExceptionForRR(rr, "acknowledgeLastIncomingGsmSms", e);
1598             }
1599         }
1600     }
1601
1602     @Override
1603     public void acceptCall(Message result) {
1604         IRadio radioProxy = getRadioProxy(result);
1605         if (radioProxy != null) {
1606             RILRequest rr = obtainRequest(RIL_REQUEST_ANSWER, result,
1607                     mRILDefaultWorkSource);
1608
1609             if (RILJ_LOGD) {
1610                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1611             }
1612
1613             try {
1614                 radioProxy.acceptCall(rr.mSerial);
1615                 mMetrics.writeRilAnswer(mPhoneId, rr.mSerial);
1616             } catch (RemoteException | RuntimeException e) {
1617                 handleRadioProxyExceptionForRR(rr, "acceptCall", e);
1618             }
1619         }
1620     }
1621
1622     @Override
1623     public void deactivateDataCall(int cid, int reason, Message result) {
1624         IRadio radioProxy = getRadioProxy(result);
1625         if (radioProxy != null) {
1626             RILRequest rr = obtainRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, result,
1627                     mRILDefaultWorkSource);
1628
1629             if (RILJ_LOGD) {
1630                 riljLog(rr.serialString() + "> "
1631                         + requestToString(rr.mRequest) + " cid = " + cid + " reason = " + reason);
1632             }
1633
1634             try {
1635                 radioProxy.deactivateDataCall(rr.mSerial, cid, (reason == 0) ? false : true);
1636                 mMetrics.writeRilDeactivateDataCall(mPhoneId, rr.mSerial,
1637                         cid, reason);
1638             } catch (RemoteException | RuntimeException e) {
1639                 handleRadioProxyExceptionForRR(rr, "deactivateDataCall", e);
1640             }
1641         }
1642     }
1643
1644     @Override
1645     public void queryFacilityLock(String facility, String password, int serviceClass,
1646                                   Message result) {
1647         queryFacilityLockForApp(facility, password, serviceClass, null, result);
1648     }
1649
1650     @Override
1651     public void queryFacilityLockForApp(String facility, String password, int serviceClass,
1652                                         String appId, Message result) {
1653         IRadio radioProxy = getRadioProxy(result);
1654         if (radioProxy != null) {
1655             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_FACILITY_LOCK, result,
1656                     mRILDefaultWorkSource);
1657
1658             if (RILJ_LOGD) {
1659                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1660                         + " facility = " + facility + " serviceClass = " + serviceClass
1661                         + " appId = " + appId);
1662             }
1663
1664             try {
1665                 radioProxy.getFacilityLockForApp(rr.mSerial,
1666                         convertNullToEmptyString(facility),
1667                         convertNullToEmptyString(password),
1668                         serviceClass,
1669                         convertNullToEmptyString(appId));
1670             } catch (RemoteException | RuntimeException e) {
1671                 handleRadioProxyExceptionForRR(rr, "getFacilityLockForApp", e);
1672             }
1673         }
1674     }
1675
1676     @Override
1677     public void setFacilityLock(String facility, boolean lockState, String password,
1678                                 int serviceClass, Message result) {
1679         setFacilityLockForApp(facility, lockState, password, serviceClass, null, result);
1680     }
1681
1682     @Override
1683     public void setFacilityLockForApp(String facility, boolean lockState, String password,
1684                                       int serviceClass, String appId, Message result) {
1685         IRadio radioProxy = getRadioProxy(result);
1686         if (radioProxy != null) {
1687             RILRequest rr = obtainRequest(RIL_REQUEST_SET_FACILITY_LOCK, result,
1688                     mRILDefaultWorkSource);
1689
1690             if (RILJ_LOGD) {
1691                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1692                         + " facility = " + facility + " lockstate = " + lockState
1693                         + " serviceClass = " + serviceClass + " appId = " + appId);
1694             }
1695
1696             try {
1697                 radioProxy.setFacilityLockForApp(rr.mSerial,
1698                         convertNullToEmptyString(facility),
1699                         lockState,
1700                         convertNullToEmptyString(password),
1701                         serviceClass,
1702                         convertNullToEmptyString(appId));
1703             } catch (RemoteException | RuntimeException e) {
1704                 handleRadioProxyExceptionForRR(rr, "setFacilityLockForApp", e);
1705             }
1706         }
1707     }
1708
1709     @Override
1710     public void changeBarringPassword(String facility, String oldPwd, String newPwd,
1711                                       Message result) {
1712         IRadio radioProxy = getRadioProxy(result);
1713         if (radioProxy != null) {
1714             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result,
1715                     mRILDefaultWorkSource);
1716
1717             // Do not log all function args for privacy
1718             if (RILJ_LOGD) {
1719                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1720                         + "facility = " + facility);
1721             }
1722
1723             try {
1724                 radioProxy.setBarringPassword(rr.mSerial,
1725                         convertNullToEmptyString(facility),
1726                         convertNullToEmptyString(oldPwd),
1727                         convertNullToEmptyString(newPwd));
1728             } catch (RemoteException | RuntimeException e) {
1729                 handleRadioProxyExceptionForRR(rr, "changeBarringPassword", e);
1730             }
1731         }
1732     }
1733
1734     @Override
1735     public void getNetworkSelectionMode(Message result) {
1736         IRadio radioProxy = getRadioProxy(result);
1737         if (radioProxy != null) {
1738             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, result,
1739                     mRILDefaultWorkSource);
1740
1741             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1742
1743             try {
1744                 radioProxy.getNetworkSelectionMode(rr.mSerial);
1745             } catch (RemoteException | RuntimeException e) {
1746                 handleRadioProxyExceptionForRR(rr, "getNetworkSelectionMode", e);
1747             }
1748         }
1749     }
1750
1751     @Override
1752     public void setNetworkSelectionModeAutomatic(Message result) {
1753         IRadio radioProxy = getRadioProxy(result);
1754         if (radioProxy != null) {
1755             RILRequest rr = obtainRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, result,
1756                     mRILDefaultWorkSource);
1757
1758             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1759
1760             try {
1761                 radioProxy.setNetworkSelectionModeAutomatic(rr.mSerial);
1762             } catch (RemoteException | RuntimeException e) {
1763                 handleRadioProxyExceptionForRR(rr, "setNetworkSelectionModeAutomatic", e);
1764             }
1765         }
1766     }
1767
1768     @Override
1769     public void setNetworkSelectionModeManual(String operatorNumeric, Message result) {
1770         IRadio radioProxy = getRadioProxy(result);
1771         if (radioProxy != null) {
1772             RILRequest rr = obtainRequest(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, result,
1773                     mRILDefaultWorkSource);
1774
1775             if (RILJ_LOGD) {
1776                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1777                         + " operatorNumeric = " + operatorNumeric);
1778             }
1779
1780             try {
1781                 radioProxy.setNetworkSelectionModeManual(rr.mSerial,
1782                         convertNullToEmptyString(operatorNumeric));
1783             } catch (RemoteException | RuntimeException e) {
1784                 handleRadioProxyExceptionForRR(rr, "setNetworkSelectionModeManual", e);
1785             }
1786         }
1787     }
1788
1789     @Override
1790     public void getAvailableNetworks(Message result) {
1791         IRadio radioProxy = getRadioProxy(result);
1792         if (radioProxy != null) {
1793             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS, result,
1794                     mRILDefaultWorkSource);
1795
1796             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1797
1798             try {
1799                 radioProxy.getAvailableNetworks(rr.mSerial);
1800             } catch (RemoteException | RuntimeException e) {
1801                 handleRadioProxyExceptionForRR(rr, "getAvailableNetworks", e);
1802             }
1803         }
1804     }
1805
1806     @Override
1807     public void startDtmf(char c, Message result) {
1808         IRadio radioProxy = getRadioProxy(result);
1809         if (radioProxy != null) {
1810             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_START, result,
1811                     mRILDefaultWorkSource);
1812
1813             // Do not log function arg for privacy
1814             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1815
1816             try {
1817                 radioProxy.startDtmf(rr.mSerial, c + "");
1818             } catch (RemoteException | RuntimeException e) {
1819                 handleRadioProxyExceptionForRR(rr, "startDtmf", e);
1820             }
1821         }
1822     }
1823
1824     @Override
1825     public void stopDtmf(Message result) {
1826         IRadio radioProxy = getRadioProxy(result);
1827         if (radioProxy != null) {
1828             RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_STOP, result,
1829                     mRILDefaultWorkSource);
1830
1831             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1832
1833             try {
1834                 radioProxy.stopDtmf(rr.mSerial);
1835             } catch (RemoteException | RuntimeException e) {
1836                 handleRadioProxyExceptionForRR(rr, "stopDtmf", e);
1837             }
1838         }
1839     }
1840
1841     @Override
1842     public void separateConnection(int gsmIndex, Message result) {
1843         IRadio radioProxy = getRadioProxy(result);
1844         if (radioProxy != null) {
1845             RILRequest rr = obtainRequest(RIL_REQUEST_SEPARATE_CONNECTION, result,
1846                     mRILDefaultWorkSource);
1847
1848             if (RILJ_LOGD) {
1849                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1850                         + " gsmIndex = " + gsmIndex);
1851             }
1852
1853             try {
1854                 radioProxy.separateConnection(rr.mSerial, gsmIndex);
1855             } catch (RemoteException | RuntimeException e) {
1856                 handleRadioProxyExceptionForRR(rr, "separateConnection", e);
1857             }
1858         }
1859     }
1860
1861     @Override
1862     public void getBasebandVersion(Message result) {
1863         IRadio radioProxy = getRadioProxy(result);
1864         if (radioProxy != null) {
1865             RILRequest rr = obtainRequest(RIL_REQUEST_BASEBAND_VERSION, result,
1866                     mRILDefaultWorkSource);
1867
1868             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1869
1870             try {
1871                 radioProxy.getBasebandVersion(rr.mSerial);
1872             } catch (RemoteException | RuntimeException e) {
1873                 handleRadioProxyExceptionForRR(rr, "getBasebandVersion", e);
1874             }
1875         }
1876     }
1877
1878     @Override
1879     public void setMute(boolean enableMute, Message result) {
1880         IRadio radioProxy = getRadioProxy(result);
1881         if (radioProxy != null) {
1882             RILRequest rr = obtainRequest(RIL_REQUEST_SET_MUTE, result,
1883                     mRILDefaultWorkSource);
1884
1885             if (RILJ_LOGD) {
1886                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1887                         + " enableMute = " + enableMute);
1888             }
1889
1890             try {
1891                 radioProxy.setMute(rr.mSerial, enableMute);
1892             } catch (RemoteException | RuntimeException e) {
1893                 handleRadioProxyExceptionForRR(rr, "setMute", e);
1894             }
1895         }
1896     }
1897
1898     @Override
1899     public void getMute(Message result) {
1900         IRadio radioProxy = getRadioProxy(result);
1901         if (radioProxy != null) {
1902             RILRequest rr = obtainRequest(RIL_REQUEST_GET_MUTE, result,
1903                     mRILDefaultWorkSource);
1904
1905             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1906
1907             try {
1908                 radioProxy.getMute(rr.mSerial);
1909             } catch (RemoteException | RuntimeException e) {
1910                 handleRadioProxyExceptionForRR(rr, "getMute", e);
1911             }
1912         }
1913     }
1914
1915     @Override
1916     public void queryCLIP(Message result) {
1917         IRadio radioProxy = getRadioProxy(result);
1918         if (radioProxy != null) {
1919             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CLIP, result,
1920                     mRILDefaultWorkSource);
1921
1922             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1923
1924             try {
1925                 radioProxy.getClip(rr.mSerial);
1926             } catch (RemoteException | RuntimeException e) {
1927                 handleRadioProxyExceptionForRR(rr, "queryCLIP", e);
1928             }
1929         }
1930     }
1931
1932     /**
1933      * @deprecated
1934      */
1935     @Override
1936     @Deprecated
1937     public void getPDPContextList(Message result) {
1938         getDataCallList(result);
1939     }
1940
1941     @Override
1942     public void getDataCallList(Message result) {
1943         IRadio radioProxy = getRadioProxy(result);
1944         if (radioProxy != null) {
1945             RILRequest rr = obtainRequest(RIL_REQUEST_DATA_CALL_LIST, result,
1946                     mRILDefaultWorkSource);
1947
1948             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1949
1950             try {
1951                 radioProxy.getDataCallList(rr.mSerial);
1952             } catch (RemoteException | RuntimeException e) {
1953                 handleRadioProxyExceptionForRR(rr, "getDataCallList", e);
1954             }
1955         }
1956     }
1957
1958     @Override
1959     public void invokeOemRilRequestRaw(byte[] data, Message response) {
1960         IOemHook oemHookProxy = getOemHookProxy(response);
1961         if (oemHookProxy != null) {
1962             RILRequest rr = obtainRequest(RIL_REQUEST_OEM_HOOK_RAW, response,
1963                     mRILDefaultWorkSource);
1964
1965             if (RILJ_LOGD) {
1966                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1967                         + "[" + IccUtils.bytesToHexString(data) + "]");
1968             }
1969
1970             try {
1971                 oemHookProxy.sendRequestRaw(rr.mSerial, primitiveArrayToArrayList(data));
1972             } catch (RemoteException | RuntimeException e) {
1973                 handleRadioProxyExceptionForRR(rr, "invokeOemRilRequestStrings", e);
1974             }
1975         }
1976     }
1977
1978     @Override
1979     public void invokeOemRilRequestStrings(String[] strings, Message result) {
1980         IOemHook oemHookProxy = getOemHookProxy(result);
1981         if (oemHookProxy != null) {
1982             RILRequest rr = obtainRequest(RIL_REQUEST_OEM_HOOK_STRINGS, result,
1983                     mRILDefaultWorkSource);
1984
1985             String logStr = "";
1986             for (int i = 0; i < strings.length; i++) {
1987                 logStr = logStr + strings[i] + " ";
1988             }
1989             if (RILJ_LOGD) {
1990                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " strings = "
1991                         + logStr);
1992             }
1993
1994             try {
1995                 oemHookProxy.sendRequestStrings(rr.mSerial,
1996                         new ArrayList<String>(Arrays.asList(strings)));
1997             } catch (RemoteException | RuntimeException e) {
1998                 handleRadioProxyExceptionForRR(rr, "invokeOemRilRequestStrings", e);
1999             }
2000         }
2001     }
2002
2003     @Override
2004     public void setSuppServiceNotifications(boolean enable, Message result) {
2005         IRadio radioProxy = getRadioProxy(result);
2006         if (radioProxy != null) {
2007             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result,
2008                     mRILDefaultWorkSource);
2009
2010             if (RILJ_LOGD) {
2011                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " enable = "
2012                         + enable);
2013             }
2014
2015             try {
2016                 radioProxy.setSuppServiceNotifications(rr.mSerial, enable);
2017             } catch (RemoteException | RuntimeException e) {
2018                 handleRadioProxyExceptionForRR(rr, "setSuppServiceNotifications", e);
2019             }
2020         }
2021     }
2022
2023     @Override
2024     public void writeSmsToSim(int status, String smsc, String pdu, Message result) {
2025         status = translateStatus(status);
2026         IRadio radioProxy = getRadioProxy(result);
2027         if (radioProxy != null) {
2028             RILRequest rr = obtainRequest(RIL_REQUEST_WRITE_SMS_TO_SIM, result,
2029                     mRILDefaultWorkSource);
2030
2031             if (RILJ_LOGV) {
2032                 riljLog(rr.serialString() + "> "
2033                         + requestToString(rr.mRequest)
2034                         + " " + status);
2035             }
2036
2037             SmsWriteArgs args = new SmsWriteArgs();
2038             args.status = status;
2039             args.smsc = convertNullToEmptyString(smsc);
2040             args.pdu = convertNullToEmptyString(pdu);
2041
2042             try {
2043                 radioProxy.writeSmsToSim(rr.mSerial, args);
2044             } catch (RemoteException | RuntimeException e) {
2045                 handleRadioProxyExceptionForRR(rr, "writeSmsToSim", e);
2046             }
2047         }
2048     }
2049
2050     @Override
2051     public void deleteSmsOnSim(int index, Message result) {
2052         IRadio radioProxy = getRadioProxy(result);
2053         if (radioProxy != null) {
2054             RILRequest rr = obtainRequest(RIL_REQUEST_DELETE_SMS_ON_SIM, result,
2055                     mRILDefaultWorkSource);
2056
2057             if (RILJ_LOGV) {
2058                 riljLog(rr.serialString() + "> "
2059                         + requestToString(rr.mRequest) + " index = " + index);
2060             }
2061
2062             try {
2063                 radioProxy.deleteSmsOnSim(rr.mSerial, index);
2064             } catch (RemoteException | RuntimeException e) {
2065                 handleRadioProxyExceptionForRR(rr, "deleteSmsOnSim", e);
2066             }
2067         }
2068     }
2069
2070     @Override
2071     public void setBandMode(int bandMode, Message result) {
2072         IRadio radioProxy = getRadioProxy(result);
2073         if (radioProxy != null) {
2074             RILRequest rr = obtainRequest(RIL_REQUEST_SET_BAND_MODE, result,
2075                     mRILDefaultWorkSource);
2076
2077             if (RILJ_LOGD) {
2078                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2079                         + " bandMode = " + bandMode);
2080             }
2081
2082             try {
2083                 radioProxy.setBandMode(rr.mSerial, bandMode);
2084             } catch (RemoteException | RuntimeException e) {
2085                 handleRadioProxyExceptionForRR(rr, "setBandMode", e);
2086             }
2087         }
2088     }
2089
2090     @Override
2091     public void queryAvailableBandMode(Message result) {
2092         IRadio radioProxy = getRadioProxy(result);
2093         if (radioProxy != null) {
2094             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, result,
2095                     mRILDefaultWorkSource);
2096
2097             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2098
2099             try {
2100                 radioProxy.getAvailableBandModes(rr.mSerial);
2101             } catch (RemoteException | RuntimeException e) {
2102                 handleRadioProxyExceptionForRR(rr, "queryAvailableBandMode", e);
2103             }
2104         }
2105     }
2106
2107     @Override
2108     public void sendEnvelope(String contents, Message result) {
2109         IRadio radioProxy = getRadioProxy(result);
2110         if (radioProxy != null) {
2111             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, result,
2112                     mRILDefaultWorkSource);
2113
2114             if (RILJ_LOGD) {
2115                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
2116                         + contents);
2117             }
2118
2119             try {
2120                 radioProxy.sendEnvelope(rr.mSerial, convertNullToEmptyString(contents));
2121             } catch (RemoteException | RuntimeException e) {
2122                 handleRadioProxyExceptionForRR(rr, "sendEnvelope", e);
2123             }
2124         }
2125     }
2126
2127     @Override
2128     public void sendTerminalResponse(String contents, Message result) {
2129         IRadio radioProxy = getRadioProxy(result);
2130         if (radioProxy != null) {
2131             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, result,
2132                     mRILDefaultWorkSource);
2133
2134             if (RILJ_LOGD) {
2135                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
2136                         + contents);
2137             }
2138
2139             try {
2140                 radioProxy.sendTerminalResponseToSim(rr.mSerial,
2141                         convertNullToEmptyString(contents));
2142             } catch (RemoteException | RuntimeException e) {
2143                 handleRadioProxyExceptionForRR(rr, "sendTerminalResponse", e);
2144             }
2145         }
2146     }
2147
2148     @Override
2149     public void sendEnvelopeWithStatus(String contents, Message result) {
2150         IRadio radioProxy = getRadioProxy(result);
2151         if (radioProxy != null) {
2152             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, result,
2153                     mRILDefaultWorkSource);
2154
2155             if (RILJ_LOGD) {
2156                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
2157                         + contents);
2158             }
2159
2160             try {
2161                 radioProxy.sendEnvelopeWithStatus(rr.mSerial, convertNullToEmptyString(contents));
2162             } catch (RemoteException | RuntimeException e) {
2163                 handleRadioProxyExceptionForRR(rr, "sendEnvelopeWithStatus", e);
2164             }
2165         }
2166     }
2167
2168     @Override
2169     public void explicitCallTransfer(Message result) {
2170         IRadio radioProxy = getRadioProxy(result);
2171         if (radioProxy != null) {
2172             RILRequest rr = obtainRequest(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result,
2173                     mRILDefaultWorkSource);
2174
2175             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2176
2177             try {
2178                 radioProxy.explicitCallTransfer(rr.mSerial);
2179             } catch (RemoteException | RuntimeException e) {
2180                 handleRadioProxyExceptionForRR(rr, "explicitCallTransfer", e);
2181             }
2182         }
2183     }
2184
2185     @Override
2186     public void setPreferredNetworkType(int networkType , Message result) {
2187         IRadio radioProxy = getRadioProxy(result);
2188         if (radioProxy != null) {
2189             RILRequest rr = obtainRequest(RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, result,
2190                     mRILDefaultWorkSource);
2191
2192             if (RILJ_LOGD) {
2193                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2194                         + " networkType = " + networkType);
2195             }
2196             mPreferredNetworkType = networkType;
2197             mMetrics.writeSetPreferredNetworkType(mPhoneId, networkType);
2198
2199             try {
2200                 radioProxy.setPreferredNetworkType(rr.mSerial, networkType);
2201             } catch (RemoteException | RuntimeException e) {
2202                 handleRadioProxyExceptionForRR(rr, "setPreferredNetworkType", e);
2203             }
2204         }
2205     }
2206
2207     @Override
2208     public void getPreferredNetworkType(Message result) {
2209         IRadio radioProxy = getRadioProxy(result);
2210         if (radioProxy != null) {
2211             RILRequest rr = obtainRequest(RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, result,
2212                     mRILDefaultWorkSource);
2213
2214             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2215
2216             try {
2217                 radioProxy.getPreferredNetworkType(rr.mSerial);
2218             } catch (RemoteException | RuntimeException e) {
2219                 handleRadioProxyExceptionForRR(rr, "getPreferredNetworkType", e);
2220             }
2221         }
2222     }
2223
2224     @Override
2225     public void getNeighboringCids(Message result, WorkSource workSource) {
2226         workSource = getDeafultWorkSourceIfInvalid(workSource);
2227         IRadio radioProxy = getRadioProxy(result);
2228         if (radioProxy != null) {
2229             RILRequest rr = obtainRequest(RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, result,
2230                     workSource);
2231
2232             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2233
2234             try {
2235                 radioProxy.getNeighboringCids(rr.mSerial);
2236             } catch (RemoteException | RuntimeException e) {
2237                 handleRadioProxyExceptionForRR(rr, "getNeighboringCids", e);
2238             }
2239         }
2240     }
2241
2242     @Override
2243     public void setLocationUpdates(boolean enable, Message result) {
2244         IRadio radioProxy = getRadioProxy(result);
2245         if (radioProxy != null) {
2246             RILRequest rr = obtainRequest(RIL_REQUEST_SET_LOCATION_UPDATES, result,
2247                     mRILDefaultWorkSource);
2248
2249             if (RILJ_LOGD) {
2250                 riljLog(rr.serialString() + "> "
2251                         + requestToString(rr.mRequest) + " enable = " + enable);
2252             }
2253
2254             try {
2255                 radioProxy.setLocationUpdates(rr.mSerial, enable);
2256             } catch (RemoteException | RuntimeException e) {
2257                 handleRadioProxyExceptionForRR(rr, "setLocationUpdates", e);
2258             }
2259         }
2260     }
2261
2262     @Override
2263     public void setCdmaSubscriptionSource(int cdmaSubscription , Message result) {
2264         IRadio radioProxy = getRadioProxy(result);
2265         if (radioProxy != null) {
2266             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, result,
2267                     mRILDefaultWorkSource);
2268
2269             if (RILJ_LOGD) {
2270                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2271                         + " cdmaSubscription = " + cdmaSubscription);
2272             }
2273
2274             try {
2275                 radioProxy.setCdmaSubscriptionSource(rr.mSerial, cdmaSubscription);
2276             } catch (RemoteException | RuntimeException e) {
2277                 handleRadioProxyExceptionForRR(rr, "setCdmaSubscriptionSource", e);
2278             }
2279         }
2280     }
2281
2282     @Override
2283     public void queryCdmaRoamingPreference(Message result) {
2284         IRadio radioProxy = getRadioProxy(result);
2285         if (radioProxy != null) {
2286             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, result,
2287                     mRILDefaultWorkSource);
2288
2289             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2290
2291             try {
2292                 radioProxy.getCdmaRoamingPreference(rr.mSerial);
2293             } catch (RemoteException | RuntimeException e) {
2294                 handleRadioProxyExceptionForRR(rr, "queryCdmaRoamingPreference", e);
2295             }
2296         }
2297     }
2298
2299     @Override
2300     public void setCdmaRoamingPreference(int cdmaRoamingType, Message result) {
2301         IRadio radioProxy = getRadioProxy(result);
2302         if (radioProxy != null) {
2303             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, result,
2304                     mRILDefaultWorkSource);
2305
2306             if (RILJ_LOGD) {
2307                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2308                         + " cdmaRoamingType = " + cdmaRoamingType);
2309             }
2310
2311             try {
2312                 radioProxy.setCdmaRoamingPreference(rr.mSerial, cdmaRoamingType);
2313             } catch (RemoteException | RuntimeException e) {
2314                 handleRadioProxyExceptionForRR(rr, "setCdmaRoamingPreference", e);
2315             }
2316         }
2317     }
2318
2319     @Override
2320     public void queryTTYMode(Message result) {
2321         IRadio radioProxy = getRadioProxy(result);
2322         if (radioProxy != null) {
2323             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_TTY_MODE, result,
2324                     mRILDefaultWorkSource);
2325
2326             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2327
2328             try {
2329                 radioProxy.getTTYMode(rr.mSerial);
2330             } catch (RemoteException | RuntimeException e) {
2331                 handleRadioProxyExceptionForRR(rr, "queryTTYMode", e);
2332             }
2333         }
2334     }
2335
2336     @Override
2337     public void setTTYMode(int ttyMode, Message result) {
2338         IRadio radioProxy = getRadioProxy(result);
2339         if (radioProxy != null) {
2340             RILRequest rr = obtainRequest(RIL_REQUEST_SET_TTY_MODE, result,
2341                     mRILDefaultWorkSource);
2342
2343             if (RILJ_LOGD) {
2344                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2345                         + " ttyMode = " + ttyMode);
2346             }
2347
2348             try {
2349                 radioProxy.setTTYMode(rr.mSerial, ttyMode);
2350             } catch (RemoteException | RuntimeException e) {
2351                 handleRadioProxyExceptionForRR(rr, "setTTYMode", e);
2352             }
2353         }
2354     }
2355
2356     @Override
2357     public void setPreferredVoicePrivacy(boolean enable, Message result) {
2358         IRadio radioProxy = getRadioProxy(result);
2359         if (radioProxy != null) {
2360             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, result,
2361                     mRILDefaultWorkSource);
2362
2363             if (RILJ_LOGD) {
2364                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2365                         + " enable = " + enable);
2366             }
2367
2368             try {
2369                 radioProxy.setPreferredVoicePrivacy(rr.mSerial, enable);
2370             } catch (RemoteException | RuntimeException e) {
2371                 handleRadioProxyExceptionForRR(rr, "setPreferredVoicePrivacy", e);
2372             }
2373         }
2374     }
2375
2376     @Override
2377     public void getPreferredVoicePrivacy(Message result) {
2378         IRadio radioProxy = getRadioProxy(result);
2379         if (radioProxy != null) {
2380             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE,
2381                     result, mRILDefaultWorkSource);
2382
2383             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2384
2385             try {
2386                 radioProxy.getPreferredVoicePrivacy(rr.mSerial);
2387             } catch (RemoteException | RuntimeException e) {
2388                 handleRadioProxyExceptionForRR(rr, "getPreferredVoicePrivacy", e);
2389             }
2390         }
2391     }
2392
2393     @Override
2394     public void sendCDMAFeatureCode(String featureCode, Message result) {
2395         IRadio radioProxy = getRadioProxy(result);
2396         if (radioProxy != null) {
2397             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_FLASH, result,
2398                     mRILDefaultWorkSource);
2399
2400             if (RILJ_LOGD) {
2401                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2402                         + " featureCode = " + featureCode);
2403             }
2404
2405             try {
2406                 radioProxy.sendCDMAFeatureCode(rr.mSerial, convertNullToEmptyString(featureCode));
2407             } catch (RemoteException | RuntimeException e) {
2408                 handleRadioProxyExceptionForRR(rr, "sendCDMAFeatureCode", e);
2409             }
2410         }
2411     }
2412
2413     @Override
2414     public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
2415         IRadio radioProxy = getRadioProxy(result);
2416         if (radioProxy != null) {
2417             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_BURST_DTMF, result,
2418                     mRILDefaultWorkSource);
2419
2420             if (RILJ_LOGD) {
2421                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2422                         + " dtmfString = " + dtmfString + " on = " + on + " off = " + off);
2423             }
2424
2425             try {
2426                 radioProxy.sendBurstDtmf(rr.mSerial, convertNullToEmptyString(dtmfString), on, off);
2427             } catch (RemoteException | RuntimeException e) {
2428                 handleRadioProxyExceptionForRR(rr, "sendBurstDtmf", e);
2429             }
2430         }
2431     }
2432
2433     private void constructCdmaSendSmsRilRequest(CdmaSmsMessage msg, byte[] pdu) {
2434         int addrNbrOfDigits;
2435         int subaddrNbrOfDigits;
2436         int bearerDataLength;
2437         ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
2438         DataInputStream dis = new DataInputStream(bais);
2439
2440         try {
2441             msg.teleserviceId = dis.readInt(); // teleServiceId
2442             msg.isServicePresent = (byte) dis.readInt() == 1 ? true : false; // servicePresent
2443             msg.serviceCategory = dis.readInt(); // serviceCategory
2444             msg.address.digitMode = dis.read();  // address digit mode
2445             msg.address.numberMode = dis.read(); // address number mode
2446             msg.address.numberType = dis.read(); // address number type
2447             msg.address.numberPlan = dis.read(); // address number plan
2448             addrNbrOfDigits = (byte) dis.read();
2449             for (int i = 0; i < addrNbrOfDigits; i++) {
2450                 msg.address.digits.add(dis.readByte()); // address_orig_bytes[i]
2451             }
2452             msg.subAddress.subaddressType = dis.read(); //subaddressType
2453             msg.subAddress.odd = (byte) dis.read() == 1 ? true : false; //subaddr odd
2454             subaddrNbrOfDigits = (byte) dis.read();
2455             for (int i = 0; i < subaddrNbrOfDigits; i++) {
2456                 msg.subAddress.digits.add(dis.readByte()); //subaddr_orig_bytes[i]
2457             }
2458
2459             bearerDataLength = dis.read();
2460             for (int i = 0; i < bearerDataLength; i++) {
2461                 msg.bearerData.add(dis.readByte()); //bearerData[i]
2462             }
2463         } catch (IOException ex) {
2464             if (RILJ_LOGD) {
2465                 riljLog("sendSmsCdma: conversion from input stream to object failed: "
2466                         + ex);
2467             }
2468         }
2469     }
2470
2471     @Override
2472     public void sendCdmaSms(byte[] pdu, Message result) {
2473         IRadio radioProxy = getRadioProxy(result);
2474         if (radioProxy != null) {
2475             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SEND_SMS, result,
2476                     mRILDefaultWorkSource);
2477
2478             // Do not log function arg for privacy
2479             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2480
2481             CdmaSmsMessage msg = new CdmaSmsMessage();
2482             constructCdmaSendSmsRilRequest(msg, pdu);
2483
2484             try {
2485                 radioProxy.sendCdmaSms(rr.mSerial, msg);
2486                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
2487                         SmsSession.Event.Format.SMS_FORMAT_3GPP2);
2488             } catch (RemoteException | RuntimeException e) {
2489                 handleRadioProxyExceptionForRR(rr, "sendCdmaSms", e);
2490             }
2491         }
2492     }
2493
2494     @Override
2495     public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
2496         IRadio radioProxy = getRadioProxy(result);
2497         if (radioProxy != null) {
2498             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result,
2499                     mRILDefaultWorkSource);
2500
2501             if (RILJ_LOGD) {
2502                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2503                         + " success = " + success + " cause = " + cause);
2504             }
2505
2506             CdmaSmsAck msg = new CdmaSmsAck();
2507             msg.errorClass = success ? 0 : 1;
2508             msg.smsCauseCode = cause;
2509
2510             try {
2511                 radioProxy.acknowledgeLastIncomingCdmaSms(rr.mSerial, msg);
2512             } catch (RemoteException | RuntimeException e) {
2513                 handleRadioProxyExceptionForRR(rr, "acknowledgeLastIncomingCdmaSms", e);
2514             }
2515         }
2516     }
2517
2518     @Override
2519     public void getGsmBroadcastConfig(Message result) {
2520         IRadio radioProxy = getRadioProxy(result);
2521         if (radioProxy != null) {
2522             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, result,
2523                     mRILDefaultWorkSource);
2524
2525             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2526
2527             try {
2528                 radioProxy.getGsmBroadcastConfig(rr.mSerial);
2529             } catch (RemoteException | RuntimeException e) {
2530                 handleRadioProxyExceptionForRR(rr, "getGsmBroadcastConfig", e);
2531             }
2532         }
2533     }
2534
2535     @Override
2536     public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message result) {
2537         IRadio radioProxy = getRadioProxy(result);
2538         if (radioProxy != null) {
2539             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, result,
2540                     mRILDefaultWorkSource);
2541
2542             if (RILJ_LOGD) {
2543                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2544                         + " with " + config.length + " configs : ");
2545                 for (int i = 0; i < config.length; i++) {
2546                     riljLog(config[i].toString());
2547                 }
2548             }
2549
2550             ArrayList<GsmBroadcastSmsConfigInfo> configs = new ArrayList<>();
2551
2552             int numOfConfig = config.length;
2553             GsmBroadcastSmsConfigInfo info;
2554
2555             for (int i = 0; i < numOfConfig; i++) {
2556                 info = new GsmBroadcastSmsConfigInfo();
2557                 info.fromServiceId = config[i].getFromServiceId();
2558                 info.toServiceId = config[i].getToServiceId();
2559                 info.fromCodeScheme = config[i].getFromCodeScheme();
2560                 info.toCodeScheme = config[i].getToCodeScheme();
2561                 info.selected = config[i].isSelected();
2562                 configs.add(info);
2563             }
2564
2565             try {
2566                 radioProxy.setGsmBroadcastConfig(rr.mSerial, configs);
2567             } catch (RemoteException | RuntimeException e) {
2568                 handleRadioProxyExceptionForRR(rr, "setGsmBroadcastConfig", e);
2569             }
2570         }
2571     }
2572
2573     @Override
2574     public void setGsmBroadcastActivation(boolean activate, Message result) {
2575         IRadio radioProxy = getRadioProxy(result);
2576         if (radioProxy != null) {
2577             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, result,
2578                     mRILDefaultWorkSource);
2579
2580             if (RILJ_LOGD) {
2581                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2582                         + " activate = " + activate);
2583             }
2584
2585             try {
2586                 radioProxy.setGsmBroadcastActivation(rr.mSerial, activate);
2587             } catch (RemoteException | RuntimeException e) {
2588                 handleRadioProxyExceptionForRR(rr, "setGsmBroadcastActivation", e);
2589             }
2590         }
2591     }
2592
2593     @Override
2594     public void getCdmaBroadcastConfig(Message result) {
2595         IRadio radioProxy = getRadioProxy(result);
2596         if (radioProxy != null) {
2597             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, result,
2598                     mRILDefaultWorkSource);
2599
2600             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2601
2602             try {
2603                 radioProxy.getCdmaBroadcastConfig(rr.mSerial);
2604             } catch (RemoteException | RuntimeException e) {
2605                 handleRadioProxyExceptionForRR(rr, "getCdmaBroadcastConfig", e);
2606             }
2607         }
2608     }
2609
2610     @Override
2611     public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message result) {
2612         IRadio radioProxy = getRadioProxy(result);
2613         if (radioProxy != null) {
2614             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, result,
2615                     mRILDefaultWorkSource);
2616
2617             ArrayList<CdmaBroadcastSmsConfigInfo> halConfigs = new ArrayList<>();
2618
2619             for (CdmaSmsBroadcastConfigInfo config: configs) {
2620                 for (int i = config.getFromServiceCategory();
2621                         i <= config.getToServiceCategory();
2622                         i++) {
2623                     CdmaBroadcastSmsConfigInfo info = new CdmaBroadcastSmsConfigInfo();
2624                     info.serviceCategory = i;
2625                     info.language = config.getLanguage();
2626                     info.selected = config.isSelected();
2627                     halConfigs.add(info);
2628                 }
2629             }
2630
2631             if (RILJ_LOGD) {
2632                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2633                         + " with " + halConfigs.size() + " configs : ");
2634                 for (CdmaBroadcastSmsConfigInfo config : halConfigs) {
2635                     riljLog(config.toString());
2636                 }
2637             }
2638
2639             try {
2640                 radioProxy.setCdmaBroadcastConfig(rr.mSerial, halConfigs);
2641             } catch (RemoteException | RuntimeException e) {
2642                 handleRadioProxyExceptionForRR(rr, "setCdmaBroadcastConfig", e);
2643             }
2644         }
2645     }
2646
2647     @Override
2648     public void setCdmaBroadcastActivation(boolean activate, Message result) {
2649         IRadio radioProxy = getRadioProxy(result);
2650         if (radioProxy != null) {
2651             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, result,
2652                     mRILDefaultWorkSource);
2653
2654             if (RILJ_LOGD) {
2655                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2656                         + " activate = " + activate);
2657             }
2658
2659             try {
2660                 radioProxy.setCdmaBroadcastActivation(rr.mSerial, activate);
2661             } catch (RemoteException | RuntimeException e) {
2662                 handleRadioProxyExceptionForRR(rr, "setCdmaBroadcastActivation", e);
2663             }
2664         }
2665     }
2666
2667     @Override
2668     public void getCDMASubscription(Message result) {
2669         IRadio radioProxy = getRadioProxy(result);
2670         if (radioProxy != null) {
2671             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SUBSCRIPTION, result,
2672                     mRILDefaultWorkSource);
2673
2674             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2675
2676             try {
2677                 radioProxy.getCDMASubscription(rr.mSerial);
2678             } catch (RemoteException | RuntimeException e) {
2679                 handleRadioProxyExceptionForRR(rr, "getCDMASubscription", e);
2680             }
2681         }
2682     }
2683
2684     @Override
2685     public void writeSmsToRuim(int status, String pdu, Message result) {
2686         status = translateStatus(status);
2687         IRadio radioProxy = getRadioProxy(result);
2688         if (radioProxy != null) {
2689             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, result,
2690                     mRILDefaultWorkSource);
2691
2692             if (RILJ_LOGV) {
2693                 riljLog(rr.serialString() + "> "
2694                         + requestToString(rr.mRequest)
2695                         + " status = " + status);
2696             }
2697
2698             CdmaSmsWriteArgs args = new CdmaSmsWriteArgs();
2699             args.status = status;
2700             constructCdmaSendSmsRilRequest(args.message, pdu.getBytes());
2701
2702             try {
2703                 radioProxy.writeSmsToRuim(rr.mSerial, args);
2704             } catch (RemoteException | RuntimeException e) {
2705                 handleRadioProxyExceptionForRR(rr, "writeSmsToRuim", e);
2706             }
2707         }
2708     }
2709
2710     @Override
2711     public void deleteSmsOnRuim(int index, Message result) {
2712         IRadio radioProxy = getRadioProxy(result);
2713         if (radioProxy != null) {
2714             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, result,
2715                     mRILDefaultWorkSource);
2716
2717             if (RILJ_LOGV) {
2718                 riljLog(rr.serialString() + "> "
2719                         + requestToString(rr.mRequest)
2720                         + " index = " + index);
2721             }
2722
2723             try {
2724                 radioProxy.deleteSmsOnRuim(rr.mSerial, index);
2725             } catch (RemoteException | RuntimeException e) {
2726                 handleRadioProxyExceptionForRR(rr, "deleteSmsOnRuim", e);
2727             }
2728         }
2729     }
2730
2731     @Override
2732     public void getDeviceIdentity(Message result) {
2733         IRadio radioProxy = getRadioProxy(result);
2734         if (radioProxy != null) {
2735             RILRequest rr = obtainRequest(RIL_REQUEST_DEVICE_IDENTITY, result,
2736                     mRILDefaultWorkSource);
2737
2738             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2739
2740             try {
2741                 radioProxy.getDeviceIdentity(rr.mSerial);
2742             } catch (RemoteException | RuntimeException e) {
2743                 handleRadioProxyExceptionForRR(rr, "getDeviceIdentity", e);
2744             }
2745         }
2746     }
2747
2748     @Override
2749     public void exitEmergencyCallbackMode(Message result) {
2750         IRadio radioProxy = getRadioProxy(result);
2751         if (radioProxy != null) {
2752             RILRequest rr = obtainRequest(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, result,
2753                     mRILDefaultWorkSource);
2754
2755             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2756
2757             try {
2758                 radioProxy.exitEmergencyCallbackMode(rr.mSerial);
2759             } catch (RemoteException | RuntimeException e) {
2760                 handleRadioProxyExceptionForRR(rr, "exitEmergencyCallbackMode", e);
2761             }
2762         }
2763     }
2764
2765     @Override
2766     public void getSmscAddress(Message result) {
2767         IRadio radioProxy = getRadioProxy(result);
2768         if (radioProxy != null) {
2769             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SMSC_ADDRESS, result,
2770                     mRILDefaultWorkSource);
2771
2772             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2773
2774             try {
2775                 radioProxy.getSmscAddress(rr.mSerial);
2776             } catch (RemoteException | RuntimeException e) {
2777                 handleRadioProxyExceptionForRR(rr, "getSmscAddress", e);
2778             }
2779         }
2780     }
2781
2782     @Override
2783     public void setSmscAddress(String address, Message result) {
2784         IRadio radioProxy = getRadioProxy(result);
2785         if (radioProxy != null) {
2786             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SMSC_ADDRESS, result,
2787                     mRILDefaultWorkSource);
2788
2789             if (RILJ_LOGD) {
2790                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2791                         + " address = " + address);
2792             }
2793
2794             try {
2795                 radioProxy.setSmscAddress(rr.mSerial, convertNullToEmptyString(address));
2796             } catch (RemoteException | RuntimeException e) {
2797                 handleRadioProxyExceptionForRR(rr, "setSmscAddress", e);
2798             }
2799         }
2800     }
2801
2802     @Override
2803     public void reportSmsMemoryStatus(boolean available, Message result) {
2804         IRadio radioProxy = getRadioProxy(result);
2805         if (radioProxy != null) {
2806             RILRequest rr = obtainRequest(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result,
2807                     mRILDefaultWorkSource);
2808
2809             if (RILJ_LOGD) {
2810                 riljLog(rr.serialString() + "> "
2811                         + requestToString(rr.mRequest) + " available = " + available);
2812             }
2813
2814             try {
2815                 radioProxy.reportSmsMemoryStatus(rr.mSerial, available);
2816             } catch (RemoteException | RuntimeException e) {
2817                 handleRadioProxyExceptionForRR(rr, "reportSmsMemoryStatus", e);
2818             }
2819         }
2820     }
2821
2822     @Override
2823     public void reportStkServiceIsRunning(Message result) {
2824         IRadio radioProxy = getRadioProxy(result);
2825         if (radioProxy != null) {
2826             RILRequest rr = obtainRequest(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result,
2827                     mRILDefaultWorkSource);
2828
2829             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2830
2831             try {
2832                 radioProxy.reportStkServiceIsRunning(rr.mSerial);
2833             } catch (RemoteException | RuntimeException e) {
2834                 handleRadioProxyExceptionForRR(rr, "reportStkServiceIsRunning", e);
2835             }
2836         }
2837     }
2838
2839     @Override
2840     public void getCdmaSubscriptionSource(Message result) {
2841         IRadio radioProxy = getRadioProxy(result);
2842         if (radioProxy != null) {
2843             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, result,
2844                     mRILDefaultWorkSource);
2845
2846             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2847
2848             try {
2849                 radioProxy.getCdmaSubscriptionSource(rr.mSerial);
2850             } catch (RemoteException | RuntimeException e) {
2851                 handleRadioProxyExceptionForRR(rr, "getCdmaSubscriptionSource", e);
2852             }
2853         }
2854     }
2855
2856     @Override
2857     public void requestIsimAuthentication(String nonce, Message result) {
2858         IRadio radioProxy = getRadioProxy(result);
2859         if (radioProxy != null) {
2860             RILRequest rr = obtainRequest(RIL_REQUEST_ISIM_AUTHENTICATION, result,
2861                     mRILDefaultWorkSource);
2862
2863             if (RILJ_LOGD) {
2864                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2865                         + " nonce = " + nonce);
2866             }
2867
2868             try {
2869                 radioProxy.requestIsimAuthentication(rr.mSerial, convertNullToEmptyString(nonce));
2870             } catch (RemoteException | RuntimeException e) {
2871                 handleRadioProxyExceptionForRR(rr, "requestIsimAuthentication", e);
2872             }
2873         }
2874     }
2875
2876     @Override
2877     public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) {
2878         IRadio radioProxy = getRadioProxy(result);
2879         if (radioProxy != null) {
2880             RILRequest rr = obtainRequest(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result,
2881                     mRILDefaultWorkSource);
2882
2883             if (RILJ_LOGD) {
2884                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2885                         + " success = " + success);
2886             }
2887
2888             try {
2889                 radioProxy.acknowledgeIncomingGsmSmsWithPdu(rr.mSerial, success,
2890                         convertNullToEmptyString(ackPdu));
2891             } catch (RemoteException | RuntimeException e) {
2892                 handleRadioProxyExceptionForRR(rr, "acknowledgeIncomingGsmSmsWithPdu", e);
2893             }
2894         }
2895     }
2896
2897     @Override
2898     public void getVoiceRadioTechnology(Message result) {
2899         IRadio radioProxy = getRadioProxy(result);
2900         if (radioProxy != null) {
2901             RILRequest rr = obtainRequest(RIL_REQUEST_VOICE_RADIO_TECH, result,
2902                     mRILDefaultWorkSource);
2903
2904             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2905
2906             try {
2907                 radioProxy.getVoiceRadioTechnology(rr.mSerial);
2908             } catch (RemoteException | RuntimeException e) {
2909                 handleRadioProxyExceptionForRR(rr, "getVoiceRadioTechnology", e);
2910             }
2911         }
2912     }
2913
2914     @Override
2915     public void getCellInfoList(Message result, WorkSource workSource) {
2916         workSource = getDeafultWorkSourceIfInvalid(workSource);
2917         IRadio radioProxy = getRadioProxy(result);
2918         if (radioProxy != null) {
2919             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CELL_INFO_LIST, result,
2920                     workSource);
2921
2922             if (RILJ_LOGD) {
2923                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2924             }
2925
2926             try {
2927                 radioProxy.getCellInfoList(rr.mSerial);
2928             } catch (RemoteException | RuntimeException e) {
2929                 handleRadioProxyExceptionForRR(rr, "getCellInfoList", e);
2930             }
2931         }
2932     }
2933
2934     @Override
2935     public void setCellInfoListRate(int rateInMillis, Message result, WorkSource workSource) {
2936         workSource = getDeafultWorkSourceIfInvalid(workSource);
2937         IRadio radioProxy = getRadioProxy(result);
2938         if (radioProxy != null) {
2939             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, result,
2940                     workSource);
2941
2942             if (RILJ_LOGD) {
2943                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2944                         + " rateInMillis = " + rateInMillis);
2945             }
2946
2947             try {
2948                 radioProxy.setCellInfoListRate(rr.mSerial, rateInMillis);
2949             } catch (RemoteException | RuntimeException e) {
2950                 handleRadioProxyExceptionForRR(rr, "setCellInfoListRate", e);
2951             }
2952         }
2953     }
2954
2955     void setCellInfoListRate() {
2956         setCellInfoListRate(Integer.MAX_VALUE, null, mRILDefaultWorkSource);
2957     }
2958
2959     @Override
2960     public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, Message result) {
2961
2962         IRadio radioProxy = getRadioProxy(result);
2963         if (radioProxy != null) {
2964             RILRequest rr = obtainRequest(RIL_REQUEST_SET_INITIAL_ATTACH_APN, result,
2965                     mRILDefaultWorkSource);
2966
2967             if (RILJ_LOGD) {
2968                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + dataProfile);
2969             }
2970
2971             try {
2972                 radioProxy.setInitialAttachApn(rr.mSerial, convertToHalDataProfile(dataProfile),
2973                         dataProfile.modemCognitive, isRoaming);
2974             } catch (RemoteException | RuntimeException e) {
2975                 handleRadioProxyExceptionForRR(rr, "setInitialAttachApn", e);
2976             }
2977         }
2978     }
2979
2980     @Override
2981     public void getImsRegistrationState(Message result) {
2982         IRadio radioProxy = getRadioProxy(result);
2983         if (radioProxy != null) {
2984             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_REGISTRATION_STATE, result,
2985                     mRILDefaultWorkSource);
2986
2987             if (RILJ_LOGD) {
2988                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2989             }
2990
2991             try {
2992                 radioProxy.getImsRegistrationState(rr.mSerial);
2993             } catch (RemoteException | RuntimeException e) {
2994                 handleRadioProxyExceptionForRR(rr, "getImsRegistrationState", e);
2995             }
2996         }
2997     }
2998
2999     @Override
3000     public void sendImsGsmSms(String smscPdu, String pdu, int retry, int messageRef,
3001                    Message result) {
3002         IRadio radioProxy = getRadioProxy(result);
3003         if (radioProxy != null) {
3004             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result,
3005                     mRILDefaultWorkSource);
3006
3007             // Do not log function args for privacy
3008             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3009
3010             ImsSmsMessage msg = new ImsSmsMessage();
3011             msg.tech = RILConstants.GSM_PHONE;
3012             msg.retry = (byte) retry == 1 ? true : false;
3013             msg.messageRef = messageRef;
3014
3015             GsmSmsMessage gsmMsg = constructGsmSendSmsRilRequest(smscPdu, pdu);
3016             msg.gsmMessage.add(gsmMsg);
3017             try {
3018                 radioProxy.sendImsSms(rr.mSerial, msg);
3019                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
3020                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
3021             } catch (RemoteException | RuntimeException e) {
3022                 handleRadioProxyExceptionForRR(rr, "sendImsGsmSms", e);
3023             }
3024         }
3025     }
3026
3027     @Override
3028     public void sendImsCdmaSms(byte[] pdu, int retry, int messageRef, Message result) {
3029         IRadio radioProxy = getRadioProxy(result);
3030         if (radioProxy != null) {
3031             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result,
3032                     mRILDefaultWorkSource);
3033
3034             // Do not log function args for privacy
3035             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3036
3037             ImsSmsMessage msg = new ImsSmsMessage();
3038             msg.tech = RILConstants.CDMA_PHONE;
3039             msg.retry = (byte) retry == 1 ? true : false;
3040             msg.messageRef = messageRef;
3041
3042             CdmaSmsMessage cdmaMsg = new CdmaSmsMessage();
3043             constructCdmaSendSmsRilRequest(cdmaMsg, pdu);
3044             msg.cdmaMessage.add(cdmaMsg);
3045
3046             try {
3047                 radioProxy.sendImsSms(rr.mSerial, msg);
3048                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
3049                         SmsSession.Event.Format.SMS_FORMAT_3GPP);
3050             } catch (RemoteException | RuntimeException e) {
3051                 handleRadioProxyExceptionForRR(rr, "sendImsCdmaSms", e);
3052             }
3053         }
3054     }
3055
3056     private SimApdu createSimApdu(int channel, int cla, int instruction, int p1, int p2, int p3,
3057                                   String data) {
3058         SimApdu msg = new SimApdu();
3059         msg.sessionId = channel;
3060         msg.cla = cla;
3061         msg.instruction = instruction;
3062         msg.p1 = p1;
3063         msg.p2 = p2;
3064         msg.p3 = p3;
3065         msg.data = convertNullToEmptyString(data);
3066         return msg;
3067     }
3068
3069     @Override
3070     public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2,
3071                                             int p3, String data, Message result) {
3072         IRadio radioProxy = getRadioProxy(result);
3073         if (radioProxy != null) {
3074             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, result,
3075                     mRILDefaultWorkSource);
3076
3077             if (RILJ_LOGD) {
3078                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3079                         + " cla = " + cla + " instruction = " + instruction
3080                         + " p1 = " + p1 + " p2 = " + " p3 = " + p3 + " data = " + data);
3081             }
3082
3083             SimApdu msg = createSimApdu(0, cla, instruction, p1, p2, p3, data);
3084             try {
3085                 radioProxy.iccTransmitApduBasicChannel(rr.mSerial, msg);
3086             } catch (RemoteException | RuntimeException e) {
3087                 handleRadioProxyExceptionForRR(rr, "iccTransmitApduBasicChannel", e);
3088             }
3089         }
3090     }
3091
3092     @Override
3093     public void iccOpenLogicalChannel(String aid, int p2, Message result) {
3094         IRadio radioProxy = getRadioProxy(result);
3095         if (radioProxy != null) {
3096             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_OPEN_CHANNEL, result,
3097                     mRILDefaultWorkSource);
3098
3099             if (RILJ_LOGD) {
3100                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " aid = " + aid
3101                         + " p2 = " + p2);
3102             }
3103
3104             try {
3105                 radioProxy.iccOpenLogicalChannel(rr.mSerial, convertNullToEmptyString(aid), p2);
3106             } catch (RemoteException | RuntimeException e) {
3107                 handleRadioProxyExceptionForRR(rr, "iccOpenLogicalChannel", e);
3108             }
3109         }
3110     }
3111
3112     @Override
3113     public void iccCloseLogicalChannel(int channel, Message result) {
3114         IRadio radioProxy = getRadioProxy(result);
3115         if (radioProxy != null) {
3116             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_CLOSE_CHANNEL, result,
3117                     mRILDefaultWorkSource);
3118
3119             if (RILJ_LOGD) {
3120                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " channel = "
3121                         + channel);
3122             }
3123
3124             try {
3125                 radioProxy.iccCloseLogicalChannel(rr.mSerial, channel);
3126             } catch (RemoteException | RuntimeException e) {
3127                 handleRadioProxyExceptionForRR(rr, "iccCloseLogicalChannel", e);
3128             }
3129         }
3130     }
3131
3132     @Override
3133     public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
3134                                               int p1, int p2, int p3, String data,
3135                                               Message result) {
3136         if (channel <= 0) {
3137             throw new RuntimeException(
3138                     "Invalid channel in iccTransmitApduLogicalChannel: " + channel);
3139         }
3140
3141         IRadio radioProxy = getRadioProxy(result);
3142         if (radioProxy != null) {
3143             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, result,
3144                     mRILDefaultWorkSource);
3145
3146             if (RILJ_LOGD) {
3147                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " channel = "
3148                         + channel + " cla = " + cla + " instruction = " + instruction
3149                         + " p1 = " + p1 + " p2 = " + " p3 = " + p3 + " data = " + data);
3150             }
3151
3152             SimApdu msg = createSimApdu(channel, cla, instruction, p1, p2, p3, data);
3153
3154             try {
3155                 radioProxy.iccTransmitApduLogicalChannel(rr.mSerial, msg);
3156             } catch (RemoteException | RuntimeException e) {
3157                 handleRadioProxyExceptionForRR(rr, "iccTransmitApduLogicalChannel", e);
3158             }
3159         }
3160     }
3161
3162     @Override
3163     public void nvReadItem(int itemID, Message result) {
3164         IRadio radioProxy = getRadioProxy(result);
3165         if (radioProxy != null) {
3166             RILRequest rr = obtainRequest(RIL_REQUEST_NV_READ_ITEM, result,
3167                     mRILDefaultWorkSource);
3168
3169             if (RILJ_LOGD) {
3170                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3171                         + " itemId = " + itemID);
3172             }
3173
3174             try {
3175                 radioProxy.nvReadItem(rr.mSerial, itemID);
3176             } catch (RemoteException | RuntimeException e) {
3177                 handleRadioProxyExceptionForRR(rr, "nvReadItem", e);
3178             }
3179         }
3180     }
3181
3182     @Override
3183     public void nvWriteItem(int itemId, String itemValue, Message result) {
3184         IRadio radioProxy = getRadioProxy(result);
3185         if (radioProxy != null) {
3186             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_ITEM, result,
3187                     mRILDefaultWorkSource);
3188
3189             if (RILJ_LOGD) {
3190                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3191                         + " itemId = " + itemId + " itemValue = " + itemValue);
3192             }
3193
3194             NvWriteItem item = new NvWriteItem();
3195             item.itemId = itemId;
3196             item.value = convertNullToEmptyString(itemValue);
3197
3198             try {
3199                 radioProxy.nvWriteItem(rr.mSerial, item);
3200             } catch (RemoteException | RuntimeException e) {
3201                 handleRadioProxyExceptionForRR(rr, "nvWriteItem", e);
3202             }
3203         }
3204     }
3205
3206     @Override
3207     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message result) {
3208         IRadio radioProxy = getRadioProxy(result);
3209         if (radioProxy != null) {
3210             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_CDMA_PRL, result,
3211                     mRILDefaultWorkSource);
3212
3213             if (RILJ_LOGD) {
3214                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3215                         + " PreferredRoamingList = 0x"
3216                         + IccUtils.bytesToHexString(preferredRoamingList));
3217             }
3218
3219             ArrayList<Byte> arrList = new ArrayList<>();
3220             for (int i = 0; i < preferredRoamingList.length; i++) {
3221                 arrList.add(preferredRoamingList[i]);
3222             }
3223
3224             try {
3225                 radioProxy.nvWriteCdmaPrl(rr.mSerial, arrList);
3226             } catch (RemoteException | RuntimeException e) {
3227                 handleRadioProxyExceptionForRR(rr, "nvWriteCdmaPrl", e);
3228             }
3229         }
3230     }
3231
3232     @Override
3233     public void nvResetConfig(int resetType, Message result) {
3234         IRadio radioProxy = getRadioProxy(result);
3235         if (radioProxy != null) {
3236             RILRequest rr = obtainRequest(RIL_REQUEST_NV_RESET_CONFIG, result,
3237                     mRILDefaultWorkSource);
3238
3239             if (RILJ_LOGD) {
3240                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3241                         + " resetType = " + resetType);
3242             }
3243
3244             try {
3245                 radioProxy.nvResetConfig(rr.mSerial, convertToHalResetNvType(resetType));
3246             } catch (RemoteException | RuntimeException e) {
3247                 handleRadioProxyExceptionForRR(rr, "nvResetConfig", e);
3248             }
3249         }
3250     }
3251
3252     @Override
3253     public void setUiccSubscription(int slotId, int appIndex, int subId,
3254                                     int subStatus, Message result) {
3255         IRadio radioProxy = getRadioProxy(result);
3256         if (radioProxy != null) {
3257             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UICC_SUBSCRIPTION, result,
3258                     mRILDefaultWorkSource);
3259
3260             if (RILJ_LOGD) {
3261                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3262                         + " slot = " + slotId + " appIndex = " + appIndex
3263                         + " subId = " + subId + " subStatus = " + subStatus);
3264             }
3265
3266             SelectUiccSub info = new SelectUiccSub();
3267             info.slot = slotId;
3268             info.appIndex = appIndex;
3269             info.subType = subId;
3270             info.actStatus = subStatus;
3271
3272             try {
3273                 radioProxy.setUiccSubscription(rr.mSerial, info);
3274             } catch (RemoteException | RuntimeException e) {
3275                 handleRadioProxyExceptionForRR(rr, "setUiccSubscription", e);
3276             }
3277         }
3278     }
3279
3280     @Override
3281     public void setDataAllowed(boolean allowed, Message result) {
3282         IRadio radioProxy = getRadioProxy(result);
3283         if (radioProxy != null) {
3284             RILRequest rr = obtainRequest(RIL_REQUEST_ALLOW_DATA, result,
3285                     mRILDefaultWorkSource);
3286
3287             if (RILJ_LOGD) {
3288                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3289                         + " allowed = " + allowed);
3290             }
3291
3292             try {
3293                 radioProxy.setDataAllowed(rr.mSerial, allowed);
3294             } catch (RemoteException | RuntimeException e) {
3295                 handleRadioProxyExceptionForRR(rr, "setDataAllowed", e);
3296             }
3297         }
3298     }
3299
3300     @Override
3301     public void
3302     getHardwareConfig (Message result) {
3303         IRadio radioProxy = getRadioProxy(result);
3304         if (radioProxy != null) {
3305             RILRequest rr = obtainRequest(RIL_REQUEST_GET_HARDWARE_CONFIG, result,
3306                     mRILDefaultWorkSource);
3307
3308             // Do not log function args for privacy
3309             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3310
3311             try {
3312                 radioProxy.getHardwareConfig(rr.mSerial);
3313             } catch (RemoteException | RuntimeException e) {
3314                 handleRadioProxyExceptionForRR(rr, "getHardwareConfig", e);
3315             }
3316         }
3317     }
3318
3319     @Override
3320     public void requestIccSimAuthentication(int authContext, String data, String aid,
3321                                             Message result) {
3322         IRadio radioProxy = getRadioProxy(result);
3323         if (radioProxy != null) {
3324             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_AUTHENTICATION, result,
3325                     mRILDefaultWorkSource);
3326
3327             // Do not log function args for privacy
3328             if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3329
3330             try {
3331                 radioProxy.requestIccSimAuthentication(rr.mSerial,
3332                         authContext,
3333                         convertNullToEmptyString(data),
3334                         convertNullToEmptyString(aid));
3335             } catch (RemoteException | RuntimeException e) {
3336                 handleRadioProxyExceptionForRR(rr, "requestIccSimAuthentication", e);
3337             }
3338         }
3339     }
3340
3341     @Override
3342     public void setDataProfile(DataProfile[] dps, boolean isRoaming, Message result) {
3343
3344         IRadio radioProxy = getRadioProxy(result);
3345         if (radioProxy != null) {
3346             RILRequest rr = obtainRequest(RIL_REQUEST_SET_DATA_PROFILE, result,
3347                     mRILDefaultWorkSource);
3348
3349             if (RILJ_LOGD) {
3350                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3351                         + " with data profiles : ");
3352                 for (DataProfile profile : dps) {
3353                     riljLog(profile.toString());
3354                 }
3355             }
3356
3357             ArrayList<DataProfileInfo> dpis = new ArrayList<>();
3358             for (DataProfile dp : dps) {
3359                 dpis.add(convertToHalDataProfile(dp));
3360             }
3361
3362             try {
3363                 radioProxy.setDataProfile(rr.mSerial, dpis, isRoaming);
3364             } catch (RemoteException | RuntimeException e) {
3365                 handleRadioProxyExceptionForRR(rr, "setDataProfile", e);
3366             }
3367         }
3368     }
3369
3370     @Override
3371     public void requestShutdown(Message result) {
3372         IRadio radioProxy = getRadioProxy(result);
3373         if (radioProxy != null) {
3374             RILRequest rr = obtainRequest(RIL_REQUEST_SHUTDOWN, result,
3375                     mRILDefaultWorkSource);
3376
3377             if (RILJ_LOGD) {
3378                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3379             }
3380
3381             try {
3382                 radioProxy.requestShutdown(rr.mSerial);
3383             } catch (RemoteException | RuntimeException e) {
3384                 handleRadioProxyExceptionForRR(rr, "requestShutdown", e);
3385             }
3386         }
3387     }
3388
3389     @Override
3390     public void getRadioCapability(Message response) {
3391         IRadio radioProxy = getRadioProxy(response);
3392         if (radioProxy != null) {
3393             RILRequest rr = obtainRequest(RIL_REQUEST_GET_RADIO_CAPABILITY, response,
3394                     mRILDefaultWorkSource);
3395
3396             if (RILJ_LOGD) {
3397                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3398             }
3399
3400             try {
3401                 radioProxy.getRadioCapability(rr.mSerial);
3402             } catch (RemoteException | RuntimeException e) {
3403                 handleRadioProxyExceptionForRR(rr, "getRadioCapability", e);
3404             }
3405         }
3406     }
3407
3408     @Override
3409     public void setRadioCapability(RadioCapability rc, Message response) {
3410         IRadio radioProxy = getRadioProxy(response);
3411         if (radioProxy != null) {
3412             RILRequest rr = obtainRequest(RIL_REQUEST_SET_RADIO_CAPABILITY, response,
3413                     mRILDefaultWorkSource);
3414
3415             if (RILJ_LOGD) {
3416                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3417                         + " RadioCapability = " + rc.toString());
3418             }
3419
3420             android.hardware.radio.V1_0.RadioCapability halRc =
3421                     new android.hardware.radio.V1_0.RadioCapability();
3422
3423             halRc.session = rc.getSession();
3424             halRc.phase = rc.getPhase();
3425             halRc.raf = rc.getRadioAccessFamily();
3426             halRc.logicalModemUuid = convertNullToEmptyString(rc.getLogicalModemUuid());
3427             halRc.status = rc.getStatus();
3428
3429             try {
3430                 radioProxy.setRadioCapability(rr.mSerial, halRc);
3431             } catch (Exception e) {
3432                 handleRadioProxyExceptionForRR(rr, "setRadioCapability", e);
3433             }
3434         }
3435     }
3436
3437     @Override
3438     public void startLceService(int reportIntervalMs, boolean pullMode, Message result) {
3439         IRadio radioProxy = getRadioProxy(result);
3440         if (radioProxy != null) {
3441             RILRequest rr = obtainRequest(RIL_REQUEST_START_LCE, result,
3442                     mRILDefaultWorkSource);
3443
3444             if (RILJ_LOGD) {
3445                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3446                         + " reportIntervalMs = " + reportIntervalMs + " pullMode = " + pullMode);
3447             }
3448
3449             try {
3450                 radioProxy.startLceService(rr.mSerial, reportIntervalMs, pullMode);
3451             } catch (RemoteException | RuntimeException e) {
3452                 handleRadioProxyExceptionForRR(rr, "startLceService", e);
3453             }
3454         }
3455     }
3456
3457     @Override
3458     public void stopLceService(Message result) {
3459         IRadio radioProxy = getRadioProxy(result);
3460         if (radioProxy != null) {
3461             RILRequest rr = obtainRequest(RIL_REQUEST_STOP_LCE, result,
3462                     mRILDefaultWorkSource);
3463
3464             if (RILJ_LOGD) {
3465                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3466             }
3467
3468             try {
3469                 radioProxy.stopLceService(rr.mSerial);
3470             } catch (RemoteException | RuntimeException e) {
3471                 handleRadioProxyExceptionForRR(rr, "stopLceService", e);
3472             }
3473         }
3474     }
3475
3476     @Override
3477     public void pullLceData(Message response) {
3478         IRadio radioProxy = getRadioProxy(response);
3479         if (radioProxy != null) {
3480             RILRequest rr = obtainRequest(RIL_REQUEST_PULL_LCEDATA, response,
3481                     mRILDefaultWorkSource);
3482
3483             if (RILJ_LOGD) {
3484                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3485             }
3486
3487             try {
3488                 radioProxy.pullLceData(rr.mSerial);
3489             } catch (RemoteException | RuntimeException e) {
3490                 handleRadioProxyExceptionForRR(rr, "pullLceData", e);
3491             }
3492         }
3493     }
3494
3495     @Override
3496     public void getModemActivityInfo(Message result) {
3497         IRadio radioProxy = getRadioProxy(result);
3498         if (radioProxy != null) {
3499             RILRequest rr = obtainRequest(RIL_REQUEST_GET_ACTIVITY_INFO, result,
3500                     mRILDefaultWorkSource);
3501
3502             if (RILJ_LOGD) {
3503                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3504             }
3505
3506             try {
3507                 radioProxy.getModemActivityInfo(rr.mSerial);
3508
3509                 Message msg = mRilHandler.obtainMessage(EVENT_BLOCKING_RESPONSE_TIMEOUT);
3510                 msg.obj = null;
3511                 msg.arg1 = rr.mSerial;
3512                 mRilHandler.sendMessageDelayed(msg, DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS);
3513             } catch (RemoteException | RuntimeException e) {
3514                 handleRadioProxyExceptionForRR(rr, "getModemActivityInfo", e);
3515             }
3516         }
3517
3518
3519     }
3520
3521     @Override
3522     public void setAllowedCarriers(List<CarrierIdentifier> carriers, Message result) {
3523         checkNotNull(carriers, "Allowed carriers list cannot be null.");
3524         IRadio radioProxy = getRadioProxy(result);
3525         if (radioProxy != null) {
3526             RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_CARRIERS, result,
3527                     mRILDefaultWorkSource);
3528
3529             if (RILJ_LOGD) {
3530                 String logStr = "";
3531                 for (int i = 0; i < carriers.size(); i++) {
3532                     logStr = logStr + carriers.get(i) + " ";
3533                 }
3534                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + "carriers = "
3535                         + logStr);
3536             }
3537
3538             boolean allAllowed;
3539             if (carriers.size() == 0) {
3540                 allAllowed = true;
3541             } else {
3542                 allAllowed = false;
3543             }
3544             CarrierRestrictions carrierList = new CarrierRestrictions();
3545
3546             for (CarrierIdentifier ci : carriers) { /* allowed carriers */
3547                 Carrier c = new Carrier();
3548                 c.mcc = convertNullToEmptyString(ci.getMcc());
3549                 c.mnc = convertNullToEmptyString(ci.getMnc());
3550                 int matchType = CarrierIdentifier.MatchType.ALL;
3551                 String matchData = null;
3552                 if (!TextUtils.isEmpty(ci.getSpn())) {
3553                     matchType = CarrierIdentifier.MatchType.SPN;
3554                     matchData = ci.getSpn();
3555                 } else if (!TextUtils.isEmpty(ci.getImsi())) {
3556                     matchType = CarrierIdentifier.MatchType.IMSI_PREFIX;
3557                     matchData = ci.getImsi();
3558                 } else if (!TextUtils.isEmpty(ci.getGid1())) {
3559                     matchType = CarrierIdentifier.MatchType.GID1;
3560                     matchData = ci.getGid1();
3561                 } else if (!TextUtils.isEmpty(ci.getGid2())) {
3562                     matchType = CarrierIdentifier.MatchType.GID2;
3563                     matchData = ci.getGid2();
3564                 }
3565                 c.matchType = matchType;
3566                 c.matchData = convertNullToEmptyString(matchData);
3567                 carrierList.allowedCarriers.add(c);
3568             }
3569
3570             /* TODO: add excluded carriers */
3571
3572             try {
3573                 radioProxy.setAllowedCarriers(rr.mSerial, allAllowed, carrierList);
3574             } catch (RemoteException | RuntimeException e) {
3575                 handleRadioProxyExceptionForRR(rr, "setAllowedCarriers", e);
3576             }
3577         }
3578     }
3579
3580     @Override
3581     public void getAllowedCarriers(Message result) {
3582         IRadio radioProxy = getRadioProxy(result);
3583         if (radioProxy != null) {
3584             RILRequest rr = obtainRequest(RIL_REQUEST_GET_ALLOWED_CARRIERS, result,
3585                     mRILDefaultWorkSource);
3586
3587             if (RILJ_LOGD) {
3588                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3589             }
3590
3591             try {
3592                 radioProxy.getAllowedCarriers(rr.mSerial);
3593             } catch (RemoteException | RuntimeException e) {
3594                 handleRadioProxyExceptionForRR(rr, "getAllowedCarriers", e);
3595             }
3596         }
3597     }
3598
3599     @Override
3600     public void sendDeviceState(int stateType, boolean state,
3601                                 Message result) {
3602         IRadio radioProxy = getRadioProxy(result);
3603         if (radioProxy != null) {
3604             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_DEVICE_STATE, result,
3605                     mRILDefaultWorkSource);
3606
3607             if (RILJ_LOGD) {
3608                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
3609                         + stateType + ":" + state);
3610             }
3611
3612             try {
3613                 radioProxy.sendDeviceState(rr.mSerial, stateType, state);
3614             } catch (RemoteException | RuntimeException e) {
3615                 handleRadioProxyExceptionForRR(rr, "sendDeviceState", e);
3616             }
3617         }
3618     }
3619
3620     @Override
3621     public void setUnsolResponseFilter(int filter, Message result) {
3622         IRadio radioProxy = getRadioProxy(result);
3623         if (radioProxy != null) {
3624             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, result,
3625                     mRILDefaultWorkSource);
3626
3627             if (RILJ_LOGD) {
3628                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + filter);
3629             }
3630
3631             try {
3632                 radioProxy.setIndicationFilter(rr.mSerial, filter);
3633             } catch (RemoteException | RuntimeException e) {
3634                 handleRadioProxyExceptionForRR(rr, "setIndicationFilter", e);
3635             }
3636         }
3637     }
3638
3639     @Override
3640     public void setSimCardPower(boolean powerUp, Message result) {
3641         IRadio radioProxy = getRadioProxy(result);
3642         if (radioProxy != null) {
3643             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIM_CARD_POWER, result,
3644                     mRILDefaultWorkSource);
3645
3646             if (RILJ_LOGD) {
3647                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + powerUp);
3648             }
3649
3650             try {
3651                 radioProxy.setSimCardPower(rr.mSerial, powerUp);
3652             } catch (RemoteException | RuntimeException e) {
3653                 handleRadioProxyExceptionForRR(rr, "setSimCardPower", e);
3654             }
3655         }
3656     }
3657
3658     @Override
3659     public void getIMEI(Message result) {
3660         throw new RuntimeException("getIMEI not expected to be called");
3661     }
3662
3663     @Override
3664     public void getIMEISV(Message result) {
3665         throw new RuntimeException("getIMEISV not expected to be called");
3666     }
3667
3668     /**
3669      * @deprecated
3670      */
3671     @Deprecated
3672     @Override
3673     public void getLastPdpFailCause(Message result) {
3674         throw new RuntimeException("getLastPdpFailCause not expected to be called");
3675     }
3676
3677     /**
3678      * The preferred new alternative to getLastPdpFailCause
3679      */
3680     @Override
3681     public void getLastDataCallFailCause(Message result) {
3682         throw new RuntimeException("getLastDataCallFailCause not expected to be called");
3683     }
3684
3685     /**
3686      *  Translates EF_SMS status bits to a status value compatible with
3687      *  SMS AT commands.  See TS 27.005 3.1.
3688      */
3689     private int translateStatus(int status) {
3690         switch(status & 0x7) {
3691             case SmsManager.STATUS_ON_ICC_READ:
3692                 return 1;
3693             case SmsManager.STATUS_ON_ICC_UNREAD:
3694                 return 0;
3695             case SmsManager.STATUS_ON_ICC_SENT:
3696                 return 3;
3697             case SmsManager.STATUS_ON_ICC_UNSENT:
3698                 return 2;
3699         }
3700
3701         // Default to READ.
3702         return 1;
3703     }
3704
3705     @Override
3706     public void resetRadio(Message result) {
3707         throw new RuntimeException("resetRadio not expected to be called");
3708     }
3709
3710     /**
3711      * {@inheritDoc}
3712      */
3713     @Override
3714     public void handleCallSetupRequestFromSim(boolean accept, Message result) {
3715         IRadio radioProxy = getRadioProxy(result);
3716         if (radioProxy != null) {
3717             RILRequest rr = obtainRequest(RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
3718                     result, mRILDefaultWorkSource);
3719
3720             if (RILJ_LOGD) {
3721                 riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3722             }
3723
3724             try {
3725                 radioProxy.handleStkCallSetupRequestFromSim(rr.mSerial, accept);
3726             } catch (RemoteException | RuntimeException e) {
3727                 handleRadioProxyExceptionForRR(rr, "getAllowedCarriers", e);
3728             }
3729         }
3730     }
3731
3732     //***** Private Methods
3733
3734     /**
3735      * This is a helper function to be called when a RadioIndication callback is called.
3736      * It takes care of acquiring wakelock and sending ack if needed.
3737      * @param indicationType RadioIndicationType received
3738      */
3739     void processIndication(int indicationType) {
3740         if (indicationType == RadioIndicationType.UNSOLICITED_ACK_EXP) {
3741             sendAck();
3742             if (RILJ_LOGD) riljLog("Unsol response received; Sending ack to ril.cpp");
3743         } else {
3744             // ack is not expected to be sent back. Nothing is required to be done here.
3745         }
3746     }
3747
3748     void processRequestAck(int serial) {
3749         RILRequest rr;
3750         synchronized (mRequestList) {
3751             rr = mRequestList.get(serial);
3752         }
3753         if (rr == null) {
3754             Rlog.w(RIL.RILJ_LOG_TAG, "processRequestAck: Unexpected solicited ack response! "
3755                     + "serial: " + serial);
3756         } else {
3757             decrementWakeLock(rr);
3758             if (RIL.RILJ_LOGD) {
3759                 riljLog(rr.serialString() + " Ack < " + RIL.requestToString(rr.mRequest));
3760             }
3761         }
3762     }
3763
3764     /**
3765      * This is a helper function to be called when a RadioResponse callback is called.
3766      * It takes care of acks, wakelocks, and finds and returns RILRequest corresponding to the
3767      * response if one is found.
3768      * @param responseInfo RadioResponseInfo received in response callback
3769      * @return RILRequest corresponding to the response
3770      */
3771     RILRequest processResponse(RadioResponseInfo responseInfo) {
3772         int serial = responseInfo.serial;
3773         int error = responseInfo.error;
3774         int type = responseInfo.type;
3775
3776         RILRequest rr = null;
3777
3778         if (type == RadioResponseType.SOLICITED_ACK) {
3779             synchronized (mRequestList) {
3780                 rr = mRequestList.get(serial);
3781             }
3782             if (rr == null) {
3783                 Rlog.w(RILJ_LOG_TAG, "Unexpected solicited ack response! sn: " + serial);
3784             } else {
3785                 decrementWakeLock(rr);
3786                 if (RILJ_LOGD) {
3787                     riljLog(rr.serialString() + " Ack < " + requestToString(rr.mRequest));
3788                 }
3789             }
3790             return rr;
3791         }
3792
3793         rr = findAndRemoveRequestFromList(serial);
3794         if (rr == null) {
3795             Rlog.e(RIL.RILJ_LOG_TAG, "processResponse: Unexpected response! serial: " + serial
3796                     + " error: " + error);
3797             return null;
3798         }
3799
3800         // Time logging for RIL command and storing it in TelephonyHistogram.
3801         addToRilHistogram(rr);
3802
3803         if (type == RadioResponseType.SOLICITED_ACK_EXP) {
3804             sendAck();
3805             if (RIL.RILJ_LOGD) {
3806                 riljLog("Response received for " + rr.serialString() + " "
3807                         + RIL.requestToString(rr.mRequest) + " Sending ack to ril.cpp");
3808             }
3809         } else {
3810             // ack sent for SOLICITED_ACK_EXP above; nothing to do for SOLICITED response
3811         }
3812
3813         // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789.
3814         // This is needed otherwise we don't automatically transition to the main lock
3815         // screen when the pin or puk is entered incorrectly.
3816         switch (rr.mRequest) {
3817             case RIL_REQUEST_ENTER_SIM_PUK:
3818             case RIL_REQUEST_ENTER_SIM_PUK2:
3819                 if (mIccStatusChangedRegistrants != null) {
3820                     if (RILJ_LOGD) {
3821                         riljLog("ON enter sim puk fakeSimStatusChanged: reg count="
3822                                 + mIccStatusChangedRegistrants.size());
3823                     }
3824                     mIccStatusChangedRegistrants.notifyRegistrants();
3825                 }
3826                 break;
3827             case RIL_REQUEST_SHUTDOWN:
3828                 setRadioState(RadioState.RADIO_UNAVAILABLE);
3829                 break;
3830         }
3831
3832         if (error != RadioError.NONE) {
3833             switch (rr.mRequest) {
3834                 case RIL_REQUEST_ENTER_SIM_PIN:
3835                 case RIL_REQUEST_ENTER_SIM_PIN2:
3836                 case RIL_REQUEST_CHANGE_SIM_PIN:
3837                 case RIL_REQUEST_CHANGE_SIM_PIN2:
3838                 case RIL_REQUEST_SET_FACILITY_LOCK:
3839                     if (mIccStatusChangedRegistrants != null) {
3840                         if (RILJ_LOGD) {
3841                             riljLog("ON some errors fakeSimStatusChanged: reg count="
3842                                     + mIccStatusChangedRegistrants.size());
3843                         }
3844                         mIccStatusChangedRegistrants.notifyRegistrants();
3845                     }
3846                     break;
3847
3848             }
3849         } else {
3850             switch (rr.mRequest) {
3851                 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
3852                 if (mTestingEmergencyCall.getAndSet(false)) {
3853                     if (mEmergencyCallbackModeRegistrant != null) {
3854                         riljLog("testing emergency call, notify ECM Registrants");
3855                         mEmergencyCallbackModeRegistrant.notifyRegistrant();
3856                     }
3857                 }
3858             }
3859         }
3860         return rr;
3861     }
3862
3863     /**
3864      * This is a helper function to be called at the end of all RadioResponse callbacks.
3865      * It takes care of sending error response, logging, decrementing wakelock if needed, and
3866      * releases the request from memory pool.
3867      * @param rr RILRequest for which response callback was called
3868      * @param responseInfo RadioResponseInfo received in the callback
3869      * @param ret object to be returned to request sender
3870      */
3871     void processResponseDone(RILRequest rr, RadioResponseInfo responseInfo, Object ret) {
3872         if (responseInfo.error == 0) {
3873             if (RILJ_LOGD) {
3874                 riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
3875                         + " " + retToString(rr.mRequest, ret));
3876             }
3877         } else {
3878             if (RILJ_LOGD) {
3879                 riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
3880                         + " error " + responseInfo.error);
3881             }
3882             rr.onError(responseInfo.error, ret);
3883         }
3884         mMetrics.writeOnRilSolicitedResponse(mPhoneId, rr.mSerial, responseInfo.error,
3885                 rr.mRequest, ret);
3886         if (rr != null) {
3887             if (responseInfo.type == RadioResponseType.SOLICITED) {
3888                 decrementWakeLock(rr);
3889             }
3890             rr.release();
3891         }
3892     }
3893
3894     /**
3895      * Function to send ack and acquire related wakelock
3896      */
3897     private void sendAck() {
3898         // TODO: Remove rr and clean up acquireWakelock for response and ack
3899         RILRequest rr = RILRequest.obtain(RIL_RESPONSE_ACKNOWLEDGEMENT, null,
3900                 mRILDefaultWorkSource);
3901         acquireWakeLock(rr, RIL.FOR_ACK_WAKELOCK);
3902         IRadio radioProxy = getRadioProxy(null);
3903         if (radioProxy != null) {
3904             try {
3905                 radioProxy.responseAcknowledgement();
3906             } catch (RemoteException | RuntimeException e) {
3907                 handleRadioProxyExceptionForRR(rr, "sendAck", e);
3908                 riljLoge("sendAck: " + e);
3909             }
3910         } else {
3911             Rlog.e(RILJ_LOG_TAG, "Error trying to send ack, radioProxy = null");
3912         }
3913         rr.release();
3914     }
3915
3916     private WorkSource getDeafultWorkSourceIfInvalid(WorkSource workSource) {
3917         if (workSource == null) {
3918             workSource = mRILDefaultWorkSource;
3919         }
3920
3921         return workSource;
3922     }
3923
3924     private String getWorkSourceClientId(WorkSource workSource) {
3925         if (workSource != null) {
3926             return String.valueOf(workSource.get(0)) + ":" + workSource.getName(0);
3927         }
3928
3929         return null;
3930     }
3931
3932     /**
3933      * Holds a PARTIAL_WAKE_LOCK whenever
3934      * a) There is outstanding RIL request sent to RIL deamon and no replied
3935      * b) There is a request pending to be sent out.
3936      *
3937      * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
3938      * happen often.
3939      */
3940
3941     private void acquireWakeLock(RILRequest rr, int wakeLockType) {
3942         synchronized (rr) {
3943             if (rr.mWakeLockType != INVALID_WAKELOCK) {
3944                 Rlog.d(RILJ_LOG_TAG, "Failed to aquire wakelock for " + rr.serialString());
3945                 return;
3946             }
3947
3948             switch(wakeLockType) {
3949                 case FOR_WAKELOCK:
3950                     synchronized (mWakeLock) {
3951                         mWakeLock.acquire();
3952                         mWakeLockCount++;
3953                         mWlSequenceNum++;
3954
3955                         String clientId = getWorkSourceClientId(rr.mWorkSource);
3956                         if (!mClientWakelockTracker.isClientActive(clientId)) {
3957                             if (mActiveWakelockWorkSource != null) {
3958                                 mActiveWakelockWorkSource.add(rr.mWorkSource);
3959                             } else {
3960                                 mActiveWakelockWorkSource = rr.mWorkSource;
3961                             }
3962                             mWakeLock.setWorkSource(mActiveWakelockWorkSource);
3963                         }
3964
3965                         mClientWakelockTracker.startTracking(rr.mClientId,
3966                                 rr.mRequest, rr.mSerial, mWakeLockCount);
3967
3968                         Message msg = mRilHandler.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
3969                         msg.arg1 = mWlSequenceNum;
3970                         mRilHandler.sendMessageDelayed(msg, mWakeLockTimeout);
3971                     }
3972                     break;
3973                 case FOR_ACK_WAKELOCK:
3974                     synchronized (mAckWakeLock) {
3975                         mAckWakeLock.acquire();
3976                         mAckWlSequenceNum++;
3977
3978                         Message msg = mRilHandler.obtainMessage(EVENT_ACK_WAKE_LOCK_TIMEOUT);
3979                         msg.arg1 = mAckWlSequenceNum;
3980                         mRilHandler.sendMessageDelayed(msg, mAckWakeLockTimeout);
3981                     }
3982                     break;
3983                 default: //WTF
3984                     Rlog.w(RILJ_LOG_TAG, "Acquiring Invalid Wakelock type " + wakeLockType);
3985                     return;
3986             }
3987             rr.mWakeLockType = wakeLockType;
3988         }
3989     }
3990
3991     private void decrementWakeLock(RILRequest rr) {
3992         synchronized (rr) {
3993             switch(rr.mWakeLockType) {
3994                 case FOR_WAKELOCK:
3995                     synchronized (mWakeLock) {
3996                         mClientWakelockTracker.stopTracking(rr.mClientId,
3997                                 rr.mRequest, rr.mSerial,
3998                                 (mWakeLockCount > 1) ? mWakeLockCount - 1 : 0);
3999                         String clientId = getWorkSourceClientId(rr.mWorkSource);;
4000                         if (!mClientWakelockTracker.isClientActive(clientId)
4001                                 && (mActiveWakelockWorkSource != null)) {
4002                             mActiveWakelockWorkSource.remove(rr.mWorkSource);
4003                             if (mActiveWakelockWorkSource.size() == 0) {
4004                                 mActiveWakelockWorkSource = null;
4005                             }
4006                             mWakeLock.setWorkSource(mActiveWakelockWorkSource);
4007                         }
4008
4009                         if (mWakeLockCount > 1) {
4010                             mWakeLockCount--;
4011                         } else {
4012                             mWakeLockCount = 0;
4013                             mWakeLock.release();
4014                         }
4015                     }
4016                     break;
4017                 case FOR_ACK_WAKELOCK:
4018                     //We do not decrement the ACK wakelock
4019                     break;
4020                 case INVALID_WAKELOCK:
4021                     break;
4022                 default:
4023                     Rlog.w(RILJ_LOG_TAG, "Decrementing Invalid Wakelock type " + rr.mWakeLockType);
4024             }
4025             rr.mWakeLockType = INVALID_WAKELOCK;
4026         }
4027     }
4028
4029     private boolean clearWakeLock(int wakeLockType) {
4030         if (wakeLockType == FOR_WAKELOCK) {
4031             synchronized (mWakeLock) {
4032                 if (mWakeLockCount == 0 && !mWakeLock.isHeld()) return false;
4033                 Rlog.d(RILJ_LOG_TAG, "NOTE: mWakeLockCount is " + mWakeLockCount
4034                         + "at time of clearing");
4035                 mWakeLockCount = 0;
4036                 mWakeLock.release();
4037                 mClientWakelockTracker.stopTrackingAll();
4038                 mActiveWakelockWorkSource = null;
4039                 return true;
4040             }
4041         } else {
4042             synchronized (mAckWakeLock) {
4043                 if (!mAckWakeLock.isHeld()) return false;
4044                 mAckWakeLock.release();
4045                 return true;
4046             }
4047         }
4048     }
4049
4050     /**
4051      * Release each request in mRequestList then clear the list
4052      * @param error is the RIL_Errno sent back
4053      * @param loggable true means to print all requests in mRequestList
4054      */
4055     private void clearRequestList(int error, boolean loggable) {
4056         RILRequest rr;
4057         synchronized (mRequestList) {
4058             int count = mRequestList.size();
4059             if (RILJ_LOGD && loggable) {
4060                 Rlog.d(RILJ_LOG_TAG, "clearRequestList " + " mWakeLockCount="
4061                         + mWakeLockCount + " mRequestList=" + count);
4062             }
4063
4064             for (int i = 0; i < count; i++) {
4065                 rr = mRequestList.valueAt(i);
4066                 if (RILJ_LOGD && loggable) {
4067                     Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] "
4068                             + requestToString(rr.mRequest));
4069                 }
4070                 rr.onError(error, null);
4071                 decrementWakeLock(rr);
4072                 rr.release();
4073             }
4074             mRequestList.clear();
4075         }
4076     }
4077
4078     private RILRequest findAndRemoveRequestFromList(int serial) {
4079         RILRequest rr = null;
4080         synchronized (mRequestList) {
4081             rr = mRequestList.get(serial);
4082             if (rr != null) {
4083                 mRequestList.remove(serial);
4084             }
4085         }
4086
4087         return rr;
4088     }
4089
4090     private void addToRilHistogram(RILRequest rr) {
4091         long endTime = SystemClock.elapsedRealtime();
4092         int totalTime = (int) (endTime - rr.mStartTimeMs);
4093
4094         synchronized (mRilTimeHistograms) {
4095             TelephonyHistogram entry = mRilTimeHistograms.get(rr.mRequest);
4096             if (entry == null) {
4097                 // We would have total #RIL_HISTOGRAM_BUCKET_COUNT range buckets for RIL commands
4098                 entry = new TelephonyHistogram(TelephonyHistogram.TELEPHONY_CATEGORY_RIL,
4099                         rr.mRequest, RIL_HISTOGRAM_BUCKET_COUNT);
4100                 mRilTimeHistograms.put(rr.mRequest, entry);
4101             }
4102             entry.addTimeTaken(totalTime);
4103         }
4104     }
4105
4106     RadioCapability makeStaticRadioCapability() {
4107         // default to UNKNOWN so we fail fast.
4108         int raf = RadioAccessFamily.RAF_UNKNOWN;
4109
4110         String rafString = mContext.getResources().getString(
4111                 com.android.internal.R.string.config_radio_access_family);
4112         if (!TextUtils.isEmpty(rafString)) {
4113             raf = RadioAccessFamily.rafTypeFromString(rafString);
4114         }
4115         RadioCapability rc = new RadioCapability(mPhoneId.intValue(), 0, 0, raf,
4116                 "", RadioCapability.RC_STATUS_SUCCESS);
4117         if (RILJ_LOGD) riljLog("Faking RIL_REQUEST_GET_RADIO_CAPABILITY response using " + raf);
4118         return rc;
4119     }
4120
4121     static String retToString(int req, Object ret) {
4122         if (ret == null) return "";
4123         switch (req) {
4124             // Don't log these return values, for privacy's sake.
4125             case RIL_REQUEST_GET_IMSI:
4126             case RIL_REQUEST_GET_IMEI:
4127             case RIL_REQUEST_GET_IMEISV:
4128             case RIL_REQUEST_SIM_OPEN_CHANNEL:
4129             case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
4130
4131                 if (!RILJ_LOGV) {
4132                     // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
4133                     return "";
4134                 }
4135         }
4136
4137         StringBuilder sb;
4138         String s;
4139         int length;
4140         if (ret instanceof int[]) {
4141             int[] intArray = (int[]) ret;
4142             length = intArray.length;
4143             sb = new StringBuilder("{");
4144             if (length > 0) {
4145                 int i = 0;
4146                 sb.append(intArray[i++]);
4147                 while (i < length) {
4148                     sb.append(", ").append(intArray[i++]);
4149                 }
4150             }
4151             sb.append("}");
4152             s = sb.toString();
4153         } else if (ret instanceof String[]) {
4154             String[] strings = (String[]) ret;
4155             length = strings.length;
4156             sb = new StringBuilder("{");
4157             if (length > 0) {
4158                 int i = 0;
4159                 sb.append(strings[i++]);
4160                 while (i < length) {
4161                     sb.append(", ").append(strings[i++]);
4162                 }
4163             }
4164             sb.append("}");
4165             s = sb.toString();
4166         } else if (req == RIL_REQUEST_GET_CURRENT_CALLS) {
4167             ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret;
4168             sb = new StringBuilder("{");
4169             for (DriverCall dc : calls) {
4170                 sb.append("[").append(dc).append("] ");
4171             }
4172             sb.append("}");
4173             s = sb.toString();
4174         } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) {
4175             ArrayList<NeighboringCellInfo> cells = (ArrayList<NeighboringCellInfo>) ret;
4176             sb = new StringBuilder("{");
4177             for (NeighboringCellInfo cell : cells) {
4178                 sb.append("[").append(cell).append("] ");
4179             }
4180             sb.append("}");
4181             s = sb.toString();
4182         } else if (req == RIL_REQUEST_QUERY_CALL_FORWARD_STATUS) {
4183             CallForwardInfo[] cinfo = (CallForwardInfo[]) ret;
4184             length = cinfo.length;
4185             sb = new StringBuilder("{");
4186             for (int i = 0; i < length; i++) {
4187                 sb.append("[").append(cinfo[i]).append("] ");
4188             }
4189             sb.append("}");
4190             s = sb.toString();
4191         } else if (req == RIL_REQUEST_GET_HARDWARE_CONFIG) {
4192             ArrayList<HardwareConfig> hwcfgs = (ArrayList<HardwareConfig>) ret;
4193             sb = new StringBuilder(" ");
4194             for (HardwareConfig hwcfg : hwcfgs) {
4195                 sb.append("[").append(hwcfg).append("] ");
4196             }
4197             s = sb.toString();
4198         } else {
4199             s = ret.toString();
4200         }
4201         return s;
4202     }
4203
4204     void writeMetricsNewSms(int tech, int format) {
4205         mMetrics.writeRilNewSms(mPhoneId, tech, format);
4206     }
4207
4208     void writeMetricsCallRing(char[] response) {
4209         mMetrics.writeRilCallRing(mPhoneId, response);
4210     }
4211
4212     void writeMetricsSrvcc(int state) {
4213         mMetrics.writeRilSrvcc(mPhoneId, state);
4214     }
4215
4216     void writeMetricsModemRestartEvent(String reason) {
4217         mMetrics.writeModemRestartEvent(mPhoneId, reason);
4218     }
4219
4220     /**
4221      * Notify all registrants that the ril has connected or disconnected.
4222      *
4223      * @param rilVer is the version of the ril or -1 if disconnected.
4224      */
4225     void notifyRegistrantsRilConnectionChanged(int rilVer) {
4226         mRilVersion = rilVer;
4227         if (mRilConnectedRegistrants != null) {
4228             mRilConnectedRegistrants.notifyRegistrants(
4229                     new AsyncResult(null, new Integer(rilVer), null));
4230         }
4231     }
4232
4233     void
4234     notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
4235         int response = RIL_UNSOL_CDMA_INFO_REC;
4236         if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
4237             if (mDisplayInfoRegistrants != null) {
4238                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
4239                 mDisplayInfoRegistrants.notifyRegistrants(
4240                         new AsyncResult(null, infoRec.record, null));
4241             }
4242         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
4243             if (mSignalInfoRegistrants != null) {
4244                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
4245                 mSignalInfoRegistrants.notifyRegistrants(
4246                         new AsyncResult(null, infoRec.record, null));
4247             }
4248         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
4249             if (mNumberInfoRegistrants != null) {
4250                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
4251                 mNumberInfoRegistrants.notifyRegistrants(
4252                         new AsyncResult(null, infoRec.record, null));
4253             }
4254         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
4255             if (mRedirNumInfoRegistrants != null) {
4256                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
4257                 mRedirNumInfoRegistrants.notifyRegistrants(
4258                         new AsyncResult(null, infoRec.record, null));
4259             }
4260         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
4261             if (mLineControlInfoRegistrants != null) {
4262                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
4263                 mLineControlInfoRegistrants.notifyRegistrants(
4264                         new AsyncResult(null, infoRec.record, null));
4265             }
4266         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
4267             if (mT53ClirInfoRegistrants != null) {
4268                 if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
4269                 mT53ClirInfoRegistrants.notifyRegistrants(
4270                         new AsyncResult(null, infoRec.record, null));
4271             }
4272         } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
4273             if (mT53AudCntrlInfoRegistrants != null) {
4274                 if (RILJ_LOGD) {
4275                     unsljLogRet(response, infoRec.record);
4276                 }
4277                 mT53AudCntrlInfoRegistrants.notifyRegistrants(
4278                         new AsyncResult(null, infoRec.record, null));
4279             }
4280         }
4281     }
4282
4283     static String requestToString(int request) {
4284         switch(request) {
4285             case RIL_REQUEST_GET_SIM_STATUS:
4286                 return "GET_SIM_STATUS";
4287             case RIL_REQUEST_ENTER_SIM_PIN:
4288                 return "ENTER_SIM_PIN";
4289             case RIL_REQUEST_ENTER_SIM_PUK:
4290                 return "ENTER_SIM_PUK";
4291             case RIL_REQUEST_ENTER_SIM_PIN2:
4292                 return "ENTER_SIM_PIN2";
4293             case RIL_REQUEST_ENTER_SIM_PUK2:
4294                 return "ENTER_SIM_PUK2";
4295             case RIL_REQUEST_CHANGE_SIM_PIN:
4296                 return "CHANGE_SIM_PIN";
4297             case RIL_REQUEST_CHANGE_SIM_PIN2:
4298                 return "CHANGE_SIM_PIN2";
4299             case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
4300                 return "ENTER_NETWORK_DEPERSONALIZATION";
4301             case RIL_REQUEST_GET_CURRENT_CALLS:
4302                 return "GET_CURRENT_CALLS";
4303             case RIL_REQUEST_DIAL:
4304                 return "DIAL";
4305             case RIL_REQUEST_GET_IMSI:
4306                 return "GET_IMSI";
4307             case RIL_REQUEST_HANGUP:
4308                 return "HANGUP";
4309             case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
4310                 return "HANGUP_WAITING_OR_BACKGROUND";
4311             case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
4312                 return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
4313             case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
4314                 return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
4315             case RIL_REQUEST_CONFERENCE:
4316                 return "CONFERENCE";
4317             case RIL_REQUEST_UDUB:
4318                 return "UDUB";
4319             case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
4320                 return "LAST_CALL_FAIL_CAUSE";
4321             case RIL_REQUEST_SIGNAL_STRENGTH:
4322                 return "SIGNAL_STRENGTH";
4323             case RIL_REQUEST_VOICE_REGISTRATION_STATE:
4324                 return "VOICE_REGISTRATION_STATE";
4325             case RIL_REQUEST_DATA_REGISTRATION_STATE:
4326                 return "DATA_REGISTRATION_STATE";
4327             case RIL_REQUEST_OPERATOR:
4328                 return "OPERATOR";
4329             case RIL_REQUEST_RADIO_POWER:
4330                 return "RADIO_POWER";
4331             case RIL_REQUEST_DTMF:
4332                 return "DTMF";
4333             case RIL_REQUEST_SEND_SMS:
4334                 return "SEND_SMS";
4335             case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
4336                 return "SEND_SMS_EXPECT_MORE";
4337             case RIL_REQUEST_SETUP_DATA_CALL:
4338                 return "SETUP_DATA_CALL";
4339             case RIL_REQUEST_SIM_IO:
4340                 return "SIM_IO";
4341             case RIL_REQUEST_SEND_USSD:
4342                 return "SEND_USSD";
4343             case RIL_REQUEST_CANCEL_USSD:
4344                 return "CANCEL_USSD";
4345             case RIL_REQUEST_GET_CLIR:
4346                 return "GET_CLIR";
4347             case RIL_REQUEST_SET_CLIR:
4348                 return "SET_CLIR";
4349             case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS:
4350                 return "QUERY_CALL_FORWARD_STATUS";
4351             case RIL_REQUEST_SET_CALL_FORWARD:
4352                 return "SET_CALL_FORWARD";
4353             case RIL_REQUEST_QUERY_CALL_WAITING:
4354                 return "QUERY_CALL_WAITING";
4355             case RIL_REQUEST_SET_CALL_WAITING:
4356                 return "SET_CALL_WAITING";
4357             case RIL_REQUEST_SMS_ACKNOWLEDGE:
4358                 return "SMS_ACKNOWLEDGE";
4359             case RIL_REQUEST_GET_IMEI:
4360                 return "GET_IMEI";
4361             case RIL_REQUEST_GET_IMEISV:
4362                 return "GET_IMEISV";
4363             case RIL_REQUEST_ANSWER:
4364                 return "ANSWER";
4365             case RIL_REQUEST_DEACTIVATE_DATA_CALL:
4366                 return "DEACTIVATE_DATA_CALL";
4367             case RIL_REQUEST_QUERY_FACILITY_LOCK:
4368                 return "QUERY_FACILITY_LOCK";
4369             case RIL_REQUEST_SET_FACILITY_LOCK:
4370                 return "SET_FACILITY_LOCK";
4371             case RIL_REQUEST_CHANGE_BARRING_PASSWORD:
4372                 return "CHANGE_BARRING_PASSWORD";
4373             case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
4374                 return "QUERY_NETWORK_SELECTION_MODE";
4375             case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
4376                 return "SET_NETWORK_SELECTION_AUTOMATIC";
4377             case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
4378                 return "SET_NETWORK_SELECTION_MANUAL";
4379             case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS :
4380                 return "QUERY_AVAILABLE_NETWORKS ";
4381             case RIL_REQUEST_DTMF_START:
4382                 return "DTMF_START";
4383             case RIL_REQUEST_DTMF_STOP:
4384                 return "DTMF_STOP";
4385             case RIL_REQUEST_BASEBAND_VERSION:
4386                 return "BASEBAND_VERSION";
4387             case RIL_REQUEST_SEPARATE_CONNECTION:
4388                 return "SEPARATE_CONNECTION";
4389             case RIL_REQUEST_SET_MUTE:
4390                 return "SET_MUTE";
4391             case RIL_REQUEST_GET_MUTE:
4392                 return "GET_MUTE";
4393             case RIL_REQUEST_QUERY_CLIP:
4394                 return "QUERY_CLIP";
4395             case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
4396                 return "LAST_DATA_CALL_FAIL_CAUSE";
4397             case RIL_REQUEST_DATA_CALL_LIST:
4398                 return "DATA_CALL_LIST";
4399             case RIL_REQUEST_RESET_RADIO:
4400                 return "RESET_RADIO";
4401             case RIL_REQUEST_OEM_HOOK_RAW:
4402                 return "OEM_HOOK_RAW";
4403             case RIL_REQUEST_OEM_HOOK_STRINGS:
4404                 return "OEM_HOOK_STRINGS";
4405             case RIL_REQUEST_SCREEN_STATE:
4406                 return "SCREEN_STATE";
4407             case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
4408                 return "SET_SUPP_SVC_NOTIFICATION";
4409             case RIL_REQUEST_WRITE_SMS_TO_SIM:
4410                 return "WRITE_SMS_TO_SIM";
4411             case RIL_REQUEST_DELETE_SMS_ON_SIM:
4412                 return "DELETE_SMS_ON_SIM";
4413             case RIL_REQUEST_SET_BAND_MODE:
4414                 return "SET_BAND_MODE";
4415             case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
4416                 return "QUERY_AVAILABLE_BAND_MODE";
4417             case RIL_REQUEST_STK_GET_PROFILE:
4418                 return "REQUEST_STK_GET_PROFILE";
4419             case RIL_REQUEST_STK_SET_PROFILE:
4420                 return "REQUEST_STK_SET_PROFILE";
4421             case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
4422                 return "REQUEST_STK_SEND_ENVELOPE_COMMAND";
4423             case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
4424                 return "REQUEST_STK_SEND_TERMINAL_RESPONSE";
4425             case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
4426                 return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
4427             case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER";
4428             case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
4429                 return "REQUEST_SET_PREFERRED_NETWORK_TYPE";
4430             case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
4431                 return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
4432             case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
4433                 return "REQUEST_GET_NEIGHBORING_CELL_IDS";
4434             case RIL_REQUEST_SET_LOCATION_UPDATES:
4435                 return "REQUEST_SET_LOCATION_UPDATES";
4436             case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
4437                 return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
4438             case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
4439                 return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
4440             case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
4441                 return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
4442             case RIL_REQUEST_SET_TTY_MODE:
4443                 return "RIL_REQUEST_SET_TTY_MODE";
4444             case RIL_REQUEST_QUERY_TTY_MODE:
4445                 return "RIL_REQUEST_QUERY_TTY_MODE";
4446             case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
4447                 return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
4448             case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
4449                 return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
4450             case RIL_REQUEST_CDMA_FLASH:
4451                 return "RIL_REQUEST_CDMA_FLASH";
4452             case RIL_REQUEST_CDMA_BURST_DTMF:
4453                 return "RIL_REQUEST_CDMA_BURST_DTMF";
4454             case RIL_REQUEST_CDMA_SEND_SMS:
4455                 return "RIL_REQUEST_CDMA_SEND_SMS";
4456             case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:
4457                 return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
4458             case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG:
4459                 return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
4460             case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG:
4461                 return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
4462             case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG:
4463                 return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
4464             case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG:
4465                 return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
4466             case RIL_REQUEST_GSM_BROADCAST_ACTIVATION:
4467                 return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
4468             case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY:
4469                 return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
4470             case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION:
4471                 return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
4472             case RIL_REQUEST_CDMA_SUBSCRIPTION:
4473                 return "RIL_REQUEST_CDMA_SUBSCRIPTION";
4474             case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM:
4475                 return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
4476             case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM:
4477                 return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
4478             case RIL_REQUEST_DEVICE_IDENTITY:
4479                 return "RIL_REQUEST_DEVICE_IDENTITY";
4480             case RIL_REQUEST_GET_SMSC_ADDRESS:
4481                 return "RIL_REQUEST_GET_SMSC_ADDRESS";
4482             case RIL_REQUEST_SET_SMSC_ADDRESS:
4483                 return "RIL_REQUEST_SET_SMSC_ADDRESS";
4484             case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
4485                 return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
4486             case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
4487                 return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
4488             case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
4489                 return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
4490             case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
4491                 return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
4492             case RIL_REQUEST_ISIM_AUTHENTICATION:
4493                 return "RIL_REQUEST_ISIM_AUTHENTICATION";
4494             case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU:
4495                 return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
4496             case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS:
4497                 return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
4498             case RIL_REQUEST_VOICE_RADIO_TECH:
4499                 return "RIL_REQUEST_VOICE_RADIO_TECH";
4500             case RIL_REQUEST_GET_CELL_INFO_LIST:
4501                 return "RIL_REQUEST_GET_CELL_INFO_LIST";
4502             case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
4503                 return "RIL_REQUEST_SET_CELL_INFO_LIST_RATE";
4504             case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
4505                 return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
4506             case RIL_REQUEST_SET_DATA_PROFILE:
4507                 return "RIL_REQUEST_SET_DATA_PROFILE";
4508             case RIL_REQUEST_IMS_REGISTRATION_STATE:
4509                 return "RIL_REQUEST_IMS_REGISTRATION_STATE";
4510             case RIL_REQUEST_IMS_SEND_SMS:
4511                 return "RIL_REQUEST_IMS_SEND_SMS";
4512             case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC:
4513                 return "RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC";
4514             case RIL_REQUEST_SIM_OPEN_CHANNEL:
4515                 return "RIL_REQUEST_SIM_OPEN_CHANNEL";
4516             case RIL_REQUEST_SIM_CLOSE_CHANNEL:
4517                 return "RIL_REQUEST_SIM_CLOSE_CHANNEL";
4518             case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
4519                 return "RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL";
4520             case RIL_REQUEST_NV_READ_ITEM:
4521                 return "RIL_REQUEST_NV_READ_ITEM";
4522             case RIL_REQUEST_NV_WRITE_ITEM:
4523                 return "RIL_REQUEST_NV_WRITE_ITEM";
4524             case RIL_REQUEST_NV_WRITE_CDMA_PRL:
4525                 return "RIL_REQUEST_NV_WRITE_CDMA_PRL";
4526             case RIL_REQUEST_NV_RESET_CONFIG:
4527                 return "RIL_REQUEST_NV_RESET_CONFIG";
4528             case RIL_REQUEST_SET_UICC_SUBSCRIPTION:
4529                 return "RIL_REQUEST_SET_UICC_SUBSCRIPTION";
4530             case RIL_REQUEST_ALLOW_DATA:
4531                 return "RIL_REQUEST_ALLOW_DATA";
4532             case RIL_REQUEST_GET_HARDWARE_CONFIG:
4533                 return "GET_HARDWARE_CONFIG";
4534             case RIL_REQUEST_SIM_AUTHENTICATION:
4535                 return "RIL_REQUEST_SIM_AUTHENTICATION";
4536             case RIL_REQUEST_SHUTDOWN:
4537                 return "RIL_REQUEST_SHUTDOWN";
4538             case RIL_REQUEST_SET_RADIO_CAPABILITY:
4539                 return "RIL_REQUEST_SET_RADIO_CAPABILITY";
4540             case RIL_REQUEST_GET_RADIO_CAPABILITY:
4541                 return "RIL_REQUEST_GET_RADIO_CAPABILITY";
4542             case RIL_REQUEST_START_LCE:
4543                 return "RIL_REQUEST_START_LCE";
4544             case RIL_REQUEST_STOP_LCE:
4545                 return "RIL_REQUEST_STOP_LCE";
4546             case RIL_REQUEST_PULL_LCEDATA:
4547                 return "RIL_REQUEST_PULL_LCEDATA";
4548             case RIL_REQUEST_GET_ACTIVITY_INFO:
4549                 return "RIL_REQUEST_GET_ACTIVITY_INFO";
4550             case RIL_REQUEST_SET_ALLOWED_CARRIERS:
4551                 return "RIL_REQUEST_SET_ALLOWED_CARRIERS";
4552             case RIL_REQUEST_GET_ALLOWED_CARRIERS:
4553                 return "RIL_REQUEST_GET_ALLOWED_CARRIERS";
4554             case RIL_REQUEST_SET_SIM_CARD_POWER:
4555                 return "RIL_REQUEST_SET_SIM_CARD_POWER";
4556             case RIL_REQUEST_SEND_DEVICE_STATE:
4557                 return "RIL_REQUEST_SEND_DEVICE_STATE";
4558             case RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER:
4559                 return "RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER";
4560             case RIL_RESPONSE_ACKNOWLEDGEMENT:
4561                 return "RIL_RESPONSE_ACKNOWLEDGEMENT";
4562             default: return "<unknown request>";
4563         }
4564     }
4565
4566     static String responseToString(int request) {
4567         switch(request) {
4568             case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
4569                 return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
4570             case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
4571                 return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
4572             case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED:
4573                 return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
4574             case RIL_UNSOL_RESPONSE_NEW_SMS:
4575                 return "UNSOL_RESPONSE_NEW_SMS";
4576             case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
4577                 return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
4578             case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
4579                 return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
4580             case RIL_UNSOL_ON_USSD:
4581                 return "UNSOL_ON_USSD";
4582             case RIL_UNSOL_ON_USSD_REQUEST:
4583                 return "UNSOL_ON_USSD_REQUEST";
4584             case RIL_UNSOL_NITZ_TIME_RECEIVED:
4585                 return "UNSOL_NITZ_TIME_RECEIVED";
4586             case RIL_UNSOL_SIGNAL_STRENGTH:
4587                 return "UNSOL_SIGNAL_STRENGTH";
4588             case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
4589                 return "UNSOL_DATA_CALL_LIST_CHANGED";
4590             case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
4591                 return "UNSOL_SUPP_SVC_NOTIFICATION";
4592             case RIL_UNSOL_STK_SESSION_END:
4593                 return "UNSOL_STK_SESSION_END";
4594             case RIL_UNSOL_STK_PROACTIVE_COMMAND:
4595                 return "UNSOL_STK_PROACTIVE_COMMAND";
4596             case RIL_UNSOL_STK_EVENT_NOTIFY:
4597                 return "UNSOL_STK_EVENT_NOTIFY";
4598             case RIL_UNSOL_STK_CALL_SETUP:
4599                 return "UNSOL_STK_CALL_SETUP";
4600             case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
4601                 return "UNSOL_SIM_SMS_STORAGE_FULL";
4602             case RIL_UNSOL_SIM_REFRESH:
4603                 return "UNSOL_SIM_REFRESH";
4604             case RIL_UNSOL_CALL_RING:
4605                 return "UNSOL_CALL_RING";
4606             case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
4607                 return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
4608             case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
4609                 return "UNSOL_RESPONSE_CDMA_NEW_SMS";
4610             case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
4611                 return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
4612             case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
4613                 return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
4614             case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
4615                 return "UNSOL_RESTRICTED_STATE_CHANGED";
4616             case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
4617                 return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
4618             case RIL_UNSOL_CDMA_CALL_WAITING:
4619                 return "UNSOL_CDMA_CALL_WAITING";
4620             case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
4621                 return "UNSOL_CDMA_OTA_PROVISION_STATUS";
4622             case RIL_UNSOL_CDMA_INFO_REC:
4623                 return "UNSOL_CDMA_INFO_REC";
4624             case RIL_UNSOL_OEM_HOOK_RAW:
4625                 return "UNSOL_OEM_HOOK_RAW";
4626             case RIL_UNSOL_RINGBACK_TONE:
4627                 return "UNSOL_RINGBACK_TONE";
4628             case RIL_UNSOL_RESEND_INCALL_MUTE:
4629                 return "UNSOL_RESEND_INCALL_MUTE";
4630             case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
4631                 return "CDMA_SUBSCRIPTION_SOURCE_CHANGED";
4632             case RIL_UNSOl_CDMA_PRL_CHANGED:
4633                 return "UNSOL_CDMA_PRL_CHANGED";
4634             case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
4635                 return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
4636             case RIL_UNSOL_RIL_CONNECTED:
4637                 return "UNSOL_RIL_CONNECTED";
4638             case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
4639                 return "UNSOL_VOICE_RADIO_TECH_CHANGED";
4640             case RIL_UNSOL_CELL_INFO_LIST:
4641                 return "UNSOL_CELL_INFO_LIST";
4642             case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
4643                 return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED";
4644             case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED:
4645                 return "RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
4646             case RIL_UNSOL_SRVCC_STATE_NOTIFY:
4647                 return "UNSOL_SRVCC_STATE_NOTIFY";
4648             case RIL_UNSOL_HARDWARE_CONFIG_CHANGED:
4649                 return "RIL_UNSOL_HARDWARE_CONFIG_CHANGED";
4650             case RIL_UNSOL_RADIO_CAPABILITY:
4651                 return "RIL_UNSOL_RADIO_CAPABILITY";
4652             case RIL_UNSOL_ON_SS:
4653                 return "UNSOL_ON_SS";
4654             case RIL_UNSOL_STK_CC_ALPHA_NOTIFY:
4655                 return "UNSOL_STK_CC_ALPHA_NOTIFY";
4656             case RIL_UNSOL_LCEDATA_RECV:
4657                 return "UNSOL_LCE_INFO_RECV";
4658             case RIL_UNSOL_PCO_DATA:
4659                 return "UNSOL_PCO_DATA";
4660             case RIL_UNSOL_MODEM_RESTART:
4661                 return "UNSOL_MODEM_RESTART";
4662             default:
4663                 return "<unknown response>";
4664         }
4665     }
4666
4667     void riljLog(String msg) {
4668         Rlog.d(RILJ_LOG_TAG, msg
4669                 + (mPhoneId != null ? (" [SUB" + mPhoneId + "]") : ""));
4670     }
4671
4672     void riljLoge(String msg) {
4673         Rlog.e(RILJ_LOG_TAG, msg
4674                 + (mPhoneId != null ? (" [SUB" + mPhoneId + "]") : ""));
4675     }
4676
4677     void riljLoge(String msg, Exception e) {
4678         Rlog.e(RILJ_LOG_TAG, msg
4679                 + (mPhoneId != null ? (" [SUB" + mPhoneId + "]") : ""), e);
4680     }
4681
4682     void riljLogv(String msg) {
4683         Rlog.v(RILJ_LOG_TAG, msg
4684                 + (mPhoneId != null ? (" [SUB" + mPhoneId + "]") : ""));
4685     }
4686
4687     void unsljLog(int response) {
4688         riljLog("[UNSL]< " + responseToString(response));
4689     }
4690
4691     void unsljLogMore(int response, String more) {
4692         riljLog("[UNSL]< " + responseToString(response) + " " + more);
4693     }
4694
4695     void unsljLogRet(int response, Object ret) {
4696         riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
4697     }
4698
4699     void unsljLogvRet(int response, Object ret) {
4700         riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
4701     }
4702
4703     @Override
4704     public void setPhoneType(int phoneType) { // Called by GsmCdmaPhone
4705         if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
4706         mPhoneType = phoneType;
4707     }
4708
4709     /* (non-Javadoc)
4710      * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
4711      */
4712     @Override
4713     public void testingEmergencyCall() {
4714         if (RILJ_LOGD) riljLog("testingEmergencyCall");
4715         mTestingEmergencyCall.set(true);
4716     }
4717
4718     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
4719         pw.println("RIL: " + this);
4720         pw.println(" mWakeLock=" + mWakeLock);
4721         pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
4722         synchronized (mRequestList) {
4723             synchronized (mWakeLock) {
4724                 pw.println(" mWakeLockCount=" + mWakeLockCount);
4725             }
4726             int count = mRequestList.size();
4727             pw.println(" mRequestList count=" + count);
4728             for (int i = 0; i < count; i++) {
4729                 RILRequest rr = mRequestList.valueAt(i);
4730                 pw.println("  [" + rr.mSerial + "] " + requestToString(rr.mRequest));
4731             }
4732         }
4733         pw.println(" mLastNITZTimeInfo=" + Arrays.toString(mLastNITZTimeInfo));
4734         pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get());
4735         mClientWakelockTracker.dumpClientRequestTracker();
4736     }
4737
4738     public List<ClientRequestStats> getClientRequestStats() {
4739         return mClientWakelockTracker.getClientRequestStats();
4740     }
4741
4742     public static ArrayList<Byte> primitiveArrayToArrayList(byte[] arr) {
4743         ArrayList<Byte> arrayList = new ArrayList<>(arr.length);
4744         for (byte b : arr) {
4745             arrayList.add(b);
4746         }
4747         return arrayList;
4748     }
4749
4750     public static byte[] arrayListToPrimitiveArray(ArrayList<Byte> bytes) {
4751         byte[] ret = new byte[bytes.size()];
4752         for (int i = 0; i < ret.length; i++) {
4753             ret[i] = bytes.get(i);
4754         }
4755         return ret;
4756     }
4757
4758     static ArrayList<HardwareConfig> convertHalHwConfigList(
4759             ArrayList<android.hardware.radio.V1_0.HardwareConfig> hwListRil,
4760             RIL ril) {
4761         int num;
4762         ArrayList<HardwareConfig> response;
4763         HardwareConfig hw;
4764
4765         num = hwListRil.size();
4766         response = new ArrayList<HardwareConfig>(num);
4767
4768         if (RILJ_LOGV) {
4769             ril.riljLog("convertHalHwConfigList: num=" + num);
4770         }
4771         for (android.hardware.radio.V1_0.HardwareConfig hwRil : hwListRil) {
4772             int type = hwRil.type;
4773             switch(type) {
4774                 case HardwareConfig.DEV_HARDWARE_TYPE_MODEM: {
4775                     hw = new HardwareConfig(type);
4776                     HardwareConfigModem hwModem = hwRil.modem.get(0);
4777                     hw.assignModem(hwRil.uuid, hwRil.state, hwModem.rilModel, hwModem.rat,
4778                             hwModem.maxVoice, hwModem.maxData, hwModem.maxStandby);
4779                     break;
4780                 }
4781                 case HardwareConfig.DEV_HARDWARE_TYPE_SIM: {
4782                     hw = new HardwareConfig(type);
4783                     hw.assignSim(hwRil.uuid, hwRil.state, hwRil.sim.get(0).modemUuid);
4784                     break;
4785                 }
4786                 default: {
4787                     throw new RuntimeException(
4788                             "RIL_REQUEST_GET_HARDWARE_CONFIG invalid hardward type:" + type);
4789                 }
4790             }
4791
4792             response.add(hw);
4793         }
4794
4795         return response;
4796     }
4797
4798     static RadioCapability convertHalRadioCapability(
4799             android.hardware.radio.V1_0.RadioCapability rcRil, RIL ril) {
4800         int session = rcRil.session;
4801         int phase = rcRil.phase;
4802         int rat = rcRil.raf;
4803         String logicModemUuid = rcRil.logicalModemUuid;
4804         int status = rcRil.status;
4805
4806         ril.riljLog("convertHalRadioCapability: session=" + session +
4807                 ", phase=" + phase +
4808                 ", rat=" + rat +
4809                 ", logicModemUuid=" + logicModemUuid +
4810                 ", status=" + status);
4811         RadioCapability rc = new RadioCapability(
4812                 ril.mPhoneId, session, phase, rat, logicModemUuid, status);
4813         return rc;
4814     }
4815
4816     static ArrayList<Integer> convertHalLceData(LceDataInfo lce, RIL ril) {
4817         final ArrayList<Integer> capacityResponse = new ArrayList<Integer>();
4818         final int capacityDownKbps = lce.lastHopCapacityKbps;
4819         final int confidenceLevel = lce.confidenceLevel;
4820         final int lceSuspended = lce.lceSuspended ? 1 : 0;
4821
4822         ril.riljLog("LCE capacity information received:" +
4823                 " capacity=" + capacityDownKbps +
4824                 " confidence=" + confidenceLevel +
4825                 " lceSuspended=" + lceSuspended);
4826
4827         capacityResponse.add(capacityDownKbps);
4828         capacityResponse.add(confidenceLevel);
4829         capacityResponse.add(lceSuspended);
4830         return capacityResponse;
4831     }
4832
4833     static ArrayList<CellInfo> convertHalCellInfoList(
4834             ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
4835         ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
4836
4837         for (android.hardware.radio.V1_0.CellInfo record : records) {
4838             // first convert RIL CellInfo to Parcel
4839             Parcel p = Parcel.obtain();
4840             p.writeInt(record.cellInfoType);
4841             p.writeInt(record.registered ? 1 : 0);
4842             p.writeInt(record.timeStampType);
4843             p.writeLong(record.timeStamp);
4844             switch (record.cellInfoType) {
4845                 case CellInfoType.GSM: {
4846                     CellInfoGsm cellInfoGsm = record.gsm.get(0);
4847                     p.writeInt(Integer.parseInt(cellInfoGsm.cellIdentityGsm.mcc));
4848                     p.writeInt(Integer.parseInt(cellInfoGsm.cellIdentityGsm.mnc));
4849                     p.writeInt(cellInfoGsm.cellIdentityGsm.lac);
4850                     p.writeInt(cellInfoGsm.cellIdentityGsm.cid);
4851                     p.writeInt(cellInfoGsm.cellIdentityGsm.arfcn);
4852                     p.writeInt(Byte.toUnsignedInt(cellInfoGsm.cellIdentityGsm.bsic));
4853                     p.writeInt(cellInfoGsm.signalStrengthGsm.signalStrength);
4854                     p.writeInt(cellInfoGsm.signalStrengthGsm.bitErrorRate);
4855                     p.writeInt(cellInfoGsm.signalStrengthGsm.timingAdvance);
4856                     break;
4857                 }
4858
4859                 case CellInfoType.CDMA: {
4860                     CellInfoCdma cellInfoCdma = record.cdma.get(0);
4861                     p.writeInt(cellInfoCdma.cellIdentityCdma.networkId);
4862                     p.writeInt(cellInfoCdma.cellIdentityCdma.systemId);
4863                     p.writeInt(cellInfoCdma.cellIdentityCdma.baseStationId);
4864                     p.writeInt(cellInfoCdma.cellIdentityCdma.longitude);
4865                     p.writeInt(cellInfoCdma.cellIdentityCdma.latitude);
4866                     p.writeInt(cellInfoCdma.signalStrengthCdma.dbm);
4867                     p.writeInt(cellInfoCdma.signalStrengthCdma.ecio);
4868                     p.writeInt(cellInfoCdma.signalStrengthEvdo.dbm);
4869                     p.writeInt(cellInfoCdma.signalStrengthEvdo.ecio);
4870                     p.writeInt(cellInfoCdma.signalStrengthEvdo.signalNoiseRatio);
4871                     break;
4872                 }
4873
4874                 case CellInfoType.LTE: {
4875                     CellInfoLte cellInfoLte = record.lte.get(0);
4876                     p.writeInt(Integer.parseInt(cellInfoLte.cellIdentityLte.mcc));
4877                     p.writeInt(Integer.parseInt(cellInfoLte.cellIdentityLte.mnc));
4878                     p.writeInt(cellInfoLte.cellIdentityLte.ci);
4879                     p.writeInt(cellInfoLte.cellIdentityLte.pci);
4880                     p.writeInt(cellInfoLte.cellIdentityLte.tac);
4881                     p.writeInt(cellInfoLte.cellIdentityLte.earfcn);
4882                     p.writeInt(cellInfoLte.signalStrengthLte.signalStrength);
4883                     p.writeInt(cellInfoLte.signalStrengthLte.rsrp);
4884                     p.writeInt(cellInfoLte.signalStrengthLte.rsrq);
4885                     p.writeInt(cellInfoLte.signalStrengthLte.rssnr);
4886                     p.writeInt(cellInfoLte.signalStrengthLte.cqi);
4887                     p.writeInt(cellInfoLte.signalStrengthLte.timingAdvance);
4888                     break;
4889                 }
4890
4891                 case CellInfoType.WCDMA: {
4892                     CellInfoWcdma cellInfoWcdma = record.wcdma.get(0);
4893                     p.writeInt(Integer.parseInt(cellInfoWcdma.cellIdentityWcdma.mcc));
4894                     p.writeInt(Integer.parseInt(cellInfoWcdma.cellIdentityWcdma.mnc));
4895                     p.writeInt(cellInfoWcdma.cellIdentityWcdma.lac);
4896                     p.writeInt(cellInfoWcdma.cellIdentityWcdma.cid);
4897                     p.writeInt(cellInfoWcdma.cellIdentityWcdma.psc);
4898                     p.writeInt(cellInfoWcdma.cellIdentityWcdma.uarfcn);
4899                     p.writeInt(cellInfoWcdma.signalStrengthWcdma.signalStrength);
4900                     p.writeInt(cellInfoWcdma.signalStrengthWcdma.bitErrorRate);
4901                     break;
4902                 }
4903
4904                 default:
4905                     throw new RuntimeException("unexpected cellinfotype: " + record.cellInfoType);
4906             }
4907
4908             p.setDataPosition(0);
4909             CellInfo InfoRec = CellInfo.CREATOR.createFromParcel(p);
4910             p.recycle();
4911             response.add(InfoRec);
4912         }
4913
4914         return response;
4915     }
4916
4917     static SignalStrength convertHalSignalStrength(
4918             android.hardware.radio.V1_0.SignalStrength signalStrength) {
4919         return new SignalStrength(signalStrength.gw.signalStrength,
4920                 signalStrength.gw.bitErrorRate,
4921                 signalStrength.cdma.dbm,
4922                 signalStrength.cdma.ecio,
4923                 signalStrength.evdo.dbm,
4924                 signalStrength.evdo.ecio,
4925                 signalStrength.evdo.signalNoiseRatio,
4926                 signalStrength.lte.signalStrength,
4927                 signalStrength.lte.rsrp,
4928                 signalStrength.lte.rsrq,
4929                 signalStrength.lte.rssnr,
4930                 signalStrength.lte.cqi,
4931                 signalStrength.tdScdma.rscp,
4932                 false /* gsmFlag - don't care; will be changed by SST */);
4933     }
4934 }