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