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