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
17package com.android.internal.telephony;
18
19import static com.android.internal.telephony.RILConstants.*;
20import static com.android.internal.util.Preconditions.checkNotNull;
21
22import android.content.Context;
23import android.hardware.radio.V1_0.Carrier;
24import android.hardware.radio.V1_0.CarrierRestrictions;
25import android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo;
26import android.hardware.radio.V1_0.CdmaSmsAck;
27import android.hardware.radio.V1_0.CdmaSmsMessage;
28import android.hardware.radio.V1_0.CdmaSmsWriteArgs;
29import android.hardware.radio.V1_0.CellInfoCdma;
30import android.hardware.radio.V1_0.CellInfoGsm;
31import android.hardware.radio.V1_0.CellInfoLte;
32import android.hardware.radio.V1_0.CellInfoType;
33import android.hardware.radio.V1_0.CellInfoWcdma;
34import android.hardware.radio.V1_0.DataProfileInfo;
35import android.hardware.radio.V1_0.Dial;
36import android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo;
37import android.hardware.radio.V1_0.GsmSmsMessage;
38import android.hardware.radio.V1_0.HardwareConfigModem;
39import android.hardware.radio.V1_0.IRadio;
40import android.hardware.radio.V1_0.IccIo;
41import android.hardware.radio.V1_0.ImsSmsMessage;
42import android.hardware.radio.V1_0.LceDataInfo;
43import android.hardware.radio.V1_0.MvnoType;
44import android.hardware.radio.V1_0.NvWriteItem;
45import android.hardware.radio.V1_0.RadioError;
46import android.hardware.radio.V1_0.RadioIndicationType;
47import android.hardware.radio.V1_0.RadioResponseInfo;
48import android.hardware.radio.V1_0.RadioResponseType;
49import android.hardware.radio.V1_0.ResetNvType;
50import android.hardware.radio.V1_0.SelectUiccSub;
51import android.hardware.radio.V1_0.SetupDataCallResult;
52import android.hardware.radio.V1_0.SimApdu;
53import android.hardware.radio.V1_0.SmsWriteArgs;
54import android.hardware.radio.V1_0.UusInfo;
55import android.hardware.radio.deprecated.V1_0.IOemHook;
56import android.net.ConnectivityManager;
57import android.os.AsyncResult;
58import android.os.Handler;
59import android.os.HwBinder;
60import android.os.Message;
61import android.os.Parcel;
62import android.os.PowerManager;
63import android.os.PowerManager.WakeLock;
64import android.os.RemoteException;
65import android.os.SystemClock;
66import android.os.SystemProperties;
67import android.os.WorkSource;
68import android.service.carrier.CarrierIdentifier;
69import android.telephony.CellInfo;
70import android.telephony.ClientRequestStats;
71import android.telephony.ModemActivityInfo;
72import android.telephony.NeighboringCellInfo;
73import android.telephony.PhoneNumberUtils;
74import android.telephony.RadioAccessFamily;
75import android.telephony.Rlog;
76import android.telephony.SignalStrength;
77import android.telephony.SmsManager;
78import android.telephony.TelephonyHistogram;
79import android.text.TextUtils;
80import android.util.SparseArray;
81
82import com.android.internal.telephony.cdma.CdmaInformationRecords;
83import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
84import com.android.internal.telephony.dataconnection.DataCallResponse;
85import com.android.internal.telephony.dataconnection.DataProfile;
86import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
87import com.android.internal.telephony.metrics.TelephonyMetrics;
88import com.android.internal.telephony.nano.TelephonyProto.SmsSession;
89import com.android.internal.telephony.uicc.IccUtils;
90
91import java.io.ByteArrayInputStream;
92import java.io.DataInputStream;
93import java.io.FileDescriptor;
94import java.io.IOException;
95import java.io.PrintWriter;
96import java.util.ArrayList;
97import java.util.Arrays;
98import java.util.List;
99import java.util.Random;
100import java.util.concurrent.atomic.AtomicBoolean;
101import java.util.concurrent.atomic.AtomicInteger;
102import java.util.concurrent.atomic.AtomicLong;
103
104/**
105 * {@hide}
106 */
107
108class 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 */
268public 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 = Byte.toUnsignedInt(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}
4935