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