OSDN Git Service

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