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