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