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