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