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