OSDN Git Service

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