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