ril.cpp revision 154a2efc9b75de255cf9c3916d9d778c445df2ae
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 <telephony/ril.h>
21#include <cutils/sockets.h>
22#include <cutils/jstring.h>
23#include <cutils/record_stream.h>
24#include <utils/Log.h>
25#include <utils/SystemClock.h>
26#include <pthread.h>
27#include <utils/Parcel.h>
28#include <cutils/jstring.h>
29
30#include <sys/types.h>
31#include <pwd.h>
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <stdarg.h>
36#include <string.h>
37#include <unistd.h>
38#include <fcntl.h>
39#include <time.h>
40#include <errno.h>
41#include <assert.h>
42#include <ctype.h>
43#include <alloca.h>
44#include <sys/un.h>
45#include <assert.h>
46#include <netinet/in.h>
47#include <cutils/properties.h>
48
49#include <ril_event.h>
50
51namespace android {
52
53#define PHONE_PROCESS "radio"
54
55#define SOCKET_NAME_RIL "rild"
56#define SOCKET_NAME_RIL_DEBUG "rild-debug"
57
58#define ANDROID_WAKE_LOCK_NAME "radio-interface"
59
60
61#define ANDROID_PARTIAL_WAKE_LOCK_PATH "/sys/android_power/acquire_partial_wake_lock"
62#define ANDROID_FULL_WAKE_LOCK_PATH "/sys/android_power/acquire_full_wake_lock"
63#define ANDROID_WAKE_UNLOCK_PATH "/sys/android_power/release_wake_lock"
64
65#define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
66
67// match with constant in RIL.java
68#define MAX_COMMAND_BYTES (8 * 1024)
69
70// Basically: memset buffers that the client library
71// shouldn't be using anymore in an attempt to find
72// memory usage issues sooner.
73#define MEMSET_FREED 1
74
75#define NUM_ELEMS(a)     (sizeof (a) / sizeof (a)[0])
76
77/* Constants for response types */
78#define RESPONSE_SOLICITED 0
79#define RESPONSE_UNSOLICITED 1
80
81/* Negative values for private RIL errno's */
82#define RIL_ERRNO_INVALID_RESPONSE -1
83
84// request, response, and unsolicited msg print macro
85#define PRINTBUF_SIZE 8096
86
87// Enable RILC log
88#define RILC_LOG 0
89
90#if RILC_LOG
91    #define startRequest           sprintf(printBuf, "(")
92    #define closeRequest           sprintf(printBuf, "%s)", printBuf)
93    #define printRequest(token, req)           \
94            LOGD("[%04d]> %s %s", token, requestToString(req), printBuf)
95
96    #define startResponse           sprintf(printBuf, "%s {", printBuf)
97    #define closeResponse           sprintf(printBuf, "%s}", printBuf)
98    #define printResponse           LOGD("%s", printBuf)
99
100    #define clearPrintBuf           printBuf[0] = 0
101    #define removeLastChar          printBuf[strlen(printBuf)-1] = 0
102    #define appendPrintBuf(x...)    sprintf(printBuf, x)
103#else
104    #define startRequest
105    #define closeRequest
106    #define printRequest(token, req)
107    #define startResponse
108    #define closeResponse
109    #define printResponse
110    #define clearPrintBuf
111    #define removeLastChar
112    #define appendPrintBuf(x...)
113#endif
114
115enum WakeType {DONT_WAKE, WAKE_PARTIAL, WAKE_FULL};
116
117typedef struct {
118    int requestNumber;
119    void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);
120    int(*responseFunction) (Parcel &p, void *response, size_t responselen);
121} CommandInfo;
122
123typedef struct {
124    int requestNumber;
125    int (*responseFunction) (Parcel &p, void *response, size_t responselen);
126    WakeType wakeType;
127} UnsolResponseInfo;
128
129typedef struct RequestInfo {
130    int32_t token;      //this is not RIL_Token
131    CommandInfo *pCI;
132    struct RequestInfo *p_next;
133    char cancelled;
134    char local;         // responses to local commands do not go back to command process
135} RequestInfo;
136
137typedef struct UserCallbackInfo{
138    RIL_TimedCallback p_callback;
139    void *userParam;
140    struct ril_event event;
141    struct UserCallbackInfo *p_next;
142} UserCallbackInfo;
143
144
145/*******************************************************************/
146
147RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
148static int s_registerCalled = 0;
149
150static pthread_t s_tid_dispatch;
151static pthread_t s_tid_reader;
152static int s_started = 0;
153
154static int s_fdListen = -1;
155static int s_fdCommand = -1;
156static int s_fdDebug = -1;
157
158static int s_fdWakeupRead;
159static int s_fdWakeupWrite;
160
161static struct ril_event s_commands_event;
162static struct ril_event s_wakeupfd_event;
163static struct ril_event s_listen_event;
164static struct ril_event s_wake_timeout_event;
165static struct ril_event s_debug_event;
166
167
168static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
169
170static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
171static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
172static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
173static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
174
175static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
176static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
177
178static RequestInfo *s_pendingRequests = NULL;
179
180static RequestInfo *s_toDispatchHead = NULL;
181static RequestInfo *s_toDispatchTail = NULL;
182
183static UserCallbackInfo *s_last_wake_timeout_info = NULL;
184
185static void *s_lastNITZTimeData = NULL;
186static size_t s_lastNITZTimeDataSize;
187
188#if RILC_LOG
189    static char printBuf[PRINTBUF_SIZE];
190#endif
191
192/*******************************************************************/
193
194static void dispatchVoid (Parcel& p, RequestInfo *pRI);
195static void dispatchString (Parcel& p, RequestInfo *pRI);
196static void dispatchStrings (Parcel& p, RequestInfo *pRI);
197static void dispatchInts (Parcel& p, RequestInfo *pRI);
198static void dispatchDial (Parcel& p, RequestInfo *pRI);
199static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI);
200static void dispatchCallForward(Parcel& p, RequestInfo *pRI);
201static void dispatchRaw(Parcel& p, RequestInfo *pRI);
202static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI);
203
204static int responseInts(Parcel &p, void *response, size_t responselen);
205static int responseStrings(Parcel &p, void *response, size_t responselen);
206static int responseString(Parcel &p, void *response, size_t responselen);
207static int responseVoid(Parcel &p, void *response, size_t responselen);
208static int responseCallList(Parcel &p, void *response, size_t responselen);
209static int responseSMS(Parcel &p, void *response, size_t responselen);
210static int responseSIM_IO(Parcel &p, void *response, size_t responselen);
211static int responseCallForwards(Parcel &p, void *response, size_t responselen);
212static int responseContexts(Parcel &p, void *response, size_t responselen);
213static int responseRaw(Parcel &p, void *response, size_t responselen);
214static int responseSsn(Parcel &p, void *response, size_t responselen);
215static int responseCellList(Parcel &p, void *response, size_t responselen);
216
217extern "C" const char * requestToString(int request);
218extern "C" const char * failCauseToString(RIL_Errno);
219extern "C" const char * callStateToString(RIL_CallState);
220extern "C" const char * radioStateToString(RIL_RadioState);
221
222#ifdef RIL_SHLIB
223extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
224                                size_t datalen);
225#endif
226
227static UserCallbackInfo * internalRequestTimedCallback
228    (RIL_TimedCallback callback, void *param,
229        const struct timeval *relativeTime);
230
231/** Index == requestNumber */
232static CommandInfo s_commands[] = {
233#include "ril_commands.h"
234};
235
236static UnsolResponseInfo s_unsolResponses[] = {
237#include "ril_unsol_commands.h"
238};
239
240
241static char *
242strdupReadString(Parcel &p)
243{
244    size_t stringlen;
245    const char16_t *s16;
246
247    s16 = p.readString16Inplace(&stringlen);
248
249    return strndup16to8(s16, stringlen);
250}
251
252static void writeStringToParcel(Parcel &p, const char *s)
253{
254    char16_t *s16;
255    size_t s16_len;
256    s16 = strdup8to16(s, &s16_len);
257    p.writeString16(s16, s16_len);
258    free(s16);
259}
260
261
262static void
263memsetString (char *s)
264{
265    if (s != NULL) {
266        memset (s, 0, strlen(s));
267    }
268}
269
270void   nullParcelReleaseFunction (const uint8_t* data, size_t dataSize,
271                                    const size_t* objects, size_t objectsSize,
272                                        void* cookie)
273{
274    // do nothing -- the data reference lives longer than the Parcel object
275}
276
277/**
278 * To be called from dispatch thread
279 * Issue a single local request, ensuring that the response
280 * is not sent back up to the command process
281 */
282static void
283issueLocalRequest(int request, void *data, int len)
284{
285    RequestInfo *pRI;
286    int ret;
287
288    pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
289
290    pRI->local = 1;
291    pRI->token = 0xffffffff;        // token is not used in this context
292    pRI->pCI = &(s_commands[request]);
293
294    ret = pthread_mutex_lock(&s_pendingRequestsMutex);
295    assert (ret == 0);
296
297    pRI->p_next = s_pendingRequests;
298    s_pendingRequests = pRI;
299
300    ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
301    assert (ret == 0);
302
303    LOGD("C[locl]> %s", requestToString(request));
304
305    s_callbacks.onRequest(request, data, len, pRI);
306}
307
308
309
310static int
311processCommandBuffer(void *buffer, size_t buflen)
312{
313    Parcel p;
314    status_t status;
315    int32_t request;
316    int32_t token;
317    RequestInfo *pRI;
318    int ret;
319
320    p.setData((uint8_t *) buffer, buflen);
321
322    // status checked at end
323    status = p.readInt32(&request);
324    status = p.readInt32 (&token);
325
326    if (status != NO_ERROR) {
327        LOGE("invalid request block");
328        return 0;
329    }
330
331    if (request < 1 || request >= (int32_t)NUM_ELEMS(s_commands)) {
332        LOGE("unsupported request code %d token %d", request, token);
333        // FIXME this should perhaps return a response
334        return 0;
335    }
336
337
338    pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
339
340    pRI->token = token;
341    pRI->pCI = &(s_commands[request]);
342
343    ret = pthread_mutex_lock(&s_pendingRequestsMutex);
344    assert (ret == 0);
345
346    pRI->p_next = s_pendingRequests;
347    s_pendingRequests = pRI;
348
349    ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
350    assert (ret == 0);
351
352/*    sLastDispatchedToken = token; */
353
354    pRI->pCI->dispatchFunction(p, pRI);
355
356    return 0;
357}
358
359static void
360invalidCommandBlock (RequestInfo *pRI)
361{
362    LOGE("invalid command block for token %d request %s",
363                pRI->token, requestToString(pRI->pCI->requestNumber));
364}
365
366/** Callee expects NULL */
367static void
368dispatchVoid (Parcel& p, RequestInfo *pRI)
369{
370    clearPrintBuf;
371    printRequest(pRI->token, pRI->pCI->requestNumber);
372    s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI);
373}
374
375/** Callee expects const char * */
376static void
377dispatchString (Parcel& p, RequestInfo *pRI)
378{
379    status_t status;
380    size_t datalen;
381    size_t stringlen;
382    char *string8 = NULL;
383
384    string8 = strdupReadString(p);
385
386    startRequest;
387    appendPrintBuf("%s%s", printBuf, string8);
388    closeRequest;
389    printRequest(pRI->token, pRI->pCI->requestNumber);
390
391    s_callbacks.onRequest(pRI->pCI->requestNumber, string8,
392                       sizeof(char *), pRI);
393
394#ifdef MEMSET_FREED
395    memsetString(string8);
396#endif
397
398    free(string8);
399    return;
400invalid:
401    invalidCommandBlock(pRI);
402    return;
403}
404
405/** Callee expects const char ** */
406static void
407dispatchStrings (Parcel &p, RequestInfo *pRI)
408{
409    int32_t countStrings;
410    status_t status;
411    size_t datalen;
412    char **pStrings;
413
414    status = p.readInt32 (&countStrings);
415
416    if (status != NO_ERROR) {
417        goto invalid;
418    }
419
420    startRequest;
421    if (countStrings == 0) {
422        // just some non-null pointer
423        pStrings = (char **)alloca(sizeof(char *));
424        datalen = 0;
425    } else if (((int)countStrings) == -1) {
426        pStrings = NULL;
427        datalen = 0;
428    } else {
429        datalen = sizeof(char *) * countStrings;
430
431        pStrings = (char **)alloca(datalen);
432
433        for (int i = 0 ; i < countStrings ; i++) {
434            pStrings[i] = strdupReadString(p);
435            appendPrintBuf("%s%s,", printBuf, pStrings[i]);
436        }
437    }
438    removeLastChar;
439    closeRequest;
440    printRequest(pRI->token, pRI->pCI->requestNumber);
441
442    s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI);
443
444    if (pStrings != NULL) {
445        for (int i = 0 ; i < countStrings ; i++) {
446#ifdef MEMSET_FREED
447            memsetString (pStrings[i]);
448#endif
449            free(pStrings[i]);
450        }
451
452#ifdef MEMSET_FREED
453        memset(pStrings, 0, datalen);
454#endif
455    }
456
457    return;
458invalid:
459    invalidCommandBlock(pRI);
460    return;
461}
462
463/** Callee expects const int * */
464static void
465dispatchInts (Parcel &p, RequestInfo *pRI)
466{
467    int32_t count;
468    status_t status;
469    size_t datalen;
470    int *pInts;
471
472    status = p.readInt32 (&count);
473
474    if (status != NO_ERROR || count == 0) {
475        goto invalid;
476    }
477
478    datalen = sizeof(int) * count;
479    pInts = (int *)alloca(datalen);
480
481    startRequest;
482    for (int i = 0 ; i < count ; i++) {
483        int32_t t;
484
485        status = p.readInt32(&t);
486        pInts[i] = (int)t;
487        appendPrintBuf("%s%d,", printBuf, t);
488
489        if (status != NO_ERROR) {
490            goto invalid;
491        }
492   }
493   removeLastChar;
494   closeRequest;
495   printRequest(pRI->token, pRI->pCI->requestNumber);
496
497   s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<int *>(pInts),
498                       datalen, pRI);
499
500#ifdef MEMSET_FREED
501    memset(pInts, 0, datalen);
502#endif
503
504    return;
505invalid:
506    invalidCommandBlock(pRI);
507    return;
508}
509
510
511/**
512 * Callee expects const RIL_SMS_WriteArgs *
513 * Payload is:
514 *   int32_t status
515 *   String pdu
516 */
517static void
518dispatchSmsWrite (Parcel &p, RequestInfo *pRI)
519{
520    RIL_SMS_WriteArgs args;
521    int32_t t;
522    status_t status;
523
524    memset (&args, 0, sizeof(args));
525
526    status = p.readInt32(&t);
527    args.status = (int)t;
528
529    args.pdu = strdupReadString(p);
530
531    if (status != NO_ERROR || args.pdu == NULL) {
532        goto invalid;
533    }
534
535    args.smsc = strdupReadString(p);
536
537    startRequest;
538    appendPrintBuf("%s%d,%s,smsc=%s", printBuf, args.status,
539        (char*)args.pdu,  (char*)args.smsc);
540    closeRequest;
541    printRequest(pRI->token, pRI->pCI->requestNumber);
542
543    s_callbacks.onRequest(pRI->pCI->requestNumber, &args, sizeof(args), pRI);
544
545#ifdef MEMSET_FREED
546    memsetString (args.pdu);
547#endif
548
549    free (args.pdu);
550
551#ifdef MEMSET_FREED
552    memset(&args, 0, sizeof(args));
553#endif
554
555    return;
556invalid:
557    invalidCommandBlock(pRI);
558    return;
559}
560
561/**
562 * Callee expects const RIL_Dial *
563 * Payload is:
564 *   String address
565 *   int32_t clir
566 */
567static void
568dispatchDial (Parcel &p, RequestInfo *pRI)
569{
570    RIL_Dial dial;
571    int32_t t;
572    status_t status;
573
574    memset (&dial, 0, sizeof(dial));
575
576    dial.address = strdupReadString(p);
577
578    status = p.readInt32(&t);
579    dial.clir = (int)t;
580
581    if (status != NO_ERROR || dial.address == NULL) {
582        goto invalid;
583    }
584
585    startRequest;
586    appendPrintBuf("%snum=%s,clir=%d", printBuf, dial.address, dial.clir);
587    closeRequest;
588    printRequest(pRI->token, pRI->pCI->requestNumber);
589
590    s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeof(dial), pRI);
591
592#ifdef MEMSET_FREED
593    memsetString (dial.address);
594#endif
595
596    free (dial.address);
597
598#ifdef MEMSET_FREED
599    memset(&dial, 0, sizeof(dial));
600#endif
601
602    return;
603invalid:
604    invalidCommandBlock(pRI);
605    return;
606}
607
608/**
609 * Callee expects const RIL_SIM_IO *
610 * Payload is:
611 *   int32_t command
612 *   int32_t fileid
613 *   String path
614 *   int32_t p1, p2, p3
615 *   String data
616 *   String pin2
617 */
618static void
619dispatchSIM_IO (Parcel &p, RequestInfo *pRI)
620{
621    RIL_SIM_IO simIO;
622    int32_t t;
623    status_t status;
624
625    memset (&simIO, 0, sizeof(simIO));
626
627    // note we only check status at the end
628
629    status = p.readInt32(&t);
630    simIO.command = (int)t;
631
632    status = p.readInt32(&t);
633    simIO.fileid = (int)t;
634
635    simIO.path = strdupReadString(p);
636
637    status = p.readInt32(&t);
638    simIO.p1 = (int)t;
639
640    status = p.readInt32(&t);
641    simIO.p2 = (int)t;
642
643    status = p.readInt32(&t);
644    simIO.p3 = (int)t;
645
646    simIO.data = strdupReadString(p);
647    simIO.pin2 = strdupReadString(p);
648
649    startRequest;
650    appendPrintBuf("%scmd=0x%X,efid=0x%X,path=%s,%d,%d,%d,%s,pin2=%s", printBuf,
651        simIO.command, simIO.fileid, (char*)simIO.path,
652        simIO.p1, simIO.p2, simIO.p3,
653        (char*)simIO.data,  (char*)simIO.pin2);
654    closeRequest;
655    printRequest(pRI->token, pRI->pCI->requestNumber);
656
657    if (status != NO_ERROR) {
658        goto invalid;
659    }
660
661       s_callbacks.onRequest(pRI->pCI->requestNumber, &simIO, sizeof(simIO), pRI);
662
663#ifdef MEMSET_FREED
664    memsetString (simIO.path);
665    memsetString (simIO.data);
666    memsetString (simIO.pin2);
667#endif
668
669    free (simIO.path);
670    free (simIO.data);
671    free (simIO.pin2);
672
673#ifdef MEMSET_FREED
674    memset(&simIO, 0, sizeof(simIO));
675#endif
676
677    return;
678invalid:
679    invalidCommandBlock(pRI);
680    return;
681}
682
683/**
684 * Callee expects const RIL_CallForwardInfo *
685 * Payload is:
686 *  int32_t status/action
687 *  int32_t reason
688 *  int32_t serviceCode
689 *  int32_t toa
690 *  String number  (0 length -> null)
691 *  int32_t timeSeconds
692 */
693static void
694dispatchCallForward(Parcel &p, RequestInfo *pRI)
695{
696    RIL_CallForwardInfo cff;
697    int32_t t;
698    status_t status;
699
700    memset (&cff, 0, sizeof(cff));
701
702    // note we only check status at the end
703
704    status = p.readInt32(&t);
705    cff.status = (int)t;
706
707    status = p.readInt32(&t);
708    cff.reason = (int)t;
709
710    status = p.readInt32(&t);
711    cff.serviceClass = (int)t;
712
713    status = p.readInt32(&t);
714    cff.toa = (int)t;
715
716    cff.number = strdupReadString(p);
717
718    status = p.readInt32(&t);
719    cff.timeSeconds = (int)t;
720
721    if (status != NO_ERROR) {
722        goto invalid;
723    }
724
725    // special case: number 0-length fields is null
726
727    if (cff.number != NULL && strlen (cff.number) == 0) {
728        cff.number = NULL;
729    }
730
731    startRequest;
732    appendPrintBuf("%sstat=%d,reason=%d,serv=%d,toa=%d,%s,tout=%d", printBuf,
733        cff.status, cff.reason, cff.serviceClass, cff.toa,
734        (char*)cff.number, cff.timeSeconds);
735    closeRequest;
736    printRequest(pRI->token, pRI->pCI->requestNumber);
737
738    s_callbacks.onRequest(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI);
739
740#ifdef MEMSET_FREED
741    memsetString(cff.number);
742#endif
743
744    free (cff.number);
745
746#ifdef MEMSET_FREED
747    memset(&cff, 0, sizeof(cff));
748#endif
749
750    return;
751invalid:
752    invalidCommandBlock(pRI);
753    return;
754}
755
756
757static void
758dispatchRaw(Parcel &p, RequestInfo *pRI)
759{
760    int32_t len;
761    status_t status;
762    const void *data;
763
764    status = p.readInt32(&len);
765
766    if (status != NO_ERROR) {
767        goto invalid;
768    }
769
770    // The java code writes -1 for null arrays
771    if (((int)len) == -1) {
772        data = NULL;
773        len = 0;
774    }
775
776    data = p.readInplace(len);
777
778    startRequest;
779    appendPrintBuf("%sraw_size=%d", printBuf, len);
780    closeRequest;
781    printRequest(pRI->token, pRI->pCI->requestNumber);
782
783    s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI);
784
785    return;
786invalid:
787    invalidCommandBlock(pRI);
788    return;
789}
790
791static int
792blockingWrite(int fd, const void *buffer, size_t len)
793{
794    size_t writeOffset = 0;
795    const uint8_t *toWrite;
796
797    toWrite = (const uint8_t *)buffer;
798
799    while (writeOffset < len) {
800        ssize_t written;
801        do {
802            written = write (fd, toWrite + writeOffset,
803                                len - writeOffset);
804        } while (written < 0 && errno == EINTR);
805
806        if (written >= 0) {
807            writeOffset += written;
808        } else {   // written < 0
809            LOGE ("RIL Response: unexpected error on write errno:%d", errno);
810            close(fd);
811            return -1;
812        }
813    }
814
815    return 0;
816}
817
818static int
819sendResponseRaw (const void *data, size_t dataSize)
820{
821    int fd = s_fdCommand;
822    int ret;
823    uint32_t header;
824
825    if (s_fdCommand < 0) {
826        return -1;
827    }
828
829    if (dataSize > MAX_COMMAND_BYTES) {
830        LOGE("RIL: packet larger than %u (%u)",
831                MAX_COMMAND_BYTES, (unsigned int )dataSize);
832
833        return -1;
834    }
835
836
837    // FIXME is blocking here ok? issue #550970
838
839    pthread_mutex_lock(&s_writeMutex);
840
841    header = htonl(dataSize);
842
843    ret = blockingWrite(fd, (void *)&header, sizeof(header));
844
845    if (ret < 0) {
846        return ret;
847    }
848
849    blockingWrite(fd, data, dataSize);
850
851    if (ret < 0) {
852        return ret;
853    }
854
855    pthread_mutex_unlock(&s_writeMutex);
856
857    return 0;
858}
859
860static int
861sendResponse (Parcel &p)
862{
863    printResponse;
864    return sendResponseRaw(p.data(), p.dataSize());
865}
866
867/** response is an int* pointing to an array of ints*/
868
869static int
870responseInts(Parcel &p, void *response, size_t responselen)
871{
872    int numInts;
873
874    if (response == NULL && responselen != 0) {
875        LOGE("invalid response: NULL");
876        return RIL_ERRNO_INVALID_RESPONSE;
877    }
878    if (responselen % sizeof(int) != 0) {
879        LOGE("invalid response length %d expected multiple of %d\n",
880            (int)responselen, (int)sizeof(int));
881        return RIL_ERRNO_INVALID_RESPONSE;
882    }
883
884    int *p_int = (int *) response;
885
886    numInts = responselen / sizeof(int *);
887    p.writeInt32 (numInts);
888
889    /* each int*/
890    startResponse;
891    for (int i = 0 ; i < numInts ; i++) {
892        appendPrintBuf("%s%d,", printBuf, p_int[i]);
893        p.writeInt32(p_int[i]);
894    }
895    removeLastChar;
896    closeResponse;
897
898    return 0;
899}
900
901/** response is a char **, pointing to an array of char *'s */
902static int responseStrings(Parcel &p, void *response, size_t responselen)
903{
904    int numStrings;
905
906    if (response == NULL && responselen != 0) {
907        LOGE("invalid response: NULL");
908        return RIL_ERRNO_INVALID_RESPONSE;
909    }
910    if (responselen % sizeof(char *) != 0) {
911        LOGE("invalid response length %d expected multiple of %d\n",
912            (int)responselen, (int)sizeof(char *));
913        return RIL_ERRNO_INVALID_RESPONSE;
914    }
915
916    if (response == NULL) {
917        p.writeInt32 (0);
918    } else {
919        char **p_cur = (char **) response;
920
921        numStrings = responselen / sizeof(char *);
922        p.writeInt32 (numStrings);
923
924        /* each string*/
925        startResponse;
926        for (int i = 0 ; i < numStrings ; i++) {
927            appendPrintBuf("%s%s,", printBuf, (char*)p_cur[i]);
928            writeStringToParcel (p, p_cur[i]);
929        }
930        removeLastChar;
931        closeResponse;
932    }
933    return 0;
934}
935
936
937/**
938 * NULL strings are accepted
939 * FIXME currently ignores responselen
940 */
941static int responseString(Parcel &p, void *response, size_t responselen)
942{
943    /* one string only */
944    startResponse;
945    appendPrintBuf("%s%s", printBuf, (char*)response);
946    closeResponse;
947
948    writeStringToParcel(p, (const char *)response);
949
950    return 0;
951}
952
953static int responseVoid(Parcel &p, void *response, size_t responselen)
954{
955    startResponse;
956    removeLastChar;
957    return 0;
958}
959
960static int responseCallList(Parcel &p, void *response, size_t responselen)
961{
962    int num;
963
964    if (response == NULL && responselen != 0) {
965        LOGE("invalid response: NULL");
966        return RIL_ERRNO_INVALID_RESPONSE;
967    }
968
969    if (responselen % sizeof (RIL_Call *) != 0) {
970        LOGE("invalid response length %d expected multiple of %d\n",
971            (int)responselen, (int)sizeof (RIL_Call *));
972        return RIL_ERRNO_INVALID_RESPONSE;
973    }
974
975    startResponse;
976    /* number of call info's */
977    num = responselen / sizeof(RIL_Call *);
978    p.writeInt32(num);
979
980    for (int i = 0 ; i < num ; i++) {
981        RIL_Call *p_cur = ((RIL_Call **) response)[i];
982        /* each call info */
983        p.writeInt32(p_cur->state);
984        p.writeInt32(p_cur->index);
985        p.writeInt32(p_cur->toa);
986        p.writeInt32(p_cur->isMpty);
987        p.writeInt32(p_cur->isMT);
988        p.writeInt32(p_cur->als);
989        p.writeInt32(p_cur->isVoice);
990        writeStringToParcel (p, p_cur->number);
991        appendPrintBuf("%s[%s,id=%d,toa=%d,%s,%s,als=%d,%s,%s],", printBuf,
992            callStateToString(p_cur->state),
993            p_cur->index, p_cur->toa,
994            (p_cur->isMpty)?"mpty":"norm",
995            (p_cur->isMT)?"mt":"mo",
996            p_cur->als,
997            (p_cur->isVoice)?"voc":"nonvoc",
998            (char*)p_cur->number);
999    }
1000    removeLastChar;
1001    closeResponse;
1002
1003    return 0;
1004}
1005
1006static int responseSMS(Parcel &p, void *response, size_t responselen)
1007{
1008    if (response == NULL) {
1009        LOGE("invalid response: NULL");
1010        return RIL_ERRNO_INVALID_RESPONSE;
1011    }
1012
1013    if (responselen != sizeof (RIL_SMS_Response) ) {
1014        LOGE("invalid response length %d expected %d",
1015                (int)responselen, (int)sizeof (RIL_SMS_Response));
1016        return RIL_ERRNO_INVALID_RESPONSE;
1017    }
1018
1019    RIL_SMS_Response *p_cur = (RIL_SMS_Response *) response;
1020
1021    p.writeInt32(p_cur->messageRef);
1022    writeStringToParcel(p, p_cur->ackPDU);
1023
1024    startResponse;
1025    appendPrintBuf("%s%d,%s", printBuf, p_cur->messageRef,
1026        (char*)p_cur->ackPDU);
1027    closeResponse;
1028
1029    return 0;
1030}
1031
1032static int responseContexts(Parcel &p, void *response, size_t responselen)
1033{
1034    if (response == NULL && responselen != 0) {
1035        LOGE("invalid response: NULL");
1036        return RIL_ERRNO_INVALID_RESPONSE;
1037    }
1038
1039    if (responselen % sizeof(RIL_PDP_Context_Response) != 0) {
1040        LOGE("invalid response length %d expected multiple of %d",
1041                (int)responselen, (int)sizeof(RIL_PDP_Context_Response));
1042        return RIL_ERRNO_INVALID_RESPONSE;
1043    }
1044
1045    int num = responselen / sizeof(RIL_PDP_Context_Response);
1046    p.writeInt32(num);
1047
1048    RIL_PDP_Context_Response *p_cur = (RIL_PDP_Context_Response *) response;
1049    startResponse;
1050    int i;
1051    for (i = 0; i < num; i++) {
1052        p.writeInt32(p_cur[i].cid);
1053        p.writeInt32(p_cur[i].active);
1054        writeStringToParcel(p, p_cur[i].type);
1055        writeStringToParcel(p, p_cur[i].apn);
1056        writeStringToParcel(p, p_cur[i].address);
1057        appendPrintBuf("%s[cid=%d,%s,%s,%s,%s],", printBuf,
1058            p_cur[i].cid,
1059            (p_cur[i].active==0)?"down":"up",
1060            (char*)p_cur[i].type,
1061            (char*)p_cur[i].apn,
1062            (char*)p_cur[i].address);
1063    }
1064    removeLastChar;
1065    closeResponse;
1066
1067    return 0;
1068}
1069
1070static int responseRaw(Parcel &p, void *response, size_t responselen)
1071{
1072    if (response == NULL && responselen != 0) {
1073        LOGE("invalid response: NULL with responselen != 0");
1074        return RIL_ERRNO_INVALID_RESPONSE;
1075    }
1076
1077    // The java code reads -1 size as null byte array
1078    if (response == NULL) {
1079        p.writeInt32(-1);
1080    } else {
1081        p.writeInt32(responselen);
1082        p.write(response, responselen);
1083    }
1084
1085    return 0;
1086}
1087
1088
1089static int responseSIM_IO(Parcel &p, void *response, size_t responselen)
1090{
1091    if (response == NULL) {
1092        LOGE("invalid response: NULL");
1093        return RIL_ERRNO_INVALID_RESPONSE;
1094    }
1095
1096    if (responselen != sizeof (RIL_SIM_IO_Response) ) {
1097        LOGE("invalid response length was %d expected %d",
1098                (int)responselen, (int)sizeof (RIL_SIM_IO_Response));
1099        return RIL_ERRNO_INVALID_RESPONSE;
1100    }
1101
1102    RIL_SIM_IO_Response *p_cur = (RIL_SIM_IO_Response *) response;
1103    p.writeInt32(p_cur->sw1);
1104    p.writeInt32(p_cur->sw2);
1105    writeStringToParcel(p, p_cur->simResponse);
1106
1107    startResponse;
1108    appendPrintBuf("%ssw1=0x%X,sw2=0x%X,%s", printBuf, p_cur->sw1, p_cur->sw2,
1109        (char*)p_cur->simResponse);
1110    closeResponse;
1111
1112
1113    return 0;
1114}
1115
1116static int responseCallForwards(Parcel &p, void *response, size_t responselen)
1117{
1118    int num;
1119
1120    if (response == NULL && responselen != 0) {
1121        LOGE("invalid response: NULL");
1122        return RIL_ERRNO_INVALID_RESPONSE;
1123    }
1124
1125    if (responselen % sizeof(RIL_CallForwardInfo *) != 0) {
1126        LOGE("invalid response length %d expected multiple of %d",
1127                (int)responselen, (int)sizeof(RIL_CallForwardInfo *));
1128        return RIL_ERRNO_INVALID_RESPONSE;
1129    }
1130
1131    /* number of call info's */
1132    num = responselen / sizeof(RIL_CallForwardInfo *);
1133    p.writeInt32(num);
1134
1135    startResponse;
1136    for (int i = 0 ; i < num ; i++) {
1137        RIL_CallForwardInfo *p_cur = ((RIL_CallForwardInfo **) response)[i];
1138
1139        p.writeInt32(p_cur->status);
1140        p.writeInt32(p_cur->reason);
1141        p.writeInt32(p_cur->serviceClass);
1142        p.writeInt32(p_cur->toa);
1143        writeStringToParcel(p, p_cur->number);
1144        p.writeInt32(p_cur->timeSeconds);
1145        appendPrintBuf("%s[%s,reason=%d,cls=%d,toa=%d,%s,tout=%d],", printBuf,
1146            (p_cur->status==1)?"enable":"disable",
1147            p_cur->reason, p_cur->serviceClass, p_cur->toa,
1148            (char*)p_cur->number,
1149            p_cur->timeSeconds);
1150    }
1151    removeLastChar;
1152    closeResponse;
1153
1154    return 0;
1155}
1156
1157static int responseSsn(Parcel &p, void *response, size_t responselen)
1158{
1159    if (response == NULL) {
1160        LOGE("invalid response: NULL");
1161        return RIL_ERRNO_INVALID_RESPONSE;
1162    }
1163
1164    if (responselen != sizeof(RIL_SuppSvcNotification)) {
1165        LOGE("invalid response length was %d expected %d",
1166                (int)responselen, (int)sizeof (RIL_SuppSvcNotification));
1167        return RIL_ERRNO_INVALID_RESPONSE;
1168    }
1169
1170    RIL_SuppSvcNotification *p_cur = (RIL_SuppSvcNotification *) response;
1171    p.writeInt32(p_cur->notificationType);
1172    p.writeInt32(p_cur->code);
1173    p.writeInt32(p_cur->index);
1174    p.writeInt32(p_cur->type);
1175    writeStringToParcel(p, p_cur->number);
1176
1177    startResponse;
1178    appendPrintBuf("%s%s,code=%d,id=%d,type=%d,%s", printBuf,
1179        (p_cur->notificationType==0)?"mo":"mt",
1180         p_cur->code, p_cur->index, p_cur->type,
1181        (char*)p_cur->number);
1182    closeResponse;
1183
1184    return 0;
1185}
1186
1187static int responseCellList(Parcel &p, void *response, size_t responselen)
1188{
1189    int num;
1190
1191    if (response == NULL && responselen != 0) {
1192        LOGE("invalid response: NULL");
1193        return RIL_ERRNO_INVALID_RESPONSE;
1194    }
1195
1196    if (responselen % sizeof (RIL_NeighboringCell *) != 0) {
1197        LOGE("invalid response length %d expected multiple of %d\n",
1198            (int)responselen, (int)sizeof (RIL_NeighboringCell *));
1199        return RIL_ERRNO_INVALID_RESPONSE;
1200    }
1201
1202    startResponse;
1203    /* number of cell info's */
1204    num = responselen / sizeof(RIL_NeighboringCell *);
1205    p.writeInt32(num);
1206
1207    for (int i = 0 ; i < num ; i++) {
1208        RIL_NeighboringCell *p_cur = ((RIL_NeighboringCell **) response)[i];
1209
1210        /* each cell info */
1211        p.writeInt32(p_cur->rssi);
1212        writeStringToParcel (p, p_cur->cid);
1213
1214        appendPrintBuf("%s[cid=%s,rssi=%d],", printBuf,
1215            p_cur->cid, p_cur->rssi);
1216    }
1217    removeLastChar;
1218    closeResponse;
1219
1220    return 0;
1221}
1222
1223static void triggerEvLoop()
1224{
1225    int ret;
1226    if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
1227        /* trigger event loop to wakeup. No reason to do this,
1228         * if we're in the event loop thread */
1229         do {
1230            ret = write (s_fdWakeupWrite, " ", 1);
1231         } while (ret < 0 && errno == EINTR);
1232    }
1233}
1234
1235static void rilEventAddWakeup(struct ril_event *ev)
1236{
1237    ril_event_add(ev);
1238    triggerEvLoop();
1239}
1240
1241/**
1242 * A write on the wakeup fd is done just to pop us out of select()
1243 * We empty the buffer here and then ril_event will reset the timers on the
1244 * way back down
1245 */
1246static void processWakeupCallback(int fd, short flags, void *param)
1247{
1248    char buff[16];
1249    int ret;
1250
1251    LOGV("processWakeupCallback");
1252
1253    /* empty our wakeup socket out */
1254    do {
1255        ret = read(s_fdWakeupRead, &buff, sizeof(buff));
1256    } while (ret > 0 || (ret < 0 && errno == EINTR));
1257}
1258
1259static void onCommandsSocketClosed()
1260{
1261    int ret;
1262    RequestInfo *p_cur;
1263
1264    /* mark pending requests as "cancelled" so we dont report responses */
1265
1266    ret = pthread_mutex_lock(&s_pendingRequestsMutex);
1267    assert (ret == 0);
1268
1269    p_cur = s_pendingRequests;
1270
1271    for (p_cur = s_pendingRequests
1272            ; p_cur != NULL
1273            ; p_cur  = p_cur->p_next
1274    ) {
1275        p_cur->cancelled = 1;
1276    }
1277
1278    ret = pthread_mutex_unlock(&s_pendingRequestsMutex);
1279    assert (ret == 0);
1280}
1281
1282static void processCommandsCallback(int fd, short flags, void *param)
1283{
1284    RecordStream *p_rs;
1285    void *p_record;
1286    size_t recordlen;
1287    int ret;
1288
1289    assert(fd == s_fdCommand);
1290
1291    p_rs = (RecordStream *)param;
1292
1293    for (;;) {
1294        /* loop until EAGAIN/EINTR, end of stream, or other error */
1295        ret = record_stream_get_next(p_rs, &p_record, &recordlen);
1296
1297        if (ret == 0 && p_record == NULL) {
1298            /* end-of-stream */
1299            break;
1300        } else if (ret < 0) {
1301            break;
1302        } else if (ret == 0) { /* && p_record != NULL */
1303            processCommandBuffer(p_record, recordlen);
1304        }
1305    }
1306
1307    if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
1308        /* fatal error or end-of-stream */
1309        if (ret != 0) {
1310            LOGE("error on reading command socket errno:%d\n", errno);
1311        } else {
1312            LOGW("EOS.  Closing command socket.");
1313        }
1314
1315        close(s_fdCommand);
1316        s_fdCommand = -1;
1317
1318        ril_event_del(&s_commands_event);
1319
1320        record_stream_free(p_rs);
1321
1322        /* start listening for new connections again */
1323        rilEventAddWakeup(&s_listen_event);
1324
1325        onCommandsSocketClosed();
1326    }
1327}
1328
1329
1330static void onNewCommandConnect()
1331{
1332    // implicit radio state changed
1333    RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
1334                                    NULL, 0);
1335
1336    // Send last NITZ time data, in case it was missed
1337    if (s_lastNITZTimeData != NULL) {
1338        sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize);
1339
1340        free(s_lastNITZTimeData);
1341        s_lastNITZTimeData = NULL;
1342    }
1343
1344    // Get version string
1345    if (s_callbacks.getVersion != NULL) {
1346        const char *version;
1347        version = s_callbacks.getVersion();
1348        LOGI("RIL Daemon version: %s\n", version);
1349
1350        property_set(PROPERTY_RIL_IMPL, version);
1351    } else {
1352        LOGI("RIL Daemon version: unavailable\n");
1353        property_set(PROPERTY_RIL_IMPL, "unavailable");
1354    }
1355
1356}
1357
1358static void listenCallback (int fd, short flags, void *param)
1359{
1360    int ret;
1361    int err;
1362    int is_phone_socket;
1363    RecordStream *p_rs;
1364
1365    struct sockaddr_un peeraddr;
1366    socklen_t socklen = sizeof (peeraddr);
1367
1368    struct ucred creds;
1369    socklen_t szCreds = sizeof(creds);
1370
1371    struct passwd *pwd = NULL;
1372
1373    assert (s_fdCommand < 0);
1374    assert (fd == s_fdListen);
1375
1376    s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
1377
1378    if (s_fdCommand < 0 ) {
1379        LOGE("Error on accept() errno:%d", errno);
1380        /* start listening for new connections again */
1381        rilEventAddWakeup(&s_listen_event);
1382	return;
1383    }
1384
1385    /* check the credential of the other side and only accept socket from
1386     * phone process
1387     */
1388    errno = 0;
1389    is_phone_socket = 0;
1390
1391    err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
1392
1393    if (err == 0 && szCreds > 0) {
1394      errno = 0;
1395      pwd = getpwuid(creds.uid);
1396      if (pwd != NULL) {
1397	if (strcmp(pwd->pw_name, PHONE_PROCESS) == 0) {
1398	  is_phone_socket = 1;
1399	} else {
1400	  LOGE("RILD can't accept socket from process %s", pwd->pw_name);
1401	}
1402      } else {
1403	LOGE("Error on getpwuid() errno: %d", errno);
1404      }
1405    } else {
1406      LOGD("Error on getsockopt() errno: %d", errno);
1407    }
1408
1409    if ( !is_phone_socket ) {
1410      LOGE("RILD must accept socket from %s", PHONE_PROCESS);
1411
1412      close(s_fdCommand);
1413      s_fdCommand = -1;
1414
1415      onCommandsSocketClosed();
1416
1417      /* start listening for new connections again */
1418      rilEventAddWakeup(&s_listen_event);
1419
1420      return;
1421    }
1422
1423    ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);
1424
1425    if (ret < 0) {
1426        LOGE ("Error setting O_NONBLOCK errno:%d", errno);
1427    }
1428
1429    LOGI("libril: new connection");
1430
1431    p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES);
1432
1433    ril_event_set (&s_commands_event, s_fdCommand, 1,
1434        processCommandsCallback, p_rs);
1435
1436    rilEventAddWakeup (&s_commands_event);
1437
1438    onNewCommandConnect();
1439}
1440
1441static void freeDebugCallbackArgs(int number, char **args) {
1442    for (int i = 0; i < number; i++) {
1443        if (args[i] != NULL) {
1444            free(args[i]);
1445        }
1446    }
1447    free(args);
1448}
1449
1450static void debugCallback (int fd, short flags, void *param)
1451{
1452    int acceptFD, option;
1453    struct sockaddr_un peeraddr;
1454    socklen_t socklen = sizeof (peeraddr);
1455    int data;
1456    unsigned int qxdm_data[6];
1457    const char *deactData[1] = {"1"};
1458    char *actData[1];
1459    RIL_Dial dialData;
1460    int hangupData[1] = {1};
1461    int number;
1462    char **args;
1463
1464    acceptFD = accept (fd,  (sockaddr *) &peeraddr, &socklen);
1465
1466    if (acceptFD < 0) {
1467        LOGE ("error accepting on debug port: %d\n", errno);
1468        return;
1469    }
1470
1471    if (recv(acceptFD, &number, sizeof(int), 0) != sizeof(int)) {
1472        LOGE ("error reading on socket: number of Args: \n");
1473        return;
1474    }
1475    args = (char **) malloc(sizeof(char*) * number);
1476
1477    for (int i = 0; i < number; i++) {
1478        int len;
1479        if (recv(acceptFD, &len, sizeof(int), 0) != sizeof(int)) {
1480            LOGE ("error reading on socket: Len of Args: \n");
1481            freeDebugCallbackArgs(i, args);
1482            return;
1483        }
1484        // +1 for null-term
1485        args[i] = (char *) malloc((sizeof(char) * len) + 1);
1486        if (recv(acceptFD, args[i], sizeof(char) * len, 0)
1487            != sizeof(char) * len) {
1488            LOGE ("error reading on socket: Args[%d] \n", i);
1489            freeDebugCallbackArgs(i, args);
1490            return;
1491        }
1492        char * buf = args[i];
1493        buf[len] = 0;
1494    }
1495
1496    switch (atoi(args[0])) {
1497        case 0:
1498            LOGI ("Connection on debug port: issuing reset.");
1499            issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0);
1500            break;
1501        case 1:
1502            LOGI ("Connection on debug port: issuing radio power off.");
1503            data = 0;
1504            issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
1505            // Close the socket
1506            close(s_fdCommand);
1507            s_fdCommand = -1;
1508            break;
1509        case 2:
1510            LOGI ("Debug port: issuing unsolicited network change.");
1511            RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED,
1512                                      NULL, 0);
1513            break;
1514        case 3:
1515            LOGI ("Debug port: QXDM log enable.");
1516            qxdm_data[0] = 65536;
1517            qxdm_data[1] = 16;
1518            qxdm_data[2] = 1;
1519            qxdm_data[3] = 32;
1520            qxdm_data[4] = 0;
1521            qxdm_data[4] = 8;
1522            issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
1523                              6 * sizeof(int));
1524            break;
1525        case 4:
1526            LOGI ("Debug port: QXDM log disable.");
1527            qxdm_data[0] = 65536;
1528            qxdm_data[1] = 16;
1529            qxdm_data[2] = 0;
1530            qxdm_data[3] = 32;
1531            qxdm_data[4] = 0;
1532            qxdm_data[4] = 8;
1533            issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data,
1534                              6 * sizeof(int));
1535            break;
1536        case 5:
1537            LOGI("Debug port: Radio On");
1538            data = 1;
1539            issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int));
1540            sleep(2);
1541            // Set network selection automatic.
1542            issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0);
1543            break;
1544        case 6:
1545            LOGI("Debug port: Setup PDP, Apn :%s\n", args[1]);
1546            actData[0] = args[1];
1547            issueLocalRequest(RIL_REQUEST_SETUP_DEFAULT_PDP, &actData,
1548                              sizeof(actData));
1549            break;
1550        case 7:
1551            LOGI("Debug port: Deactivate PDP");
1552            issueLocalRequest(RIL_REQUEST_DEACTIVATE_DEFAULT_PDP, &deactData,
1553                              sizeof(deactData));
1554            break;
1555        case 8:
1556            LOGI("Debug port: Dial Call");
1557            dialData.clir = 0;
1558            dialData.address = args[1];
1559            issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData));
1560            break;
1561        case 9:
1562            LOGI("Debug port: Answer Call");
1563            issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0);
1564            break;
1565        case 10:
1566            LOGI("Debug port: End Call");
1567            issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData,
1568                              sizeof(hangupData));
1569            break;
1570        default:
1571            LOGE ("Invalid request");
1572            break;
1573    }
1574    freeDebugCallbackArgs(number, args);
1575    close(acceptFD);
1576}
1577
1578
1579static void userTimerCallback (int fd, short flags, void *param)
1580{
1581    UserCallbackInfo *p_info;
1582
1583    p_info = (UserCallbackInfo *)param;
1584
1585    p_info->p_callback(p_info->userParam);
1586
1587
1588    // FIXME generalize this...there should be a cancel mechanism
1589    if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
1590        s_last_wake_timeout_info = NULL;
1591    }
1592
1593    free(p_info);
1594}
1595
1596
1597static void *
1598eventLoop(void *param)
1599{
1600    int ret;
1601    int filedes[2];
1602
1603    ril_event_init();
1604
1605    pthread_mutex_lock(&s_startupMutex);
1606
1607    s_started = 1;
1608    pthread_cond_broadcast(&s_startupCond);
1609
1610    pthread_mutex_unlock(&s_startupMutex);
1611
1612    ret = pipe(filedes);
1613
1614    if (ret < 0) {
1615        LOGE("Error in pipe() errno:%d", errno);
1616        return NULL;
1617    }
1618
1619    s_fdWakeupRead = filedes[0];
1620    s_fdWakeupWrite = filedes[1];
1621
1622    fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
1623
1624    ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
1625                processWakeupCallback, NULL);
1626
1627    rilEventAddWakeup (&s_wakeupfd_event);
1628
1629    // Only returns on error
1630    ril_event_loop();
1631    LOGE ("error in event_loop_base errno:%d", errno);
1632
1633    return NULL;
1634}
1635
1636extern "C" void
1637RIL_startEventLoop(void)
1638{
1639    int ret;
1640    pthread_attr_t attr;
1641
1642    /* spin up eventLoop thread and wait for it to get started */
1643    s_started = 0;
1644    pthread_mutex_lock(&s_startupMutex);
1645
1646    pthread_attr_init (&attr);
1647    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1648    ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
1649
1650    while (s_started == 0) {
1651        pthread_cond_wait(&s_startupCond, &s_startupMutex);
1652    }
1653
1654    pthread_mutex_unlock(&s_startupMutex);
1655
1656    if (ret < 0) {
1657        LOGE("Failed to create dispatch thread errno:%d", errno);
1658        return;
1659    }
1660}
1661
1662// Used for testing purpose only.
1663extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
1664    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
1665}
1666
1667extern "C" void
1668RIL_register (const RIL_RadioFunctions *callbacks)
1669{
1670    int ret;
1671    int flags;
1672
1673    if (callbacks == NULL
1674        || ! (callbacks->version == RIL_VERSION || callbacks->version == 1)
1675    ) {
1676        LOGE(
1677            "RIL_register: RIL_RadioFunctions * null or invalid version"
1678            " (expected %d)", RIL_VERSION);
1679        return;
1680    }
1681
1682    if (s_registerCalled > 0) {
1683        LOGE("RIL_register has been called more than once. "
1684                "Subsequent call ignored");
1685        return;
1686    }
1687
1688    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
1689
1690    s_registerCalled = 1;
1691
1692    // Little self-check
1693
1694    for (int i = 0; i < (int)NUM_ELEMS(s_commands) ; i++) {
1695        assert(i == s_commands[i].requestNumber);
1696    }
1697
1698    for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses) ; i++) {
1699        assert(i + RIL_UNSOL_RESPONSE_BASE
1700                == s_unsolResponses[i].requestNumber);
1701    }
1702
1703    // New rild impl calls RIL_startEventLoop() first
1704    // old standalone impl wants it here.
1705
1706    if (s_started == 0) {
1707        RIL_startEventLoop();
1708    }
1709
1710    // start listen socket
1711
1712#if 0
1713    ret = socket_local_server (SOCKET_NAME_RIL,
1714            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
1715
1716    if (ret < 0) {
1717        LOGE("Unable to bind socket errno:%d", errno);
1718        exit (-1);
1719    }
1720    s_fdListen = ret;
1721
1722#else
1723    s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
1724    if (s_fdListen < 0) {
1725        LOGE("Failed to get socket '" SOCKET_NAME_RIL "'");
1726        exit(-1);
1727    }
1728
1729    ret = listen(s_fdListen, 4);
1730
1731    if (ret < 0) {
1732        LOGE("Failed to listen on control socket '%d': %s",
1733             s_fdListen, strerror(errno));
1734        exit(-1);
1735    }
1736#endif
1737
1738
1739    /* note: non-persistent so we can accept only one connection at a time */
1740    ril_event_set (&s_listen_event, s_fdListen, false,
1741                listenCallback, NULL);
1742
1743    rilEventAddWakeup (&s_listen_event);
1744
1745#if 1
1746    // start debug interface socket
1747
1748    s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG);
1749    if (s_fdDebug < 0) {
1750        LOGE("Failed to get socket '" SOCKET_NAME_RIL_DEBUG "' errno:%d", errno);
1751        exit(-1);
1752    }
1753
1754    ret = listen(s_fdDebug, 4);
1755
1756    if (ret < 0) {
1757        LOGE("Failed to listen on ril debug socket '%d': %s",
1758             s_fdDebug, strerror(errno));
1759        exit(-1);
1760    }
1761
1762    ril_event_set (&s_debug_event, s_fdDebug, true,
1763                debugCallback, NULL);
1764
1765    rilEventAddWakeup (&s_debug_event);
1766#endif
1767
1768}
1769
1770static int
1771checkAndDequeueRequestInfo(struct RequestInfo *pRI)
1772{
1773    int ret = 0;
1774
1775    if (pRI == NULL) {
1776        return 0;
1777    }
1778
1779    pthread_mutex_lock(&s_pendingRequestsMutex);
1780
1781    for(RequestInfo **ppCur = &s_pendingRequests
1782        ; *ppCur != NULL
1783        ; ppCur = &((*ppCur)->p_next)
1784    ) {
1785        if (pRI == *ppCur) {
1786            ret = 1;
1787
1788            *ppCur = (*ppCur)->p_next;
1789            break;
1790        }
1791    }
1792
1793    pthread_mutex_unlock(&s_pendingRequestsMutex);
1794
1795    return ret;
1796}
1797
1798
1799extern "C" void
1800RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen)
1801{
1802    RequestInfo *pRI;
1803    int ret;
1804    size_t errorOffset;
1805
1806    pRI = (RequestInfo *)t;
1807
1808    if (!checkAndDequeueRequestInfo(pRI)) {
1809        LOGE ("RIL_onRequestComplete: invalid RIL_Token");
1810        return;
1811    }
1812
1813    if (pRI->local > 0) {
1814        // Locally issued command...void only!
1815        // response does not go back up the command socket
1816        LOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
1817
1818        goto done;
1819    }
1820
1821    appendPrintBuf("[%04d]< %s",
1822        pRI->token, requestToString(pRI->pCI->requestNumber));
1823
1824    if (pRI->cancelled == 0) {
1825        Parcel p;
1826
1827        p.writeInt32 (RESPONSE_SOLICITED);
1828        p.writeInt32 (pRI->token);
1829        errorOffset = p.dataPosition();
1830
1831        p.writeInt32 (e);
1832
1833        if (e == RIL_E_SUCCESS) {
1834            /* process response on success */
1835            ret = pRI->pCI->responseFunction(p, response, responselen);
1836
1837            /* if an error occurred, rewind and mark it */
1838            if (ret != 0) {
1839                p.setDataPosition(errorOffset);
1840                p.writeInt32 (ret);
1841            }
1842        } else {
1843            appendPrintBuf("%s returns %s", printBuf, failCauseToString(e));
1844        }
1845
1846        if (s_fdCommand < 0) {
1847            LOGD ("RIL onRequestComplete: Command channel closed");
1848        }
1849        sendResponse(p);
1850    }
1851
1852done:
1853    free(pRI);
1854}
1855
1856
1857static void
1858grabFullWakeLock()
1859{
1860    int fd;
1861
1862    fd = open (ANDROID_FULL_WAKE_LOCK_PATH, O_WRONLY);
1863
1864    if (fd < 0) {
1865        LOGW ("Cannot open " ANDROID_FULL_WAKE_LOCK_PATH);
1866        return;
1867    }
1868
1869    write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
1870    close (fd);
1871}
1872
1873static void
1874grabPartialWakeLock()
1875{
1876    int fd;
1877
1878    fd = open (ANDROID_PARTIAL_WAKE_LOCK_PATH, O_WRONLY);
1879
1880    if (fd < 0) {
1881        LOGW ("Cannot open " ANDROID_PARTIAL_WAKE_LOCK_PATH);
1882        return;
1883    }
1884
1885    write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
1886    close (fd);
1887}
1888
1889static void
1890releaseWakeLock()
1891{
1892    int fd;
1893
1894    fd = open (ANDROID_WAKE_UNLOCK_PATH, O_WRONLY);
1895
1896    if (fd < 0) {
1897        LOGW ("Cannot open " ANDROID_WAKE_UNLOCK_PATH);
1898        return;
1899    }
1900
1901    write (fd, ANDROID_WAKE_LOCK_NAME, strlen(ANDROID_WAKE_LOCK_NAME));
1902    close (fd);
1903}
1904
1905/**
1906 * Timer callback to put us back to sleep before the default timeout
1907 */
1908static void
1909wakeTimeoutCallback (void *param)
1910{
1911    // We're using "param != NULL" as a cancellation mechanism
1912    if (param == NULL) {
1913        //LOGD("wakeTimeout: releasing wake lock");
1914
1915        releaseWakeLock();
1916    } else {
1917        //LOGD("wakeTimeout: releasing wake lock CANCELLED");
1918    }
1919}
1920
1921extern "C"
1922void RIL_onUnsolicitedResponse(int unsolResponse, void *data,
1923                                size_t datalen)
1924{
1925    int unsolResponseIndex;
1926    int ret;
1927
1928    if (s_registerCalled == 0) {
1929        // Ignore RIL_onUnsolicitedResponse before RIL_register
1930        LOGW("RIL_onUnsolicitedResponse called before RIL_register");
1931        return;
1932    }
1933
1934    unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
1935
1936    if (unsolResponseIndex < 0
1937        || unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses)) {
1938        LOGE("unsupported unsolicited response code %d", unsolResponse);
1939        return;
1940    }
1941
1942    appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
1943
1944    Parcel p;
1945
1946    p.writeInt32 (RESPONSE_UNSOLICITED);
1947    p.writeInt32 (unsolResponse);
1948
1949    ret = s_unsolResponses[unsolResponseIndex]
1950                .responseFunction(p, data, datalen);
1951
1952    // some things get more payload
1953    switch(unsolResponse) {
1954        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
1955            p.writeInt32(s_callbacks.onStateRequest());
1956            appendPrintBuf("%s {%s}", printBuf,
1957                radioStateToString(s_callbacks.onStateRequest()));
1958        break;
1959
1960
1961        case RIL_UNSOL_NITZ_TIME_RECEIVED:
1962            int64_t timeReceived = elapsedRealtime();
1963            // Store the time this was received in case it is delayed
1964            p.writeInt64(timeReceived);
1965        break;
1966    }
1967
1968    if (ret != 0) {
1969        // Problem with the response. Don't continue;
1970        return;
1971    }
1972
1973
1974    ret = sendResponse(p);
1975
1976    if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
1977
1978        // Unfortunately, NITZ time is not poll/update like everything
1979        // else in the system. So, if the upstream client isn't connected,
1980        // keep a copy of the last NITZ response (with receive time noted
1981        // above) around so we can deliver it when it is connected
1982
1983        if (s_lastNITZTimeData != NULL) {
1984            free (s_lastNITZTimeData);
1985            s_lastNITZTimeData = NULL;
1986        }
1987
1988        s_lastNITZTimeData = malloc(p.dataSize());
1989        s_lastNITZTimeDataSize = p.dataSize();
1990        memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
1991    }
1992
1993    bool shouldScheduleTimeout = false;
1994
1995    switch (s_unsolResponses[unsolResponseIndex].wakeType) {
1996        case WAKE_PARTIAL:
1997            grabPartialWakeLock();
1998            shouldScheduleTimeout = true;
1999        break;
2000
2001        case WAKE_FULL:
2002            grabFullWakeLock();
2003            shouldScheduleTimeout = true;
2004        break;
2005
2006        case DONT_WAKE:
2007        default:
2008            break;
2009    }
2010
2011    // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
2012    // FIXME The java code should handshake here to release wake lock
2013
2014    if (shouldScheduleTimeout) {
2015        // Cancel the previous request
2016        if (s_last_wake_timeout_info != NULL) {
2017            s_last_wake_timeout_info->userParam = (void *)1;
2018        }
2019
2020        s_last_wake_timeout_info
2021            = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
2022                                            &TIMEVAL_WAKE_TIMEOUT);
2023    }
2024}
2025
2026/** FIXME generalize this if you track UserCAllbackInfo, clear it
2027    when the callback occurs
2028*/
2029static UserCallbackInfo *
2030internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
2031                                const struct timeval *relativeTime)
2032
2033{
2034    struct timeval myRelativeTime;
2035    UserCallbackInfo *p_info;
2036
2037    p_info = (UserCallbackInfo *) malloc (sizeof(UserCallbackInfo));
2038
2039    p_info->p_callback = callback;
2040    p_info->userParam = param;
2041
2042    if (relativeTime == NULL) {
2043        /* treat null parameter as a 0 relative time */
2044        memset (&myRelativeTime, 0, sizeof(myRelativeTime));
2045    } else {
2046        /* FIXME I think event_add's tv param is really const anyway */
2047        memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
2048    }
2049
2050    ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
2051
2052    ril_timer_add(&(p_info->event), &myRelativeTime);
2053
2054    triggerEvLoop();
2055    return p_info;
2056}
2057
2058
2059extern "C" void
2060RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
2061                                const struct timeval *relativeTime)
2062{
2063    internalRequestTimedCallback (callback, param, relativeTime);
2064}
2065
2066const char *
2067failCauseToString(RIL_Errno e)
2068{
2069    switch(e) {
2070        case RIL_E_SUCCESS: return "E_SUCCESS";
2071        case RIL_E_RADIO_NOT_AVAILABLE: return "E_RAIDO_NOT_AVAILABLE";
2072        case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
2073        case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
2074        case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
2075        case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
2076        case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
2077        case RIL_E_CANCELLED: return "E_CANCELLED";
2078        case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
2079        case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
2080        case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
2081        default: return "<unknown error>";
2082    }
2083}
2084
2085const char *
2086radioStateToString(RIL_RadioState s)
2087{
2088    switch(s) {
2089        case RADIO_STATE_OFF: return "RADIO_OFF";
2090        case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
2091        case RADIO_STATE_SIM_NOT_READY: return "RADIO_SIM_NOT_READY";
2092        case RADIO_STATE_SIM_LOCKED_OR_ABSENT: return "RADIO_SIM_LOCKED_OR_ABSENT";
2093        case RADIO_STATE_SIM_READY: return "RADIO_SIM_READY";
2094        default: return "<unknown state>";
2095    }
2096}
2097
2098const char *
2099callStateToString(RIL_CallState s)
2100{
2101    switch(s) {
2102        case RIL_CALL_ACTIVE : return "ACTIVE";
2103        case RIL_CALL_HOLDING: return "HOLDING";
2104        case RIL_CALL_DIALING: return "DIALING";
2105        case RIL_CALL_ALERTING: return "ALERTING";
2106        case RIL_CALL_INCOMING: return "INCOMING";
2107        case RIL_CALL_WAITING: return "WAITING";
2108        default: return "<unknown state>";
2109    }
2110}
2111
2112const char *
2113requestToString(int request)
2114{
2115/*
2116 cat libs/telephony/ril_commands.h \
2117 | egrep "^ *{RIL_" \
2118 | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
2119
2120
2121 cat libs/telephony/ril_unsol_commands.h \
2122 | egrep "^ *{RIL_" \
2123 | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
2124
2125*/
2126    switch(request) {
2127        case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
2128        case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
2129        case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
2130        case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
2131        case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
2132        case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
2133        case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
2134        case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
2135        case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
2136        case RIL_REQUEST_DIAL: return "DIAL";
2137        case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
2138        case RIL_REQUEST_HANGUP: return "HANGUP";
2139        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
2140        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
2141        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
2142        case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
2143        case RIL_REQUEST_UDUB: return "UDUB";
2144        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
2145        case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
2146        case RIL_REQUEST_REGISTRATION_STATE: return "REGISTRATION_STATE";
2147        case RIL_REQUEST_GPRS_REGISTRATION_STATE: return "GPRS_REGISTRATION_STATE";
2148        case RIL_REQUEST_OPERATOR: return "OPERATOR";
2149        case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
2150        case RIL_REQUEST_DTMF: return "DTMF";
2151        case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
2152        case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
2153        case RIL_REQUEST_SETUP_DEFAULT_PDP: return "SETUP_DEFAULT_PDP";
2154        case RIL_REQUEST_SIM_IO: return "SIM_IO";
2155        case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
2156        case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
2157        case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
2158        case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
2159        case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
2160        case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
2161        case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
2162        case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
2163        case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
2164        case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
2165        case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
2166        case RIL_REQUEST_ANSWER: return "ANSWER";
2167        case RIL_REQUEST_DEACTIVATE_DEFAULT_PDP: return "DEACTIVATE_DEFAULT_PDP";
2168        case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
2169        case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
2170        case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
2171        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
2172        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
2173        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
2174        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
2175        case RIL_REQUEST_DTMF_START: return "DTMF_START";
2176        case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
2177        case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
2178        case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
2179        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
2180        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
2181        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
2182        case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
2183        case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
2184        case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
2185        case RIL_REQUEST_LAST_PDP_FAIL_CAUSE: return "LAST_PDP_FAIL_CAUSE";
2186        case RIL_REQUEST_PDP_CONTEXT_LIST: return "PDP_CONTEXT_LIST";
2187        case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
2188        case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
2189        case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
2190	    case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
2191	    case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
2192        case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
2193        case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
2194        case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
2195        case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
2196        case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
2197        case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
2198        case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
2199        case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
2200
2201        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
2202        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
2203        case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
2204        case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
2205        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
2206        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
2207        case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
2208        case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
2209        case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
2210        case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
2211        case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
2212        case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
2213        case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
2214        case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
2215        case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FUL";
2216        case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
2217        case RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED: return "UNSOL_PDP_CONTEXT_LIST_CHANGED";
2218        case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
2219        default: return "<unknown request>";
2220    }
2221}
2222
2223} /* namespace android */
2224