OSDN Git Service

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