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