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