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