OSDN Git Service

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