OSDN Git Service

am 83b1d8d9: am 8374641d: Merge "Support for LTE/WCDMA mode"
[android-x86/hardware-ril.git] / libril / ril.cpp
1 /* //device/libs/telephony/ril.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #define LOG_TAG "RILC"
19
20 #include <hardware_legacy/power.h>
21
22 #include <telephony/ril.h>
23 #include <telephony/ril_cdma_sms.h>
24 #include <cutils/sockets.h>
25 #include <cutils/jstring.h>
26 #include <telephony/record_stream.h>
27 #include <utils/Log.h>
28 #include <utils/SystemClock.h>
29 #include <pthread.h>
30 #include <binder/Parcel.h>
31 #include <cutils/jstring.h>
32
33 #include <sys/types.h>
34 #include <sys/limits.h>
35 #include <pwd.h>
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <fcntl.h>
43 #include <time.h>
44 #include <errno.h>
45 #include <assert.h>
46 #include <ctype.h>
47 #include <alloca.h>
48 #include <sys/un.h>
49 #include <assert.h>
50 #include <netinet/in.h>
51 #include <cutils/properties.h>
52
53 #include <ril_event.h>
54
55 namespace android {
56
57 #define PHONE_PROCESS "radio"
58
59 #define SOCKET_NAME_RIL "rild"
60 #define SOCKET_NAME_RIL_DEBUG "rild-debug"
61
62 #define ANDROID_WAKE_LOCK_NAME "radio-interface"
63
64
65 #define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
66
67 // match with constant in RIL.java
68 #define MAX_COMMAND_BYTES (8 * 1024)
69
70 // Basically: memset buffers that the client library
71 // shouldn't be using anymore in an attempt to find
72 // memory usage issues sooner.
73 #define MEMSET_FREED 1
74
75 #define NUM_ELEMS(a)     (sizeof (a) / sizeof (a)[0])
76
77 #define MIN(a,b) ((a)<(b) ? (a) : (b))
78
79 /* Constants for response types */
80 #define RESPONSE_SOLICITED 0
81 #define RESPONSE_UNSOLICITED 1
82
83 /* Negative values for private RIL errno's */
84 #define RIL_ERRNO_INVALID_RESPONSE -1
85
86 // request, response, and unsolicited msg print macro
87 #define PRINTBUF_SIZE 8096
88
89 // Enable RILC log
90 #define RILC_LOG 0
91
92 #if RILC_LOG
93     #define startRequest           sprintf(printBuf, "(")
94     #define closeRequest           sprintf(printBuf, "%s)", printBuf)
95     #define printRequest(token, req)           \
96             RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
97
98     #define startResponse           sprintf(printBuf, "%s {", printBuf)
99     #define closeResponse           sprintf(printBuf, "%s}", printBuf)
100     #define printResponse           RLOGD("%s", printBuf)
101
102     #define clearPrintBuf           printBuf[0] = 0
103     #define removeLastChar          printBuf[strlen(printBuf)-1] = 0
104     #define appendPrintBuf(x...)    sprintf(printBuf, x)
105 #else
106     #define startRequest
107     #define closeRequest
108     #define printRequest(token, req)
109     #define startResponse
110     #define closeResponse
111     #define printResponse
112     #define clearPrintBuf
113     #define removeLastChar
114     #define appendPrintBuf(x...)
115 #endif
116
117 enum WakeType {DONT_WAKE, WAKE_PARTIAL};
118
119 typedef struct {
120     int requestNumber;
121     void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
122     int(*responseFunction) (Parcel &p, void *response, size_t responselen);
123 } CommandInfo;
124
125 typedef struct {
126     int requestNumber;
127     int (*responseFunction) (Parcel &p, void *response, size_t responselen);
128     WakeType wakeType;
129 } UnsolResponseInfo;
130
131 typedef struct RequestInfo {
132     int32_t token;      //this is not RIL_Token
133     CommandInfo *pCI;
134     struct RequestInfo *p_next;
135     char cancelled;
136     char local;         // responses to local commands do not go back to command process
137 } RequestInfo;
138
139 typedef struct UserCallbackInfo {
140     RIL_TimedCallback p_callback;
141     void *userParam;
142     struct ril_event event;
143     struct UserCallbackInfo *p_next;
144 } UserCallbackInfo;
145
146
147 /*******************************************************************/
148
149 RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
150 static int s_registerCalled = 0;
151
152 static pthread_t s_tid_dispatch;
153 static pthread_t s_tid_reader;
154 static int s_started = 0;
155
156 static int s_fdListen = -1;
157 static int s_fdCommand = -1;
158 static int s_fdDebug = -1;
159
160 static int s_fdWakeupRead;
161 static int s_fdWakeupWrite;
162
163 static struct ril_event s_commands_event;
164 static struct ril_event s_wakeupfd_event;
165 static struct ril_event s_listen_event;
166 static struct ril_event s_wake_timeout_event;
167 static struct ril_event s_debug_event;
168
169
170 static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
171
172 static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
173 static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
174 static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
175 static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
176
177 static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
178 static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
179
180 static RequestInfo *s_pendingRequests = NULL;
181
182 static RequestInfo *s_toDispatchHead = NULL;
183 static RequestInfo *s_toDispatchTail = NULL;
184
185 static UserCallbackInfo *s_last_wake_timeout_info = NULL;
186
187 static void *s_lastNITZTimeData = NULL;
188 static size_t s_lastNITZTimeDataSize;
189
190 #if RILC_LOG
191     static char printBuf[PRINTBUF_SIZE];
192 #endif
193
194 /*******************************************************************/
195
196 static void dispatchVoid (Parcel& p, RequestInfo *pRI);
197 static void dispatchString (Parcel& p, RequestInfo *pRI);
198 static void dispatchStrings (Parcel& p, RequestInfo *pRI);
199 static void dispatchInts (Parcel& p, RequestInfo *pRI);
200 static void dispatchDial (Parcel& p, RequestInfo *pRI);
201 static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
202 static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
203 static void dispatchRaw(Parcel& p, RequestInfo *pRI);
204 static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
205 static void dispatchDataCall (Parcel& p, RequestInfo *pRI);
206 static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI);
207 static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI);
208 static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI);
209
210 static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI);
211 static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI);
212 static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI);
213 static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI);
214 static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI);
215 static int responseInts(Parcel &p, void *response, size_t responselen);
216 static int responseStrings(Parcel &p, void *response, size_t responselen);
217 static int responseString(Parcel &p, void *response, size_t responselen);
218 static int responseVoid(Parcel &p, void *response, size_t responselen);
219 static int responseCallList(Parcel &p, void *response, size_t responselen);
220 static int responseSMS(Parcel &p, void *response, size_t responselen);
221 static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
222 static int responseCallForwards(Parcel &p, void *response, size_t responselen);
223 static int responseDataCallList(Parcel &p, void *response, size_t responselen);
224 static int responseSetupDataCall(Parcel &p, void *response, size_t responselen);
225 static int responseRaw(Parcel &p, void *response, size_t responselen);
226 static int responseSsn(Parcel &p, void *response, size_t responselen);
227 static int responseSimStatus(Parcel &p, void *response, size_t responselen);
228 static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen);
229 static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen);
230 static int responseCdmaSms(Parcel &p, void *response, size_t responselen);
231 static int responseCellList(Parcel &p, void *response, size_t responselen);
232 static int responseCdmaInformationRecords(Parcel &p,void *response, size_t responselen);
233 static int responseRilSignalStrength(Parcel &p,void *response, size_t responselen);
234 static int responseCallRing(Parcel &p, void *response, size_t responselen);
235 static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t responselen);
236 static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen);
237 static int responseSimRefresh(Parcel &p, void *response, size_t responselen);
238 static int responseCellInfoList(Parcel &p, void *response, size_t responselen);
239
240 static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
241 static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
242 static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
243
244 extern "C" const char * requestToString(int request);
245 extern "C" const char * failCauseToString(RIL_Errno);
246 extern "C" const char * callStateToString(RIL_CallState);
247 extern "C" const char * radioStateToString(RIL_RadioState);
248
249 #ifdef RIL_SHLIB
250 extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
251                                 size_t datalen);
252 #endif
253
254 static UserCallbackInfo * internalRequestTimedCallback
255     (RIL_TimedCallback callback, void *param,
256         const struct timeval *relativeTime);
257
258 /** Index == requestNumber */
259 static CommandInfo s_commands[] = {
260 #include "ril_commands.h"
261 };
262
263 static UnsolResponseInfo s_unsolResponses[] = {
264 #include "ril_unsol_commands.h"
265 };
266
267 /* For older RILs that do not support new commands RIL_REQUEST_VOICE_RADIO_TECH and
268    RIL_UNSOL_VOICE_RADIO_TECH_CHANGED messages, decode the voice radio tech from
269    radio state message and store it. Every time there is a change in Radio State
270    check to see if voice radio tech changes and notify telephony
271  */
272 int voiceRadioTech = -1;
273
274 /* For older RILs that do not support new commands RIL_REQUEST_GET_CDMA_SUBSCRIPTION_SOURCE
275    and RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED messages, decode the subscription
276    source from radio state and store it. Every time there is a change in Radio State
277    check to see if subscription source changed and notify telephony
278  */
279 int cdmaSubscriptionSource = -1;
280
281 /* For older RILs that do not send RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, decode the
282    SIM/RUIM state from radio state and store it. Every time there is a change in Radio State,
283    check to see if SIM/RUIM status changed and notify telephony
284  */
285 int simRuimStatus = -1;
286
287 static char *
288 strdupReadString(Parcel &p) {
289     size_t stringlen;
290     const char16_t *s16;
291
292     s16 = p.readString16Inplace(&stringlen);
293
294     return strndup16to8(s16, stringlen);
295 }
296
297 static void writeStringToParcel(Parcel &p, const char *s) {
298     char16_t *s16;
299     size_t s16_len;
300     s16 = strdup8to16(s, &s16_len);
301     p.writeString16(s16, s16_len);
302     free(s16);
303 }
304
305
306 static void
307 memsetString (char *s) {
308     if (s != NULL) {
309         memset (s, 0, strlen(s));
310     }
311 }
312
313 void   nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
314                                     const size_t* objects, size_t objectsSize,
315                                         void* cookie) {
316     // do nothing -- the data reference lives longer than the Parcel object
317 }
318
319 /**
320  * To be called from dispatch thread
321  * Issue a single local request, ensuring that the response
322  * is not sent back up to the command process
323  */
324 static void
325 issueLocalRequest(int request, void *data, int len) {
326     RequestInfo *pRI;
327     int ret;
328
329     pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
330
331     pRI->local = 1;
332     pRI->token = 0xffffffff;        // token is not used in this context
333     pRI->pCI = &(s_commands[request]);
334
335     ret = pthread_mutex_lock(&s_pendingRequestsMutex);
336     assert (ret == 0);
337
338     pRI->p_next = s_pendingRequests;
339     s_pendingRequests = pRI;
340
341     ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
342     assert (ret == 0);
343
344     RLOGD("C[locl]> %s", requestToString(request));
345
346     s_callbacks.onRequest(request, data, len, pRI);
347 }
348
349
350
351 static int
352 processCommandBuffer(void *buffer, size_t buflen) {
353     Parcel p;
354     status_t status;
355     int32_t request;
356     int32_t token;
357     RequestInfo *pRI;
358     int ret;
359
360     p.setData((uint8_t *) buffer, buflen);
361
362     // status checked at end
363     status = p.readInt32(&request);
364     status = p.readInt32 (&token);
365
366     if (status != NO_ERROR) {
367         RLOGE("invalid request block");
368         return 0;
369     }
370
371     if (request < 1 || request >= (int32_t)NUM_ELEMS(s_commands)) {
372         RLOGE("unsupported request code %d token %d", request, token);
373         // FIXME this should perhaps return a response
374         return 0;
375     }
376
377
378     pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
379
380     pRI->token = token;
381     pRI->pCI = &(s_commands[request]);
382
383     ret = pthread_mutex_lock(&s_pendingRequestsMutex);
384     assert (ret == 0);
385
386     pRI->p_next = s_pendingRequests;
387     s_pendingRequests = pRI;
388
389     ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
390     assert (ret == 0);
391
392 /*    sLastDispatchedToken = token; */
393
394     pRI->pCI->dispatchFunction(p, pRI);
395
396     return 0;
397 }
398
399 static void
400 invalidCommandBlock (RequestInfo *pRI) {
401     RLOGE("invalid command block for token %d request %s",
402                 pRI->token, requestToString(pRI->pCI->requestNumber));
403 }
404
405 /** Callee expects NULL */
406 static void
407 dispatchVoid (Parcel& p, RequestInfo *pRI) {
408     clearPrintBuf;
409     printRequest(pRI->token, pRI->pCI->requestNumber);
410     s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI);
411 }
412
413 /** Callee expects const char * */
414 static void
415 dispatchString (Parcel& p, RequestInfo *pRI) {
416     status_t status;
417     size_t datalen;
418     size_t stringlen;
419     char *string8 = NULL;
420
421     string8 = strdupReadString(p);
422
423     startRequest;
424     appendPrintBuf("%s%s", printBuf, string8);
425     closeRequest;
426     printRequest(pRI->token, pRI->pCI->requestNumber);
427
428     s_callbacks.onRequest(pRI->pCI->requestNumber, string8,
429                        sizeof(char *), pRI);
430
431 #ifdef MEMSET_FREED
432     memsetString(string8);
433 #endif
434
435     free(string8);
436     return;
437 invalid:
438     invalidCommandBlock(pRI);
439     return;
440 }
441
442 /** Callee expects const char ** */
443 static void
444 dispatchStrings (Parcel &p, RequestInfo *pRI) {
445     int32_t countStrings;
446     status_t status;
447     size_t datalen;
448     char **pStrings;
449
450     status = p.readInt32 (&countStrings);
451
452     if (status != NO_ERROR) {
453         goto invalid;
454     }
455
456     startRequest;
457     if (countStrings == 0) {
458         // just some non-null pointer
459         pStrings = (char **)alloca(sizeof(char *));
460         datalen = 0;
461     } else if (((int)countStrings) == -1) {
462         pStrings = NULL;
463         datalen = 0;
464     } else {
465         datalen = sizeof(char *) * countStrings;
466
467         pStrings = (char **)alloca(datalen);
468
469         for (int i = 0 ; i < countStrings ; i++) {
470             pStrings[i] = strdupReadString(p);
471             appendPrintBuf("%s%s,", printBuf, pStrings[i]);
472         }
473     }
474     removeLastChar;
475     closeRequest;
476     printRequest(pRI->token, pRI->pCI->requestNumber);
477
478     s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI);
479
480     if (pStrings != NULL) {
481         for (int i = 0 ; i < countStrings ; i++) {
482 #ifdef MEMSET_FREED
483             memsetString (pStrings[i]);
484 #endif
485             free(pStrings[i]);
486         }
487
488 #ifdef MEMSET_FREED
489         memset(pStrings, 0, datalen);
490 #endif
491     }
492
493     return;
494 invalid:
495     invalidCommandBlock(pRI);
496     return;
497 }
498
499 /** Callee expects const int * */
500 static void
501 dispatchInts (Parcel &p, RequestInfo *pRI) {
502     int32_t count;
503     status_t status;
504     size_t datalen;
505     int *pInts;
506
507     status = p.readInt32 (&count);
508
509     if (status != NO_ERROR || count == 0) {
510         goto invalid;
511     }
512
513     datalen = sizeof(int) * count;
514     pInts = (int *)alloca(datalen);
515
516     startRequest;
517     for (int i = 0 ; i < count ; i++) {
518         int32_t t;
519
520         status = p.readInt32(&t);
521         pInts[i] = (int)t;
522         appendPrintBuf("%s%d,", printBuf, t);
523
524         if (status != NO_ERROR) {
525             goto invalid;
526         }
527    }
528    removeLastChar;
529    closeRequest;
530    printRequest(pRI->token, pRI->pCI->requestNumber);
531
532    s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<int *>(pInts),
533                        datalen, pRI);
534
535 #ifdef MEMSET_FREED
536     memset(pInts, 0, datalen);
537 #endif
538
539     return;
540 invalid:
541     invalidCommandBlock(pRI);
542     return;
543 }
544
545
546 /**
547  * Callee expects const RIL_SMS_WriteArgs *
548  * Payload is:
549  *   int32_t status
550  *   String pdu
551  */
552 static void
553 dispatchSmsWrite (Parcel &p, RequestInfo *pRI) {
554     RIL_SMS_WriteArgs args;
555     int32_t t;
556     status_t status;
557
558     memset (&args, 0, sizeof(args));
559
560     status = p.readInt32(&t);
561     args.status = (int)t;
562
563     args.pdu = strdupReadString(p);
564
565     if (status != NO_ERROR || args.pdu == NULL) {
566         goto invalid;
567     }
568
569     args.smsc = strdupReadString(p);
570
571     startRequest;
572     appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
573         (char*)args.pdu,  (char*)args.smsc);
574     closeRequest;
575     printRequest(pRI->token, pRI->pCI->requestNumber);
576
577     s_callbacks.onRequest(pRI->pCI->requestNumber, &args, sizeof(args), pRI);
578
579 #ifdef MEMSET_FREED
580     memsetString (args.pdu);
581 #endif
582
583     free (args.pdu);
584
585 #ifdef MEMSET_FREED
586     memset(&args, 0, sizeof(args));
587 #endif
588
589     return;
590 invalid:
591     invalidCommandBlock(pRI);
592     return;
593 }
594
595 /**
596  * Callee expects const RIL_Dial *
597  * Payload is:
598  *   String address
599  *   int32_t clir
600  */
601 static void
602 dispatchDial (Parcel &p, RequestInfo *pRI) {
603     RIL_Dial dial;
604     RIL_UUS_Info uusInfo;
605     int32_t sizeOfDial;
606     int32_t t;
607     int32_t uusPresent;
608     status_t status;
609
610     memset (&dial, 0, sizeof(dial));
611
612     dial.address = strdupReadString(p);
613
614     status = p.readInt32(&t);
615     dial.clir = (int)t;
616
617     if (status != NO_ERROR || dial.address == NULL) {
618         goto invalid;
619     }
620
621     if (s_callbacks.version < 3) { // Remove when partners upgrade to version 3
622         uusPresent = 0;
623         sizeOfDial = sizeof(dial) - sizeof(RIL_UUS_Info *);
624     } else {
625         status = p.readInt32(&uusPresent);
626
627         if (status != NO_ERROR) {
628             goto invalid;
629         }
630
631         if (uusPresent == 0) {
632             dial.uusInfo = NULL;
633         } else {
634             int32_t len;
635
636             memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
637
638             status = p.readInt32(&t);
639             uusInfo.uusType = (RIL_UUS_Type) t;
640
641             status = p.readInt32(&t);
642             uusInfo.uusDcs = (RIL_UUS_DCS) t;
643
644             status = p.readInt32(&len);
645             if (status != NO_ERROR) {
646                 goto invalid;
647             }
648
649             // The java code writes -1 for null arrays
650             if (((int) len) == -1) {
651                 uusInfo.uusData = NULL;
652                 len = 0;
653             } else {
654                 uusInfo.uusData = (char*) p.readInplace(len);
655             }
656
657             uusInfo.uusLength = len;
658             dial.uusInfo = &uusInfo;
659         }
660         sizeOfDial = sizeof(dial);
661     }
662
663     startRequest;
664     appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
665     if (uusPresent) {
666         appendPrintBuf("%s,uusType=%d,uusDcs=%d,uusLen=%d", printBuf,
667                 dial.uusInfo->uusType, dial.uusInfo->uusDcs,
668                 dial.uusInfo->uusLength);
669     }
670     closeRequest;
671     printRequest(pRI->token, pRI->pCI->requestNumber);
672
673     s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI);
674
675 #ifdef MEMSET_FREED
676     memsetString (dial.address);
677 #endif
678
679     free (dial.address);
680
681 #ifdef MEMSET_FREED
682     memset(&uusInfo, 0, sizeof(RIL_UUS_Info));
683     memset(&dial, 0, sizeof(dial));
684 #endif
685
686     return;
687 invalid:
688     invalidCommandBlock(pRI);
689     return;
690 }
691
692 /**
693  * Callee expects const RIL_SIM_IO *
694  * Payload is:
695  *   int32_t command
696  *   int32_t fileid
697  *   String path
698  *   int32_t p1, p2, p3
699  *   String data
700  *   String pin2
701  *   String aidPtr
702  */
703 static void
704 dispatchSIM_IO (Parcel &p, RequestInfo *pRI) {
705     union RIL_SIM_IO {
706         RIL_SIM_IO_v6 v6;
707         RIL_SIM_IO_v5 v5;
708     } simIO;
709
710     int32_t t;
711     int size;
712     status_t status;
713
714     memset (&simIO, 0, sizeof(simIO));
715
716     // note we only check status at the end
717
718     status = p.readInt32(&t);
719     simIO.v6.command = (int)t;
720
721     status = p.readInt32(&t);
722     simIO.v6.fileid = (int)t;
723
724     simIO.v6.path = strdupReadString(p);
725
726     status = p.readInt32(&t);
727     simIO.v6.p1 = (int)t;
728
729     status = p.readInt32(&t);
730     simIO.v6.p2 = (int)t;
731
732     status = p.readInt32(&t);
733     simIO.v6.p3 = (int)t;
734
735     simIO.v6.data = strdupReadString(p);
736     simIO.v6.pin2 = strdupReadString(p);
737     simIO.v6.aidPtr = strdupReadString(p);
738
739     startRequest;
740     appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s,aid=%s", printBuf,
741         simIO.v6.command, simIO.v6.fileid, (char*)simIO.v6.path,
742         simIO.v6.p1, simIO.v6.p2, simIO.v6.p3,
743         (char*)simIO.v6.data,  (char*)simIO.v6.pin2, simIO.v6.aidPtr);
744     closeRequest;
745     printRequest(pRI->token, pRI->pCI->requestNumber);
746
747     if (status != NO_ERROR) {
748         goto invalid;
749     }
750
751     size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6);
752     s_callbacks.onRequest(pRI->pCI->requestNumber, &simIO, size, pRI);
753
754 #ifdef MEMSET_FREED
755     memsetString (simIO.v6.path);
756     memsetString (simIO.v6.data);
757     memsetString (simIO.v6.pin2);
758     memsetString (simIO.v6.aidPtr);
759 #endif
760
761     free (simIO.v6.path);
762     free (simIO.v6.data);
763     free (simIO.v6.pin2);
764     free (simIO.v6.aidPtr);
765
766 #ifdef MEMSET_FREED
767     memset(&simIO, 0, sizeof(simIO));
768 #endif
769
770     return;
771 invalid:
772     invalidCommandBlock(pRI);
773     return;
774 }
775
776 /**
777  * Callee expects const RIL_CallForwardInfo *
778  * Payload is:
779  *  int32_t status/action
780  *  int32_t reason
781  *  int32_t serviceCode
782  *  int32_t toa
783  *  String number  (0 length -> null)
784  *  int32_t timeSeconds
785  */
786 static void
787 dispatchCallForward(Parcel &p, RequestInfo *pRI) {
788     RIL_CallForwardInfo cff;
789     int32_t t;
790     status_t status;
791
792     memset (&cff, 0, sizeof(cff));
793
794     // note we only check status at the end
795
796     status = p.readInt32(&t);
797     cff.status = (int)t;
798
799     status = p.readInt32(&t);
800     cff.reason = (int)t;
801
802     status = p.readInt32(&t);
803     cff.serviceClass = (int)t;
804
805     status = p.readInt32(&t);
806     cff.toa = (int)t;
807
808     cff.number = strdupReadString(p);
809
810     status = p.readInt32(&t);
811     cff.timeSeconds = (int)t;
812
813     if (status != NO_ERROR) {
814         goto invalid;
815     }
816
817     // special case: number 0-length fields is null
818
819     if (cff.number != NULL && strlen (cff.number) == 0) {
820         cff.number = NULL;
821     }
822
823     startRequest;
824     appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
825         cff.status, cff.reason, cff.serviceClass, cff.toa,
826         (char*)cff.number, cff.timeSeconds);
827     closeRequest;
828     printRequest(pRI->token, pRI->pCI->requestNumber);
829
830     s_callbacks.onRequest(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI);
831
832 #ifdef MEMSET_FREED
833     memsetString(cff.number);
834 #endif
835
836     free (cff.number);
837
838 #ifdef MEMSET_FREED
839     memset(&cff, 0, sizeof(cff));
840 #endif
841
842     return;
843 invalid:
844     invalidCommandBlock(pRI);
845     return;
846 }
847
848
849 static void
850 dispatchRaw(Parcel &p, RequestInfo *pRI) {
851     int32_t len;
852     status_t status;
853     const void *data;
854
855     status = p.readInt32(&len);
856
857     if (status != NO_ERROR) {
858         goto invalid;
859     }
860
861     // The java code writes -1 for null arrays
862     if (((int)len) == -1) {
863         data = NULL;
864         len = 0;
865     }
866
867     data = p.readInplace(len);
868
869     startRequest;
870     appendPrintBuf("%sraw_size=%d", printBuf, len);
871     closeRequest;
872     printRequest(pRI->token, pRI->pCI->requestNumber);
873
874     s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI);
875
876     return;
877 invalid:
878     invalidCommandBlock(pRI);
879     return;
880 }
881
882 static void
883 dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
884     RIL_CDMA_SMS_Message rcsm;
885     int32_t  t;
886     uint8_t ut;
887     status_t status;
888     int32_t digitCount;
889     int digitLimit;
890
891     memset(&rcsm, 0, sizeof(rcsm));
892
893     status = p.readInt32(&t);
894     rcsm.uTeleserviceID = (int) t;
895
896     status = p.read(&ut,sizeof(ut));
897     rcsm.bIsServicePresent = (uint8_t) ut;
898
899     status = p.readInt32(&t);
900     rcsm.uServicecategory = (int) t;
901
902     status = p.readInt32(&t);
903     rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
904
905     status = p.readInt32(&t);
906     rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
907
908     status = p.readInt32(&t);
909     rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
910
911     status = p.readInt32(&t);
912     rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
913
914     status = p.read(&ut,sizeof(ut));
915     rcsm.sAddress.number_of_digits= (uint8_t) ut;
916
917     digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
918     for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
919         status = p.read(&ut,sizeof(ut));
920         rcsm.sAddress.digits[digitCount] = (uint8_t) ut;
921     }
922
923     status = p.readInt32(&t);
924     rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
925
926     status = p.read(&ut,sizeof(ut));
927     rcsm.sSubAddress.odd = (uint8_t) ut;
928
929     status = p.read(&ut,sizeof(ut));
930     rcsm.sSubAddress.number_of_digits = (uint8_t) ut;
931
932     digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
933     for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
934         status = p.read(&ut,sizeof(ut));
935         rcsm.sSubAddress.digits[digitCount] = (uint8_t) ut;
936     }
937
938     status = p.readInt32(&t);
939     rcsm.uBearerDataLen = (int) t;
940
941     digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
942     for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
943         status = p.read(&ut, sizeof(ut));
944         rcsm.aBearerData[digitCount] = (uint8_t) ut;
945     }
946
947     if (status != NO_ERROR) {
948         goto invalid;
949     }
950
951     startRequest;
952     appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
953             sAddress.digit_mode=%d, sAddress.Number_mode=%d, sAddress.number_type=%d, ",
954             printBuf, rcsm.uTeleserviceID,rcsm.bIsServicePresent,rcsm.uServicecategory,
955             rcsm.sAddress.digit_mode, rcsm.sAddress.number_mode,rcsm.sAddress.number_type);
956     closeRequest;
957
958     printRequest(pRI->token, pRI->pCI->requestNumber);
959
960     s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI);
961
962 #ifdef MEMSET_FREED
963     memset(&rcsm, 0, sizeof(rcsm));
964 #endif
965
966     return;
967
968 invalid:
969     invalidCommandBlock(pRI);
970     return;
971 }
972
973 static void
974 dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) {
975     RIL_CDMA_SMS_Ack rcsa;
976     int32_t  t;
977     status_t status;
978     int32_t digitCount;
979
980     memset(&rcsa, 0, sizeof(rcsa));
981
982     status = p.readInt32(&t);
983     rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) t;
984
985     status = p.readInt32(&t);
986     rcsa.uSMSCauseCode = (int) t;
987
988     if (status != NO_ERROR) {
989         goto invalid;
990     }
991
992     startRequest;
993     appendPrintBuf("%suErrorClass=%d, uTLStatus=%d, ",
994             printBuf, rcsa.uErrorClass, rcsa.uSMSCauseCode);
995     closeRequest;
996
997     printRequest(pRI->token, pRI->pCI->requestNumber);
998
999     s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI);
1000
1001 #ifdef MEMSET_FREED
1002     memset(&rcsa, 0, sizeof(rcsa));
1003 #endif
1004
1005     return;
1006
1007 invalid:
1008     invalidCommandBlock(pRI);
1009     return;
1010 }
1011
1012 static void
1013 dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1014     int32_t t;
1015     status_t status;
1016     int32_t num;
1017
1018     status = p.readInt32(&num);
1019     if (status != NO_ERROR) {
1020         goto invalid;
1021     }
1022
1023     {
1024         RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
1025         RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
1026
1027         startRequest;
1028         for (int i = 0 ; i < num ; i++ ) {
1029             gsmBciPtrs[i] = &gsmBci[i];
1030
1031             status = p.readInt32(&t);
1032             gsmBci[i].fromServiceId = (int) t;
1033
1034             status = p.readInt32(&t);
1035             gsmBci[i].toServiceId = (int) t;
1036
1037             status = p.readInt32(&t);
1038             gsmBci[i].fromCodeScheme = (int) t;
1039
1040             status = p.readInt32(&t);
1041             gsmBci[i].toCodeScheme = (int) t;
1042
1043             status = p.readInt32(&t);
1044             gsmBci[i].selected = (uint8_t) t;
1045
1046             appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId =%d, \
1047                   fromCodeScheme=%d, toCodeScheme=%d, selected =%d]", printBuf, i,
1048                   gsmBci[i].fromServiceId, gsmBci[i].toServiceId,
1049                   gsmBci[i].fromCodeScheme, gsmBci[i].toCodeScheme,
1050                   gsmBci[i].selected);
1051         }
1052         closeRequest;
1053
1054         if (status != NO_ERROR) {
1055             goto invalid;
1056         }
1057
1058         s_callbacks.onRequest(pRI->pCI->requestNumber,
1059                               gsmBciPtrs,
1060                               num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *),
1061                               pRI);
1062
1063 #ifdef MEMSET_FREED
1064         memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo));
1065         memset(gsmBciPtrs, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
1066 #endif
1067     }
1068
1069     return;
1070
1071 invalid:
1072     invalidCommandBlock(pRI);
1073     return;
1074 }
1075
1076 static void
1077 dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) {
1078     int32_t t;
1079     status_t status;
1080     int32_t num;
1081
1082     status = p.readInt32(&num);
1083     if (status != NO_ERROR) {
1084         goto invalid;
1085     }
1086
1087     {
1088         RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
1089         RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
1090
1091         startRequest;
1092         for (int i = 0 ; i < num ; i++ ) {
1093             cdmaBciPtrs[i] = &cdmaBci[i];
1094
1095             status = p.readInt32(&t);
1096             cdmaBci[i].service_category = (int) t;
1097
1098             status = p.readInt32(&t);
1099             cdmaBci[i].language = (int) t;
1100
1101             status = p.readInt32(&t);
1102             cdmaBci[i].selected = (uint8_t) t;
1103
1104             appendPrintBuf("%s [%d: service_category=%d, language =%d, \
1105                   entries.bSelected =%d]", printBuf, i, cdmaBci[i].service_category,
1106                   cdmaBci[i].language, cdmaBci[i].selected);
1107         }
1108         closeRequest;
1109
1110         if (status != NO_ERROR) {
1111             goto invalid;
1112         }
1113
1114         s_callbacks.onRequest(pRI->pCI->requestNumber,
1115                               cdmaBciPtrs,
1116                               num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *),
1117                               pRI);
1118
1119 #ifdef MEMSET_FREED
1120         memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo));
1121         memset(cdmaBciPtrs, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *));
1122 #endif
1123     }
1124
1125     return;
1126
1127 invalid:
1128     invalidCommandBlock(pRI);
1129     return;
1130 }
1131
1132 static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) {
1133     RIL_CDMA_SMS_WriteArgs rcsw;
1134     int32_t  t;
1135     uint32_t ut;
1136     uint8_t  uct;
1137     status_t status;
1138     int32_t  digitCount;
1139
1140     memset(&rcsw, 0, sizeof(rcsw));
1141
1142     status = p.readInt32(&t);
1143     rcsw.status = t;
1144
1145     status = p.readInt32(&t);
1146     rcsw.message.uTeleserviceID = (int) t;
1147
1148     status = p.read(&uct,sizeof(uct));
1149     rcsw.message.bIsServicePresent = (uint8_t) uct;
1150
1151     status = p.readInt32(&t);
1152     rcsw.message.uServicecategory = (int) t;
1153
1154     status = p.readInt32(&t);
1155     rcsw.message.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) t;
1156
1157     status = p.readInt32(&t);
1158     rcsw.message.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) t;
1159
1160     status = p.readInt32(&t);
1161     rcsw.message.sAddress.number_type = (RIL_CDMA_SMS_NumberType) t;
1162
1163     status = p.readInt32(&t);
1164     rcsw.message.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) t;
1165
1166     status = p.read(&uct,sizeof(uct));
1167     rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
1168
1169     for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_ADDRESS_MAX; digitCount ++) {
1170         status = p.read(&uct,sizeof(uct));
1171         rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
1172     }
1173
1174     status = p.readInt32(&t);
1175     rcsw.message.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) t;
1176
1177     status = p.read(&uct,sizeof(uct));
1178     rcsw.message.sSubAddress.odd = (uint8_t) uct;
1179
1180     status = p.read(&uct,sizeof(uct));
1181     rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
1182
1183     for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_SUBADDRESS_MAX; digitCount ++) {
1184         status = p.read(&uct,sizeof(uct));
1185         rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
1186     }
1187
1188     status = p.readInt32(&t);
1189     rcsw.message.uBearerDataLen = (int) t;
1190
1191     for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_BEARER_DATA_MAX; digitCount ++) {
1192         status = p.read(&uct, sizeof(uct));
1193         rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
1194     }
1195
1196     if (status != NO_ERROR) {
1197         goto invalid;
1198     }
1199
1200     startRequest;
1201     appendPrintBuf("%sstatus=%d, message.uTeleserviceID=%d, message.bIsServicePresent=%d, \
1202             message.uServicecategory=%d, message.sAddress.digit_mode=%d, \
1203             message.sAddress.number_mode=%d, \
1204             message.sAddress.number_type=%d, ",
1205             printBuf, rcsw.status, rcsw.message.uTeleserviceID, rcsw.message.bIsServicePresent,
1206             rcsw.message.uServicecategory, rcsw.message.sAddress.digit_mode,
1207             rcsw.message.sAddress.number_mode,
1208             rcsw.message.sAddress.number_type);
1209     closeRequest;
1210
1211     printRequest(pRI->token, pRI->pCI->requestNumber);
1212
1213     s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI);
1214
1215 #ifdef MEMSET_FREED
1216     memset(&rcsw, 0, sizeof(rcsw));
1217 #endif
1218
1219     return;
1220
1221 invalid:
1222     invalidCommandBlock(pRI);
1223     return;
1224
1225 }
1226
1227 // For backwards compatibility in RIL_REQUEST_SETUP_DATA_CALL.
1228 // Version 4 of the RIL interface adds a new PDP type parameter to support
1229 // IPv6 and dual-stack PDP contexts. When dealing with a previous version of
1230 // RIL, remove the parameter from the request.
1231 static void dispatchDataCall(Parcel& p, RequestInfo *pRI) {
1232     // In RIL v3, REQUEST_SETUP_DATA_CALL takes 6 parameters.
1233     const int numParamsRilV3 = 6;
1234
1235     // The first bytes of the RIL parcel contain the request number and the
1236     // serial number - see processCommandBuffer(). Copy them over too.
1237     int pos = p.dataPosition();
1238
1239     int numParams = p.readInt32();
1240     if (s_callbacks.version < 4 && numParams > numParamsRilV3) {
1241       Parcel p2;
1242       p2.appendFrom(&p, 0, pos);
1243       p2.writeInt32(numParamsRilV3);
1244       for(int i = 0; i < numParamsRilV3; i++) {
1245         p2.writeString16(p.readString16());
1246       }
1247       p2.setDataPosition(pos);
1248       dispatchStrings(p2, pRI);
1249     } else {
1250       p.setDataPosition(pos);
1251       dispatchStrings(p, pRI);
1252     }
1253 }
1254
1255 // For backwards compatibility with RILs that dont support RIL_REQUEST_VOICE_RADIO_TECH.
1256 // When all RILs handle this request, this function can be removed and
1257 // the request can be sent directly to the RIL using dispatchVoid.
1258 static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) {
1259     RIL_RadioState state = s_callbacks.onStateRequest();
1260
1261     if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1262         RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1263     }
1264
1265     // RILs that support RADIO_STATE_ON should support this request.
1266     if (RADIO_STATE_ON == state) {
1267         dispatchVoid(p, pRI);
1268         return;
1269     }
1270
1271     // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1272     // will not support this new request either and decode Voice Radio Technology
1273     // from Radio State
1274     voiceRadioTech = decodeVoiceRadioTechnology(state);
1275
1276     if (voiceRadioTech < 0)
1277         RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1278     else
1279         RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &voiceRadioTech, sizeof(int));
1280 }
1281
1282 // For backwards compatibility in RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:.
1283 // When all RILs handle this request, this function can be removed and
1284 // the request can be sent directly to the RIL using dispatchVoid.
1285 static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) {
1286     RIL_RadioState state = s_callbacks.onStateRequest();
1287
1288     if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) {
1289         RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1290     }
1291
1292     // RILs that support RADIO_STATE_ON should support this request.
1293     if (RADIO_STATE_ON == state) {
1294         dispatchVoid(p, pRI);
1295         return;
1296     }
1297
1298     // For Older RILs, that do not support RADIO_STATE_ON, assume that they
1299     // will not support this new request either and decode CDMA Subscription Source
1300     // from Radio State
1301     cdmaSubscriptionSource = decodeCdmaSubscriptionSource(state);
1302
1303     if (cdmaSubscriptionSource < 0)
1304         RIL_onRequestComplete(pRI, RIL_E_GENERIC_FAILURE, NULL, 0);
1305     else
1306         RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int));
1307 }
1308
1309 static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI)
1310 {
1311     RIL_InitialAttachApn pf;
1312     int32_t  t;
1313     status_t status;
1314
1315     memset(&pf, 0, sizeof(pf));
1316
1317     pf.apn = strdupReadString(p);
1318     pf.protocol = strdupReadString(p);
1319
1320     status = p.readInt32(&t);
1321     pf.authtype = (int) t;
1322
1323     pf.username = strdupReadString(p);
1324     pf.password = strdupReadString(p);
1325
1326     startRequest;
1327     appendPrintBuf("%sapn=%s, protocol=%s, auth_type=%d, username=%s, password=%s",
1328             printBuf, pf.apn, pf.protocol, pf.auth_type, pf.username, pf.password);
1329     closeRequest;
1330     printRequest(pRI->token, pRI->pCI->requestNumber);
1331
1332     if (status != NO_ERROR) {
1333         goto invalid;
1334     }
1335     s_callbacks.onRequest(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI);
1336
1337 #ifdef MEMSET_FREED
1338     memsetString(pf.apn);
1339     memsetString(pf.protocol);
1340     memsetString(pf.username);
1341     memsetString(pf.password);
1342 #endif
1343
1344     free(pf.apn);
1345     free(pf.protocol);
1346     free(pf.username);
1347     free(pf.password);
1348
1349 #ifdef MEMSET_FREED
1350     memset(&pf, 0, sizeof(pf));
1351 #endif
1352
1353     return;
1354 invalid:
1355     invalidCommandBlock(pRI);
1356     return;
1357 }
1358
1359 static int
1360 blockingWrite(int fd, const void *buffer, size_t len) {
1361     size_t writeOffset = 0;
1362     const uint8_t *toWrite;
1363
1364     toWrite = (const uint8_t *)buffer;
1365
1366     while (writeOffset < len) {
1367         ssize_t written;
1368         do {
1369             written = write (fd, toWrite + writeOffset,
1370                                 len - writeOffset);
1371         } while (written < 0 && ((errno == EINTR) || (errno == EAGAIN)));
1372
1373         if (written >= 0) {
1374             writeOffset += written;
1375         } else {   // written < 0
1376             RLOGE ("RIL Response: unexpected error on write errno:%d", errno);
1377             close(fd);
1378             return -1;
1379         }
1380     }
1381
1382     return 0;
1383 }
1384
1385 static int
1386 sendResponseRaw (const void *data, size_t dataSize) {
1387     int fd = s_fdCommand;
1388     int ret;
1389     uint32_t header;
1390
1391     if (s_fdCommand < 0) {
1392         return -1;
1393     }
1394
1395     if (dataSize > MAX_COMMAND_BYTES) {
1396         RLOGE("RIL: packet larger than %u (%u)",
1397                 MAX_COMMAND_BYTES, (unsigned int )dataSize);
1398
1399         return -1;
1400     }
1401
1402     pthread_mutex_lock(&s_writeMutex);
1403
1404     header = htonl(dataSize);
1405
1406     ret = blockingWrite(fd, (void *)&header, sizeof(header));
1407
1408     if (ret < 0) {
1409         pthread_mutex_unlock(&s_writeMutex);
1410         return ret;
1411     }
1412
1413     ret = blockingWrite(fd, data, dataSize);
1414
1415     if (ret < 0) {
1416         pthread_mutex_unlock(&s_writeMutex);
1417         return ret;
1418     }
1419
1420     pthread_mutex_unlock(&s_writeMutex);
1421
1422     return 0;
1423 }
1424
1425 static int
1426 sendResponse (Parcel &p) {
1427     printResponse;
1428     return sendResponseRaw(p.data(), p.dataSize());
1429 }
1430
1431 /** response is an int* pointing to an array of ints*/
1432
1433 static int
1434 responseInts(Parcel &p, void *response, size_t responselen) {
1435     int numInts;
1436
1437     if (response == NULL && responselen != 0) {
1438         RLOGE("invalid response: NULL");
1439         return RIL_ERRNO_INVALID_RESPONSE;
1440     }
1441     if (responselen % sizeof(int) != 0) {
1442         RLOGE("invalid response length %d expected multiple of %d\n",
1443             (int)responselen, (int)sizeof(int));
1444         return RIL_ERRNO_INVALID_RESPONSE;
1445     }
1446
1447     int *p_int = (int *) response;
1448
1449     numInts = responselen / sizeof(int *);
1450     p.writeInt32 (numInts);
1451
1452     /* each int*/
1453     startResponse;
1454     for (int i = 0 ; i < numInts ; i++) {
1455         appendPrintBuf("%s%d,", printBuf, p_int[i]);
1456         p.writeInt32(p_int[i]);
1457     }
1458     removeLastChar;
1459     closeResponse;
1460
1461     return 0;
1462 }
1463
1464 /** response is a char **, pointing to an array of char *'s
1465     The parcel will begin with the version */
1466 static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
1467     p.writeInt32(version);
1468     return responseStrings(p, response, responselen);
1469 }
1470
1471 /** response is a char **, pointing to an array of char *'s */
1472 static int responseStrings(Parcel &p, void *response, size_t responselen) {
1473     int numStrings;
1474
1475     if (response == NULL && responselen != 0) {
1476         RLOGE("invalid response: NULL");
1477         return RIL_ERRNO_INVALID_RESPONSE;
1478     }
1479     if (responselen % sizeof(char *) != 0) {
1480         RLOGE("invalid response length %d expected multiple of %d\n",
1481             (int)responselen, (int)sizeof(char *));
1482         return RIL_ERRNO_INVALID_RESPONSE;
1483     }
1484
1485     if (response == NULL) {
1486         p.writeInt32 (0);
1487     } else {
1488         char **p_cur = (char **) response;
1489
1490         numStrings = responselen / sizeof(char *);
1491         p.writeInt32 (numStrings);
1492
1493         /* each string*/
1494         startResponse;
1495         for (int i = 0 ; i < numStrings ; i++) {
1496             appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
1497             writeStringToParcel (p, p_cur[i]);
1498         }
1499         removeLastChar;
1500         closeResponse;
1501     }
1502     return 0;
1503 }
1504
1505
1506 /**
1507  * NULL strings are accepted
1508  * FIXME currently ignores responselen
1509  */
1510 static int responseString(Parcel &p, void *response, size_t responselen) {
1511     /* one string only */
1512     startResponse;
1513     appendPrintBuf("%s%s", printBuf, (char*)response);
1514     closeResponse;
1515
1516     writeStringToParcel(p, (const char *)response);
1517
1518     return 0;
1519 }
1520
1521 static int responseVoid(Parcel &p, void *response, size_t responselen) {
1522     startResponse;
1523     removeLastChar;
1524     return 0;
1525 }
1526
1527 static int responseCallList(Parcel &p, void *response, size_t responselen) {
1528     int num;
1529
1530     if (response == NULL && responselen != 0) {
1531         RLOGE("invalid response: NULL");
1532         return RIL_ERRNO_INVALID_RESPONSE;
1533     }
1534
1535     if (responselen % sizeof (RIL_Call *) != 0) {
1536         RLOGE("invalid response length %d expected multiple of %d\n",
1537             (int)responselen, (int)sizeof (RIL_Call *));
1538         return RIL_ERRNO_INVALID_RESPONSE;
1539     }
1540
1541     startResponse;
1542     /* number of call info's */
1543     num = responselen / sizeof(RIL_Call *);
1544     p.writeInt32(num);
1545
1546     for (int i = 0 ; i < num ; i++) {
1547         RIL_Call *p_cur = ((RIL_Call **) response)[i];
1548         /* each call info */
1549         p.writeInt32(p_cur->state);
1550         p.writeInt32(p_cur->index);
1551         p.writeInt32(p_cur->toa);
1552         p.writeInt32(p_cur->isMpty);
1553         p.writeInt32(p_cur->isMT);
1554         p.writeInt32(p_cur->als);
1555         p.writeInt32(p_cur->isVoice);
1556         p.writeInt32(p_cur->isVoicePrivacy);
1557         writeStringToParcel(p, p_cur->number);
1558         p.writeInt32(p_cur->numberPresentation);
1559         writeStringToParcel(p, p_cur->name);
1560         p.writeInt32(p_cur->namePresentation);
1561         // Remove when partners upgrade to version 3
1562         if ((s_callbacks.version < 3) || (p_cur->uusInfo == NULL || p_cur->uusInfo->uusData == NULL)) {
1563             p.writeInt32(0); /* UUS Information is absent */
1564         } else {
1565             RIL_UUS_Info *uusInfo = p_cur->uusInfo;
1566             p.writeInt32(1); /* UUS Information is present */
1567             p.writeInt32(uusInfo->uusType);
1568             p.writeInt32(uusInfo->uusDcs);
1569             p.writeInt32(uusInfo->uusLength);
1570             p.write(uusInfo->uusData, uusInfo->uusLength);
1571         }
1572         appendPrintBuf("%s[id=%d,%s,toa=%d,",
1573             printBuf,
1574             p_cur->index,
1575             callStateToString(p_cur->state),
1576             p_cur->toa);
1577         appendPrintBuf("%s%s,%s,als=%d,%s,%s,",
1578             printBuf,
1579             (p_cur->isMpty)?"conf":"norm",
1580             (p_cur->isMT)?"mt":"mo",
1581             p_cur->als,
1582             (p_cur->isVoice)?"voc":"nonvoc",
1583             (p_cur->isVoicePrivacy)?"evp":"noevp");
1584         appendPrintBuf("%s%s,cli=%d,name='%s',%d]",
1585             printBuf,
1586             p_cur->number,
1587             p_cur->numberPresentation,
1588             p_cur->name,
1589             p_cur->namePresentation);
1590     }
1591     removeLastChar;
1592     closeResponse;
1593
1594     return 0;
1595 }
1596
1597 static int responseSMS(Parcel &p, void *response, size_t responselen) {
1598     if (response == NULL) {
1599         RLOGE("invalid response: NULL");
1600         return RIL_ERRNO_INVALID_RESPONSE;
1601     }
1602
1603     if (responselen != sizeof (RIL_SMS_Response) ) {
1604         RLOGE("invalid response length %d expected %d",
1605                 (int)responselen, (int)sizeof (RIL_SMS_Response));
1606         return RIL_ERRNO_INVALID_RESPONSE;
1607     }
1608
1609     RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
1610
1611     p.writeInt32(p_cur->messageRef);
1612     writeStringToParcel(p, p_cur->ackPDU);
1613     p.writeInt32(p_cur->errorCode);
1614
1615     startResponse;
1616     appendPrintBuf("%s%d,%s,%d", printBuf, p_cur->messageRef,
1617         (char*)p_cur->ackPDU, p_cur->errorCode);
1618     closeResponse;
1619
1620     return 0;
1621 }
1622
1623 static int responseDataCallListV4(Parcel &p, void *response, size_t responselen)
1624 {
1625     if (response == NULL && responselen != 0) {
1626         RLOGE("invalid response: NULL");
1627         return RIL_ERRNO_INVALID_RESPONSE;
1628     }
1629
1630     if (responselen % sizeof(RIL_Data_Call_Response_v4) != 0) {
1631         RLOGE("invalid response length %d expected multiple of %d",
1632                 (int)responselen, (int)sizeof(RIL_Data_Call_Response_v4));
1633         return RIL_ERRNO_INVALID_RESPONSE;
1634     }
1635
1636     int num = responselen / sizeof(RIL_Data_Call_Response_v4);
1637     p.writeInt32(num);
1638
1639     RIL_Data_Call_Response_v4 *p_cur = (RIL_Data_Call_Response_v4 *) response;
1640     startResponse;
1641     int i;
1642     for (i = 0; i < num; i++) {
1643         p.writeInt32(p_cur[i].cid);
1644         p.writeInt32(p_cur[i].active);
1645         writeStringToParcel(p, p_cur[i].type);
1646         // apn is not used, so don't send.
1647         writeStringToParcel(p, p_cur[i].address);
1648         appendPrintBuf("%s[cid=%d,%s,%s,%s],", printBuf,
1649             p_cur[i].cid,
1650             (p_cur[i].active==0)?"down":"up",
1651             (char*)p_cur[i].type,
1652             (char*)p_cur[i].address);
1653     }
1654     removeLastChar;
1655     closeResponse;
1656
1657     return 0;
1658 }
1659
1660 static int responseDataCallList(Parcel &p, void *response, size_t responselen)
1661 {
1662     // Write version
1663     p.writeInt32(s_callbacks.version);
1664
1665     if (s_callbacks.version < 5) {
1666         return responseDataCallListV4(p, response, responselen);
1667     } else {
1668         if (response == NULL && responselen != 0) {
1669             RLOGE("invalid response: NULL");
1670             return RIL_ERRNO_INVALID_RESPONSE;
1671         }
1672
1673         if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) {
1674             RLOGE("invalid response length %d expected multiple of %d",
1675                     (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6));
1676             return RIL_ERRNO_INVALID_RESPONSE;
1677         }
1678
1679         int num = responselen / sizeof(RIL_Data_Call_Response_v6);
1680         p.writeInt32(num);
1681
1682         RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response;
1683         startResponse;
1684         int i;
1685         for (i = 0; i < num; i++) {
1686             p.writeInt32((int)p_cur[i].status);
1687             p.writeInt32(p_cur[i].suggestedRetryTime);
1688             p.writeInt32(p_cur[i].cid);
1689             p.writeInt32(p_cur[i].active);
1690             writeStringToParcel(p, p_cur[i].type);
1691             writeStringToParcel(p, p_cur[i].ifname);
1692             writeStringToParcel(p, p_cur[i].addresses);
1693             writeStringToParcel(p, p_cur[i].dnses);
1694             writeStringToParcel(p, p_cur[i].gateways);
1695             appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf,
1696                 p_cur[i].status,
1697                 p_cur[i].suggestedRetryTime,
1698                 p_cur[i].cid,
1699                 (p_cur[i].active==0)?"down":"up",
1700                 (char*)p_cur[i].type,
1701                 (char*)p_cur[i].ifname,
1702                 (char*)p_cur[i].addresses,
1703                 (char*)p_cur[i].dnses,
1704                 (char*)p_cur[i].gateways);
1705         }
1706         removeLastChar;
1707         closeResponse;
1708     }
1709
1710     return 0;
1711 }
1712
1713 static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
1714 {
1715     if (s_callbacks.version < 5) {
1716         return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
1717     } else {
1718         return responseDataCallList(p, response, responselen);
1719     }
1720 }
1721
1722 static int responseRaw(Parcel &p, void *response, size_t responselen) {
1723     if (response == NULL && responselen != 0) {
1724         RLOGE("invalid response: NULL with responselen != 0");
1725         return RIL_ERRNO_INVALID_RESPONSE;
1726     }
1727
1728     // The java code reads -1 size as null byte array
1729     if (response == NULL) {
1730         p.writeInt32(-1);
1731     } else {
1732         p.writeInt32(responselen);
1733         p.write(response, responselen);
1734     }
1735
1736     return 0;
1737 }
1738
1739
1740 static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
1741     if (response == NULL) {
1742         RLOGE("invalid response: NULL");
1743         return RIL_ERRNO_INVALID_RESPONSE;
1744     }
1745
1746     if (responselen != sizeof (RIL_SIM_IO_Response) ) {
1747         RLOGE("invalid response length was %d expected %d",
1748                 (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
1749         return RIL_ERRNO_INVALID_RESPONSE;
1750     }
1751
1752     RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
1753     p.writeInt32(p_cur->sw1);
1754     p.writeInt32(p_cur->sw2);
1755     writeStringToParcel(p, p_cur->simResponse);
1756
1757     startResponse;
1758     appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
1759         (char*)p_cur->simResponse);
1760     closeResponse;
1761
1762
1763     return 0;
1764 }
1765
1766 static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
1767     int num;
1768
1769     if (response == NULL && responselen != 0) {
1770         RLOGE("invalid response: NULL");
1771         return RIL_ERRNO_INVALID_RESPONSE;
1772     }
1773
1774     if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
1775         RLOGE("invalid response length %d expected multiple of %d",
1776                 (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
1777         return RIL_ERRNO_INVALID_RESPONSE;
1778     }
1779
1780     /* number of call info's */
1781     num = responselen / sizeof(RIL_CallForwardInfo *);
1782     p.writeInt32(num);
1783
1784     startResponse;
1785     for (int i = 0 ; i < num ; i++) {
1786         RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
1787
1788         p.writeInt32(p_cur->status);
1789         p.writeInt32(p_cur->reason);
1790         p.writeInt32(p_cur->serviceClass);
1791         p.writeInt32(p_cur->toa);
1792         writeStringToParcel(p, p_cur->number);
1793         p.writeInt32(p_cur->timeSeconds);
1794         appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
1795             (p_cur->status==1)?"enable":"disable",
1796             p_cur->reason, p_cur->serviceClass, p_cur->toa,
1797             (char*)p_cur->number,
1798             p_cur->timeSeconds);
1799     }
1800     removeLastChar;
1801     closeResponse;
1802
1803     return 0;
1804 }
1805
1806 static int responseSsn(Parcel &p, void *response, size_t responselen) {
1807     if (response == NULL) {
1808         RLOGE("invalid response: NULL");
1809         return RIL_ERRNO_INVALID_RESPONSE;
1810     }
1811
1812     if (responselen != sizeof(RIL_SuppSvcNotification)) {
1813         RLOGE("invalid response length was %d expected %d",
1814                 (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
1815         return RIL_ERRNO_INVALID_RESPONSE;
1816     }
1817
1818     RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
1819     p.writeInt32(p_cur->notificationType);
1820     p.writeInt32(p_cur->code);
1821     p.writeInt32(p_cur->index);
1822     p.writeInt32(p_cur->type);
1823     writeStringToParcel(p, p_cur->number);
1824
1825     startResponse;
1826     appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
1827         (p_cur->notificationType==0)?"mo":"mt",
1828          p_cur->code, p_cur->index, p_cur->type,
1829         (char*)p_cur->number);
1830     closeResponse;
1831
1832     return 0;
1833 }
1834
1835 static int responseCellList(Parcel &p, void *response, size_t responselen) {
1836     int num;
1837
1838     if (response == NULL && responselen != 0) {
1839         RLOGE("invalid response: NULL");
1840         return RIL_ERRNO_INVALID_RESPONSE;
1841     }
1842
1843     if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
1844         RLOGE("invalid response length %d expected multiple of %d\n",
1845             (int)responselen, (int)sizeof (RIL_NeighboringCell *));
1846         return RIL_ERRNO_INVALID_RESPONSE;
1847     }
1848
1849     startResponse;
1850     /* number of records */
1851     num = responselen / sizeof(RIL_NeighboringCell *);
1852     p.writeInt32(num);
1853
1854     for (int i = 0 ; i < num ; i++) {
1855         RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
1856
1857         p.writeInt32(p_cur->rssi);
1858         writeStringToParcel (p, p_cur->cid);
1859
1860         appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
1861             p_cur->cid, p_cur->rssi);
1862     }
1863     removeLastChar;
1864     closeResponse;
1865
1866     return 0;
1867 }
1868
1869 /**
1870  * Marshall the signalInfoRecord into the parcel if it exists.
1871  */
1872 static void marshallSignalInfoRecord(Parcel &p,
1873             RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
1874     p.writeInt32(p_signalInfoRecord.isPresent);
1875     p.writeInt32(p_signalInfoRecord.signalType);
1876     p.writeInt32(p_signalInfoRecord.alertPitch);
1877     p.writeInt32(p_signalInfoRecord.signal);
1878 }
1879
1880 static int responseCdmaInformationRecords(Parcel &p,
1881             void *response, size_t responselen) {
1882     int num;
1883     char* string8 = NULL;
1884     int buffer_lenght;
1885     RIL_CDMA_InformationRecord *infoRec;
1886
1887     if (response == NULL && responselen != 0) {
1888         RLOGE("invalid response: NULL");
1889         return RIL_ERRNO_INVALID_RESPONSE;
1890     }
1891
1892     if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
1893         RLOGE("invalid response length %d expected multiple of %d\n",
1894             (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
1895         return RIL_ERRNO_INVALID_RESPONSE;
1896     }
1897
1898     RIL_CDMA_InformationRecords *p_cur =
1899                              (RIL_CDMA_InformationRecords *) response;
1900     num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
1901
1902     startResponse;
1903     p.writeInt32(num);
1904
1905     for (int i = 0 ; i < num ; i++) {
1906         infoRec = &p_cur->infoRec[i];
1907         p.writeInt32(infoRec->name);
1908         switch (infoRec->name) {
1909             case RIL_CDMA_DISPLAY_INFO_REC:
1910             case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
1911                 if (infoRec->rec.display.alpha_len >
1912                                          CDMA_ALPHA_INFO_BUFFER_LENGTH) {
1913                     RLOGE("invalid display info response length %d \
1914                           expected not more than %d\n",
1915                          (int)infoRec->rec.display.alpha_len,
1916                          CDMA_ALPHA_INFO_BUFFER_LENGTH);
1917                     return RIL_ERRNO_INVALID_RESPONSE;
1918                 }
1919                 string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1)
1920                                                              * sizeof(char) );
1921                 for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
1922                     string8[i] = infoRec->rec.display.alpha_buf[i];
1923                 }
1924                 string8[(int)infoRec->rec.display.alpha_len] = '\0';
1925                 writeStringToParcel(p, (const char*)string8);
1926                 free(string8);
1927                 string8 = NULL;
1928                 break;
1929             case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
1930             case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
1931             case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
1932                 if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
1933                     RLOGE("invalid display info response length %d \
1934                           expected not more than %d\n",
1935                          (int)infoRec->rec.number.len,
1936                          CDMA_NUMBER_INFO_BUFFER_LENGTH);
1937                     return RIL_ERRNO_INVALID_RESPONSE;
1938                 }
1939                 string8 = (char*) malloc((infoRec->rec.number.len + 1)
1940                                                              * sizeof(char) );
1941                 for (int i = 0 ; i < infoRec->rec.number.len; i++) {
1942                     string8[i] = infoRec->rec.number.buf[i];
1943                 }
1944                 string8[(int)infoRec->rec.number.len] = '\0';
1945                 writeStringToParcel(p, (const char*)string8);
1946                 free(string8);
1947                 string8 = NULL;
1948                 p.writeInt32(infoRec->rec.number.number_type);
1949                 p.writeInt32(infoRec->rec.number.number_plan);
1950                 p.writeInt32(infoRec->rec.number.pi);
1951                 p.writeInt32(infoRec->rec.number.si);
1952                 break;
1953             case RIL_CDMA_SIGNAL_INFO_REC:
1954                 p.writeInt32(infoRec->rec.signal.isPresent);
1955                 p.writeInt32(infoRec->rec.signal.signalType);
1956                 p.writeInt32(infoRec->rec.signal.alertPitch);
1957                 p.writeInt32(infoRec->rec.signal.signal);
1958
1959                 appendPrintBuf("%sisPresent=%X, signalType=%X, \
1960                                 alertPitch=%X, signal=%X, ",
1961                    printBuf, (int)infoRec->rec.signal.isPresent,
1962                    (int)infoRec->rec.signal.signalType,
1963                    (int)infoRec->rec.signal.alertPitch,
1964                    (int)infoRec->rec.signal.signal);
1965                 removeLastChar;
1966                 break;
1967             case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
1968                 if (infoRec->rec.redir.redirectingNumber.len >
1969                                               CDMA_NUMBER_INFO_BUFFER_LENGTH) {
1970                     RLOGE("invalid display info response length %d \
1971                           expected not more than %d\n",
1972                          (int)infoRec->rec.redir.redirectingNumber.len,
1973                          CDMA_NUMBER_INFO_BUFFER_LENGTH);
1974                     return RIL_ERRNO_INVALID_RESPONSE;
1975                 }
1976                 string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber
1977                                           .len + 1) * sizeof(char) );
1978                 for (int i = 0;
1979                          i < infoRec->rec.redir.redirectingNumber.len;
1980                          i++) {
1981                     string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
1982                 }
1983                 string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
1984                 writeStringToParcel(p, (const char*)string8);
1985                 free(string8);
1986                 string8 = NULL;
1987                 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
1988                 p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
1989                 p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
1990                 p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
1991                 p.writeInt32(infoRec->rec.redir.redirectingReason);
1992                 break;
1993             case RIL_CDMA_LINE_CONTROL_INFO_REC:
1994                 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
1995                 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
1996                 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
1997                 p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
1998
1999                 appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
2000                                 lineCtrlToggle=%d, lineCtrlReverse=%d, \
2001                                 lineCtrlPowerDenial=%d, ", printBuf,
2002                        (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
2003                        (int)infoRec->rec.lineCtrl.lineCtrlToggle,
2004                        (int)infoRec->rec.lineCtrl.lineCtrlReverse,
2005                        (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
2006                 removeLastChar;
2007                 break;
2008             case RIL_CDMA_T53_CLIR_INFO_REC:
2009                 p.writeInt32((int)(infoRec->rec.clir.cause));
2010
2011                 appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
2012                 removeLastChar;
2013                 break;
2014             case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
2015                 p.writeInt32(infoRec->rec.audioCtrl.upLink);
2016                 p.writeInt32(infoRec->rec.audioCtrl.downLink);
2017
2018                 appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
2019                         infoRec->rec.audioCtrl.upLink,
2020                         infoRec->rec.audioCtrl.downLink);
2021                 removeLastChar;
2022                 break;
2023             case RIL_CDMA_T53_RELEASE_INFO_REC:
2024                 // TODO(Moto): See David Krause, he has the answer:)
2025                 RLOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
2026                 return RIL_ERRNO_INVALID_RESPONSE;
2027             default:
2028                 RLOGE("Incorrect name value");
2029                 return RIL_ERRNO_INVALID_RESPONSE;
2030         }
2031     }
2032     closeResponse;
2033
2034     return 0;
2035 }
2036
2037 static int responseRilSignalStrength(Parcel &p,
2038                     void *response, size_t responselen) {
2039     if (response == NULL && responselen != 0) {
2040         RLOGE("invalid response: NULL");
2041         return RIL_ERRNO_INVALID_RESPONSE;
2042     }
2043
2044     if (responselen >= sizeof (RIL_SignalStrength_v5)) {
2045         RIL_SignalStrength_v6 *p_cur = ((RIL_SignalStrength_v6 *) response);
2046
2047         p.writeInt32(p_cur->GW_SignalStrength.signalStrength);
2048         p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
2049         p.writeInt32(p_cur->CDMA_SignalStrength.dbm);
2050         p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
2051         p.writeInt32(p_cur->EVDO_SignalStrength.dbm);
2052         p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
2053         p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
2054         if (responselen >= sizeof (RIL_SignalStrength_v6)) {
2055             /*
2056              * Fixup LTE for backwards compatibility
2057              */
2058             if (s_callbacks.version <= 6) {
2059                 // signalStrength: -1 -> 99
2060                 if (p_cur->LTE_SignalStrength.signalStrength == -1) {
2061                     p_cur->LTE_SignalStrength.signalStrength = 99;
2062                 }
2063                 // rsrp: -1 -> INT_MAX all other negative value to positive.
2064                 // So remap here
2065                 if (p_cur->LTE_SignalStrength.rsrp == -1) {
2066                     p_cur->LTE_SignalStrength.rsrp = INT_MAX;
2067                 } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
2068                     p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
2069                 }
2070                 // rsrq: -1 -> INT_MAX
2071                 if (p_cur->LTE_SignalStrength.rsrq == -1) {
2072                     p_cur->LTE_SignalStrength.rsrq = INT_MAX;
2073                 }
2074                 // Not remapping rssnr is already using INT_MAX
2075
2076                 // cqi: -1 -> INT_MAX
2077                 if (p_cur->LTE_SignalStrength.cqi == -1) {
2078                     p_cur->LTE_SignalStrength.cqi = INT_MAX;
2079                 }
2080             }
2081             p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
2082             p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
2083             p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
2084             p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
2085             p.writeInt32(p_cur->LTE_SignalStrength.cqi);
2086         } else {
2087             p.writeInt32(99);
2088             p.writeInt32(INT_MAX);
2089             p.writeInt32(INT_MAX);
2090             p.writeInt32(INT_MAX);
2091             p.writeInt32(INT_MAX);
2092         }
2093
2094         startResponse;
2095         appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
2096                 CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
2097                 EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
2098                 EVDO_SS.signalNoiseRatio=%d,\
2099                 LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
2100                 LTE_SS.rssnr=%d,LTE_SS.cqi=%d]",
2101                 printBuf,
2102                 p_cur->GW_SignalStrength.signalStrength,
2103                 p_cur->GW_SignalStrength.bitErrorRate,
2104                 p_cur->CDMA_SignalStrength.dbm,
2105                 p_cur->CDMA_SignalStrength.ecio,
2106                 p_cur->EVDO_SignalStrength.dbm,
2107                 p_cur->EVDO_SignalStrength.ecio,
2108                 p_cur->EVDO_SignalStrength.signalNoiseRatio,
2109                 p_cur->LTE_SignalStrength.signalStrength,
2110                 p_cur->LTE_SignalStrength.rsrp,
2111                 p_cur->LTE_SignalStrength.rsrq,
2112                 p_cur->LTE_SignalStrength.rssnr,
2113                 p_cur->LTE_SignalStrength.cqi);
2114         closeResponse;
2115
2116     } else {
2117         RLOGE("invalid response length");
2118         return RIL_ERRNO_INVALID_RESPONSE;
2119     }
2120
2121     return 0;
2122 }
2123
2124 static int responseCallRing(Parcel &p, void *response, size_t responselen) {
2125     if ((response == NULL) || (responselen == 0)) {
2126         return responseVoid(p, response, responselen);
2127     } else {
2128         return responseCdmaSignalInfoRecord(p, response, responselen);
2129     }
2130 }
2131
2132 static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
2133     if (response == NULL || responselen == 0) {
2134         RLOGE("invalid response: NULL");
2135         return RIL_ERRNO_INVALID_RESPONSE;
2136     }
2137
2138     if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
2139         RLOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
2140             (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
2141         return RIL_ERRNO_INVALID_RESPONSE;
2142     }
2143
2144     startResponse;
2145
2146     RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
2147     marshallSignalInfoRecord(p, *p_cur);
2148
2149     appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
2150               signal=%d]",
2151               printBuf,
2152               p_cur->isPresent,
2153               p_cur->signalType,
2154               p_cur->alertPitch,
2155               p_cur->signal);
2156
2157     closeResponse;
2158     return 0;
2159 }
2160
2161 static int responseCdmaCallWaiting(Parcel &p, void *response,
2162             size_t responselen) {
2163     if (response == NULL && responselen != 0) {
2164         RLOGE("invalid response: NULL");
2165         return RIL_ERRNO_INVALID_RESPONSE;
2166     }
2167
2168     if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
2169         RLOGW("Upgrade to ril version %d\n", RIL_VERSION);
2170     }
2171
2172     RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
2173
2174     writeStringToParcel(p, p_cur->number);
2175     p.writeInt32(p_cur->numberPresentation);
2176     writeStringToParcel(p, p_cur->name);
2177     marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
2178
2179     if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
2180         p.writeInt32(p_cur->number_type);
2181         p.writeInt32(p_cur->number_plan);
2182     } else {
2183         p.writeInt32(0);
2184         p.writeInt32(0);
2185     }
2186
2187     startResponse;
2188     appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
2189             signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
2190             signal=%d,number_type=%d,number_plan=%d]",
2191             printBuf,
2192             p_cur->number,
2193             p_cur->numberPresentation,
2194             p_cur->name,
2195             p_cur->signalInfoRecord.isPresent,
2196             p_cur->signalInfoRecord.signalType,
2197             p_cur->signalInfoRecord.alertPitch,
2198             p_cur->signalInfoRecord.signal,
2199             p_cur->number_type,
2200             p_cur->number_plan);
2201     closeResponse;
2202
2203     return 0;
2204 }
2205
2206 static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
2207     if (response == NULL && responselen != 0) {
2208         RLOGE("responseSimRefresh: invalid response: NULL");
2209         return RIL_ERRNO_INVALID_RESPONSE;
2210     }
2211
2212     startResponse;
2213     if (s_callbacks.version == 7) {
2214         RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
2215         p.writeInt32(p_cur->result);
2216         p.writeInt32(p_cur->ef_id);
2217         writeStringToParcel(p, p_cur->aid);
2218
2219         appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
2220                 printBuf,
2221                 p_cur->result,
2222                 p_cur->ef_id,
2223                 p_cur->aid);
2224     } else {
2225         int *p_cur = ((int *) response);
2226         p.writeInt32(p_cur[0]);
2227         p.writeInt32(p_cur[1]);
2228         writeStringToParcel(p, NULL);
2229
2230         appendPrintBuf("%sresult=%d, ef_id=%d",
2231                 printBuf,
2232                 p_cur[0],
2233                 p_cur[1]);
2234     }
2235     closeResponse;
2236
2237     return 0;
2238 }
2239
2240 static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
2241 {
2242     if (response == NULL && responselen != 0) {
2243         RLOGE("invalid response: NULL");
2244         return RIL_ERRNO_INVALID_RESPONSE;
2245     }
2246
2247     if (responselen % sizeof(RIL_CellInfo) != 0) {
2248         RLOGE("invalid response length %d expected multiple of %d",
2249                 (int)responselen, (int)sizeof(RIL_CellInfo));
2250         return RIL_ERRNO_INVALID_RESPONSE;
2251     }
2252
2253     int num = responselen / sizeof(RIL_CellInfo);
2254     p.writeInt32(num);
2255
2256     RIL_CellInfo *p_cur = (RIL_CellInfo *) response;
2257     startResponse;
2258     int i;
2259     for (i = 0; i < num; i++) {
2260         appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i,
2261             p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
2262         p.writeInt32((int)p_cur->cellInfoType);
2263         p.writeInt32(p_cur->registered);
2264         p.writeInt32(p_cur->timeStampType);
2265         p.writeInt64(p_cur->timeStamp);
2266         switch(p_cur->cellInfoType) {
2267             case RIL_CELL_INFO_TYPE_GSM: {
2268                 appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,", printBuf,
2269                     p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
2270                     p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
2271                     p_cur->CellInfo.gsm.cellIdentityGsm.lac,
2272                     p_cur->CellInfo.gsm.cellIdentityGsm.cid);
2273                 appendPrintBuf("%s gsmSS: ss=%d,ber=%d],", printBuf,
2274                     p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
2275                     p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
2276
2277                 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
2278                 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
2279                 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
2280                 p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
2281                 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
2282                 p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
2283                 break;
2284             }
2285             case RIL_CELL_INFO_TYPE_WCDMA: {
2286                 appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,", printBuf,
2287                     p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
2288                     p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
2289                     p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
2290                     p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
2291                     p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
2292                 appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf,
2293                     p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
2294                     p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
2295
2296                 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
2297                 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
2298                 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
2299                 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
2300                 p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
2301                 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
2302                 p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
2303                 break;
2304             }
2305             case RIL_CELL_INFO_TYPE_CDMA: {
2306                 appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf,
2307                     p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
2308                     p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
2309                     p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
2310                     p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
2311                     p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
2312
2313                 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
2314                 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
2315                 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
2316                 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
2317                 p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
2318
2319                 appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf,
2320                     p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
2321                     p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
2322                     p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
2323                     p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
2324                     p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
2325
2326                 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
2327                 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
2328                 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
2329                 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
2330                 p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
2331                 break;
2332             }
2333             case RIL_CELL_INFO_TYPE_LTE: {
2334                 appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d", printBuf,
2335                     p_cur->CellInfo.lte.cellIdentityLte.mcc,
2336                     p_cur->CellInfo.lte.cellIdentityLte.mnc,
2337                     p_cur->CellInfo.lte.cellIdentityLte.ci,
2338                     p_cur->CellInfo.lte.cellIdentityLte.pci,
2339                     p_cur->CellInfo.lte.cellIdentityLte.tac);
2340
2341                 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
2342                 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
2343                 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
2344                 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
2345                 p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
2346
2347                 appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf,
2348                     p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
2349                     p_cur->CellInfo.lte.signalStrengthLte.rsrp,
2350                     p_cur->CellInfo.lte.signalStrengthLte.rsrq,
2351                     p_cur->CellInfo.lte.signalStrengthLte.rssnr,
2352                     p_cur->CellInfo.lte.signalStrengthLte.cqi,
2353                     p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
2354                 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
2355                 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
2356                 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
2357                 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
2358                 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
2359                 p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
2360                 break;
2361             }
2362         }
2363         p_cur += 1;
2364     }
2365     removeLastChar;
2366     closeResponse;
2367
2368     return 0;
2369 }
2370
2371 static void triggerEvLoop() {
2372     int ret;
2373     if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
2374         /* trigger event loop to wakeup. No reason to do this,
2375          * if we're in the event loop thread */
2376          do {
2377             ret = write (s_fdWakeupWrite, " ", 1);
2378          } while (ret < 0 && errno == EINTR);
2379     }
2380 }
2381
2382 static void rilEventAddWakeup(struct ril_event *ev) {
2383     ril_event_add(ev);
2384     triggerEvLoop();
2385 }
2386
2387 static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
2388         p.writeInt32(num_apps);
2389         startResponse;
2390         for (int i = 0; i < num_apps; i++) {
2391             p.writeInt32(appStatus[i].app_type);
2392             p.writeInt32(appStatus[i].app_state);
2393             p.writeInt32(appStatus[i].perso_substate);
2394             writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
2395             writeStringToParcel(p, (const char*)
2396                                           (appStatus[i].app_label_ptr));
2397             p.writeInt32(appStatus[i].pin1_replaced);
2398             p.writeInt32(appStatus[i].pin1);
2399             p.writeInt32(appStatus[i].pin2);
2400             appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
2401                     aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
2402                     printBuf,
2403                     appStatus[i].app_type,
2404                     appStatus[i].app_state,
2405                     appStatus[i].perso_substate,
2406                     appStatus[i].aid_ptr,
2407                     appStatus[i].app_label_ptr,
2408                     appStatus[i].pin1_replaced,
2409                     appStatus[i].pin1,
2410                     appStatus[i].pin2);
2411         }
2412         closeResponse;
2413 }
2414
2415 static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
2416     int i;
2417
2418     if (response == NULL && responselen != 0) {
2419         RLOGE("invalid response: NULL");
2420         return RIL_ERRNO_INVALID_RESPONSE;
2421     }
2422
2423     if (responselen == sizeof (RIL_CardStatus_v6)) {
2424         RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
2425
2426         p.writeInt32(p_cur->card_state);
2427         p.writeInt32(p_cur->universal_pin_state);
2428         p.writeInt32(p_cur->gsm_umts_subscription_app_index);
2429         p.writeInt32(p_cur->cdma_subscription_app_index);
2430         p.writeInt32(p_cur->ims_subscription_app_index);
2431
2432         sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
2433     } else if (responselen == sizeof (RIL_CardStatus_v5)) {
2434         RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
2435
2436         p.writeInt32(p_cur->card_state);
2437         p.writeInt32(p_cur->universal_pin_state);
2438         p.writeInt32(p_cur->gsm_umts_subscription_app_index);
2439         p.writeInt32(p_cur->cdma_subscription_app_index);
2440         p.writeInt32(-1);
2441
2442         sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
2443     } else {
2444         RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
2445         return RIL_ERRNO_INVALID_RESPONSE;
2446     }
2447
2448     return 0;
2449 }
2450
2451 static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
2452     int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
2453     p.writeInt32(num);
2454
2455     startResponse;
2456     RIL_GSM_BroadcastSmsConfigInfo **p_cur =
2457                 (RIL_GSM_BroadcastSmsConfigInfo **) response;
2458     for (int i = 0; i < num; i++) {
2459         p.writeInt32(p_cur[i]->fromServiceId);
2460         p.writeInt32(p_cur[i]->toServiceId);
2461         p.writeInt32(p_cur[i]->fromCodeScheme);
2462         p.writeInt32(p_cur[i]->toCodeScheme);
2463         p.writeInt32(p_cur[i]->selected);
2464
2465         appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
2466                 fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
2467                 printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
2468                 p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
2469                 p_cur[i]->selected);
2470     }
2471     closeResponse;
2472
2473     return 0;
2474 }
2475
2476 static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
2477     RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
2478                (RIL_CDMA_BroadcastSmsConfigInfo **) response;
2479
2480     int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
2481     p.writeInt32(num);
2482
2483     startResponse;
2484     for (int i = 0 ; i < num ; i++ ) {
2485         p.writeInt32(p_cur[i]->service_category);
2486         p.writeInt32(p_cur[i]->language);
2487         p.writeInt32(p_cur[i]->selected);
2488
2489         appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
2490               selected =%d], ",
2491               printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
2492               p_cur[i]->selected);
2493     }
2494     closeResponse;
2495
2496     return 0;
2497 }
2498
2499 static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
2500     int num;
2501     int digitCount;
2502     int digitLimit;
2503     uint8_t uct;
2504     void* dest;
2505
2506     RLOGD("Inside responseCdmaSms");
2507
2508     if (response == NULL && responselen != 0) {
2509         RLOGE("invalid response: NULL");
2510         return RIL_ERRNO_INVALID_RESPONSE;
2511     }
2512
2513     if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
2514         RLOGE("invalid response length was %d expected %d",
2515                 (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
2516         return RIL_ERRNO_INVALID_RESPONSE;
2517     }
2518
2519     RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
2520     p.writeInt32(p_cur->uTeleserviceID);
2521     p.write(&(p_cur->bIsServicePresent),sizeof(uct));
2522     p.writeInt32(p_cur->uServicecategory);
2523     p.writeInt32(p_cur->sAddress.digit_mode);
2524     p.writeInt32(p_cur->sAddress.number_mode);
2525     p.writeInt32(p_cur->sAddress.number_type);
2526     p.writeInt32(p_cur->sAddress.number_plan);
2527     p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
2528     digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
2529     for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2530         p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
2531     }
2532
2533     p.writeInt32(p_cur->sSubAddress.subaddressType);
2534     p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
2535     p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
2536     digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
2537     for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2538         p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
2539     }
2540
2541     digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
2542     p.writeInt32(p_cur->uBearerDataLen);
2543     for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2544        p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
2545     }
2546
2547     startResponse;
2548     appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
2549             sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
2550             printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
2551             p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
2552     closeResponse;
2553
2554     return 0;
2555 }
2556
2557 /**
2558  * A write on the wakeup fd is done just to pop us out of select()
2559  * We empty the buffer here and then ril_event will reset the timers on the
2560  * way back down
2561  */
2562 static void processWakeupCallback(int fd, short flags, void *param) {
2563     char buff[16];
2564     int ret;
2565
2566     RLOGV("processWakeupCallback");
2567
2568     /* empty our wakeup socket out */
2569     do {
2570         ret = read(s_fdWakeupRead, &buff, sizeof(buff));
2571     } while (ret > 0 || (ret < 0 && errno == EINTR));
2572 }
2573
2574 static void onCommandsSocketClosed() {
2575     int ret;
2576     RequestInfo *p_cur;
2577
2578     /* mark pending requests as "cancelled" so we dont report responses */
2579
2580     ret = pthread_mutex_lock(&s_pendingRequestsMutex);
2581     assert (ret == 0);
2582
2583     p_cur = s_pendingRequests;
2584
2585     for (p_cur = s_pendingRequests
2586             ; p_cur != NULL
2587             ; p_cur  = p_cur->p_next
2588     ) {
2589         p_cur->cancelled = 1;
2590     }
2591
2592     ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
2593     assert (ret == 0);
2594 }
2595
2596 static void processCommandsCallback(int fd, short flags, void *param) {
2597     RecordStream *p_rs;
2598     void *p_record;
2599     size_t recordlen;
2600     int ret;
2601
2602     assert(fd == s_fdCommand);
2603
2604     p_rs = (RecordStream *)param;
2605
2606     for (;;) {
2607         /* loop until EAGAIN/EINTR, end of stream, or other error */
2608         ret = record_stream_get_next(p_rs, &p_record, &recordlen);
2609
2610         if (ret == 0 && p_record == NULL) {
2611             /* end-of-stream */
2612             break;
2613         } else if (ret < 0) {
2614             break;
2615         } else if (ret == 0) { /* && p_record != NULL */
2616             processCommandBuffer(p_record, recordlen);
2617         }
2618     }
2619
2620     if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
2621         /* fatal error or end-of-stream */
2622         if (ret != 0) {
2623             RLOGE("error on reading command socket errno:%d\n", errno);
2624         } else {
2625             RLOGW("EOS.  Closing command socket.");
2626         }
2627
2628         close(s_fdCommand);
2629         s_fdCommand = -1;
2630
2631         ril_event_del(&s_commands_event);
2632
2633         record_stream_free(p_rs);
2634
2635         /* start listening for new connections again */
2636         rilEventAddWakeup(&s_listen_event);
2637
2638         onCommandsSocketClosed();
2639     }
2640 }
2641
2642
2643 static void onNewCommandConnect() {
2644     // Inform we are connected and the ril version
2645     int rilVer = s_callbacks.version;
2646     RIL_onUnsolicitedResponse(RIL_UNSOL_RIL_CONNECTED,
2647                                     &rilVer, sizeof(rilVer));
2648
2649     // implicit radio state changed
2650     RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
2651                                     NULL, 0);
2652
2653     // Send last NITZ time data, in case it was missed
2654     if (s_lastNITZTimeData != NULL) {
2655         sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize);
2656
2657         free(s_lastNITZTimeData);
2658         s_lastNITZTimeData = NULL;
2659     }
2660
2661     // Get version string
2662     if (s_callbacks.getVersion != NULL) {
2663         const char *version;
2664         version = s_callbacks.getVersion();
2665         RLOGI("RIL Daemon version: %s\n", version);
2666
2667         property_set(PROPERTY_RIL_IMPL, version);
2668     } else {
2669         RLOGI("RIL Daemon version: unavailable\n");
2670         property_set(PROPERTY_RIL_IMPL, "unavailable");
2671     }
2672
2673 }
2674
2675 static void listenCallback (int fd, short flags, void *param) {
2676     int ret;
2677     int err;
2678     int is_phone_socket;
2679     RecordStream *p_rs;
2680
2681     struct sockaddr_un peeraddr;
2682     socklen_t socklen = sizeof (peeraddr);
2683
2684     struct ucred creds;
2685     socklen_t szCreds = sizeof(creds);
2686
2687     struct passwd *pwd = NULL;
2688
2689     assert (s_fdCommand < 0);
2690     assert (fd == s_fdListen);
2691
2692     s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
2693
2694     if (s_fdCommand < 0 ) {
2695         RLOGE("Error on accept() errno:%d", errno);
2696         /* start listening for new connections again */
2697         rilEventAddWakeup(&s_listen_event);
2698               return;
2699     }
2700
2701     /* check the credential of the other side and only accept socket from
2702      * phone process
2703      */
2704     errno = 0;
2705     is_phone_socket = 0;
2706
2707     err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
2708
2709     if (err == 0 && szCreds > 0) {
2710         errno = 0;
2711         pwd = getpwuid(creds.uid);
2712         if (pwd != NULL) {
2713             if (strcmp(pwd->pw_name, PHONE_PROCESS) == 0) {
2714                 is_phone_socket = 1;
2715             } else {
2716                 RLOGE("RILD can't accept socket from process %s", pwd->pw_name);
2717             }
2718         } else {
2719             RLOGE("Error on getpwuid() errno: %d", errno);
2720         }
2721     } else {
2722         RLOGD("Error on getsockopt() errno: %d", errno);
2723     }
2724
2725     if ( !is_phone_socket ) {
2726       RLOGE("RILD must accept socket from %s", PHONE_PROCESS);
2727
2728       close(s_fdCommand);
2729       s_fdCommand = -1;
2730
2731       onCommandsSocketClosed();
2732
2733       /* start listening for new connections again */
2734       rilEventAddWakeup(&s_listen_event);
2735
2736       return;
2737     }
2738
2739     ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);
2740
2741     if (ret < 0) {
2742         RLOGE ("Error setting O_NONBLOCK errno:%d", errno);
2743     }
2744
2745     RLOGI("libril: new connection");
2746
2747     p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES);
2748
2749     ril_event_set (&s_commands_event, s_fdCommand, 1,
2750         processCommandsCallback, p_rs);
2751
2752     rilEventAddWakeup (&s_commands_event);
2753
2754     onNewCommandConnect();
2755 }
2756
2757 static void freeDebugCallbackArgs(int number, char **args) {
2758     for (int i = 0; i < number; i++) {
2759         if (args[i] != NULL) {
2760             free(args[i]);
2761         }
2762     }
2763     free(args);
2764 }
2765
2766 static void debugCallback (int fd, short flags, void *param) {
2767     int acceptFD, option;
2768     struct sockaddr_un peeraddr;
2769     socklen_t socklen = sizeof (peeraddr);
2770     int data;
2771     unsigned int qxdm_data[6];
2772     const char *deactData[1] = {"1"};
2773     char *actData[1];
2774     RIL_Dial dialData;
2775     int hangupData[1] = {1};
2776     int number;
2777     char **args;
2778
2779     acceptFD = accept (fd,  (sockaddr *) &peeraddr, &socklen);
2780
2781     if (acceptFD < 0) {
2782         RLOGE ("error accepting on debug port: %d\n", errno);
2783         return;
2784     }
2785
2786     if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
2787         RLOGE ("error reading on socket: number of Args: \n");
2788         return;
2789     }
2790     args = (char **) malloc(sizeof(char*) * number);
2791
2792     for (int i = 0; i < number; i++) {
2793         int len;
2794         if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
2795             RLOGE ("error reading on socket: Len of Args: \n");
2796             freeDebugCallbackArgs(i, args);
2797             return;
2798         }
2799         // +1 for null-term
2800         args[i] = (char *) malloc((sizeof(char) * len) + 1);
2801         if (recv(acceptFD, args[i], sizeof(char) * len, 0)
2802             != (int)sizeof(char) * len) {
2803             RLOGE ("error reading on socket: Args[%d] \n", i);
2804             freeDebugCallbackArgs(i, args);
2805             return;
2806         }
2807         char * buf = args[i];
2808         buf[len] = 0;
2809     }
2810
2811     switch (atoi(args[0])) {
2812         case 0:
2813             RLOGI ("Connection on debug port: issuing reset.");
2814             issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0);
2815             break;
2816         case 1:
2817             RLOGI ("Connection on debug port: issuing radio power off.");
2818             data = 0;
2819             issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
2820             // Close the socket
2821             close(s_fdCommand);
2822             s_fdCommand = -1;
2823             break;
2824         case 2:
2825             RLOGI ("Debug port: issuing unsolicited voice network change.");
2826             RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
2827                                       NULL, 0);
2828             break;
2829         case 3:
2830             RLOGI ("Debug port: QXDM log enable.");
2831             qxdm_data[0] = 65536;     // head.func_tag
2832             qxdm_data[1] = 16;        // head.len
2833             qxdm_data[2] = 1;         // mode: 1 for 'start logging'
2834             qxdm_data[3] = 32;        // log_file_size: 32megabytes
2835             qxdm_data[4] = 0;         // log_mask
2836             qxdm_data[5] = 8;         // log_max_fileindex
2837             issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
2838                               6 * sizeof(int));
2839             break;
2840         case 4:
2841             RLOGI ("Debug port: QXDM log disable.");
2842             qxdm_data[0] = 65536;
2843             qxdm_data[1] = 16;
2844             qxdm_data[2] = 0;          // mode: 0 for 'stop logging'
2845             qxdm_data[3] = 32;
2846             qxdm_data[4] = 0;
2847             qxdm_data[5] = 8;
2848             issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
2849                               6 * sizeof(int));
2850             break;
2851         case 5:
2852             RLOGI("Debug port: Radio On");
2853             data = 1;
2854             issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
2855             sleep(2);
2856             // Set network selection automatic.
2857             issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0);
2858             break;
2859         case 6:
2860             RLOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]);
2861             actData[0] = args[1];
2862             issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData,
2863                               sizeof(actData));
2864             break;
2865         case 7:
2866             RLOGI("Debug port: Deactivate Data Call");
2867             issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
2868                               sizeof(deactData));
2869             break;
2870         case 8:
2871             RLOGI("Debug port: Dial Call");
2872             dialData.clir = 0;
2873             dialData.address = args[1];
2874             issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData));
2875             break;
2876         case 9:
2877             RLOGI("Debug port: Answer Call");
2878             issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0);
2879             break;
2880         case 10:
2881             RLOGI("Debug port: End Call");
2882             issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
2883                               sizeof(hangupData));
2884             break;
2885         default:
2886             RLOGE ("Invalid request");
2887             break;
2888     }
2889     freeDebugCallbackArgs(number, args);
2890     close(acceptFD);
2891 }
2892
2893
2894 static void userTimerCallback (int fd, short flags, void *param) {
2895     UserCallbackInfo *p_info;
2896
2897     p_info = (UserCallbackInfo *)param;
2898
2899     p_info->p_callback(p_info->userParam);
2900
2901
2902     // FIXME generalize this...there should be a cancel mechanism
2903     if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
2904         s_last_wake_timeout_info = NULL;
2905     }
2906
2907     free(p_info);
2908 }
2909
2910
2911 static void *
2912 eventLoop(void *param) {
2913     int ret;
2914     int filedes[2];
2915
2916     ril_event_init();
2917
2918     pthread_mutex_lock(&s_startupMutex);
2919
2920     s_started = 1;
2921     pthread_cond_broadcast(&s_startupCond);
2922
2923     pthread_mutex_unlock(&s_startupMutex);
2924
2925     ret = pipe(filedes);
2926
2927     if (ret < 0) {
2928         RLOGE("Error in pipe() errno:%d", errno);
2929         return NULL;
2930     }
2931
2932     s_fdWakeupRead = filedes[0];
2933     s_fdWakeupWrite = filedes[1];
2934
2935     fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
2936
2937     ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
2938                 processWakeupCallback, NULL);
2939
2940     rilEventAddWakeup (&s_wakeupfd_event);
2941
2942     // Only returns on error
2943     ril_event_loop();
2944     RLOGE ("error in event_loop_base errno:%d", errno);
2945     // kill self to restart on error
2946     kill(0, SIGKILL);
2947
2948     return NULL;
2949 }
2950
2951 extern "C" void
2952 RIL_startEventLoop(void) {
2953     int ret;
2954     pthread_attr_t attr;
2955
2956     /* spin up eventLoop thread and wait for it to get started */
2957     s_started = 0;
2958     pthread_mutex_lock(&s_startupMutex);
2959
2960     pthread_attr_init (&attr);
2961     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2962     ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
2963
2964     while (s_started == 0) {
2965         pthread_cond_wait(&s_startupCond, &s_startupMutex);
2966     }
2967
2968     pthread_mutex_unlock(&s_startupMutex);
2969
2970     if (ret < 0) {
2971         RLOGE("Failed to create dispatch thread errno:%d", errno);
2972         return;
2973     }
2974 }
2975
2976 // Used for testing purpose only.
2977 extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
2978     memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
2979 }
2980
2981 extern "C" void
2982 RIL_register (const RIL_RadioFunctions *callbacks) {
2983     int ret;
2984     int flags;
2985
2986     if (callbacks == NULL) {
2987         RLOGE("RIL_register: RIL_RadioFunctions * null");
2988         return;
2989     }
2990     if (callbacks->version < RIL_VERSION_MIN) {
2991         RLOGE("RIL_register: version %d is to old, min version is %d",
2992              callbacks->version, RIL_VERSION_MIN);
2993         return;
2994     }
2995     if (callbacks->version > RIL_VERSION) {
2996         RLOGE("RIL_register: version %d is too new, max version is %d",
2997              callbacks->version, RIL_VERSION);
2998         return;
2999     }
3000     RLOGE("RIL_register: RIL version %d", callbacks->version);
3001
3002     if (s_registerCalled > 0) {
3003         RLOGE("RIL_register has been called more than once. "
3004                 "Subsequent call ignored");
3005         return;
3006     }
3007
3008     memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
3009
3010     s_registerCalled = 1;
3011
3012     // Little self-check
3013
3014     for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
3015         assert(i == s_commands[i].requestNumber);
3016     }
3017
3018     for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
3019         assert(i + RIL_UNSOL_RESPONSE_BASE
3020                 == s_unsolResponses[i].requestNumber);
3021     }
3022
3023     // New rild impl calls RIL_startEventLoop() first
3024     // old standalone impl wants it here.
3025
3026     if (s_started == 0) {
3027         RIL_startEventLoop();
3028     }
3029
3030     // start listen socket
3031
3032 #if 0
3033     ret = socket_local_server (SOCKET_NAME_RIL,
3034             ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
3035
3036     if (ret < 0) {
3037         RLOGE("Unable to bind socket errno:%d", errno);
3038         exit (-1);
3039     }
3040     s_fdListen = ret;
3041
3042 #else
3043     s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
3044     if (s_fdListen < 0) {
3045         RLOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
3046         exit(-1);
3047     }
3048
3049     ret = listen(s_fdListen, 4);
3050
3051     if (ret < 0) {
3052         RLOGE("Failed to listen on control socket '%d': %s",
3053              s_fdListen, strerror(errno));
3054         exit(-1);
3055     }
3056 #endif
3057
3058
3059     /* note: non-persistent so we can accept only one connection at a time */
3060     ril_event_set (&s_listen_event, s_fdListen, false,
3061                 listenCallback, NULL);
3062
3063     rilEventAddWakeup (&s_listen_event);
3064
3065 #if 1
3066     // start debug interface socket
3067
3068     s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG);
3069     if (s_fdDebug < 0) {
3070         RLOGE("Failed to get socket '" SOCKET_NAME_RIL_DEBUG "' errno:%d", errno);
3071         exit(-1);
3072     }
3073
3074     ret = listen(s_fdDebug, 4);
3075
3076     if (ret < 0) {
3077         RLOGE("Failed to listen on ril debug socket '%d': %s",
3078              s_fdDebug, strerror(errno));
3079         exit(-1);
3080     }
3081
3082     ril_event_set (&s_debug_event, s_fdDebug, true,
3083                 debugCallback, NULL);
3084
3085     rilEventAddWakeup (&s_debug_event);
3086 #endif
3087
3088 }
3089
3090 static int
3091 checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
3092     int ret = 0;
3093
3094     if (pRI == NULL) {
3095         return 0;
3096     }
3097
3098     pthread_mutex_lock(&s_pendingRequestsMutex);
3099
3100     for(RequestInfo **ppCur = &s_pendingRequests
3101         ; *ppCur != NULL
3102         ; ppCur = &((*ppCur)->p_next)
3103     ) {
3104         if (pRI == *ppCur) {
3105             ret = 1;
3106
3107             *ppCur = (*ppCur)->p_next;
3108             break;
3109         }
3110     }
3111
3112     pthread_mutex_unlock(&s_pendingRequestsMutex);
3113
3114     return ret;
3115 }
3116
3117
3118 extern "C" void
3119 RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
3120     RequestInfo *pRI;
3121     int ret;
3122     size_t errorOffset;
3123
3124     pRI = (RequestInfo *)t;
3125
3126     if (!checkAndDequeueRequestInfo(pRI)) {
3127         RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
3128         return;
3129     }
3130
3131     if (pRI->local > 0) {
3132         // Locally issued command...void only!
3133         // response does not go back up the command socket
3134         RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
3135
3136         goto done;
3137     }
3138
3139     appendPrintBuf("[%04d]< %s",
3140         pRI->token, requestToString(pRI->pCI->requestNumber));
3141
3142     if (pRI->cancelled == 0) {
3143         Parcel p;
3144
3145         p.writeInt32 (RESPONSE_SOLICITED);
3146         p.writeInt32 (pRI->token);
3147         errorOffset = p.dataPosition();
3148
3149         p.writeInt32 (e);
3150
3151         if (response != NULL) {
3152             // there is a response payload, no matter success or not.
3153             ret = pRI->pCI->responseFunction(p, response, responselen);
3154
3155             /* if an error occurred, rewind and mark it */
3156             if (ret != 0) {
3157                 p.setDataPosition(errorOffset);
3158                 p.writeInt32 (ret);
3159             }
3160         }
3161
3162         if (e != RIL_E_SUCCESS) {
3163             appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
3164         }
3165
3166         if (s_fdCommand < 0) {
3167             RLOGD ("RIL onRequestComplete: Command channel closed");
3168         }
3169         sendResponse(p);
3170     }
3171
3172 done:
3173     free(pRI);
3174 }
3175
3176
3177 static void
3178 grabPartialWakeLock() {
3179     acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
3180 }
3181
3182 static void
3183 releaseWakeLock() {
3184     release_wake_lock(ANDROID_WAKE_LOCK_NAME);
3185 }
3186
3187 /**
3188  * Timer callback to put us back to sleep before the default timeout
3189  */
3190 static void
3191 wakeTimeoutCallback (void *param) {
3192     // We're using "param != NULL" as a cancellation mechanism
3193     if (param == NULL) {
3194         //RLOGD("wakeTimeout: releasing wake lock");
3195
3196         releaseWakeLock();
3197     } else {
3198         //RLOGD("wakeTimeout: releasing wake lock CANCELLED");
3199     }
3200 }
3201
3202 static int
3203 decodeVoiceRadioTechnology (RIL_RadioState radioState) {
3204     switch (radioState) {
3205         case RADIO_STATE_SIM_NOT_READY:
3206         case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
3207         case RADIO_STATE_SIM_READY:
3208             return RADIO_TECH_UMTS;
3209
3210         case RADIO_STATE_RUIM_NOT_READY:
3211         case RADIO_STATE_RUIM_READY:
3212         case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
3213         case RADIO_STATE_NV_NOT_READY:
3214         case RADIO_STATE_NV_READY:
3215             return RADIO_TECH_1xRTT;
3216
3217         default:
3218             RLOGD("decodeVoiceRadioTechnology: Invoked with incorrect RadioState");
3219             return -1;
3220     }
3221 }
3222
3223 static int
3224 decodeCdmaSubscriptionSource (RIL_RadioState radioState) {
3225     switch (radioState) {
3226         case RADIO_STATE_SIM_NOT_READY:
3227         case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
3228         case RADIO_STATE_SIM_READY:
3229         case RADIO_STATE_RUIM_NOT_READY:
3230         case RADIO_STATE_RUIM_READY:
3231         case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
3232             return CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
3233
3234         case RADIO_STATE_NV_NOT_READY:
3235         case RADIO_STATE_NV_READY:
3236             return CDMA_SUBSCRIPTION_SOURCE_NV;
3237
3238         default:
3239             RLOGD("decodeCdmaSubscriptionSource: Invoked with incorrect RadioState");
3240             return -1;
3241     }
3242 }
3243
3244 static int
3245 decodeSimStatus (RIL_RadioState radioState) {
3246    switch (radioState) {
3247        case RADIO_STATE_SIM_NOT_READY:
3248        case RADIO_STATE_RUIM_NOT_READY:
3249        case RADIO_STATE_NV_NOT_READY:
3250        case RADIO_STATE_NV_READY:
3251            return -1;
3252        case RADIO_STATE_SIM_LOCKED_OR_ABSENT:
3253        case RADIO_STATE_SIM_READY:
3254        case RADIO_STATE_RUIM_READY:
3255        case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:
3256            return radioState;
3257        default:
3258            RLOGD("decodeSimStatus: Invoked with incorrect RadioState");
3259            return -1;
3260    }
3261 }
3262
3263 static bool is3gpp2(int radioTech) {
3264     switch (radioTech) {
3265         case RADIO_TECH_IS95A:
3266         case RADIO_TECH_IS95B:
3267         case RADIO_TECH_1xRTT:
3268         case RADIO_TECH_EVDO_0:
3269         case RADIO_TECH_EVDO_A:
3270         case RADIO_TECH_EVDO_B:
3271         case RADIO_TECH_EHRPD:
3272             return true;
3273         default:
3274             return false;
3275     }
3276 }
3277
3278 /* If RIL sends SIM states or RUIM states, store the voice radio
3279  * technology and subscription source information so that they can be
3280  * returned when telephony framework requests them
3281  */
3282 static RIL_RadioState
3283 processRadioState(RIL_RadioState newRadioState) {
3284
3285     if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) {
3286         int newVoiceRadioTech;
3287         int newCdmaSubscriptionSource;
3288         int newSimStatus;
3289
3290         /* This is old RIL. Decode Subscription source and Voice Radio Technology
3291            from Radio State and send change notifications if there has been a change */
3292         newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState);
3293         if(newVoiceRadioTech != voiceRadioTech) {
3294             voiceRadioTech = newVoiceRadioTech;
3295             RIL_onUnsolicitedResponse (RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
3296                         &voiceRadioTech, sizeof(voiceRadioTech));
3297         }
3298         if(is3gpp2(newVoiceRadioTech)) {
3299             newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState);
3300             if(newCdmaSubscriptionSource != cdmaSubscriptionSource) {
3301                 cdmaSubscriptionSource = newCdmaSubscriptionSource;
3302                 RIL_onUnsolicitedResponse (RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
3303                         &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource));
3304             }
3305         }
3306         newSimStatus = decodeSimStatus(newRadioState);
3307         if(newSimStatus != simRuimStatus) {
3308             simRuimStatus = newSimStatus;
3309             RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
3310         }
3311
3312         /* Send RADIO_ON to telephony */
3313         newRadioState = RADIO_STATE_ON;
3314     }
3315
3316     return newRadioState;
3317 }
3318
3319 extern "C"
3320 void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
3321                                 size_t datalen)
3322 {
3323     int unsolResponseIndex;
3324     int ret;
3325     int64_t timeReceived = 0;
3326     bool shouldScheduleTimeout = false;
3327     RIL_RadioState newState;
3328
3329     if (s_registerCalled == 0) {
3330         // Ignore RIL_onUnsolicitedResponse before RIL_register
3331         RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
3332         return;
3333     }
3334
3335     unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
3336
3337     if ((unsolResponseIndex < 0)
3338         || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) {
3339         RLOGE("unsupported unsolicited response code %d", unsolResponse);
3340         return;
3341     }
3342
3343     // Grab a wake lock if needed for this reponse,
3344     // as we exit we'll either release it immediately
3345     // or set a timer to release it later.
3346     switch (s_unsolResponses[unsolResponseIndex].wakeType) {
3347         case WAKE_PARTIAL:
3348             grabPartialWakeLock();
3349             shouldScheduleTimeout = true;
3350         break;
3351
3352         case DONT_WAKE:
3353         default:
3354             // No wake lock is grabed so don't set timeout
3355             shouldScheduleTimeout = false;
3356             break;
3357     }
3358
3359     // Mark the time this was received, doing this
3360     // after grabing the wakelock incase getting
3361     // the elapsedRealTime might cause us to goto
3362     // sleep.
3363     if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
3364         timeReceived = elapsedRealtime();
3365     }
3366
3367     appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
3368
3369     Parcel p;
3370
3371     p.writeInt32 (RESPONSE_UNSOLICITED);
3372     p.writeInt32 (unsolResponse);
3373
3374     ret = s_unsolResponses[unsolResponseIndex]
3375                 .responseFunction(p, data, datalen);
3376     if (ret != 0) {
3377         // Problem with the response. Don't continue;
3378         goto error_exit;
3379     }
3380
3381     // some things get more payload
3382     switch(unsolResponse) {
3383         case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
3384             newState = processRadioState(s_callbacks.onStateRequest());
3385             p.writeInt32(newState);
3386             appendPrintBuf("%s {%s}", printBuf,
3387                 radioStateToString(s_callbacks.onStateRequest()));
3388         break;
3389
3390
3391         case RIL_UNSOL_NITZ_TIME_RECEIVED:
3392             // Store the time that this was received so the
3393             // handler of this message can account for
3394             // the time it takes to arrive and process. In
3395             // particular the system has been known to sleep
3396             // before this message can be processed.
3397             p.writeInt64(timeReceived);
3398         break;
3399     }
3400
3401     ret = sendResponse(p);
3402     if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
3403
3404         // Unfortunately, NITZ time is not poll/update like everything
3405         // else in the system. So, if the upstream client isn't connected,
3406         // keep a copy of the last NITZ response (with receive time noted
3407         // above) around so we can deliver it when it is connected
3408
3409         if (s_lastNITZTimeData != NULL) {
3410             free (s_lastNITZTimeData);
3411             s_lastNITZTimeData = NULL;
3412         }
3413
3414         s_lastNITZTimeData = malloc(p.dataSize());
3415         s_lastNITZTimeDataSize = p.dataSize();
3416         memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
3417     }
3418
3419     // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
3420     // FIXME The java code should handshake here to release wake lock
3421
3422     if (shouldScheduleTimeout) {
3423         // Cancel the previous request
3424         if (s_last_wake_timeout_info != NULL) {
3425             s_last_wake_timeout_info->userParam = (void *)1;
3426         }
3427
3428         s_last_wake_timeout_info
3429             = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
3430                                             &TIMEVAL_WAKE_TIMEOUT);
3431     }
3432
3433     // Normal exit
3434     return;
3435
3436 error_exit:
3437     if (shouldScheduleTimeout) {
3438         releaseWakeLock();
3439     }
3440 }
3441
3442 /** FIXME generalize this if you track UserCAllbackInfo, clear it
3443     when the callback occurs
3444 */
3445 static UserCallbackInfo *
3446 internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
3447                                 const struct timeval *relativeTime)
3448 {
3449     struct timeval myRelativeTime;
3450     UserCallbackInfo *p_info;
3451
3452     p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
3453
3454     p_info->p_callback = callback;
3455     p_info->userParam = param;
3456
3457     if (relativeTime == NULL) {
3458         /* treat null parameter as a 0 relative time */
3459         memset (&myRelativeTime, 0, sizeof(myRelativeTime));
3460     } else {
3461         /* FIXME I think event_add's tv param is really const anyway */
3462         memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
3463     }
3464
3465     ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
3466
3467     ril_timer_add(&(p_info->event), &myRelativeTime);
3468
3469     triggerEvLoop();
3470     return p_info;
3471 }
3472
3473
3474 extern "C" void
3475 RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
3476                                 const struct timeval *relativeTime) {
3477     internalRequestTimedCallback (callback, param, relativeTime);
3478 }
3479
3480 const char *
3481 failCauseToString(RIL_Errno e) {
3482     switch(e) {
3483         case RIL_E_SUCCESS: return "E_SUCCESS";
3484         case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
3485         case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
3486         case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
3487         case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
3488         case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
3489         case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
3490         case RIL_E_CANCELLED: return "E_CANCELLED";
3491         case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
3492         case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
3493         case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
3494         case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
3495         case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
3496 #ifdef FEATURE_MULTIMODE_ANDROID
3497         case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
3498         case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
3499 #endif
3500         default: return "<unknown error>";
3501     }
3502 }
3503
3504 const char *
3505 radioStateToString(RIL_RadioState s) {
3506     switch(s) {
3507         case RADIO_STATE_OFF: return "RADIO_OFF";
3508         case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
3509         case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
3510         case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
3511         case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
3512         case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
3513         case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
3514         case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
3515         case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
3516         case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
3517         case RADIO_STATE_ON:return"RADIO_ON";
3518         default: return "<unknown state>";
3519     }
3520 }
3521
3522 const char *
3523 callStateToString(RIL_CallState s) {
3524     switch(s) {
3525         case RIL_CALL_ACTIVE : return "ACTIVE";
3526         case RIL_CALL_HOLDING: return "HOLDING";
3527         case RIL_CALL_DIALING: return "DIALING";
3528         case RIL_CALL_ALERTING: return "ALERTING";
3529         case RIL_CALL_INCOMING: return "INCOMING";
3530         case RIL_CALL_WAITING: return "WAITING";
3531         default: return "<unknown state>";
3532     }
3533 }
3534
3535 const char *
3536 requestToString(int request) {
3537 /*
3538  cat libs/telephony/ril_commands.h \
3539  | egrep "^ *{RIL_" \
3540  | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3541
3542
3543  cat libs/telephony/ril_unsol_commands.h \
3544  | egrep "^ *{RIL_" \
3545  | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
3546
3547 */
3548     switch(request) {
3549         case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
3550         case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
3551         case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
3552         case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
3553         case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
3554         case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
3555         case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
3556         case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
3557         case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
3558         case RIL_REQUEST_DIAL: return "DIAL";
3559         case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
3560         case RIL_REQUEST_HANGUP: return "HANGUP";
3561         case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
3562         case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
3563         case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
3564         case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
3565         case RIL_REQUEST_UDUB: return "UDUB";
3566         case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
3567         case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
3568         case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
3569         case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
3570         case RIL_REQUEST_OPERATOR: return "OPERATOR";
3571         case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
3572         case RIL_REQUEST_DTMF: return "DTMF";
3573         case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
3574         case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
3575         case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
3576         case RIL_REQUEST_SIM_IO: return "SIM_IO";
3577         case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
3578         case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
3579         case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
3580         case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
3581         case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
3582         case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
3583         case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
3584         case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
3585         case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
3586         case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
3587         case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
3588         case RIL_REQUEST_ANSWER: return "ANSWER";
3589         case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
3590         case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
3591         case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
3592         case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
3593         case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
3594         case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
3595         case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
3596         case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
3597         case RIL_REQUEST_DTMF_START: return "DTMF_START";
3598         case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
3599         case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
3600         case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
3601         case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
3602         case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
3603         case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
3604         case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
3605         case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
3606         case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
3607         case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
3608         case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
3609         case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
3610         case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
3611         case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
3612         case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
3613         case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
3614         case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
3615         case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
3616         case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
3617         case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
3618         case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
3619         case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
3620         case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
3621         case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
3622         case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
3623         case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
3624         case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
3625         case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
3626         case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
3627         case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
3628         case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
3629         case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
3630         case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
3631         case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
3632         case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
3633         case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
3634         case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
3635         case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
3636         case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
3637         case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
3638         case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
3639         case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
3640         case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
3641         case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
3642         case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
3643         case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
3644         case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
3645         case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
3646         case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
3647         case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
3648         case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
3649         case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
3650         case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
3651         case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
3652         case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
3653         case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST";
3654         case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE";
3655         case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
3656         case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
3657         case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
3658         case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
3659         case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
3660         case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
3661         case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
3662         case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
3663         case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
3664         case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
3665         case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
3666         case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
3667         case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
3668         case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
3669         case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
3670         case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
3671         case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
3672         case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
3673         case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
3674         case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
3675         case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
3676         case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
3677         case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
3678         case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
3679         case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
3680         case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
3681         case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
3682         case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
3683         case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
3684         case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
3685         case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
3686         case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
3687         case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
3688         case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
3689         case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
3690         case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
3691         case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
3692         default: return "<unknown request>";
3693     }
3694 }
3695
3696 } /* namespace android */