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