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