RIL.java revision d720945f2be5ea5fe0faf67e67d9ea0e184eba67
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.net.ConnectivityManager;
33import android.net.LocalSocket;
34import android.net.LocalSocketAddress;
35import android.os.AsyncResult;
36import android.os.Handler;
37import android.os.HandlerThread;
38import android.os.Looper;
39import android.os.Message;
40import android.os.Parcel;
41import android.os.PowerManager;
42import android.os.SystemProperties;
43import android.os.PowerManager.WakeLock;
44import android.telephony.NeighboringCellInfo;
45import android.telephony.PhoneNumberUtils;
46import android.telephony.SignalStrength;
47import android.telephony.SmsManager;
48import android.telephony.SmsMessage;
49import android.text.TextUtils;
50import android.telephony.Rlog;
51
52import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
53import com.android.internal.telephony.gsm.SuppServiceNotification;
54import com.android.internal.telephony.uicc.IccCardApplicationStatus;
55import com.android.internal.telephony.uicc.IccCardStatus;
56import com.android.internal.telephony.uicc.IccIoResult;
57import com.android.internal.telephony.uicc.IccRefreshResponse;
58import com.android.internal.telephony.uicc.IccUtils;
59import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
60import com.android.internal.telephony.cdma.CdmaInformationRecords;
61
62import java.io.ByteArrayInputStream;
63import java.io.DataInputStream;
64import java.io.FileDescriptor;
65import java.io.IOException;
66import java.io.InputStream;
67import java.io.PrintWriter;
68import java.util.ArrayList;
69import java.util.Collections;
70import java.util.concurrent.atomic.AtomicBoolean;
71
72/**
73 * {@hide}
74 */
75class RILRequest {
76    static final String LOG_TAG = "RILJ";
77
78    //***** Class Variables
79    static int sNextSerial = 0;
80    static Object sSerialMonitor = new Object();
81    private static Object sPoolSync = new Object();
82    private static RILRequest sPool = null;
83    private static int sPoolSize = 0;
84    private static final int MAX_POOL_SIZE = 4;
85
86    //***** Instance Variables
87    int mSerial;
88    int mRequest;
89    Message mResult;
90    Parcel mp;
91    RILRequest mNext;
92
93    /**
94     * Retrieves a new RILRequest instance from the pool.
95     *
96     * @param request RIL_REQUEST_*
97     * @param result sent when operation completes
98     * @return a RILRequest instance from the pool.
99     */
100    static RILRequest obtain(int request, Message result) {
101        RILRequest rr = null;
102
103        synchronized(sPoolSync) {
104            if (sPool != null) {
105                rr = sPool;
106                sPool = rr.mNext;
107                rr.mNext = null;
108                sPoolSize--;
109            }
110        }
111
112        if (rr == null) {
113            rr = new RILRequest();
114        }
115
116        synchronized(sSerialMonitor) {
117            rr.mSerial = sNextSerial++;
118        }
119        rr.mRequest = request;
120        rr.mResult = result;
121        rr.mp = Parcel.obtain();
122
123        if (result != null && result.getTarget() == null) {
124            throw new NullPointerException("Message target must not be null");
125        }
126
127        // first elements in any RIL Parcel
128        rr.mp.writeInt(request);
129        rr.mp.writeInt(rr.mSerial);
130
131        return rr;
132    }
133
134    /**
135     * Returns a RILRequest instance to the pool.
136     *
137     * Note: This should only be called once per use.
138     */
139    void release() {
140        synchronized (sPoolSync) {
141            if (sPoolSize < MAX_POOL_SIZE) {
142                this.mNext = sPool;
143                sPool = this;
144                sPoolSize++;
145                mResult = null;
146            }
147        }
148    }
149
150    private RILRequest() {
151    }
152
153    static void
154    resetSerial() {
155        synchronized(sSerialMonitor) {
156            sNextSerial = 0;
157        }
158    }
159
160    String
161    serialString() {
162        //Cheesy way to do %04d
163        StringBuilder sb = new StringBuilder(8);
164        String sn;
165
166        sn = Integer.toString(mSerial);
167
168        //sb.append("J[");
169        sb.append('[');
170        for (int i = 0, s = sn.length() ; i < 4 - s; i++) {
171            sb.append('0');
172        }
173
174        sb.append(sn);
175        sb.append(']');
176        return sb.toString();
177    }
178
179    void
180    onError(int error, Object ret) {
181        CommandException ex;
182
183        ex = CommandException.fromRilErrno(error);
184
185        if (RIL.RILJ_LOGD) Rlog.d(LOG_TAG, serialString() + "< "
186            + RIL.requestToString(mRequest)
187            + " error: " + ex);
188
189        if (mResult != null) {
190            AsyncResult.forMessage(mResult, ret, ex);
191            mResult.sendToTarget();
192        }
193
194        if (mp != null) {
195            mp.recycle();
196            mp = null;
197        }
198    }
199}
200
201
202/**
203 * RIL implementation of the CommandsInterface.
204 *
205 * {@hide}
206 */
207public final class RIL extends BaseCommands implements CommandsInterface {
208    static final String LOG_TAG = "RILJ";
209    static final boolean RILJ_LOGD = true;
210    static final boolean RILJ_LOGV = false; // STOP SHIP if true
211
212    /**
213     * Wake lock timeout should be longer than the longest timeout in
214     * the vendor ril.
215     */
216    private static final int DEFAULT_WAKE_LOCK_TIMEOUT = 60000;
217
218    //***** Instance Variables
219
220    LocalSocket mSocket;
221    HandlerThread mSenderThread;
222    RILSender mSender;
223    Thread mReceiverThread;
224    RILReceiver mReceiver;
225    WakeLock mWakeLock;
226    int mWakeLockTimeout;
227    // The number of requests pending to be sent out, it increases before calling
228    // EVENT_SEND and decreases while handling EVENT_SEND. It gets cleared while
229    // WAKE_LOCK_TIMEOUT occurs.
230    int mRequestMessagesPending;
231    // The number of requests sent out but waiting for response. It increases while
232    // sending request and decreases while handling response. It should match
233    // mRequestList.size() unless there are requests no replied while
234    // WAKE_LOCK_TIMEOUT occurs.
235    int mRequestMessagesWaiting;
236
237    //I'd rather this be LinkedList or something
238    ArrayList<RILRequest> mRequestsList = new ArrayList<RILRequest>();
239
240    Object     mLastNITZTimeInfo;
241
242    // When we are testing emergency calls
243    AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
244
245    //***** Events
246
247    static final int EVENT_SEND                 = 1;
248    static final int EVENT_WAKE_LOCK_TIMEOUT    = 2;
249
250    //***** Constants
251
252    // match with constant in ril.cpp
253    static final int RIL_MAX_COMMAND_BYTES = (8 * 1024);
254    static final int RESPONSE_SOLICITED = 0;
255    static final int RESPONSE_UNSOLICITED = 1;
256
257    static final String SOCKET_NAME_RIL = "rild";
258
259    static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000;
260
261    // The number of the required config values for broadcast SMS stored in the C struct
262    // RIL_CDMA_BroadcastServiceInfo
263    private static final int CDMA_BSI_NO_OF_INTS_STRUCT = 3;
264
265    private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31;
266
267    BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
268        @Override
269        public void onReceive(Context context, Intent intent) {
270            if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
271                sendScreenState(true);
272            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
273                sendScreenState(false);
274            } else {
275                Rlog.w(LOG_TAG, "RIL received unexpected Intent: " + intent.getAction());
276            }
277        }
278    };
279
280    class RILSender extends Handler implements Runnable {
281        public RILSender(Looper looper) {
282            super(looper);
283        }
284
285        // Only allocated once
286        byte[] dataLength = new byte[4];
287
288        //***** Runnable implementation
289        public void
290        run() {
291            //setup if needed
292        }
293
294
295        //***** Handler implementation
296        @Override public void
297        handleMessage(Message msg) {
298            RILRequest rr = (RILRequest)(msg.obj);
299            RILRequest req = null;
300
301            switch (msg.what) {
302                case EVENT_SEND:
303                    /**
304                     * mRequestMessagePending++ already happened for every
305                     * EVENT_SEND, thus we must make sure
306                     * mRequestMessagePending-- happens once and only once
307                     */
308                    boolean alreadySubtracted = false;
309                    try {
310                        LocalSocket s;
311
312                        s = mSocket;
313
314                        if (s == null) {
315                            rr.onError(RADIO_NOT_AVAILABLE, null);
316                            rr.release();
317                            if (mRequestMessagesPending > 0)
318                                mRequestMessagesPending--;
319                            alreadySubtracted = true;
320                            return;
321                        }
322
323                        synchronized (mRequestsList) {
324                            mRequestsList.add(rr);
325                            mRequestMessagesWaiting++;
326                        }
327
328                        if (mRequestMessagesPending > 0)
329                            mRequestMessagesPending--;
330                        alreadySubtracted = true;
331
332                        byte[] data;
333
334                        data = rr.mp.marshall();
335                        rr.mp.recycle();
336                        rr.mp = null;
337
338                        if (data.length > RIL_MAX_COMMAND_BYTES) {
339                            throw new RuntimeException(
340                                    "Parcel larger than max bytes allowed! "
341                                                          + data.length);
342                        }
343
344                        // parcel length in big endian
345                        dataLength[0] = dataLength[1] = 0;
346                        dataLength[2] = (byte)((data.length >> 8) & 0xff);
347                        dataLength[3] = (byte)((data.length) & 0xff);
348
349                        //Rlog.v(LOG_TAG, "writing packet: " + data.length + " bytes");
350
351                        s.getOutputStream().write(dataLength);
352                        s.getOutputStream().write(data);
353                    } catch (IOException ex) {
354                        Rlog.e(LOG_TAG, "IOException", ex);
355                        req = findAndRemoveRequestFromList(rr.mSerial);
356                        // make sure this request has not already been handled,
357                        // eg, if RILReceiver cleared the list.
358                        if (req != null || !alreadySubtracted) {
359                            rr.onError(RADIO_NOT_AVAILABLE, null);
360                            rr.release();
361                        }
362                    } catch (RuntimeException exc) {
363                        Rlog.e(LOG_TAG, "Uncaught exception ", exc);
364                        req = findAndRemoveRequestFromList(rr.mSerial);
365                        // make sure this request has not already been handled,
366                        // eg, if RILReceiver cleared the list.
367                        if (req != null || !alreadySubtracted) {
368                            rr.onError(GENERIC_FAILURE, null);
369                            rr.release();
370                        }
371                    } finally {
372                        // Note: We are "Done" only if there are no outstanding
373                        // requests or replies. Thus this code path will only release
374                        // the wake lock on errors.
375                        releaseWakeLockIfDone();
376                    }
377
378                    if (!alreadySubtracted && mRequestMessagesPending > 0) {
379                        mRequestMessagesPending--;
380                    }
381
382                    break;
383
384                case EVENT_WAKE_LOCK_TIMEOUT:
385                    // Haven't heard back from the last request.  Assume we're
386                    // not getting a response and  release the wake lock.
387                    synchronized (mWakeLock) {
388                        if (mWakeLock.isHeld()) {
389                            // The timer of WAKE_LOCK_TIMEOUT is reset with each
390                            // new send request. So when WAKE_LOCK_TIMEOUT occurs
391                            // all requests in mRequestList already waited at
392                            // least DEFAULT_WAKE_LOCK_TIMEOUT but no response.
393                            // Reset mRequestMessagesWaiting to enable
394                            // releaseWakeLockIfDone().
395                            //
396                            // Note: Keep mRequestList so that delayed response
397                            // can still be handled when response finally comes.
398                            if (mRequestMessagesWaiting != 0) {
399                                Rlog.d(LOG_TAG, "NOTE: mReqWaiting is NOT 0 but"
400                                        + mRequestMessagesWaiting + " at TIMEOUT, reset!"
401                                        + " There still msg waitng for response");
402
403                                mRequestMessagesWaiting = 0;
404
405                                if (RILJ_LOGD) {
406                                    synchronized (mRequestsList) {
407                                        int count = mRequestsList.size();
408                                        Rlog.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
409                                                " mRequestList=" + count);
410
411                                        for (int i = 0; i < count; i++) {
412                                            rr = mRequestsList.get(i);
413                                            Rlog.d(LOG_TAG, i + ": [" + rr.mSerial + "] "
414                                                    + requestToString(rr.mRequest));
415                                        }
416                                    }
417                                }
418                            }
419                            // mRequestMessagesPending shows how many
420                            // requests are waiting to be sent (and before
421                            // to be added in request list) since star the
422                            // WAKE_LOCK_TIMEOUT timer. Since WAKE_LOCK_TIMEOUT
423                            // is the expected time to get response, all requests
424                            // should already sent out (i.e.
425                            // mRequestMessagesPending is 0 )while TIMEOUT occurs.
426                            if (mRequestMessagesPending != 0) {
427                                Rlog.e(LOG_TAG, "ERROR: mReqPending is NOT 0 but"
428                                        + mRequestMessagesPending + " at TIMEOUT, reset!");
429                                mRequestMessagesPending = 0;
430
431                            }
432                            mWakeLock.release();
433                        }
434                    }
435                    break;
436            }
437        }
438    }
439
440    /**
441     * Reads in a single RIL message off the wire. A RIL message consists
442     * of a 4-byte little-endian length and a subsequent series of bytes.
443     * The final message (length header omitted) is read into
444     * <code>buffer</code> and the length of the final message (less header)
445     * is returned. A return value of -1 indicates end-of-stream.
446     *
447     * @param is non-null; Stream to read from
448     * @param buffer Buffer to fill in. Must be as large as maximum
449     * message size, or an ArrayOutOfBounds exception will be thrown.
450     * @return Length of message less header, or -1 on end of stream.
451     * @throws IOException
452     */
453    private static int readRilMessage(InputStream is, byte[] buffer)
454            throws IOException {
455        int countRead;
456        int offset;
457        int remaining;
458        int messageLength;
459
460        // First, read in the length of the message
461        offset = 0;
462        remaining = 4;
463        do {
464            countRead = is.read(buffer, offset, remaining);
465
466            if (countRead < 0 ) {
467                Rlog.e(LOG_TAG, "Hit EOS reading message length");
468                return -1;
469            }
470
471            offset += countRead;
472            remaining -= countRead;
473        } while (remaining > 0);
474
475        messageLength = ((buffer[0] & 0xff) << 24)
476                | ((buffer[1] & 0xff) << 16)
477                | ((buffer[2] & 0xff) << 8)
478                | (buffer[3] & 0xff);
479
480        // Then, re-use the buffer and read in the message itself
481        offset = 0;
482        remaining = messageLength;
483        do {
484            countRead = is.read(buffer, offset, remaining);
485
486            if (countRead < 0 ) {
487                Rlog.e(LOG_TAG, "Hit EOS reading message.  messageLength=" + messageLength
488                        + " remaining=" + remaining);
489                return -1;
490            }
491
492            offset += countRead;
493            remaining -= countRead;
494        } while (remaining > 0);
495
496        return messageLength;
497    }
498
499    class RILReceiver implements Runnable {
500        byte[] buffer;
501
502        RILReceiver() {
503            buffer = new byte[RIL_MAX_COMMAND_BYTES];
504        }
505
506        public void
507        run() {
508            int retryCount = 0;
509
510            try {for (;;) {
511                LocalSocket s = null;
512                LocalSocketAddress l;
513
514                try {
515                    s = new LocalSocket();
516                    l = new LocalSocketAddress(SOCKET_NAME_RIL,
517                            LocalSocketAddress.Namespace.RESERVED);
518                    s.connect(l);
519                } catch (IOException ex){
520                    try {
521                        if (s != null) {
522                            s.close();
523                        }
524                    } catch (IOException ex2) {
525                        //ignore failure to close after failure to connect
526                    }
527
528                    // don't print an error message after the the first time
529                    // or after the 8th time
530
531                    if (retryCount == 8) {
532                        Rlog.e (LOG_TAG,
533                            "Couldn't find '" + SOCKET_NAME_RIL
534                            + "' socket after " + retryCount
535                            + " times, continuing to retry silently");
536                    } else if (retryCount > 0 && retryCount < 8) {
537                        Rlog.i (LOG_TAG,
538                            "Couldn't find '" + SOCKET_NAME_RIL
539                            + "' socket; retrying after timeout");
540                    }
541
542                    try {
543                        Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
544                    } catch (InterruptedException er) {
545                    }
546
547                    retryCount++;
548                    continue;
549                }
550
551                retryCount = 0;
552
553                mSocket = s;
554                Rlog.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");
555
556                int length = 0;
557                try {
558                    InputStream is = mSocket.getInputStream();
559
560                    for (;;) {
561                        Parcel p;
562
563                        length = readRilMessage(is, buffer);
564
565                        if (length < 0) {
566                            // End-of-stream reached
567                            break;
568                        }
569
570                        p = Parcel.obtain();
571                        p.unmarshall(buffer, 0, length);
572                        p.setDataPosition(0);
573
574                        //Rlog.v(LOG_TAG, "Read packet: " + length + " bytes");
575
576                        processResponse(p);
577                        p.recycle();
578                    }
579                } catch (java.io.IOException ex) {
580                    Rlog.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",
581                          ex);
582                } catch (Throwable tr) {
583                    Rlog.e(LOG_TAG, "Uncaught exception read length=" + length +
584                        "Exception:" + tr.toString());
585                }
586
587                Rlog.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL
588                      + "' socket");
589
590                setRadioState (RadioState.RADIO_UNAVAILABLE);
591
592                try {
593                    mSocket.close();
594                } catch (IOException ex) {
595                }
596
597                mSocket = null;
598                RILRequest.resetSerial();
599
600                // Clear request list on close
601                clearRequestsList(RADIO_NOT_AVAILABLE, false);
602            }} catch (Throwable tr) {
603                Rlog.e(LOG_TAG,"Uncaught exception", tr);
604            }
605
606            /* We're disconnected so we don't know the ril version */
607            notifyRegistrantsRilConnectionChanged(-1);
608        }
609    }
610
611
612
613    //***** Constructors
614
615    public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
616        super(context);
617        if (RILJ_LOGD) {
618            riljLog("RIL(context, preferredNetworkType=" + preferredNetworkType +
619                    " cdmaSubscription=" + cdmaSubscription + ")");
620        }
621        mCdmaSubscription  = cdmaSubscription;
622        mPreferredNetworkType = preferredNetworkType;
623        mPhoneType = RILConstants.NO_PHONE;
624
625        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
626        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
627        mWakeLock.setReferenceCounted(false);
628        mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,
629                DEFAULT_WAKE_LOCK_TIMEOUT);
630        mRequestMessagesPending = 0;
631        mRequestMessagesWaiting = 0;
632
633        mSenderThread = new HandlerThread("RILSender");
634        mSenderThread.start();
635
636        Looper looper = mSenderThread.getLooper();
637        mSender = new RILSender(looper);
638
639        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
640                Context.CONNECTIVITY_SERVICE);
641        if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
642            riljLog("Not starting RILReceiver: wifi-only");
643        } else {
644            riljLog("Starting RILReceiver");
645            mReceiver = new RILReceiver();
646            mReceiverThread = new Thread(mReceiver, "RILReceiver");
647            mReceiverThread.start();
648
649            IntentFilter filter = new IntentFilter();
650            filter.addAction(Intent.ACTION_SCREEN_ON);
651            filter.addAction(Intent.ACTION_SCREEN_OFF);
652            context.registerReceiver(mIntentReceiver, filter);
653        }
654    }
655
656    //***** CommandsInterface implementation
657
658    public void getVoiceRadioTechnology(Message result) {
659        RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_RADIO_TECH, result);
660
661        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
662
663        send(rr);
664    }
665
666
667    @Override public void
668    setOnNITZTime(Handler h, int what, Object obj) {
669        super.setOnNITZTime(h, what, obj);
670
671        // Send the last NITZ time if we have it
672        if (mLastNITZTimeInfo != null) {
673            mNITZTimeRegistrant
674                .notifyRegistrant(
675                    new AsyncResult (null, mLastNITZTimeInfo, null));
676            mLastNITZTimeInfo = null;
677        }
678    }
679
680    public void
681    getIccCardStatus(Message result) {
682        //Note: This RIL request has not been renamed to ICC,
683        //       but this request is also valid for SIM and RUIM
684        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result);
685
686        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
687
688        send(rr);
689    }
690
691    @Override public void
692    supplyIccPin(String pin, Message result) {
693        supplyIccPinForApp(pin, null, result);
694    }
695
696    @Override public void
697    supplyIccPinForApp(String pin, String aid, Message result) {
698        //Note: This RIL request has not been renamed to ICC,
699        //       but this request is also valid for SIM and RUIM
700        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result);
701
702        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
703
704        rr.mp.writeInt(2);
705        rr.mp.writeString(pin);
706        rr.mp.writeString(aid);
707
708        send(rr);
709    }
710
711    @Override public void
712    supplyIccPuk(String puk, String newPin, Message result) {
713        supplyIccPukForApp(puk, newPin, null, result);
714    }
715
716    @Override public void
717    supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
718        //Note: This RIL request has not been renamed to ICC,
719        //       but this request is also valid for SIM and RUIM
720        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result);
721
722        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
723
724        rr.mp.writeInt(3);
725        rr.mp.writeString(puk);
726        rr.mp.writeString(newPin);
727        rr.mp.writeString(aid);
728
729        send(rr);
730    }
731
732    @Override public void
733    supplyIccPin2(String pin, Message result) {
734        supplyIccPin2ForApp(pin, null, result);
735    }
736
737    @Override public void
738    supplyIccPin2ForApp(String pin, String aid, Message result) {
739        //Note: This RIL request has not been renamed to ICC,
740        //       but this request is also valid for SIM and RUIM
741        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result);
742
743        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
744
745        rr.mp.writeInt(2);
746        rr.mp.writeString(pin);
747        rr.mp.writeString(aid);
748
749        send(rr);
750    }
751
752    @Override public void
753    supplyIccPuk2(String puk2, String newPin2, Message result) {
754        supplyIccPuk2ForApp(puk2, newPin2, null, result);
755    }
756
757    @Override public void
758    supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
759        //Note: This RIL request has not been renamed to ICC,
760        //       but this request is also valid for SIM and RUIM
761        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result);
762
763        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
764
765        rr.mp.writeInt(3);
766        rr.mp.writeString(puk);
767        rr.mp.writeString(newPin2);
768        rr.mp.writeString(aid);
769
770        send(rr);
771    }
772
773    @Override public void
774    changeIccPin(String oldPin, String newPin, Message result) {
775        changeIccPinForApp(oldPin, newPin, null, result);
776    }
777
778    @Override public void
779    changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
780        //Note: This RIL request has not been renamed to ICC,
781        //       but this request is also valid for SIM and RUIM
782        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result);
783
784        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
785
786        rr.mp.writeInt(3);
787        rr.mp.writeString(oldPin);
788        rr.mp.writeString(newPin);
789        rr.mp.writeString(aid);
790
791        send(rr);
792    }
793
794    @Override public void
795    changeIccPin2(String oldPin2, String newPin2, Message result) {
796        changeIccPin2ForApp(oldPin2, newPin2, null, result);
797    }
798
799    @Override public void
800    changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
801        //Note: This RIL request has not been renamed to ICC,
802        //       but this request is also valid for SIM and RUIM
803        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result);
804
805        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
806
807        rr.mp.writeInt(3);
808        rr.mp.writeString(oldPin2);
809        rr.mp.writeString(newPin2);
810        rr.mp.writeString(aid);
811
812        send(rr);
813    }
814
815    public void
816    changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) {
817        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result);
818
819        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
820
821        rr.mp.writeInt(3);
822        rr.mp.writeString(facility);
823        rr.mp.writeString(oldPwd);
824        rr.mp.writeString(newPwd);
825
826        send(rr);
827    }
828
829    public void
830    supplyNetworkDepersonalization(String netpin, Message result) {
831        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result);
832
833        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
834
835        rr.mp.writeInt(1);
836        rr.mp.writeString(netpin);
837
838        send(rr);
839    }
840
841    public void
842    getCurrentCalls (Message result) {
843        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);
844
845        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
846
847        send(rr);
848    }
849
850    @Deprecated public void
851    getPDPContextList(Message result) {
852        getDataCallList(result);
853    }
854
855    public void
856    getDataCallList(Message result) {
857        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_CALL_LIST, result);
858
859        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
860
861        send(rr);
862    }
863
864    public void
865    dial (String address, int clirMode, Message result) {
866        dial(address, clirMode, null, result);
867    }
868
869    public void
870    dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
871        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
872
873        rr.mp.writeString(address);
874        rr.mp.writeInt(clirMode);
875        rr.mp.writeInt(0); // UUS information is absent
876
877        if (uusInfo == null) {
878            rr.mp.writeInt(0); // UUS information is absent
879        } else {
880            rr.mp.writeInt(1); // UUS information is present
881            rr.mp.writeInt(uusInfo.getType());
882            rr.mp.writeInt(uusInfo.getDcs());
883            rr.mp.writeByteArray(uusInfo.getUserData());
884        }
885
886        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
887
888        send(rr);
889    }
890
891    public void
892    getIMSI(Message result) {
893        getIMSIForApp(null, result);
894    }
895
896    public void
897    getIMSIForApp(String aid, Message result) {
898        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result);
899
900        rr.mp.writeInt(1);
901        rr.mp.writeString(aid);
902
903        if (RILJ_LOGD) riljLog(rr.serialString() +
904                              "> getIMSI: " + requestToString(rr.mRequest)
905                              + " aid: " + aid);
906
907        send(rr);
908    }
909
910    public void
911    getIMEI(Message result) {
912        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEI, result);
913
914        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
915
916        send(rr);
917    }
918
919    public void
920    getIMEISV(Message result) {
921        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEISV, result);
922
923        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
924
925        send(rr);
926    }
927
928
929    public void
930    hangupConnection (int gsmIndex, Message result) {
931        if (RILJ_LOGD) riljLog("hangupConnection: gsmIndex=" + gsmIndex);
932
933        RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP, result);
934
935        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " +
936                gsmIndex);
937
938        rr.mp.writeInt(1);
939        rr.mp.writeInt(gsmIndex);
940
941        send(rr);
942    }
943
944    public void
945    hangupWaitingOrBackground (Message result) {
946        RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND,
947                                        result);
948
949        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
950
951        send(rr);
952    }
953
954    public void
955    hangupForegroundResumeBackground (Message result) {
956        RILRequest rr
957                = RILRequest.obtain(
958                        RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
959                                        result);
960        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
961
962        send(rr);
963    }
964
965    public void
966    switchWaitingOrHoldingAndActive (Message result) {
967        RILRequest rr
968                = RILRequest.obtain(
969                        RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
970                                        result);
971        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
972
973        send(rr);
974    }
975
976    public void
977    conference (Message result) {
978        RILRequest rr
979                = RILRequest.obtain(RIL_REQUEST_CONFERENCE, result);
980
981        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
982
983        send(rr);
984    }
985
986
987    public void setPreferredVoicePrivacy(boolean enable, Message result) {
988        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE,
989                result);
990
991        rr.mp.writeInt(1);
992        rr.mp.writeInt(enable ? 1:0);
993
994        send(rr);
995    }
996
997    public void getPreferredVoicePrivacy(Message result) {
998        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE,
999                result);
1000        send(rr);
1001    }
1002
1003    public void
1004    separateConnection (int gsmIndex, Message result) {
1005        RILRequest rr
1006                = RILRequest.obtain(RIL_REQUEST_SEPARATE_CONNECTION, result);
1007
1008        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1009                            + " " + gsmIndex);
1010
1011        rr.mp.writeInt(1);
1012        rr.mp.writeInt(gsmIndex);
1013
1014        send(rr);
1015    }
1016
1017    public void
1018    acceptCall (Message result) {
1019        RILRequest rr
1020                = RILRequest.obtain(RIL_REQUEST_ANSWER, result);
1021
1022        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1023
1024        send(rr);
1025    }
1026
1027    public void
1028    rejectCall (Message result) {
1029        RILRequest rr
1030                = RILRequest.obtain(RIL_REQUEST_UDUB, result);
1031
1032        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1033
1034        send(rr);
1035    }
1036
1037    public void
1038    explicitCallTransfer (Message result) {
1039        RILRequest rr
1040                = RILRequest.obtain(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result);
1041
1042        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1043
1044        send(rr);
1045    }
1046
1047    public void
1048    getLastCallFailCause (Message result) {
1049        RILRequest rr
1050                = RILRequest.obtain(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result);
1051
1052        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1053
1054        send(rr);
1055    }
1056
1057    /**
1058     * @deprecated
1059     */
1060    public void
1061    getLastPdpFailCause (Message result) {
1062        getLastDataCallFailCause (result);
1063    }
1064
1065    /**
1066     * The preferred new alternative to getLastPdpFailCause
1067     */
1068    public void
1069    getLastDataCallFailCause (Message result) {
1070        RILRequest rr
1071                = RILRequest.obtain(RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, result);
1072
1073        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1074
1075        send(rr);
1076    }
1077
1078    public void
1079    setMute (boolean enableMute, Message response) {
1080        RILRequest rr
1081                = RILRequest.obtain(RIL_REQUEST_SET_MUTE, response);
1082
1083        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1084                            + " " + enableMute);
1085
1086        rr.mp.writeInt(1);
1087        rr.mp.writeInt(enableMute ? 1 : 0);
1088
1089        send(rr);
1090    }
1091
1092    public void
1093    getMute (Message response) {
1094        RILRequest rr
1095                = RILRequest.obtain(RIL_REQUEST_GET_MUTE, response);
1096
1097        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1098
1099        send(rr);
1100    }
1101
1102    public void
1103    getSignalStrength (Message result) {
1104        RILRequest rr
1105                = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result);
1106
1107        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1108
1109        send(rr);
1110    }
1111
1112    public void
1113    getVoiceRegistrationState (Message result) {
1114        RILRequest rr
1115                = RILRequest.obtain(RIL_REQUEST_VOICE_REGISTRATION_STATE, result);
1116
1117        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1118
1119        send(rr);
1120    }
1121
1122    public void
1123    getDataRegistrationState (Message result) {
1124        RILRequest rr
1125                = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result);
1126
1127        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1128
1129        send(rr);
1130    }
1131
1132    public void
1133    getOperator(Message result) {
1134        RILRequest rr
1135                = RILRequest.obtain(RIL_REQUEST_OPERATOR, result);
1136
1137        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1138
1139        send(rr);
1140    }
1141
1142    public void
1143    sendDtmf(char c, Message result) {
1144        RILRequest rr
1145                = RILRequest.obtain(RIL_REQUEST_DTMF, result);
1146
1147        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1148
1149        rr.mp.writeString(Character.toString(c));
1150
1151        send(rr);
1152    }
1153
1154    public void
1155    startDtmf(char c, Message result) {
1156        RILRequest rr
1157                = RILRequest.obtain(RIL_REQUEST_DTMF_START, result);
1158
1159        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1160
1161        rr.mp.writeString(Character.toString(c));
1162
1163        send(rr);
1164    }
1165
1166    public void
1167    stopDtmf(Message result) {
1168        RILRequest rr
1169                = RILRequest.obtain(RIL_REQUEST_DTMF_STOP, result);
1170
1171        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1172
1173        send(rr);
1174    }
1175
1176    public void
1177    sendBurstDtmf(String dtmfString, int on, int off, Message result) {
1178        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BURST_DTMF, result);
1179
1180        rr.mp.writeInt(3);
1181        rr.mp.writeString(dtmfString);
1182        rr.mp.writeString(Integer.toString(on));
1183        rr.mp.writeString(Integer.toString(off));
1184
1185        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1186                + " : " + dtmfString);
1187
1188        send(rr);
1189    }
1190
1191    public void
1192    sendSMS (String smscPDU, String pdu, Message result) {
1193        RILRequest rr
1194                = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result);
1195
1196        rr.mp.writeInt(2);
1197        rr.mp.writeString(smscPDU);
1198        rr.mp.writeString(pdu);
1199
1200        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1201
1202        send(rr);
1203    }
1204
1205    public void
1206    sendCdmaSms(byte[] pdu, Message result) {
1207        int address_nbr_of_digits;
1208        int subaddr_nbr_of_digits;
1209        int bearerDataLength;
1210        ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
1211        DataInputStream dis = new DataInputStream(bais);
1212
1213        RILRequest rr
1214                = RILRequest.obtain(RIL_REQUEST_CDMA_SEND_SMS, result);
1215
1216        try {
1217            rr.mp.writeInt(dis.readInt()); //teleServiceId
1218            rr.mp.writeByte((byte) dis.readInt()); //servicePresent
1219            rr.mp.writeInt(dis.readInt()); //serviceCategory
1220            rr.mp.writeInt(dis.read()); //address_digit_mode
1221            rr.mp.writeInt(dis.read()); //address_nbr_mode
1222            rr.mp.writeInt(dis.read()); //address_ton
1223            rr.mp.writeInt(dis.read()); //address_nbr_plan
1224            address_nbr_of_digits = (byte) dis.read();
1225            rr.mp.writeByte((byte) address_nbr_of_digits);
1226            for(int i=0; i < address_nbr_of_digits; i++){
1227                rr.mp.writeByte(dis.readByte()); // address_orig_bytes[i]
1228            }
1229            rr.mp.writeInt(dis.read()); //subaddressType
1230            rr.mp.writeByte((byte) dis.read()); //subaddr_odd
1231            subaddr_nbr_of_digits = (byte) dis.read();
1232            rr.mp.writeByte((byte) subaddr_nbr_of_digits);
1233            for(int i=0; i < subaddr_nbr_of_digits; i++){
1234                rr.mp.writeByte(dis.readByte()); //subaddr_orig_bytes[i]
1235            }
1236
1237            bearerDataLength = dis.read();
1238            rr.mp.writeInt(bearerDataLength);
1239            for(int i=0; i < bearerDataLength; i++){
1240                rr.mp.writeByte(dis.readByte()); //bearerData[i]
1241            }
1242        }catch (IOException ex){
1243            if (RILJ_LOGD) riljLog("sendSmsCdma: conversion from input stream to object failed: "
1244                    + ex);
1245        }
1246
1247        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1248
1249        send(rr);
1250    }
1251
1252    public void deleteSmsOnSim(int index, Message response) {
1253        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DELETE_SMS_ON_SIM,
1254                response);
1255
1256        rr.mp.writeInt(1);
1257        rr.mp.writeInt(index);
1258
1259        if (false) {
1260            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
1261                    + requestToString(rr.mRequest)
1262                    + " " + index);
1263        }
1264
1265        send(rr);
1266    }
1267
1268    public void deleteSmsOnRuim(int index, Message response) {
1269        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM,
1270                response);
1271
1272        rr.mp.writeInt(1);
1273        rr.mp.writeInt(index);
1274
1275        if (false) {
1276            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
1277                    + requestToString(rr.mRequest)
1278                    + " " + index);
1279        }
1280
1281        send(rr);
1282    }
1283
1284    public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
1285        status = translateStatus(status);
1286
1287        RILRequest rr = RILRequest.obtain(RIL_REQUEST_WRITE_SMS_TO_SIM,
1288                response);
1289
1290        rr.mp.writeInt(status);
1291        rr.mp.writeString(pdu);
1292        rr.mp.writeString(smsc);
1293
1294        if (false) {
1295            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
1296                    + requestToString(rr.mRequest)
1297                    + " " + status);
1298        }
1299
1300        send(rr);
1301    }
1302
1303    public void writeSmsToRuim(int status, String pdu, Message response) {
1304        status = translateStatus(status);
1305
1306        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM,
1307                response);
1308
1309        rr.mp.writeInt(status);
1310        rr.mp.writeString(pdu);
1311
1312        if (false) {
1313            if (RILJ_LOGD) riljLog(rr.serialString() + "> "
1314                    + requestToString(rr.mRequest)
1315                    + " " + status);
1316        }
1317
1318        send(rr);
1319    }
1320
1321    /**
1322     *  Translates EF_SMS status bits to a status value compatible with
1323     *  SMS AT commands.  See TS 27.005 3.1.
1324     */
1325    private int translateStatus(int status) {
1326        switch(status & 0x7) {
1327            case SmsManager.STATUS_ON_ICC_READ:
1328                return 1;
1329            case SmsManager.STATUS_ON_ICC_UNREAD:
1330                return 0;
1331            case SmsManager.STATUS_ON_ICC_SENT:
1332                return 3;
1333            case SmsManager.STATUS_ON_ICC_UNSENT:
1334                return 2;
1335        }
1336
1337        // Default to READ.
1338        return 1;
1339    }
1340
1341    public void
1342    setupDataCall(String radioTechnology, String profile, String apn,
1343            String user, String password, String authType, String protocol,
1344            Message result) {
1345        RILRequest rr
1346                = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
1347
1348        rr.mp.writeInt(7);
1349
1350        rr.mp.writeString(radioTechnology);
1351        rr.mp.writeString(profile);
1352        rr.mp.writeString(apn);
1353        rr.mp.writeString(user);
1354        rr.mp.writeString(password);
1355        rr.mp.writeString(authType);
1356        rr.mp.writeString(protocol);
1357
1358        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
1359                + requestToString(rr.mRequest) + " " + radioTechnology + " "
1360                + profile + " " + apn + " " + user + " "
1361                + password + " " + authType + " " + protocol);
1362
1363        send(rr);
1364    }
1365
1366    public void
1367    deactivateDataCall(int cid, int reason, Message result) {
1368        RILRequest rr
1369                = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result);
1370
1371        rr.mp.writeInt(2);
1372        rr.mp.writeString(Integer.toString(cid));
1373        rr.mp.writeString(Integer.toString(reason));
1374
1375        if (RILJ_LOGD) riljLog(rr.serialString() + "> " +
1376                requestToString(rr.mRequest) + " " + cid + " " + reason);
1377
1378        send(rr);
1379    }
1380
1381    public void
1382    setRadioPower(boolean on, Message result) {
1383        RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
1384
1385        rr.mp.writeInt(1);
1386        rr.mp.writeInt(on ? 1 : 0);
1387
1388        if (RILJ_LOGD) {
1389            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1390                    + (on ? " on" : " off"));
1391        }
1392
1393        send(rr);
1394    }
1395
1396    public void
1397    setSuppServiceNotifications(boolean enable, Message result) {
1398        RILRequest rr
1399                = RILRequest.obtain(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result);
1400
1401        rr.mp.writeInt(1);
1402        rr.mp.writeInt(enable ? 1 : 0);
1403
1404        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
1405                + requestToString(rr.mRequest));
1406
1407        send(rr);
1408    }
1409
1410    public void
1411    acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
1412        RILRequest rr
1413                = RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result);
1414
1415        rr.mp.writeInt(2);
1416        rr.mp.writeInt(success ? 1 : 0);
1417        rr.mp.writeInt(cause);
1418
1419        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1420                + " " + success + " " + cause);
1421
1422        send(rr);
1423    }
1424
1425    public void
1426    acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
1427        RILRequest rr
1428                = RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result);
1429
1430        rr.mp.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass
1431        // cause code according to X.S004-550E
1432        rr.mp.writeInt(cause);
1433
1434        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1435                + " " + success + " " + cause);
1436
1437        send(rr);
1438    }
1439
1440    public void
1441    acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) {
1442        RILRequest rr
1443                = RILRequest.obtain(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result);
1444
1445        rr.mp.writeInt(2);
1446        rr.mp.writeString(success ? "1" : "0");
1447        rr.mp.writeString(ackPdu);
1448
1449        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1450                + ' ' + success + " [" + ackPdu + ']');
1451
1452        send(rr);
1453    }
1454
1455    public void
1456    iccIO (int command, int fileid, String path, int p1, int p2, int p3,
1457            String data, String pin2, Message result) {
1458        iccIOForApp(command, fileid, path, p1, p2, p3, data, pin2, null, result);
1459    }
1460    public void
1461    iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3,
1462            String data, String pin2, String aid, Message result) {
1463        //Note: This RIL request has not been renamed to ICC,
1464        //       but this request is also valid for SIM and RUIM
1465        RILRequest rr
1466                = RILRequest.obtain(RIL_REQUEST_SIM_IO, result);
1467
1468        rr.mp.writeInt(command);
1469        rr.mp.writeInt(fileid);
1470        rr.mp.writeString(path);
1471        rr.mp.writeInt(p1);
1472        rr.mp.writeInt(p2);
1473        rr.mp.writeInt(p3);
1474        rr.mp.writeString(data);
1475        rr.mp.writeString(pin2);
1476        rr.mp.writeString(aid);
1477
1478        if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: "
1479                + requestToString(rr.mRequest)
1480                + " 0x" + Integer.toHexString(command)
1481                + " 0x" + Integer.toHexString(fileid) + " "
1482                + " path: " + path + ","
1483                + p1 + "," + p2 + "," + p3
1484                + " aid: " + aid);
1485
1486        send(rr);
1487    }
1488
1489    public void
1490    getCLIR(Message result) {
1491        RILRequest rr
1492                = RILRequest.obtain(RIL_REQUEST_GET_CLIR, result);
1493
1494        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1495
1496        send(rr);
1497    }
1498
1499    public void
1500    setCLIR(int clirMode, Message result) {
1501        RILRequest rr
1502                = RILRequest.obtain(RIL_REQUEST_SET_CLIR, result);
1503
1504        // count ints
1505        rr.mp.writeInt(1);
1506
1507        rr.mp.writeInt(clirMode);
1508
1509        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1510                    + " " + clirMode);
1511
1512        send(rr);
1513    }
1514
1515    public void
1516    queryCallWaiting(int serviceClass, Message response) {
1517        RILRequest rr
1518                = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_WAITING, response);
1519
1520        rr.mp.writeInt(1);
1521        rr.mp.writeInt(serviceClass);
1522
1523        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1524                    + " " + serviceClass);
1525
1526        send(rr);
1527    }
1528
1529    public void
1530    setCallWaiting(boolean enable, int serviceClass, Message response) {
1531        RILRequest rr
1532                = RILRequest.obtain(RIL_REQUEST_SET_CALL_WAITING, response);
1533
1534        rr.mp.writeInt(2);
1535        rr.mp.writeInt(enable ? 1 : 0);
1536        rr.mp.writeInt(serviceClass);
1537
1538        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1539                + " " + enable + ", " + serviceClass);
1540
1541        send(rr);
1542    }
1543
1544    public void
1545    setNetworkSelectionModeAutomatic(Message response) {
1546        RILRequest rr
1547                = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
1548                                    response);
1549
1550        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1551
1552        send(rr);
1553    }
1554
1555    public void
1556    setNetworkSelectionModeManual(String operatorNumeric, Message response) {
1557        RILRequest rr
1558                = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
1559                                    response);
1560
1561        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1562                    + " " + operatorNumeric);
1563
1564        rr.mp.writeString(operatorNumeric);
1565
1566        send(rr);
1567    }
1568
1569    public void
1570    getNetworkSelectionMode(Message response) {
1571        RILRequest rr
1572                = RILRequest.obtain(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE,
1573                                    response);
1574
1575        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1576
1577        send(rr);
1578    }
1579
1580    public void
1581    getAvailableNetworks(Message response) {
1582        RILRequest rr
1583                = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS,
1584                                    response);
1585
1586        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1587
1588        send(rr);
1589    }
1590
1591    public void
1592    setCallForward(int action, int cfReason, int serviceClass,
1593                String number, int timeSeconds, Message response) {
1594        RILRequest rr
1595                = RILRequest.obtain(RIL_REQUEST_SET_CALL_FORWARD, response);
1596
1597        rr.mp.writeInt(action);
1598        rr.mp.writeInt(cfReason);
1599        rr.mp.writeInt(serviceClass);
1600        rr.mp.writeInt(PhoneNumberUtils.toaFromString(number));
1601        rr.mp.writeString(number);
1602        rr.mp.writeInt (timeSeconds);
1603
1604        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1605                    + " " + action + " " + cfReason + " " + serviceClass
1606                    + timeSeconds);
1607
1608        send(rr);
1609    }
1610
1611    public void
1612    queryCallForwardStatus(int cfReason, int serviceClass,
1613                String number, Message response) {
1614        RILRequest rr
1615            = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, response);
1616
1617        rr.mp.writeInt(2); // 2 is for query action, not in used anyway
1618        rr.mp.writeInt(cfReason);
1619        rr.mp.writeInt(serviceClass);
1620        rr.mp.writeInt(PhoneNumberUtils.toaFromString(number));
1621        rr.mp.writeString(number);
1622        rr.mp.writeInt (0);
1623
1624        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1625                + " " + cfReason + " " + serviceClass);
1626
1627        send(rr);
1628    }
1629
1630    public void
1631    queryCLIP(Message response) {
1632        RILRequest rr
1633            = RILRequest.obtain(RIL_REQUEST_QUERY_CLIP, response);
1634
1635        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1636
1637        send(rr);
1638    }
1639
1640
1641    public void
1642    getBasebandVersion (Message response) {
1643        RILRequest rr
1644                = RILRequest.obtain(RIL_REQUEST_BASEBAND_VERSION, response);
1645
1646        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1647
1648        send(rr);
1649    }
1650
1651    @Override
1652    public void
1653    queryFacilityLock(String facility, String password, int serviceClass,
1654                            Message response) {
1655        queryFacilityLockForApp(facility, password, serviceClass, null, response);
1656    }
1657
1658    @Override
1659    public void
1660    queryFacilityLockForApp(String facility, String password, int serviceClass, String appId,
1661                            Message response) {
1662        RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response);
1663
1664        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1665                                                 + " [" + facility + " " + serviceClass
1666                                                 + " " + appId + "]");
1667
1668        // count strings
1669        rr.mp.writeInt(4);
1670
1671        rr.mp.writeString(facility);
1672        rr.mp.writeString(password);
1673
1674        rr.mp.writeString(Integer.toString(serviceClass));
1675        rr.mp.writeString(appId);
1676
1677        send(rr);
1678    }
1679
1680    @Override
1681    public void
1682    setFacilityLock (String facility, boolean lockState, String password,
1683                        int serviceClass, Message response) {
1684        setFacilityLockForApp(facility, lockState, password, serviceClass, null, response);
1685    }
1686
1687    @Override
1688    public void
1689    setFacilityLockForApp(String facility, boolean lockState, String password,
1690                        int serviceClass, String appId, Message response) {
1691        String lockString;
1692         RILRequest rr
1693                = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response);
1694
1695        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1696                                                        + " [" + facility + " " + lockState
1697                                                        + " " + serviceClass + " " + appId + "]");
1698
1699        // count strings
1700        rr.mp.writeInt(5);
1701
1702        rr.mp.writeString(facility);
1703        lockString = (lockState)?"1":"0";
1704        rr.mp.writeString(lockString);
1705        rr.mp.writeString(password);
1706        rr.mp.writeString(Integer.toString(serviceClass));
1707        rr.mp.writeString(appId);
1708
1709        send(rr);
1710
1711    }
1712
1713    public void
1714    sendUSSD (String ussdString, Message response) {
1715        RILRequest rr
1716                = RILRequest.obtain(RIL_REQUEST_SEND_USSD, response);
1717
1718        if (RILJ_LOGD) {
1719            String logUssdString = "*******";
1720            if (RILJ_LOGV) logUssdString = ussdString;
1721            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1722                                   + " " + logUssdString);
1723        }
1724
1725        rr.mp.writeString(ussdString);
1726
1727        send(rr);
1728    }
1729
1730    // inherited javadoc suffices
1731    public void cancelPendingUssd (Message response) {
1732        RILRequest rr
1733                = RILRequest.obtain(RIL_REQUEST_CANCEL_USSD, response);
1734
1735        if (RILJ_LOGD) riljLog(rr.serialString()
1736                + "> " + requestToString(rr.mRequest));
1737
1738        send(rr);
1739    }
1740
1741
1742    public void resetRadio(Message result) {
1743        RILRequest rr
1744                = RILRequest.obtain(RIL_REQUEST_RESET_RADIO, result);
1745
1746        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1747
1748        send(rr);
1749    }
1750
1751    public void invokeOemRilRequestRaw(byte[] data, Message response) {
1752        RILRequest rr
1753                = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_RAW, response);
1754
1755        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1756               + "[" + IccUtils.bytesToHexString(data) + "]");
1757
1758        rr.mp.writeByteArray(data);
1759
1760        send(rr);
1761
1762    }
1763
1764    public void invokeOemRilRequestStrings(String[] strings, Message response) {
1765        RILRequest rr
1766                = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_STRINGS, response);
1767
1768        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1769
1770        rr.mp.writeStringArray(strings);
1771
1772        send(rr);
1773    }
1774
1775     /**
1776     * Assign a specified band for RF configuration.
1777     *
1778     * @param bandMode one of BM_*_BAND
1779     * @param response is callback message
1780     */
1781    public void setBandMode (int bandMode, Message response) {
1782        RILRequest rr
1783                = RILRequest.obtain(RIL_REQUEST_SET_BAND_MODE, response);
1784
1785        rr.mp.writeInt(1);
1786        rr.mp.writeInt(bandMode);
1787
1788        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1789                 + " " + bandMode);
1790
1791        send(rr);
1792     }
1793
1794    /**
1795     * Query the list of band mode supported by RF.
1796     *
1797     * @param response is callback message
1798     *        ((AsyncResult)response.obj).result  is an int[] with every
1799     *        element representing one avialable BM_*_BAND
1800     */
1801    public void queryAvailableBandMode (Message response) {
1802        RILRequest rr
1803                = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE,
1804                response);
1805
1806        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1807
1808        send(rr);
1809    }
1810
1811    /**
1812     * {@inheritDoc}
1813     */
1814    public void sendTerminalResponse(String contents, Message response) {
1815        RILRequest rr = RILRequest.obtain(
1816                RILConstants.RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, response);
1817
1818        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1819
1820        rr.mp.writeString(contents);
1821        send(rr);
1822    }
1823
1824    /**
1825     * {@inheritDoc}
1826     */
1827    public void sendEnvelope(String contents, Message response) {
1828        RILRequest rr = RILRequest.obtain(
1829                RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, response);
1830
1831        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1832
1833        rr.mp.writeString(contents);
1834        send(rr);
1835    }
1836
1837    /**
1838     * {@inheritDoc}
1839     */
1840    public void sendEnvelopeWithStatus(String contents, Message response) {
1841        RILRequest rr = RILRequest.obtain(
1842                RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, response);
1843
1844        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1845                + '[' + contents + ']');
1846
1847        rr.mp.writeString(contents);
1848        send(rr);
1849    }
1850
1851    /**
1852     * {@inheritDoc}
1853     */
1854    public void handleCallSetupRequestFromSim(
1855            boolean accept, Message response) {
1856
1857        RILRequest rr = RILRequest.obtain(
1858            RILConstants.RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
1859            response);
1860
1861        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1862
1863        int[] param = new int[1];
1864        param[0] = accept ? 1 : 0;
1865        rr.mp.writeIntArray(param);
1866        send(rr);
1867    }
1868
1869    /**
1870     * {@inheritDoc}
1871     */
1872    @Override
1873    public void setCurrentPreferredNetworkType() {
1874        if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType: " + mSetPreferredNetworkType);
1875        setPreferredNetworkType(mSetPreferredNetworkType, null);
1876    }
1877    private int mSetPreferredNetworkType;
1878
1879    /**
1880     * {@inheritDoc}
1881     */
1882    public void setPreferredNetworkType(int networkType , Message response) {
1883        RILRequest rr = RILRequest.obtain(
1884                RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);
1885
1886        rr.mp.writeInt(1);
1887        rr.mp.writeInt(networkType);
1888
1889        mSetPreferredNetworkType = networkType;
1890        mPreferredNetworkType = networkType;
1891
1892        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1893                + " : " + networkType);
1894
1895        send(rr);
1896    }
1897
1898    /**
1899     * {@inheritDoc}
1900     */
1901    public void getPreferredNetworkType(Message response) {
1902        RILRequest rr = RILRequest.obtain(
1903                RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, response);
1904
1905        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1906
1907        send(rr);
1908    }
1909
1910    /**
1911     * {@inheritDoc}
1912     */
1913    public void getNeighboringCids(Message response) {
1914        RILRequest rr = RILRequest.obtain(
1915                RILConstants.RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, response);
1916
1917        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1918
1919        send(rr);
1920    }
1921
1922    /**
1923     * {@inheritDoc}
1924     */
1925    public void setLocationUpdates(boolean enable, Message response) {
1926        RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_LOCATION_UPDATES, response);
1927        rr.mp.writeInt(1);
1928        rr.mp.writeInt(enable ? 1 : 0);
1929
1930        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
1931                + requestToString(rr.mRequest) + ": " + enable);
1932
1933        send(rr);
1934    }
1935
1936    /**
1937     * {@inheritDoc}
1938     */
1939    public void getSmscAddress(Message result) {
1940        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SMSC_ADDRESS, result);
1941
1942        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1943
1944        send(rr);
1945    }
1946
1947    /**
1948     * {@inheritDoc}
1949     */
1950    public void setSmscAddress(String address, Message result) {
1951        RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_SMSC_ADDRESS, result);
1952
1953        rr.mp.writeString(address);
1954
1955        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
1956                + " : " + address);
1957
1958        send(rr);
1959    }
1960
1961    /**
1962     * {@inheritDoc}
1963     */
1964    public void reportSmsMemoryStatus(boolean available, Message result) {
1965        RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result);
1966        rr.mp.writeInt(1);
1967        rr.mp.writeInt(available ? 1 : 0);
1968
1969        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
1970                + requestToString(rr.mRequest) + ": " + available);
1971
1972        send(rr);
1973    }
1974
1975    /**
1976     * {@inheritDoc}
1977     */
1978    public void reportStkServiceIsRunning(Message result) {
1979        RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result);
1980
1981        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1982
1983        send(rr);
1984    }
1985
1986    /**
1987     * {@inheritDoc}
1988     */
1989    public void getGsmBroadcastConfig(Message response) {
1990        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, response);
1991
1992        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
1993
1994        send(rr);
1995    }
1996
1997    /**
1998     * {@inheritDoc}
1999     */
2000    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
2001        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, response);
2002
2003        int numOfConfig = config.length;
2004        rr.mp.writeInt(numOfConfig);
2005
2006        for(int i = 0; i < numOfConfig; i++) {
2007            rr.mp.writeInt(config[i].getFromServiceId());
2008            rr.mp.writeInt(config[i].getToServiceId());
2009            rr.mp.writeInt(config[i].getFromCodeScheme());
2010            rr.mp.writeInt(config[i].getToCodeScheme());
2011            rr.mp.writeInt(config[i].isSelected() ? 1 : 0);
2012        }
2013
2014        if (RILJ_LOGD) {
2015            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
2016                    + " with " + numOfConfig + " configs : ");
2017            for (int i = 0; i < numOfConfig; i++) {
2018                riljLog(config[i].toString());
2019            }
2020        }
2021
2022        send(rr);
2023    }
2024
2025    /**
2026     * {@inheritDoc}
2027     */
2028    public void setGsmBroadcastActivation(boolean activate, Message response) {
2029        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, response);
2030
2031        rr.mp.writeInt(1);
2032        rr.mp.writeInt(activate ? 0 : 1);
2033
2034        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
2035
2036        send(rr);
2037    }
2038
2039    //***** Private Methods
2040
2041    private void sendScreenState(boolean on) {
2042        RILRequest rr = RILRequest.obtain(RIL_REQUEST_SCREEN_STATE, null);
2043        rr.mp.writeInt(1);
2044        rr.mp.writeInt(on ? 1 : 0);
2045
2046        if (RILJ_LOGD) riljLog(rr.serialString()
2047                + "> " + requestToString(rr.mRequest) + ": " + on);
2048
2049        send(rr);
2050    }
2051
2052    protected void
2053    onRadioAvailable() {
2054        // In case screen state was lost (due to process crash),
2055        // this ensures that the RIL knows the correct screen state.
2056
2057        // TODO: Should query Power Manager and send the actual
2058        // screen state.  Just send true for now.
2059        sendScreenState(true);
2060   }
2061
2062    private RadioState getRadioStateFromInt(int stateInt) {
2063        RadioState state;
2064
2065        /* RIL_RadioState ril.h */
2066        switch(stateInt) {
2067            case 0: state = RadioState.RADIO_OFF; break;
2068            case 1: state = RadioState.RADIO_UNAVAILABLE; break;
2069            case 10: state = RadioState.RADIO_ON; break;
2070
2071            default:
2072                throw new RuntimeException(
2073                            "Unrecognized RIL_RadioState: " + stateInt);
2074        }
2075        return state;
2076    }
2077
2078    private void switchToRadioState(RadioState newState) {
2079        setRadioState(newState);
2080    }
2081
2082    /**
2083     * Holds a PARTIAL_WAKE_LOCK whenever
2084     * a) There is outstanding RIL request sent to RIL deamon and no replied
2085     * b) There is a request pending to be sent out.
2086     *
2087     * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
2088     * happen often.
2089     */
2090
2091    private void
2092    acquireWakeLock() {
2093        synchronized (mWakeLock) {
2094            mWakeLock.acquire();
2095            mRequestMessagesPending++;
2096
2097            mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
2098            Message msg = mSender.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
2099            mSender.sendMessageDelayed(msg, mWakeLockTimeout);
2100        }
2101    }
2102
2103    private void
2104    releaseWakeLockIfDone() {
2105        synchronized (mWakeLock) {
2106            if (mWakeLock.isHeld() &&
2107                (mRequestMessagesPending == 0) &&
2108                (mRequestMessagesWaiting == 0)) {
2109                mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
2110                mWakeLock.release();
2111            }
2112        }
2113    }
2114
2115    private void
2116    send(RILRequest rr) {
2117        Message msg;
2118
2119        if (mSocket == null) {
2120            rr.onError(RADIO_NOT_AVAILABLE, null);
2121            rr.release();
2122            return;
2123        }
2124
2125        msg = mSender.obtainMessage(EVENT_SEND, rr);
2126
2127        acquireWakeLock();
2128
2129        msg.sendToTarget();
2130    }
2131
2132    private void
2133    processResponse (Parcel p) {
2134        int type;
2135
2136        type = p.readInt();
2137
2138        if (type == RESPONSE_UNSOLICITED) {
2139            processUnsolicited (p);
2140        } else if (type == RESPONSE_SOLICITED) {
2141            processSolicited (p);
2142        }
2143
2144        releaseWakeLockIfDone();
2145    }
2146
2147    /**
2148     * Release each request in mReqeustsList then clear the list
2149     * @param error is the RIL_Errno sent back
2150     * @param loggable true means to print all requests in mRequestslist
2151     */
2152    private void clearRequestsList(int error, boolean loggable) {
2153        RILRequest rr;
2154        synchronized (mRequestsList) {
2155            int count = mRequestsList.size();
2156            if (RILJ_LOGD && loggable) {
2157                Rlog.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
2158                        " mReqPending=" + mRequestMessagesPending +
2159                        " mRequestList=" + count);
2160            }
2161
2162            for (int i = 0; i < count ; i++) {
2163                rr = mRequestsList.get(i);
2164                if (RILJ_LOGD && loggable) {
2165                    Rlog.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
2166                            requestToString(rr.mRequest));
2167                }
2168                rr.onError(error, null);
2169                rr.release();
2170            }
2171            mRequestsList.clear();
2172            mRequestMessagesWaiting = 0;
2173        }
2174    }
2175
2176    private RILRequest findAndRemoveRequestFromList(int serial) {
2177        synchronized (mRequestsList) {
2178            for (int i = 0, s = mRequestsList.size() ; i < s ; i++) {
2179                RILRequest rr = mRequestsList.get(i);
2180
2181                if (rr.mSerial == serial) {
2182                    mRequestsList.remove(i);
2183                    if (mRequestMessagesWaiting > 0)
2184                        mRequestMessagesWaiting--;
2185                    return rr;
2186                }
2187            }
2188        }
2189
2190        return null;
2191    }
2192
2193    private void
2194    processSolicited (Parcel p) {
2195        int serial, error;
2196        boolean found = false;
2197
2198        serial = p.readInt();
2199        error = p.readInt();
2200
2201        RILRequest rr;
2202
2203        rr = findAndRemoveRequestFromList(serial);
2204
2205        if (rr == null) {
2206            Rlog.w(LOG_TAG, "Unexpected solicited response! sn: "
2207                            + serial + " error: " + error);
2208            return;
2209        }
2210
2211        Object ret = null;
2212
2213        if (error == 0 || p.dataAvail() > 0) {
2214            // either command succeeds or command fails but with data payload
2215            try {switch (rr.mRequest) {
2216            /*
2217 cat libs/telephony/ril_commands.h \
2218 | egrep "^ *{RIL_" \
2219 | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
2220             */
2221            case RIL_REQUEST_GET_SIM_STATUS: ret =  responseIccCardStatus(p); break;
2222            case RIL_REQUEST_ENTER_SIM_PIN: ret =  responseInts(p); break;
2223            case RIL_REQUEST_ENTER_SIM_PUK: ret =  responseInts(p); break;
2224            case RIL_REQUEST_ENTER_SIM_PIN2: ret =  responseInts(p); break;
2225            case RIL_REQUEST_ENTER_SIM_PUK2: ret =  responseInts(p); break;
2226            case RIL_REQUEST_CHANGE_SIM_PIN: ret =  responseInts(p); break;
2227            case RIL_REQUEST_CHANGE_SIM_PIN2: ret =  responseInts(p); break;
2228            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret =  responseInts(p); break;
2229            case RIL_REQUEST_GET_CURRENT_CALLS: ret =  responseCallList(p); break;
2230            case RIL_REQUEST_DIAL: ret =  responseVoid(p); break;
2231            case RIL_REQUEST_GET_IMSI: ret =  responseString(p); break;
2232            case RIL_REQUEST_HANGUP: ret =  responseVoid(p); break;
2233            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret =  responseVoid(p); break;
2234            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: {
2235                if (mTestingEmergencyCall.getAndSet(false)) {
2236                    if (mEmergencyCallbackModeRegistrant != null) {
2237                        riljLog("testing emergency call, notify ECM Registrants");
2238                        mEmergencyCallbackModeRegistrant.notifyRegistrant();
2239                    }
2240                }
2241                ret =  responseVoid(p);
2242                break;
2243            }
2244            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret =  responseVoid(p); break;
2245            case RIL_REQUEST_CONFERENCE: ret =  responseVoid(p); break;
2246            case RIL_REQUEST_UDUB: ret =  responseVoid(p); break;
2247            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret =  responseInts(p); break;
2248            case RIL_REQUEST_SIGNAL_STRENGTH: ret =  responseSignalStrength(p); break;
2249            case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret =  responseStrings(p); break;
2250            case RIL_REQUEST_DATA_REGISTRATION_STATE: ret =  responseStrings(p); break;
2251            case RIL_REQUEST_OPERATOR: ret =  responseStrings(p); break;
2252            case RIL_REQUEST_RADIO_POWER: ret =  responseVoid(p); break;
2253            case RIL_REQUEST_DTMF: ret =  responseVoid(p); break;
2254            case RIL_REQUEST_SEND_SMS: ret =  responseSMS(p); break;
2255            case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret =  responseSMS(p); break;
2256            case RIL_REQUEST_SETUP_DATA_CALL: ret =  responseSetupDataCall(p); break;
2257            case RIL_REQUEST_SIM_IO: ret =  responseICC_IO(p); break;
2258            case RIL_REQUEST_SEND_USSD: ret =  responseVoid(p); break;
2259            case RIL_REQUEST_CANCEL_USSD: ret =  responseVoid(p); break;
2260            case RIL_REQUEST_GET_CLIR: ret =  responseInts(p); break;
2261            case RIL_REQUEST_SET_CLIR: ret =  responseVoid(p); break;
2262            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret =  responseCallForward(p); break;
2263            case RIL_REQUEST_SET_CALL_FORWARD: ret =  responseVoid(p); break;
2264            case RIL_REQUEST_QUERY_CALL_WAITING: ret =  responseInts(p); break;
2265            case RIL_REQUEST_SET_CALL_WAITING: ret =  responseVoid(p); break;
2266            case RIL_REQUEST_SMS_ACKNOWLEDGE: ret =  responseVoid(p); break;
2267            case RIL_REQUEST_GET_IMEI: ret =  responseString(p); break;
2268            case RIL_REQUEST_GET_IMEISV: ret =  responseString(p); break;
2269            case RIL_REQUEST_ANSWER: ret =  responseVoid(p); break;
2270            case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret =  responseVoid(p); break;
2271            case RIL_REQUEST_QUERY_FACILITY_LOCK: ret =  responseInts(p); break;
2272            case RIL_REQUEST_SET_FACILITY_LOCK: ret =  responseInts(p); break;
2273            case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret =  responseVoid(p); break;
2274            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret =  responseInts(p); break;
2275            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret =  responseVoid(p); break;
2276            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret =  responseVoid(p); break;
2277            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret =  responseOperatorInfos(p); break;
2278            case RIL_REQUEST_DTMF_START: ret =  responseVoid(p); break;
2279            case RIL_REQUEST_DTMF_STOP: ret =  responseVoid(p); break;
2280            case RIL_REQUEST_BASEBAND_VERSION: ret =  responseString(p); break;
2281            case RIL_REQUEST_SEPARATE_CONNECTION: ret =  responseVoid(p); break;
2282            case RIL_REQUEST_SET_MUTE: ret =  responseVoid(p); break;
2283            case RIL_REQUEST_GET_MUTE: ret =  responseInts(p); break;
2284            case RIL_REQUEST_QUERY_CLIP: ret =  responseInts(p); break;
2285            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret =  responseInts(p); break;
2286            case RIL_REQUEST_DATA_CALL_LIST: ret =  responseDataCallList(p); break;
2287            case RIL_REQUEST_RESET_RADIO: ret =  responseVoid(p); break;
2288            case RIL_REQUEST_OEM_HOOK_RAW: ret =  responseRaw(p); break;
2289            case RIL_REQUEST_OEM_HOOK_STRINGS: ret =  responseStrings(p); break;
2290            case RIL_REQUEST_SCREEN_STATE: ret =  responseVoid(p); break;
2291            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret =  responseVoid(p); break;
2292            case RIL_REQUEST_WRITE_SMS_TO_SIM: ret =  responseInts(p); break;
2293            case RIL_REQUEST_DELETE_SMS_ON_SIM: ret =  responseVoid(p); break;
2294            case RIL_REQUEST_SET_BAND_MODE: ret =  responseVoid(p); break;
2295            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret =  responseInts(p); break;
2296            case RIL_REQUEST_STK_GET_PROFILE: ret =  responseString(p); break;
2297            case RIL_REQUEST_STK_SET_PROFILE: ret =  responseVoid(p); break;
2298            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret =  responseString(p); break;
2299            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret =  responseVoid(p); break;
2300            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret =  responseInts(p); break;
2301            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret =  responseVoid(p); break;
2302            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret =  responseVoid(p); break;
2303            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret =  responseGetPreferredNetworkType(p); break;
2304            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
2305            case RIL_REQUEST_SET_LOCATION_UPDATES: ret =  responseVoid(p); break;
2306            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret =  responseVoid(p); break;
2307            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret =  responseVoid(p); break;
2308            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret =  responseInts(p); break;
2309            case RIL_REQUEST_SET_TTY_MODE: ret =  responseVoid(p); break;
2310            case RIL_REQUEST_QUERY_TTY_MODE: ret =  responseInts(p); break;
2311            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret =  responseVoid(p); break;
2312            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret =  responseInts(p); break;
2313            case RIL_REQUEST_CDMA_FLASH: ret =  responseVoid(p); break;
2314            case RIL_REQUEST_CDMA_BURST_DTMF: ret =  responseVoid(p); break;
2315            case RIL_REQUEST_CDMA_SEND_SMS: ret =  responseSMS(p); break;
2316            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret =  responseVoid(p); break;
2317            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret =  responseGmsBroadcastConfig(p); break;
2318            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret =  responseVoid(p); break;
2319            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret =  responseVoid(p); break;
2320            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret =  responseCdmaBroadcastConfig(p); break;
2321            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret =  responseVoid(p); break;
2322            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret =  responseVoid(p); break;
2323            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret =  responseVoid(p); break;
2324            case RIL_REQUEST_CDMA_SUBSCRIPTION: ret =  responseStrings(p); break;
2325            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret =  responseInts(p); break;
2326            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret =  responseVoid(p); break;
2327            case RIL_REQUEST_DEVICE_IDENTITY: ret =  responseStrings(p); break;
2328            case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
2329            case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
2330            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2331            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
2332            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
2333            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret =  responseInts(p); break;
2334            case RIL_REQUEST_ISIM_AUTHENTICATION: ret =  responseString(p); break;
2335            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
2336            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
2337            case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break;
2338            default:
2339                throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
2340            //break;
2341            }} catch (Throwable tr) {
2342                // Exceptions here usually mean invalid RIL responses
2343
2344                Rlog.w(LOG_TAG, rr.serialString() + "< "
2345                        + requestToString(rr.mRequest)
2346                        + " exception, possible invalid RIL response", tr);
2347
2348                if (rr.mResult != null) {
2349                    AsyncResult.forMessage(rr.mResult, null, tr);
2350                    rr.mResult.sendToTarget();
2351                }
2352                rr.release();
2353                return;
2354            }
2355        }
2356
2357        // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789.
2358        // This is needed otherwise we don't automatically transition to the main lock
2359        // screen when the pin or puk is entered incorrectly.
2360        switch (rr.mRequest) {
2361            case RIL_REQUEST_ENTER_SIM_PUK:
2362            case RIL_REQUEST_ENTER_SIM_PUK2:
2363                if (mIccStatusChangedRegistrants != null) {
2364                    if (RILJ_LOGD) {
2365                        riljLog("ON enter sim puk fakeSimStatusChanged: reg count="
2366                                + mIccStatusChangedRegistrants.size());
2367                    }
2368                    mIccStatusChangedRegistrants.notifyRegistrants();
2369                }
2370                break;
2371        }
2372
2373        if (error != 0) {
2374            switch (rr.mRequest) {
2375                case RIL_REQUEST_ENTER_SIM_PIN:
2376                case RIL_REQUEST_ENTER_SIM_PIN2:
2377                case RIL_REQUEST_CHANGE_SIM_PIN:
2378                case RIL_REQUEST_CHANGE_SIM_PIN2:
2379                case RIL_REQUEST_SET_FACILITY_LOCK:
2380                    if (mIccStatusChangedRegistrants != null) {
2381                        if (RILJ_LOGD) {
2382                            riljLog("ON some errors fakeSimStatusChanged: reg count="
2383                                    + mIccStatusChangedRegistrants.size());
2384                        }
2385                        mIccStatusChangedRegistrants.notifyRegistrants();
2386                    }
2387                    break;
2388            }
2389
2390            rr.onError(error, ret);
2391            rr.release();
2392            return;
2393        }
2394
2395        if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
2396            + " " + retToString(rr.mRequest, ret));
2397
2398        if (rr.mResult != null) {
2399            AsyncResult.forMessage(rr.mResult, ret, null);
2400            rr.mResult.sendToTarget();
2401        }
2402
2403        rr.release();
2404    }
2405
2406    private String
2407    retToString(int req, Object ret) {
2408        if (ret == null) return "";
2409        switch (req) {
2410            // Don't log these return values, for privacy's sake.
2411            case RIL_REQUEST_GET_IMSI:
2412            case RIL_REQUEST_GET_IMEI:
2413            case RIL_REQUEST_GET_IMEISV:
2414                if (!RILJ_LOGV) {
2415                    // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
2416                    return "";
2417                }
2418        }
2419
2420        StringBuilder sb;
2421        String s;
2422        int length;
2423        if (ret instanceof int[]){
2424            int[] intArray = (int[]) ret;
2425            length = intArray.length;
2426            sb = new StringBuilder("{");
2427            if (length > 0) {
2428                int i = 0;
2429                sb.append(intArray[i++]);
2430                while ( i < length) {
2431                    sb.append(", ").append(intArray[i++]);
2432                }
2433            }
2434            sb.append("}");
2435            s = sb.toString();
2436        } else if (ret instanceof String[]) {
2437            String[] strings = (String[]) ret;
2438            length = strings.length;
2439            sb = new StringBuilder("{");
2440            if (length > 0) {
2441                int i = 0;
2442                sb.append(strings[i++]);
2443                while ( i < length) {
2444                    sb.append(", ").append(strings[i++]);
2445                }
2446            }
2447            sb.append("}");
2448            s = sb.toString();
2449        }else if (req == RIL_REQUEST_GET_CURRENT_CALLS) {
2450            ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret;
2451            sb = new StringBuilder(" ");
2452            for (DriverCall dc : calls) {
2453                sb.append("[").append(dc).append("] ");
2454            }
2455            s = sb.toString();
2456        } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) {
2457            ArrayList<NeighboringCellInfo> cells;
2458            cells = (ArrayList<NeighboringCellInfo>) ret;
2459            sb = new StringBuilder(" ");
2460            for (NeighboringCellInfo cell : cells) {
2461                sb.append(cell).append(" ");
2462            }
2463            s = sb.toString();
2464        } else {
2465            s = ret.toString();
2466        }
2467        return s;
2468    }
2469
2470    private void
2471    processUnsolicited (Parcel p) {
2472        int response;
2473        Object ret;
2474
2475        response = p.readInt();
2476
2477        try {switch(response) {
2478/*
2479 cat libs/telephony/ril_unsol_commands.h \
2480 | egrep "^ *{RIL_" \
2481 | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
2482*/
2483
2484            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret =  responseVoid(p); break;
2485            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret =  responseVoid(p); break;
2486            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret =  responseVoid(p); break;
2487            case RIL_UNSOL_RESPONSE_NEW_SMS: ret =  responseString(p); break;
2488            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret =  responseString(p); break;
2489            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret =  responseInts(p); break;
2490            case RIL_UNSOL_ON_USSD: ret =  responseStrings(p); break;
2491            case RIL_UNSOL_NITZ_TIME_RECEIVED: ret =  responseString(p); break;
2492            case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
2493            case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
2494            case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
2495            case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
2496            case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
2497            case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
2498            case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
2499            case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret =  responseVoid(p); break;
2500            case RIL_UNSOL_SIM_REFRESH: ret =  responseSimRefresh(p); break;
2501            case RIL_UNSOL_CALL_RING: ret =  responseCallRing(p); break;
2502            case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
2503            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:  ret =  responseVoid(p); break;
2504            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:  ret =  responseCdmaSms(p); break;
2505            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:  ret =  responseRaw(p); break;
2506            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:  ret =  responseVoid(p); break;
2507            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2508            case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
2509            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
2510            case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
2511            case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
2512            case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
2513            case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
2514            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break;
2515            case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
2516            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2517            case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
2518            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret =  responseInts(p); break;
2519
2520            default:
2521                throw new RuntimeException("Unrecognized unsol response: " + response);
2522            //break; (implied)
2523        }} catch (Throwable tr) {
2524            Rlog.e(LOG_TAG, "Exception processing unsol response: " + response +
2525                "Exception:" + tr.toString());
2526            return;
2527        }
2528
2529        switch(response) {
2530            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
2531                /* has bonus radio state int */
2532                RadioState newState = getRadioStateFromInt(p.readInt());
2533                if (RILJ_LOGD) unsljLogMore(response, newState.toString());
2534
2535                switchToRadioState(newState);
2536            break;
2537            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
2538                if (RILJ_LOGD) unsljLog(response);
2539
2540                mCallStateRegistrants
2541                    .notifyRegistrants(new AsyncResult(null, null, null));
2542            break;
2543            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
2544                if (RILJ_LOGD) unsljLog(response);
2545
2546                mVoiceNetworkStateRegistrants
2547                    .notifyRegistrants(new AsyncResult(null, null, null));
2548            break;
2549            case RIL_UNSOL_RESPONSE_NEW_SMS: {
2550                if (RILJ_LOGD) unsljLog(response);
2551
2552                // FIXME this should move up a layer
2553                String a[] = new String[2];
2554
2555                a[1] = (String)ret;
2556
2557                SmsMessage sms;
2558
2559                sms = SmsMessage.newFromCMT(a);
2560                if (mGsmSmsRegistrant != null) {
2561                    mGsmSmsRegistrant
2562                        .notifyRegistrant(new AsyncResult(null, sms, null));
2563                }
2564            break;
2565            }
2566            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
2567                if (RILJ_LOGD) unsljLogRet(response, ret);
2568
2569                if (mSmsStatusRegistrant != null) {
2570                    mSmsStatusRegistrant.notifyRegistrant(
2571                            new AsyncResult(null, ret, null));
2572                }
2573            break;
2574            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
2575                if (RILJ_LOGD) unsljLogRet(response, ret);
2576
2577                int[] smsIndex = (int[])ret;
2578
2579                if(smsIndex.length == 1) {
2580                    if (mSmsOnSimRegistrant != null) {
2581                        mSmsOnSimRegistrant.
2582                                notifyRegistrant(new AsyncResult(null, smsIndex, null));
2583                    }
2584                } else {
2585                    if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length "
2586                            + smsIndex.length);
2587                }
2588            break;
2589            case RIL_UNSOL_ON_USSD:
2590                String[] resp = (String[])ret;
2591
2592                if (resp.length < 2) {
2593                    resp = new String[2];
2594                    resp[0] = ((String[])ret)[0];
2595                    resp[1] = null;
2596                }
2597                if (RILJ_LOGD) unsljLogMore(response, resp[0]);
2598                if (mUSSDRegistrant != null) {
2599                    mUSSDRegistrant.notifyRegistrant(
2600                        new AsyncResult (null, resp, null));
2601                }
2602            break;
2603            case RIL_UNSOL_NITZ_TIME_RECEIVED:
2604                if (RILJ_LOGD) unsljLogRet(response, ret);
2605
2606                // has bonus long containing milliseconds since boot that the NITZ
2607                // time was received
2608                long nitzReceiveTime = p.readLong();
2609
2610                Object[] result = new Object[2];
2611
2612                result[0] = ret;
2613                result[1] = Long.valueOf(nitzReceiveTime);
2614
2615                boolean ignoreNitz = SystemProperties.getBoolean(
2616                        TelephonyProperties.PROPERTY_IGNORE_NITZ, false);
2617
2618                if (ignoreNitz) {
2619                    if (RILJ_LOGD) riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED");
2620                } else {
2621                    if (mNITZTimeRegistrant != null) {
2622
2623                        mNITZTimeRegistrant
2624                            .notifyRegistrant(new AsyncResult (null, result, null));
2625                    } else {
2626                        // in case NITZ time registrant isnt registered yet
2627                        mLastNITZTimeInfo = result;
2628                    }
2629                }
2630            break;
2631
2632            case RIL_UNSOL_SIGNAL_STRENGTH:
2633                // Note this is set to "verbose" because it happens
2634                // frequently
2635                if (RILJ_LOGV) unsljLogvRet(response, ret);
2636
2637                if (mSignalStrengthRegistrant != null) {
2638                    mSignalStrengthRegistrant.notifyRegistrant(
2639                                        new AsyncResult (null, ret, null));
2640                }
2641            break;
2642            case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
2643                if (RILJ_LOGD) unsljLogRet(response, ret);
2644
2645                mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
2646            break;
2647
2648            case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
2649                if (RILJ_LOGD) unsljLogRet(response, ret);
2650
2651                if (mSsnRegistrant != null) {
2652                    mSsnRegistrant.notifyRegistrant(
2653                                        new AsyncResult (null, ret, null));
2654                }
2655                break;
2656
2657            case RIL_UNSOL_STK_SESSION_END:
2658                if (RILJ_LOGD) unsljLog(response);
2659
2660                if (mCatSessionEndRegistrant != null) {
2661                    mCatSessionEndRegistrant.notifyRegistrant(
2662                                        new AsyncResult (null, ret, null));
2663                }
2664                break;
2665
2666            case RIL_UNSOL_STK_PROACTIVE_COMMAND:
2667                if (RILJ_LOGD) unsljLogRet(response, ret);
2668
2669                if (mCatProCmdRegistrant != null) {
2670                    mCatProCmdRegistrant.notifyRegistrant(
2671                                        new AsyncResult (null, ret, null));
2672                }
2673                break;
2674
2675            case RIL_UNSOL_STK_EVENT_NOTIFY:
2676                if (RILJ_LOGD) unsljLogRet(response, ret);
2677
2678                if (mCatEventRegistrant != null) {
2679                    mCatEventRegistrant.notifyRegistrant(
2680                                        new AsyncResult (null, ret, null));
2681                }
2682                break;
2683
2684            case RIL_UNSOL_STK_CALL_SETUP:
2685                if (RILJ_LOGD) unsljLogRet(response, ret);
2686
2687                if (mCatCallSetUpRegistrant != null) {
2688                    mCatCallSetUpRegistrant.notifyRegistrant(
2689                                        new AsyncResult (null, ret, null));
2690                }
2691                break;
2692
2693            case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
2694                if (RILJ_LOGD) unsljLog(response);
2695
2696                if (mIccSmsFullRegistrant != null) {
2697                    mIccSmsFullRegistrant.notifyRegistrant();
2698                }
2699                break;
2700
2701            case RIL_UNSOL_SIM_REFRESH:
2702                if (RILJ_LOGD) unsljLogRet(response, ret);
2703
2704                if (mIccRefreshRegistrants != null) {
2705                    mIccRefreshRegistrants.notifyRegistrants(
2706                            new AsyncResult (null, ret, null));
2707                }
2708                break;
2709
2710            case RIL_UNSOL_CALL_RING:
2711                if (RILJ_LOGD) unsljLogRet(response, ret);
2712
2713                if (mRingRegistrant != null) {
2714                    mRingRegistrant.notifyRegistrant(
2715                            new AsyncResult (null, ret, null));
2716                }
2717                break;
2718
2719            case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
2720                if (RILJ_LOGD) unsljLogvRet(response, ret);
2721                if (mRestrictedStateRegistrant != null) {
2722                    mRestrictedStateRegistrant.notifyRegistrant(
2723                                        new AsyncResult (null, ret, null));
2724                }
2725                break;
2726
2727            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
2728                if (RILJ_LOGD) unsljLog(response);
2729
2730                if (mIccStatusChangedRegistrants != null) {
2731                    mIccStatusChangedRegistrants.notifyRegistrants();
2732                }
2733                break;
2734
2735            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
2736                if (RILJ_LOGD) unsljLog(response);
2737
2738                SmsMessage sms = (SmsMessage) ret;
2739
2740                if (mCdmaSmsRegistrant != null) {
2741                    mCdmaSmsRegistrant
2742                        .notifyRegistrant(new AsyncResult(null, sms, null));
2743                }
2744                break;
2745
2746            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
2747                if (RILJ_LOGD) unsljLog(response);
2748
2749                if (mGsmBroadcastSmsRegistrant != null) {
2750                    mGsmBroadcastSmsRegistrant
2751                        .notifyRegistrant(new AsyncResult(null, ret, null));
2752                }
2753                break;
2754
2755            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
2756                if (RILJ_LOGD) unsljLog(response);
2757
2758                if (mIccSmsFullRegistrant != null) {
2759                    mIccSmsFullRegistrant.notifyRegistrant();
2760                }
2761                break;
2762
2763            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
2764                if (RILJ_LOGD) unsljLog(response);
2765
2766                if (mEmergencyCallbackModeRegistrant != null) {
2767                    mEmergencyCallbackModeRegistrant.notifyRegistrant();
2768                }
2769                break;
2770
2771            case RIL_UNSOL_CDMA_CALL_WAITING:
2772                if (RILJ_LOGD) unsljLogRet(response, ret);
2773
2774                if (mCallWaitingInfoRegistrants != null) {
2775                    mCallWaitingInfoRegistrants.notifyRegistrants(
2776                                        new AsyncResult (null, ret, null));
2777                }
2778                break;
2779
2780            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
2781                if (RILJ_LOGD) unsljLogRet(response, ret);
2782
2783                if (mOtaProvisionRegistrants != null) {
2784                    mOtaProvisionRegistrants.notifyRegistrants(
2785                                        new AsyncResult (null, ret, null));
2786                }
2787                break;
2788
2789            case RIL_UNSOL_CDMA_INFO_REC:
2790                ArrayList<CdmaInformationRecords> listInfoRecs;
2791
2792                try {
2793                    listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
2794                } catch (ClassCastException e) {
2795                    Rlog.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
2796                    break;
2797                }
2798
2799                for (CdmaInformationRecords rec : listInfoRecs) {
2800                    if (RILJ_LOGD) unsljLogRet(response, rec);
2801                    notifyRegistrantsCdmaInfoRec(rec);
2802                }
2803                break;
2804
2805            case RIL_UNSOL_OEM_HOOK_RAW:
2806                if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret));
2807                if (mUnsolOemHookRawRegistrant != null) {
2808                    mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
2809                }
2810                break;
2811
2812            case RIL_UNSOL_RINGBACK_TONE:
2813                if (RILJ_LOGD) unsljLogvRet(response, ret);
2814                if (mRingbackToneRegistrants != null) {
2815                    boolean playtone = (((int[])ret)[0] == 1);
2816                    mRingbackToneRegistrants.notifyRegistrants(
2817                                        new AsyncResult (null, playtone, null));
2818                }
2819                break;
2820
2821            case RIL_UNSOL_RESEND_INCALL_MUTE:
2822                if (RILJ_LOGD) unsljLogRet(response, ret);
2823
2824                if (mResendIncallMuteRegistrants != null) {
2825                    mResendIncallMuteRegistrants.notifyRegistrants(
2826                                        new AsyncResult (null, ret, null));
2827                }
2828                break;
2829
2830            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
2831                if (RILJ_LOGD) unsljLogRet(response, ret);
2832
2833                if (mVoiceRadioTechChangedRegistrants != null) {
2834                    mVoiceRadioTechChangedRegistrants.notifyRegistrants(
2835                            new AsyncResult(null, ret, null));
2836                }
2837                break;
2838
2839            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
2840                if (RILJ_LOGD) unsljLogRet(response, ret);
2841
2842                if (mCdmaSubscriptionChangedRegistrants != null) {
2843                    mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
2844                                        new AsyncResult (null, ret, null));
2845                }
2846                break;
2847
2848            case RIL_UNSOl_CDMA_PRL_CHANGED:
2849                if (RILJ_LOGD) unsljLogRet(response, ret);
2850
2851                if (mCdmaPrlChangedRegistrants != null) {
2852                    mCdmaPrlChangedRegistrants.notifyRegistrants(
2853                                        new AsyncResult (null, ret, null));
2854                }
2855                break;
2856
2857            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
2858                if (RILJ_LOGD) unsljLogRet(response, ret);
2859
2860                if (mExitEmergencyCallbackModeRegistrants != null) {
2861                    mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
2862                                        new AsyncResult (null, null, null));
2863                }
2864                break;
2865
2866            case RIL_UNSOL_RIL_CONNECTED: {
2867                if (RILJ_LOGD) unsljLogRet(response, ret);
2868
2869                // Initial conditions
2870                setRadioPower(false, null);
2871                setPreferredNetworkType(mPreferredNetworkType, null);
2872                setCdmaSubscriptionSource(mCdmaSubscription, null);
2873                notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
2874                break;
2875            }
2876        }
2877    }
2878
2879    /**
2880     * Notifiy all registrants that the ril has connected or disconnected.
2881     *
2882     * @param rilVer is the version of the ril or -1 if disconnected.
2883     */
2884    private void notifyRegistrantsRilConnectionChanged(int rilVer) {
2885        mRilVersion = rilVer;
2886        if (mRilConnectedRegistrants != null) {
2887            mRilConnectedRegistrants.notifyRegistrants(
2888                                new AsyncResult (null, new Integer(rilVer), null));
2889        }
2890    }
2891
2892    private Object
2893    responseInts(Parcel p) {
2894        int numInts;
2895        int response[];
2896
2897        numInts = p.readInt();
2898
2899        response = new int[numInts];
2900
2901        for (int i = 0 ; i < numInts ; i++) {
2902            response[i] = p.readInt();
2903        }
2904
2905        return response;
2906    }
2907
2908
2909    private Object
2910    responseVoid(Parcel p) {
2911        return null;
2912    }
2913
2914    private Object
2915    responseCallForward(Parcel p) {
2916        int numInfos;
2917        CallForwardInfo infos[];
2918
2919        numInfos = p.readInt();
2920
2921        infos = new CallForwardInfo[numInfos];
2922
2923        for (int i = 0 ; i < numInfos ; i++) {
2924            infos[i] = new CallForwardInfo();
2925
2926            infos[i].status = p.readInt();
2927            infos[i].reason = p.readInt();
2928            infos[i].serviceClass = p.readInt();
2929            infos[i].toa = p.readInt();
2930            infos[i].number = p.readString();
2931            infos[i].timeSeconds = p.readInt();
2932        }
2933
2934        return infos;
2935    }
2936
2937    private Object
2938    responseSuppServiceNotification(Parcel p) {
2939        SuppServiceNotification notification = new SuppServiceNotification();
2940
2941        notification.notificationType = p.readInt();
2942        notification.code = p.readInt();
2943        notification.index = p.readInt();
2944        notification.type = p.readInt();
2945        notification.number = p.readString();
2946
2947        return notification;
2948    }
2949
2950    private Object
2951    responseCdmaSms(Parcel p) {
2952        SmsMessage sms;
2953        sms = SmsMessage.newFromParcel(p);
2954
2955        return sms;
2956    }
2957
2958    private Object
2959    responseString(Parcel p) {
2960        String response;
2961
2962        response = p.readString();
2963
2964        return response;
2965    }
2966
2967    private Object
2968    responseStrings(Parcel p) {
2969        int num;
2970        String response[];
2971
2972        response = p.readStringArray();
2973
2974        if (false) {
2975            num = p.readInt();
2976
2977            response = new String[num];
2978            for (int i = 0; i < num; i++) {
2979                response[i] = p.readString();
2980            }
2981        }
2982
2983        return response;
2984    }
2985
2986    private Object
2987    responseRaw(Parcel p) {
2988        int num;
2989        byte response[];
2990
2991        response = p.createByteArray();
2992
2993        return response;
2994    }
2995
2996    private Object
2997    responseSMS(Parcel p) {
2998        int messageRef, errorCode;
2999        String ackPDU;
3000
3001        messageRef = p.readInt();
3002        ackPDU = p.readString();
3003        errorCode = p.readInt();
3004
3005        SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode);
3006
3007        return response;
3008    }
3009
3010
3011    private Object
3012    responseICC_IO(Parcel p) {
3013        int sw1, sw2;
3014        byte data[] = null;
3015        Message ret;
3016
3017        sw1 = p.readInt();
3018        sw2 = p.readInt();
3019
3020        String s = p.readString();
3021
3022        if (RILJ_LOGV) riljLog("< iccIO: "
3023                + " 0x" + Integer.toHexString(sw1)
3024                + " 0x" + Integer.toHexString(sw2) + " "
3025                + s);
3026
3027        return new IccIoResult(sw1, sw2, s);
3028    }
3029
3030    private Object
3031    responseIccCardStatus(Parcel p) {
3032        IccCardApplicationStatus appStatus;
3033
3034        IccCardStatus cardStatus = new IccCardStatus();
3035        cardStatus.setCardState(p.readInt());
3036        cardStatus.setUniversalPinState(p.readInt());
3037        cardStatus.mGsmUmtsSubscriptionAppIndex = p.readInt();
3038        cardStatus.mCdmaSubscriptionAppIndex = p.readInt();
3039        cardStatus.mImsSubscriptionAppIndex = p.readInt();
3040        int numApplications = p.readInt();
3041
3042        // limit to maximum allowed applications
3043        if (numApplications > IccCardStatus.CARD_MAX_APPS) {
3044            numApplications = IccCardStatus.CARD_MAX_APPS;
3045        }
3046        cardStatus.mApplications = new IccCardApplicationStatus[numApplications];
3047        for (int i = 0 ; i < numApplications ; i++) {
3048            appStatus = new IccCardApplicationStatus();
3049            appStatus.app_type       = appStatus.AppTypeFromRILInt(p.readInt());
3050            appStatus.app_state      = appStatus.AppStateFromRILInt(p.readInt());
3051            appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(p.readInt());
3052            appStatus.aid            = p.readString();
3053            appStatus.app_label      = p.readString();
3054            appStatus.pin1_replaced  = p.readInt();
3055            appStatus.pin1           = appStatus.PinStateFromRILInt(p.readInt());
3056            appStatus.pin2           = appStatus.PinStateFromRILInt(p.readInt());
3057            cardStatus.mApplications[i] = appStatus;
3058        }
3059        return cardStatus;
3060    }
3061
3062    private Object
3063    responseSimRefresh(Parcel p) {
3064        IccRefreshResponse response = new IccRefreshResponse();
3065
3066        response.refreshResult = p.readInt();
3067        response.efId   = p.readInt();
3068        response.aid = p.readString();
3069        return response;
3070    }
3071
3072    private Object
3073    responseCallList(Parcel p) {
3074        int num;
3075        int voiceSettings;
3076        ArrayList<DriverCall> response;
3077        DriverCall dc;
3078
3079        num = p.readInt();
3080        response = new ArrayList<DriverCall>(num);
3081
3082        if (RILJ_LOGV) {
3083            riljLog("responseCallList: num=" + num +
3084                    " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant +
3085                    " mTestingEmergencyCall=" + mTestingEmergencyCall.get());
3086        }
3087        for (int i = 0 ; i < num ; i++) {
3088            dc = new DriverCall();
3089
3090            dc.state = DriverCall.stateFromCLCC(p.readInt());
3091            dc.index = p.readInt();
3092            dc.TOA = p.readInt();
3093            dc.isMpty = (0 != p.readInt());
3094            dc.isMT = (0 != p.readInt());
3095            dc.als = p.readInt();
3096            voiceSettings = p.readInt();
3097            dc.isVoice = (0 == voiceSettings) ? false : true;
3098            dc.isVoicePrivacy = (0 != p.readInt());
3099            dc.number = p.readString();
3100            int np = p.readInt();
3101            dc.numberPresentation = DriverCall.presentationFromCLIP(np);
3102            dc.name = p.readString();
3103            dc.namePresentation = p.readInt();
3104            int uusInfoPresent = p.readInt();
3105            if (uusInfoPresent == 1) {
3106                dc.uusInfo = new UUSInfo();
3107                dc.uusInfo.setType(p.readInt());
3108                dc.uusInfo.setDcs(p.readInt());
3109                byte[] userData = p.createByteArray();
3110                dc.uusInfo.setUserData(userData);
3111                riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
3112                                dc.uusInfo.getType(), dc.uusInfo.getDcs(),
3113                                dc.uusInfo.getUserData().length));
3114                riljLogv("Incoming UUS : data (string)="
3115                        + new String(dc.uusInfo.getUserData()));
3116                riljLogv("Incoming UUS : data (hex): "
3117                        + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
3118            } else {
3119                riljLogv("Incoming UUS : NOT present!");
3120            }
3121
3122            // Make sure there's a leading + on addresses with a TOA of 145
3123            dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
3124
3125            response.add(dc);
3126
3127            if (dc.isVoicePrivacy) {
3128                mVoicePrivacyOnRegistrants.notifyRegistrants();
3129                riljLog("InCall VoicePrivacy is enabled");
3130            } else {
3131                mVoicePrivacyOffRegistrants.notifyRegistrants();
3132                riljLog("InCall VoicePrivacy is disabled");
3133            }
3134        }
3135
3136        Collections.sort(response);
3137
3138        if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) {
3139            if (mEmergencyCallbackModeRegistrant != null) {
3140                riljLog("responseCallList: call ended, testing emergency call," +
3141                            " notify ECM Registrants");
3142                mEmergencyCallbackModeRegistrant.notifyRegistrant();
3143            }
3144        }
3145
3146        return response;
3147    }
3148
3149    private DataCallState getDataCallState(Parcel p, int version) {
3150        DataCallState dataCall = new DataCallState();
3151
3152        dataCall.version = version;
3153        if (version < 5) {
3154            dataCall.cid = p.readInt();
3155            dataCall.active = p.readInt();
3156            dataCall.type = p.readString();
3157            String addresses = p.readString();
3158            if (!TextUtils.isEmpty(addresses)) {
3159                dataCall.addresses = addresses.split(" ");
3160            }
3161        } else {
3162            dataCall.status = p.readInt();
3163            dataCall.suggestedRetryTime = p.readInt();
3164            dataCall.cid = p.readInt();
3165            dataCall.active = p.readInt();
3166            dataCall.type = p.readString();
3167            dataCall.ifname = p.readString();
3168            if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) &&
3169                    TextUtils.isEmpty(dataCall.ifname)) {
3170              throw new RuntimeException("getDataCallState, no ifname");
3171            }
3172            String addresses = p.readString();
3173            if (!TextUtils.isEmpty(addresses)) {
3174                dataCall.addresses = addresses.split(" ");
3175            }
3176            String dnses = p.readString();
3177            if (!TextUtils.isEmpty(dnses)) {
3178                dataCall.dnses = dnses.split(" ");
3179            }
3180            String gateways = p.readString();
3181            if (!TextUtils.isEmpty(gateways)) {
3182                dataCall.gateways = gateways.split(" ");
3183            }
3184        }
3185        return dataCall;
3186    }
3187
3188    private Object
3189    responseDataCallList(Parcel p) {
3190        ArrayList<DataCallState> response;
3191
3192        int ver = p.readInt();
3193        int num = p.readInt();
3194        riljLog("responseDataCallList ver=" + ver + " num=" + num);
3195
3196        response = new ArrayList<DataCallState>(num);
3197        for (int i = 0; i < num; i++) {
3198            response.add(getDataCallState(p, ver));
3199        }
3200
3201        return response;
3202    }
3203
3204    private Object
3205    responseSetupDataCall(Parcel p) {
3206        int ver = p.readInt();
3207        int num = p.readInt();
3208        if (RILJ_LOGV) riljLog("responseSetupDataCall ver=" + ver + " num=" + num);
3209
3210        DataCallState dataCall;
3211
3212        if (ver < 5) {
3213            dataCall = new DataCallState();
3214            dataCall.version = ver;
3215            dataCall.cid = Integer.parseInt(p.readString());
3216            dataCall.ifname = p.readString();
3217            if (TextUtils.isEmpty(dataCall.ifname)) {
3218                throw new RuntimeException(
3219                        "RIL_REQUEST_SETUP_DATA_CALL response, no ifname");
3220            }
3221            String addresses = p.readString();
3222            if (!TextUtils.isEmpty(addresses)) {
3223              dataCall.addresses = addresses.split(" ");
3224            }
3225            if (num >= 4) {
3226                String dnses = p.readString();
3227                if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses);
3228                if (!TextUtils.isEmpty(dnses)) {
3229                    dataCall.dnses = dnses.split(" ");
3230                }
3231            }
3232            if (num >= 5) {
3233                String gateways = p.readString();
3234                if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways);
3235                if (!TextUtils.isEmpty(gateways)) {
3236                    dataCall.gateways = gateways.split(" ");
3237                }
3238            }
3239        } else {
3240            if (num != 1) {
3241                throw new RuntimeException(
3242                        "RIL_REQUEST_SETUP_DATA_CALL response expecting 1 RIL_Data_Call_response_v5"
3243                        + " got " + num);
3244            }
3245            dataCall = getDataCallState(p, ver);
3246        }
3247
3248        return dataCall;
3249    }
3250
3251    private Object
3252    responseOperatorInfos(Parcel p) {
3253        String strings[] = (String [])responseStrings(p);
3254        ArrayList<OperatorInfo> ret;
3255
3256        if (strings.length % 4 != 0) {
3257            throw new RuntimeException(
3258                "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
3259                + strings.length + " strings, expected multible of 4");
3260        }
3261
3262        ret = new ArrayList<OperatorInfo>(strings.length / 4);
3263
3264        for (int i = 0 ; i < strings.length ; i += 4) {
3265            ret.add (
3266                new OperatorInfo(
3267                    strings[i+0],
3268                    strings[i+1],
3269                    strings[i+2],
3270                    strings[i+3]));
3271        }
3272
3273        return ret;
3274    }
3275
3276    private Object
3277    responseCellList(Parcel p) {
3278       int num, rssi;
3279       String location;
3280       ArrayList<NeighboringCellInfo> response;
3281       NeighboringCellInfo cell;
3282
3283       num = p.readInt();
3284       response = new ArrayList<NeighboringCellInfo>();
3285
3286       // Determine the radio access type
3287       String radioString = SystemProperties.get(
3288               TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, "unknown");
3289       int radioType;
3290       if (radioString.equals("GPRS")) {
3291           radioType = NETWORK_TYPE_GPRS;
3292       } else if (radioString.equals("EDGE")) {
3293           radioType = NETWORK_TYPE_EDGE;
3294       } else if (radioString.equals("UMTS")) {
3295           radioType = NETWORK_TYPE_UMTS;
3296       } else if (radioString.equals("HSDPA")) {
3297           radioType = NETWORK_TYPE_HSDPA;
3298       } else if (radioString.equals("HSUPA")) {
3299           radioType = NETWORK_TYPE_HSUPA;
3300       } else if (radioString.equals("HSPA")) {
3301           radioType = NETWORK_TYPE_HSPA;
3302       } else {
3303           radioType = NETWORK_TYPE_UNKNOWN;
3304       }
3305
3306       // Interpret the location based on radio access type
3307       if (radioType != NETWORK_TYPE_UNKNOWN) {
3308           for (int i = 0 ; i < num ; i++) {
3309               rssi = p.readInt();
3310               location = p.readString();
3311               cell = new NeighboringCellInfo(rssi, location, radioType);
3312               response.add(cell);
3313           }
3314       }
3315       return response;
3316    }
3317
3318    private Object responseGetPreferredNetworkType(Parcel p) {
3319       int [] response = (int[]) responseInts(p);
3320
3321       if (response.length >= 1) {
3322           // Since this is the response for getPreferredNetworkType
3323           // we'll assume that it should be the value we want the
3324           // vendor ril to take if we reestablish a connection to it.
3325           mPreferredNetworkType = response[0];
3326       }
3327       return response;
3328    }
3329
3330    private Object responseGmsBroadcastConfig(Parcel p) {
3331        int num;
3332        ArrayList<SmsBroadcastConfigInfo> response;
3333        SmsBroadcastConfigInfo info;
3334
3335        num = p.readInt();
3336        response = new ArrayList<SmsBroadcastConfigInfo>(num);
3337
3338        for (int i = 0; i < num; i++) {
3339            int fromId = p.readInt();
3340            int toId = p.readInt();
3341            int fromScheme = p.readInt();
3342            int toScheme = p.readInt();
3343            boolean selected = (p.readInt() == 1);
3344
3345            info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme,
3346                    toScheme, selected);
3347            response.add(info);
3348        }
3349        return response;
3350    }
3351
3352    private Object
3353    responseCdmaBroadcastConfig(Parcel p) {
3354        int numServiceCategories;
3355        int response[];
3356
3357        numServiceCategories = p.readInt();
3358
3359        if (numServiceCategories == 0) {
3360            // TODO: The logic of providing default values should
3361            // not be done by this transport layer. And needs to
3362            // be done by the vendor ril or application logic.
3363            int numInts;
3364            numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
3365            response = new int[numInts];
3366
3367            // Faking a default record for all possible records.
3368            response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
3369
3370            // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
3371            // default language and selection status to false for all.
3372            for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) {
3373                response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT;
3374                response[i + 1] = 1;
3375                response[i + 2] = 0;
3376            }
3377        } else {
3378            int numInts;
3379            numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
3380            response = new int[numInts];
3381
3382            response[0] = numServiceCategories;
3383            for (int i = 1 ; i < numInts; i++) {
3384                 response[i] = p.readInt();
3385             }
3386        }
3387
3388        return response;
3389    }
3390
3391    private Object
3392    responseSignalStrength(Parcel p) {
3393        SignalStrength signalStrength = new SignalStrength(p);
3394        return signalStrength;
3395    }
3396
3397    private ArrayList<CdmaInformationRecords>
3398    responseCdmaInformationRecord(Parcel p) {
3399        int numberOfInfoRecs;
3400        ArrayList<CdmaInformationRecords> response;
3401
3402        /**
3403         * Loop through all of the information records unmarshalling them
3404         * and converting them to Java Objects.
3405         */
3406        numberOfInfoRecs = p.readInt();
3407        response = new ArrayList<CdmaInformationRecords>(numberOfInfoRecs);
3408
3409        for (int i = 0; i < numberOfInfoRecs; i++) {
3410            CdmaInformationRecords InfoRec = new CdmaInformationRecords(p);
3411            response.add(InfoRec);
3412        }
3413
3414        return response;
3415    }
3416
3417    private Object
3418    responseCdmaCallWaiting(Parcel p) {
3419        CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
3420
3421        notification.number = p.readString();
3422        notification.numberPresentation = notification.presentationFromCLIP(p.readInt());
3423        notification.name = p.readString();
3424        notification.namePresentation = notification.numberPresentation;
3425        notification.isPresent = p.readInt();
3426        notification.signalType = p.readInt();
3427        notification.alertPitch = p.readInt();
3428        notification.signal = p.readInt();
3429        notification.numberType = p.readInt();
3430        notification.numberPlan = p.readInt();
3431
3432        return notification;
3433    }
3434
3435    private Object
3436    responseCallRing(Parcel p){
3437        char response[] = new char[4];
3438
3439        response[0] = (char) p.readInt();    // isPresent
3440        response[1] = (char) p.readInt();    // signalType
3441        response[2] = (char) p.readInt();    // alertPitch
3442        response[3] = (char) p.readInt();    // signal
3443
3444        return response;
3445    }
3446
3447    private void
3448    notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
3449        int response = RIL_UNSOL_CDMA_INFO_REC;
3450        if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
3451            if (mDisplayInfoRegistrants != null) {
3452                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3453                mDisplayInfoRegistrants.notifyRegistrants(
3454                        new AsyncResult (null, infoRec.record, null));
3455            }
3456        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
3457            if (mSignalInfoRegistrants != null) {
3458                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3459                mSignalInfoRegistrants.notifyRegistrants(
3460                        new AsyncResult (null, infoRec.record, null));
3461            }
3462        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
3463            if (mNumberInfoRegistrants != null) {
3464                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3465                mNumberInfoRegistrants.notifyRegistrants(
3466                        new AsyncResult (null, infoRec.record, null));
3467            }
3468        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
3469            if (mRedirNumInfoRegistrants != null) {
3470                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3471                mRedirNumInfoRegistrants.notifyRegistrants(
3472                        new AsyncResult (null, infoRec.record, null));
3473            }
3474        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
3475            if (mLineControlInfoRegistrants != null) {
3476                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3477                mLineControlInfoRegistrants.notifyRegistrants(
3478                        new AsyncResult (null, infoRec.record, null));
3479            }
3480        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
3481            if (mT53ClirInfoRegistrants != null) {
3482                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3483                mT53ClirInfoRegistrants.notifyRegistrants(
3484                        new AsyncResult (null, infoRec.record, null));
3485            }
3486        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
3487            if (mT53AudCntrlInfoRegistrants != null) {
3488               if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3489               mT53AudCntrlInfoRegistrants.notifyRegistrants(
3490                       new AsyncResult (null, infoRec.record, null));
3491            }
3492        }
3493    }
3494
3495    static String
3496    requestToString(int request) {
3497/*
3498 cat libs/telephony/ril_commands.h \
3499 | egrep "^ *{RIL_" \
3500 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3501*/
3502        switch(request) {
3503            case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
3504            case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
3505            case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
3506            case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
3507            case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
3508            case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
3509            case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
3510            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
3511            case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
3512            case RIL_REQUEST_DIAL: return "DIAL";
3513            case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
3514            case RIL_REQUEST_HANGUP: return "HANGUP";
3515            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
3516            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
3517            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
3518            case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
3519            case RIL_REQUEST_UDUB: return "UDUB";
3520            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
3521            case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
3522            case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
3523            case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
3524            case RIL_REQUEST_OPERATOR: return "OPERATOR";
3525            case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
3526            case RIL_REQUEST_DTMF: return "DTMF";
3527            case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
3528            case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
3529            case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
3530            case RIL_REQUEST_SIM_IO: return "SIM_IO";
3531            case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
3532            case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
3533            case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
3534            case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
3535            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
3536            case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
3537            case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
3538            case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
3539            case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
3540            case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
3541            case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
3542            case RIL_REQUEST_ANSWER: return "ANSWER";
3543            case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
3544            case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
3545            case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
3546            case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
3547            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
3548            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
3549            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
3550            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
3551            case RIL_REQUEST_DTMF_START: return "DTMF_START";
3552            case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
3553            case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
3554            case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
3555            case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
3556            case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
3557            case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
3558            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
3559            case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
3560            case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
3561            case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
3562            case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
3563            case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
3564            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION";
3565            case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
3566            case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM";
3567            case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
3568            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
3569            case RIL_REQUEST_STK_GET_PROFILE: return "REQUEST_STK_GET_PROFILE";
3570            case RIL_REQUEST_STK_SET_PROFILE: return "REQUEST_STK_SET_PROFILE";
3571            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "REQUEST_STK_SEND_ENVELOPE_COMMAND";
3572            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "REQUEST_STK_SEND_TERMINAL_RESPONSE";
3573            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
3574            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER";
3575            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "REQUEST_SET_PREFERRED_NETWORK_TYPE";
3576            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
3577            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS";
3578            case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES";
3579            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
3580            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
3581            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
3582            case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE";
3583            case RIL_REQUEST_QUERY_TTY_MODE: return "RIL_REQUEST_QUERY_TTY_MODE";
3584            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
3585            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
3586            case RIL_REQUEST_CDMA_FLASH: return "RIL_REQUEST_CDMA_FLASH";
3587            case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF";
3588            case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS";
3589            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
3590            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
3591            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
3592            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
3593            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
3594            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
3595            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
3596            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
3597            case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
3598            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
3599            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
3600            case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY";
3601            case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS";
3602            case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS";
3603            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
3604            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
3605            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
3606            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
3607            case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION";
3608            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
3609            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
3610            case RIL_REQUEST_VOICE_RADIO_TECH: return "RIL_REQUEST_VOICE_RADIO_TECH";
3611            default: return "<unknown request>";
3612        }
3613    }
3614
3615    static String
3616    responseToString(int request)
3617    {
3618/*
3619 cat libs/telephony/ril_unsol_commands.h \
3620 | egrep "^ *{RIL_" \
3621 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3622*/
3623        switch(request) {
3624            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
3625            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
3626            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
3627            case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
3628            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
3629            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
3630            case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
3631            case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST";
3632            case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
3633            case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
3634            case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
3635            case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
3636            case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
3637            case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
3638            case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
3639            case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
3640            case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL";
3641            case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
3642            case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
3643            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
3644            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS";
3645            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
3646            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
3647            case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
3648            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
3649            case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
3650            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
3651            case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
3652            case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
3653            case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
3654            case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
3655            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "CDMA_SUBSCRIPTION_SOURCE_CHANGED";
3656            case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
3657            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
3658            case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
3659            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
3660            default: return "<unknown reponse>";
3661        }
3662    }
3663
3664    private void riljLog(String msg) {
3665        Rlog.d(LOG_TAG, msg);
3666    }
3667
3668    private void riljLogv(String msg) {
3669        Rlog.v(LOG_TAG, msg);
3670    }
3671
3672    private void unsljLog(int response) {
3673        riljLog("[UNSL]< " + responseToString(response));
3674    }
3675
3676    private void unsljLogMore(int response, String more) {
3677        riljLog("[UNSL]< " + responseToString(response) + " " + more);
3678    }
3679
3680    private void unsljLogRet(int response, Object ret) {
3681        riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
3682    }
3683
3684    private void unsljLogvRet(int response, Object ret) {
3685        riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
3686    }
3687
3688
3689    // ***** Methods for CDMA support
3690    public void
3691    getDeviceIdentity(Message response) {
3692        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DEVICE_IDENTITY, response);
3693
3694        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3695
3696        send(rr);
3697    }
3698
3699    public void
3700    getCDMASubscription(Message response) {
3701        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SUBSCRIPTION, response);
3702
3703        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3704
3705        send(rr);
3706    }
3707
3708    @Override
3709    public void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructor
3710        if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
3711        mPhoneType = phoneType;
3712    }
3713
3714    /**
3715     * {@inheritDoc}
3716     */
3717    public void queryCdmaRoamingPreference(Message response) {
3718        RILRequest rr = RILRequest.obtain(
3719                RILConstants.RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, response);
3720
3721        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3722
3723        send(rr);
3724    }
3725
3726    /**
3727     * {@inheritDoc}
3728     */
3729    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
3730        RILRequest rr = RILRequest.obtain(
3731                RILConstants.RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, response);
3732
3733        rr.mp.writeInt(1);
3734        rr.mp.writeInt(cdmaRoamingType);
3735
3736        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3737                + " : " + cdmaRoamingType);
3738
3739        send(rr);
3740    }
3741
3742    /**
3743     * {@inheritDoc}
3744     */
3745    public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
3746        RILRequest rr = RILRequest.obtain(
3747                RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response);
3748
3749        rr.mp.writeInt(1);
3750        rr.mp.writeInt(cdmaSubscription);
3751
3752        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3753                + " : " + cdmaSubscription);
3754
3755        send(rr);
3756    }
3757
3758    /**
3759     * {@inheritDoc}
3760     */
3761    @Override
3762    public void getCdmaSubscriptionSource(Message response) {
3763        RILRequest rr = RILRequest.obtain(
3764                RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response);
3765
3766        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3767
3768        send(rr);
3769    }
3770
3771    /**
3772     * {@inheritDoc}
3773     */
3774    public void queryTTYMode(Message response) {
3775        RILRequest rr = RILRequest.obtain(
3776                RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
3777
3778        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3779
3780        send(rr);
3781    }
3782
3783    /**
3784     * {@inheritDoc}
3785     */
3786    public void setTTYMode(int ttyMode, Message response) {
3787        RILRequest rr = RILRequest.obtain(
3788                RILConstants.RIL_REQUEST_SET_TTY_MODE, response);
3789
3790        rr.mp.writeInt(1);
3791        rr.mp.writeInt(ttyMode);
3792
3793        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3794                + " : " + ttyMode);
3795
3796        send(rr);
3797    }
3798
3799    /**
3800     * {@inheritDoc}
3801     */
3802    public void
3803    sendCDMAFeatureCode(String FeatureCode, Message response) {
3804        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response);
3805
3806        rr.mp.writeString(FeatureCode);
3807
3808        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3809                + " : " + FeatureCode);
3810
3811        send(rr);
3812    }
3813
3814    public void getCdmaBroadcastConfig(Message response) {
3815        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, response);
3816
3817        send(rr);
3818    }
3819
3820    // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
3821    public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
3822        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response);
3823
3824        for(int i = 0; i < configValuesArray.length; i++) {
3825            rr.mp.writeInt(configValuesArray[i]);
3826        }
3827
3828        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3829
3830        send(rr);
3831    }
3832
3833    public void setCdmaBroadcastActivation(boolean activate, Message response) {
3834        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response);
3835
3836        rr.mp.writeInt(1);
3837        rr.mp.writeInt(activate ? 0 :1);
3838
3839        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3840
3841        send(rr);
3842    }
3843
3844    /**
3845     * {@inheritDoc}
3846     */
3847    public void exitEmergencyCallbackMode(Message response) {
3848        RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response);
3849
3850        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3851
3852        send(rr);
3853    }
3854
3855    public void requestIsimAuthentication(String nonce, Message response) {
3856        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ISIM_AUTHENTICATION, response);
3857
3858        rr.mp.writeString(nonce);
3859
3860        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3861
3862        send(rr);
3863    }
3864
3865    /* (non-Javadoc)
3866     * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
3867     */
3868    @Override
3869    public void testingEmergencyCall() {
3870        if (RILJ_LOGD) riljLog("testingEmergencyCall");
3871        mTestingEmergencyCall.set(true);
3872    }
3873
3874    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
3875        pw.println("RIL:");
3876        pw.println(" mSocket=" + mSocket);
3877        pw.println(" mSenderThread=" + mSenderThread);
3878        pw.println(" mSender=" + mSender);
3879        pw.println(" mReceiverThread=" + mReceiverThread);
3880        pw.println(" mReceiver=" + mReceiver);
3881        pw.println(" mWakeLock=" + mWakeLock);
3882        pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
3883        synchronized (mRequestsList) {
3884          pw.println(" mRequestMessagesPending=" + mRequestMessagesPending);
3885          pw.println(" mRequestMessagesWaiting=" + mRequestMessagesWaiting);
3886            int count = mRequestsList.size();
3887            pw.println(" mRequestList count=" + count);
3888            for (int i = 0; i < count; i++) {
3889                RILRequest rr = mRequestsList.get(i);
3890                pw.println("  [" + rr.mSerial + "] " + requestToString(rr.mRequest));
3891            }
3892        }
3893        pw.println(" mLastNITZTimeInfo=" + mLastNITZTimeInfo);
3894        pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get());
3895    }
3896}
3897