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