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