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