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