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