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