RIL.java revision cf57b29a755b0249da687201bcc726941d37d42b
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> mRequestList = 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 (mRequestList) {
324                            mRequestList.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 (mRequestList) {
407                                        int count = mRequestList.size();
408                                        Rlog.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
409                                                " mRequestList=" + count);
410
411                                        for (int i = 0; i < count; i++) {
412                                            rr = mRequestList.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                clearRequestList(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        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2058        sendScreenState(pm.isScreenOn());
2059   }
2060
2061    private RadioState getRadioStateFromInt(int stateInt) {
2062        RadioState state;
2063
2064        /* RIL_RadioState ril.h */
2065        switch(stateInt) {
2066            case 0: state = RadioState.RADIO_OFF; break;
2067            case 1: state = RadioState.RADIO_UNAVAILABLE; break;
2068            case 10: state = RadioState.RADIO_ON; break;
2069
2070            default:
2071                throw new RuntimeException(
2072                            "Unrecognized RIL_RadioState: " + stateInt);
2073        }
2074        return state;
2075    }
2076
2077    private void switchToRadioState(RadioState newState) {
2078        setRadioState(newState);
2079    }
2080
2081    /**
2082     * Holds a PARTIAL_WAKE_LOCK whenever
2083     * a) There is outstanding RIL request sent to RIL deamon and no replied
2084     * b) There is a request pending to be sent out.
2085     *
2086     * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
2087     * happen often.
2088     */
2089
2090    private void
2091    acquireWakeLock() {
2092        synchronized (mWakeLock) {
2093            mWakeLock.acquire();
2094            mRequestMessagesPending++;
2095
2096            mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
2097            Message msg = mSender.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
2098            mSender.sendMessageDelayed(msg, mWakeLockTimeout);
2099        }
2100    }
2101
2102    private void
2103    releaseWakeLockIfDone() {
2104        synchronized (mWakeLock) {
2105            if (mWakeLock.isHeld() &&
2106                (mRequestMessagesPending == 0) &&
2107                (mRequestMessagesWaiting == 0)) {
2108                mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
2109                mWakeLock.release();
2110            }
2111        }
2112    }
2113
2114    private void
2115    send(RILRequest rr) {
2116        Message msg;
2117
2118        if (mSocket == null) {
2119            rr.onError(RADIO_NOT_AVAILABLE, null);
2120            rr.release();
2121            return;
2122        }
2123
2124        msg = mSender.obtainMessage(EVENT_SEND, rr);
2125
2126        acquireWakeLock();
2127
2128        msg.sendToTarget();
2129    }
2130
2131    private void
2132    processResponse (Parcel p) {
2133        int type;
2134
2135        type = p.readInt();
2136
2137        if (type == RESPONSE_UNSOLICITED) {
2138            processUnsolicited (p);
2139        } else if (type == RESPONSE_SOLICITED) {
2140            processSolicited (p);
2141        }
2142
2143        releaseWakeLockIfDone();
2144    }
2145
2146    /**
2147     * Release each request in mRequestList then clear the list
2148     * @param error is the RIL_Errno sent back
2149     * @param loggable true means to print all requests in mRequestList
2150     */
2151    private void clearRequestList(int error, boolean loggable) {
2152        RILRequest rr;
2153        synchronized (mRequestList) {
2154            int count = mRequestList.size();
2155            if (RILJ_LOGD && loggable) {
2156                Rlog.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
2157                        " mReqPending=" + mRequestMessagesPending +
2158                        " mRequestList=" + count);
2159            }
2160
2161            for (int i = 0; i < count ; i++) {
2162                rr = mRequestList.get(i);
2163                if (RILJ_LOGD && loggable) {
2164                    Rlog.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
2165                            requestToString(rr.mRequest));
2166                }
2167                rr.onError(error, null);
2168                rr.release();
2169            }
2170            mRequestList.clear();
2171            mRequestMessagesWaiting = 0;
2172        }
2173    }
2174
2175    private RILRequest findAndRemoveRequestFromList(int serial) {
2176        synchronized (mRequestList) {
2177            for (int i = 0, s = mRequestList.size() ; i < s ; i++) {
2178                RILRequest rr = mRequestList.get(i);
2179
2180                if (rr.mSerial == serial) {
2181                    mRequestList.remove(i);
2182                    if (mRequestMessagesWaiting > 0)
2183                        mRequestMessagesWaiting--;
2184                    return rr;
2185                }
2186            }
2187        }
2188
2189        return null;
2190    }
2191
2192    private void
2193    processSolicited (Parcel p) {
2194        int serial, error;
2195        boolean found = false;
2196
2197        serial = p.readInt();
2198        error = p.readInt();
2199
2200        RILRequest rr;
2201
2202        rr = findAndRemoveRequestFromList(serial);
2203
2204        if (rr == null) {
2205            Rlog.w(LOG_TAG, "Unexpected solicited response! sn: "
2206                            + serial + " error: " + error);
2207            return;
2208        }
2209
2210        Object ret = null;
2211
2212        if (error == 0 || p.dataAvail() > 0) {
2213            // either command succeeds or command fails but with data payload
2214            try {switch (rr.mRequest) {
2215            /*
2216 cat libs/telephony/ril_commands.h \
2217 | egrep "^ *{RIL_" \
2218 | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
2219             */
2220            case RIL_REQUEST_GET_SIM_STATUS: ret =  responseIccCardStatus(p); break;
2221            case RIL_REQUEST_ENTER_SIM_PIN: ret =  responseInts(p); break;
2222            case RIL_REQUEST_ENTER_SIM_PUK: ret =  responseInts(p); break;
2223            case RIL_REQUEST_ENTER_SIM_PIN2: ret =  responseInts(p); break;
2224            case RIL_REQUEST_ENTER_SIM_PUK2: ret =  responseInts(p); break;
2225            case RIL_REQUEST_CHANGE_SIM_PIN: ret =  responseInts(p); break;
2226            case RIL_REQUEST_CHANGE_SIM_PIN2: ret =  responseInts(p); break;
2227            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret =  responseInts(p); break;
2228            case RIL_REQUEST_GET_CURRENT_CALLS: ret =  responseCallList(p); break;
2229            case RIL_REQUEST_DIAL: ret =  responseVoid(p); break;
2230            case RIL_REQUEST_GET_IMSI: ret =  responseString(p); break;
2231            case RIL_REQUEST_HANGUP: ret =  responseVoid(p); break;
2232            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret =  responseVoid(p); break;
2233            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: {
2234                if (mTestingEmergencyCall.getAndSet(false)) {
2235                    if (mEmergencyCallbackModeRegistrant != null) {
2236                        riljLog("testing emergency call, notify ECM Registrants");
2237                        mEmergencyCallbackModeRegistrant.notifyRegistrant();
2238                    }
2239                }
2240                ret =  responseVoid(p);
2241                break;
2242            }
2243            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret =  responseVoid(p); break;
2244            case RIL_REQUEST_CONFERENCE: ret =  responseVoid(p); break;
2245            case RIL_REQUEST_UDUB: ret =  responseVoid(p); break;
2246            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret =  responseInts(p); break;
2247            case RIL_REQUEST_SIGNAL_STRENGTH: ret =  responseSignalStrength(p); break;
2248            case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret =  responseStrings(p); break;
2249            case RIL_REQUEST_DATA_REGISTRATION_STATE: ret =  responseStrings(p); break;
2250            case RIL_REQUEST_OPERATOR: ret =  responseStrings(p); break;
2251            case RIL_REQUEST_RADIO_POWER: ret =  responseVoid(p); break;
2252            case RIL_REQUEST_DTMF: ret =  responseVoid(p); break;
2253            case RIL_REQUEST_SEND_SMS: ret =  responseSMS(p); break;
2254            case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret =  responseSMS(p); break;
2255            case RIL_REQUEST_SETUP_DATA_CALL: ret =  responseSetupDataCall(p); break;
2256            case RIL_REQUEST_SIM_IO: ret =  responseICC_IO(p); break;
2257            case RIL_REQUEST_SEND_USSD: ret =  responseVoid(p); break;
2258            case RIL_REQUEST_CANCEL_USSD: ret =  responseVoid(p); break;
2259            case RIL_REQUEST_GET_CLIR: ret =  responseInts(p); break;
2260            case RIL_REQUEST_SET_CLIR: ret =  responseVoid(p); break;
2261            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret =  responseCallForward(p); break;
2262            case RIL_REQUEST_SET_CALL_FORWARD: ret =  responseVoid(p); break;
2263            case RIL_REQUEST_QUERY_CALL_WAITING: ret =  responseInts(p); break;
2264            case RIL_REQUEST_SET_CALL_WAITING: ret =  responseVoid(p); break;
2265            case RIL_REQUEST_SMS_ACKNOWLEDGE: ret =  responseVoid(p); break;
2266            case RIL_REQUEST_GET_IMEI: ret =  responseString(p); break;
2267            case RIL_REQUEST_GET_IMEISV: ret =  responseString(p); break;
2268            case RIL_REQUEST_ANSWER: ret =  responseVoid(p); break;
2269            case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret =  responseVoid(p); break;
2270            case RIL_REQUEST_QUERY_FACILITY_LOCK: ret =  responseInts(p); break;
2271            case RIL_REQUEST_SET_FACILITY_LOCK: ret =  responseInts(p); break;
2272            case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret =  responseVoid(p); break;
2273            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret =  responseInts(p); break;
2274            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret =  responseVoid(p); break;
2275            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret =  responseVoid(p); break;
2276            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret =  responseOperatorInfos(p); break;
2277            case RIL_REQUEST_DTMF_START: ret =  responseVoid(p); break;
2278            case RIL_REQUEST_DTMF_STOP: ret =  responseVoid(p); break;
2279            case RIL_REQUEST_BASEBAND_VERSION: ret =  responseString(p); break;
2280            case RIL_REQUEST_SEPARATE_CONNECTION: ret =  responseVoid(p); break;
2281            case RIL_REQUEST_SET_MUTE: ret =  responseVoid(p); break;
2282            case RIL_REQUEST_GET_MUTE: ret =  responseInts(p); break;
2283            case RIL_REQUEST_QUERY_CLIP: ret =  responseInts(p); break;
2284            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret =  responseInts(p); break;
2285            case RIL_REQUEST_DATA_CALL_LIST: ret =  responseDataCallList(p); break;
2286            case RIL_REQUEST_RESET_RADIO: ret =  responseVoid(p); break;
2287            case RIL_REQUEST_OEM_HOOK_RAW: ret =  responseRaw(p); break;
2288            case RIL_REQUEST_OEM_HOOK_STRINGS: ret =  responseStrings(p); break;
2289            case RIL_REQUEST_SCREEN_STATE: ret =  responseVoid(p); break;
2290            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret =  responseVoid(p); break;
2291            case RIL_REQUEST_WRITE_SMS_TO_SIM: ret =  responseInts(p); break;
2292            case RIL_REQUEST_DELETE_SMS_ON_SIM: ret =  responseVoid(p); break;
2293            case RIL_REQUEST_SET_BAND_MODE: ret =  responseVoid(p); break;
2294            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret =  responseInts(p); break;
2295            case RIL_REQUEST_STK_GET_PROFILE: ret =  responseString(p); break;
2296            case RIL_REQUEST_STK_SET_PROFILE: ret =  responseVoid(p); break;
2297            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret =  responseString(p); break;
2298            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret =  responseVoid(p); break;
2299            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret =  responseInts(p); break;
2300            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret =  responseVoid(p); break;
2301            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret =  responseVoid(p); break;
2302            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret =  responseGetPreferredNetworkType(p); break;
2303            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
2304            case RIL_REQUEST_SET_LOCATION_UPDATES: ret =  responseVoid(p); break;
2305            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret =  responseVoid(p); break;
2306            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret =  responseVoid(p); break;
2307            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret =  responseInts(p); break;
2308            case RIL_REQUEST_SET_TTY_MODE: ret =  responseVoid(p); break;
2309            case RIL_REQUEST_QUERY_TTY_MODE: ret =  responseInts(p); break;
2310            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret =  responseVoid(p); break;
2311            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret =  responseInts(p); break;
2312            case RIL_REQUEST_CDMA_FLASH: ret =  responseVoid(p); break;
2313            case RIL_REQUEST_CDMA_BURST_DTMF: ret =  responseVoid(p); break;
2314            case RIL_REQUEST_CDMA_SEND_SMS: ret =  responseSMS(p); break;
2315            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret =  responseVoid(p); break;
2316            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret =  responseGmsBroadcastConfig(p); break;
2317            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret =  responseVoid(p); break;
2318            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret =  responseVoid(p); break;
2319            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret =  responseCdmaBroadcastConfig(p); break;
2320            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret =  responseVoid(p); break;
2321            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret =  responseVoid(p); break;
2322            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret =  responseVoid(p); break;
2323            case RIL_REQUEST_CDMA_SUBSCRIPTION: ret =  responseStrings(p); break;
2324            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret =  responseInts(p); break;
2325            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret =  responseVoid(p); break;
2326            case RIL_REQUEST_DEVICE_IDENTITY: ret =  responseStrings(p); break;
2327            case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
2328            case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
2329            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2330            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
2331            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
2332            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret =  responseInts(p); break;
2333            case RIL_REQUEST_ISIM_AUTHENTICATION: ret =  responseString(p); break;
2334            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
2335            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
2336            case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break;
2337            default:
2338                throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
2339            //break;
2340            }} catch (Throwable tr) {
2341                // Exceptions here usually mean invalid RIL responses
2342
2343                Rlog.w(LOG_TAG, rr.serialString() + "< "
2344                        + requestToString(rr.mRequest)
2345                        + " exception, possible invalid RIL response", tr);
2346
2347                if (rr.mResult != null) {
2348                    AsyncResult.forMessage(rr.mResult, null, tr);
2349                    rr.mResult.sendToTarget();
2350                }
2351                rr.release();
2352                return;
2353            }
2354        }
2355
2356        // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789.
2357        // This is needed otherwise we don't automatically transition to the main lock
2358        // screen when the pin or puk is entered incorrectly.
2359        switch (rr.mRequest) {
2360            case RIL_REQUEST_ENTER_SIM_PUK:
2361            case RIL_REQUEST_ENTER_SIM_PUK2:
2362                if (mIccStatusChangedRegistrants != null) {
2363                    if (RILJ_LOGD) {
2364                        riljLog("ON enter sim puk fakeSimStatusChanged: reg count="
2365                                + mIccStatusChangedRegistrants.size());
2366                    }
2367                    mIccStatusChangedRegistrants.notifyRegistrants();
2368                }
2369                break;
2370        }
2371
2372        if (error != 0) {
2373            switch (rr.mRequest) {
2374                case RIL_REQUEST_ENTER_SIM_PIN:
2375                case RIL_REQUEST_ENTER_SIM_PIN2:
2376                case RIL_REQUEST_CHANGE_SIM_PIN:
2377                case RIL_REQUEST_CHANGE_SIM_PIN2:
2378                case RIL_REQUEST_SET_FACILITY_LOCK:
2379                    if (mIccStatusChangedRegistrants != null) {
2380                        if (RILJ_LOGD) {
2381                            riljLog("ON some errors fakeSimStatusChanged: reg count="
2382                                    + mIccStatusChangedRegistrants.size());
2383                        }
2384                        mIccStatusChangedRegistrants.notifyRegistrants();
2385                    }
2386                    break;
2387            }
2388
2389            rr.onError(error, ret);
2390            rr.release();
2391            return;
2392        }
2393
2394        if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
2395            + " " + retToString(rr.mRequest, ret));
2396
2397        if (rr.mResult != null) {
2398            AsyncResult.forMessage(rr.mResult, ret, null);
2399            rr.mResult.sendToTarget();
2400        }
2401
2402        rr.release();
2403    }
2404
2405    private String
2406    retToString(int req, Object ret) {
2407        if (ret == null) return "";
2408        switch (req) {
2409            // Don't log these return values, for privacy's sake.
2410            case RIL_REQUEST_GET_IMSI:
2411            case RIL_REQUEST_GET_IMEI:
2412            case RIL_REQUEST_GET_IMEISV:
2413                if (!RILJ_LOGV) {
2414                    // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
2415                    return "";
2416                }
2417        }
2418
2419        StringBuilder sb;
2420        String s;
2421        int length;
2422        if (ret instanceof int[]){
2423            int[] intArray = (int[]) ret;
2424            length = intArray.length;
2425            sb = new StringBuilder("{");
2426            if (length > 0) {
2427                int i = 0;
2428                sb.append(intArray[i++]);
2429                while ( i < length) {
2430                    sb.append(", ").append(intArray[i++]);
2431                }
2432            }
2433            sb.append("}");
2434            s = sb.toString();
2435        } else if (ret instanceof String[]) {
2436            String[] strings = (String[]) ret;
2437            length = strings.length;
2438            sb = new StringBuilder("{");
2439            if (length > 0) {
2440                int i = 0;
2441                sb.append(strings[i++]);
2442                while ( i < length) {
2443                    sb.append(", ").append(strings[i++]);
2444                }
2445            }
2446            sb.append("}");
2447            s = sb.toString();
2448        }else if (req == RIL_REQUEST_GET_CURRENT_CALLS) {
2449            ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret;
2450            sb = new StringBuilder(" ");
2451            for (DriverCall dc : calls) {
2452                sb.append("[").append(dc).append("] ");
2453            }
2454            s = sb.toString();
2455        } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) {
2456            ArrayList<NeighboringCellInfo> cells;
2457            cells = (ArrayList<NeighboringCellInfo>) ret;
2458            sb = new StringBuilder(" ");
2459            for (NeighboringCellInfo cell : cells) {
2460                sb.append(cell).append(" ");
2461            }
2462            s = sb.toString();
2463        } else {
2464            s = ret.toString();
2465        }
2466        return s;
2467    }
2468
2469    private void
2470    processUnsolicited (Parcel p) {
2471        int response;
2472        Object ret;
2473
2474        response = p.readInt();
2475
2476        try {switch(response) {
2477/*
2478 cat libs/telephony/ril_unsol_commands.h \
2479 | egrep "^ *{RIL_" \
2480 | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
2481*/
2482
2483            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret =  responseVoid(p); break;
2484            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret =  responseVoid(p); break;
2485            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret =  responseVoid(p); break;
2486            case RIL_UNSOL_RESPONSE_NEW_SMS: ret =  responseString(p); break;
2487            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret =  responseString(p); break;
2488            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret =  responseInts(p); break;
2489            case RIL_UNSOL_ON_USSD: ret =  responseStrings(p); break;
2490            case RIL_UNSOL_NITZ_TIME_RECEIVED: ret =  responseString(p); break;
2491            case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
2492            case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
2493            case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
2494            case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
2495            case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
2496            case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
2497            case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
2498            case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret =  responseVoid(p); break;
2499            case RIL_UNSOL_SIM_REFRESH: ret =  responseSimRefresh(p); break;
2500            case RIL_UNSOL_CALL_RING: ret =  responseCallRing(p); break;
2501            case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
2502            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:  ret =  responseVoid(p); break;
2503            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:  ret =  responseCdmaSms(p); break;
2504            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:  ret =  responseRaw(p); break;
2505            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:  ret =  responseVoid(p); break;
2506            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2507            case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
2508            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
2509            case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
2510            case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
2511            case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
2512            case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
2513            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break;
2514            case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
2515            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2516            case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
2517            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret =  responseInts(p); break;
2518
2519            default:
2520                throw new RuntimeException("Unrecognized unsol response: " + response);
2521            //break; (implied)
2522        }} catch (Throwable tr) {
2523            Rlog.e(LOG_TAG, "Exception processing unsol response: " + response +
2524                "Exception:" + tr.toString());
2525            return;
2526        }
2527
2528        switch(response) {
2529            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
2530                /* has bonus radio state int */
2531                RadioState newState = getRadioStateFromInt(p.readInt());
2532                if (RILJ_LOGD) unsljLogMore(response, newState.toString());
2533
2534                switchToRadioState(newState);
2535            break;
2536            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
2537                if (RILJ_LOGD) unsljLog(response);
2538
2539                mCallStateRegistrants
2540                    .notifyRegistrants(new AsyncResult(null, null, null));
2541            break;
2542            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
2543                if (RILJ_LOGD) unsljLog(response);
2544
2545                mVoiceNetworkStateRegistrants
2546                    .notifyRegistrants(new AsyncResult(null, null, null));
2547            break;
2548            case RIL_UNSOL_RESPONSE_NEW_SMS: {
2549                if (RILJ_LOGD) unsljLog(response);
2550
2551                // FIXME this should move up a layer
2552                String a[] = new String[2];
2553
2554                a[1] = (String)ret;
2555
2556                SmsMessage sms;
2557
2558                sms = SmsMessage.newFromCMT(a);
2559                if (mGsmSmsRegistrant != null) {
2560                    mGsmSmsRegistrant
2561                        .notifyRegistrant(new AsyncResult(null, sms, null));
2562                }
2563            break;
2564            }
2565            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
2566                if (RILJ_LOGD) unsljLogRet(response, ret);
2567
2568                if (mSmsStatusRegistrant != null) {
2569                    mSmsStatusRegistrant.notifyRegistrant(
2570                            new AsyncResult(null, ret, null));
2571                }
2572            break;
2573            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
2574                if (RILJ_LOGD) unsljLogRet(response, ret);
2575
2576                int[] smsIndex = (int[])ret;
2577
2578                if(smsIndex.length == 1) {
2579                    if (mSmsOnSimRegistrant != null) {
2580                        mSmsOnSimRegistrant.
2581                                notifyRegistrant(new AsyncResult(null, smsIndex, null));
2582                    }
2583                } else {
2584                    if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length "
2585                            + smsIndex.length);
2586                }
2587            break;
2588            case RIL_UNSOL_ON_USSD:
2589                String[] resp = (String[])ret;
2590
2591                if (resp.length < 2) {
2592                    resp = new String[2];
2593                    resp[0] = ((String[])ret)[0];
2594                    resp[1] = null;
2595                }
2596                if (RILJ_LOGD) unsljLogMore(response, resp[0]);
2597                if (mUSSDRegistrant != null) {
2598                    mUSSDRegistrant.notifyRegistrant(
2599                        new AsyncResult (null, resp, null));
2600                }
2601            break;
2602            case RIL_UNSOL_NITZ_TIME_RECEIVED:
2603                if (RILJ_LOGD) unsljLogRet(response, ret);
2604
2605                // has bonus long containing milliseconds since boot that the NITZ
2606                // time was received
2607                long nitzReceiveTime = p.readLong();
2608
2609                Object[] result = new Object[2];
2610
2611                result[0] = ret;
2612                result[1] = Long.valueOf(nitzReceiveTime);
2613
2614                boolean ignoreNitz = SystemProperties.getBoolean(
2615                        TelephonyProperties.PROPERTY_IGNORE_NITZ, false);
2616
2617                if (ignoreNitz) {
2618                    if (RILJ_LOGD) riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED");
2619                } else {
2620                    if (mNITZTimeRegistrant != null) {
2621
2622                        mNITZTimeRegistrant
2623                            .notifyRegistrant(new AsyncResult (null, result, null));
2624                    } else {
2625                        // in case NITZ time registrant isnt registered yet
2626                        mLastNITZTimeInfo = result;
2627                    }
2628                }
2629            break;
2630
2631            case RIL_UNSOL_SIGNAL_STRENGTH:
2632                // Note this is set to "verbose" because it happens
2633                // frequently
2634                if (RILJ_LOGV) unsljLogvRet(response, ret);
2635
2636                if (mSignalStrengthRegistrant != null) {
2637                    mSignalStrengthRegistrant.notifyRegistrant(
2638                                        new AsyncResult (null, ret, null));
2639                }
2640            break;
2641            case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
2642                if (RILJ_LOGD) unsljLogRet(response, ret);
2643
2644                mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
2645            break;
2646
2647            case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
2648                if (RILJ_LOGD) unsljLogRet(response, ret);
2649
2650                if (mSsnRegistrant != null) {
2651                    mSsnRegistrant.notifyRegistrant(
2652                                        new AsyncResult (null, ret, null));
2653                }
2654                break;
2655
2656            case RIL_UNSOL_STK_SESSION_END:
2657                if (RILJ_LOGD) unsljLog(response);
2658
2659                if (mCatSessionEndRegistrant != null) {
2660                    mCatSessionEndRegistrant.notifyRegistrant(
2661                                        new AsyncResult (null, ret, null));
2662                }
2663                break;
2664
2665            case RIL_UNSOL_STK_PROACTIVE_COMMAND:
2666                if (RILJ_LOGD) unsljLogRet(response, ret);
2667
2668                if (mCatProCmdRegistrant != null) {
2669                    mCatProCmdRegistrant.notifyRegistrant(
2670                                        new AsyncResult (null, ret, null));
2671                }
2672                break;
2673
2674            case RIL_UNSOL_STK_EVENT_NOTIFY:
2675                if (RILJ_LOGD) unsljLogRet(response, ret);
2676
2677                if (mCatEventRegistrant != null) {
2678                    mCatEventRegistrant.notifyRegistrant(
2679                                        new AsyncResult (null, ret, null));
2680                }
2681                break;
2682
2683            case RIL_UNSOL_STK_CALL_SETUP:
2684                if (RILJ_LOGD) unsljLogRet(response, ret);
2685
2686                if (mCatCallSetUpRegistrant != null) {
2687                    mCatCallSetUpRegistrant.notifyRegistrant(
2688                                        new AsyncResult (null, ret, null));
2689                }
2690                break;
2691
2692            case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
2693                if (RILJ_LOGD) unsljLog(response);
2694
2695                if (mIccSmsFullRegistrant != null) {
2696                    mIccSmsFullRegistrant.notifyRegistrant();
2697                }
2698                break;
2699
2700            case RIL_UNSOL_SIM_REFRESH:
2701                if (RILJ_LOGD) unsljLogRet(response, ret);
2702
2703                if (mIccRefreshRegistrants != null) {
2704                    mIccRefreshRegistrants.notifyRegistrants(
2705                            new AsyncResult (null, ret, null));
2706                }
2707                break;
2708
2709            case RIL_UNSOL_CALL_RING:
2710                if (RILJ_LOGD) unsljLogRet(response, ret);
2711
2712                if (mRingRegistrant != null) {
2713                    mRingRegistrant.notifyRegistrant(
2714                            new AsyncResult (null, ret, null));
2715                }
2716                break;
2717
2718            case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
2719                if (RILJ_LOGD) unsljLogvRet(response, ret);
2720                if (mRestrictedStateRegistrant != null) {
2721                    mRestrictedStateRegistrant.notifyRegistrant(
2722                                        new AsyncResult (null, ret, null));
2723                }
2724                break;
2725
2726            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
2727                if (RILJ_LOGD) unsljLog(response);
2728
2729                if (mIccStatusChangedRegistrants != null) {
2730                    mIccStatusChangedRegistrants.notifyRegistrants();
2731                }
2732                break;
2733
2734            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
2735                if (RILJ_LOGD) unsljLog(response);
2736
2737                SmsMessage sms = (SmsMessage) ret;
2738
2739                if (mCdmaSmsRegistrant != null) {
2740                    mCdmaSmsRegistrant
2741                        .notifyRegistrant(new AsyncResult(null, sms, null));
2742                }
2743                break;
2744
2745            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
2746                if (RILJ_LOGD) unsljLog(response);
2747
2748                if (mGsmBroadcastSmsRegistrant != null) {
2749                    mGsmBroadcastSmsRegistrant
2750                        .notifyRegistrant(new AsyncResult(null, ret, null));
2751                }
2752                break;
2753
2754            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
2755                if (RILJ_LOGD) unsljLog(response);
2756
2757                if (mIccSmsFullRegistrant != null) {
2758                    mIccSmsFullRegistrant.notifyRegistrant();
2759                }
2760                break;
2761
2762            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
2763                if (RILJ_LOGD) unsljLog(response);
2764
2765                if (mEmergencyCallbackModeRegistrant != null) {
2766                    mEmergencyCallbackModeRegistrant.notifyRegistrant();
2767                }
2768                break;
2769
2770            case RIL_UNSOL_CDMA_CALL_WAITING:
2771                if (RILJ_LOGD) unsljLogRet(response, ret);
2772
2773                if (mCallWaitingInfoRegistrants != null) {
2774                    mCallWaitingInfoRegistrants.notifyRegistrants(
2775                                        new AsyncResult (null, ret, null));
2776                }
2777                break;
2778
2779            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
2780                if (RILJ_LOGD) unsljLogRet(response, ret);
2781
2782                if (mOtaProvisionRegistrants != null) {
2783                    mOtaProvisionRegistrants.notifyRegistrants(
2784                                        new AsyncResult (null, ret, null));
2785                }
2786                break;
2787
2788            case RIL_UNSOL_CDMA_INFO_REC:
2789                ArrayList<CdmaInformationRecords> listInfoRecs;
2790
2791                try {
2792                    listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
2793                } catch (ClassCastException e) {
2794                    Rlog.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
2795                    break;
2796                }
2797
2798                for (CdmaInformationRecords rec : listInfoRecs) {
2799                    if (RILJ_LOGD) unsljLogRet(response, rec);
2800                    notifyRegistrantsCdmaInfoRec(rec);
2801                }
2802                break;
2803
2804            case RIL_UNSOL_OEM_HOOK_RAW:
2805                if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret));
2806                if (mUnsolOemHookRawRegistrant != null) {
2807                    mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
2808                }
2809                break;
2810
2811            case RIL_UNSOL_RINGBACK_TONE:
2812                if (RILJ_LOGD) unsljLogvRet(response, ret);
2813                if (mRingbackToneRegistrants != null) {
2814                    boolean playtone = (((int[])ret)[0] == 1);
2815                    mRingbackToneRegistrants.notifyRegistrants(
2816                                        new AsyncResult (null, playtone, null));
2817                }
2818                break;
2819
2820            case RIL_UNSOL_RESEND_INCALL_MUTE:
2821                if (RILJ_LOGD) unsljLogRet(response, ret);
2822
2823                if (mResendIncallMuteRegistrants != null) {
2824                    mResendIncallMuteRegistrants.notifyRegistrants(
2825                                        new AsyncResult (null, ret, null));
2826                }
2827                break;
2828
2829            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
2830                if (RILJ_LOGD) unsljLogRet(response, ret);
2831
2832                if (mVoiceRadioTechChangedRegistrants != null) {
2833                    mVoiceRadioTechChangedRegistrants.notifyRegistrants(
2834                            new AsyncResult(null, ret, null));
2835                }
2836                break;
2837
2838            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
2839                if (RILJ_LOGD) unsljLogRet(response, ret);
2840
2841                if (mCdmaSubscriptionChangedRegistrants != null) {
2842                    mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
2843                                        new AsyncResult (null, ret, null));
2844                }
2845                break;
2846
2847            case RIL_UNSOl_CDMA_PRL_CHANGED:
2848                if (RILJ_LOGD) unsljLogRet(response, ret);
2849
2850                if (mCdmaPrlChangedRegistrants != null) {
2851                    mCdmaPrlChangedRegistrants.notifyRegistrants(
2852                                        new AsyncResult (null, ret, null));
2853                }
2854                break;
2855
2856            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
2857                if (RILJ_LOGD) unsljLogRet(response, ret);
2858
2859                if (mExitEmergencyCallbackModeRegistrants != null) {
2860                    mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
2861                                        new AsyncResult (null, null, null));
2862                }
2863                break;
2864
2865            case RIL_UNSOL_RIL_CONNECTED: {
2866                if (RILJ_LOGD) unsljLogRet(response, ret);
2867
2868                // Initial conditions
2869                setRadioPower(false, null);
2870                setPreferredNetworkType(mPreferredNetworkType, null);
2871                setCdmaSubscriptionSource(mCdmaSubscription, null);
2872                notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
2873                break;
2874            }
2875        }
2876    }
2877
2878    /**
2879     * Notifiy all registrants that the ril has connected or disconnected.
2880     *
2881     * @param rilVer is the version of the ril or -1 if disconnected.
2882     */
2883    private void notifyRegistrantsRilConnectionChanged(int rilVer) {
2884        mRilVersion = rilVer;
2885        if (mRilConnectedRegistrants != null) {
2886            mRilConnectedRegistrants.notifyRegistrants(
2887                                new AsyncResult (null, new Integer(rilVer), null));
2888        }
2889    }
2890
2891    private Object
2892    responseInts(Parcel p) {
2893        int numInts;
2894        int response[];
2895
2896        numInts = p.readInt();
2897
2898        response = new int[numInts];
2899
2900        for (int i = 0 ; i < numInts ; i++) {
2901            response[i] = p.readInt();
2902        }
2903
2904        return response;
2905    }
2906
2907
2908    private Object
2909    responseVoid(Parcel p) {
2910        return null;
2911    }
2912
2913    private Object
2914    responseCallForward(Parcel p) {
2915        int numInfos;
2916        CallForwardInfo infos[];
2917
2918        numInfos = p.readInt();
2919
2920        infos = new CallForwardInfo[numInfos];
2921
2922        for (int i = 0 ; i < numInfos ; i++) {
2923            infos[i] = new CallForwardInfo();
2924
2925            infos[i].status = p.readInt();
2926            infos[i].reason = p.readInt();
2927            infos[i].serviceClass = p.readInt();
2928            infos[i].toa = p.readInt();
2929            infos[i].number = p.readString();
2930            infos[i].timeSeconds = p.readInt();
2931        }
2932
2933        return infos;
2934    }
2935
2936    private Object
2937    responseSuppServiceNotification(Parcel p) {
2938        SuppServiceNotification notification = new SuppServiceNotification();
2939
2940        notification.notificationType = p.readInt();
2941        notification.code = p.readInt();
2942        notification.index = p.readInt();
2943        notification.type = p.readInt();
2944        notification.number = p.readString();
2945
2946        return notification;
2947    }
2948
2949    private Object
2950    responseCdmaSms(Parcel p) {
2951        SmsMessage sms;
2952        sms = SmsMessage.newFromParcel(p);
2953
2954        return sms;
2955    }
2956
2957    private Object
2958    responseString(Parcel p) {
2959        String response;
2960
2961        response = p.readString();
2962
2963        return response;
2964    }
2965
2966    private Object
2967    responseStrings(Parcel p) {
2968        int num;
2969        String response[];
2970
2971        response = p.readStringArray();
2972
2973        if (false) {
2974            num = p.readInt();
2975
2976            response = new String[num];
2977            for (int i = 0; i < num; i++) {
2978                response[i] = p.readString();
2979            }
2980        }
2981
2982        return response;
2983    }
2984
2985    private Object
2986    responseRaw(Parcel p) {
2987        int num;
2988        byte response[];
2989
2990        response = p.createByteArray();
2991
2992        return response;
2993    }
2994
2995    private Object
2996    responseSMS(Parcel p) {
2997        int messageRef, errorCode;
2998        String ackPDU;
2999
3000        messageRef = p.readInt();
3001        ackPDU = p.readString();
3002        errorCode = p.readInt();
3003
3004        SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode);
3005
3006        return response;
3007    }
3008
3009
3010    private Object
3011    responseICC_IO(Parcel p) {
3012        int sw1, sw2;
3013        byte data[] = null;
3014        Message ret;
3015
3016        sw1 = p.readInt();
3017        sw2 = p.readInt();
3018
3019        String s = p.readString();
3020
3021        if (RILJ_LOGV) riljLog("< iccIO: "
3022                + " 0x" + Integer.toHexString(sw1)
3023                + " 0x" + Integer.toHexString(sw2) + " "
3024                + s);
3025
3026        return new IccIoResult(sw1, sw2, s);
3027    }
3028
3029    private Object
3030    responseIccCardStatus(Parcel p) {
3031        IccCardApplicationStatus appStatus;
3032
3033        IccCardStatus cardStatus = new IccCardStatus();
3034        cardStatus.setCardState(p.readInt());
3035        cardStatus.setUniversalPinState(p.readInt());
3036        cardStatus.mGsmUmtsSubscriptionAppIndex = p.readInt();
3037        cardStatus.mCdmaSubscriptionAppIndex = p.readInt();
3038        cardStatus.mImsSubscriptionAppIndex = p.readInt();
3039        int numApplications = p.readInt();
3040
3041        // limit to maximum allowed applications
3042        if (numApplications > IccCardStatus.CARD_MAX_APPS) {
3043            numApplications = IccCardStatus.CARD_MAX_APPS;
3044        }
3045        cardStatus.mApplications = new IccCardApplicationStatus[numApplications];
3046        for (int i = 0 ; i < numApplications ; i++) {
3047            appStatus = new IccCardApplicationStatus();
3048            appStatus.app_type       = appStatus.AppTypeFromRILInt(p.readInt());
3049            appStatus.app_state      = appStatus.AppStateFromRILInt(p.readInt());
3050            appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(p.readInt());
3051            appStatus.aid            = p.readString();
3052            appStatus.app_label      = p.readString();
3053            appStatus.pin1_replaced  = p.readInt();
3054            appStatus.pin1           = appStatus.PinStateFromRILInt(p.readInt());
3055            appStatus.pin2           = appStatus.PinStateFromRILInt(p.readInt());
3056            cardStatus.mApplications[i] = appStatus;
3057        }
3058        return cardStatus;
3059    }
3060
3061    private Object
3062    responseSimRefresh(Parcel p) {
3063        IccRefreshResponse response = new IccRefreshResponse();
3064
3065        response.refreshResult = p.readInt();
3066        response.efId   = p.readInt();
3067        response.aid = p.readString();
3068        return response;
3069    }
3070
3071    private Object
3072    responseCallList(Parcel p) {
3073        int num;
3074        int voiceSettings;
3075        ArrayList<DriverCall> response;
3076        DriverCall dc;
3077
3078        num = p.readInt();
3079        response = new ArrayList<DriverCall>(num);
3080
3081        if (RILJ_LOGV) {
3082            riljLog("responseCallList: num=" + num +
3083                    " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant +
3084                    " mTestingEmergencyCall=" + mTestingEmergencyCall.get());
3085        }
3086        for (int i = 0 ; i < num ; i++) {
3087            dc = new DriverCall();
3088
3089            dc.state = DriverCall.stateFromCLCC(p.readInt());
3090            dc.index = p.readInt();
3091            dc.TOA = p.readInt();
3092            dc.isMpty = (0 != p.readInt());
3093            dc.isMT = (0 != p.readInt());
3094            dc.als = p.readInt();
3095            voiceSettings = p.readInt();
3096            dc.isVoice = (0 == voiceSettings) ? false : true;
3097            dc.isVoicePrivacy = (0 != p.readInt());
3098            dc.number = p.readString();
3099            int np = p.readInt();
3100            dc.numberPresentation = DriverCall.presentationFromCLIP(np);
3101            dc.name = p.readString();
3102            dc.namePresentation = p.readInt();
3103            int uusInfoPresent = p.readInt();
3104            if (uusInfoPresent == 1) {
3105                dc.uusInfo = new UUSInfo();
3106                dc.uusInfo.setType(p.readInt());
3107                dc.uusInfo.setDcs(p.readInt());
3108                byte[] userData = p.createByteArray();
3109                dc.uusInfo.setUserData(userData);
3110                riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
3111                                dc.uusInfo.getType(), dc.uusInfo.getDcs(),
3112                                dc.uusInfo.getUserData().length));
3113                riljLogv("Incoming UUS : data (string)="
3114                        + new String(dc.uusInfo.getUserData()));
3115                riljLogv("Incoming UUS : data (hex): "
3116                        + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
3117            } else {
3118                riljLogv("Incoming UUS : NOT present!");
3119            }
3120
3121            // Make sure there's a leading + on addresses with a TOA of 145
3122            dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
3123
3124            response.add(dc);
3125
3126            if (dc.isVoicePrivacy) {
3127                mVoicePrivacyOnRegistrants.notifyRegistrants();
3128                riljLog("InCall VoicePrivacy is enabled");
3129            } else {
3130                mVoicePrivacyOffRegistrants.notifyRegistrants();
3131                riljLog("InCall VoicePrivacy is disabled");
3132            }
3133        }
3134
3135        Collections.sort(response);
3136
3137        if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) {
3138            if (mEmergencyCallbackModeRegistrant != null) {
3139                riljLog("responseCallList: call ended, testing emergency call," +
3140                            " notify ECM Registrants");
3141                mEmergencyCallbackModeRegistrant.notifyRegistrant();
3142            }
3143        }
3144
3145        return response;
3146    }
3147
3148    private DataCallState getDataCallState(Parcel p, int version) {
3149        DataCallState dataCall = new DataCallState();
3150
3151        dataCall.version = version;
3152        if (version < 5) {
3153            dataCall.cid = p.readInt();
3154            dataCall.active = p.readInt();
3155            dataCall.type = p.readString();
3156            String addresses = p.readString();
3157            if (!TextUtils.isEmpty(addresses)) {
3158                dataCall.addresses = addresses.split(" ");
3159            }
3160        } else {
3161            dataCall.status = p.readInt();
3162            dataCall.suggestedRetryTime = p.readInt();
3163            dataCall.cid = p.readInt();
3164            dataCall.active = p.readInt();
3165            dataCall.type = p.readString();
3166            dataCall.ifname = p.readString();
3167            if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) &&
3168                    TextUtils.isEmpty(dataCall.ifname)) {
3169              throw new RuntimeException("getDataCallState, no ifname");
3170            }
3171            String addresses = p.readString();
3172            if (!TextUtils.isEmpty(addresses)) {
3173                dataCall.addresses = addresses.split(" ");
3174            }
3175            String dnses = p.readString();
3176            if (!TextUtils.isEmpty(dnses)) {
3177                dataCall.dnses = dnses.split(" ");
3178            }
3179            String gateways = p.readString();
3180            if (!TextUtils.isEmpty(gateways)) {
3181                dataCall.gateways = gateways.split(" ");
3182            }
3183        }
3184        return dataCall;
3185    }
3186
3187    private Object
3188    responseDataCallList(Parcel p) {
3189        ArrayList<DataCallState> response;
3190
3191        int ver = p.readInt();
3192        int num = p.readInt();
3193        riljLog("responseDataCallList ver=" + ver + " num=" + num);
3194
3195        response = new ArrayList<DataCallState>(num);
3196        for (int i = 0; i < num; i++) {
3197            response.add(getDataCallState(p, ver));
3198        }
3199
3200        return response;
3201    }
3202
3203    private Object
3204    responseSetupDataCall(Parcel p) {
3205        int ver = p.readInt();
3206        int num = p.readInt();
3207        if (RILJ_LOGV) riljLog("responseSetupDataCall ver=" + ver + " num=" + num);
3208
3209        DataCallState dataCall;
3210
3211        if (ver < 5) {
3212            dataCall = new DataCallState();
3213            dataCall.version = ver;
3214            dataCall.cid = Integer.parseInt(p.readString());
3215            dataCall.ifname = p.readString();
3216            if (TextUtils.isEmpty(dataCall.ifname)) {
3217                throw new RuntimeException(
3218                        "RIL_REQUEST_SETUP_DATA_CALL response, no ifname");
3219            }
3220            String addresses = p.readString();
3221            if (!TextUtils.isEmpty(addresses)) {
3222              dataCall.addresses = addresses.split(" ");
3223            }
3224            if (num >= 4) {
3225                String dnses = p.readString();
3226                if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses);
3227                if (!TextUtils.isEmpty(dnses)) {
3228                    dataCall.dnses = dnses.split(" ");
3229                }
3230            }
3231            if (num >= 5) {
3232                String gateways = p.readString();
3233                if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways);
3234                if (!TextUtils.isEmpty(gateways)) {
3235                    dataCall.gateways = gateways.split(" ");
3236                }
3237            }
3238        } else {
3239            if (num != 1) {
3240                throw new RuntimeException(
3241                        "RIL_REQUEST_SETUP_DATA_CALL response expecting 1 RIL_Data_Call_response_v5"
3242                        + " got " + num);
3243            }
3244            dataCall = getDataCallState(p, ver);
3245        }
3246
3247        return dataCall;
3248    }
3249
3250    private Object
3251    responseOperatorInfos(Parcel p) {
3252        String strings[] = (String [])responseStrings(p);
3253        ArrayList<OperatorInfo> ret;
3254
3255        if (strings.length % 4 != 0) {
3256            throw new RuntimeException(
3257                "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
3258                + strings.length + " strings, expected multible of 4");
3259        }
3260
3261        ret = new ArrayList<OperatorInfo>(strings.length / 4);
3262
3263        for (int i = 0 ; i < strings.length ; i += 4) {
3264            ret.add (
3265                new OperatorInfo(
3266                    strings[i+0],
3267                    strings[i+1],
3268                    strings[i+2],
3269                    strings[i+3]));
3270        }
3271
3272        return ret;
3273    }
3274
3275    private Object
3276    responseCellList(Parcel p) {
3277       int num, rssi;
3278       String location;
3279       ArrayList<NeighboringCellInfo> response;
3280       NeighboringCellInfo cell;
3281
3282       num = p.readInt();
3283       response = new ArrayList<NeighboringCellInfo>();
3284
3285       // Determine the radio access type
3286       String radioString = SystemProperties.get(
3287               TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, "unknown");
3288       int radioType;
3289       if (radioString.equals("GPRS")) {
3290           radioType = NETWORK_TYPE_GPRS;
3291       } else if (radioString.equals("EDGE")) {
3292           radioType = NETWORK_TYPE_EDGE;
3293       } else if (radioString.equals("UMTS")) {
3294           radioType = NETWORK_TYPE_UMTS;
3295       } else if (radioString.equals("HSDPA")) {
3296           radioType = NETWORK_TYPE_HSDPA;
3297       } else if (radioString.equals("HSUPA")) {
3298           radioType = NETWORK_TYPE_HSUPA;
3299       } else if (radioString.equals("HSPA")) {
3300           radioType = NETWORK_TYPE_HSPA;
3301       } else {
3302           radioType = NETWORK_TYPE_UNKNOWN;
3303       }
3304
3305       // Interpret the location based on radio access type
3306       if (radioType != NETWORK_TYPE_UNKNOWN) {
3307           for (int i = 0 ; i < num ; i++) {
3308               rssi = p.readInt();
3309               location = p.readString();
3310               cell = new NeighboringCellInfo(rssi, location, radioType);
3311               response.add(cell);
3312           }
3313       }
3314       return response;
3315    }
3316
3317    private Object responseGetPreferredNetworkType(Parcel p) {
3318       int [] response = (int[]) responseInts(p);
3319
3320       if (response.length >= 1) {
3321           // Since this is the response for getPreferredNetworkType
3322           // we'll assume that it should be the value we want the
3323           // vendor ril to take if we reestablish a connection to it.
3324           mPreferredNetworkType = response[0];
3325       }
3326       return response;
3327    }
3328
3329    private Object responseGmsBroadcastConfig(Parcel p) {
3330        int num;
3331        ArrayList<SmsBroadcastConfigInfo> response;
3332        SmsBroadcastConfigInfo info;
3333
3334        num = p.readInt();
3335        response = new ArrayList<SmsBroadcastConfigInfo>(num);
3336
3337        for (int i = 0; i < num; i++) {
3338            int fromId = p.readInt();
3339            int toId = p.readInt();
3340            int fromScheme = p.readInt();
3341            int toScheme = p.readInt();
3342            boolean selected = (p.readInt() == 1);
3343
3344            info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme,
3345                    toScheme, selected);
3346            response.add(info);
3347        }
3348        return response;
3349    }
3350
3351    private Object
3352    responseCdmaBroadcastConfig(Parcel p) {
3353        int numServiceCategories;
3354        int response[];
3355
3356        numServiceCategories = p.readInt();
3357
3358        if (numServiceCategories == 0) {
3359            // TODO: The logic of providing default values should
3360            // not be done by this transport layer. And needs to
3361            // be done by the vendor ril or application logic.
3362            int numInts;
3363            numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
3364            response = new int[numInts];
3365
3366            // Faking a default record for all possible records.
3367            response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
3368
3369            // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
3370            // default language and selection status to false for all.
3371            for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) {
3372                response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT;
3373                response[i + 1] = 1;
3374                response[i + 2] = 0;
3375            }
3376        } else {
3377            int numInts;
3378            numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
3379            response = new int[numInts];
3380
3381            response[0] = numServiceCategories;
3382            for (int i = 1 ; i < numInts; i++) {
3383                 response[i] = p.readInt();
3384             }
3385        }
3386
3387        return response;
3388    }
3389
3390    private Object
3391    responseSignalStrength(Parcel p) {
3392        SignalStrength signalStrength = new SignalStrength(p);
3393        return signalStrength;
3394    }
3395
3396    private ArrayList<CdmaInformationRecords>
3397    responseCdmaInformationRecord(Parcel p) {
3398        int numberOfInfoRecs;
3399        ArrayList<CdmaInformationRecords> response;
3400
3401        /**
3402         * Loop through all of the information records unmarshalling them
3403         * and converting them to Java Objects.
3404         */
3405        numberOfInfoRecs = p.readInt();
3406        response = new ArrayList<CdmaInformationRecords>(numberOfInfoRecs);
3407
3408        for (int i = 0; i < numberOfInfoRecs; i++) {
3409            CdmaInformationRecords InfoRec = new CdmaInformationRecords(p);
3410            response.add(InfoRec);
3411        }
3412
3413        return response;
3414    }
3415
3416    private Object
3417    responseCdmaCallWaiting(Parcel p) {
3418        CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
3419
3420        notification.number = p.readString();
3421        notification.numberPresentation = notification.presentationFromCLIP(p.readInt());
3422        notification.name = p.readString();
3423        notification.namePresentation = notification.numberPresentation;
3424        notification.isPresent = p.readInt();
3425        notification.signalType = p.readInt();
3426        notification.alertPitch = p.readInt();
3427        notification.signal = p.readInt();
3428        notification.numberType = p.readInt();
3429        notification.numberPlan = p.readInt();
3430
3431        return notification;
3432    }
3433
3434    private Object
3435    responseCallRing(Parcel p){
3436        char response[] = new char[4];
3437
3438        response[0] = (char) p.readInt();    // isPresent
3439        response[1] = (char) p.readInt();    // signalType
3440        response[2] = (char) p.readInt();    // alertPitch
3441        response[3] = (char) p.readInt();    // signal
3442
3443        return response;
3444    }
3445
3446    private void
3447    notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
3448        int response = RIL_UNSOL_CDMA_INFO_REC;
3449        if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
3450            if (mDisplayInfoRegistrants != null) {
3451                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3452                mDisplayInfoRegistrants.notifyRegistrants(
3453                        new AsyncResult (null, infoRec.record, null));
3454            }
3455        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
3456            if (mSignalInfoRegistrants != null) {
3457                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3458                mSignalInfoRegistrants.notifyRegistrants(
3459                        new AsyncResult (null, infoRec.record, null));
3460            }
3461        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
3462            if (mNumberInfoRegistrants != null) {
3463                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3464                mNumberInfoRegistrants.notifyRegistrants(
3465                        new AsyncResult (null, infoRec.record, null));
3466            }
3467        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
3468            if (mRedirNumInfoRegistrants != null) {
3469                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3470                mRedirNumInfoRegistrants.notifyRegistrants(
3471                        new AsyncResult (null, infoRec.record, null));
3472            }
3473        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
3474            if (mLineControlInfoRegistrants != null) {
3475                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3476                mLineControlInfoRegistrants.notifyRegistrants(
3477                        new AsyncResult (null, infoRec.record, null));
3478            }
3479        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
3480            if (mT53ClirInfoRegistrants != null) {
3481                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3482                mT53ClirInfoRegistrants.notifyRegistrants(
3483                        new AsyncResult (null, infoRec.record, null));
3484            }
3485        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
3486            if (mT53AudCntrlInfoRegistrants != null) {
3487               if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3488               mT53AudCntrlInfoRegistrants.notifyRegistrants(
3489                       new AsyncResult (null, infoRec.record, null));
3490            }
3491        }
3492    }
3493
3494    static String
3495    requestToString(int request) {
3496/*
3497 cat libs/telephony/ril_commands.h \
3498 | egrep "^ *{RIL_" \
3499 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3500*/
3501        switch(request) {
3502            case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
3503            case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
3504            case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
3505            case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
3506            case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
3507            case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
3508            case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
3509            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
3510            case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
3511            case RIL_REQUEST_DIAL: return "DIAL";
3512            case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
3513            case RIL_REQUEST_HANGUP: return "HANGUP";
3514            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
3515            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
3516            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
3517            case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
3518            case RIL_REQUEST_UDUB: return "UDUB";
3519            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
3520            case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
3521            case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
3522            case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
3523            case RIL_REQUEST_OPERATOR: return "OPERATOR";
3524            case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
3525            case RIL_REQUEST_DTMF: return "DTMF";
3526            case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
3527            case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
3528            case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
3529            case RIL_REQUEST_SIM_IO: return "SIM_IO";
3530            case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
3531            case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
3532            case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
3533            case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
3534            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
3535            case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
3536            case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
3537            case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
3538            case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
3539            case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
3540            case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
3541            case RIL_REQUEST_ANSWER: return "ANSWER";
3542            case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
3543            case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
3544            case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
3545            case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
3546            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
3547            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
3548            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
3549            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
3550            case RIL_REQUEST_DTMF_START: return "DTMF_START";
3551            case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
3552            case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
3553            case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
3554            case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
3555            case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
3556            case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
3557            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
3558            case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
3559            case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
3560            case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
3561            case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
3562            case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
3563            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION";
3564            case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
3565            case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM";
3566            case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
3567            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
3568            case RIL_REQUEST_STK_GET_PROFILE: return "REQUEST_STK_GET_PROFILE";
3569            case RIL_REQUEST_STK_SET_PROFILE: return "REQUEST_STK_SET_PROFILE";
3570            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "REQUEST_STK_SEND_ENVELOPE_COMMAND";
3571            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "REQUEST_STK_SEND_TERMINAL_RESPONSE";
3572            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
3573            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER";
3574            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "REQUEST_SET_PREFERRED_NETWORK_TYPE";
3575            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
3576            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS";
3577            case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES";
3578            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
3579            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
3580            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
3581            case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE";
3582            case RIL_REQUEST_QUERY_TTY_MODE: return "RIL_REQUEST_QUERY_TTY_MODE";
3583            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
3584            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
3585            case RIL_REQUEST_CDMA_FLASH: return "RIL_REQUEST_CDMA_FLASH";
3586            case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF";
3587            case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS";
3588            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
3589            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
3590            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
3591            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
3592            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
3593            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
3594            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
3595            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
3596            case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
3597            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
3598            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
3599            case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY";
3600            case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS";
3601            case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS";
3602            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
3603            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
3604            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
3605            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
3606            case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION";
3607            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
3608            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
3609            case RIL_REQUEST_VOICE_RADIO_TECH: return "RIL_REQUEST_VOICE_RADIO_TECH";
3610            default: return "<unknown request>";
3611        }
3612    }
3613
3614    static String
3615    responseToString(int request)
3616    {
3617/*
3618 cat libs/telephony/ril_unsol_commands.h \
3619 | egrep "^ *{RIL_" \
3620 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3621*/
3622        switch(request) {
3623            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
3624            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
3625            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
3626            case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
3627            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
3628            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
3629            case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
3630            case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST";
3631            case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
3632            case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
3633            case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
3634            case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
3635            case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
3636            case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
3637            case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
3638            case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
3639            case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL";
3640            case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
3641            case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
3642            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
3643            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS";
3644            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
3645            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
3646            case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
3647            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
3648            case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
3649            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
3650            case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
3651            case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
3652            case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
3653            case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
3654            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "CDMA_SUBSCRIPTION_SOURCE_CHANGED";
3655            case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
3656            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
3657            case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
3658            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
3659            default: return "<unknown reponse>";
3660        }
3661    }
3662
3663    private void riljLog(String msg) {
3664        Rlog.d(LOG_TAG, msg);
3665    }
3666
3667    private void riljLogv(String msg) {
3668        Rlog.v(LOG_TAG, msg);
3669    }
3670
3671    private void unsljLog(int response) {
3672        riljLog("[UNSL]< " + responseToString(response));
3673    }
3674
3675    private void unsljLogMore(int response, String more) {
3676        riljLog("[UNSL]< " + responseToString(response) + " " + more);
3677    }
3678
3679    private void unsljLogRet(int response, Object ret) {
3680        riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
3681    }
3682
3683    private void unsljLogvRet(int response, Object ret) {
3684        riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
3685    }
3686
3687
3688    // ***** Methods for CDMA support
3689    public void
3690    getDeviceIdentity(Message response) {
3691        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DEVICE_IDENTITY, response);
3692
3693        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3694
3695        send(rr);
3696    }
3697
3698    public void
3699    getCDMASubscription(Message response) {
3700        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SUBSCRIPTION, response);
3701
3702        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3703
3704        send(rr);
3705    }
3706
3707    @Override
3708    public void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructor
3709        if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
3710        mPhoneType = phoneType;
3711    }
3712
3713    /**
3714     * {@inheritDoc}
3715     */
3716    public void queryCdmaRoamingPreference(Message response) {
3717        RILRequest rr = RILRequest.obtain(
3718                RILConstants.RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, response);
3719
3720        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3721
3722        send(rr);
3723    }
3724
3725    /**
3726     * {@inheritDoc}
3727     */
3728    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
3729        RILRequest rr = RILRequest.obtain(
3730                RILConstants.RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, response);
3731
3732        rr.mp.writeInt(1);
3733        rr.mp.writeInt(cdmaRoamingType);
3734
3735        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3736                + " : " + cdmaRoamingType);
3737
3738        send(rr);
3739    }
3740
3741    /**
3742     * {@inheritDoc}
3743     */
3744    public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
3745        RILRequest rr = RILRequest.obtain(
3746                RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response);
3747
3748        rr.mp.writeInt(1);
3749        rr.mp.writeInt(cdmaSubscription);
3750
3751        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3752                + " : " + cdmaSubscription);
3753
3754        send(rr);
3755    }
3756
3757    /**
3758     * {@inheritDoc}
3759     */
3760    @Override
3761    public void getCdmaSubscriptionSource(Message response) {
3762        RILRequest rr = RILRequest.obtain(
3763                RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response);
3764
3765        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3766
3767        send(rr);
3768    }
3769
3770    /**
3771     * {@inheritDoc}
3772     */
3773    public void queryTTYMode(Message response) {
3774        RILRequest rr = RILRequest.obtain(
3775                RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
3776
3777        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3778
3779        send(rr);
3780    }
3781
3782    /**
3783     * {@inheritDoc}
3784     */
3785    public void setTTYMode(int ttyMode, Message response) {
3786        RILRequest rr = RILRequest.obtain(
3787                RILConstants.RIL_REQUEST_SET_TTY_MODE, response);
3788
3789        rr.mp.writeInt(1);
3790        rr.mp.writeInt(ttyMode);
3791
3792        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3793                + " : " + ttyMode);
3794
3795        send(rr);
3796    }
3797
3798    /**
3799     * {@inheritDoc}
3800     */
3801    public void
3802    sendCDMAFeatureCode(String FeatureCode, Message response) {
3803        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response);
3804
3805        rr.mp.writeString(FeatureCode);
3806
3807        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3808                + " : " + FeatureCode);
3809
3810        send(rr);
3811    }
3812
3813    public void getCdmaBroadcastConfig(Message response) {
3814        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, response);
3815
3816        send(rr);
3817    }
3818
3819    // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
3820    public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
3821        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response);
3822
3823        for(int i = 0; i < configValuesArray.length; i++) {
3824            rr.mp.writeInt(configValuesArray[i]);
3825        }
3826
3827        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3828
3829        send(rr);
3830    }
3831
3832    public void setCdmaBroadcastActivation(boolean activate, Message response) {
3833        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response);
3834
3835        rr.mp.writeInt(1);
3836        rr.mp.writeInt(activate ? 0 :1);
3837
3838        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3839
3840        send(rr);
3841    }
3842
3843    /**
3844     * {@inheritDoc}
3845     */
3846    public void exitEmergencyCallbackMode(Message response) {
3847        RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response);
3848
3849        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3850
3851        send(rr);
3852    }
3853
3854    public void requestIsimAuthentication(String nonce, Message response) {
3855        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ISIM_AUTHENTICATION, response);
3856
3857        rr.mp.writeString(nonce);
3858
3859        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3860
3861        send(rr);
3862    }
3863
3864    /* (non-Javadoc)
3865     * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
3866     */
3867    @Override
3868    public void testingEmergencyCall() {
3869        if (RILJ_LOGD) riljLog("testingEmergencyCall");
3870        mTestingEmergencyCall.set(true);
3871    }
3872
3873    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
3874        pw.println("RIL: " + this);
3875        pw.println(" mSocket=" + mSocket);
3876        pw.println(" mSenderThread=" + mSenderThread);
3877        pw.println(" mSender=" + mSender);
3878        pw.println(" mReceiverThread=" + mReceiverThread);
3879        pw.println(" mReceiver=" + mReceiver);
3880        pw.println(" mWakeLock=" + mWakeLock);
3881        pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
3882        synchronized (mRequestList) {
3883          pw.println(" mRequestMessagesPending=" + mRequestMessagesPending);
3884          pw.println(" mRequestMessagesWaiting=" + mRequestMessagesWaiting);
3885            int count = mRequestList.size();
3886            pw.println(" mRequestList count=" + count);
3887            for (int i = 0; i < count; i++) {
3888                RILRequest rr = mRequestList.get(i);
3889                pw.println("  [" + rr.mSerial + "] " + requestToString(rr.mRequest));
3890            }
3891        }
3892        pw.println(" mLastNITZTimeInfo=" + mLastNITZTimeInfo);
3893        pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get());
3894    }
3895}
3896