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