OSDN Git Service

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