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