RIL.java revision c241cad754ecf27c96b09f1e585b8be341dfcb71
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony;
18
19import static com.android.internal.telephony.RILConstants.*;
20import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
21import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
22import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
23import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
24import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA;
25import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
26import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
27
28import android.content.BroadcastReceiver;
29import android.content.Context;
30import android.content.Intent;
31import android.content.IntentFilter;
32import android.net.ConnectivityManager;
33import android.net.LocalSocket;
34import android.net.LocalSocketAddress;
35import android.os.AsyncResult;
36import android.os.Handler;
37import android.os.HandlerThread;
38import android.os.Looper;
39import android.os.Message;
40import android.os.Parcel;
41import android.os.PowerManager;
42import android.os.SystemProperties;
43import android.os.PowerManager.WakeLock;
44import android.telephony.NeighboringCellInfo;
45import android.telephony.PhoneNumberUtils;
46import android.telephony.SignalStrength;
47import android.telephony.SmsManager;
48import android.telephony.SmsMessage;
49import android.text.TextUtils;
50import android.telephony.Rlog;
51
52import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
53import com.android.internal.telephony.gsm.SuppServiceNotification;
54import com.android.internal.telephony.uicc.IccCardApplicationStatus;
55import com.android.internal.telephony.uicc.IccCardStatus;
56import com.android.internal.telephony.uicc.IccIoResult;
57import com.android.internal.telephony.uicc.IccRefreshResponse;
58import com.android.internal.telephony.uicc.IccUtils;
59import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
60import com.android.internal.telephony.cdma.CdmaInformationRecords;
61
62import java.io.ByteArrayInputStream;
63import java.io.DataInputStream;
64import java.io.FileDescriptor;
65import java.io.IOException;
66import java.io.InputStream;
67import java.io.PrintWriter;
68import java.util.ArrayList;
69import java.util.Collections;
70import java.util.concurrent.atomic.AtomicBoolean;
71
72/**
73 * {@hide}
74 */
75class RILRequest {
76    static final String LOG_TAG = "RILJ";
77
78    //***** Class Variables
79    static int sNextSerial = 0;
80    static Object sSerialMonitor = new Object();
81    private static Object sPoolSync = new Object();
82    private static RILRequest sPool = null;
83    private static int sPoolSize = 0;
84    private static final int MAX_POOL_SIZE = 4;
85
86    //***** Instance Variables
87    int mSerial;
88    int mRequest;
89    Message mResult;
90    Parcel mp;
91    RILRequest mNext;
92
93    /**
94     * Retrieves a new RILRequest instance from the pool.
95     *
96     * @param request RIL_REQUEST_*
97     * @param result sent when operation completes
98     * @return a RILRequest instance from the pool.
99     */
100    static RILRequest obtain(int request, Message result) {
101        RILRequest rr = null;
102
103        synchronized(sPoolSync) {
104            if (sPool != null) {
105                rr = sPool;
106                sPool = rr.mNext;
107                rr.mNext = null;
108                sPoolSize--;
109            }
110        }
111
112        if (rr == null) {
113            rr = new RILRequest();
114        }
115
116        synchronized(sSerialMonitor) {
117            rr.mSerial = sNextSerial++;
118        }
119        rr.mRequest = request;
120        rr.mResult = result;
121        rr.mp = Parcel.obtain();
122
123        if (result != null && result.getTarget() == null) {
124            throw new NullPointerException("Message target must not be null");
125        }
126
127        // first elements in any RIL Parcel
128        rr.mp.writeInt(request);
129        rr.mp.writeInt(rr.mSerial);
130
131        return rr;
132    }
133
134    /**
135     * Returns a RILRequest instance to the pool.
136     *
137     * Note: This should only be called once per use.
138     */
139    void release() {
140        synchronized (sPoolSync) {
141            if (sPoolSize < MAX_POOL_SIZE) {
142                this.mNext = sPool;
143                sPool = this;
144                sPoolSize++;
145                mResult = null;
146            }
147        }
148    }
149
150    private RILRequest() {
151    }
152
153    static void
154    resetSerial() {
155        synchronized(sSerialMonitor) {
156            sNextSerial = 0;
157        }
158    }
159
160    String
161    serialString() {
162        //Cheesy way to do %04d
163        StringBuilder sb = new StringBuilder(8);
164        String sn;
165
166        sn = Integer.toString(mSerial);
167
168        //sb.append("J[");
169        sb.append('[');
170        for (int i = 0, s = sn.length() ; i < 4 - s; i++) {
171            sb.append('0');
172        }
173
174        sb.append(sn);
175        sb.append(']');
176        return sb.toString();
177    }
178
179    void
180    onError(int error, Object ret) {
181        CommandException ex;
182
183        ex = CommandException.fromRilErrno(error);
184
185        if (RIL.RILJ_LOGD) Rlog.d(LOG_TAG, serialString() + "< "
186            + RIL.requestToString(mRequest)
187            + " error: " + ex);
188
189        if (mResult != null) {
190            AsyncResult.forMessage(mResult, ret, ex);
191            mResult.sendToTarget();
192        }
193
194        if (mp != null) {
195            mp.recycle();
196            mp = null;
197        }
198    }
199}
200
201
202/**
203 * RIL implementation of the CommandsInterface.
204 *
205 * {@hide}
206 */
207public final class RIL extends BaseCommands implements CommandsInterface {
208    static final String LOG_TAG = "RILJ";
209    static final boolean RILJ_LOGD = true;
210    static final boolean RILJ_LOGV = false; // STOP SHIP if true
211
212    /**
213     * Wake lock timeout should be longer than the longest timeout in
214     * the vendor ril.
215     */
216    private static final int DEFAULT_WAKE_LOCK_TIMEOUT = 60000;
217
218    //***** Instance Variables
219
220    LocalSocket mSocket;
221    HandlerThread mSenderThread;
222    RILSender mSender;
223    Thread mReceiverThread;
224    RILReceiver mReceiver;
225    WakeLock mWakeLock;
226    int mWakeLockTimeout;
227    // The number of requests pending to be sent out, it increases before calling
228    // EVENT_SEND and decreases while handling EVENT_SEND. It gets cleared while
229    // WAKE_LOCK_TIMEOUT occurs.
230    int mRequestMessagesPending;
231    // The number of requests sent out but waiting for response. It increases while
232    // sending request and decreases while handling response. It should match
233    // mRequestList.size() unless there are requests no replied while
234    // WAKE_LOCK_TIMEOUT occurs.
235    int mRequestMessagesWaiting;
236
237    //I'd rather this be LinkedList or something
238    ArrayList<RILRequest> mRequestList = new ArrayList<RILRequest>();
239
240    Object     mLastNITZTimeInfo;
241
242    // When we are testing emergency calls
243    AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
244
245    //***** Events
246
247    static final int EVENT_SEND                 = 1;
248    static final int EVENT_WAKE_LOCK_TIMEOUT    = 2;
249
250    //***** Constants
251
252    // match with constant in ril.cpp
253    static final int RIL_MAX_COMMAND_BYTES = (8 * 1024);
254    static final int RESPONSE_SOLICITED = 0;
255    static final int RESPONSE_UNSOLICITED = 1;
256
257    static final String SOCKET_NAME_RIL = "rild";
258
259    static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000;
260
261    // The number of the required config values for broadcast SMS stored in the C struct
262    // RIL_CDMA_BroadcastServiceInfo
263    private static final int CDMA_BSI_NO_OF_INTS_STRUCT = 3;
264
265    private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31;
266
267    BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
268        @Override
269        public void onReceive(Context context, Intent intent) {
270            if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
271                sendScreenState(true);
272            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
273                sendScreenState(false);
274            } else {
275                Rlog.w(LOG_TAG, "RIL received unexpected Intent: " + intent.getAction());
276            }
277        }
278    };
279
280    class RILSender extends Handler implements Runnable {
281        public RILSender(Looper looper) {
282            super(looper);
283        }
284
285        // Only allocated once
286        byte[] dataLength = new byte[4];
287
288        //***** Runnable implementation
289        public void
290        run() {
291            //setup if needed
292        }
293
294
295        //***** Handler implementation
296        @Override public void
297        handleMessage(Message msg) {
298            RILRequest rr = (RILRequest)(msg.obj);
299            RILRequest req = null;
300
301            switch (msg.what) {
302                case EVENT_SEND:
303                    /**
304                     * mRequestMessagePending++ already happened for every
305                     * EVENT_SEND, thus we must make sure
306                     * mRequestMessagePending-- happens once and only once
307                     */
308                    boolean alreadySubtracted = false;
309                    try {
310                        LocalSocket s;
311
312                        s = mSocket;
313
314                        if (s == null) {
315                            rr.onError(RADIO_NOT_AVAILABLE, null);
316                            rr.release();
317                            if (mRequestMessagesPending > 0)
318                                mRequestMessagesPending--;
319                            alreadySubtracted = true;
320                            return;
321                        }
322
323                        synchronized (mRequestList) {
324                            mRequestList.add(rr);
325                            mRequestMessagesWaiting++;
326                        }
327
328                        if (mRequestMessagesPending > 0)
329                            mRequestMessagesPending--;
330                        alreadySubtracted = true;
331
332                        byte[] data;
333
334                        data = rr.mp.marshall();
335                        rr.mp.recycle();
336                        rr.mp = null;
337
338                        if (data.length > RIL_MAX_COMMAND_BYTES) {
339                            throw new RuntimeException(
340                                    "Parcel larger than max bytes allowed! "
341                                                          + data.length);
342                        }
343
344                        // parcel length in big endian
345                        dataLength[0] = dataLength[1] = 0;
346                        dataLength[2] = (byte)((data.length >> 8) & 0xff);
347                        dataLength[3] = (byte)((data.length) & 0xff);
348
349                        //Rlog.v(LOG_TAG, "writing packet: " + data.length + " bytes");
350
351                        s.getOutputStream().write(dataLength);
352                        s.getOutputStream().write(data);
353                    } catch (IOException ex) {
354                        Rlog.e(LOG_TAG, "IOException", ex);
355                        req = findAndRemoveRequestFromList(rr.mSerial);
356                        // make sure this request has not already been handled,
357                        // eg, if RILReceiver cleared the list.
358                        if (req != null || !alreadySubtracted) {
359                            rr.onError(RADIO_NOT_AVAILABLE, null);
360                            rr.release();
361                        }
362                    } catch (RuntimeException exc) {
363                        Rlog.e(LOG_TAG, "Uncaught exception ", exc);
364                        req = findAndRemoveRequestFromList(rr.mSerial);
365                        // make sure this request has not already been handled,
366                        // eg, if RILReceiver cleared the list.
367                        if (req != null || !alreadySubtracted) {
368                            rr.onError(GENERIC_FAILURE, null);
369                            rr.release();
370                        }
371                    } finally {
372                        // Note: We are "Done" only if there are no outstanding
373                        // requests or replies. Thus this code path will only release
374                        // the wake lock on errors.
375                        releaseWakeLockIfDone();
376                    }
377
378                    if (!alreadySubtracted && mRequestMessagesPending > 0) {
379                        mRequestMessagesPending--;
380                    }
381
382                    break;
383
384                case EVENT_WAKE_LOCK_TIMEOUT:
385                    // Haven't heard back from the last request.  Assume we're
386                    // not getting a response and  release the wake lock.
387                    synchronized (mWakeLock) {
388                        if (mWakeLock.isHeld()) {
389                            // The timer of WAKE_LOCK_TIMEOUT is reset with each
390                            // new send request. So when WAKE_LOCK_TIMEOUT occurs
391                            // all requests in mRequestList already waited at
392                            // least DEFAULT_WAKE_LOCK_TIMEOUT but no response.
393                            // Reset mRequestMessagesWaiting to enable
394                            // releaseWakeLockIfDone().
395                            //
396                            // Note: Keep mRequestList so that delayed response
397                            // can still be handled when response finally comes.
398                            if (mRequestMessagesWaiting != 0) {
399                                Rlog.d(LOG_TAG, "NOTE: mReqWaiting is NOT 0 but"
400                                        + mRequestMessagesWaiting + " at TIMEOUT, reset!"
401                                        + " There still msg waitng for response");
402
403                                mRequestMessagesWaiting = 0;
404
405                                if (RILJ_LOGD) {
406                                    synchronized (mRequestList) {
407                                        int count = mRequestList.size();
408                                        Rlog.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
409                                                " mRequestList=" + count);
410
411                                        for (int i = 0; i < count; i++) {
412                                            rr = mRequestList.get(i);
413                                            Rlog.d(LOG_TAG, i + ": [" + rr.mSerial + "] "
414                                                    + requestToString(rr.mRequest));
415                                        }
416                                    }
417                                }
418                            }
419                            // mRequestMessagesPending shows how many
420                            // requests are waiting to be sent (and before
421                            // to be added in request list) since star the
422                            // WAKE_LOCK_TIMEOUT timer. Since WAKE_LOCK_TIMEOUT
423                            // is the expected time to get response, all requests
424                            // should already sent out (i.e.
425                            // mRequestMessagesPending is 0 )while TIMEOUT occurs.
426                            if (mRequestMessagesPending != 0) {
427                                Rlog.e(LOG_TAG, "ERROR: mReqPending is NOT 0 but"
428                                        + mRequestMessagesPending + " at TIMEOUT, reset!");
429                                mRequestMessagesPending = 0;
430
431                            }
432                            mWakeLock.release();
433                        }
434                    }
435                    break;
436            }
437        }
438    }
439
440    /**
441     * Reads in a single RIL message off the wire. A RIL message consists
442     * of a 4-byte little-endian length and a subsequent series of bytes.
443     * The final message (length header omitted) is read into
444     * <code>buffer</code> and the length of the final message (less header)
445     * is returned. A return value of -1 indicates end-of-stream.
446     *
447     * @param is non-null; Stream to read from
448     * @param buffer Buffer to fill in. Must be as large as maximum
449     * message size, or an ArrayOutOfBounds exception will be thrown.
450     * @return Length of message less header, or -1 on end of stream.
451     * @throws IOException
452     */
453    private static int readRilMessage(InputStream is, byte[] buffer)
454            throws IOException {
455        int countRead;
456        int offset;
457        int remaining;
458        int messageLength;
459
460        // First, read in the length of the message
461        offset = 0;
462        remaining = 4;
463        do {
464            countRead = is.read(buffer, offset, remaining);
465
466            if (countRead < 0 ) {
467                Rlog.e(LOG_TAG, "Hit EOS reading message length");
468                return -1;
469            }
470
471            offset += countRead;
472            remaining -= countRead;
473        } while (remaining > 0);
474
475        messageLength = ((buffer[0] & 0xff) << 24)
476                | ((buffer[1] & 0xff) << 16)
477                | ((buffer[2] & 0xff) << 8)
478                | (buffer[3] & 0xff);
479
480        // Then, re-use the buffer and read in the message itself
481        offset = 0;
482        remaining = messageLength;
483        do {
484            countRead = is.read(buffer, offset, remaining);
485
486            if (countRead < 0 ) {
487                Rlog.e(LOG_TAG, "Hit EOS reading message.  messageLength=" + messageLength
488                        + " remaining=" + remaining);
489                return -1;
490            }
491
492            offset += countRead;
493            remaining -= countRead;
494        } while (remaining > 0);
495
496        return messageLength;
497    }
498
499    class RILReceiver implements Runnable {
500        byte[] buffer;
501
502        RILReceiver() {
503            buffer = new byte[RIL_MAX_COMMAND_BYTES];
504        }
505
506        public void
507        run() {
508            int retryCount = 0;
509
510            try {for (;;) {
511                LocalSocket s = null;
512                LocalSocketAddress l;
513
514                try {
515                    s = new LocalSocket();
516                    l = new LocalSocketAddress(SOCKET_NAME_RIL,
517                            LocalSocketAddress.Namespace.RESERVED);
518                    s.connect(l);
519                } catch (IOException ex){
520                    try {
521                        if (s != null) {
522                            s.close();
523                        }
524                    } catch (IOException ex2) {
525                        //ignore failure to close after failure to connect
526                    }
527
528                    // don't print an error message after the the first time
529                    // or after the 8th time
530
531                    if (retryCount == 8) {
532                        Rlog.e (LOG_TAG,
533                            "Couldn't find '" + SOCKET_NAME_RIL
534                            + "' socket after " + retryCount
535                            + " times, continuing to retry silently");
536                    } else if (retryCount > 0 && retryCount < 8) {
537                        Rlog.i (LOG_TAG,
538                            "Couldn't find '" + SOCKET_NAME_RIL
539                            + "' socket; retrying after timeout");
540                    }
541
542                    try {
543                        Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
544                    } catch (InterruptedException er) {
545                    }
546
547                    retryCount++;
548                    continue;
549                }
550
551                retryCount = 0;
552
553                mSocket = s;
554                Rlog.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");
555
556                int length = 0;
557                try {
558                    InputStream is = mSocket.getInputStream();
559
560                    for (;;) {
561                        Parcel p;
562
563                        length = readRilMessage(is, buffer);
564
565                        if (length < 0) {
566                            // End-of-stream reached
567                            break;
568                        }
569
570                        p = Parcel.obtain();
571                        p.unmarshall(buffer, 0, length);
572                        p.setDataPosition(0);
573
574                        //Rlog.v(LOG_TAG, "Read packet: " + length + " bytes");
575
576                        processResponse(p);
577                        p.recycle();
578                    }
579                } catch (java.io.IOException ex) {
580                    Rlog.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",
581                          ex);
582                } catch (Throwable tr) {
583                    Rlog.e(LOG_TAG, "Uncaught exception read length=" + length +
584                        "Exception:" + tr.toString());
585                }
586
587                Rlog.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL
588                      + "' socket");
589
590                setRadioState (RadioState.RADIO_UNAVAILABLE);
591
592                try {
593                    mSocket.close();
594                } catch (IOException ex) {
595                }
596
597                mSocket = null;
598                RILRequest.resetSerial();
599
600                // Clear request list on close
601                clearRequestList(RADIO_NOT_AVAILABLE, false);
602            }} catch (Throwable tr) {
603                Rlog.e(LOG_TAG,"Uncaught exception", tr);
604            }
605
606            /* We're disconnected so we don't know the ril version */
607            notifyRegistrantsRilConnectionChanged(-1);
608        }
609    }
610
611
612
613    //***** Constructors
614
615    public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
616        super(context);
617        if (RILJ_LOGD) {
618            riljLog("RIL(context, preferredNetworkType=" + preferredNetworkType +
619                    " cdmaSubscription=" + cdmaSubscription + ")");
620        }
621        mCdmaSubscription  = cdmaSubscription;
622        mPreferredNetworkType = preferredNetworkType;
623        mPhoneType = RILConstants.NO_PHONE;
624
625        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
626        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
627        mWakeLock.setReferenceCounted(false);
628        mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,
629                DEFAULT_WAKE_LOCK_TIMEOUT);
630        mRequestMessagesPending = 0;
631        mRequestMessagesWaiting = 0;
632
633        mSenderThread = new HandlerThread("RILSender");
634        mSenderThread.start();
635
636        Looper looper = mSenderThread.getLooper();
637        mSender = new RILSender(looper);
638
639        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
640                Context.CONNECTIVITY_SERVICE);
641        if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
642            riljLog("Not starting RILReceiver: wifi-only");
643        } if (SystemProperties.getBoolean("ro.radio.noril", false)) {
644            riljLog("Not starting RILReceiver: basebandless target");
645        } else {
646            riljLog("Starting RILReceiver");
647            mReceiver = new RILReceiver();
648            mReceiverThread = new Thread(mReceiver, "RILReceiver");
649            mReceiverThread.start();
650
651            IntentFilter filter = new IntentFilter();
652            filter.addAction(Intent.ACTION_SCREEN_ON);
653            filter.addAction(Intent.ACTION_SCREEN_OFF);
654            context.registerReceiver(mIntentReceiver, filter);
655        }
656    }
657
658    //***** CommandsInterface implementation
659
660    public void getVoiceRadioTechnology(Message result) {
661        RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_RADIO_TECH, result);
662
663        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
664
665        send(rr);
666    }
667
668
669    @Override public void
670    setOnNITZTime(Handler h, int what, Object obj) {
671        super.setOnNITZTime(h, what, obj);
672
673        // Send the last NITZ time if we have it
674        if (mLastNITZTimeInfo != null) {
675            mNITZTimeRegistrant
676                .notifyRegistrant(
677                    new AsyncResult (null, mLastNITZTimeInfo, null));
678            mLastNITZTimeInfo = null;
679        }
680    }
681
682    public void
683    getIccCardStatus(Message result) {
684        //Note: This RIL request has not been renamed to ICC,
685        //       but this request is also valid for SIM and RUIM
686        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result);
687
688        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
689
690        send(rr);
691    }
692
693    @Override public void
694    supplyIccPin(String pin, Message result) {
695        supplyIccPinForApp(pin, null, result);
696    }
697
698    @Override public void
699    supplyIccPinForApp(String pin, String aid, Message result) {
700        //Note: This RIL request has not been renamed to ICC,
701        //       but this request is also valid for SIM and RUIM
702        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result);
703
704        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
705
706        rr.mp.writeInt(2);
707        rr.mp.writeString(pin);
708        rr.mp.writeString(aid);
709
710        send(rr);
711    }
712
713    @Override public void
714    supplyIccPuk(String puk, String newPin, Message result) {
715        supplyIccPukForApp(puk, newPin, null, result);
716    }
717
718    @Override public void
719    supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
720        //Note: This RIL request has not been renamed to ICC,
721        //       but this request is also valid for SIM and RUIM
722        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result);
723
724        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
725
726        rr.mp.writeInt(3);
727        rr.mp.writeString(puk);
728        rr.mp.writeString(newPin);
729        rr.mp.writeString(aid);
730
731        send(rr);
732    }
733
734    @Override public void
735    supplyIccPin2(String pin, Message result) {
736        supplyIccPin2ForApp(pin, null, result);
737    }
738
739    @Override public void
740    supplyIccPin2ForApp(String pin, String aid, Message result) {
741        //Note: This RIL request has not been renamed to ICC,
742        //       but this request is also valid for SIM and RUIM
743        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result);
744
745        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
746
747        rr.mp.writeInt(2);
748        rr.mp.writeString(pin);
749        rr.mp.writeString(aid);
750
751        send(rr);
752    }
753
754    @Override public void
755    supplyIccPuk2(String puk2, String newPin2, Message result) {
756        supplyIccPuk2ForApp(puk2, newPin2, null, result);
757    }
758
759    @Override public void
760    supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
761        //Note: This RIL request has not been renamed to ICC,
762        //       but this request is also valid for SIM and RUIM
763        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result);
764
765        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
766
767        rr.mp.writeInt(3);
768        rr.mp.writeString(puk);
769        rr.mp.writeString(newPin2);
770        rr.mp.writeString(aid);
771
772        send(rr);
773    }
774
775    @Override public void
776    changeIccPin(String oldPin, String newPin, Message result) {
777        changeIccPinForApp(oldPin, newPin, null, result);
778    }
779
780    @Override public void
781    changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
782        //Note: This RIL request has not been renamed to ICC,
783        //       but this request is also valid for SIM and RUIM
784        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result);
785
786        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
787
788        rr.mp.writeInt(3);
789        rr.mp.writeString(oldPin);
790        rr.mp.writeString(newPin);
791        rr.mp.writeString(aid);
792
793        send(rr);
794    }
795
796    @Override public void
797    changeIccPin2(String oldPin2, String newPin2, Message result) {
798        changeIccPin2ForApp(oldPin2, newPin2, null, result);
799    }
800
801    @Override public void
802    changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
803        //Note: This RIL request has not been renamed to ICC,
804        //       but this request is also valid for SIM and RUIM
805        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result);
806
807        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
808
809        rr.mp.writeInt(3);
810        rr.mp.writeString(oldPin2);
811        rr.mp.writeString(newPin2);
812        rr.mp.writeString(aid);
813
814        send(rr);
815    }
816
817    public void
818    changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) {
819        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result);
820
821        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
822
823        rr.mp.writeInt(3);
824        rr.mp.writeString(facility);
825        rr.mp.writeString(oldPwd);
826        rr.mp.writeString(newPwd);
827
828        send(rr);
829    }
830
831    public void
832    supplyNetworkDepersonalization(String netpin, Message result) {
833        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result);
834
835        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
836
837        rr.mp.writeInt(1);
838        rr.mp.writeString(netpin);
839
840        send(rr);
841    }
842
843    public void
844    getCurrentCalls (Message result) {
845        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);
846
847        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
848
849        send(rr);
850    }
851
852    @Deprecated public void
853    getPDPContextList(Message result) {
854        getDataCallList(result);
855    }
856
857    public void
858    getDataCallList(Message result) {
859        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_CALL_LIST, result);
860
861        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
862
863        send(rr);
864    }
865
866    public void
867    dial (String address, int clirMode, Message result) {
868        dial(address, clirMode, null, result);
869    }
870
871    public void
872    dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
873        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
874
875        rr.mp.writeString(address);
876        rr.mp.writeInt(clirMode);
877        rr.mp.writeInt(0); // UUS information is absent
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        // TODO: Should query Power Manager and send the actual
2060        // screen state.  Just send true for now.
2061        sendScreenState(true);
2062   }
2063
2064    private RadioState getRadioStateFromInt(int stateInt) {
2065        RadioState state;
2066
2067        /* RIL_RadioState ril.h */
2068        switch(stateInt) {
2069            case 0: state = RadioState.RADIO_OFF; break;
2070            case 1: state = RadioState.RADIO_UNAVAILABLE; break;
2071            case 10: state = RadioState.RADIO_ON; break;
2072
2073            default:
2074                throw new RuntimeException(
2075                            "Unrecognized RIL_RadioState: " + stateInt);
2076        }
2077        return state;
2078    }
2079
2080    private void switchToRadioState(RadioState newState) {
2081        setRadioState(newState);
2082    }
2083
2084    /**
2085     * Holds a PARTIAL_WAKE_LOCK whenever
2086     * a) There is outstanding RIL request sent to RIL deamon and no replied
2087     * b) There is a request pending to be sent out.
2088     *
2089     * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
2090     * happen often.
2091     */
2092
2093    private void
2094    acquireWakeLock() {
2095        synchronized (mWakeLock) {
2096            mWakeLock.acquire();
2097            mRequestMessagesPending++;
2098
2099            mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
2100            Message msg = mSender.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
2101            mSender.sendMessageDelayed(msg, mWakeLockTimeout);
2102        }
2103    }
2104
2105    private void
2106    releaseWakeLockIfDone() {
2107        synchronized (mWakeLock) {
2108            if (mWakeLock.isHeld() &&
2109                (mRequestMessagesPending == 0) &&
2110                (mRequestMessagesWaiting == 0)) {
2111                mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
2112                mWakeLock.release();
2113            }
2114        }
2115    }
2116
2117    private void
2118    send(RILRequest rr) {
2119        Message msg;
2120
2121        if (mSocket == null) {
2122            rr.onError(RADIO_NOT_AVAILABLE, null);
2123            rr.release();
2124            return;
2125        }
2126
2127        msg = mSender.obtainMessage(EVENT_SEND, rr);
2128
2129        acquireWakeLock();
2130
2131        msg.sendToTarget();
2132    }
2133
2134    private void
2135    processResponse (Parcel p) {
2136        int type;
2137
2138        type = p.readInt();
2139
2140        if (type == RESPONSE_UNSOLICITED) {
2141            processUnsolicited (p);
2142        } else if (type == RESPONSE_SOLICITED) {
2143            processSolicited (p);
2144        }
2145
2146        releaseWakeLockIfDone();
2147    }
2148
2149    /**
2150     * Release each request in mRequestList then clear the list
2151     * @param error is the RIL_Errno sent back
2152     * @param loggable true means to print all requests in mRequestList
2153     */
2154    private void clearRequestList(int error, boolean loggable) {
2155        RILRequest rr;
2156        synchronized (mRequestList) {
2157            int count = mRequestList.size();
2158            if (RILJ_LOGD && loggable) {
2159                Rlog.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
2160                        " mReqPending=" + mRequestMessagesPending +
2161                        " mRequestList=" + count);
2162            }
2163
2164            for (int i = 0; i < count ; i++) {
2165                rr = mRequestList.get(i);
2166                if (RILJ_LOGD && loggable) {
2167                    Rlog.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
2168                            requestToString(rr.mRequest));
2169                }
2170                rr.onError(error, null);
2171                rr.release();
2172            }
2173            mRequestList.clear();
2174            mRequestMessagesWaiting = 0;
2175        }
2176    }
2177
2178    private RILRequest findAndRemoveRequestFromList(int serial) {
2179        synchronized (mRequestList) {
2180            for (int i = 0, s = mRequestList.size() ; i < s ; i++) {
2181                RILRequest rr = mRequestList.get(i);
2182
2183                if (rr.mSerial == serial) {
2184                    mRequestList.remove(i);
2185                    if (mRequestMessagesWaiting > 0)
2186                        mRequestMessagesWaiting--;
2187                    return rr;
2188                }
2189            }
2190        }
2191
2192        return null;
2193    }
2194
2195    private void
2196    processSolicited (Parcel p) {
2197        int serial, error;
2198        boolean found = false;
2199
2200        serial = p.readInt();
2201        error = p.readInt();
2202
2203        RILRequest rr;
2204
2205        rr = findAndRemoveRequestFromList(serial);
2206
2207        if (rr == null) {
2208            Rlog.w(LOG_TAG, "Unexpected solicited response! sn: "
2209                            + serial + " error: " + error);
2210            return;
2211        }
2212
2213        Object ret = null;
2214
2215        if (error == 0 || p.dataAvail() > 0) {
2216            // either command succeeds or command fails but with data payload
2217            try {switch (rr.mRequest) {
2218            /*
2219 cat libs/telephony/ril_commands.h \
2220 | egrep "^ *{RIL_" \
2221 | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
2222             */
2223            case RIL_REQUEST_GET_SIM_STATUS: ret =  responseIccCardStatus(p); break;
2224            case RIL_REQUEST_ENTER_SIM_PIN: ret =  responseInts(p); break;
2225            case RIL_REQUEST_ENTER_SIM_PUK: ret =  responseInts(p); break;
2226            case RIL_REQUEST_ENTER_SIM_PIN2: ret =  responseInts(p); break;
2227            case RIL_REQUEST_ENTER_SIM_PUK2: ret =  responseInts(p); break;
2228            case RIL_REQUEST_CHANGE_SIM_PIN: ret =  responseInts(p); break;
2229            case RIL_REQUEST_CHANGE_SIM_PIN2: ret =  responseInts(p); break;
2230            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret =  responseInts(p); break;
2231            case RIL_REQUEST_GET_CURRENT_CALLS: ret =  responseCallList(p); break;
2232            case RIL_REQUEST_DIAL: ret =  responseVoid(p); break;
2233            case RIL_REQUEST_GET_IMSI: ret =  responseString(p); break;
2234            case RIL_REQUEST_HANGUP: ret =  responseVoid(p); break;
2235            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret =  responseVoid(p); break;
2236            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: {
2237                if (mTestingEmergencyCall.getAndSet(false)) {
2238                    if (mEmergencyCallbackModeRegistrant != null) {
2239                        riljLog("testing emergency call, notify ECM Registrants");
2240                        mEmergencyCallbackModeRegistrant.notifyRegistrant();
2241                    }
2242                }
2243                ret =  responseVoid(p);
2244                break;
2245            }
2246            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret =  responseVoid(p); break;
2247            case RIL_REQUEST_CONFERENCE: ret =  responseVoid(p); break;
2248            case RIL_REQUEST_UDUB: ret =  responseVoid(p); break;
2249            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret =  responseInts(p); break;
2250            case RIL_REQUEST_SIGNAL_STRENGTH: ret =  responseSignalStrength(p); break;
2251            case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret =  responseStrings(p); break;
2252            case RIL_REQUEST_DATA_REGISTRATION_STATE: ret =  responseStrings(p); break;
2253            case RIL_REQUEST_OPERATOR: ret =  responseStrings(p); break;
2254            case RIL_REQUEST_RADIO_POWER: ret =  responseVoid(p); break;
2255            case RIL_REQUEST_DTMF: ret =  responseVoid(p); break;
2256            case RIL_REQUEST_SEND_SMS: ret =  responseSMS(p); break;
2257            case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret =  responseSMS(p); break;
2258            case RIL_REQUEST_SETUP_DATA_CALL: ret =  responseSetupDataCall(p); break;
2259            case RIL_REQUEST_SIM_IO: ret =  responseICC_IO(p); break;
2260            case RIL_REQUEST_SEND_USSD: ret =  responseVoid(p); break;
2261            case RIL_REQUEST_CANCEL_USSD: ret =  responseVoid(p); break;
2262            case RIL_REQUEST_GET_CLIR: ret =  responseInts(p); break;
2263            case RIL_REQUEST_SET_CLIR: ret =  responseVoid(p); break;
2264            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret =  responseCallForward(p); break;
2265            case RIL_REQUEST_SET_CALL_FORWARD: ret =  responseVoid(p); break;
2266            case RIL_REQUEST_QUERY_CALL_WAITING: ret =  responseInts(p); break;
2267            case RIL_REQUEST_SET_CALL_WAITING: ret =  responseVoid(p); break;
2268            case RIL_REQUEST_SMS_ACKNOWLEDGE: ret =  responseVoid(p); break;
2269            case RIL_REQUEST_GET_IMEI: ret =  responseString(p); break;
2270            case RIL_REQUEST_GET_IMEISV: ret =  responseString(p); break;
2271            case RIL_REQUEST_ANSWER: ret =  responseVoid(p); break;
2272            case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret =  responseVoid(p); break;
2273            case RIL_REQUEST_QUERY_FACILITY_LOCK: ret =  responseInts(p); break;
2274            case RIL_REQUEST_SET_FACILITY_LOCK: ret =  responseInts(p); break;
2275            case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret =  responseVoid(p); break;
2276            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret =  responseInts(p); break;
2277            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret =  responseVoid(p); break;
2278            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret =  responseVoid(p); break;
2279            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret =  responseOperatorInfos(p); break;
2280            case RIL_REQUEST_DTMF_START: ret =  responseVoid(p); break;
2281            case RIL_REQUEST_DTMF_STOP: ret =  responseVoid(p); break;
2282            case RIL_REQUEST_BASEBAND_VERSION: ret =  responseString(p); break;
2283            case RIL_REQUEST_SEPARATE_CONNECTION: ret =  responseVoid(p); break;
2284            case RIL_REQUEST_SET_MUTE: ret =  responseVoid(p); break;
2285            case RIL_REQUEST_GET_MUTE: ret =  responseInts(p); break;
2286            case RIL_REQUEST_QUERY_CLIP: ret =  responseInts(p); break;
2287            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret =  responseInts(p); break;
2288            case RIL_REQUEST_DATA_CALL_LIST: ret =  responseDataCallList(p); break;
2289            case RIL_REQUEST_RESET_RADIO: ret =  responseVoid(p); break;
2290            case RIL_REQUEST_OEM_HOOK_RAW: ret =  responseRaw(p); break;
2291            case RIL_REQUEST_OEM_HOOK_STRINGS: ret =  responseStrings(p); break;
2292            case RIL_REQUEST_SCREEN_STATE: ret =  responseVoid(p); break;
2293            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret =  responseVoid(p); break;
2294            case RIL_REQUEST_WRITE_SMS_TO_SIM: ret =  responseInts(p); break;
2295            case RIL_REQUEST_DELETE_SMS_ON_SIM: ret =  responseVoid(p); break;
2296            case RIL_REQUEST_SET_BAND_MODE: ret =  responseVoid(p); break;
2297            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret =  responseInts(p); break;
2298            case RIL_REQUEST_STK_GET_PROFILE: ret =  responseString(p); break;
2299            case RIL_REQUEST_STK_SET_PROFILE: ret =  responseVoid(p); break;
2300            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret =  responseString(p); break;
2301            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret =  responseVoid(p); break;
2302            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret =  responseInts(p); break;
2303            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret =  responseVoid(p); break;
2304            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret =  responseVoid(p); break;
2305            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret =  responseGetPreferredNetworkType(p); break;
2306            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
2307            case RIL_REQUEST_SET_LOCATION_UPDATES: ret =  responseVoid(p); break;
2308            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret =  responseVoid(p); break;
2309            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret =  responseVoid(p); break;
2310            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret =  responseInts(p); break;
2311            case RIL_REQUEST_SET_TTY_MODE: ret =  responseVoid(p); break;
2312            case RIL_REQUEST_QUERY_TTY_MODE: ret =  responseInts(p); break;
2313            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret =  responseVoid(p); break;
2314            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret =  responseInts(p); break;
2315            case RIL_REQUEST_CDMA_FLASH: ret =  responseVoid(p); break;
2316            case RIL_REQUEST_CDMA_BURST_DTMF: ret =  responseVoid(p); break;
2317            case RIL_REQUEST_CDMA_SEND_SMS: ret =  responseSMS(p); break;
2318            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret =  responseVoid(p); break;
2319            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret =  responseGmsBroadcastConfig(p); break;
2320            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret =  responseVoid(p); break;
2321            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret =  responseVoid(p); break;
2322            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret =  responseCdmaBroadcastConfig(p); break;
2323            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret =  responseVoid(p); break;
2324            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret =  responseVoid(p); break;
2325            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret =  responseVoid(p); break;
2326            case RIL_REQUEST_CDMA_SUBSCRIPTION: ret =  responseStrings(p); break;
2327            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret =  responseInts(p); break;
2328            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret =  responseVoid(p); break;
2329            case RIL_REQUEST_DEVICE_IDENTITY: ret =  responseStrings(p); break;
2330            case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
2331            case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
2332            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2333            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
2334            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
2335            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret =  responseInts(p); break;
2336            case RIL_REQUEST_ISIM_AUTHENTICATION: ret =  responseString(p); break;
2337            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
2338            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
2339            case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break;
2340            default:
2341                throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
2342            //break;
2343            }} catch (Throwable tr) {
2344                // Exceptions here usually mean invalid RIL responses
2345
2346                Rlog.w(LOG_TAG, rr.serialString() + "< "
2347                        + requestToString(rr.mRequest)
2348                        + " exception, possible invalid RIL response", tr);
2349
2350                if (rr.mResult != null) {
2351                    AsyncResult.forMessage(rr.mResult, null, tr);
2352                    rr.mResult.sendToTarget();
2353                }
2354                rr.release();
2355                return;
2356            }
2357        }
2358
2359        // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789.
2360        // This is needed otherwise we don't automatically transition to the main lock
2361        // screen when the pin or puk is entered incorrectly.
2362        switch (rr.mRequest) {
2363            case RIL_REQUEST_ENTER_SIM_PUK:
2364            case RIL_REQUEST_ENTER_SIM_PUK2:
2365                if (mIccStatusChangedRegistrants != null) {
2366                    if (RILJ_LOGD) {
2367                        riljLog("ON enter sim puk fakeSimStatusChanged: reg count="
2368                                + mIccStatusChangedRegistrants.size());
2369                    }
2370                    mIccStatusChangedRegistrants.notifyRegistrants();
2371                }
2372                break;
2373        }
2374
2375        if (error != 0) {
2376            switch (rr.mRequest) {
2377                case RIL_REQUEST_ENTER_SIM_PIN:
2378                case RIL_REQUEST_ENTER_SIM_PIN2:
2379                case RIL_REQUEST_CHANGE_SIM_PIN:
2380                case RIL_REQUEST_CHANGE_SIM_PIN2:
2381                case RIL_REQUEST_SET_FACILITY_LOCK:
2382                    if (mIccStatusChangedRegistrants != null) {
2383                        if (RILJ_LOGD) {
2384                            riljLog("ON some errors fakeSimStatusChanged: reg count="
2385                                    + mIccStatusChangedRegistrants.size());
2386                        }
2387                        mIccStatusChangedRegistrants.notifyRegistrants();
2388                    }
2389                    break;
2390            }
2391
2392            rr.onError(error, ret);
2393            rr.release();
2394            return;
2395        }
2396
2397        if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
2398            + " " + retToString(rr.mRequest, ret));
2399
2400        if (rr.mResult != null) {
2401            AsyncResult.forMessage(rr.mResult, ret, null);
2402            rr.mResult.sendToTarget();
2403        }
2404
2405        rr.release();
2406    }
2407
2408    private String
2409    retToString(int req, Object ret) {
2410        if (ret == null) return "";
2411        switch (req) {
2412            // Don't log these return values, for privacy's sake.
2413            case RIL_REQUEST_GET_IMSI:
2414            case RIL_REQUEST_GET_IMEI:
2415            case RIL_REQUEST_GET_IMEISV:
2416                if (!RILJ_LOGV) {
2417                    // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
2418                    return "";
2419                }
2420        }
2421
2422        StringBuilder sb;
2423        String s;
2424        int length;
2425        if (ret instanceof int[]){
2426            int[] intArray = (int[]) ret;
2427            length = intArray.length;
2428            sb = new StringBuilder("{");
2429            if (length > 0) {
2430                int i = 0;
2431                sb.append(intArray[i++]);
2432                while ( i < length) {
2433                    sb.append(", ").append(intArray[i++]);
2434                }
2435            }
2436            sb.append("}");
2437            s = sb.toString();
2438        } else if (ret instanceof String[]) {
2439            String[] strings = (String[]) ret;
2440            length = strings.length;
2441            sb = new StringBuilder("{");
2442            if (length > 0) {
2443                int i = 0;
2444                sb.append(strings[i++]);
2445                while ( i < length) {
2446                    sb.append(", ").append(strings[i++]);
2447                }
2448            }
2449            sb.append("}");
2450            s = sb.toString();
2451        }else if (req == RIL_REQUEST_GET_CURRENT_CALLS) {
2452            ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret;
2453            sb = new StringBuilder(" ");
2454            for (DriverCall dc : calls) {
2455                sb.append("[").append(dc).append("] ");
2456            }
2457            s = sb.toString();
2458        } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) {
2459            ArrayList<NeighboringCellInfo> cells;
2460            cells = (ArrayList<NeighboringCellInfo>) ret;
2461            sb = new StringBuilder(" ");
2462            for (NeighboringCellInfo cell : cells) {
2463                sb.append(cell).append(" ");
2464            }
2465            s = sb.toString();
2466        } else {
2467            s = ret.toString();
2468        }
2469        return s;
2470    }
2471
2472    private void
2473    processUnsolicited (Parcel p) {
2474        int response;
2475        Object ret;
2476
2477        response = p.readInt();
2478
2479        try {switch(response) {
2480/*
2481 cat libs/telephony/ril_unsol_commands.h \
2482 | egrep "^ *{RIL_" \
2483 | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
2484*/
2485
2486            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret =  responseVoid(p); break;
2487            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret =  responseVoid(p); break;
2488            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret =  responseVoid(p); break;
2489            case RIL_UNSOL_RESPONSE_NEW_SMS: ret =  responseString(p); break;
2490            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret =  responseString(p); break;
2491            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret =  responseInts(p); break;
2492            case RIL_UNSOL_ON_USSD: ret =  responseStrings(p); break;
2493            case RIL_UNSOL_NITZ_TIME_RECEIVED: ret =  responseString(p); break;
2494            case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
2495            case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
2496            case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
2497            case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
2498            case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
2499            case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
2500            case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
2501            case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret =  responseVoid(p); break;
2502            case RIL_UNSOL_SIM_REFRESH: ret =  responseSimRefresh(p); break;
2503            case RIL_UNSOL_CALL_RING: ret =  responseCallRing(p); break;
2504            case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
2505            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:  ret =  responseVoid(p); break;
2506            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:  ret =  responseCdmaSms(p); break;
2507            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:  ret =  responseRaw(p); break;
2508            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:  ret =  responseVoid(p); break;
2509            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2510            case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
2511            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
2512            case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
2513            case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
2514            case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
2515            case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
2516            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break;
2517            case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
2518            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
2519            case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
2520            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret =  responseInts(p); break;
2521
2522            default:
2523                throw new RuntimeException("Unrecognized unsol response: " + response);
2524            //break; (implied)
2525        }} catch (Throwable tr) {
2526            Rlog.e(LOG_TAG, "Exception processing unsol response: " + response +
2527                "Exception:" + tr.toString());
2528            return;
2529        }
2530
2531        switch(response) {
2532            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
2533                /* has bonus radio state int */
2534                RadioState newState = getRadioStateFromInt(p.readInt());
2535                if (RILJ_LOGD) unsljLogMore(response, newState.toString());
2536
2537                switchToRadioState(newState);
2538            break;
2539            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
2540                if (RILJ_LOGD) unsljLog(response);
2541
2542                mCallStateRegistrants
2543                    .notifyRegistrants(new AsyncResult(null, null, null));
2544            break;
2545            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
2546                if (RILJ_LOGD) unsljLog(response);
2547
2548                mVoiceNetworkStateRegistrants
2549                    .notifyRegistrants(new AsyncResult(null, null, null));
2550            break;
2551            case RIL_UNSOL_RESPONSE_NEW_SMS: {
2552                if (RILJ_LOGD) unsljLog(response);
2553
2554                // FIXME this should move up a layer
2555                String a[] = new String[2];
2556
2557                a[1] = (String)ret;
2558
2559                SmsMessage sms;
2560
2561                sms = SmsMessage.newFromCMT(a);
2562                if (mGsmSmsRegistrant != null) {
2563                    mGsmSmsRegistrant
2564                        .notifyRegistrant(new AsyncResult(null, sms, null));
2565                }
2566            break;
2567            }
2568            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
2569                if (RILJ_LOGD) unsljLogRet(response, ret);
2570
2571                if (mSmsStatusRegistrant != null) {
2572                    mSmsStatusRegistrant.notifyRegistrant(
2573                            new AsyncResult(null, ret, null));
2574                }
2575            break;
2576            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
2577                if (RILJ_LOGD) unsljLogRet(response, ret);
2578
2579                int[] smsIndex = (int[])ret;
2580
2581                if(smsIndex.length == 1) {
2582                    if (mSmsOnSimRegistrant != null) {
2583                        mSmsOnSimRegistrant.
2584                                notifyRegistrant(new AsyncResult(null, smsIndex, null));
2585                    }
2586                } else {
2587                    if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length "
2588                            + smsIndex.length);
2589                }
2590            break;
2591            case RIL_UNSOL_ON_USSD:
2592                String[] resp = (String[])ret;
2593
2594                if (resp.length < 2) {
2595                    resp = new String[2];
2596                    resp[0] = ((String[])ret)[0];
2597                    resp[1] = null;
2598                }
2599                if (RILJ_LOGD) unsljLogMore(response, resp[0]);
2600                if (mUSSDRegistrant != null) {
2601                    mUSSDRegistrant.notifyRegistrant(
2602                        new AsyncResult (null, resp, null));
2603                }
2604            break;
2605            case RIL_UNSOL_NITZ_TIME_RECEIVED:
2606                if (RILJ_LOGD) unsljLogRet(response, ret);
2607
2608                // has bonus long containing milliseconds since boot that the NITZ
2609                // time was received
2610                long nitzReceiveTime = p.readLong();
2611
2612                Object[] result = new Object[2];
2613
2614                result[0] = ret;
2615                result[1] = Long.valueOf(nitzReceiveTime);
2616
2617                boolean ignoreNitz = SystemProperties.getBoolean(
2618                        TelephonyProperties.PROPERTY_IGNORE_NITZ, false);
2619
2620                if (ignoreNitz) {
2621                    if (RILJ_LOGD) riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED");
2622                } else {
2623                    if (mNITZTimeRegistrant != null) {
2624
2625                        mNITZTimeRegistrant
2626                            .notifyRegistrant(new AsyncResult (null, result, null));
2627                    } else {
2628                        // in case NITZ time registrant isnt registered yet
2629                        mLastNITZTimeInfo = result;
2630                    }
2631                }
2632            break;
2633
2634            case RIL_UNSOL_SIGNAL_STRENGTH:
2635                // Note this is set to "verbose" because it happens
2636                // frequently
2637                if (RILJ_LOGV) unsljLogvRet(response, ret);
2638
2639                if (mSignalStrengthRegistrant != null) {
2640                    mSignalStrengthRegistrant.notifyRegistrant(
2641                                        new AsyncResult (null, ret, null));
2642                }
2643            break;
2644            case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
2645                if (RILJ_LOGD) unsljLogRet(response, ret);
2646
2647                mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
2648            break;
2649
2650            case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
2651                if (RILJ_LOGD) unsljLogRet(response, ret);
2652
2653                if (mSsnRegistrant != null) {
2654                    mSsnRegistrant.notifyRegistrant(
2655                                        new AsyncResult (null, ret, null));
2656                }
2657                break;
2658
2659            case RIL_UNSOL_STK_SESSION_END:
2660                if (RILJ_LOGD) unsljLog(response);
2661
2662                if (mCatSessionEndRegistrant != null) {
2663                    mCatSessionEndRegistrant.notifyRegistrant(
2664                                        new AsyncResult (null, ret, null));
2665                }
2666                break;
2667
2668            case RIL_UNSOL_STK_PROACTIVE_COMMAND:
2669                if (RILJ_LOGD) unsljLogRet(response, ret);
2670
2671                if (mCatProCmdRegistrant != null) {
2672                    mCatProCmdRegistrant.notifyRegistrant(
2673                                        new AsyncResult (null, ret, null));
2674                }
2675                break;
2676
2677            case RIL_UNSOL_STK_EVENT_NOTIFY:
2678                if (RILJ_LOGD) unsljLogRet(response, ret);
2679
2680                if (mCatEventRegistrant != null) {
2681                    mCatEventRegistrant.notifyRegistrant(
2682                                        new AsyncResult (null, ret, null));
2683                }
2684                break;
2685
2686            case RIL_UNSOL_STK_CALL_SETUP:
2687                if (RILJ_LOGD) unsljLogRet(response, ret);
2688
2689                if (mCatCallSetUpRegistrant != null) {
2690                    mCatCallSetUpRegistrant.notifyRegistrant(
2691                                        new AsyncResult (null, ret, null));
2692                }
2693                break;
2694
2695            case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
2696                if (RILJ_LOGD) unsljLog(response);
2697
2698                if (mIccSmsFullRegistrant != null) {
2699                    mIccSmsFullRegistrant.notifyRegistrant();
2700                }
2701                break;
2702
2703            case RIL_UNSOL_SIM_REFRESH:
2704                if (RILJ_LOGD) unsljLogRet(response, ret);
2705
2706                if (mIccRefreshRegistrants != null) {
2707                    mIccRefreshRegistrants.notifyRegistrants(
2708                            new AsyncResult (null, ret, null));
2709                }
2710                break;
2711
2712            case RIL_UNSOL_CALL_RING:
2713                if (RILJ_LOGD) unsljLogRet(response, ret);
2714
2715                if (mRingRegistrant != null) {
2716                    mRingRegistrant.notifyRegistrant(
2717                            new AsyncResult (null, ret, null));
2718                }
2719                break;
2720
2721            case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
2722                if (RILJ_LOGD) unsljLogvRet(response, ret);
2723                if (mRestrictedStateRegistrant != null) {
2724                    mRestrictedStateRegistrant.notifyRegistrant(
2725                                        new AsyncResult (null, ret, null));
2726                }
2727                break;
2728
2729            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
2730                if (RILJ_LOGD) unsljLog(response);
2731
2732                if (mIccStatusChangedRegistrants != null) {
2733                    mIccStatusChangedRegistrants.notifyRegistrants();
2734                }
2735                break;
2736
2737            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
2738                if (RILJ_LOGD) unsljLog(response);
2739
2740                SmsMessage sms = (SmsMessage) ret;
2741
2742                if (mCdmaSmsRegistrant != null) {
2743                    mCdmaSmsRegistrant
2744                        .notifyRegistrant(new AsyncResult(null, sms, null));
2745                }
2746                break;
2747
2748            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
2749                if (RILJ_LOGD) unsljLog(response);
2750
2751                if (mGsmBroadcastSmsRegistrant != null) {
2752                    mGsmBroadcastSmsRegistrant
2753                        .notifyRegistrant(new AsyncResult(null, ret, null));
2754                }
2755                break;
2756
2757            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
2758                if (RILJ_LOGD) unsljLog(response);
2759
2760                if (mIccSmsFullRegistrant != null) {
2761                    mIccSmsFullRegistrant.notifyRegistrant();
2762                }
2763                break;
2764
2765            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
2766                if (RILJ_LOGD) unsljLog(response);
2767
2768                if (mEmergencyCallbackModeRegistrant != null) {
2769                    mEmergencyCallbackModeRegistrant.notifyRegistrant();
2770                }
2771                break;
2772
2773            case RIL_UNSOL_CDMA_CALL_WAITING:
2774                if (RILJ_LOGD) unsljLogRet(response, ret);
2775
2776                if (mCallWaitingInfoRegistrants != null) {
2777                    mCallWaitingInfoRegistrants.notifyRegistrants(
2778                                        new AsyncResult (null, ret, null));
2779                }
2780                break;
2781
2782            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
2783                if (RILJ_LOGD) unsljLogRet(response, ret);
2784
2785                if (mOtaProvisionRegistrants != null) {
2786                    mOtaProvisionRegistrants.notifyRegistrants(
2787                                        new AsyncResult (null, ret, null));
2788                }
2789                break;
2790
2791            case RIL_UNSOL_CDMA_INFO_REC:
2792                ArrayList<CdmaInformationRecords> listInfoRecs;
2793
2794                try {
2795                    listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
2796                } catch (ClassCastException e) {
2797                    Rlog.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
2798                    break;
2799                }
2800
2801                for (CdmaInformationRecords rec : listInfoRecs) {
2802                    if (RILJ_LOGD) unsljLogRet(response, rec);
2803                    notifyRegistrantsCdmaInfoRec(rec);
2804                }
2805                break;
2806
2807            case RIL_UNSOL_OEM_HOOK_RAW:
2808                if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret));
2809                if (mUnsolOemHookRawRegistrant != null) {
2810                    mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
2811                }
2812                break;
2813
2814            case RIL_UNSOL_RINGBACK_TONE:
2815                if (RILJ_LOGD) unsljLogvRet(response, ret);
2816                if (mRingbackToneRegistrants != null) {
2817                    boolean playtone = (((int[])ret)[0] == 1);
2818                    mRingbackToneRegistrants.notifyRegistrants(
2819                                        new AsyncResult (null, playtone, null));
2820                }
2821                break;
2822
2823            case RIL_UNSOL_RESEND_INCALL_MUTE:
2824                if (RILJ_LOGD) unsljLogRet(response, ret);
2825
2826                if (mResendIncallMuteRegistrants != null) {
2827                    mResendIncallMuteRegistrants.notifyRegistrants(
2828                                        new AsyncResult (null, ret, null));
2829                }
2830                break;
2831
2832            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
2833                if (RILJ_LOGD) unsljLogRet(response, ret);
2834
2835                if (mVoiceRadioTechChangedRegistrants != null) {
2836                    mVoiceRadioTechChangedRegistrants.notifyRegistrants(
2837                            new AsyncResult(null, ret, null));
2838                }
2839                break;
2840
2841            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
2842                if (RILJ_LOGD) unsljLogRet(response, ret);
2843
2844                if (mCdmaSubscriptionChangedRegistrants != null) {
2845                    mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
2846                                        new AsyncResult (null, ret, null));
2847                }
2848                break;
2849
2850            case RIL_UNSOl_CDMA_PRL_CHANGED:
2851                if (RILJ_LOGD) unsljLogRet(response, ret);
2852
2853                if (mCdmaPrlChangedRegistrants != null) {
2854                    mCdmaPrlChangedRegistrants.notifyRegistrants(
2855                                        new AsyncResult (null, ret, null));
2856                }
2857                break;
2858
2859            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
2860                if (RILJ_LOGD) unsljLogRet(response, ret);
2861
2862                if (mExitEmergencyCallbackModeRegistrants != null) {
2863                    mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
2864                                        new AsyncResult (null, null, null));
2865                }
2866                break;
2867
2868            case RIL_UNSOL_RIL_CONNECTED: {
2869                if (RILJ_LOGD) unsljLogRet(response, ret);
2870
2871                // Initial conditions
2872                setRadioPower(false, null);
2873                setPreferredNetworkType(mPreferredNetworkType, null);
2874                setCdmaSubscriptionSource(mCdmaSubscription, null);
2875                notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
2876                break;
2877            }
2878        }
2879    }
2880
2881    /**
2882     * Notifiy all registrants that the ril has connected or disconnected.
2883     *
2884     * @param rilVer is the version of the ril or -1 if disconnected.
2885     */
2886    private void notifyRegistrantsRilConnectionChanged(int rilVer) {
2887        mRilVersion = rilVer;
2888        if (mRilConnectedRegistrants != null) {
2889            mRilConnectedRegistrants.notifyRegistrants(
2890                                new AsyncResult (null, new Integer(rilVer), null));
2891        }
2892    }
2893
2894    private Object
2895    responseInts(Parcel p) {
2896        int numInts;
2897        int response[];
2898
2899        numInts = p.readInt();
2900
2901        response = new int[numInts];
2902
2903        for (int i = 0 ; i < numInts ; i++) {
2904            response[i] = p.readInt();
2905        }
2906
2907        return response;
2908    }
2909
2910
2911    private Object
2912    responseVoid(Parcel p) {
2913        return null;
2914    }
2915
2916    private Object
2917    responseCallForward(Parcel p) {
2918        int numInfos;
2919        CallForwardInfo infos[];
2920
2921        numInfos = p.readInt();
2922
2923        infos = new CallForwardInfo[numInfos];
2924
2925        for (int i = 0 ; i < numInfos ; i++) {
2926            infos[i] = new CallForwardInfo();
2927
2928            infos[i].status = p.readInt();
2929            infos[i].reason = p.readInt();
2930            infos[i].serviceClass = p.readInt();
2931            infos[i].toa = p.readInt();
2932            infos[i].number = p.readString();
2933            infos[i].timeSeconds = p.readInt();
2934        }
2935
2936        return infos;
2937    }
2938
2939    private Object
2940    responseSuppServiceNotification(Parcel p) {
2941        SuppServiceNotification notification = new SuppServiceNotification();
2942
2943        notification.notificationType = p.readInt();
2944        notification.code = p.readInt();
2945        notification.index = p.readInt();
2946        notification.type = p.readInt();
2947        notification.number = p.readString();
2948
2949        return notification;
2950    }
2951
2952    private Object
2953    responseCdmaSms(Parcel p) {
2954        SmsMessage sms;
2955        sms = SmsMessage.newFromParcel(p);
2956
2957        return sms;
2958    }
2959
2960    private Object
2961    responseString(Parcel p) {
2962        String response;
2963
2964        response = p.readString();
2965
2966        return response;
2967    }
2968
2969    private Object
2970    responseStrings(Parcel p) {
2971        int num;
2972        String response[];
2973
2974        response = p.readStringArray();
2975
2976        if (false) {
2977            num = p.readInt();
2978
2979            response = new String[num];
2980            for (int i = 0; i < num; i++) {
2981                response[i] = p.readString();
2982            }
2983        }
2984
2985        return response;
2986    }
2987
2988    private Object
2989    responseRaw(Parcel p) {
2990        int num;
2991        byte response[];
2992
2993        response = p.createByteArray();
2994
2995        return response;
2996    }
2997
2998    private Object
2999    responseSMS(Parcel p) {
3000        int messageRef, errorCode;
3001        String ackPDU;
3002
3003        messageRef = p.readInt();
3004        ackPDU = p.readString();
3005        errorCode = p.readInt();
3006
3007        SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode);
3008
3009        return response;
3010    }
3011
3012
3013    private Object
3014    responseICC_IO(Parcel p) {
3015        int sw1, sw2;
3016        byte data[] = null;
3017        Message ret;
3018
3019        sw1 = p.readInt();
3020        sw2 = p.readInt();
3021
3022        String s = p.readString();
3023
3024        if (RILJ_LOGV) riljLog("< iccIO: "
3025                + " 0x" + Integer.toHexString(sw1)
3026                + " 0x" + Integer.toHexString(sw2) + " "
3027                + s);
3028
3029        return new IccIoResult(sw1, sw2, s);
3030    }
3031
3032    private Object
3033    responseIccCardStatus(Parcel p) {
3034        IccCardApplicationStatus appStatus;
3035
3036        IccCardStatus cardStatus = new IccCardStatus();
3037        cardStatus.setCardState(p.readInt());
3038        cardStatus.setUniversalPinState(p.readInt());
3039        cardStatus.mGsmUmtsSubscriptionAppIndex = p.readInt();
3040        cardStatus.mCdmaSubscriptionAppIndex = p.readInt();
3041        cardStatus.mImsSubscriptionAppIndex = p.readInt();
3042        int numApplications = p.readInt();
3043
3044        // limit to maximum allowed applications
3045        if (numApplications > IccCardStatus.CARD_MAX_APPS) {
3046            numApplications = IccCardStatus.CARD_MAX_APPS;
3047        }
3048        cardStatus.mApplications = new IccCardApplicationStatus[numApplications];
3049        for (int i = 0 ; i < numApplications ; i++) {
3050            appStatus = new IccCardApplicationStatus();
3051            appStatus.app_type       = appStatus.AppTypeFromRILInt(p.readInt());
3052            appStatus.app_state      = appStatus.AppStateFromRILInt(p.readInt());
3053            appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(p.readInt());
3054            appStatus.aid            = p.readString();
3055            appStatus.app_label      = p.readString();
3056            appStatus.pin1_replaced  = p.readInt();
3057            appStatus.pin1           = appStatus.PinStateFromRILInt(p.readInt());
3058            appStatus.pin2           = appStatus.PinStateFromRILInt(p.readInt());
3059            cardStatus.mApplications[i] = appStatus;
3060        }
3061        return cardStatus;
3062    }
3063
3064    private Object
3065    responseSimRefresh(Parcel p) {
3066        IccRefreshResponse response = new IccRefreshResponse();
3067
3068        response.refreshResult = p.readInt();
3069        response.efId   = p.readInt();
3070        response.aid = p.readString();
3071        return response;
3072    }
3073
3074    private Object
3075    responseCallList(Parcel p) {
3076        int num;
3077        int voiceSettings;
3078        ArrayList<DriverCall> response;
3079        DriverCall dc;
3080
3081        num = p.readInt();
3082        response = new ArrayList<DriverCall>(num);
3083
3084        if (RILJ_LOGV) {
3085            riljLog("responseCallList: num=" + num +
3086                    " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant +
3087                    " mTestingEmergencyCall=" + mTestingEmergencyCall.get());
3088        }
3089        for (int i = 0 ; i < num ; i++) {
3090            dc = new DriverCall();
3091
3092            dc.state = DriverCall.stateFromCLCC(p.readInt());
3093            dc.index = p.readInt();
3094            dc.TOA = p.readInt();
3095            dc.isMpty = (0 != p.readInt());
3096            dc.isMT = (0 != p.readInt());
3097            dc.als = p.readInt();
3098            voiceSettings = p.readInt();
3099            dc.isVoice = (0 == voiceSettings) ? false : true;
3100            dc.isVoicePrivacy = (0 != p.readInt());
3101            dc.number = p.readString();
3102            int np = p.readInt();
3103            dc.numberPresentation = DriverCall.presentationFromCLIP(np);
3104            dc.name = p.readString();
3105            dc.namePresentation = p.readInt();
3106            int uusInfoPresent = p.readInt();
3107            if (uusInfoPresent == 1) {
3108                dc.uusInfo = new UUSInfo();
3109                dc.uusInfo.setType(p.readInt());
3110                dc.uusInfo.setDcs(p.readInt());
3111                byte[] userData = p.createByteArray();
3112                dc.uusInfo.setUserData(userData);
3113                riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
3114                                dc.uusInfo.getType(), dc.uusInfo.getDcs(),
3115                                dc.uusInfo.getUserData().length));
3116                riljLogv("Incoming UUS : data (string)="
3117                        + new String(dc.uusInfo.getUserData()));
3118                riljLogv("Incoming UUS : data (hex): "
3119                        + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
3120            } else {
3121                riljLogv("Incoming UUS : NOT present!");
3122            }
3123
3124            // Make sure there's a leading + on addresses with a TOA of 145
3125            dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
3126
3127            response.add(dc);
3128
3129            if (dc.isVoicePrivacy) {
3130                mVoicePrivacyOnRegistrants.notifyRegistrants();
3131                riljLog("InCall VoicePrivacy is enabled");
3132            } else {
3133                mVoicePrivacyOffRegistrants.notifyRegistrants();
3134                riljLog("InCall VoicePrivacy is disabled");
3135            }
3136        }
3137
3138        Collections.sort(response);
3139
3140        if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) {
3141            if (mEmergencyCallbackModeRegistrant != null) {
3142                riljLog("responseCallList: call ended, testing emergency call," +
3143                            " notify ECM Registrants");
3144                mEmergencyCallbackModeRegistrant.notifyRegistrant();
3145            }
3146        }
3147
3148        return response;
3149    }
3150
3151    private DataCallState getDataCallState(Parcel p, int version) {
3152        DataCallState dataCall = new DataCallState();
3153
3154        dataCall.version = version;
3155        if (version < 5) {
3156            dataCall.cid = p.readInt();
3157            dataCall.active = p.readInt();
3158            dataCall.type = p.readString();
3159            String addresses = p.readString();
3160            if (!TextUtils.isEmpty(addresses)) {
3161                dataCall.addresses = addresses.split(" ");
3162            }
3163        } else {
3164            dataCall.status = p.readInt();
3165            dataCall.suggestedRetryTime = p.readInt();
3166            dataCall.cid = p.readInt();
3167            dataCall.active = p.readInt();
3168            dataCall.type = p.readString();
3169            dataCall.ifname = p.readString();
3170            if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) &&
3171                    TextUtils.isEmpty(dataCall.ifname)) {
3172              throw new RuntimeException("getDataCallState, no ifname");
3173            }
3174            String addresses = p.readString();
3175            if (!TextUtils.isEmpty(addresses)) {
3176                dataCall.addresses = addresses.split(" ");
3177            }
3178            String dnses = p.readString();
3179            if (!TextUtils.isEmpty(dnses)) {
3180                dataCall.dnses = dnses.split(" ");
3181            }
3182            String gateways = p.readString();
3183            if (!TextUtils.isEmpty(gateways)) {
3184                dataCall.gateways = gateways.split(" ");
3185            }
3186        }
3187        return dataCall;
3188    }
3189
3190    private Object
3191    responseDataCallList(Parcel p) {
3192        ArrayList<DataCallState> response;
3193
3194        int ver = p.readInt();
3195        int num = p.readInt();
3196        riljLog("responseDataCallList ver=" + ver + " num=" + num);
3197
3198        response = new ArrayList<DataCallState>(num);
3199        for (int i = 0; i < num; i++) {
3200            response.add(getDataCallState(p, ver));
3201        }
3202
3203        return response;
3204    }
3205
3206    private Object
3207    responseSetupDataCall(Parcel p) {
3208        int ver = p.readInt();
3209        int num = p.readInt();
3210        if (RILJ_LOGV) riljLog("responseSetupDataCall ver=" + ver + " num=" + num);
3211
3212        DataCallState dataCall;
3213
3214        if (ver < 5) {
3215            dataCall = new DataCallState();
3216            dataCall.version = ver;
3217            dataCall.cid = Integer.parseInt(p.readString());
3218            dataCall.ifname = p.readString();
3219            if (TextUtils.isEmpty(dataCall.ifname)) {
3220                throw new RuntimeException(
3221                        "RIL_REQUEST_SETUP_DATA_CALL response, no ifname");
3222            }
3223            String addresses = p.readString();
3224            if (!TextUtils.isEmpty(addresses)) {
3225              dataCall.addresses = addresses.split(" ");
3226            }
3227            if (num >= 4) {
3228                String dnses = p.readString();
3229                if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses);
3230                if (!TextUtils.isEmpty(dnses)) {
3231                    dataCall.dnses = dnses.split(" ");
3232                }
3233            }
3234            if (num >= 5) {
3235                String gateways = p.readString();
3236                if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways);
3237                if (!TextUtils.isEmpty(gateways)) {
3238                    dataCall.gateways = gateways.split(" ");
3239                }
3240            }
3241        } else {
3242            if (num != 1) {
3243                throw new RuntimeException(
3244                        "RIL_REQUEST_SETUP_DATA_CALL response expecting 1 RIL_Data_Call_response_v5"
3245                        + " got " + num);
3246            }
3247            dataCall = getDataCallState(p, ver);
3248        }
3249
3250        return dataCall;
3251    }
3252
3253    private Object
3254    responseOperatorInfos(Parcel p) {
3255        String strings[] = (String [])responseStrings(p);
3256        ArrayList<OperatorInfo> ret;
3257
3258        if (strings.length % 4 != 0) {
3259            throw new RuntimeException(
3260                "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
3261                + strings.length + " strings, expected multible of 4");
3262        }
3263
3264        ret = new ArrayList<OperatorInfo>(strings.length / 4);
3265
3266        for (int i = 0 ; i < strings.length ; i += 4) {
3267            ret.add (
3268                new OperatorInfo(
3269                    strings[i+0],
3270                    strings[i+1],
3271                    strings[i+2],
3272                    strings[i+3]));
3273        }
3274
3275        return ret;
3276    }
3277
3278    private Object
3279    responseCellList(Parcel p) {
3280       int num, rssi;
3281       String location;
3282       ArrayList<NeighboringCellInfo> response;
3283       NeighboringCellInfo cell;
3284
3285       num = p.readInt();
3286       response = new ArrayList<NeighboringCellInfo>();
3287
3288       // Determine the radio access type
3289       String radioString = SystemProperties.get(
3290               TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, "unknown");
3291       int radioType;
3292       if (radioString.equals("GPRS")) {
3293           radioType = NETWORK_TYPE_GPRS;
3294       } else if (radioString.equals("EDGE")) {
3295           radioType = NETWORK_TYPE_EDGE;
3296       } else if (radioString.equals("UMTS")) {
3297           radioType = NETWORK_TYPE_UMTS;
3298       } else if (radioString.equals("HSDPA")) {
3299           radioType = NETWORK_TYPE_HSDPA;
3300       } else if (radioString.equals("HSUPA")) {
3301           radioType = NETWORK_TYPE_HSUPA;
3302       } else if (radioString.equals("HSPA")) {
3303           radioType = NETWORK_TYPE_HSPA;
3304       } else {
3305           radioType = NETWORK_TYPE_UNKNOWN;
3306       }
3307
3308       // Interpret the location based on radio access type
3309       if (radioType != NETWORK_TYPE_UNKNOWN) {
3310           for (int i = 0 ; i < num ; i++) {
3311               rssi = p.readInt();
3312               location = p.readString();
3313               cell = new NeighboringCellInfo(rssi, location, radioType);
3314               response.add(cell);
3315           }
3316       }
3317       return response;
3318    }
3319
3320    private Object responseGetPreferredNetworkType(Parcel p) {
3321       int [] response = (int[]) responseInts(p);
3322
3323       if (response.length >= 1) {
3324           // Since this is the response for getPreferredNetworkType
3325           // we'll assume that it should be the value we want the
3326           // vendor ril to take if we reestablish a connection to it.
3327           mPreferredNetworkType = response[0];
3328       }
3329       return response;
3330    }
3331
3332    private Object responseGmsBroadcastConfig(Parcel p) {
3333        int num;
3334        ArrayList<SmsBroadcastConfigInfo> response;
3335        SmsBroadcastConfigInfo info;
3336
3337        num = p.readInt();
3338        response = new ArrayList<SmsBroadcastConfigInfo>(num);
3339
3340        for (int i = 0; i < num; i++) {
3341            int fromId = p.readInt();
3342            int toId = p.readInt();
3343            int fromScheme = p.readInt();
3344            int toScheme = p.readInt();
3345            boolean selected = (p.readInt() == 1);
3346
3347            info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme,
3348                    toScheme, selected);
3349            response.add(info);
3350        }
3351        return response;
3352    }
3353
3354    private Object
3355    responseCdmaBroadcastConfig(Parcel p) {
3356        int numServiceCategories;
3357        int response[];
3358
3359        numServiceCategories = p.readInt();
3360
3361        if (numServiceCategories == 0) {
3362            // TODO: The logic of providing default values should
3363            // not be done by this transport layer. And needs to
3364            // be done by the vendor ril or application logic.
3365            int numInts;
3366            numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
3367            response = new int[numInts];
3368
3369            // Faking a default record for all possible records.
3370            response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
3371
3372            // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
3373            // default language and selection status to false for all.
3374            for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) {
3375                response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT;
3376                response[i + 1] = 1;
3377                response[i + 2] = 0;
3378            }
3379        } else {
3380            int numInts;
3381            numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
3382            response = new int[numInts];
3383
3384            response[0] = numServiceCategories;
3385            for (int i = 1 ; i < numInts; i++) {
3386                 response[i] = p.readInt();
3387             }
3388        }
3389
3390        return response;
3391    }
3392
3393    private Object
3394    responseSignalStrength(Parcel p) {
3395        SignalStrength signalStrength = new SignalStrength(p);
3396        return signalStrength;
3397    }
3398
3399    private ArrayList<CdmaInformationRecords>
3400    responseCdmaInformationRecord(Parcel p) {
3401        int numberOfInfoRecs;
3402        ArrayList<CdmaInformationRecords> response;
3403
3404        /**
3405         * Loop through all of the information records unmarshalling them
3406         * and converting them to Java Objects.
3407         */
3408        numberOfInfoRecs = p.readInt();
3409        response = new ArrayList<CdmaInformationRecords>(numberOfInfoRecs);
3410
3411        for (int i = 0; i < numberOfInfoRecs; i++) {
3412            CdmaInformationRecords InfoRec = new CdmaInformationRecords(p);
3413            response.add(InfoRec);
3414        }
3415
3416        return response;
3417    }
3418
3419    private Object
3420    responseCdmaCallWaiting(Parcel p) {
3421        CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
3422
3423        notification.number = p.readString();
3424        notification.numberPresentation = notification.presentationFromCLIP(p.readInt());
3425        notification.name = p.readString();
3426        notification.namePresentation = notification.numberPresentation;
3427        notification.isPresent = p.readInt();
3428        notification.signalType = p.readInt();
3429        notification.alertPitch = p.readInt();
3430        notification.signal = p.readInt();
3431        notification.numberType = p.readInt();
3432        notification.numberPlan = p.readInt();
3433
3434        return notification;
3435    }
3436
3437    private Object
3438    responseCallRing(Parcel p){
3439        char response[] = new char[4];
3440
3441        response[0] = (char) p.readInt();    // isPresent
3442        response[1] = (char) p.readInt();    // signalType
3443        response[2] = (char) p.readInt();    // alertPitch
3444        response[3] = (char) p.readInt();    // signal
3445
3446        return response;
3447    }
3448
3449    private void
3450    notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
3451        int response = RIL_UNSOL_CDMA_INFO_REC;
3452        if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
3453            if (mDisplayInfoRegistrants != null) {
3454                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3455                mDisplayInfoRegistrants.notifyRegistrants(
3456                        new AsyncResult (null, infoRec.record, null));
3457            }
3458        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
3459            if (mSignalInfoRegistrants != null) {
3460                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3461                mSignalInfoRegistrants.notifyRegistrants(
3462                        new AsyncResult (null, infoRec.record, null));
3463            }
3464        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
3465            if (mNumberInfoRegistrants != null) {
3466                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3467                mNumberInfoRegistrants.notifyRegistrants(
3468                        new AsyncResult (null, infoRec.record, null));
3469            }
3470        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
3471            if (mRedirNumInfoRegistrants != null) {
3472                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3473                mRedirNumInfoRegistrants.notifyRegistrants(
3474                        new AsyncResult (null, infoRec.record, null));
3475            }
3476        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
3477            if (mLineControlInfoRegistrants != null) {
3478                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3479                mLineControlInfoRegistrants.notifyRegistrants(
3480                        new AsyncResult (null, infoRec.record, null));
3481            }
3482        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
3483            if (mT53ClirInfoRegistrants != null) {
3484                if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3485                mT53ClirInfoRegistrants.notifyRegistrants(
3486                        new AsyncResult (null, infoRec.record, null));
3487            }
3488        } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
3489            if (mT53AudCntrlInfoRegistrants != null) {
3490               if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
3491               mT53AudCntrlInfoRegistrants.notifyRegistrants(
3492                       new AsyncResult (null, infoRec.record, null));
3493            }
3494        }
3495    }
3496
3497    static String
3498    requestToString(int request) {
3499/*
3500 cat libs/telephony/ril_commands.h \
3501 | egrep "^ *{RIL_" \
3502 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3503*/
3504        switch(request) {
3505            case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
3506            case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
3507            case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
3508            case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
3509            case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
3510            case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
3511            case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
3512            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
3513            case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
3514            case RIL_REQUEST_DIAL: return "DIAL";
3515            case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
3516            case RIL_REQUEST_HANGUP: return "HANGUP";
3517            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
3518            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
3519            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
3520            case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
3521            case RIL_REQUEST_UDUB: return "UDUB";
3522            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
3523            case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
3524            case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
3525            case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
3526            case RIL_REQUEST_OPERATOR: return "OPERATOR";
3527            case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
3528            case RIL_REQUEST_DTMF: return "DTMF";
3529            case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
3530            case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
3531            case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
3532            case RIL_REQUEST_SIM_IO: return "SIM_IO";
3533            case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
3534            case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
3535            case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
3536            case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
3537            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
3538            case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
3539            case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
3540            case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
3541            case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
3542            case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
3543            case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
3544            case RIL_REQUEST_ANSWER: return "ANSWER";
3545            case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
3546            case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
3547            case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
3548            case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
3549            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
3550            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
3551            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
3552            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
3553            case RIL_REQUEST_DTMF_START: return "DTMF_START";
3554            case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
3555            case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
3556            case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
3557            case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
3558            case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
3559            case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
3560            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
3561            case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
3562            case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
3563            case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
3564            case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
3565            case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
3566            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION";
3567            case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
3568            case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM";
3569            case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
3570            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
3571            case RIL_REQUEST_STK_GET_PROFILE: return "REQUEST_STK_GET_PROFILE";
3572            case RIL_REQUEST_STK_SET_PROFILE: return "REQUEST_STK_SET_PROFILE";
3573            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "REQUEST_STK_SEND_ENVELOPE_COMMAND";
3574            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "REQUEST_STK_SEND_TERMINAL_RESPONSE";
3575            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
3576            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER";
3577            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "REQUEST_SET_PREFERRED_NETWORK_TYPE";
3578            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
3579            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS";
3580            case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES";
3581            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
3582            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
3583            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
3584            case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE";
3585            case RIL_REQUEST_QUERY_TTY_MODE: return "RIL_REQUEST_QUERY_TTY_MODE";
3586            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
3587            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
3588            case RIL_REQUEST_CDMA_FLASH: return "RIL_REQUEST_CDMA_FLASH";
3589            case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF";
3590            case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS";
3591            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
3592            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
3593            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
3594            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
3595            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
3596            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
3597            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
3598            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
3599            case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
3600            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
3601            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
3602            case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY";
3603            case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS";
3604            case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS";
3605            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
3606            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
3607            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
3608            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
3609            case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION";
3610            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
3611            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
3612            case RIL_REQUEST_VOICE_RADIO_TECH: return "RIL_REQUEST_VOICE_RADIO_TECH";
3613            default: return "<unknown request>";
3614        }
3615    }
3616
3617    static String
3618    responseToString(int request)
3619    {
3620/*
3621 cat libs/telephony/ril_unsol_commands.h \
3622 | egrep "^ *{RIL_" \
3623 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3624*/
3625        switch(request) {
3626            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
3627            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
3628            case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
3629            case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
3630            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
3631            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
3632            case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
3633            case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST";
3634            case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
3635            case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
3636            case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
3637            case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
3638            case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
3639            case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
3640            case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
3641            case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
3642            case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL";
3643            case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
3644            case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
3645            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
3646            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS";
3647            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
3648            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
3649            case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
3650            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
3651            case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
3652            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
3653            case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
3654            case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
3655            case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
3656            case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
3657            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "CDMA_SUBSCRIPTION_SOURCE_CHANGED";
3658            case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
3659            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
3660            case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
3661            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
3662            default: return "<unknown reponse>";
3663        }
3664    }
3665
3666    private void riljLog(String msg) {
3667        Rlog.d(LOG_TAG, msg);
3668    }
3669
3670    private void riljLogv(String msg) {
3671        Rlog.v(LOG_TAG, msg);
3672    }
3673
3674    private void unsljLog(int response) {
3675        riljLog("[UNSL]< " + responseToString(response));
3676    }
3677
3678    private void unsljLogMore(int response, String more) {
3679        riljLog("[UNSL]< " + responseToString(response) + " " + more);
3680    }
3681
3682    private void unsljLogRet(int response, Object ret) {
3683        riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
3684    }
3685
3686    private void unsljLogvRet(int response, Object ret) {
3687        riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
3688    }
3689
3690
3691    // ***** Methods for CDMA support
3692    public void
3693    getDeviceIdentity(Message response) {
3694        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DEVICE_IDENTITY, response);
3695
3696        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3697
3698        send(rr);
3699    }
3700
3701    public void
3702    getCDMASubscription(Message response) {
3703        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SUBSCRIPTION, response);
3704
3705        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3706
3707        send(rr);
3708    }
3709
3710    @Override
3711    public void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructor
3712        if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
3713        mPhoneType = phoneType;
3714    }
3715
3716    /**
3717     * {@inheritDoc}
3718     */
3719    public void queryCdmaRoamingPreference(Message response) {
3720        RILRequest rr = RILRequest.obtain(
3721                RILConstants.RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, response);
3722
3723        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3724
3725        send(rr);
3726    }
3727
3728    /**
3729     * {@inheritDoc}
3730     */
3731    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
3732        RILRequest rr = RILRequest.obtain(
3733                RILConstants.RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, response);
3734
3735        rr.mp.writeInt(1);
3736        rr.mp.writeInt(cdmaRoamingType);
3737
3738        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3739                + " : " + cdmaRoamingType);
3740
3741        send(rr);
3742    }
3743
3744    /**
3745     * {@inheritDoc}
3746     */
3747    public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
3748        RILRequest rr = RILRequest.obtain(
3749                RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response);
3750
3751        rr.mp.writeInt(1);
3752        rr.mp.writeInt(cdmaSubscription);
3753
3754        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3755                + " : " + cdmaSubscription);
3756
3757        send(rr);
3758    }
3759
3760    /**
3761     * {@inheritDoc}
3762     */
3763    @Override
3764    public void getCdmaSubscriptionSource(Message response) {
3765        RILRequest rr = RILRequest.obtain(
3766                RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response);
3767
3768        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3769
3770        send(rr);
3771    }
3772
3773    /**
3774     * {@inheritDoc}
3775     */
3776    public void queryTTYMode(Message response) {
3777        RILRequest rr = RILRequest.obtain(
3778                RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
3779
3780        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3781
3782        send(rr);
3783    }
3784
3785    /**
3786     * {@inheritDoc}
3787     */
3788    public void setTTYMode(int ttyMode, Message response) {
3789        RILRequest rr = RILRequest.obtain(
3790                RILConstants.RIL_REQUEST_SET_TTY_MODE, response);
3791
3792        rr.mp.writeInt(1);
3793        rr.mp.writeInt(ttyMode);
3794
3795        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3796                + " : " + ttyMode);
3797
3798        send(rr);
3799    }
3800
3801    /**
3802     * {@inheritDoc}
3803     */
3804    public void
3805    sendCDMAFeatureCode(String FeatureCode, Message response) {
3806        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response);
3807
3808        rr.mp.writeString(FeatureCode);
3809
3810        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
3811                + " : " + FeatureCode);
3812
3813        send(rr);
3814    }
3815
3816    public void getCdmaBroadcastConfig(Message response) {
3817        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, response);
3818
3819        send(rr);
3820    }
3821
3822    // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
3823    public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
3824        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response);
3825
3826        for(int i = 0; i < configValuesArray.length; i++) {
3827            rr.mp.writeInt(configValuesArray[i]);
3828        }
3829
3830        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3831
3832        send(rr);
3833    }
3834
3835    public void setCdmaBroadcastActivation(boolean activate, Message response) {
3836        RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response);
3837
3838        rr.mp.writeInt(1);
3839        rr.mp.writeInt(activate ? 0 :1);
3840
3841        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3842
3843        send(rr);
3844    }
3845
3846    /**
3847     * {@inheritDoc}
3848     */
3849    public void exitEmergencyCallbackMode(Message response) {
3850        RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response);
3851
3852        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3853
3854        send(rr);
3855    }
3856
3857    public void requestIsimAuthentication(String nonce, Message response) {
3858        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ISIM_AUTHENTICATION, response);
3859
3860        rr.mp.writeString(nonce);
3861
3862        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
3863
3864        send(rr);
3865    }
3866
3867    /* (non-Javadoc)
3868     * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
3869     */
3870    @Override
3871    public void testingEmergencyCall() {
3872        if (RILJ_LOGD) riljLog("testingEmergencyCall");
3873        mTestingEmergencyCall.set(true);
3874    }
3875
3876    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
3877        pw.println("RIL: " + this);
3878        pw.println(" mSocket=" + mSocket);
3879        pw.println(" mSenderThread=" + mSenderThread);
3880        pw.println(" mSender=" + mSender);
3881        pw.println(" mReceiverThread=" + mReceiverThread);
3882        pw.println(" mReceiver=" + mReceiver);
3883        pw.println(" mWakeLock=" + mWakeLock);
3884        pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
3885        synchronized (mRequestList) {
3886          pw.println(" mRequestMessagesPending=" + mRequestMessagesPending);
3887          pw.println(" mRequestMessagesWaiting=" + mRequestMessagesWaiting);
3888            int count = mRequestList.size();
3889            pw.println(" mRequestList count=" + count);
3890            for (int i = 0; i < count; i++) {
3891                RILRequest rr = mRequestList.get(i);
3892                pw.println("  [" + rr.mSerial + "] " + requestToString(rr.mRequest));
3893            }
3894        }
3895        pw.println(" mLastNITZTimeInfo=" + mLastNITZTimeInfo);
3896        pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get());
3897    }
3898}
3899