ril.cpp revision beb25b58dcb48a2cfa2cfe10f5fb15908ff465f8
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].suggestedRetryTime);
1551            p.writeInt32(p_cur[i].cid);
1552            p.writeInt32(p_cur[i].active);
1553            writeStringToParcel(p, p_cur[i].type);
1554            writeStringToParcel(p, p_cur[i].ifname);
1555            writeStringToParcel(p, p_cur[i].addresses);
1556            writeStringToParcel(p, p_cur[i].dnses);
1557            writeStringToParcel(p, p_cur[i].gateways);
1558            appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%d,%s,%s,%s],", printBuf,
1559                p_cur[i].status,
1560                p_cur[i].suggestedRetryTime,
1561                p_cur[i].cid,
1562                (p_cur[i].active==0)?"down":"up",
1563                (char*)p_cur[i].ifname,
1564                (char*)p_cur[i].addresses,
1565                (char*)p_cur[i].dnses,
1566                (char*)p_cur[i].gateways);
1567        }
1568        removeLastChar;
1569        closeResponse;
1570    }
1571
1572    return 0;
1573}
1574
1575static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
1576{
1577    if (s_callbacks.version < 5) {
1578        return responseStringsWithVersion(s_callbacks.version, p, response, responselen);
1579    } else {
1580        return responseDataCallList(p, response, responselen);
1581    }
1582}
1583
1584static int responseRaw(Parcel &p, void *response, size_t responselen) {
1585    if (response == NULL && responselen != 0) {
1586        LOGE("invalid response: NULL with responselen != 0");
1587        return RIL_ERRNO_INVALID_RESPONSE;
1588    }
1589
1590    // The java code reads -1 size as null byte array
1591    if (response == NULL) {
1592        p.writeInt32(-1);
1593    } else {
1594        p.writeInt32(responselen);
1595        p.write(response, responselen);
1596    }
1597
1598    return 0;
1599}
1600
1601
1602static int responseSIM_IO(Parcel &p, void *response, size_t responselen) {
1603    if (response == NULL) {
1604        LOGE("invalid response: NULL");
1605        return RIL_ERRNO_INVALID_RESPONSE;
1606    }
1607
1608    if (responselen != sizeof (RIL_SIM_IO_Response) ) {
1609        LOGE("invalid response length was %d expected %d",
1610                (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
1611        return RIL_ERRNO_INVALID_RESPONSE;
1612    }
1613
1614    RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
1615    p.writeInt32(p_cur->sw1);
1616    p.writeInt32(p_cur->sw2);
1617    writeStringToParcel(p, p_cur->simResponse);
1618
1619    startResponse;
1620    appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
1621        (char*)p_cur->simResponse);
1622    closeResponse;
1623
1624
1625    return 0;
1626}
1627
1628static int responseCallForwards(Parcel &p, void *response, size_t responselen) {
1629    int num;
1630
1631    if (response == NULL && responselen != 0) {
1632        LOGE("invalid response: NULL");
1633        return RIL_ERRNO_INVALID_RESPONSE;
1634    }
1635
1636    if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
1637        LOGE("invalid response length %d expected multiple of %d",
1638                (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
1639        return RIL_ERRNO_INVALID_RESPONSE;
1640    }
1641
1642    /* number of call info's */
1643    num = responselen / sizeof(RIL_CallForwardInfo *);
1644    p.writeInt32(num);
1645
1646    startResponse;
1647    for (int i = 0 ; i < num ; i++) {
1648        RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
1649
1650        p.writeInt32(p_cur->status);
1651        p.writeInt32(p_cur->reason);
1652        p.writeInt32(p_cur->serviceClass);
1653        p.writeInt32(p_cur->toa);
1654        writeStringToParcel(p, p_cur->number);
1655        p.writeInt32(p_cur->timeSeconds);
1656        appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
1657            (p_cur->status==1)?"enable":"disable",
1658            p_cur->reason, p_cur->serviceClass, p_cur->toa,
1659            (char*)p_cur->number,
1660            p_cur->timeSeconds);
1661    }
1662    removeLastChar;
1663    closeResponse;
1664
1665    return 0;
1666}
1667
1668static int responseSsn(Parcel &p, void *response, size_t responselen) {
1669    if (response == NULL) {
1670        LOGE("invalid response: NULL");
1671        return RIL_ERRNO_INVALID_RESPONSE;
1672    }
1673
1674    if (responselen != sizeof(RIL_SuppSvcNotification)) {
1675        LOGE("invalid response length was %d expected %d",
1676                (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
1677        return RIL_ERRNO_INVALID_RESPONSE;
1678    }
1679
1680    RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
1681    p.writeInt32(p_cur->notificationType);
1682    p.writeInt32(p_cur->code);
1683    p.writeInt32(p_cur->index);
1684    p.writeInt32(p_cur->type);
1685    writeStringToParcel(p, p_cur->number);
1686
1687    startResponse;
1688    appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
1689        (p_cur->notificationType==0)?"mo":"mt",
1690         p_cur->code, p_cur->index, p_cur->type,
1691        (char*)p_cur->number);
1692    closeResponse;
1693
1694    return 0;
1695}
1696
1697static int responseCellList(Parcel &p, void *response, size_t responselen) {
1698    int num;
1699
1700    if (response == NULL && responselen != 0) {
1701        LOGE("invalid response: NULL");
1702        return RIL_ERRNO_INVALID_RESPONSE;
1703    }
1704
1705    if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
1706        LOGE("invalid response length %d expected multiple of %d\n",
1707            (int)responselen, (int)sizeof (RIL_NeighboringCell *));
1708        return RIL_ERRNO_INVALID_RESPONSE;
1709    }
1710
1711    startResponse;
1712    /* number of records */
1713    num = responselen / sizeof(RIL_NeighboringCell *);
1714    p.writeInt32(num);
1715
1716    for (int i = 0 ; i < num ; i++) {
1717        RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
1718
1719        p.writeInt32(p_cur->rssi);
1720        writeStringToParcel (p, p_cur->cid);
1721
1722        appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
1723            p_cur->cid, p_cur->rssi);
1724    }
1725    removeLastChar;
1726    closeResponse;
1727
1728    return 0;
1729}
1730
1731/**
1732 * Marshall the signalInfoRecord into the parcel if it exists.
1733 */
1734static void marshallSignalInfoRecord(Parcel &p,
1735            RIL_CDMA_SignalInfoRecord &p_signalInfoRecord) {
1736    p.writeInt32(p_signalInfoRecord.isPresent);
1737    p.writeInt32(p_signalInfoRecord.signalType);
1738    p.writeInt32(p_signalInfoRecord.alertPitch);
1739    p.writeInt32(p_signalInfoRecord.signal);
1740}
1741
1742static int responseCdmaInformationRecords(Parcel &p,
1743            void *response, size_t responselen) {
1744    int num;
1745    char* string8 = NULL;
1746    int buffer_lenght;
1747    RIL_CDMA_InformationRecord *infoRec;
1748
1749    if (response == NULL && responselen != 0) {
1750        LOGE("invalid response: NULL");
1751        return RIL_ERRNO_INVALID_RESPONSE;
1752    }
1753
1754    if (responselen != sizeof (RIL_CDMA_InformationRecords)) {
1755        LOGE("invalid response length %d expected multiple of %d\n",
1756            (int)responselen, (int)sizeof (RIL_CDMA_InformationRecords *));
1757        return RIL_ERRNO_INVALID_RESPONSE;
1758    }
1759
1760    RIL_CDMA_InformationRecords *p_cur =
1761                             (RIL_CDMA_InformationRecords *) response;
1762    num = MIN(p_cur->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
1763
1764    startResponse;
1765    p.writeInt32(num);
1766
1767    for (int i = 0 ; i < num ; i++) {
1768        infoRec = &p_cur->infoRec[i];
1769        p.writeInt32(infoRec->name);
1770        switch (infoRec->name) {
1771            case RIL_CDMA_DISPLAY_INFO_REC:
1772            case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
1773                if (infoRec->rec.display.alpha_len >
1774                                         CDMA_ALPHA_INFO_BUFFER_LENGTH) {
1775                    LOGE("invalid display info response length %d \
1776                          expected not more than %d\n",
1777                         (int)infoRec->rec.display.alpha_len,
1778                         CDMA_ALPHA_INFO_BUFFER_LENGTH);
1779                    return RIL_ERRNO_INVALID_RESPONSE;
1780                }
1781                string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1)
1782                                                             * sizeof(char) );
1783                for (int i = 0 ; i < infoRec->rec.display.alpha_len ; i++) {
1784                    string8[i] = infoRec->rec.display.alpha_buf[i];
1785                }
1786                string8[(int)infoRec->rec.display.alpha_len] = '\0';
1787                writeStringToParcel(p, (const char*)string8);
1788                free(string8);
1789                string8 = NULL;
1790                break;
1791            case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
1792            case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
1793            case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
1794                if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
1795                    LOGE("invalid display info response length %d \
1796                          expected not more than %d\n",
1797                         (int)infoRec->rec.number.len,
1798                         CDMA_NUMBER_INFO_BUFFER_LENGTH);
1799                    return RIL_ERRNO_INVALID_RESPONSE;
1800                }
1801                string8 = (char*) malloc((infoRec->rec.number.len + 1)
1802                                                             * sizeof(char) );
1803                for (int i = 0 ; i < infoRec->rec.number.len; i++) {
1804                    string8[i] = infoRec->rec.number.buf[i];
1805                }
1806                string8[(int)infoRec->rec.number.len] = '\0';
1807                writeStringToParcel(p, (const char*)string8);
1808                free(string8);
1809                string8 = NULL;
1810                p.writeInt32(infoRec->rec.number.number_type);
1811                p.writeInt32(infoRec->rec.number.number_plan);
1812                p.writeInt32(infoRec->rec.number.pi);
1813                p.writeInt32(infoRec->rec.number.si);
1814                break;
1815            case RIL_CDMA_SIGNAL_INFO_REC:
1816                p.writeInt32(infoRec->rec.signal.isPresent);
1817                p.writeInt32(infoRec->rec.signal.signalType);
1818                p.writeInt32(infoRec->rec.signal.alertPitch);
1819                p.writeInt32(infoRec->rec.signal.signal);
1820
1821                appendPrintBuf("%sisPresent=%X, signalType=%X, \
1822                                alertPitch=%X, signal=%X, ",
1823                   printBuf, (int)infoRec->rec.signal.isPresent,
1824                   (int)infoRec->rec.signal.signalType,
1825                   (int)infoRec->rec.signal.alertPitch,
1826                   (int)infoRec->rec.signal.signal);
1827                removeLastChar;
1828                break;
1829            case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
1830                if (infoRec->rec.redir.redirectingNumber.len >
1831                                              CDMA_NUMBER_INFO_BUFFER_LENGTH) {
1832                    LOGE("invalid display info response length %d \
1833                          expected not more than %d\n",
1834                         (int)infoRec->rec.redir.redirectingNumber.len,
1835                         CDMA_NUMBER_INFO_BUFFER_LENGTH);
1836                    return RIL_ERRNO_INVALID_RESPONSE;
1837                }
1838                string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber
1839                                          .len + 1) * sizeof(char) );
1840                for (int i = 0;
1841                         i < infoRec->rec.redir.redirectingNumber.len;
1842                         i++) {
1843                    string8[i] = infoRec->rec.redir.redirectingNumber.buf[i];
1844                }
1845                string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
1846                writeStringToParcel(p, (const char*)string8);
1847                free(string8);
1848                string8 = NULL;
1849                p.writeInt32(infoRec->rec.redir.redirectingNumber.number_type);
1850                p.writeInt32(infoRec->rec.redir.redirectingNumber.number_plan);
1851                p.writeInt32(infoRec->rec.redir.redirectingNumber.pi);
1852                p.writeInt32(infoRec->rec.redir.redirectingNumber.si);
1853                p.writeInt32(infoRec->rec.redir.redirectingReason);
1854                break;
1855            case RIL_CDMA_LINE_CONTROL_INFO_REC:
1856                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPolarityIncluded);
1857                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlToggle);
1858                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlReverse);
1859                p.writeInt32(infoRec->rec.lineCtrl.lineCtrlPowerDenial);
1860
1861                appendPrintBuf("%slineCtrlPolarityIncluded=%d, \
1862                                lineCtrlToggle=%d, lineCtrlReverse=%d, \
1863                                lineCtrlPowerDenial=%d, ", printBuf,
1864                       (int)infoRec->rec.lineCtrl.lineCtrlPolarityIncluded,
1865                       (int)infoRec->rec.lineCtrl.lineCtrlToggle,
1866                       (int)infoRec->rec.lineCtrl.lineCtrlReverse,
1867                       (int)infoRec->rec.lineCtrl.lineCtrlPowerDenial);
1868                removeLastChar;
1869                break;
1870            case RIL_CDMA_T53_CLIR_INFO_REC:
1871                p.writeInt32((int)(infoRec->rec.clir.cause));
1872
1873                appendPrintBuf("%scause%d", printBuf, infoRec->rec.clir.cause);
1874                removeLastChar;
1875                break;
1876            case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
1877                p.writeInt32(infoRec->rec.audioCtrl.upLink);
1878                p.writeInt32(infoRec->rec.audioCtrl.downLink);
1879
1880                appendPrintBuf("%supLink=%d, downLink=%d, ", printBuf,
1881                        infoRec->rec.audioCtrl.upLink,
1882                        infoRec->rec.audioCtrl.downLink);
1883                removeLastChar;
1884                break;
1885            case RIL_CDMA_T53_RELEASE_INFO_REC:
1886                // TODO(Moto): See David Krause, he has the answer:)
1887                LOGE("RIL_CDMA_T53_RELEASE_INFO_REC: return INVALID_RESPONSE");
1888                return RIL_ERRNO_INVALID_RESPONSE;
1889            default:
1890                LOGE("Incorrect name value");
1891                return RIL_ERRNO_INVALID_RESPONSE;
1892        }
1893    }
1894    closeResponse;
1895
1896    return 0;
1897}
1898
1899static int responseRilSignalStrength(Parcel &p,
1900                    void *response, size_t responselen) {
1901    if (response == NULL && responselen != 0) {
1902        LOGE("invalid response: NULL");
1903        return RIL_ERRNO_INVALID_RESPONSE;
1904    }
1905
1906    if (responselen >= sizeof (RIL_SignalStrength_v5)) {
1907        RIL_SignalStrength_v6 *p_cur = ((RIL_SignalStrength_v6 *) response);
1908
1909        p.writeInt32(p_cur->GW_SignalStrength.signalStrength);
1910        p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
1911        p.writeInt32(p_cur->CDMA_SignalStrength.dbm);
1912        p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
1913        p.writeInt32(p_cur->EVDO_SignalStrength.dbm);
1914        p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
1915        p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
1916        if (responselen >= sizeof (RIL_SignalStrength_v6)) {
1917            p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
1918            p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
1919            p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
1920            p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
1921            p.writeInt32(p_cur->LTE_SignalStrength.cqi);
1922        } else {
1923            memset(&p_cur->LTE_SignalStrength, sizeof (RIL_LTE_SignalStrength), 0);
1924        }
1925
1926        startResponse;
1927        appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
1928                CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
1929                EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
1930                EVDO_SS.signalNoiseRatio=%d,\
1931                LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
1932                LTE_SS.rssnr=%d,LTE_SS.cqi=%d]",
1933                printBuf,
1934                p_cur->GW_SignalStrength.signalStrength,
1935                p_cur->GW_SignalStrength.bitErrorRate,
1936                p_cur->CDMA_SignalStrength.dbm,
1937                p_cur->CDMA_SignalStrength.ecio,
1938                p_cur->EVDO_SignalStrength.dbm,
1939                p_cur->EVDO_SignalStrength.ecio,
1940                p_cur->EVDO_SignalStrength.signalNoiseRatio,
1941                p_cur->LTE_SignalStrength.signalStrength,
1942                p_cur->LTE_SignalStrength.rsrp,
1943                p_cur->LTE_SignalStrength.rsrq,
1944                p_cur->LTE_SignalStrength.rssnr,
1945                p_cur->LTE_SignalStrength.cqi);
1946        closeResponse;
1947
1948    } else {
1949        LOGE("invalid response length");
1950        return RIL_ERRNO_INVALID_RESPONSE;
1951    }
1952
1953    return 0;
1954}
1955
1956static int responseCallRing(Parcel &p, void *response, size_t responselen) {
1957    if ((response == NULL) || (responselen == 0)) {
1958        return responseVoid(p, response, responselen);
1959    } else {
1960        return responseCdmaSignalInfoRecord(p, response, responselen);
1961    }
1962}
1963
1964static int responseCdmaSignalInfoRecord(Parcel &p, void *response, size_t responselen) {
1965    if (response == NULL || responselen == 0) {
1966        LOGE("invalid response: NULL");
1967        return RIL_ERRNO_INVALID_RESPONSE;
1968    }
1969
1970    if (responselen != sizeof (RIL_CDMA_SignalInfoRecord)) {
1971        LOGE("invalid response length %d expected sizeof (RIL_CDMA_SignalInfoRecord) of %d\n",
1972            (int)responselen, (int)sizeof (RIL_CDMA_SignalInfoRecord));
1973        return RIL_ERRNO_INVALID_RESPONSE;
1974    }
1975
1976    startResponse;
1977
1978    RIL_CDMA_SignalInfoRecord *p_cur = ((RIL_CDMA_SignalInfoRecord *) response);
1979    marshallSignalInfoRecord(p, *p_cur);
1980
1981    appendPrintBuf("%s[isPresent=%d,signalType=%d,alertPitch=%d\
1982              signal=%d]",
1983              printBuf,
1984              p_cur->isPresent,
1985              p_cur->signalType,
1986              p_cur->alertPitch,
1987              p_cur->signal);
1988
1989    closeResponse;
1990    return 0;
1991}
1992
1993static int responseCdmaCallWaiting(Parcel &p, void *response,
1994            size_t responselen) {
1995    if (response == NULL && responselen != 0) {
1996        LOGE("invalid response: NULL");
1997        return RIL_ERRNO_INVALID_RESPONSE;
1998    }
1999
2000    if (responselen < sizeof(RIL_CDMA_CallWaiting_v6)) {
2001        LOGW("Upgrade to ril version %d\n", RIL_VERSION);
2002    }
2003
2004    RIL_CDMA_CallWaiting_v6 *p_cur = ((RIL_CDMA_CallWaiting_v6 *) response);
2005
2006    writeStringToParcel(p, p_cur->number);
2007    p.writeInt32(p_cur->numberPresentation);
2008    writeStringToParcel(p, p_cur->name);
2009    marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
2010
2011    if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
2012        p.writeInt32(p_cur->number_type);
2013        p.writeInt32(p_cur->number_plan);
2014    } else {
2015        p.writeInt32(0);
2016        p.writeInt32(0);
2017    }
2018
2019    startResponse;
2020    appendPrintBuf("%snumber=%s,numberPresentation=%d, name=%s,\
2021            signalInfoRecord[isPresent=%d,signalType=%d,alertPitch=%d\
2022            signal=%d,number_type=%d,number_plan=%d]",
2023            printBuf,
2024            p_cur->number,
2025            p_cur->numberPresentation,
2026            p_cur->name,
2027            p_cur->signalInfoRecord.isPresent,
2028            p_cur->signalInfoRecord.signalType,
2029            p_cur->signalInfoRecord.alertPitch,
2030            p_cur->signalInfoRecord.signal,
2031            p_cur->number_type,
2032            p_cur->number_plan);
2033    closeResponse;
2034
2035    return 0;
2036}
2037
2038static void triggerEvLoop() {
2039    int ret;
2040    if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
2041        /* trigger event loop to wakeup. No reason to do this,
2042         * if we're in the event loop thread */
2043         do {
2044            ret = write (s_fdWakeupWrite, " ", 1);
2045         } while (ret < 0 && errno == EINTR);
2046    }
2047}
2048
2049static void rilEventAddWakeup(struct ril_event *ev) {
2050    ril_event_add(ev);
2051    triggerEvLoop();
2052}
2053
2054static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatus[]) {
2055        p.writeInt32(num_apps);
2056        startResponse;
2057        for (int i = 0; i < num_apps; i++) {
2058            p.writeInt32(appStatus[i].app_type);
2059            p.writeInt32(appStatus[i].app_state);
2060            p.writeInt32(appStatus[i].perso_substate);
2061            writeStringToParcel(p, (const char*)(appStatus[i].aid_ptr));
2062            writeStringToParcel(p, (const char*)
2063                                          (appStatus[i].app_label_ptr));
2064            p.writeInt32(appStatus[i].pin1_replaced);
2065            p.writeInt32(appStatus[i].pin1);
2066            p.writeInt32(appStatus[i].pin2);
2067            appendPrintBuf("%s[app_type=%d,app_state=%d,perso_substate=%d,\
2068                    aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
2069                    printBuf,
2070                    appStatus[i].app_type,
2071                    appStatus[i].app_state,
2072                    appStatus[i].perso_substate,
2073                    appStatus[i].aid_ptr,
2074                    appStatus[i].app_label_ptr,
2075                    appStatus[i].pin1_replaced,
2076                    appStatus[i].pin1,
2077                    appStatus[i].pin2);
2078        }
2079        closeResponse;
2080}
2081
2082static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
2083    int i;
2084
2085    if (response == NULL && responselen != 0) {
2086        LOGE("invalid response: NULL");
2087        return RIL_ERRNO_INVALID_RESPONSE;
2088    }
2089
2090    if (responselen == sizeof (RIL_CardStatus_v6)) {
2091        RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
2092
2093        p.writeInt32(p_cur->card_state);
2094        p.writeInt32(p_cur->universal_pin_state);
2095        p.writeInt32(p_cur->gsm_umts_subscription_app_index);
2096        p.writeInt32(p_cur->cdma_subscription_app_index);
2097        p.writeInt32(p_cur->ims_subscription_app_index);
2098
2099        sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
2100    } else if (responselen == sizeof (RIL_CardStatus_v5)) {
2101        RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
2102
2103        p.writeInt32(p_cur->card_state);
2104        p.writeInt32(p_cur->universal_pin_state);
2105        p.writeInt32(p_cur->gsm_umts_subscription_app_index);
2106        p.writeInt32(p_cur->cdma_subscription_app_index);
2107        p.writeInt32(-1);
2108
2109        sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
2110    } else {
2111        LOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
2112        return RIL_ERRNO_INVALID_RESPONSE;
2113    }
2114
2115    return 0;
2116}
2117
2118static int responseGsmBrSmsCnf(Parcel &p, void *response, size_t responselen) {
2119    int num = responselen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
2120    p.writeInt32(num);
2121
2122    startResponse;
2123    RIL_GSM_BroadcastSmsConfigInfo **p_cur =
2124                (RIL_GSM_BroadcastSmsConfigInfo **) response;
2125    for (int i = 0; i < num; i++) {
2126        p.writeInt32(p_cur[i]->fromServiceId);
2127        p.writeInt32(p_cur[i]->toServiceId);
2128        p.writeInt32(p_cur[i]->fromCodeScheme);
2129        p.writeInt32(p_cur[i]->toCodeScheme);
2130        p.writeInt32(p_cur[i]->selected);
2131
2132        appendPrintBuf("%s [%d: fromServiceId=%d, toServiceId=%d, \
2133                fromCodeScheme=%d, toCodeScheme=%d, selected =%d]",
2134                printBuf, i, p_cur[i]->fromServiceId, p_cur[i]->toServiceId,
2135                p_cur[i]->fromCodeScheme, p_cur[i]->toCodeScheme,
2136                p_cur[i]->selected);
2137    }
2138    closeResponse;
2139
2140    return 0;
2141}
2142
2143static int responseCdmaBrSmsCnf(Parcel &p, void *response, size_t responselen) {
2144    RIL_CDMA_BroadcastSmsConfigInfo **p_cur =
2145               (RIL_CDMA_BroadcastSmsConfigInfo **) response;
2146
2147    int num = responselen / sizeof (RIL_CDMA_BroadcastSmsConfigInfo *);
2148    p.writeInt32(num);
2149
2150    startResponse;
2151    for (int i = 0 ; i < num ; i++ ) {
2152        p.writeInt32(p_cur[i]->service_category);
2153        p.writeInt32(p_cur[i]->language);
2154        p.writeInt32(p_cur[i]->selected);
2155
2156        appendPrintBuf("%s [%d: srvice_category=%d, language =%d, \
2157              selected =%d], ",
2158              printBuf, i, p_cur[i]->service_category, p_cur[i]->language,
2159              p_cur[i]->selected);
2160    }
2161    closeResponse;
2162
2163    return 0;
2164}
2165
2166static int responseCdmaSms(Parcel &p, void *response, size_t responselen) {
2167    int num;
2168    int digitCount;
2169    int digitLimit;
2170    uint8_t uct;
2171    void* dest;
2172
2173    LOGD("Inside responseCdmaSms");
2174
2175    if (response == NULL && responselen != 0) {
2176        LOGE("invalid response: NULL");
2177        return RIL_ERRNO_INVALID_RESPONSE;
2178    }
2179
2180    if (responselen != sizeof(RIL_CDMA_SMS_Message)) {
2181        LOGE("invalid response length was %d expected %d",
2182                (int)responselen, (int)sizeof(RIL_CDMA_SMS_Message));
2183        return RIL_ERRNO_INVALID_RESPONSE;
2184    }
2185
2186    RIL_CDMA_SMS_Message *p_cur = (RIL_CDMA_SMS_Message *) response;
2187    p.writeInt32(p_cur->uTeleserviceID);
2188    p.write(&(p_cur->bIsServicePresent),sizeof(uct));
2189    p.writeInt32(p_cur->uServicecategory);
2190    p.writeInt32(p_cur->sAddress.digit_mode);
2191    p.writeInt32(p_cur->sAddress.number_mode);
2192    p.writeInt32(p_cur->sAddress.number_type);
2193    p.writeInt32(p_cur->sAddress.number_plan);
2194    p.write(&(p_cur->sAddress.number_of_digits), sizeof(uct));
2195    digitLimit= MIN((p_cur->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
2196    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2197        p.write(&(p_cur->sAddress.digits[digitCount]),sizeof(uct));
2198    }
2199
2200    p.writeInt32(p_cur->sSubAddress.subaddressType);
2201    p.write(&(p_cur->sSubAddress.odd),sizeof(uct));
2202    p.write(&(p_cur->sSubAddress.number_of_digits),sizeof(uct));
2203    digitLimit= MIN((p_cur->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
2204    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2205        p.write(&(p_cur->sSubAddress.digits[digitCount]),sizeof(uct));
2206    }
2207
2208    digitLimit= MIN((p_cur->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
2209    p.writeInt32(p_cur->uBearerDataLen);
2210    for(digitCount =0 ; digitCount < digitLimit; digitCount ++) {
2211       p.write(&(p_cur->aBearerData[digitCount]), sizeof(uct));
2212    }
2213
2214    startResponse;
2215    appendPrintBuf("%suTeleserviceID=%d, bIsServicePresent=%d, uServicecategory=%d, \
2216            sAddress.digit_mode=%d, sAddress.number_mode=%d, sAddress.number_type=%d, ",
2217            printBuf, p_cur->uTeleserviceID,p_cur->bIsServicePresent,p_cur->uServicecategory,
2218            p_cur->sAddress.digit_mode, p_cur->sAddress.number_mode,p_cur->sAddress.number_type);
2219    closeResponse;
2220
2221    return 0;
2222}
2223
2224/**
2225 * A write on the wakeup fd is done just to pop us out of select()
2226 * We empty the buffer here and then ril_event will reset the timers on the
2227 * way back down
2228 */
2229static void processWakeupCallback(int fd, short flags, void *param) {
2230    char buff[16];
2231    int ret;
2232
2233    LOGV("processWakeupCallback");
2234
2235    /* empty our wakeup socket out */
2236    do {
2237        ret = read(s_fdWakeupRead, &buff, sizeof(buff));
2238    } while (ret > 0 || (ret < 0 && errno == EINTR));
2239}
2240
2241static void onCommandsSocketClosed() {
2242    int ret;
2243    RequestInfo *p_cur;
2244
2245    /* mark pending requests as "cancelled" so we dont report responses */
2246
2247    ret = pthread_mutex_lock(&s_pendingRequestsMutex);
2248    assert (ret == 0);
2249
2250    p_cur = s_pendingRequests;
2251
2252    for (p_cur = s_pendingRequests
2253            ; p_cur != NULL
2254            ; p_cur  = p_cur->p_next
2255    ) {
2256        p_cur->cancelled = 1;
2257    }
2258
2259    ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
2260    assert (ret == 0);
2261}
2262
2263static void processCommandsCallback(int fd, short flags, void *param) {
2264    RecordStream *p_rs;
2265    void *p_record;
2266    size_t recordlen;
2267    int ret;
2268
2269    assert(fd == s_fdCommand);
2270
2271    p_rs = (RecordStream *)param;
2272
2273    for (;;) {
2274        /* loop until EAGAIN/EINTR, end of stream, or other error */
2275        ret = record_stream_get_next(p_rs, &p_record, &recordlen);
2276
2277        if (ret == 0 && p_record == NULL) {
2278            /* end-of-stream */
2279            break;
2280        } else if (ret < 0) {
2281            break;
2282        } else if (ret == 0) { /* && p_record != NULL */
2283            processCommandBuffer(p_record, recordlen);
2284        }
2285    }
2286
2287    if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
2288        /* fatal error or end-of-stream */
2289        if (ret != 0) {
2290            LOGE("error on reading command socket errno:%d\n", errno);
2291        } else {
2292            LOGW("EOS.  Closing command socket.");
2293        }
2294
2295        close(s_fdCommand);
2296        s_fdCommand = -1;
2297
2298        ril_event_del(&s_commands_event);
2299
2300        record_stream_free(p_rs);
2301
2302        /* start listening for new connections again */
2303        rilEventAddWakeup(&s_listen_event);
2304
2305        onCommandsSocketClosed();
2306    }
2307}
2308
2309
2310static void onNewCommandConnect() {
2311    // Inform we are connected and the ril version
2312    int rilVer = s_callbacks.version;
2313    RIL_onUnsolicitedResponse(RIL_UNSOL_RIL_CONNECTED,
2314                                    &rilVer, sizeof(rilVer));
2315
2316    // implicit radio state changed
2317    RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
2318                                    NULL, 0);
2319
2320    // Send last NITZ time data, in case it was missed
2321    if (s_lastNITZTimeData != NULL) {
2322        sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize);
2323
2324        free(s_lastNITZTimeData);
2325        s_lastNITZTimeData = NULL;
2326    }
2327
2328    // Get version string
2329    if (s_callbacks.getVersion != NULL) {
2330        const char *version;
2331        version = s_callbacks.getVersion();
2332        LOGI("RIL Daemon version: %s\n", version);
2333
2334        property_set(PROPERTY_RIL_IMPL, version);
2335    } else {
2336        LOGI("RIL Daemon version: unavailable\n");
2337        property_set(PROPERTY_RIL_IMPL, "unavailable");
2338    }
2339
2340}
2341
2342static void listenCallback (int fd, short flags, void *param) {
2343    int ret;
2344    int err;
2345    int is_phone_socket;
2346    RecordStream *p_rs;
2347
2348    struct sockaddr_un peeraddr;
2349    socklen_t socklen = sizeof (peeraddr);
2350
2351    struct ucred creds;
2352    socklen_t szCreds = sizeof(creds);
2353
2354    struct passwd *pwd = NULL;
2355
2356    assert (s_fdCommand < 0);
2357    assert (fd == s_fdListen);
2358
2359    s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
2360
2361    if (s_fdCommand < 0 ) {
2362        LOGE("Error on accept() errno:%d", errno);
2363        /* start listening for new connections again */
2364        rilEventAddWakeup(&s_listen_event);
2365	      return;
2366    }
2367
2368    /* check the credential of the other side and only accept socket from
2369     * phone process
2370     */
2371    errno = 0;
2372    is_phone_socket = 0;
2373
2374    err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
2375
2376    if (err == 0 && szCreds > 0) {
2377        errno = 0;
2378        pwd = getpwuid(creds.uid);
2379        if (pwd != NULL) {
2380            if (strcmp(pwd->pw_name, PHONE_PROCESS) == 0) {
2381                is_phone_socket = 1;
2382            } else {
2383                LOGE("RILD can't accept socket from process %s", pwd->pw_name);
2384            }
2385        } else {
2386            LOGE("Error on getpwuid() errno: %d", errno);
2387        }
2388    } else {
2389        LOGD("Error on getsockopt() errno: %d", errno);
2390    }
2391
2392    if ( !is_phone_socket ) {
2393      LOGE("RILD must accept socket from %s", PHONE_PROCESS);
2394
2395      close(s_fdCommand);
2396      s_fdCommand = -1;
2397
2398      onCommandsSocketClosed();
2399
2400      /* start listening for new connections again */
2401      rilEventAddWakeup(&s_listen_event);
2402
2403      return;
2404    }
2405
2406    ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);
2407
2408    if (ret < 0) {
2409        LOGE ("Error setting O_NONBLOCK errno:%d", errno);
2410    }
2411
2412    LOGI("libril: new connection");
2413
2414    p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES);
2415
2416    ril_event_set (&s_commands_event, s_fdCommand, 1,
2417        processCommandsCallback, p_rs);
2418
2419    rilEventAddWakeup (&s_commands_event);
2420
2421    onNewCommandConnect();
2422}
2423
2424static void freeDebugCallbackArgs(int number, char **args) {
2425    for (int i = 0; i < number; i++) {
2426        if (args[i] != NULL) {
2427            free(args[i]);
2428        }
2429    }
2430    free(args);
2431}
2432
2433static void debugCallback (int fd, short flags, void *param) {
2434    int acceptFD, option;
2435    struct sockaddr_un peeraddr;
2436    socklen_t socklen = sizeof (peeraddr);
2437    int data;
2438    unsigned int qxdm_data[6];
2439    const char *deactData[1] = {"1"};
2440    char *actData[1];
2441    RIL_Dial dialData;
2442    int hangupData[1] = {1};
2443    int number;
2444    char **args;
2445
2446    acceptFD = accept (fd,  (sockaddr *) &peeraddr, &socklen);
2447
2448    if (acceptFD < 0) {
2449        LOGE ("error accepting on debug port: %d\n", errno);
2450        return;
2451    }
2452
2453    if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
2454        LOGE ("error reading on socket: number of Args: \n");
2455        return;
2456    }
2457    args = (char **) malloc(sizeof(char*) * number);
2458
2459    for (int i = 0; i < number; i++) {
2460        int len;
2461        if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
2462            LOGE ("error reading on socket: Len of Args: \n");
2463            freeDebugCallbackArgs(i, args);
2464            return;
2465        }
2466        // +1 for null-term
2467        args[i] = (char *) malloc((sizeof(char) * len) + 1);
2468        if (recv(acceptFD, args[i], sizeof(char) * len, 0)
2469            != (int)sizeof(char) * len) {
2470            LOGE ("error reading on socket: Args[%d] \n", i);
2471            freeDebugCallbackArgs(i, args);
2472            return;
2473        }
2474        char * buf = args[i];
2475        buf[len] = 0;
2476    }
2477
2478    switch (atoi(args[0])) {
2479        case 0:
2480            LOGI ("Connection on debug port: issuing reset.");
2481            issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0);
2482            break;
2483        case 1:
2484            LOGI ("Connection on debug port: issuing radio power off.");
2485            data = 0;
2486            issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
2487            // Close the socket
2488            close(s_fdCommand);
2489            s_fdCommand = -1;
2490            break;
2491        case 2:
2492            LOGI ("Debug port: issuing unsolicited voice network change.");
2493            RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
2494                                      NULL, 0);
2495            break;
2496        case 3:
2497            LOGI ("Debug port: QXDM log enable.");
2498            qxdm_data[0] = 65536;     // head.func_tag
2499            qxdm_data[1] = 16;        // head.len
2500            qxdm_data[2] = 1;         // mode: 1 for 'start logging'
2501            qxdm_data[3] = 32;        // log_file_size: 32megabytes
2502            qxdm_data[4] = 0;         // log_mask
2503            qxdm_data[5] = 8;         // log_max_fileindex
2504            issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
2505                              6 * sizeof(int));
2506            break;
2507        case 4:
2508            LOGI ("Debug port: QXDM log disable.");
2509            qxdm_data[0] = 65536;
2510            qxdm_data[1] = 16;
2511            qxdm_data[2] = 0;          // mode: 0 for 'stop logging'
2512            qxdm_data[3] = 32;
2513            qxdm_data[4] = 0;
2514            qxdm_data[5] = 8;
2515            issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
2516                              6 * sizeof(int));
2517            break;
2518        case 5:
2519            LOGI("Debug port: Radio On");
2520            data = 1;
2521            issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
2522            sleep(2);
2523            // Set network selection automatic.
2524            issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0);
2525            break;
2526        case 6:
2527            LOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]);
2528            actData[0] = args[1];
2529            issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData,
2530                              sizeof(actData));
2531            break;
2532        case 7:
2533            LOGI("Debug port: Deactivate Data Call");
2534            issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData,
2535                              sizeof(deactData));
2536            break;
2537        case 8:
2538            LOGI("Debug port: Dial Call");
2539            dialData.clir = 0;
2540            dialData.address = args[1];
2541            issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData));
2542            break;
2543        case 9:
2544            LOGI("Debug port: Answer Call");
2545            issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0);
2546            break;
2547        case 10:
2548            LOGI("Debug port: End Call");
2549            issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
2550                              sizeof(hangupData));
2551            break;
2552        default:
2553            LOGE ("Invalid request");
2554            break;
2555    }
2556    freeDebugCallbackArgs(number, args);
2557    close(acceptFD);
2558}
2559
2560
2561static void userTimerCallback (int fd, short flags, void *param) {
2562    UserCallbackInfo *p_info;
2563
2564    p_info = (UserCallbackInfo *)param;
2565
2566    p_info->p_callback(p_info->userParam);
2567
2568
2569    // FIXME generalize this...there should be a cancel mechanism
2570    if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
2571        s_last_wake_timeout_info = NULL;
2572    }
2573
2574    free(p_info);
2575}
2576
2577
2578static void *
2579eventLoop(void *param) {
2580    int ret;
2581    int filedes[2];
2582
2583    ril_event_init();
2584
2585    pthread_mutex_lock(&s_startupMutex);
2586
2587    s_started = 1;
2588    pthread_cond_broadcast(&s_startupCond);
2589
2590    pthread_mutex_unlock(&s_startupMutex);
2591
2592    ret = pipe(filedes);
2593
2594    if (ret < 0) {
2595        LOGE("Error in pipe() errno:%d", errno);
2596        return NULL;
2597    }
2598
2599    s_fdWakeupRead = filedes[0];
2600    s_fdWakeupWrite = filedes[1];
2601
2602    fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
2603
2604    ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
2605                processWakeupCallback, NULL);
2606
2607    rilEventAddWakeup (&s_wakeupfd_event);
2608
2609    // Only returns on error
2610    ril_event_loop();
2611    LOGE ("error in event_loop_base errno:%d", errno);
2612
2613    return NULL;
2614}
2615
2616extern "C" void
2617RIL_startEventLoop(void) {
2618    int ret;
2619    pthread_attr_t attr;
2620
2621    /* spin up eventLoop thread and wait for it to get started */
2622    s_started = 0;
2623    pthread_mutex_lock(&s_startupMutex);
2624
2625    pthread_attr_init (&attr);
2626    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2627    ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
2628
2629    while (s_started == 0) {
2630        pthread_cond_wait(&s_startupCond, &s_startupMutex);
2631    }
2632
2633    pthread_mutex_unlock(&s_startupMutex);
2634
2635    if (ret < 0) {
2636        LOGE("Failed to create dispatch thread errno:%d", errno);
2637        return;
2638    }
2639}
2640
2641// Used for testing purpose only.
2642extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
2643    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
2644}
2645
2646extern "C" void
2647RIL_register (const RIL_RadioFunctions *callbacks) {
2648    int ret;
2649    int flags;
2650
2651    if (callbacks == NULL) {
2652        LOGE("RIL_register: RIL_RadioFunctions * null");
2653        return;
2654    }
2655    if (callbacks->version < RIL_VERSION_MIN) {
2656        LOGE("RIL_register: version %d is to old, min version is %d",
2657             callbacks->version, RIL_VERSION_MIN);
2658        return;
2659    }
2660    if (callbacks->version > RIL_VERSION) {
2661        LOGE("RIL_register: version %d is too new, max version is %d",
2662             callbacks->version, RIL_VERSION);
2663        return;
2664    }
2665    LOGE("RIL_register: RIL version %d", callbacks->version);
2666
2667    if (s_registerCalled > 0) {
2668        LOGE("RIL_register has been called more than once. "
2669                "Subsequent call ignored");
2670        return;
2671    }
2672
2673    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
2674
2675    s_registerCalled = 1;
2676
2677    // Little self-check
2678
2679    for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
2680        assert(i == s_commands[i].requestNumber);
2681    }
2682
2683    for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
2684        assert(i + RIL_UNSOL_RESPONSE_BASE
2685                == s_unsolResponses[i].requestNumber);
2686    }
2687
2688    // New rild impl calls RIL_startEventLoop() first
2689    // old standalone impl wants it here.
2690
2691    if (s_started == 0) {
2692        RIL_startEventLoop();
2693    }
2694
2695    // start listen socket
2696
2697#if 0
2698    ret = socket_local_server (SOCKET_NAME_RIL,
2699            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
2700
2701    if (ret < 0) {
2702        LOGE("Unable to bind socket errno:%d", errno);
2703        exit (-1);
2704    }
2705    s_fdListen = ret;
2706
2707#else
2708    s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
2709    if (s_fdListen < 0) {
2710        LOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
2711        exit(-1);
2712    }
2713
2714    ret = listen(s_fdListen, 4);
2715
2716    if (ret < 0) {
2717        LOGE("Failed to listen on control socket '%d': %s",
2718             s_fdListen, strerror(errno));
2719        exit(-1);
2720    }
2721#endif
2722
2723
2724    /* note: non-persistent so we can accept only one connection at a time */
2725    ril_event_set (&s_listen_event, s_fdListen, false,
2726                listenCallback, NULL);
2727
2728    rilEventAddWakeup (&s_listen_event);
2729
2730#if 1
2731    // start debug interface socket
2732
2733    s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG);
2734    if (s_fdDebug < 0) {
2735        LOGE("Failed to get socket '" SOCKET_NAME_RIL_DEBUG "' errno:%d", errno);
2736        exit(-1);
2737    }
2738
2739    ret = listen(s_fdDebug, 4);
2740
2741    if (ret < 0) {
2742        LOGE("Failed to listen on ril debug socket '%d': %s",
2743             s_fdDebug, strerror(errno));
2744        exit(-1);
2745    }
2746
2747    ril_event_set (&s_debug_event, s_fdDebug, true,
2748                debugCallback, NULL);
2749
2750    rilEventAddWakeup (&s_debug_event);
2751#endif
2752
2753}
2754
2755static int
2756checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
2757    int ret = 0;
2758
2759    if (pRI == NULL) {
2760        return 0;
2761    }
2762
2763    pthread_mutex_lock(&s_pendingRequestsMutex);
2764
2765    for(RequestInfo **ppCur = &s_pendingRequests
2766        ; *ppCur != NULL
2767        ; ppCur = &((*ppCur)->p_next)
2768    ) {
2769        if (pRI == *ppCur) {
2770            ret = 1;
2771
2772            *ppCur = (*ppCur)->p_next;
2773            break;
2774        }
2775    }
2776
2777    pthread_mutex_unlock(&s_pendingRequestsMutex);
2778
2779    return ret;
2780}
2781
2782
2783extern "C" void
2784RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
2785    RequestInfo *pRI;
2786    int ret;
2787    size_t errorOffset;
2788
2789    pRI = (RequestInfo *)t;
2790
2791    if (!checkAndDequeueRequestInfo(pRI)) {
2792        LOGE ("RIL_onRequestComplete: invalid RIL_Token");
2793        return;
2794    }
2795
2796    if (pRI->local > 0) {
2797        // Locally issued command...void only!
2798        // response does not go back up the command socket
2799        LOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
2800
2801        goto done;
2802    }
2803
2804    appendPrintBuf("[%04d]< %s",
2805        pRI->token, requestToString(pRI->pCI->requestNumber));
2806
2807    if (pRI->cancelled == 0) {
2808        Parcel p;
2809
2810        p.writeInt32 (RESPONSE_SOLICITED);
2811        p.writeInt32 (pRI->token);
2812        errorOffset = p.dataPosition();
2813
2814        p.writeInt32 (e);
2815
2816        if (response != NULL) {
2817            // there is a response payload, no matter success or not.
2818            ret = pRI->pCI->responseFunction(p, response, responselen);
2819
2820            /* if an error occurred, rewind and mark it */
2821            if (ret != 0) {
2822                p.setDataPosition(errorOffset);
2823                p.writeInt32 (ret);
2824            }
2825        }
2826
2827        if (e != RIL_E_SUCCESS) {
2828            appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e));
2829        }
2830
2831        if (s_fdCommand < 0) {
2832            LOGD ("RIL onRequestComplete: Command channel closed");
2833        }
2834        sendResponse(p);
2835    }
2836
2837done:
2838    free(pRI);
2839}
2840
2841
2842static void
2843grabPartialWakeLock() {
2844    acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
2845}
2846
2847static void
2848releaseWakeLock() {
2849    release_wake_lock(ANDROID_WAKE_LOCK_NAME);
2850}
2851
2852/**
2853 * Timer callback to put us back to sleep before the default timeout
2854 */
2855static void
2856wakeTimeoutCallback (void *param) {
2857    // We're using "param != NULL" as a cancellation mechanism
2858    if (param == NULL) {
2859        //LOGD("wakeTimeout: releasing wake lock");
2860
2861        releaseWakeLock();
2862    } else {
2863        //LOGD("wakeTimeout: releasing wake lock CANCELLED");
2864    }
2865}
2866
2867extern "C"
2868void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
2869                                size_t datalen)
2870{
2871    int unsolResponseIndex;
2872    int ret;
2873    int64_t timeReceived = 0;
2874    bool shouldScheduleTimeout = false;
2875
2876    if (s_registerCalled == 0) {
2877        // Ignore RIL_onUnsolicitedResponse before RIL_register
2878        LOGW("RIL_onUnsolicitedResponse called before RIL_register");
2879        return;
2880    }
2881
2882    unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
2883
2884    if ((unsolResponseIndex < 0)
2885        || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) {
2886        LOGE("unsupported unsolicited response code %d", unsolResponse);
2887        return;
2888    }
2889
2890    // Grab a wake lock if needed for this reponse,
2891    // as we exit we'll either release it immediately
2892    // or set a timer to release it later.
2893    switch (s_unsolResponses[unsolResponseIndex].wakeType) {
2894        case WAKE_PARTIAL:
2895            grabPartialWakeLock();
2896            shouldScheduleTimeout = true;
2897        break;
2898
2899        case DONT_WAKE:
2900        default:
2901            // No wake lock is grabed so don't set timeout
2902            shouldScheduleTimeout = false;
2903            break;
2904    }
2905
2906    // Mark the time this was received, doing this
2907    // after grabing the wakelock incase getting
2908    // the elapsedRealTime might cause us to goto
2909    // sleep.
2910    if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
2911        timeReceived = elapsedRealtime();
2912    }
2913
2914    appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
2915
2916    Parcel p;
2917
2918    p.writeInt32 (RESPONSE_UNSOLICITED);
2919    p.writeInt32 (unsolResponse);
2920
2921    ret = s_unsolResponses[unsolResponseIndex]
2922                .responseFunction(p, data, datalen);
2923    if (ret != 0) {
2924        // Problem with the response. Don't continue;
2925        goto error_exit;
2926    }
2927
2928    // some things get more payload
2929    switch(unsolResponse) {
2930        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
2931            p.writeInt32(s_callbacks.onStateRequest());
2932            appendPrintBuf("%s {%s}", printBuf,
2933                radioStateToString(s_callbacks.onStateRequest()));
2934        break;
2935
2936
2937        case RIL_UNSOL_NITZ_TIME_RECEIVED:
2938            // Store the time that this was received so the
2939            // handler of this message can account for
2940            // the time it takes to arrive and process. In
2941            // particular the system has been known to sleep
2942            // before this message can be processed.
2943            p.writeInt64(timeReceived);
2944        break;
2945    }
2946
2947    ret = sendResponse(p);
2948    if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
2949
2950        // Unfortunately, NITZ time is not poll/update like everything
2951        // else in the system. So, if the upstream client isn't connected,
2952        // keep a copy of the last NITZ response (with receive time noted
2953        // above) around so we can deliver it when it is connected
2954
2955        if (s_lastNITZTimeData != NULL) {
2956            free (s_lastNITZTimeData);
2957            s_lastNITZTimeData = NULL;
2958        }
2959
2960        s_lastNITZTimeData = malloc(p.dataSize());
2961        s_lastNITZTimeDataSize = p.dataSize();
2962        memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
2963    }
2964
2965    // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
2966    // FIXME The java code should handshake here to release wake lock
2967
2968    if (shouldScheduleTimeout) {
2969        // Cancel the previous request
2970        if (s_last_wake_timeout_info != NULL) {
2971            s_last_wake_timeout_info->userParam = (void *)1;
2972        }
2973
2974        s_last_wake_timeout_info
2975            = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
2976                                            &TIMEVAL_WAKE_TIMEOUT);
2977    }
2978
2979    // Normal exit
2980    return;
2981
2982error_exit:
2983    if (shouldScheduleTimeout) {
2984        releaseWakeLock();
2985    }
2986}
2987
2988/** FIXME generalize this if you track UserCAllbackInfo, clear it
2989    when the callback occurs
2990*/
2991static UserCallbackInfo *
2992internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
2993                                const struct timeval *relativeTime)
2994{
2995    struct timeval myRelativeTime;
2996    UserCallbackInfo *p_info;
2997
2998    p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
2999
3000    p_info->p_callback = callback;
3001    p_info->userParam = param;
3002
3003    if (relativeTime == NULL) {
3004        /* treat null parameter as a 0 relative time */
3005        memset (&myRelativeTime, 0, sizeof(myRelativeTime));
3006    } else {
3007        /* FIXME I think event_add's tv param is really const anyway */
3008        memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
3009    }
3010
3011    ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
3012
3013    ril_timer_add(&(p_info->event), &myRelativeTime);
3014
3015    triggerEvLoop();
3016    return p_info;
3017}
3018
3019
3020extern "C" void
3021RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
3022                                const struct timeval *relativeTime) {
3023    internalRequestTimedCallback (callback, param, relativeTime);
3024}
3025
3026const char *
3027failCauseToString(RIL_Errno e) {
3028    switch(e) {
3029        case RIL_E_SUCCESS: return "E_SUCCESS";
3030        case RIL_E_RADIO_NOT_AVAILABLE: return "E_RAIDO_NOT_AVAILABLE";
3031        case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
3032        case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
3033        case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
3034        case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
3035        case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
3036        case RIL_E_CANCELLED: return "E_CANCELLED";
3037        case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
3038        case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
3039        case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
3040        case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
3041        case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
3042#ifdef FEATURE_MULTIMODE_ANDROID
3043        case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
3044        case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
3045#endif
3046        default: return "<unknown error>";
3047    }
3048}
3049
3050const char *
3051radioStateToString(RIL_RadioState s) {
3052    switch(s) {
3053        case RADIO_STATE_OFF: return "RADIO_OFF";
3054        case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
3055        case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
3056        case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
3057        case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
3058        case RADIO_STATE_RUIM_NOT_READY:return"RADIO_RUIM_NOT_READY";
3059        case RADIO_STATE_RUIM_READY:return"RADIO_RUIM_READY";
3060        case RADIO_STATE_RUIM_LOCKED_OR_ABSENT:return"RADIO_RUIM_LOCKED_OR_ABSENT";
3061        case RADIO_STATE_NV_NOT_READY:return"RADIO_NV_NOT_READY";
3062        case RADIO_STATE_NV_READY:return"RADIO_NV_READY";
3063        default: return "<unknown state>";
3064    }
3065}
3066
3067const char *
3068callStateToString(RIL_CallState s) {
3069    switch(s) {
3070        case RIL_CALL_ACTIVE : return "ACTIVE";
3071        case RIL_CALL_HOLDING: return "HOLDING";
3072        case RIL_CALL_DIALING: return "DIALING";
3073        case RIL_CALL_ALERTING: return "ALERTING";
3074        case RIL_CALL_INCOMING: return "INCOMING";
3075        case RIL_CALL_WAITING: return "WAITING";
3076        default: return "<unknown state>";
3077    }
3078}
3079
3080const char *
3081requestToString(int request) {
3082/*
3083 cat libs/telephony/ril_commands.h \
3084 | egrep "^ *{RIL_" \
3085 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
3086
3087
3088 cat libs/telephony/ril_unsol_commands.h \
3089 | egrep "^ *{RIL_" \
3090 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
3091
3092*/
3093    switch(request) {
3094        case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
3095        case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
3096        case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
3097        case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
3098        case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
3099        case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
3100        case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
3101        case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
3102        case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
3103        case RIL_REQUEST_DIAL: return "DIAL";
3104        case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
3105        case RIL_REQUEST_HANGUP: return "HANGUP";
3106        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
3107        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
3108        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
3109        case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
3110        case RIL_REQUEST_UDUB: return "UDUB";
3111        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
3112        case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
3113        case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
3114        case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
3115        case RIL_REQUEST_OPERATOR: return "OPERATOR";
3116        case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
3117        case RIL_REQUEST_DTMF: return "DTMF";
3118        case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
3119        case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
3120        case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
3121        case RIL_REQUEST_SIM_IO: return "SIM_IO";
3122        case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
3123        case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
3124        case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
3125        case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
3126        case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
3127        case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
3128        case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
3129        case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
3130        case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
3131        case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
3132        case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
3133        case RIL_REQUEST_ANSWER: return "ANSWER";
3134        case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
3135        case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
3136        case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
3137        case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
3138        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
3139        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
3140        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
3141        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
3142        case RIL_REQUEST_DTMF_START: return "DTMF_START";
3143        case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
3144        case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
3145        case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
3146        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
3147        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
3148        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
3149        case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
3150        case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
3151        case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
3152        case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
3153        case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
3154        case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
3155        case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
3156        case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
3157        case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
3158        case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
3159        case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
3160        case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
3161        case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
3162        case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
3163        case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
3164        case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
3165        case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
3166        case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
3167        case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:return"CDMA_SET_SUBSCRIPTION_SOURCE";
3168        case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:return"CDMA_SET_ROAMING_PREFERENCE";
3169        case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:return"CDMA_QUERY_ROAMING_PREFERENCE";
3170        case RIL_REQUEST_SET_TTY_MODE:return"SET_TTY_MODE";
3171        case RIL_REQUEST_QUERY_TTY_MODE:return"QUERY_TTY_MODE";
3172        case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
3173        case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:return"CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
3174        case RIL_REQUEST_CDMA_FLASH:return"CDMA_FLASH";
3175        case RIL_REQUEST_CDMA_BURST_DTMF:return"CDMA_BURST_DTMF";
3176        case RIL_REQUEST_CDMA_SEND_SMS:return"CDMA_SEND_SMS";
3177        case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:return"CDMA_SMS_ACKNOWLEDGE";
3178        case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:return"GSM_GET_BROADCAST_SMS_CONFIG";
3179        case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:return"GSM_SET_BROADCAST_SMS_CONFIG";
3180        case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG:return "CDMA_GET_BROADCAST_SMS_CONFIG";
3181        case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG:return "CDMA_SET_BROADCAST_SMS_CONFIG";
3182        case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION:return "CDMA_SMS_BROADCAST_ACTIVATION";
3183        case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return"CDMA_VALIDATE_AND_WRITE_AKEY";
3184        case RIL_REQUEST_CDMA_SUBSCRIPTION: return"CDMA_SUBSCRIPTION";
3185        case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
3186        case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
3187        case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
3188        case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
3189        case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
3190        case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
3191        case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
3192        case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
3193        case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
3194        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
3195        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
3196        case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
3197        case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
3198        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
3199        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
3200        case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
3201        case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
3202        case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
3203        case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
3204        case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
3205        case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
3206        case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
3207        case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
3208        case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
3209        case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
3210        case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
3211        case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
3212        case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
3213        case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_NEW_CDMA_SMS";
3214        case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_NEW_BROADCAST_SMS";
3215        case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
3216        case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
3217        case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
3218        case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
3219        case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
3220        case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
3221        case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
3222        case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
3223        case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
3224        case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
3225        case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
3226        case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
3227        case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
3228        default: return "<unknown request>";
3229    }
3230}
3231
3232} /* namespace android */
3233